dev-old
Petr Krutov 3 years ago
parent ffbcce9897
commit 5db1aa5ddb

@ -1,4 +1,4 @@
name: Release to registry name: Release
on: on:
push: push:
tags: tags:

@ -0,0 +1,33 @@
linters:
enable:
- bodyclose
- decorder
- dogsled
- errorlint
- exportloopref
- gocognit
- goconst
- gocyclo
- gosec
- ifshort
- makezero
#- nestif - disabled till better times
- nilerr
- prealloc
- unconvert
- unparam
linters-settings:
errcheck:
exclude-functions:
- (*github.com/hashicorp/terraform-plugin-sdk/helper/schema.ResourceData).Set
staticcheck:
go: "1.18"
checks:
- all
- -SA1019
nestif:
min-complexity: 7
issues:
max-same-issues: 0

@ -1,18 +1,35 @@
### Bug fixes ### Bug fixes
- resgroup recreation if quotas unspecified - changing boot\_disk\_size in kvmvm
- downsizing CPU and RAM in kvmvm
- pfw recreation if public\_port\_end unspecified
### New datasources ### New datasources
- vgpu - disk\_list
- pcidevice\_list - rg\_list
- pcidevice - account\_list
- sep - account\_computes\_list
- sep\_list - account\_disks\_list
- sep\_disk\_list - account\_vins\_list
- sep\_config - account\_audits\_list
- sep\_pool - account
- sep\_consumption - account\_rg\_list
- account\_counsumed\_units
- account\_counsumed\_units\_by\_type
- account\_reserved\_units
- account\_templates\_list
- account\_deleted\_list
- bservice\_list
- bservice\_snapshot\_list
- bservice\_deleted\_list
- bservice
- bservice\_group
- extnet\_default
- extnet\_list
- extnet
- extnet\_computes\_list
- vins\_list
### New resources ### New resources
- pcidevice - account
- sep - bservice
- sep\_config - bservice\_group

@ -21,13 +21,15 @@ spec:
} }
steps { steps {
container('alpine') { container('alpine') {
sh 'apk update && apk add openjdk11 java-postgresql-jdbc' sh 'apk update && apk add openjdk11 java-postgresql-jdbc go'
dependencyCheck additionalArguments: '-f JSON -f HTML -n --enableExperimental\ dependencyCheck additionalArguments: '-f JSON -f HTML -n --enableExperimental \
-l deplog \
--dbDriverName org.postgresql.Driver \ --dbDriverName org.postgresql.Driver \
--dbDriverPath /usr/share/java/postgresql-jdbc.jar \ --dbDriverPath /usr/share/java/postgresql-jdbc.jar \
--dbUser $DEPCHECKDB_USR \ --dbUser $DEPCHECKDB_USR \
--dbPassword $DEPCHECKDB_PSW \ --dbPassword $DEPCHECKDB_PSW \
--connectionString jdbc:postgresql://postgres-postgresql.postgres/depcheck', odcInstallation: 'depcheck' --connectionString jdbc:postgresql://postgres-postgresql.postgres/depcheck', odcInstallation: 'depcheck'
sh 'cat deplog'
} }
} }
} }

@ -18,7 +18,9 @@ Terraform provider для платформы Digital Energy Cloud Orchestration
- Работа с snapshots, - Работа с snapshots,
- Работа с pcidevice, - Работа с pcidevice,
- Работа с sep, - Работа с sep,
- Работа с vgpu. - Работа с vgpu,
- Работа с bservice,
- Работа с extnets.
Вики проекта: https://github.com/rudecs/terraform-provider-decort/wiki Вики проекта: https://github.com/rudecs/terraform-provider-decort/wiki

@ -17,7 +17,9 @@ NOTE: provider rc-1.25 is designed for DECORT API 3.7.x. For older API versions
- Work with snapshots, - Work with snapshots,
- Work with pcidevice. - Work with pcidevice.
- Work with sep, - Work with sep,
- Work with vgpu. - Work with vgpu,
- Work with bservice,
- Work with extnets.
This provider supports Import operations on pre-existing resources. This provider supports Import operations on pre-existing resources.

@ -94,8 +94,7 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
decort_username: "", decort_username: "",
} }
var allow_unverified_ssl bool allow_unverified_ssl := d.Get("allow_unverified_ssl").(bool)
allow_unverified_ssl = d.Get("allow_unverified_ssl").(bool)
if ret_config.controller_url == "" { if ret_config.controller_url == "" {
return nil, fmt.Errorf("Empty DECORT cloud controller URL provided.") return nil, fmt.Errorf("Empty DECORT cloud controller URL provided.")
@ -138,7 +137,7 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
if allow_unverified_ssl { if allow_unverified_ssl {
log.Warn("ControllerConfigure: allow_unverified_ssl is set - will not check certificates!") log.Warn("ControllerConfigure: allow_unverified_ssl is set - will not check certificates!")
transCfg := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}} transCfg := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}} //nolint:gosec
ret_config.cc_client = &http.Client{ ret_config.cc_client = &http.Client{
Transport: transCfg, Transport: transCfg,
Timeout: Timeout180s, Timeout: Timeout180s,
@ -336,7 +335,7 @@ func (config *ControllerCfg) validateLegacyUser() (bool, error) {
return true, nil return true, nil
} }
func (config *ControllerCfg) decortAPICall(method string, api_name string, url_values *url.Values) (json_resp string, err error) { func (config *ControllerCfg) decortAPICall(method string, api_name string, url_values *url.Values) (json_resp string, err error) { //nolint:unparam
// This is a convenience wrapper around standard HTTP request methods that is aware of the // This is a convenience wrapper around standard HTTP request methods that is aware of the
// authorization mode for which the provider was initialized and compiles request accordingly. // authorization mode for which the provider was initialized and compiles request accordingly.

@ -1,6 +1,6 @@
/* /*
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com> Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -25,108 +25,393 @@ Visit https://github.com/rudecs/terraform-provider-decort for full source code p
package decort package decort
import ( import (
"encoding/json" "github.com/google/uuid"
"fmt"
// "net/url"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/schema"
) )
func flattenAccount(d *schema.ResourceData, acc_facts string) error { func dataSourceAccountRead(d *schema.ResourceData, m interface{}) error {
// NOTE: this function modifies ResourceData argument - as such it should never be called acc, err := utilityAccountCheckPresence(d, m)
// from resourceAccountExists(...) method
// log.Debugf("flattenAccount: ready to decode response body from %q", CloudspacesGetAPI)
details := AccountRecord{}
err := json.Unmarshal([]byte(acc_facts), &details)
if err != nil { if err != nil {
return err return err
} }
log.Debugf("flattenAccount: decoded Account name %q / ID %d, status %q", details.Name, details.ID, details.Status) id := uuid.New()
d.SetId(id.String())
d.SetId(fmt.Sprintf("%d", details.ID)) d.Set("dc_location", acc.DCLocation)
d.Set("name", details.Name) d.Set("resources", flattenAccResources(acc.Resources))
d.Set("status", details.Status) d.Set("ckey", acc.CKey)
d.Set("meta", 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)
d.Set("vinses", acc.Vinses)
d.Set("computes", flattenAccComputes(acc.Computes))
d.Set("machines", flattenAccMachines(acc.Machines))
return nil return nil
} }
func dataSourceAccountRead(d *schema.ResourceData, m interface{}) error { func flattenAccComputes(acs Computes) []map[string]interface{} {
acc_facts, err := utilityAccountCheckPresence(d, m) res := make([]map[string]interface{}, 0)
if acc_facts == "" { temp := map[string]interface{}{
// if empty string is returned from utilityAccountCheckPresence then there is no "started": acs.Started,
// such account and err tells so - just return it to the calling party "stopped": acs.Stopped,
d.SetId("") // ensure ID is empty in this case
return err
} }
res = append(res, temp)
return res
}
return flattenAccount(d, acc_facts) func flattenAccMachines(ams Machines) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"running": ams.Running,
"halted": ams.Halted,
}
res = append(res, temp)
return res
} }
func dataSourceAccount() *schema.Resource { func flattenAccAcl(acls []AccountAclRecord) []map[string]interface{} {
return &schema.Resource{ res := make([]map[string]interface{}, 0)
SchemaVersion: 1, for _, acls := range acls {
temp := map[string]interface{}{
"can_be_deleted": acls.CanBeDeleted,
"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
}
Read: dataSourceAccountRead, 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
}
Timeouts: &schema.ResourceTimeout{ func flattenAccResource(r Resource) []map[string]interface{} {
Read: &Timeout30s, res := make([]map[string]interface{}, 0)
Default: &Timeout60s, 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
}
Schema: map[string]*schema.Schema{ func dataSourceAccountSchemaMake() map[string]*schema.Schema {
"name": { res := map[string]*schema.Schema{
Type: schema.TypeString, "account_id": {
Optional: true, Type: schema.TypeInt,
Description: "Name of the account. Names are case sensitive and unique.", Required: true,
},
"dc_location": {
Type: schema.TypeString,
Computed: true,
},
"resources": {
Type: schema.TypeList,
Computed: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"current": {
Type: schema.TypeList,
Computed: true,
MaxItems: 1,
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,
MaxItems: 1,
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,
},
},
},
},
},
}, },
},
"account_id": { "ckey": {
Type: schema.TypeInt, Type: schema.TypeString,
Optional: true, Computed: true,
Description: "Unique ID of the account. If account ID is specified, then account name is ignored.", },
"meta": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
}, },
},
"status": { "acl": {
Type: schema.TypeString, Type: schema.TypeList,
Computed: true, Computed: true,
Description: "Current status of the account.", Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"can_be_deleted": {
Type: schema.TypeBool,
Computed: true,
},
"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,
},
},
}, },
},
/* We keep the following attributes commented out, as we are not implementing account "company": {
management with Terraform plugin, so we do not need this extra info. Type: schema.TypeString,
Computed: true,
"quota": { },
Type: schema.TypeList, "companyurl": {
Optional: true, Type: schema.TypeString,
MaxItems: 1, Computed: true,
Elem: &schema.Resource{ },
Schema: quotaRgSubresourceSchema(), // this is a dictionary "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,
MaxItems: 1,
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,
},
}, },
Description: "Quotas on the resources for this account and all its resource groups.",
}, },
},
"resource_groups": { "send_access_emails": {
Type: schema.TypeList, Type: schema.TypeBool,
Computed: true, Computed: true,
Elem: &schema.Schema { },
Type: schema.TypeInt, "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,
},
},
"computes": {
Type: schema.TypeList,
Computed: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"started": {
Type: schema.TypeInt,
Computed: true,
},
"stopped": {
Type: schema.TypeInt,
Computed: true,
},
}, },
Description: "IDs of resource groups in this account."
}, },
},
"vins": { "machines": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
Elem: &schema.Schema { MaxItems: 1,
Type: schema.TypeInt, Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"halted": {
Type: schema.TypeInt,
Computed: true,
},
"running": {
Type: schema.TypeInt,
Computed: true,
},
}, },
Description: "IDs of VINSes created at the account level."
}, },
*/
}, },
"vinses": {
Type: schema.TypeInt,
Computed: true,
},
}
return res
}
func dataSourceAccount() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceAccountRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceAccountSchemaMake(),
} }
} }

@ -0,0 +1,114 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
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(d *schema.ResourceData, m interface{}) error {
accountAuditsList, err := utilityAccountAuditsListCheckPresence(d, m)
if err != nil {
return 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: 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,
},
},
},
},
}
return res
}
func dataSourceAccountAuditsList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceAccountAuditsListRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceAccountAuditsListSchemaMake(),
}
}

@ -0,0 +1,189 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
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(d *schema.ResourceData, m interface{}) error {
accountComputesList, err := utilityAccountComputesListCheckPresence(d, m)
if err != nil {
return 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: 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,
},
},
},
},
}
return res
}
func dataSourceAccountComputesList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceAccountComputesListRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceAccountComputesListSchemaMake(),
}
}

@ -0,0 +1,98 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func dataSourceAccountConsumedUnitsRead(d *schema.ResourceData, m interface{}) error {
accountConsumedUnits, err := utilityAccountConsumedUnitsCheckPresence(d, m)
if err != nil {
return err
}
id := uuid.New()
d.SetId(id.String())
d.Set("cu_c", accountConsumedUnits.CUC)
d.Set("cu_d", accountConsumedUnits.CUD)
d.Set("cu_i", accountConsumedUnits.CUI)
d.Set("cu_m", accountConsumedUnits.CUM)
d.Set("cu_np", accountConsumedUnits.CUNP)
d.Set("gpu_units", accountConsumedUnits.GpuUnits)
return nil
}
func dataSourceAccountConsumedUnitsSchemaMake() map[string]*schema.Schema {
res := map[string]*schema.Schema{
"account_id": {
Type: schema.TypeInt,
Required: true,
Description: "ID of the account",
},
"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,
},
}
return res
}
func dataSourceAccountConsumedUnits() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceAccountConsumedUnitsRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceAccountConsumedUnitsSchemaMake(),
}
}

@ -0,0 +1,78 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func dataSourceAccountConsumedUnitsByTypeRead(d *schema.ResourceData, m interface{}) error {
result, err := utilityAccountConsumedUnitsByTypeCheckPresence(d, m)
if err != nil {
return err
}
id := uuid.New()
d.SetId(id.String())
d.Set("cu_result", result)
return nil
}
func dataSourceAccountConsumedUnitsByTypeSchemaMake() map[string]*schema.Schema {
res := map[string]*schema.Schema{
"account_id": {
Type: schema.TypeInt,
Required: true,
Description: "ID of the account",
},
"cu_type": {
Type: schema.TypeString,
Required: true,
Description: "cloud unit resource type",
},
"cu_result": {
Type: schema.TypeFloat,
Computed: true,
},
}
return res
}
func dataSourceAccountConsumedUnitsByType() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceAccountConsumedUnitsByTypeRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceAccountConsumedUnitsByTypeSchemaMake(),
}
}

@ -0,0 +1,58 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func dataSourceAccountDeletedListRead(d *schema.ResourceData, m interface{}) error {
accountDeletedList, err := utilityAccountDeletedListCheckPresence(d, m)
if err != nil {
return err
}
id := uuid.New()
d.SetId(id.String())
d.Set("items", flattenAccountList(accountDeletedList))
return nil
}
func dataSourceAccountDeletedList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceAccountDeletedListRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceAccountListSchemaMake(),
}
}

@ -0,0 +1,119 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
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": ad.Pool,
"sep_id": ad.SepId,
"size_max": ad.SizeMax,
"type": ad.Type,
}
res = append(res, temp)
}
return res
}
func dataSourceAccountDisksListRead(d *schema.ResourceData, m interface{}) error {
accountDisksList, err := utilityAccountDisksListCheckPresence(d, m)
if err != nil {
return 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: map[string]*schema.Schema{
"disk_id": {
Type: schema.TypeInt,
Computed: true,
},
"disk_name": {
Type: schema.TypeString,
Computed: true,
},
"pool": {
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,
},
},
},
},
}
return res
}
func dataSourceAccountDisksList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceAccountDisksListRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceAccountDisksListSchemaMake(),
}
}

@ -0,0 +1,194 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
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(d *schema.ResourceData, m interface{}) error {
accountFlipGroupsList, err := utilityAccountFlipGroupsListCheckPresence(d, m)
if err != nil {
return 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: 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,
},
},
},
},
}
return res
}
func dataSourceAccountFlipGroupsList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceAccountFlipGroupsListRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceAccountFlipGroupsListSchemaMake(),
}
}

@ -0,0 +1,306 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func flattenAccountList(al AccountCloudApiList) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, acc := range al {
temp := map[string]interface{}{
"acl": flattenRgAcl(acc.Acl),
"created_time": acc.CreatedTime,
"deleted_time": acc.DeletedTime,
"account_id": acc.ID,
"account_name": acc.Name,
"status": acc.Status,
"updated_time": acc.UpdatedTime,
}
res = append(res, temp)
}
return res
}
/*uncomment for cloudbroker
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": 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 dataSourceAccountListRead(d *schema.ResourceData, m interface{}) error {
accountList, err := utilityAccountListCheckPresence(d, m)
if err != nil {
return 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: map[string]*schema.Schema{
/*uncomment for cloudbroker
"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,
},
},
},
},
/*uncomment for cloudbroker
"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,
},
/*uncomment for cloudbroker
"deactivation_time": {
Type: schema.TypeFloat,
Computed: true,
},
"deleted_by": {
Type: schema.TypeString,
Computed: true,
},
*/
"deleted_time": {
Type: schema.TypeInt,
Computed: true,
},
/*uncomment for cloudbroker
"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,
},
/*uncomment for cloudbroker
"resource_limits": {
Type: schema.TypeList,
Computed: true,
MaxItems: 1,
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,
},
/*uncomment for cloudbroker
"version": {
Type: schema.TypeInt,
Computed: true,
},
"vins": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
*/
},
},
},
}
return res
}
func dataSourceAccountList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceAccountListRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceAccountListSchemaMake(),
}
}

@ -0,0 +1,98 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func dataSourceAccountReservedUnitsRead(d *schema.ResourceData, m interface{}) error {
accountReservedUnits, err := utilityAccountReservedUnitsCheckPresence(d, m)
if err != nil {
return err
}
id := uuid.New()
d.SetId(id.String())
d.Set("cu_c", accountReservedUnits.CUC)
d.Set("cu_d", accountReservedUnits.CUD)
d.Set("cu_i", accountReservedUnits.CUI)
d.Set("cu_m", accountReservedUnits.CUM)
d.Set("cu_np", accountReservedUnits.CUNP)
d.Set("gpu_units", accountReservedUnits.GpuUnits)
return nil
}
func dataSourceAccountReservedUnitsSchemaMake() map[string]*schema.Schema {
res := map[string]*schema.Schema{
"account_id": {
Type: schema.TypeInt,
Required: true,
Description: "ID of the account",
},
"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,
},
}
return res
}
func dataSourceAccountReservedUnits() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceAccountReservedUnitsRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceAccountReservedUnitsSchemaMake(),
}
}

@ -0,0 +1,294 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
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 dataSourceAccountRGListRead(d *schema.ResourceData, m interface{}) error {
accountRGList, err := utilityAccountRGListCheckPresence(d, m)
if err != nil {
return 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: map[string]*schema.Schema{
"computes": {
Type: schema.TypeList,
MaxItems: 1,
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,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"consumed": {
Type: schema.TypeList,
Computed: true,
MaxItems: 1,
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,
MaxItems: 1,
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,
MaxItems: 1,
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,
},
},
},
},
}
return res
}
func dataSourceAccountRGList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceAccountRGListRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceAccountRGListSchemaMake(),
}
}

@ -0,0 +1,139 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func flattenAccountTemplatesList(atl AccountTemplatesList) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, at := range atl {
temp := map[string]interface{}{
"unc_path": at.UNCPath,
"account_id": at.AccountId,
"desc": at.Desc,
"template_id": at.ID,
"template_name": at.Name,
"public": at.Public,
"size": at.Size,
"status": at.Status,
"type": at.Type,
"username": at.Username,
}
res = append(res, temp)
}
return res
}
func dataSourceAccountTemplatesListRead(d *schema.ResourceData, m interface{}) error {
accountTemplatesList, err := utilityAccountTemplatesListCheckPresence(d, m)
if err != nil {
return err
}
id := uuid.New()
d.SetId(id.String())
d.Set("items", flattenAccountTemplatesList(accountTemplatesList))
return nil
}
func dataSourceAccountTemplatesListSchemaMake() 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: map[string]*schema.Schema{
"unc_path": {
Type: schema.TypeString,
Computed: true,
},
"account_id": {
Type: schema.TypeInt,
Computed: true,
},
"desc": {
Type: schema.TypeString,
Computed: true,
},
"template_id": {
Type: schema.TypeInt,
Computed: true,
},
"template_name": {
Type: schema.TypeString,
Computed: true,
},
"public": {
Type: schema.TypeBool,
Computed: true,
},
"size": {
Type: schema.TypeInt,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
"username": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
}
return res
}
func dataSourceAccountTemplatessList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceAccountTemplatesListRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceAccountTemplatesListSchemaMake(),
}
}

@ -0,0 +1,174 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
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(d *schema.ResourceData, m interface{}) error {
accountVinsList, err := utilityAccountVinsListCheckPresence(d, m)
if err != nil {
return 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: 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,
},
},
},
},
}
return res
}
func dataSourceAccountVinsList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceAccountVinsListRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceAccountVinsListSchemaMake(),
}
}

@ -0,0 +1,293 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func dataSourceBasicServiceRead(d *schema.ResourceData, m interface{}) error {
bs, err := utilityBasicServiceCheckPresence(d, m)
if err != nil {
return err
}
id := uuid.New()
d.SetId(id.String())
d.Set("account_id", bs.AccountId)
d.Set("account_name", bs.AccountName)
d.Set("base_domain", bs.BaseDomain)
d.Set("computes", flattenBasicServiceComputes(bs.Computes))
d.Set("cpu_total", bs.CPUTotal)
d.Set("created_by", bs.CreatedBy)
d.Set("created_time", bs.CreatedTime)
d.Set("deleted_by", bs.DeletedBy)
d.Set("deleted_time", bs.DeletedTime)
d.Set("disk_total", bs.DiskTotal)
d.Set("gid", bs.GID)
d.Set("groups", bs.Groups)
d.Set("groups_name", bs.GroupsName)
d.Set("guid", bs.GUID)
d.Set("milestones", bs.Milestones)
d.Set("service_name", bs.Name)
d.Set("parent_srv_id", bs.ParentSrvId)
d.Set("parent_srv_type", bs.ParentSrvType)
d.Set("ram_total", bs.RamTotal)
d.Set("rg_id", bs.RGID)
d.Set("rg_name", bs.RGName)
d.Set("snapshots", flattenBasicServiceSnapshots(bs.Snapshots))
d.Set("ssh_key", bs.SSHKey)
d.Set("ssh_user", bs.SSHUser)
d.Set("status", bs.Status)
d.Set("tech_status", bs.TechStatus)
d.Set("updated_by", bs.UpdatedBy)
d.Set("updated_time", bs.UpdatedTime)
d.Set("user_managed", bs.UserManaged)
return nil
}
func flattenBasicServiceComputes(bscs BasicServiceComputes) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, bsc := range bscs {
temp := map[string]interface{}{
"compgroup_id": bsc.CompGroupId,
"compgroup_name": bsc.CompGroupName,
"compgroup_role": bsc.CompGroupRole,
"id": bsc.ID,
"name": bsc.Name,
}
res = append(res, temp)
}
return res
}
func flattenBasicServiceSnapshots(bsrvss BasicServiceSnapshots) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, bsrvs := range bsrvss {
temp := map[string]interface{}{
"guid": bsrvs.GUID,
"label": bsrvs.Label,
"timestamp": bsrvs.Timestamp,
"valid": bsrvs.Valid,
}
res = append(res, temp)
}
return res
}
func dataSourceBasicServiceSchemaMake() map[string]*schema.Schema {
res := map[string]*schema.Schema{
"service_id": {
Type: schema.TypeInt,
Required: true,
},
"account_id": {
Type: schema.TypeInt,
Computed: true,
},
"account_name": {
Type: schema.TypeString,
Computed: true,
},
"base_domain": {
Type: schema.TypeString,
Computed: true,
},
"computes": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"compgroup_id": {
Type: schema.TypeInt,
Computed: true,
},
"compgroup_name": {
Type: schema.TypeString,
Computed: true,
},
"compgroup_role": {
Type: schema.TypeString,
Computed: true,
},
"id": {
Type: schema.TypeInt,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"cpu_total": {
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,
},
"disk_total": {
Type: schema.TypeString,
Computed: true,
},
"gid": {
Type: schema.TypeInt,
Computed: true,
},
"groups": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
"groups_name": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"guid": {
Type: schema.TypeInt,
Computed: true,
},
"milestones": {
Type: schema.TypeInt,
Computed: true,
},
"service_name": {
Type: schema.TypeString,
Computed: true,
},
"parent_srv_id": {
Type: schema.TypeInt,
Computed: true,
},
"parent_srv_type": {
Type: schema.TypeString,
Computed: true,
},
"ram_total": {
Type: schema.TypeInt,
Computed: true,
},
"rg_id": {
Type: schema.TypeInt,
Computed: true,
},
"rg_name": {
Type: schema.TypeString,
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,
},
"timestamp": {
Type: schema.TypeInt,
Computed: true,
},
"valid": {
Type: schema.TypeBool,
Computed: true,
},
},
},
},
"ssh_key": {
Type: schema.TypeString,
Computed: true,
},
"ssh_user": {
Type: schema.TypeString,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"tech_status": {
Type: schema.TypeString,
Computed: true,
},
"updated_by": {
Type: schema.TypeString,
Computed: true,
},
"updated_time": {
Type: schema.TypeInt,
Computed: true,
},
"user_managed": {
Type: schema.TypeBool,
Computed: true,
},
}
return res
}
func dataSourceBasicService() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceBasicServiceRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceBasicServiceSchemaMake(),
}
}

@ -0,0 +1,58 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func dataSourceBasicServiceDeletedListRead(d *schema.ResourceData, m interface{}) error {
basicServiceDeletedList, err := utilityBasicServiceDeletedListCheckPresence(d, m)
if err != nil {
return err
}
id := uuid.New()
d.SetId(id.String())
d.Set("items", flattenBasicServiceList(basicServiceDeletedList))
return nil
}
func dataSourceBasicServiceDeletedList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceBasicServiceDeletedListRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceBasicServiceListSchemaMake(),
}
}

@ -0,0 +1,291 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func dataSourceBasicServiceGroupRead(d *schema.ResourceData, m interface{}) error {
bsg, err := utilityBasicServiceGroupCheckPresence(d, m)
if err != nil {
return err
}
id := uuid.New()
d.SetId(id.String())
d.Set("account_id", bsg.AccountId)
d.Set("account_name", bsg.AccountName)
d.Set("computes", flattenBSGroupComputes(bsg.Computes))
d.Set("consistency", bsg.Consistency)
d.Set("cpu", bsg.CPU)
d.Set("created_by", bsg.CreatedBy)
d.Set("created_time", bsg.CreatedTime)
d.Set("deleted_by", bsg.DeletedBy)
d.Set("deleted_time", bsg.DeletedTime)
d.Set("disk", bsg.Disk)
d.Set("driver", bsg.Driver)
d.Set("extnets", bsg.Extnets)
d.Set("gid", bsg.GID)
d.Set("guid", bsg.GUID)
d.Set("image_id", bsg.ImageId)
d.Set("milestones", bsg.Milestones)
d.Set("compgroup_name", bsg.Name)
d.Set("parents", bsg.Parents)
d.Set("ram", bsg.RAM)
d.Set("rg_id", bsg.RGID)
d.Set("rg_name", bsg.RGName)
d.Set("role", bsg.Role)
d.Set("sep_id", bsg.SepId)
d.Set("seq_no", bsg.SeqNo)
d.Set("status", bsg.Status)
d.Set("tech_status", bsg.TechStatus)
d.Set("timeout_start", bsg.TimeoutStart)
d.Set("updated_by", bsg.UpdatedBy)
d.Set("updated_time", bsg.UpdatedTime)
d.Set("vinses", bsg.Vinses)
return nil
}
func flattenBSGroupOSUsers(bsgosus BasicServiceGroupOSUsers) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, bsgosu := range bsgosus {
temp := map[string]interface{}{
"login": bsgosu.Login,
"password": bsgosu.Password,
}
res = append(res, temp)
}
return res
}
func flattenBSGroupComputes(bsgcs BasicServiceGroupComputes) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, bsgc := range bsgcs {
temp := map[string]interface{}{
"id": bsgc.ID,
"ip_addresses": bsgc.IPAdresses,
"name": bsgc.Name,
"os_users": flattenBSGroupOSUsers(bsgc.OSUsers),
}
res = append(res, temp)
}
return res
}
func dataSourceBasicServiceGroupSchemaMake() map[string]*schema.Schema {
res := map[string]*schema.Schema{
"service_id": {
Type: schema.TypeInt,
Required: true,
},
"compgroup_id": {
Type: schema.TypeInt,
Required: true,
},
"account_id": {
Type: schema.TypeInt,
Computed: true,
},
"account_name": {
Type: schema.TypeString,
Computed: true,
},
"computes": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeInt,
Computed: true,
},
"ip_addresses": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"os_users": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"login": {
Type: schema.TypeString,
Computed: true,
},
"password": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
},
},
},
"consistency": {
Type: schema.TypeBool,
Computed: true,
},
"cpu": {
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,
},
"disk": {
Type: schema.TypeInt,
Computed: true,
},
"driver": {
Type: schema.TypeString,
Computed: true,
},
"extnets": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
"gid": {
Type: schema.TypeInt,
Computed: true,
},
"guid": {
Type: schema.TypeInt,
Computed: true,
},
"image_id": {
Type: schema.TypeInt,
Computed: true,
},
"milestones": {
Type: schema.TypeInt,
Computed: true,
},
"compgroup_name": {
Type: schema.TypeString,
Computed: true,
},
"parents": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
"ram": {
Type: schema.TypeInt,
Computed: true,
},
"rg_id": {
Type: schema.TypeInt,
Computed: true,
},
"rg_name": {
Type: schema.TypeString,
Computed: true,
},
"role": {
Type: schema.TypeString,
Computed: true,
},
"sep_id": {
Type: schema.TypeInt,
Computed: true,
},
"seq_no": {
Type: schema.TypeInt,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"tech_status": {
Type: schema.TypeString,
Computed: true,
},
"timeout_start": {
Type: schema.TypeInt,
Computed: true,
},
"updated_by": {
Type: schema.TypeString,
Computed: true,
},
"updated_time": {
Type: schema.TypeInt,
Computed: true,
},
"vinses": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
}
return res
}
func dataSourceBasicServiceGroup() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceBasicServiceGroupRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceBasicServiceGroupSchemaMake(),
}
}

@ -0,0 +1,215 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func flattenBasicServiceList(bsl BasicServiceList) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, bs := range bsl {
temp := map[string]interface{}{
"account_id": bs.AccountId,
"account_name": bs.AccountName,
"base_domain": bs.BaseDomain,
"created_by": bs.CreatedBy,
"created_time": bs.CreatedTime,
"deleted_by": bs.DeletedBy,
"deleted_time": bs.DeletedTime,
"gid": bs.GID,
"groups": bs.Groups,
"guid": bs.GUID,
"service_id": bs.ID,
"service_name": bs.Name,
"parent_srv_id": bs.ParentSrvId,
"parent_srv_type": bs.ParentSrvType,
"rg_id": bs.RGID,
"rg_name": bs.RGName,
"ssh_user": bs.SSHUser,
"status": bs.Status,
"tech_status": bs.TechStatus,
"updated_by": bs.UpdatedBy,
"updated_time": bs.UpdatedTime,
"user_managed": bs.UserManaged,
}
res = append(res, temp)
}
return res
}
func dataSourceBasicServiceListRead(d *schema.ResourceData, m interface{}) error {
basicServiceList, err := utilityBasicServiceListCheckPresence(d, m)
if err != nil {
return err
}
id := uuid.New()
d.SetId(id.String())
d.Set("items", flattenBasicServiceList(basicServiceList))
return nil
}
func dataSourceBasicServiceListSchemaMake() map[string]*schema.Schema {
res := map[string]*schema.Schema{
"account_id": {
Type: schema.TypeInt,
Optional: true,
Description: "ID of the account to query for BasicService instances",
},
"rg_id": {
Type: schema.TypeInt,
Optional: true,
Description: "ID of the resource group to query for BasicService instances",
},
"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,
},
"base_domain": {
Type: schema.TypeString,
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,
},
"gid": {
Type: schema.TypeInt,
Computed: true,
},
"groups": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
"guid": {
Type: schema.TypeInt,
Computed: true,
},
"service_id": {
Type: schema.TypeInt,
Computed: true,
},
"service_name": {
Type: schema.TypeString,
Computed: true,
},
"parent_srv_id": {
Type: schema.TypeInt,
Computed: true,
},
"parent_srv_type": {
Type: schema.TypeString,
Computed: true,
},
"rg_id": {
Type: schema.TypeInt,
Computed: true,
},
"rg_name": {
Type: schema.TypeString,
Computed: true,
},
"ssh_user": {
Type: schema.TypeString,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"tech_status": {
Type: schema.TypeString,
Computed: true,
},
"updated_by": {
Type: schema.TypeString,
Computed: true,
},
"updated_time": {
Type: schema.TypeInt,
Computed: true,
},
"user_managed": {
Type: schema.TypeBool,
Computed: true,
},
},
},
},
}
return res
}
func dataSourceBasicServiceList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceBasicServiceListRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceBasicServiceListSchemaMake(),
}
}

@ -0,0 +1,93 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func dataSourceBasicServiceSnapshotListRead(d *schema.ResourceData, m interface{}) error {
basicServiceSnapshotList, err := utilityBasicServiceSnapshotListCheckPresence(d, m)
if err != nil {
return err
}
id := uuid.New()
d.SetId(id.String())
d.Set("items", flattenBasicServiceSnapshots(basicServiceSnapshotList))
return nil
}
func dataSourceBasicServiceSnapshotListSchemaMake() map[string]*schema.Schema {
res := map[string]*schema.Schema{
"service_id": {
Type: schema.TypeInt,
Required: true,
Description: "ID of the BasicService instance",
},
"items": {
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,
},
"timestamp": {
Type: schema.TypeInt,
Computed: true,
},
"valid": {
Type: schema.TypeBool,
Computed: true,
},
},
},
},
}
return res
}
func dataSourceBasicServiceSnapshotList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceBasicServiceSnapshotListRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceBasicServiceSnapshotListSchemaMake(),
}
}

@ -66,60 +66,6 @@ func parseComputeDisksToExtraDisks(disks []DiskRecord) []interface{} {
return result return result
} }
// NOTE: this is a legacy function, which is not used as of rc-1.10
// Use "parseComputeDisksToExtraDisks" instead
func parseComputeDisks(disks []DiskRecord) []interface{} {
// Return value was designed to d.Set("disks",) item of dataSourceCompute schema
// However, this item was excluded from the schema as it is not directly
// managed through Terraform
length := len(disks)
log.Debugf("parseComputeDisks: called for %d disks", length)
/*
if length == 1 && disks[0].Type == "B" {
// 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 lenght
length = 0
}
*/
result := []interface{}{}
if length == 0 {
return result
}
for _, value := range disks {
/*
if value.Type == "B" {
// skip boot disk when parsing the list of disks
continue
}
*/
elem := make(map[string]interface{})
// keys in this map should correspond to the Schema definition
// as returned by dataSourceDiskSchemaMake()
elem["name"] = value.Name
elem["disk_id"] = value.ID
elem["account_id"] = value.AccountID
elem["account_name"] = value.AccountName
elem["description"] = value.Desc
elem["image_id"] = value.ImageID
elem["size"] = value.SizeMax
elem["type"] = value.Type
elem["sep_id"] = value.SepID
elem["sep_type"] = value.SepType
elem["pool"] = value.Pool
// elem["status"] = value.Status
// elem["tech_status"] = value.TechStatus
elem["compute_id"] = value.ComputeID
result = append(result, elem)
}
return result
}
func parseBootDiskSize(disks []DiskRecord) int { func parseBootDiskSize(disks []DiskRecord) int {
// this return value will be used to d.Set("boot_disk_size",) item of dataSourceCompute schema // this return value will be used to d.Set("boot_disk_size",) item of dataSourceCompute schema
if len(disks) == 0 { if len(disks) == 0 {
@ -176,71 +122,6 @@ func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []interface{} {
return result return result
} }
/*
func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []map[string]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 := make([]map[string]interface{}, length, length)
for i, 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[i] = elem
}
return result
}
*/
// NOTE: this function is retained for historical purposes and actually not used as of rc-1.10
func parseComputeInterfaces(ifaces []InterfaceRecord) []map[string]interface{} {
// return value was designed to d.Set("interfaces",) item of dataSourceCompute schema
// However, this item was excluded from the schema as it is not directly
// managed through Terraform
length := len(ifaces)
log.Debugf("parseComputeInterfaces: called for %d ifaces", length)
result := make([]map[string]interface{}, length, length)
for i, value := range ifaces {
// Keys in this map should correspond to the Schema definition
// as returned by dataSourceInterfaceSchemaMake()
elem := make(map[string]interface{})
elem["net_id"] = value.NetID
elem["net_type"] = value.NetType
elem["ip_address"] = value.IPAddress
elem["netmask"] = value.NetMask
elem["mac"] = value.MAC
elem["default_gw"] = value.DefaultGW
elem["name"] = value.Name
elem["connection_id"] = value.ConnID
elem["connection_type"] = value.ConnType
/* TODO: add code to parse QoS
qos_schema := interfaceQosSubresourceSchemaMake()
qos_schema.Set("egress_rate", value.QOS.ERate)
qos_schema.Set("ingress_rate", value.QOS.InRate)
qos_schema.Set("ingress_burst", value.QOS.InBurst)
elem["qos"] = qos_schema
*/
result[i] = elem
}
return result
}
func flattenCompute(d *schema.ResourceData, compFacts string) error { func flattenCompute(d *schema.ResourceData, compFacts string) error {
// This function expects that compFacts string contains response from API compute/get, // This function expects that compFacts string contains response from API compute/get,
// i.e. detailed information about compute instance. // i.e. detailed information about compute instance.
@ -440,17 +321,6 @@ func dataSourceCompute() *schema.Resource {
Description: "Network connection(s) for this compute.", Description: "Network connection(s) for this compute.",
}, },
/*
"interfaces": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: interfaceSubresourceSchemaMake(),
},
Description: "Specification for the virtual NICs configured on this compute instance.",
},
*/
"os_users": { "os_users": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
@ -478,26 +348,6 @@ func dataSourceCompute() *schema.Resource {
Default: true, Default: true,
Description: "Is compute started.", Description: "Is compute started.",
}, },
/*
"status": {
Type: schema.TypeString,
Computed: true,
Description: "Current model status of this compute instance.",
},
"tech_status": {
Type: schema.TypeString,
Computed: true,
Description: "Current technical status of this compute instance.",
},
"internal_ip": {
Type: schema.TypeString,
Computed: true,
Description: "Internal IP address of this Compute.",
},
*/
}, },
} }
} }

@ -0,0 +1,391 @@
/*
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func flattenDiskList(dl DisksListResp) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, disk := range dl {
diskAcl, _ := json.Marshal(disk.Acl)
diskIotune, _ := json.Marshal(disk.IOTune)
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": string(diskIotune),
"iqn": disk.IQN,
"login": disk.Login,
"machine_id": disk.MachineId,
"machine_name": disk.MachineName,
"milestones": disk.Milestones,
"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,
"update_by": disk.UpdateBy,
}
res = append(res, temp)
}
return res
}
func flattendDiskSnapshotList(sl SnapshotRecordList) []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(d *schema.ResourceData, m interface{}) error {
diskList, err := utilityDiskListCheckPresence(d, m)
if err != nil {
return 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.TypeString,
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,
},
"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,
},
"update_by": {
Type: schema.TypeInt,
Computed: true,
},
},
},
},
}
return res
}
func dataSourceDiskList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceDiskListRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceDiskListSchemaMake(),
}
}

@ -0,0 +1,321 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func dataSourceExtnetRead(d *schema.ResourceData, m interface{}) error {
e, err := utilityExtnetCheckPresence(d, m)
if err != nil {
return err
}
id := uuid.New()
d.SetId(id.String())
d.Set("ckey", e.CKey)
d.Set("meta", flattenMeta(e.Meta))
d.Set("check__ips", e.CheckIPs)
d.Set("check_ips", e.CheckIps)
d.Set("default", e.Default)
d.Set("default_qos", flattenExtnetDefaultQos(e.DefaultQos))
d.Set("desc", e.Desc)
d.Set("dns", e.Dns)
d.Set("excluded", e.Excluded)
d.Set("free_ips", e.FreeIps)
d.Set("gateway", e.Gateway)
d.Set("gid", e.GID)
d.Set("guid", e.GUID)
d.Set("ipcidr", e.IPCidr)
d.Set("milestones", e.Milestones)
d.Set("net_name", e.Name)
d.Set("network", e.Network)
d.Set("network_id", e.NetworkId)
d.Set("pre_reservations_num", e.PreReservationsNum)
d.Set("prefix", e.Prefix)
d.Set("pri_vnf_dev_id", e.PriVnfDevId)
d.Set("reservations", flattenExtnetReservations(e.Reservations))
d.Set("shared_with", e.SharedWith)
d.Set("status", e.Status)
d.Set("vlan_id", e.VlanID)
d.Set("vnfs", flattenExtnetVNFS(e.VNFS))
return nil
}
func flattenExtnetReservations(ers ExtnetReservations) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, er := range ers {
temp := map[string]interface{}{
"client_type": er.ClientType,
"domainname": er.DomainName,
"hostname": er.HostName,
"desc": er.Desc,
"ip": er.IP,
"mac": er.MAC,
"type": er.Type,
"vm_id": er.VMID,
}
res = append(res, temp)
}
return res
}
func flattenExtnetDefaultQos(edqos ExtnetQos) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"e_rate": edqos.ERate,
"guid": edqos.GUID,
"in_burst": edqos.InBurst,
"in_rate": edqos.InRate,
}
res = append(res, temp)
return res
}
func flattenExtnetVNFS(evnfs ExtnetVNFS) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"dhcp": evnfs.DHCP,
}
res = append(res, temp)
return res
}
func dataSourceExtnetSchemaMake() map[string]*schema.Schema {
res := map[string]*schema.Schema{
"net_id": {
Type: schema.TypeInt,
Required: true,
},
"ckey": {
Type: schema.TypeString,
Computed: true,
},
"meta": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Description: "meta",
},
"check__ips": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"check_ips": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"default": {
Type: schema.TypeBool,
Computed: true,
},
"default_qos": {
Type: schema.TypeList,
MaxItems: 1,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"e_rate": {
Type: schema.TypeInt,
Computed: true,
},
"guid": {
Type: schema.TypeString,
Computed: true,
},
"in_burst": {
Type: schema.TypeInt,
Computed: true,
},
"in_rate": {
Type: schema.TypeInt,
Computed: true,
},
},
},
},
"desc": {
Type: schema.TypeString,
Computed: true,
},
"dns": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"excluded": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"free_ips": {
Type: schema.TypeInt,
Computed: true,
},
"gateway": {
Type: schema.TypeString,
Computed: true,
},
"gid": {
Type: schema.TypeInt,
Computed: true,
},
"guid": {
Type: schema.TypeInt,
Computed: true,
},
"ipcidr": {
Type: schema.TypeString,
Computed: true,
},
"milestones": {
Type: schema.TypeInt,
Computed: true,
},
"net_name": {
Type: schema.TypeString,
Computed: true,
},
"network": {
Type: schema.TypeString,
Computed: true,
},
"network_id": {
Type: schema.TypeInt,
Computed: true,
},
"pre_reservations_num": {
Type: schema.TypeInt,
Computed: true,
},
"prefix": {
Type: schema.TypeInt,
Computed: true,
},
"pri_vnf_dev_id": {
Type: schema.TypeInt,
Computed: true,
},
"reservations": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"client_type": {
Type: schema.TypeString,
Computed: true,
},
"domainname": {
Type: schema.TypeString,
Computed: true,
},
"hostname": {
Type: schema.TypeString,
Computed: true,
},
"desc": {
Type: schema.TypeString,
Computed: true,
},
"ip": {
Type: schema.TypeString,
Computed: true,
},
"mac": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
"vm_id": {
Type: schema.TypeInt,
Computed: true,
},
},
},
},
"shared_with": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"vlan_id": {
Type: schema.TypeInt,
Computed: true,
},
"vnfs": {
Type: schema.TypeList,
MaxItems: 1,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"dhcp": {
Type: schema.TypeInt,
Computed: true,
},
},
},
},
}
return res
}
func dataSourceExtnet() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceExtnetRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceExtnetSchemaMake(),
}
}

@ -0,0 +1,156 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func flattenExtnetsComputes(ecs ExtnetExtendList) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, ec := range ecs {
temp := map[string]interface{}{
"net_id": ec.ID,
"ipaddr": ec.IPAddr,
"ipcidr": ec.IPCidr,
"name": ec.Name,
}
res = append(res, temp)
}
return res
}
func flattenExtnetComputesList(ecl ExtnetComputesList) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, ec := range ecl {
temp := map[string]interface{}{
"account_id": ec.AccountId,
"account_name": ec.AccountName,
"extnets": flattenExtnetsComputes(ec.Extnets),
"id": ec.ID,
"name": ec.Name,
"rg_id": ec.RGID,
"rg_name": ec.RGName,
}
res = append(res, temp)
}
return res
}
func dataSourceExtnetComputesListRead(d *schema.ResourceData, m interface{}) error {
extnetComputesList, err := utilityExtnetComputesListCheckPresence(d, m)
if err != nil {
return err
}
id := uuid.New()
d.SetId(id.String())
d.Set("items", flattenExtnetComputesList(extnetComputesList))
return nil
}
func dataSourceExtnetComputesListSchemaMake() map[string]*schema.Schema {
res := map[string]*schema.Schema{
"account_id": {
Type: schema.TypeInt,
Required: true,
Description: "filter by account ID",
},
"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,
},
"extnets": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"net_id": {
Type: schema.TypeInt,
Computed: true,
},
"ipaddr": {
Type: schema.TypeString,
Computed: true,
},
"ipcidr": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"id": {
Type: schema.TypeInt,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"rg_id": {
Type: schema.TypeInt,
Computed: true,
},
"rg_name": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
}
return res
}
func dataSourceExtnetComputesList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceExtnetComputesListRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceExtnetComputesListSchemaMake(),
}
}

@ -0,0 +1,74 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"strconv"
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func dataSourceExtnetDefaultRead(d *schema.ResourceData, m interface{}) error {
extnetId, err := utilityExtnetDefaultCheckPresence(d, m)
if err != nil {
return err
}
id := uuid.New()
d.SetId(id.String())
extnetIdInt, err := strconv.ParseInt(extnetId, 10, 32)
if err != nil {
return err
}
d.Set("net_id", extnetIdInt)
return nil
}
func dataSourceExtnetDefaultSchemaMake() map[string]*schema.Schema {
res := map[string]*schema.Schema{
"net_id": {
Type: schema.TypeInt,
Computed: true,
},
}
return res
}
func dataSourceExtnetDefault() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceExtnetDefaultRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceExtnetDefaultSchemaMake(),
}
}

@ -0,0 +1,112 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func flattenExtnetList(el ExtnetList) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, e := range el {
temp := map[string]interface{}{
"net_id": e.ID,
"ipcidr": e.IPCidr,
"name": e.Name,
}
res = append(res, temp)
}
return res
}
func dataSourceExtnetListRead(d *schema.ResourceData, m interface{}) error {
extnetList, err := utilityExtnetListCheckPresence(d, m)
if err != nil {
return err
}
id := uuid.New()
d.SetId(id.String())
d.Set("items", flattenExtnetList(extnetList))
return nil
}
func dataSourceExtnetListSchemaMake() map[string]*schema.Schema {
res := map[string]*schema.Schema{
"account_id": {
Type: schema.TypeInt,
Optional: true,
Description: "filter by account ID",
},
"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{
"net_id": {
Type: schema.TypeInt,
Computed: true,
},
"ipcidr": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
}
return res
}
func dataSourceExtnetList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceExtnetListRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceExtnetListSchemaMake(),
}
}

@ -37,7 +37,6 @@ func flattenGrid(d *schema.ResourceData, grid *Grid) {
d.Set("guid", grid.Guid) d.Set("guid", grid.Guid)
d.Set("location_code", grid.LocationCode) d.Set("location_code", grid.LocationCode)
d.Set("id", grid.Id) d.Set("id", grid.Id)
return
} }
func dataSourceGridRead(d *schema.ResourceData, m interface{}) error { func dataSourceGridRead(d *schema.ResourceData, m interface{}) error {

@ -69,7 +69,6 @@ func flattenImage(d *schema.ResourceData, image *Image) {
d.Set("meta", flattenMeta(image.Meta)) d.Set("meta", flattenMeta(image.Meta))
d.Set("desc", image.Desc) d.Set("desc", image.Desc)
d.Set("shared_with", image.SharedWith) d.Set("shared_with", image.SharedWith)
return
} }
func dataSourceImageRead(d *schema.ResourceData, m interface{}) error { func dataSourceImageRead(d *schema.ResourceData, m interface{}) error {

@ -29,7 +29,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/schema"
) )
func flattenImageListStacks(d *schema.ResourceData, stack ImageListStacks) []map[string]interface{} { func flattenImageListStacks(_ *schema.ResourceData, stack ImageListStacks) []map[string]interface{} {
temp := make([]map[string]interface{}, 0) temp := make([]map[string]interface{}, 0)
for _, item := range stack { for _, item := range stack {
t := map[string]interface{}{ t := map[string]interface{}{

@ -0,0 +1,314 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
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(d *schema.ResourceData, m interface{}) error {
rgList, err := utilityRgListCheckPresence(d, m)
if err != nil {
return 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,
MaxItems: 1,
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,
Read: dataSourceRgListRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceRgListSchemaMake(),
}
}

@ -48,13 +48,13 @@ func flattenVins(d *schema.ResourceData, vins_facts string) error {
} }
log.Debugf("flattenVins: decoded ViNS name:ID %s:%d, account ID %d, RG ID %d", log.Debugf("flattenVins: decoded ViNS name:ID %s:%d, account ID %d, RG ID %d",
vinsRecord.Name, vinsRecord.ID, vinsRecord.AccountID, vinsRecord.RgID) vinsRecord.Name, vinsRecord.ID, vinsRecord.AccountID, vinsRecord.RgID)
d.SetId(fmt.Sprintf("%d", vinsRecord.ID)) d.SetId(fmt.Sprintf("%d", vinsRecord.ID))
d.Set("name", vinsRecord.Name) d.Set("name", vinsRecord.Name)
d.Set("account_id", vinsRecord.AccountID) d.Set("account_id", vinsRecord.AccountID)
d.Set("account_name", vinsRecord.AccountName) d.Set("account_name", vinsRecord.AccountName)
err = d.Set("rg_id", vinsRecord.RgID) d.Set("rg_id", vinsRecord.RgID)
d.Set("description", vinsRecord.Desc) d.Set("description", vinsRecord.Desc)
d.Set("ipcidr", vinsRecord.IPCidr) d.Set("ipcidr", vinsRecord.IPCidr)
@ -117,11 +117,11 @@ func dataSourceVins() *schema.Resource {
}, },
/* /*
"vins_id": { "vins_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.", Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.",
}, },
*/ */
"rg_id": { "rg_id": {

@ -0,0 +1,178 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func flattenVinsList(vl VinsList) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, v := range vl {
temp := map[string]interface{}{
"account_id": v.AccountId,
"account_name": v.AccountName,
"created_by": v.CreatedBy,
"created_time": v.CreatedTime,
"deleted_by": v.DeletedBy,
"deleted_time": v.DeletedTime,
"external_ip": v.ExternalIP,
"vins_id": v.ID,
"vins_name": v.Name,
"network": v.Network,
"rg_id": v.RGID,
"rg_name": v.RGName,
"status": v.Status,
"updated_by": v.UpdatedBy,
"updated_time": v.UpdatedTime,
"vxlan_id": v.VXLanID,
}
res = append(res, temp)
}
return res
}
func dataSourceVinsListRead(d *schema.ResourceData, m interface{}) error {
vinsList, err := utilityVinsListCheckPresence(d, m)
if err != nil {
return err
}
id := uuid.New()
d.SetId(id.String())
d.Set("items", flattenVinsList(vinsList))
return nil
}
func dataSourceVinsListSchemaMake() map[string]*schema.Schema {
res := map[string]*schema.Schema{
"include_deleted": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "include deleted computes",
},
"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,
},
"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,
},
"vins_id": {
Type: schema.TypeInt,
Computed: true,
},
"vins_name": {
Type: schema.TypeString,
Computed: true,
},
"network": {
Type: schema.TypeString,
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,
},
"vxlan_id": {
Type: schema.TypeInt,
Computed: true,
},
},
},
},
}
return res
}
func dataSourceVinsList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceVinsListRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceVinsListSchemaMake(),
}
}

@ -1,86 +0,0 @@
/*
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package decort
import (
// log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
)
// ID, type, name, size, account ID, SEP ID, SEP type, pool, status, tech status, compute ID, image ID
func diskSubresourceSchemaMake() map[string]*schema.Schema {
rets := map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
Description: "Name of this disk.",
},
"size": {
Type: schema.TypeInt,
Required: true,
ValidateFunc: validation.IntAtLeast(1),
Description: "Size of the disk in GB.",
},
"account_id": {
Type: schema.TypeInt,
Computed: true,
ValidateFunc: validation.IntAtLeast(1),
Description: "ID of the account this disk belongs to.",
},
"type": {
Type: schema.TypeString,
Optional: true,
Description: "Type of this disk.",
},
"sep_id": {
Type: schema.TypeString,
Optional: true,
Default: "default",
Description: "ID of the storage end-point provider serving this disk.",
},
"sep_type": {
Type: schema.TypeString,
Optional: true,
Default: "default",
Description: "Type of the storage provider serving this disk.",
},
"pool": {
Type: schema.TypeString,
Optional: true,
Default: "default",
Description: "Pool on the storage where this disk is located.",
},
"image_id": {
Type: schema.TypeInt,
Computed: true,
Description: "ID of the binary Image this disk resource is cloned from (if any).",
},
}
return rets
}

@ -1,331 +0,0 @@
/*
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file contains definitions and code for handling Interface component of Compute schema
*/
package decort
import (
/*
"log"
"strconv"
"strings"
*/
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
)
func interfaceSubresourceSchemaMake() map[string]*schema.Schema {
rets := map[string]*schema.Schema{
"net_id": {
Type: schema.TypeInt,
Computed: true,
Description: "ID of the network entity this interface is connected to.",
},
"net_type": {
Type: schema.TypeString,
Computed: true,
Description: "Type of the network entity this interface is connected to.",
},
"ip_address": {
Type: schema.TypeString,
Computed: true,
Description: "IP addresses assigned to this interface.",
},
"netmask": {
Type: schema.TypeInt,
Computed: true,
Description: "Network mask to be used with this interface.",
},
"mac": {
Type: schema.TypeString,
Computed: true,
Description: "MAC address of this interface.",
},
"default_gw": {
Type: schema.TypeString,
Computed: true,
Description: "Default gateway associated with this interface.",
},
"name": {
Type: schema.TypeString,
Computed: true,
Description: "Interface name.",
},
"connection_id": {
Type: schema.TypeInt,
Computed: true,
Description: "VxLAN or VLAN ID this interface is connected to.",
},
"connection_type": {
Type: schema.TypeString,
Computed: true,
Description: "Type of the segment (VLAN or VxLAN) this interface is connected to.",
},
"qos": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: interfaceQosSubresourceSchemaMake(),
},
Description: "QoS settings for this interface.",
},
}
return rets
}
func interfaceQosSubresourceSchemaMake() map[string]*schema.Schema {
rets := map[string]*schema.Schema{
"egress_rate": {
Type: schema.TypeInt,
Computed: true,
Description: "Egress rate limit on this interface.",
},
"ingress_burst": {
Type: schema.TypeInt,
Computed: true,
Description: "Ingress burst limit on this interface.",
},
"ingress_rate": {
Type: schema.TypeInt,
Computed: true,
Description: "Ingress rate limit on this interface.",
},
"guid": {
Type: schema.TypeString,
Computed: true,
Description: "GUID of this QoS record.",
},
}
return rets
}
/*
func flattenNetworks(nets []NicRecord) []interface{} {
// this function expects an array of NicRecord as returned by machines/get API call
// NOTE: it does NOT expect a strucutre as returned by externalnetwork/list
var length = 0
var strarray []string
for _, value := range nets {
if value.NicType == "PUBLIC" {
length += 1
}
}
log.Debugf("flattenNetworks: found %d NICs with PUBLIC type", length)
result := make([]interface{}, length)
if length == 0 {
return result
}
elem := make(map[string]interface{})
var subindex = 0
for index, value := range nets {
if value.NicType == "PUBLIC" {
// this will be changed as network segments entity
// value.Params for ext net comes in a form "gateway:176.118.165.1 externalnetworkId:6"
// for network_id we need to extract from this string
strarray = strings.Split(value.Params, " ")
substr := strings.Split(strarray[1], ":")
elem["network_id"], _ = strconv.Atoi(substr[1])
elem["ip_range"] = value.IPAddress
// elem["label"] = ... - should be uncommented for the future release
log.Debugf("flattenNetworks: parsed element %d - network_id %d, ip_range %s",
index, elem["network_id"].(int), value.IPAddress)
result[subindex] = elem
subindex += 1
}
}
return result
}
func makePortforwardsConfig(arg_list []interface{}) (pfws []PortforwardConfig, count int) {
count = len(arg_list)
if count < 1 {
return nil, 0
}
pfws = make([]PortforwardConfig, count)
var subres_data map[string]interface{}
for index, value := range arg_list {
subres_data = value.(map[string]interface{})
// pfws[index].Label = subres_data["label"].(string) - should be uncommented for future release
pfws[index].ExtPort = subres_data["ext_port"].(int)
pfws[index].IntPort = subres_data["int_port"].(int)
pfws[index].Proto = subres_data["proto"].(string)
}
return pfws, count
}
func flattenPortforwards(pfws []PortforwardRecord) []interface{} {
result := make([]interface{}, len(pfws))
elem := make(map[string]interface{})
var port_num int
for index, value := range pfws {
// elem["label"] = ... - should be uncommented for the future release
// external port field is of TypeInt in the portforwardSubresourceSchema, but string is returned
// by portforwards/list API, so we need conversion here
port_num, _ = strconv.Atoi(value.ExtPort)
elem["ext_port"] = port_num
// internal port field is of TypeInt in the portforwardSubresourceSchema, but string is returned
// by portforwards/list API, so we need conversion here
port_num, _ = strconv.Atoi(value.IntPort)
elem["int_port"] = port_num
elem["proto"] = value.Proto
elem["ext_ip"] = value.ExtIP
elem["int_ip"] = value.IntIP
result[index] = elem
}
return result
}
func portforwardSubresourceSchema() map[string]*schema.Schema {
rets := map[string]*schema.Schema{
"label": {
Type: schema.TypeString,
Required: true,
Description: "Unique label of this network connection to identify it amnong other connections for this VM.",
},
"ext_port": {
Type: schema.TypeInt,
Required: true,
ValidateFunc: validation.IntBetween(1, 65535),
Description: "External port number for this port forwarding rule.",
},
"int_port": {
Type: schema.TypeInt,
Required: true,
ValidateFunc: validation.IntBetween(1, 65535),
Description: "Internal port number for this port forwarding rule.",
},
"proto": {
Type: schema.TypeString,
Required: true,
// ValidateFunc: validation.IntBetween(1, ),
Description: "Protocol type for this port forwarding rule. Should be either 'tcp' or 'udp'.",
},
"ext_ip": {
Type: schema.TypeString,
Computed: true,
Description: ".",
},
"int_ip": {
Type: schema.TypeString,
Computed: true,
Description: ".",
},
}
return rets
}
func flattenNICs(nics []NicRecord) []interface{} {
var result = make([]interface{}, len(nics))
elem := make(map[string]interface{})
for index, value := range nics {
elem["status"] = value.Status
elem["type"] = value.NicType
elem["mac"] = value.MacAddress
elem["ip_address"] = value.IPAddress
elem["parameters"] = value.Params
elem["reference_id"] = value.ReferenceID
elem["network_id"] = value.NetworkID
result[index] = elem
}
return result
}
func nicSubresourceSchema() map[string]*schema.Schema {
rets := map[string]*schema.Schema{
"status": {
Type: schema.TypeString,
Computed: true,
Description: "Current status of this NIC.",
},
"type": {
Type: schema.TypeString,
Computed: true,
Description: "Type of this NIC.",
},
"mac": {
Type: schema.TypeString,
Computed: true,
Description: "MAC address assigned to this NIC.",
},
"ip_address": {
Type: schema.TypeString,
Computed: true,
Description: "IP address assigned to this NIC.",
},
"parameters": {
Type: schema.TypeString,
Computed: true,
Description: "Additional NIC parameters.",
},
"reference_id": {
Type: schema.TypeString,
Computed: true,
Description: "Reference ID of this NIC.",
},
"network_id": {
Type: schema.TypeInt,
Computed: true,
Description: "Network ID which this NIC is connected to.",
},
}
return rets
}
*/

@ -51,33 +51,49 @@ type UserAclRecord struct {
} }
type AccountAclRecord struct { type AccountAclRecord struct {
IsExplicit bool `json:"explicit"` IsExplicit bool `json:"explicit"`
Guid string `json:"guid"` Guid string `json:"guid"`
Rights string `json:"right"` Rights string `json:"right"`
Status string `json:"status"` Status string `json:"status"`
Type string `json:"type"` Type string `json:"type"`
UgroupID string `json:"userGroupId"` UgroupID string `json:"userGroupId"`
CanBeDeleted bool `json:"canBeDeleted"`
}
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 { type ResgroupRecord struct {
ACLs []UserAclRecord `json:"acl"` ACLs []AccountAclRecord `json:"acl"`
Owner AccountAclRecord `json:"accountAcl"` AccountID int `json:"accountId"`
AccountID int `json:"accountId"` AccountName string `json:"accountName"`
AccountName string `json:"accountName"` CreatedBy string `json:"createdBy"`
CreatedBy string `json:"createdBy"` CreatedTime uint64 `json:"createdTime"`
CreatedTime uint64 `json:"createdTime"` DefaultNetID int `json:"def_net_id"`
DefaultNetID int `json:"def_net_id"` DefaultNetType string `json:"def_net_type"`
DefaultNetType string `json:"def_net_type"` DeletedBy string `json:"deletedBy"`
Decsription string `json:"desc"` DeletedTime int `json:"deletedTime"`
GridID int `json:"gid"` Decsription string `json:"desc"`
ID uint `json:"id"` GridID int `json:"gid"`
LockStatus string `json:"lockStatus"` GUID int `json:"guid"`
Name string `json:"name"` ID uint `json:"id"`
Status string `json:"status"` LockStatus string `json:"lockStatus"`
UpdatedBy string `json:"updatedBy"` Milestones int `json:"milestones"`
UpdatedTime uint64 `json:"updatedTime"` Name string `json:"name"`
Vins []int `json:"vins"` RegisterComputes bool `json:"registerComputes"`
Computes []int `json:"vms"` 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"`
} }
const ResgroupListAPI = "/restmachine/cloudapi/rg/list" const ResgroupListAPI = "/restmachine/cloudapi/rg/list"
@ -298,46 +314,62 @@ const ComputeResizeAPI = "/restmachine/cloudapi/compute/resize"
type SnapshotRecord struct { type SnapshotRecord struct {
Guid string `json:"guid"` Guid string `json:"guid"`
Label string `json:"label"` Label string `json:"label"`
ResId string `json:"resId"`
SnapSetGuid string `json:"snapSetGuid"` SnapSetGuid string `json:"snapSetGuid"`
SnapSetTime uint64 `json:"snapSetTime"` SnapSetTime uint64 `json:"snapSetTime"`
TimeStamp uint64 `json:"timestamp"` TimeStamp uint64 `json:"timestamp"`
} }
type SnapshotRecordList []SnapshotRecord
type DiskRecord struct { type DiskRecord struct {
// ACLs `json:"ACL"` - it is a dictionary, special parsing required Acl map[string]interface{} `json:"acl"`
// was - Acl map[string]string `json:"acl"` AccountID int `json:"accountId"`
AccountID int `json:"accountId"` AccountName string `json:"accountName"`
AccountName string `json:"accountName"` // NOTE: absent from compute/get output BootPartition int `json:"bootPartition"`
BootPartition int `json:"bootPartition"` CreatedTime uint64 `json:"creationTime"`
CreatedTime uint64 `json:"creationTime"` ComputeID int `json:"computeId"`
DeletedTime uint64 `json:"deletionTime"` ComputeName string `json:"computeName"`
Desc string `json:"desc"` DeletedTime uint64 `json:"deletionTime"`
DestructionTime uint64 `json:"destructionTime"` DeviceName string `json:"devicename"`
DiskPath string `json:"diskPath"` Desc string `json:"desc"`
GridID int `json:"gid"` DestructionTime uint64 `json:"destructionTime"`
ID uint `json:"id"` DiskPath string `json:"diskPath"`
ImageID int `json:"imageId"` GridID int `json:"gid"`
Images []int `json:"images"` GUID int `json:"guid"`
// IOTune 'json:"iotune" - it is a dictionary ID uint `json:"id"`
Name string `json:"name"` ImageID int `json:"imageId"`
// Order `json:"order"` Images []int `json:"images"`
ParentId int `json:"parentId"` IOTune map[string]interface{} `json:"iotune"`
PciSlot int `json:"pciSlot"` IQN string `json:"iqn"`
// ResID string `json:"resId"` Login string `json:"login"`
// ResName string `json:"resName"` Name string `json:"name"`
// Params string `json:"params"` MachineId int `json:"machineId"`
Pool string `json:"pool"` MachineName string `json:"machineName"`
PurgeTime uint64 `json:"purgeTime"` Milestones uint64 `json:"milestones"`
// Role string `json:"role"` Order int `json:"order"`
SepType string `json:"sepType"` Params string `json:"params"`
SepID int `json:"sepId"` // NOTE: absent from compute/get output Passwd string `json:"passwd"`
SizeMax int `json:"sizeMax"` ParentId int `json:"parentId"`
SizeUsed int `json:"sizeUsed"` // sum over all snapshots of this disk to report total consumed space PciSlot int `json:"pciSlot"`
Snapshots []SnapshotRecord `json:"snapshots"` Pool string `json:"pool"`
Status string `json:"status"` PurgeTime uint64 `json:"purgeTime"`
TechStatus string `json:"techStatus"` PurgeAttempts uint64 `json:"purgeAttempts"`
Type string `json:"type"` RealityDeviceNumber int `json:"realityDeviceNumber"`
ComputeID int `json:"vmid"` 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 OsUserRecord struct { type OsUserRecord struct {
@ -502,6 +534,7 @@ const DisksCreateAPI = "/restmachine/cloudapi/disks/create"
const DisksGetAPI = "/restmachine/cloudapi/disks/get" // Returns single DiskRecord on success const DisksGetAPI = "/restmachine/cloudapi/disks/get" // Returns single DiskRecord on success
const DisksListAPI = "/restmachine/cloudapi/disks/list" // Returns list of DiskRecord on success const DisksListAPI = "/restmachine/cloudapi/disks/list" // Returns list of DiskRecord on success
type DisksListResp []DiskRecord type DisksListResp []DiskRecord
// //
@ -955,3 +988,499 @@ type SepConfig map[string]interface{}
type SepList []Sep type SepList []Sep
type SepPool map[string]interface{} type SepPool map[string]interface{}
///////////////////////
///// ACCOUNTS ////
///////////////////////
const accountAddUserAPI = "/restmachine/cloudapi/account/addUser"
const accountAuditsAPI = "/restmachine/cloudapi/account/audits"
const accountCreateAPI = "/restmachine/cloudapi/account/create"
const accountDeleteAPI = "/restmachine/cloudapi/account/delete"
const accountDeleteUserAPI = "/restmachine/cloudapi/account/deleteUser"
const accountDisableAPI = "/restmachine/cloudapi/account/disable"
const accountEnableAPI = "/restmachine/cloudapi/account/enable"
const accountGetAPI = "/restmachine/cloudapi/account/get"
const accountGetConsumedUnitsAPI = "/restmachine/cloudapi/account/getConsumedAccountUnits"
const accountGetConsumedUnitsByTypeAPI = "/restmachine/cloudapi/account/getConsumedCloudUnitsByType"
const accountGetReservedUnitsAPI = "/restmachine/cloudapi/account/getReservedAccountUnits"
const accountListAPI = "/restmachine/cloudapi/account/list"
const accountListComputesAPI = "/restmachine/cloudapi/account/listComputes"
const accountListDeletedAPI = "/restmachine/cloudapi/account/listDeleted"
const accountListDisksAPI = "/restmachine/cloudapi/account/listDisks"
const accountListFlipGroupsAPI = "/restmachine/cloudapi/account/listFlipGroups"
const accountListRGAPI = "/restmachine/cloudapi/account/listRG"
const accountListTemplatesAPI = "/restmachine/cloudapi/account/listTemplates"
const accountListVinsAPI = "/restmachine/cloudapi/account/listVins"
const accountRestoreAPI = "/restmachine/cloudapi/account/restore"
const accountUpdateAPI = "/restmachine/cloudapi/account/update"
const accountUpdateUserAPI = "/restmachine/cloudapi/account/updateUser"
////Structs
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 AccountCloudApi struct {
Acl []AccountAclRecord `json:"acl"`
CreatedTime int `json:"createdTime"`
DeletedTime int `json:"deletedTime"`
ID int `json:"id"`
Name string `json:"name"`
Status string `json:"status"`
UpdatedTime int `json:"updatedTime"`
}
type AccountCloudApiList []AccountCloudApi
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 Computes struct {
Started int `json:"started"`
Stopped int `json:"stopped"`
}
type Machines struct {
Running int `json:"running"`
Halted int `json:"halted"`
}
type AccountWithResources struct {
Account
Resources Resources `json:"Resources"`
Computes Computes `json:"computes"`
Machines Machines `json:"machines"`
Vinses int `json:"vinses"`
}
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 AccountTemplate struct {
UNCPath string `json:"UNCPath"`
AccountId int `json:"accountId"`
Desc string `json:"desc"`
ID int `json:"id"`
Name string `json:"name"`
Public bool `json:"public"`
Size int `json:"size"`
Status string `json:"status"`
Type string `json:"type"`
Username string `json:"username"`
}
type AccountTemplatesList []AccountTemplate
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
////////////////////
//// BSERVICE ////
////////////////////
const bserviceCreateAPI = "/restmachine/cloudapi/bservice/create"
const bserviceDeleteAPI = "/restmachine/cloudapi/bservice/delete"
const bserviceDisableAPI = "/restmachine/cloudapi/bservice/disable"
const bserviceEnableAPI = "/restmachine/cloudapi/bservice/enable"
const bserviceGetAPI = "/restmachine/cloudapi/bservice/get"
const bserviceGroupAddAPI = "/restmachine/cloudapi/bservice/groupAdd"
const bserviceGroupComputeRemoveAPI = "/restmachine/cloudapi/bservice/groupComputeRemove"
const bserviceGroupGetAPI = "/restmachine/cloudapi/bservice/groupGet"
const bserviceGroupParentAddAPI = "/restmachine/cloudapi/bservice/groupParentAdd"
const bserviceGroupParentRemoveAPI = "/restmachine/cloudapi/bservice/groupParentRemove"
const bserviceGroupRemoveAPI = "/restmachine/cloudapi/bservice/groupRemove"
const bserviceGroupResizeAPI = "/restmachine/cloudapi/bservice/groupResize"
const bserviceGroupStartAPI = "/restmachine/cloudapi/bservice/groupStart"
const bserviceGroupStopAPI = "/restmachine/cloudapi/bservice/groupStop"
const bserviceGroupUpdateAPI = "/restmachine/cloudapi/bservice/groupUpdate"
const bserviceGroupUpdateExtnetAPI = "/restmachine/cloudapi/bservice/groupUpdateExtnet"
const bserviceGroupUpdateVinsAPI = "/restmachine/cloudapi/bservice/groupUpdateVins"
const bserviceListAPI = "/restmachine/cloudapi/bservice/list"
const bserviceListDeletedAPI = "/restmachine/cloudapi/bservice/listDeleted"
const bserviceRestoreAPI = "/restmachine/cloudapi/bservice/restore"
const bserviceSnapshotCreateAPI = "/restmachine/cloudapi/bservice/snapshotCreate"
const bserviceSnapshotDeleteAPI = "/restmachine/cloudapi/bservice/snapshotDelete"
const bserviceSnapshotListAPI = "/restmachine/cloudapi/bservice/snapshotList"
const bserviceSnapshotRollbackAPI = "/restmachine/cloudapi/bservice/snapshotRollback"
const bserviceStartAPI = "/restmachine/cloudapi/bservice/start"
const bserviceStopAPI = "/restmachine/cloudapi/bservice/stop"
///Structs
type BasicServiceCompute struct {
CompGroupId int `json:"compgroupId"`
CompGroupName string `json:"compgroupName"`
CompGroupRole string `json:"compgroupRole"`
ID int `json:"id"`
Name string `json:"name"`
}
type BasicServiceComputes []BasicServiceCompute
type BasicServiceSnapshot struct {
GUID string `json:"guid"`
Label string `json:"label"`
Timestamp int `json:"timestamp"`
Valid bool `json:"valid"`
}
type BasicServiceSnapshots []BasicServiceSnapshot
type BasicService struct {
AccountId int `json:"accountId"`
AccountName string `json:"accountName"`
BaseDomain string `json:"baseDomain"`
CreatedBy string `json:"createdBy"`
CreatedTime int `json:"createdTime"`
DeletedBy string `json:"deletedBy"`
DeletedTime int `json:"deletedTime"`
GID int `json:"gid"`
Groups []int `json:"groups"`
GUID int `json:"guid"`
ID int `json:"id"`
Name string `json:"name"`
ParentSrvId int `json:"parentSrvId"`
ParentSrvType string `json:"parentSrvType"`
RGID int `json:"rgId"`
RGName string `json:"rgName"`
SSHUser string `json:"sshUser"`
Status string `json:"status"`
TechStatus string `json:"techStatus"`
UpdatedBy string `json:"updatedBy"`
UpdatedTime int `json:"updatedTime"`
UserManaged bool `json:"userManaged"`
}
type BasicServiceList []BasicService
type BasicServiceExtend struct {
BasicService
Computes BasicServiceComputes `json:"computes"`
CPUTotal int `json:"cpuTotal"`
DiskTotal int `json:"diskTotal"`
GroupsName []string `json:"groupsName"`
Milestones int `json:"milestones"`
RamTotal int `json:"ramTotal"`
Snapshots BasicServiceSnapshots `json:"snapshots"`
SSHKey string `json:"sshKey"`
}
type BasicServiceGroupOSUser struct {
Login string `json:"login"`
Password string `json:"password"`
}
type BasicServiceGroupOSUsers []BasicServiceGroupOSUser
type BasicServicceGroupCompute struct {
ID int `json:"id"`
IPAdresses []string `json:"ipAddresses"`
Name string `json:"name"`
OSUsers BasicServiceGroupOSUsers `json:"osUsers"`
}
type BasicServiceGroupComputes []BasicServicceGroupCompute
type BasicServiceGroup struct {
AccountId int `json:"accountId"`
AccountName string `json:"accountName"`
Computes BasicServiceGroupComputes `json:"computes"`
Consistency bool `json:"consistency"`
CPU int `json:"cpu"`
CreatedBy string `json:"createdBy"`
CreatedTime int `json:"createdTime"`
DeletedBy string `json:"deletedBy"`
DeletedTime int `json:"deletedTime"`
Disk int `json:"disk"`
Driver string `json:"driver"`
Extnets []int `json:"extnets"`
GID int `json:"gid"`
GUID int `json:"guid"`
ID int `json:"id"`
ImageId int `json:"imageId"`
Milestones int `json:"milestones"`
Name string `json:"name"`
Parents []int `json:"parents"`
RAM int `json:"ram"`
RGID int `json:"rgId"`
RGName string `json:"rgName"`
Role string `json:"role"`
SepId int `json:"sepId"`
SeqNo int `json:"seqNo"`
ServiceId int `json:"serviceId"`
Status string `json:"status"`
TechStatus string `json:"techStatus"`
TimeoutStart int `json:"timeoutStart"`
UpdatedBy string `json:"updatedBy"`
UpdatedTime int `json:"updatedTime"`
Vinses []int `json:"vinses"`
}
///////////////////
///// EXTNET /////
///////////////////
const extnetListAPI = "/restmachine/cloudapi/extnet/list"
const extnetListComputesAPI = "/restmachine/cloudapi/extnet/listComputes"
const extnetGetDefaultAPI = "/restmachine/cloudapi/extnet/getDefault"
const extnetGetAPI = "/restmachine/cloudapi/extnet/get"
type Extnet struct {
ID int `json:"id"`
IPCidr string `json:"ipcidr"`
Name string `json:"name"`
}
type ExtnetExtend struct {
Extnet
IPAddr string `json:"ipaddr"`
}
type ExtnetList []Extnet
type ExtnetExtendList []ExtnetExtend
type ExtnetComputes struct {
AccountId int `json:"accountId"`
AccountName string `json:"accountName"`
Extnets ExtnetExtendList `json:"extnets"`
ID int `json:"id"`
Name string `json:"name"`
RGID int `json:"rgId"`
RGName string `json:"rgName"`
}
type ExtnetComputesList []ExtnetComputes
type ExtnetQos struct {
ERate int `json:"eRate"`
GUID string `json:"guid"`
InBurst int `json:"inBurst"`
InRate int `json:"inRate"`
}
type ExtnetReservation struct {
ClientType string `json:"clientType"`
Desc string `json:"desc"`
DomainName string `json:"domainname"`
HostName string `json:"hostname"`
IP string `json:"ip"`
MAC string `json:"mac"`
Type string `json:"type"`
VMID int `json:"vmId"`
}
type ExtnetReservations []ExtnetReservation
type ExtnetVNFS struct {
DHCP int `json:"dhcp"`
}
type ExtnetDetailed struct {
CKey string `json:"_ckey"`
Meta []interface{} `json:"_meta"`
CheckIPs []string `json:"checkIPs"`
CheckIps []string `json:"checkIps"`
Default bool `json:"default"`
DefaultQos ExtnetQos `json:"defaultQos"`
Desc string `json:"desc"`
Dns []string `json:"dns"`
Excluded []string `json:"excluded"`
FreeIps int `json:"free_ips"`
Gateway string `json:"gateway"`
GID int `json:"gid"`
GUID int `json:"guid"`
ID int `json:"id"`
IPCidr string `json:"ipcidr"`
Milestones int `json:"milestones"`
Name string `json:"name"`
Network string `json:"network"`
NetworkId int `json:"networkId"`
PreReservationsNum int `json:"preReservationsNum"`
Prefix int `json:"prefix"`
PriVnfDevId int `json:"priVnfDevId"`
Reservations ExtnetReservations `json:"reservations"`
SharedWith []int `json:"sharedWith"`
Status string `json:"status"`
VlanID int `json:"vlanId"`
VNFS ExtnetVNFS `json:"vnfs"`
}
//////////////
//// VINS ////
//////////////
const vinsListAPI = "/restmachine/cloudapi/vins/list"
type Vins struct {
AccountId int `json:"accountId"`
AccountName string `json:"accountName"`
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"`
RGID int `json:"rgId"`
RGName string `json:"rgName"`
Status string `json:"status"`
UpdatedBy string `json:"updatedBy"`
UpdatedTime int `json:"updatedTime"`
VXLanID int `json:"vxlanId"`
}
type VinsList []Vins

@ -23,7 +23,9 @@ import (
// "fmt" // "fmt"
"bytes" "bytes"
"hash/fnv" "hash/fnv"
log "github.com/sirupsen/logrus"
log "github.com/sirupsen/logrus"
// "net/url" // "net/url"
"sort" "sort"
@ -43,19 +45,19 @@ func networkSubresIPAddreDiffSupperss(key, oldVal, newVal string, d *schema.Reso
return true // suppress difference return true // suppress difference
} }
// This function is based on the original Terraform SerializeResourceForHash found // This function is based on the original Terraform SerializeResourceForHash found
// in helper/schema/serialize.go // in helper/schema/serialize.go
// It skips network subresource attributes, which are irrelevant for identification // It skips network subresource attributes, which are irrelevant for identification
// of unique network blocks // of unique network blocks
func networkSubresourceSerialize(output *bytes.Buffer, val interface{}, resource *schema.Resource) { func networkSubresourceSerialize(output *bytes.Buffer, val interface{}, resource *schema.Resource) {
if val == nil { if val == nil {
return return
} }
rs := resource.Schema rs := resource.Schema
m := val.(map[string]interface{}) m := val.(map[string]interface{})
var keys []string keys := make([]string, 0, len(rs))
allComputed := true allComputed := true
for k, val := range rs { for k, val := range rs {
@ -96,7 +98,7 @@ func networkSubresourceSerialize(output *bytes.Buffer, val interface{}, resource
// from network subresource (e.g. in flattenCompute) // from network subresource (e.g. in flattenCompute)
// //
// This function is based on the original Terraform function HashResource from // This function is based on the original Terraform function HashResource from
// helper/schema/set.go // helper/schema/set.go
func HashNetworkSubresource(resource *schema.Resource) schema.SchemaSetFunc { func HashNetworkSubresource(resource *schema.Resource) schema.SchemaSetFunc {
return func(v interface{}) int { return func(v interface{}) int {
var serialized bytes.Buffer var serialized bytes.Buffer
@ -111,11 +113,11 @@ func HashNetworkSubresource(resource *schema.Resource) schema.SchemaSetFunc {
func networkSubresourceSchemaMake() map[string]*schema.Schema { func networkSubresourceSchemaMake() map[string]*schema.Schema {
rets := map[string]*schema.Schema{ rets := map[string]*schema.Schema{
"net_type": { "net_type": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
StateFunc: stateFuncToUpper, StateFunc: stateFuncToUpper,
ValidateFunc: validation.StringInSlice([]string{"EXTNET", "VINS"}, false), // observe case while validating ValidateFunc: validation.StringInSlice([]string{"EXTNET", "VINS"}, false), // observe case while validating
Description: "Type of the network for this connection, either EXTNET or VINS.", Description: "Type of the network for this connection, either EXTNET or VINS.",
}, },
"net_id": { "net_id": {
@ -125,11 +127,11 @@ func networkSubresourceSchemaMake() map[string]*schema.Schema {
}, },
"ip_address": { "ip_address": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
DiffSuppressFunc: networkSubresIPAddreDiffSupperss, DiffSuppressFunc: networkSubresIPAddreDiffSupperss,
Description: "Optional IP address to assign to this connection. This IP should belong to the selected network and free for use.", Description: "Optional IP address to assign to this connection. This IP should belong to the selected network and free for use.",
}, },
"mac": { "mac": {
@ -137,7 +139,6 @@ func networkSubresourceSchemaMake() map[string]*schema.Schema {
Computed: true, Computed: true,
Description: "MAC address associated with this connection. MAC address is assigned automatically.", Description: "MAC address associated with this connection. MAC address is assigned automatically.",
}, },
} }
return rets return rets
} }

@ -26,8 +26,6 @@ import (
// "github.com/hashicorp/terraform-plugin-sdk/terraform" // "github.com/hashicorp/terraform-plugin-sdk/terraform"
) )
var decsController *ControllerCfg
func Provider() *schema.Provider { func Provider() *schema.Provider {
return &schema.Provider{ return &schema.Provider{
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
@ -99,44 +97,71 @@ func Provider() *schema.Provider {
}, },
ResourcesMap: map[string]*schema.Resource{ ResourcesMap: map[string]*schema.Resource{
"decort_resgroup": resourceResgroup(), "decort_resgroup": resourceResgroup(),
"decort_kvmvm": resourceCompute(), "decort_kvmvm": resourceCompute(),
"decort_disk": resourceDisk(), "decort_disk": resourceDisk(),
"decort_vins": resourceVins(), "decort_vins": resourceVins(),
"decort_pfw": resourcePfw(), "decort_pfw": resourcePfw(),
"decort_k8s": resourceK8s(), "decort_k8s": resourceK8s(),
"decort_k8s_wg": resourceK8sWg(), "decort_k8s_wg": resourceK8sWg(),
"decort_image": resourceImage(), "decort_image": resourceImage(),
"decort_virtual_image": resourceVirtualImage(), "decort_virtual_image": resourceVirtualImage(),
"decort_cdrom_image": resourceCDROMImage(), "decort_cdrom_image": resourceCDROMImage(),
"decort_delete_images": resourceDeleteImages(), "decort_delete_images": resourceDeleteImages(),
"decort_snapshot": resourceSnapshot(), "decort_snapshot": resourceSnapshot(),
"decort_pcidevice": resourcePcidevice(), "decort_pcidevice": resourcePcidevice(),
"decort_sep": resourceSep(), "decort_sep": resourceSep(),
"decort_sep_config": resourceSepConfig(), "decort_sep_config": resourceSepConfig(),
"decort_account": resourceAccount(),
"decort_bservice": resourceBasicService(),
"decort_bservice_group": resourceBasicServiceGroup(),
}, },
DataSourcesMap: map[string]*schema.Resource{ DataSourcesMap: map[string]*schema.Resource{
"decort_account": dataSourceAccount(), "decort_account": dataSourceAccount(),
"decort_resgroup": dataSourceResgroup(), "decort_resgroup": dataSourceResgroup(),
"decort_kvmvm": dataSourceCompute(), "decort_kvmvm": dataSourceCompute(),
"decort_image": dataSourceImage(), "decort_image": dataSourceImage(),
"decort_disk": dataSourceDisk(), "decort_disk": dataSourceDisk(),
"decort_vins": dataSourceVins(), "decort_vins": dataSourceVins(),
"decort_grid": dataSourceGrid(), "decort_grid": dataSourceGrid(),
"decort_grid_list": dataSourceGridList(), "decort_grid_list": dataSourceGridList(),
"decort_image_list": dataSourceImageList(), "decort_image_list": dataSourceImageList(),
"decort_image_list_stacks": dataSourceImageListStacks(), "decort_image_list_stacks": dataSourceImageListStacks(),
"decort_snapshot_list": dataSourceSnapshotList(), "decort_snapshot_list": dataSourceSnapshotList(),
"decort_vgpu": dataSourceVGPU(), "decort_vgpu": dataSourceVGPU(),
"decort_pcidevice": dataSourcePcidevice(), "decort_pcidevice": dataSourcePcidevice(),
"decort_pcidevice_list": dataSourcePcideviceList(), "decort_pcidevice_list": dataSourcePcideviceList(),
"decort_sep_list": dataSourceSepList(), "decort_sep_list": dataSourceSepList(),
"decort_sep": dataSourceSep(), "decort_sep": dataSourceSep(),
"decort_sep_consumption": dataSourceSepConsumption(), "decort_sep_consumption": dataSourceSepConsumption(),
"decort_sep_disk_list": dataSourceSepDiskList(), "decort_sep_disk_list": dataSourceSepDiskList(),
"decort_sep_config": dataSourceSepConfig(), "decort_sep_config": dataSourceSepConfig(),
"decort_sep_pool": dataSourceSepPool(), "decort_sep_pool": dataSourceSepPool(),
"decort_disk_list": dataSourceDiskList(),
"decort_rg_list": dataSourceRgList(),
"decort_account_list": dataSourceAccountList(),
"decort_account_computes_list": dataSourceAccountComputesList(),
"decort_account_disks_list": dataSourceAccountDisksList(),
"decort_account_vins_list": dataSourceAccountVinsList(),
"decort_account_audits_list": dataSourceAccountAuditsList(),
"decort_account_rg_list": dataSourceAccountRGList(),
"decort_account_consumed_units": dataSourceAccountConsumedUnits(),
"decort_account_consumed_units_by_type": dataSourceAccountConsumedUnitsByType(),
"decort_account_reserved_units": dataSourceAccountReservedUnits(),
"decort_account_templates_list": dataSourceAccountTemplatessList(),
"decort_account_deleted_list": dataSourceAccountDeletedList(),
"decort_account_flipgroups_list": dataSourceAccountFlipGroupsList(),
"decort_bservice_list": dataSourceBasicServiceList(),
"decort_bservice": dataSourceBasicService(),
"decort_bservice_snapshot_list": dataSourceBasicServiceSnapshotList(),
"decort_bservice_group": dataSourceBasicServiceGroup(),
"decort_bservice_deleted_list": dataSourceBasicServiceDeletedList(),
"decort_extnet_list": dataSourceExtnetList(),
"decort_extnet_computes_list": dataSourceExtnetComputesList(),
"decort_extnet": dataSourceExtnet(),
"decort_extnet_default": dataSourceExtnetDefault(),
"decort_vins_list": dataSourceVinsList(),
// "decort_pfw": dataSourcePfw(), // "decort_pfw": dataSourcePfw(),
}, },

@ -28,7 +28,7 @@ import (
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation" // "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
) )
func makeQuotaRecord(arg_list []interface{}) (QuotaRecord, int) { func makeQuotaRecord(arg_list []interface{}) QuotaRecord {
quota := QuotaRecord{ quota := QuotaRecord{
Cpu: -1, Cpu: -1,
Ram: -1., // this is float64, but may change in the future Ram: -1., // this is float64, but may change in the future
@ -63,7 +63,7 @@ func makeQuotaRecord(arg_list []interface{}) (QuotaRecord, int) {
quota.GpuUnits = subres_data["gpu_units"].(int) quota.GpuUnits = subres_data["gpu_units"].(int)
} }
return quota, 1 return quota
} }
func parseQuota(quota QuotaRecord) []interface{} { func parseQuota(quota QuotaRecord) []interface{} {

@ -0,0 +1,794 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"errors"
"net/url"
"strconv"
"strings"
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
log "github.com/sirupsen/logrus"
)
func resourceAccountCreate(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceAccountCreate")
if accountId, ok := d.GetOk("account_id"); ok {
if exists, err := resourceAccountExists(d, m); exists {
if err != nil {
return err
}
d.SetId(strconv.Itoa(accountId.(int)))
err = resourceAccountRead(d, m)
if err != nil {
return err
}
return nil
}
return errors.New("provided account id does not exist")
}
controller := m.(*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 := controller.decortAPICall("POST", accountCreateAPI, urlValues)
if err != nil {
return err
}
id := uuid.New()
d.SetId(accountId)
d.Set("account_id", accountId)
err = resourceAccountRead(d, m)
if err != nil {
return err
}
d.SetId(id.String())
return nil
}
func resourceAccountRead(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceAccountRead")
acc, err := utilityAccountCheckPresence(d, m)
if acc == nil {
d.SetId("")
return err
}
d.Set("dc_location", acc.DCLocation)
d.Set("resources", flattenAccResources(acc.Resources))
d.Set("ckey", acc.CKey)
d.Set("meta", 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)
d.Set("vinses", acc.Vinses)
d.Set("computes", flattenAccComputes(acc.Computes))
d.Set("machines", flattenAccMachines(acc.Machines))
return nil
}
func resourceAccountDelete(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceAccountDelete")
account, err := utilityAccountCheckPresence(d, m)
if account == nil {
if err != nil {
return err
}
return nil
}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
urlValues.Add("permanently", strconv.FormatBool(d.Get("permanently").(bool)))
_, err = controller.decortAPICall("POST", accountDeleteAPI, urlValues)
if err != nil {
return err
}
d.SetId("")
return nil
}
func resourceAccountExists(d *schema.ResourceData, m interface{}) (bool, error) {
log.Debugf("resourceAccountExists")
account, err := utilityAccountCheckPresence(d, m)
if account == nil {
if err != nil {
return false, err
}
return false, nil
}
return true, nil
}
func resourceAccountEdit(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceAccountEdit")
c := m.(*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("POST", api, urlValues)
if err != nil {
return 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("POST", accountUpdateAPI, urlValues)
if err != nil {
return 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("POST", accountUpdateAPI, urlValues)
if err != nil {
return 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("POST", accountUpdateAPI, urlValues)
if err != nil {
return 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("POST", accountRestoreAPI, urlValues)
if err != nil {
return 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("POST", accountDeleteUserAPI, urlValues)
if err != nil {
return 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("POST", accountAddUserAPI, urlValues)
if err != nil {
return 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("POST", accountUpdateUserAPI, urlValues)
if err != nil {
return 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 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,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"current": {
Type: schema.TypeList,
Computed: true,
MaxItems: 1,
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,
MaxItems: 1,
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{
"can_be_deleted": {
Type: schema.TypeBool,
Computed: true,
},
"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,
},
},
"computes": {
Type: schema.TypeList,
Computed: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"started": {
Type: schema.TypeInt,
Computed: true,
},
"stopped": {
Type: schema.TypeInt,
Computed: true,
},
},
},
},
"machines": {
Type: schema.TypeList,
Computed: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"halted": {
Type: schema.TypeInt,
Computed: true,
},
"running": {
Type: schema.TypeInt,
Computed: true,
},
},
},
},
"vinses": {
Type: schema.TypeInt,
Computed: true,
},
}
}
func resourceAccount() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Create: resourceAccountCreate,
Read: resourceAccountRead,
Update: resourceAccountEdit,
Delete: resourceAccountDelete,
Exists: resourceAccountExists,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Timeouts: &schema.ResourceTimeout{
Create: &Timeout60s,
Read: &Timeout30s,
Update: &Timeout60s,
Delete: &Timeout60s,
Default: &Timeout60s,
},
Schema: resourceAccountSchemaMake(),
}
}

@ -0,0 +1,554 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"errors"
"net/url"
"strconv"
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
log "github.com/sirupsen/logrus"
)
func resourceBasicServiceCreate(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceBasicServiceCreate")
if serviceId, ok := d.GetOk("service_id"); ok {
if exists, err := resourceBasicServiceExists(d, m); exists {
if err != nil {
return err
}
id := uuid.New()
d.SetId(strconv.Itoa(serviceId.(int)))
d.Set("service_id", strconv.Itoa(serviceId.(int)))
err = resourceBasicServiceRead(d, m)
if err != nil {
return err
}
d.SetId(id.String())
return nil
}
return errors.New("provided service id does not exist")
}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("name", d.Get("service_name").(string))
urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int)))
if sshKey, ok := d.GetOk("ssh_key"); ok {
urlValues.Add("sshKey", sshKey.(string))
}
if sshUser, ok := d.GetOk("ssh_user"); ok {
urlValues.Add("sshUser", sshUser.(string))
}
serviceId, err := controller.decortAPICall("POST", bserviceCreateAPI, urlValues)
if err != nil {
return err
}
id := uuid.New()
d.SetId(serviceId)
d.Set("service_id", serviceId)
err = resourceBasicServiceRead(d, m)
if err != nil {
return err
}
d.SetId(id.String())
return nil
}
func resourceBasicServiceRead(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceBasicServiceRead")
bs, err := utilityBasicServiceCheckPresence(d, m)
if bs == nil {
d.SetId("")
return err
}
d.Set("account_id", bs.AccountId)
d.Set("account_name", bs.AccountName)
d.Set("base_domain", bs.BaseDomain)
d.Set("computes", flattenBasicServiceComputes(bs.Computes))
d.Set("cpu_total", bs.CPUTotal)
d.Set("created_by", bs.CreatedBy)
d.Set("created_time", bs.CreatedTime)
d.Set("deleted_by", bs.DeletedBy)
d.Set("deleted_time", bs.DeletedTime)
d.Set("disk_total", bs.DiskTotal)
d.Set("gid", bs.GID)
d.Set("groups", bs.Groups)
d.Set("groups_name", bs.GroupsName)
d.Set("guid", bs.GUID)
d.Set("milestones", bs.Milestones)
d.Set("service_name", bs.Name)
d.Set("service_id", bs.ID)
d.Set("parent_srv_id", bs.ParentSrvId)
d.Set("parent_srv_type", bs.ParentSrvType)
d.Set("ram_total", bs.RamTotal)
d.Set("rg_id", bs.RGID)
d.Set("rg_name", bs.RGName)
d.Set("snapshots", flattenBasicServiceSnapshots(bs.Snapshots))
d.Set("ssh_key", bs.SSHKey)
d.Set("ssh_user", bs.SSHUser)
d.Set("status", bs.Status)
d.Set("tech_status", bs.TechStatus)
d.Set("updated_by", bs.UpdatedBy)
d.Set("updated_time", bs.UpdatedTime)
d.Set("user_managed", bs.UserManaged)
return nil
}
func resourceBasicServiceDelete(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceBasicServiceDelete")
bs, err := utilityBasicServiceCheckPresence(d, m)
if bs == nil {
if err != nil {
return err
}
return nil
}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
urlValues.Add("permanently", strconv.FormatBool(d.Get("permanently").(bool)))
_, err = controller.decortAPICall("POST", bserviceDeleteAPI, urlValues)
if err != nil {
return err
}
d.SetId("")
return nil
}
func resourceBasicServiceExists(d *schema.ResourceData, m interface{}) (bool, error) {
log.Debugf("resourceBasicServiceExists")
bservice, err := utilityBasicServiceCheckPresence(d, m)
if bservice == nil {
if err != nil {
return false, err
}
return false, nil
}
return true, nil
}
func resourceBasicServiceEdit(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceBasicServiceEdit")
c := m.(*ControllerCfg)
urlValues := &url.Values{}
if d.HasChange("enable") {
api := bserviceDisableAPI
enable := d.Get("enable").(bool)
if enable {
api = bserviceEnableAPI
}
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
_, err := c.decortAPICall("POST", api, urlValues)
if err != nil {
return err
}
urlValues = &url.Values{}
}
if d.HasChange("restore") {
restore := d.Get("restore").(bool)
if restore {
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
_, err := c.decortAPICall("POST", bserviceRestoreAPI, urlValues)
if err != nil {
return err
}
urlValues = &url.Values{}
}
}
if d.HasChange("start") {
api := bserviceStopAPI
start := d.Get("start").(bool)
if start {
api = bserviceStartAPI
}
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
_, err := c.decortAPICall("POST", api, urlValues)
if err != nil {
return err
}
urlValues = &url.Values{}
}
if d.HasChange("snapshots") {
deletedSnapshots := make([]interface{}, 0)
addedSnapshots := make([]interface{}, 0)
updatedSnapshots := make([]interface{}, 0)
old, new := d.GetChange("snapshots")
oldConv := old.([]interface{})
newConv := new.([]interface{})
for _, el := range oldConv {
if !isContainsSnapshot(newConv, el) {
deletedSnapshots = append(deletedSnapshots, el)
}
}
for _, el := range newConv {
if !isContainsSnapshot(oldConv, el) {
addedSnapshots = append(addedSnapshots, el)
} else {
if isRollback(oldConv, el) {
updatedSnapshots = append(updatedSnapshots, el)
}
}
}
if len(deletedSnapshots) > 0 {
for _, snapshot := range deletedSnapshots {
snapshotConv := snapshot.(map[string]interface{})
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
urlValues.Add("label", snapshotConv["label"].(string))
_, err := c.decortAPICall("POST", bserviceSnapshotDeleteAPI, urlValues)
if err != nil {
return err
}
urlValues = &url.Values{}
}
}
if len(addedSnapshots) > 0 {
for _, snapshot := range addedSnapshots {
snapshotConv := snapshot.(map[string]interface{})
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
urlValues.Add("label", snapshotConv["label"].(string))
_, err := c.decortAPICall("POST", bserviceSnapshotCreateAPI, urlValues)
if err != nil {
return err
}
urlValues = &url.Values{}
}
}
if len(updatedSnapshots) > 0 {
for _, snapshot := range updatedSnapshots {
snapshotConv := snapshot.(map[string]interface{})
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
urlValues.Add("label", snapshotConv["label"].(string))
_, err := c.decortAPICall("POST", bserviceSnapshotRollbackAPI, urlValues)
if err != nil {
return err
}
urlValues = &url.Values{}
}
}
}
return nil
}
func isContainsSnapshot(els []interface{}, el interface{}) bool {
for _, elOld := range els {
elOldConv := elOld.(map[string]interface{})
elConv := el.(map[string]interface{})
if elOldConv["guid"].(string) == elConv["guid"].(string) {
return true
}
}
return false
}
func isRollback(els []interface{}, el interface{}) bool {
for _, elOld := range els {
elOldConv := elOld.(map[string]interface{})
elConv := el.(map[string]interface{})
if elOldConv["guid"].(string) == elConv["guid"].(string) &&
elOldConv["rollback"].(bool) != elConv["rollback"].(bool) &&
elConv["rollback"].(bool) {
return true
}
}
return false
}
func resourceBasicServiceSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"service_name": {
Type: schema.TypeString,
Required: true,
Description: "Name of the service",
},
"rg_id": {
Type: schema.TypeInt,
Required: true,
Description: "ID of the Resource Group where this service will be placed",
},
"ssh_key": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "SSH key to deploy for the specified user. Same key will be deployed to all computes of the service.",
},
"ssh_user": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "name of the user to deploy SSH key for. Pass empty string if no SSH key deployment is required",
},
"permanently": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "if set to False, Basic service will be deleted to recycle bin. Otherwise destroyed immediately",
},
"enable": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "if set to False, Basic service will be deleted to recycle bin. Otherwise destroyed immediately",
},
"restore": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Restores BasicService instance",
},
"start": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Start service. Starting a service technically means starting computes from all service groups according to group relations",
},
"service_id": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
},
"account_id": {
Type: schema.TypeInt,
Computed: true,
},
"account_name": {
Type: schema.TypeString,
Computed: true,
},
"base_domain": {
Type: schema.TypeString,
Computed: true,
},
"computes": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"compgroup_id": {
Type: schema.TypeInt,
Computed: true,
},
"compgroup_name": {
Type: schema.TypeString,
Computed: true,
},
"compgroup_role": {
Type: schema.TypeString,
Computed: true,
},
"id": {
Type: schema.TypeInt,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"cpu_total": {
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,
},
"disk_total": {
Type: schema.TypeString,
Computed: true,
},
"gid": {
Type: schema.TypeInt,
Computed: true,
},
"groups": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
"groups_name": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"guid": {
Type: schema.TypeInt,
Computed: true,
},
"milestones": {
Type: schema.TypeInt,
Computed: true,
},
"parent_srv_id": {
Type: schema.TypeInt,
Computed: true,
},
"parent_srv_type": {
Type: schema.TypeString,
Computed: true,
},
"ram_total": {
Type: schema.TypeInt,
Computed: true,
},
"rg_name": {
Type: schema.TypeString,
Computed: true,
},
"snapshots": {
Type: schema.TypeList,
Computed: true,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"guid": {
Type: schema.TypeString,
Computed: true,
},
"label": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"rollback": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"timestamp": {
Type: schema.TypeInt,
Computed: true,
},
"valid": {
Type: schema.TypeBool,
Computed: true,
},
},
},
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"tech_status": {
Type: schema.TypeString,
Computed: true,
},
"updated_by": {
Type: schema.TypeString,
Computed: true,
},
"updated_time": {
Type: schema.TypeInt,
Computed: true,
},
"user_managed": {
Type: schema.TypeBool,
Computed: true,
},
}
}
func resourceBasicService() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Create: resourceBasicServiceCreate,
Read: resourceBasicServiceRead,
Update: resourceBasicServiceEdit,
Delete: resourceBasicServiceDelete,
Exists: resourceBasicServiceExists,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Timeouts: &schema.ResourceTimeout{
Create: &Timeout60s,
Read: &Timeout30s,
Update: &Timeout60s,
Delete: &Timeout60s,
Default: &Timeout60s,
},
Schema: resourceBasicServiceSchemaMake(),
}
}

@ -0,0 +1,661 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"errors"
"net/url"
"strconv"
"strings"
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
log "github.com/sirupsen/logrus"
)
func resourceBasicServiceGroupCreate(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceBasicServiceGroupCreate")
if compgroupId, ok := d.GetOk("compgroup_id"); ok {
if _, ok := d.GetOk("service_id"); ok {
if exists, err := resourceBasicServiceGroupExists(d, m); exists {
if err != nil {
return err
}
id := uuid.New()
d.SetId(strconv.Itoa(compgroupId.(int)))
d.Set("compgroup_id", strconv.Itoa(compgroupId.(int)))
err = resourceBasicServiceGroupRead(d, m)
if err != nil {
return err
}
d.SetId(id.String())
return nil
}
return errors.New("provided compgroup id does not exist")
}
}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
urlValues.Add("name", d.Get("compgroup_name").(string))
urlValues.Add("count", strconv.Itoa(d.Get("comp_count").(int)))
urlValues.Add("cpu", strconv.Itoa(d.Get("cpu").(int)))
urlValues.Add("ram", strconv.Itoa(d.Get("ram").(int)))
urlValues.Add("disk", strconv.Itoa(d.Get("disk").(int)))
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
urlValues.Add("driver", strings.ToUpper(d.Get("driver").(string)))
if role, ok := d.GetOk("role"); ok {
urlValues.Add("role", role.(string))
}
if timeoutStart, ok := d.GetOk("timeout_start"); ok {
urlValues.Add("timeoutStart", strconv.Itoa(timeoutStart.(int)))
}
if vinses, ok := d.GetOk("vinses"); ok {
vs := vinses.([]interface{})
temp := ""
l := len(vs)
for i, v := range vs {
s := strconv.Itoa(v.(int))
if i != (l - 1) {
s += ","
}
temp = temp + s
}
temp = "[" + temp + "]"
urlValues.Add("vinses", temp)
}
if extnets, ok := d.GetOk("extnets"); ok {
es := extnets.([]interface{})
temp := ""
l := len(es)
for i, e := range es {
s := strconv.Itoa(e.(int))
if i != (l - 1) {
s += ","
}
temp = temp + s
}
temp = "[" + temp + "]"
urlValues.Add("extnets", temp)
}
compgroupId, err := controller.decortAPICall("POST", bserviceGroupAddAPI, urlValues)
if err != nil {
return err
}
id := uuid.New()
d.SetId(compgroupId)
d.Set("compgroup_id", compgroupId)
err = resourceBasicServiceGroupRead(d, m)
if err != nil {
return err
}
d.SetId(id.String())
return nil
}
func resourceBasicServiceGroupRead(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceBasicServiceGroupRead")
bsg, err := utilityBasicServiceGroupCheckPresence(d, m)
if bsg == nil {
d.SetId("")
return err
}
d.Set("account_id", bsg.AccountId)
d.Set("account_name", bsg.AccountName)
d.Set("computes", flattenBSGroupComputes(bsg.Computes))
d.Set("consistency", bsg.Consistency)
d.Set("cpu", bsg.CPU)
d.Set("created_by", bsg.CreatedBy)
d.Set("created_time", bsg.CreatedTime)
d.Set("deleted_by", bsg.DeletedBy)
d.Set("deleted_time", bsg.DeletedTime)
d.Set("disk", bsg.Disk)
d.Set("driver", bsg.Driver)
d.Set("extnets", bsg.Extnets)
d.Set("gid", bsg.GID)
d.Set("guid", bsg.GUID)
d.Set("image_id", bsg.ImageId)
d.Set("milestones", bsg.Milestones)
d.Set("compgroup_name", bsg.Name)
d.Set("compgroup_id", bsg.ID)
d.Set("parents", bsg.Parents)
d.Set("ram", bsg.RAM)
d.Set("rg_id", bsg.RGID)
d.Set("rg_name", bsg.RGName)
d.Set("role", bsg.Role)
d.Set("sep_id", bsg.SepId)
d.Set("seq_no", bsg.SeqNo)
d.Set("status", bsg.Status)
d.Set("tech_status", bsg.TechStatus)
d.Set("timeout_start", bsg.TimeoutStart)
d.Set("updated_by", bsg.UpdatedBy)
d.Set("updated_time", bsg.UpdatedTime)
d.Set("vinses", bsg.Vinses)
return nil
}
func resourceBasicServiceGroupDelete(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceBasicServiceGroupDelete")
bsg, err := utilityBasicServiceGroupCheckPresence(d, m)
if bsg == nil {
if err != nil {
return err
}
return nil
}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int)))
_, err = controller.decortAPICall("POST", bserviceGroupRemoveAPI, urlValues)
if err != nil {
return err
}
d.SetId("")
return nil
}
func resourceBasicServiceGroupExists(d *schema.ResourceData, m interface{}) (bool, error) {
log.Debugf("resourceBasicServiceGroupExists")
bserviceGroup, err := utilityBasicServiceGroupCheckPresence(d, m)
if bserviceGroup == nil {
if err != nil {
return false, err
}
return false, nil
}
return true, nil
}
func resourceBasicServiceGroupEdit(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceBasicServiceGroupEdit")
c := m.(*ControllerCfg)
urlValues := &url.Values{}
if d.HasChange("comp_count") {
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int)))
urlValues.Add("count", strconv.Itoa(d.Get("comp_count").(int)))
urlValues.Add("mode", strings.ToUpper(d.Get("mode").(string)))
_, err := c.decortAPICall("POST", bserviceGroupResizeAPI, urlValues)
if err != nil {
return err
}
urlValues = &url.Values{}
}
if d.HasChange("start") {
api := bserviceGroupStopAPI
start := d.Get("start").(bool)
if start {
api = bserviceGroupStartAPI
} else {
urlValues.Add("force", strconv.FormatBool(d.Get("force_stop").(bool)))
}
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int)))
_, err := c.decortAPICall("POST", api, urlValues)
if err != nil {
return err
}
urlValues = &url.Values{}
}
if d.HasChanges("compgroup_name", "ram", "cpu", "disk", "role") {
urlValues.Add("name", d.Get("compgroup_name").(string))
urlValues.Add("cpu", strconv.Itoa(d.Get("cpu").(int)))
urlValues.Add("ram", strconv.Itoa(d.Get("ram").(int)))
urlValues.Add("disk", strconv.Itoa(d.Get("disk").(int)))
urlValues.Add("role", d.Get("role").(string))
urlValues.Add("force", strconv.FormatBool(d.Get("force_update").(bool)))
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int)))
_, err := c.decortAPICall("POST", bserviceGroupUpdateAPI, urlValues)
if err != nil {
return err
}
urlValues = &url.Values{}
}
if d.HasChange("extnets") {
extnets := d.Get("extnets").([]interface{})
temp := ""
l := len(extnets)
for i, e := range extnets {
s := strconv.Itoa(e.(int))
if i != (l - 1) {
s += ",\n"
} else {
s += "\n"
}
temp = temp + s
}
temp = "[" + temp + "]"
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int)))
urlValues.Add("extnets", temp)
_, err := c.decortAPICall("POST", bserviceGroupUpdateExtnetAPI, urlValues)
if err != nil {
return err
}
urlValues = &url.Values{}
}
if d.HasChange("vinses") {
vinses := d.Get("vinses").([]interface{})
temp := ""
l := len(vinses)
for i, v := range vinses {
s := strconv.Itoa(v.(int))
if i != (l - 1) {
s += ",\n"
} else {
s += "\n"
}
temp = temp + s
}
temp = "[" + temp + "]"
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int)))
urlValues.Add("vinses", temp)
_, err := c.decortAPICall("POST", bserviceGroupUpdateVinsAPI, urlValues)
if err != nil {
return err
}
urlValues = &url.Values{}
}
if d.HasChange("parents") {
deletedParents := make([]interface{}, 0)
addedParents := make([]interface{}, 0)
old, new := d.GetChange("parents")
oldConv := old.([]interface{})
newConv := new.([]interface{})
for _, el := range oldConv {
if !isContainsParent(newConv, el) {
deletedParents = append(deletedParents, el)
}
}
for _, el := range newConv {
if !isContainsParent(oldConv, el) {
addedParents = append(addedParents, el)
}
}
if len(deletedParents) > 0 {
for _, parent := range deletedParents {
parentConv := parent.(int)
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int)))
urlValues.Add("parentId", strconv.Itoa(parentConv))
_, err := c.decortAPICall("POST", bserviceGroupParentRemoveAPI, urlValues)
if err != nil {
return err
}
urlValues = &url.Values{}
}
}
if len(addedParents) > 0 {
for _, parent := range addedParents {
parentConv := parent.(int)
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int)))
urlValues.Add("parentId", strconv.Itoa(parentConv))
_, err := c.decortAPICall("POST", bserviceGroupParentAddAPI, urlValues)
if err != nil {
return err
}
urlValues = &url.Values{}
}
}
}
if d.HasChange("remove_computes") {
rcs := d.Get("remove_computes").([]interface{})
if len(rcs) > 0 {
for _, rc := range rcs {
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int)))
urlValues.Add("computeId", strconv.Itoa(rc.(int)))
_, err := c.decortAPICall("POST", bserviceGroupComputeRemoveAPI, urlValues)
if err != nil {
return err
}
urlValues = &url.Values{}
}
}
}
return nil
}
func isContainsParent(els []interface{}, el interface{}) bool {
for _, elOld := range els {
elOldConv := elOld.(int)
elConv := el.(int)
if elOldConv == elConv {
return true
}
}
return false
}
func resourceBasicServiceGroupSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"service_id": {
Type: schema.TypeInt,
Required: true,
Description: "ID of the Basic Service to add a group to",
},
"compgroup_name": {
Type: schema.TypeString,
Required: true,
Description: "name of the Compute Group to add",
},
"comp_count": {
Type: schema.TypeInt,
Required: true,
Description: "computes number. Defines how many computes must be there in the group",
},
"cpu": {
Type: schema.TypeInt,
Required: true,
Description: "compute CPU number. All computes in the group have the same CPU count",
},
"ram": {
Type: schema.TypeInt,
Required: true,
Description: "compute RAM volume in MB. All computes in the group have the same RAM volume",
},
"disk": {
Type: schema.TypeInt,
Required: true,
Description: "compute boot disk size in GB",
},
"image_id": {
Type: schema.TypeInt,
Required: true,
Description: "OS image ID to create computes from",
},
"driver": {
Type: schema.TypeString,
Required: true,
Description: "compute driver like a KVM_X86, KVM_PPC, etc.",
},
"role": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "group role tag. Can be empty string, does not have to be unique",
},
"timeout_start": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
Description: "time of Compute Group readiness",
},
"extnets": {
Type: schema.TypeList,
Optional: true,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
Description: "list of external networks to connect computes to",
},
"vinses": {
Type: schema.TypeList,
Optional: true,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
Description: "list of ViNSes to connect computes to",
},
"mode": {
Type: schema.TypeString,
Optional: true,
Default: "RELATIVE",
ValidateFunc: validation.StringInSlice([]string{"RELATIVE", "ABSOLUTE"}, false),
Description: "(RELATIVE;ABSOLUTE) either delta or absolute value of computes",
},
"start": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Start the specified Compute Group within BasicService",
},
"force_stop": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "force stop Compute Group",
},
"force_update": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "force resize Compute Group",
},
"parents": {
Type: schema.TypeList,
Optional: true,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
"remove_computes": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
"compgroup_id": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
},
"account_id": {
Type: schema.TypeInt,
Computed: true,
},
"account_name": {
Type: schema.TypeString,
Computed: true,
},
"computes": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeInt,
Computed: true,
},
"ip_addresses": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"os_users": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"login": {
Type: schema.TypeString,
Computed: true,
},
"password": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
},
},
},
"consistency": {
Type: schema.TypeBool,
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,
},
"gid": {
Type: schema.TypeInt,
Computed: true,
},
"guid": {
Type: schema.TypeInt,
Computed: true,
},
"milestones": {
Type: schema.TypeInt,
Computed: true,
},
"rg_id": {
Type: schema.TypeInt,
Computed: true,
},
"rg_name": {
Type: schema.TypeString,
Computed: true,
},
"sep_id": {
Type: schema.TypeInt,
Computed: true,
},
"seq_no": {
Type: schema.TypeInt,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"tech_status": {
Type: schema.TypeString,
Computed: true,
},
"updated_by": {
Type: schema.TypeString,
Computed: true,
},
"updated_time": {
Type: schema.TypeInt,
Computed: true,
},
}
}
func resourceBasicServiceGroup() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Create: resourceBasicServiceGroupCreate,
Read: resourceBasicServiceGroupRead,
Update: resourceBasicServiceGroupEdit,
Delete: resourceBasicServiceGroupDelete,
Exists: resourceBasicServiceGroupExists,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Timeouts: &schema.ResourceTimeout{
Create: &Timeout60s,
Read: &Timeout30s,
Update: &Timeout60s,
Delete: &Timeout60s,
Default: &Timeout60s,
},
Schema: resourceBasicServiceGroupSchemaMake(),
}
}

@ -385,16 +385,10 @@ func resourceCDROMImage() *schema.Resource {
CustomizeDiff: customdiff.All( CustomizeDiff: customdiff.All(
customdiff.IfValueChange("enabled", func(old, new, meta interface{}) bool { customdiff.IfValueChange("enabled", func(old, new, meta interface{}) bool {
if old.(bool) != new.(bool) { return old.(bool) != new.(bool)
return true
}
return false
}, resourceImageChangeEnabled), }, resourceImageChangeEnabled),
customdiff.IfValueChange("name", func(old, new, meta interface{}) bool { customdiff.IfValueChange("name", func(old, new, meta interface{}) bool {
if old.(string) != new.(string) && old.(string) != "" { return old.(string) != new.(string) && old.(string) != ""
return true
}
return false
}, resourceImageEditName), }, resourceImageEditName),
customdiff.IfValueChange("shared_with", func(old, new, meta interface{}) bool { customdiff.IfValueChange("shared_with", func(old, new, meta interface{}) bool {
o := old.([]interface{}) o := old.([]interface{})
@ -411,16 +405,10 @@ func resourceCDROMImage() *schema.Resource {
count++ count++
} }
} }
if count == 0 { return count == 0
return true
}
return false
}, resourceImageShare), }, resourceImageShare),
customdiff.IfValueChange("computeci_id", func(old, new, meta interface{}) bool { customdiff.IfValueChange("computeci_id", func(old, new, meta interface{}) bool {
if old.(int) != new.(int) { return old.(int) != new.(int)
return true
}
return false
}, resourceImageChangeComputeci), }, resourceImageChangeComputeci),
customdiff.IfValueChange("enabled_stacks", func(old, new, meta interface{}) bool { customdiff.IfValueChange("enabled_stacks", func(old, new, meta interface{}) bool {
o := old.([]interface{}) o := old.([]interface{})
@ -437,10 +425,7 @@ func resourceCDROMImage() *schema.Resource {
count++ count++
} }
} }
if count == 0 { return count == 0
return true
}
return false
}, resourceImageUpdateNodes), }, resourceImageUpdateNodes),
), ),

@ -132,7 +132,7 @@ func resourceComputeCreate(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceComputeCreate: calling utilityComputeExtraDisksConfigure to attach %d extra disk(s)", argVal.(*schema.Set).Len()) log.Debugf("resourceComputeCreate: calling utilityComputeExtraDisksConfigure to attach %d extra disk(s)", argVal.(*schema.Set).Len())
err = controller.utilityComputeExtraDisksConfigure(d, false) // do_delta=false, as we are working on a new compute err = controller.utilityComputeExtraDisksConfigure(d, false) // do_delta=false, as we are working on a new compute
if err != nil { if err != nil {
log.Errorf("resourceComputeCreate: error when attaching extra disk(s) to a new Compute ID %s: %s", compId, err) log.Errorf("resourceComputeCreate: error when attaching extra disk(s) to a new Compute ID %d: %v", compId, err)
extraDisksOk = false extraDisksOk = false
} }
} }
@ -167,8 +167,7 @@ func resourceComputeCreate(d *schema.ResourceData, m interface{}) error {
reqValues := &url.Values{} reqValues := &url.Values{}
reqValues.Add("computeId", fmt.Sprintf("%d", compId)) reqValues.Add("computeId", fmt.Sprintf("%d", compId))
log.Debugf("resourceComputeCreate: starting Compute ID %d after completing its resource configuration", compId) log.Debugf("resourceComputeCreate: starting Compute ID %d after completing its resource configuration", compId)
apiResp, err = controller.decortAPICall("POST", ComputeStartAPI, reqValues) if _, err := controller.decortAPICall("POST", ComputeStartAPI, reqValues); err != nil {
if err != nil {
return err return err
} }
} }
@ -246,6 +245,7 @@ func resourceComputeUpdate(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceComputeUpdate: changing CPU %d -> %d and/or RAM %d -> %d", log.Debugf("resourceComputeUpdate: changing CPU %d -> %d and/or RAM %d -> %d",
oldCpu.(int), newCpu.(int), oldCpu.(int), newCpu.(int),
oldRam.(int), newRam.(int)) oldRam.(int), newRam.(int))
params.Add("force", "true")
_, err := controller.decortAPICall("POST", ComputeResizeAPI, params) _, err := controller.decortAPICall("POST", ComputeResizeAPI, params)
if err != nil { if err != nil {
return err return err
@ -262,13 +262,13 @@ func resourceComputeUpdate(d *schema.ResourceData, m interface{}) error {
bdsParams.Add("size", fmt.Sprintf("%d", newSize.(int))) bdsParams.Add("size", fmt.Sprintf("%d", newSize.(int)))
log.Debugf("resourceComputeUpdate: compute ID %s, boot disk ID %d resize %d -> %d", 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)) d.Id(), d.Get("boot_disk_id").(int), oldSize.(int), newSize.(int))
_, err := controller.decortAPICall("POST", DisksResizeAPI, params) _, err := controller.decortAPICall("POST", DisksResizeAPI, bdsParams)
if err != nil { if err != nil {
return err return err
} }
d.SetPartial("boot_disk_size") d.SetPartial("boot_disk_size")
} else if oldSize.(int) > newSize.(int) { } else if oldSize.(int) > newSize.(int) {
log.Warnf("resourceComputeUpdate: compute ID %d - shrinking boot disk is not allowed", d.Id()) log.Warnf("resourceComputeUpdate: compute ID %s - shrinking boot disk is not allowed", d.Id())
} }
// 3. Calculate and apply changes to data disks // 3. Calculate and apply changes to data disks
@ -319,6 +319,9 @@ func resourceComputeDelete(d *schema.ResourceData, m interface{}) error {
compFacts, err := utilityComputeCheckPresence(d, m) compFacts, err := utilityComputeCheckPresence(d, m)
if compFacts == "" { if compFacts == "" {
if err != nil {
return err
}
// the target Compute does not exist - in this case according to Terraform best practice // the target Compute does not exist - in this case according to Terraform best practice
// we exit from Destroy method without error // we exit from Destroy method without error
return nil return nil
@ -539,39 +542,6 @@ func resourceCompute() *schema.Resource {
Default: true, Default: true,
Description: "Is compute started.", Description: "Is compute started.",
}, },
/*
"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).",
},
"interfaces": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: interfaceSubresourceSchemaMake(),
},
Description: "Specification for the virtual NICs configured on this compute instance.",
},
"status": {
Type: schema.TypeString,
Computed: true,
Description: "Current model status of this compute instance.",
},
"tech_status": {
Type: schema.TypeString,
Computed: true,
Description: "Current technical status of this compute instance.",
},
*/
}, },
} }
} }

@ -47,13 +47,19 @@ func resourceDiskCreate(d *schema.ResourceData, m interface{}) error {
urlValues.Add("name", d.Get("name").(string)) urlValues.Add("name", d.Get("name").(string))
urlValues.Add("size", fmt.Sprintf("%d", d.Get("size").(int))) urlValues.Add("size", fmt.Sprintf("%d", d.Get("size").(int)))
urlValues.Add("type", "D") // NOTE: only disks of Data type are managed via plugin urlValues.Add("type", "D") // NOTE: only disks of Data type are managed via plugin
urlValues.Add("sep_id", fmt.Sprintf("%d", d.Get("sep_id").(int)))
urlValues.Add("pool", d.Get("pool").(string)) 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("description") argVal, argSet := d.GetOk("description")
if argSet { if argSet {
urlValues.Add("description", argVal.(string)) urlValues.Add("description", argVal.(string))
} }
apiResp, err := controller.decortAPICall("POST", DisksCreateAPI, urlValues) apiResp, err := controller.decortAPICall("POST", DisksCreateAPI, urlValues)
if err != nil { if err != nil {
@ -65,9 +71,9 @@ func resourceDiskCreate(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceDiskCreate: new Disk ID / name %d / %s creation sequence complete", diskId, d.Get("name").(string)) log.Debugf("resourceDiskCreate: new Disk ID / name %d / %s creation sequence complete", diskId, d.Get("name").(string))
// We may reuse dataSourceDiskRead here as we maintain similarity // We may reuse dataSourceDiskRead here as we maintain similarity
// between Disk resource and Disk data source schemas // between Disk resource and Disk data source schemas
// Disk resource read function will also update resource ID on success, so that Terraform // Disk resource read function will also update resource ID on success, so that Terraform
// will know the resource exists (however, we already did it a few lines before) // will know the resource exists (however, we already did it a few lines before)
return dataSourceDiskRead(d, m) return dataSourceDiskRead(d, m)
} }
@ -100,8 +106,8 @@ func resourceDiskUpdate(d *schema.ResourceData, m interface{}) error {
oldSize, newSize := d.GetChange("size") oldSize, newSize := d.GetChange("size")
if oldSize.(int) < newSize.(int) { if oldSize.(int) < newSize.(int) {
log.Debugf("resourceDiskUpdate: resizing disk ID %s - %d GB -> %d GB", log.Debugf("resourceDiskUpdate: resizing disk ID %s - %d GB -> %d GB",
d.Id(), oldSize.(int), newSize.(int)) d.Id(), oldSize.(int), newSize.(int))
sizeParams := &url.Values{} sizeParams := &url.Values{}
sizeParams.Add("diskId", d.Id()) sizeParams.Add("diskId", d.Id())
sizeParams.Add("size", fmt.Sprintf("%d", newSize.(int))) sizeParams.Add("size", fmt.Sprintf("%d", newSize.(int)))
@ -116,8 +122,8 @@ func resourceDiskUpdate(d *schema.ResourceData, m interface{}) error {
oldName, newName := d.GetChange("name") oldName, newName := d.GetChange("name")
if oldName.(string) != newName.(string) { if oldName.(string) != newName.(string) {
log.Debugf("resourceDiskUpdate: renaming disk ID %d - %s -> %s", log.Debugf("resourceDiskUpdate: renaming disk ID %d - %s -> %s",
d.Get("disk_id").(int), oldName.(string), newName.(string)) d.Get("disk_id").(int), oldName.(string), newName.(string))
renameParams := &url.Values{} renameParams := &url.Values{}
renameParams.Add("diskId", d.Id()) renameParams.Add("diskId", d.Id())
renameParams.Add("name", newName.(string)) renameParams.Add("name", newName.(string))
@ -129,24 +135,24 @@ func resourceDiskUpdate(d *schema.ResourceData, m interface{}) error {
} }
/* /*
NOTE: plugin will manage disks of type "Data" only, and type cannot be changed once disk is created NOTE: plugin will manage disks of type "Data" only, and type cannot be changed once disk is created
oldType, newType := d.GetChange("type") oldType, newType := d.GetChange("type")
if oldType.(string) != newType.(string) { if oldType.(string) != newType.(string) {
return fmt.Errorf("resourceDiskUpdate: Disk ID %s - changing type of existing disk not allowed", d.Id()) return fmt.Errorf("resourceDiskUpdate: Disk ID %s - changing type of existing disk not allowed", d.Id())
} }
*/ */
d.Partial(false) d.Partial(false)
// we may reuse dataSourceDiskRead here as we maintain similarity // we may reuse dataSourceDiskRead here as we maintain similarity
// between Compute resource and Compute data source schemas // between Compute resource and Compute data source schemas
return dataSourceDiskRead(d, m) return dataSourceDiskRead(d, m)
} }
func resourceDiskDelete(d *schema.ResourceData, m interface{}) error { func resourceDiskDelete(d *schema.ResourceData, m interface{}) error {
// NOTE: this function tries to detach and destroy target Disk "permanently", so // NOTE: this function tries to detach and destroy target Disk "permanently", so
// there is no way to restore it. // there is no way to restore it.
// If, however, the disk is attached to a compute, the method will // If, however, the disk is attached to a compute, the method will
// fail (by failing the underpinning DECORt API call, which is issued with detach=false) // fail (by failing the underpinning DECORt API call, which is issued with detach=false)
log.Debugf("resourceDiskDelete: called for Disk ID / name %d / %s, Account ID %d", log.Debugf("resourceDiskDelete: called for Disk ID / name %d / %s, Account ID %d",
@ -154,6 +160,9 @@ func resourceDiskDelete(d *schema.ResourceData, m interface{}) error {
diskFacts, err := utilityDiskCheckPresence(d, m) diskFacts, err := utilityDiskCheckPresence(d, m)
if diskFacts == "" { if diskFacts == "" {
if err != nil {
return err
}
// the specified Disk does not exist - in this case according to Terraform best practice // the specified Disk does not exist - in this case according to Terraform best practice
// we exit from Destroy method without error // we exit from Destroy method without error
return nil return nil
@ -166,8 +175,8 @@ func resourceDiskDelete(d *schema.ResourceData, m interface{}) error {
// However, this may change in the future, as TF state management logic may want // However, this may change in the future, as TF state management logic may want
// to delete disk resource BEFORE it is detached from compute instance, and, while // to delete disk resource BEFORE it is detached from compute instance, and, while
// perfectly OK from data preservation viewpoint, this is breaking expected TF workflow // perfectly OK from data preservation viewpoint, this is breaking expected TF workflow
// in the eyes of an experienced TF user // in the eyes of an experienced TF user
params.Add("detach", "0") params.Add("detach", "0")
params.Add("permanently", "1") params.Add("permanently", "1")
controller := m.(*ControllerCfg) controller := m.(*ControllerCfg)
@ -198,7 +207,7 @@ func resourceDiskSchemaMake() map[string]*schema.Schema {
rets := map[string]*schema.Schema{ rets := map[string]*schema.Schema{
"name": { "name": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Required: true,
Description: "Name of this disk. NOTE: disk names are NOT unique within an account. If disk ID is specified, disk name is ignored.", Description: "Name of this disk. NOTE: disk names are NOT unique within an account. If disk ID is specified, disk name is ignored.",
}, },
@ -210,34 +219,34 @@ func resourceDiskSchemaMake() map[string]*schema.Schema {
"account_id": { "account_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Required: true,
Description: "ID of the account this disk belongs to.", Description: "ID of the account this disk belongs to.",
}, },
"sep_id": { "sep_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Optional: true,
Computed: true,
ForceNew: true, ForceNew: true,
ValidateFunc: validation.IntAtLeast(1),
Description: "Storage end-point provider serving this disk. Cannot be changed for existing disk.", Description: "Storage end-point provider serving this disk. Cannot be changed for existing disk.",
}, },
"pool": { "pool": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Optional: true,
Computed: true,
ForceNew: true, ForceNew: true,
ValidateFunc: validation.StringIsNotEmpty,
Description: "Pool where this disk is located. Cannot be changed for existing disk.", Description: "Pool where this disk is located. Cannot be changed for existing disk.",
}, },
"size": { "size": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
ValidateFunc: validation.IntAtLeast(1), ValidateFunc: validation.IntAtLeast(1),
Description: "Size of the disk in GB. Note, that existing disks can only be grown in size.", Description: "Size of the disk in GB. Note, that existing disks can only be grown in size.",
}, },
/* We moved "type" attribute to computed attributes section, as plugin manages disks of only /* We moved "type" attribute to computed attributes section, as plugin manages disks of only
one type - "D", e.g. data disks. one type - "D", e.g. data disks.
"type": { "type": {
Type: schema.TypeString, Type: schema.TypeString,
@ -256,7 +265,7 @@ func resourceDiskSchemaMake() map[string]*schema.Schema {
Description: "Optional user-defined text description of this disk.", Description: "Optional user-defined text description of this disk.",
}, },
// The rest of the attributes are all computed // The rest of the attributes are all computed
"account_name": { "account_name": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
@ -282,14 +291,14 @@ func resourceDiskSchemaMake() map[string]*schema.Schema {
}, },
/* /*
"snapshots": { "snapshots": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
Elem: &schema.Resource { Elem: &schema.Resource {
Schema: snapshotSubresourceSchemaMake(), Schema: snapshotSubresourceSchemaMake(),
},
Description: "List of user-created snapshots for this disk."
}, },
Description: "List of user-created snapshots for this disk."
},
*/ */
} }

@ -87,8 +87,7 @@ func resourceImageCreate(d *schema.ResourceData, m interface{}) error {
} }
api := "" api := ""
isSync := d.Get("sync").(bool) if isSync := d.Get("sync").(bool); !isSync {
if !isSync {
api = imageCreateAPI api = imageCreateAPI
} else { } else {
api = imageSyncCreateAPI api = imageSyncCreateAPI
@ -640,16 +639,10 @@ func resourceImage() *schema.Resource {
}, },
CustomizeDiff: customdiff.All( CustomizeDiff: customdiff.All(
customdiff.IfValueChange("enabled", func(old, new, meta interface{}) bool { customdiff.IfValueChange("enabled", func(old, new, meta interface{}) bool {
if old.(bool) != new.(bool) { return old.(bool) != new.(bool)
return true
}
return false
}, resourceImageChangeEnabled), }, resourceImageChangeEnabled),
customdiff.IfValueChange("name", func(old, new, meta interface{}) bool { customdiff.IfValueChange("name", func(old, new, meta interface{}) bool {
if old.(string) != new.(string) && old.(string) != "" { return old.(string) != new.(string) && old.(string) != ""
return true
}
return false
}, resourceImageEditName), }, resourceImageEditName),
customdiff.IfValueChange("shared_with", func(old, new, meta interface{}) bool { customdiff.IfValueChange("shared_with", func(old, new, meta interface{}) bool {
o := old.([]interface{}) o := old.([]interface{})
@ -667,16 +660,10 @@ func resourceImage() *schema.Resource {
count++ count++
} }
} }
if count == 0 { return count == 0
return true
}
return false
}, resourceImageShare), }, resourceImageShare),
customdiff.IfValueChange("computeci_id", func(old, new, meta interface{}) bool { customdiff.IfValueChange("computeci_id", func(old, new, meta interface{}) bool {
if old.(int) != new.(int) { return old.(int) != new.(int)
return true
}
return false
}, resourceImageChangeComputeci), }, resourceImageChangeComputeci),
customdiff.IfValueChange("enabled_stacks", func(old, new, meta interface{}) bool { customdiff.IfValueChange("enabled_stacks", func(old, new, meta interface{}) bool {
o := old.([]interface{}) o := old.([]interface{})
@ -693,10 +680,7 @@ func resourceImage() *schema.Resource {
count++ count++
} }
} }
if count == 0 { return count == 0
return true
}
return false
}, resourceImageUpdateNodes), }, resourceImageUpdateNodes),
), ),

@ -223,15 +223,13 @@ func resourceK8sUpdate(d *schema.ResourceData, m interface{}) error {
if newWorkers.Num > wg.Num { if newWorkers.Num > wg.Num {
urlValues.Add("num", strconv.Itoa(newWorkers.Num-wg.Num)) urlValues.Add("num", strconv.Itoa(newWorkers.Num-wg.Num))
_, err := controller.decortAPICall("POST", K8sWorkerAddAPI, urlValues) if _, err := controller.decortAPICall("POST", K8sWorkerAddAPI, urlValues); err != nil {
if err != nil {
return err return err
} }
} else { } else {
for i := wg.Num - 1; i >= newWorkers.Num; i-- { for i := wg.Num - 1; i >= newWorkers.Num; i-- {
urlValues.Set("workerId", strconv.Itoa(wg.DetailedInfo[i].ID)) urlValues.Set("workerId", strconv.Itoa(wg.DetailedInfo[i].ID))
_, err := controller.decortAPICall("POST", K8sWorkerDeleteAPI, urlValues) if _, err := controller.decortAPICall("POST", K8sWorkerDeleteAPI, urlValues); err != nil {
if err != nil {
return err return err
} }
} }

@ -108,16 +108,14 @@ func resourceK8sWgUpdate(d *schema.ResourceData, m interface{}) error {
wg, err := utilityK8sWgCheckPresence(d, m) wg, err := utilityK8sWgCheckPresence(d, m)
if err != nil { if err != nil {
return nil return err
} }
urlValues := &url.Values{} urlValues := &url.Values{}
urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int))) urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int)))
urlValues.Add("workersGroupId", d.Id()) urlValues.Add("workersGroupId", d.Id())
newNum := d.Get("num").(int) if newNum := d.Get("num").(int); newNum > wg.Num {
if newNum > wg.Num {
urlValues.Add("num", strconv.Itoa(newNum-wg.Num)) urlValues.Add("num", strconv.Itoa(newNum-wg.Num))
_, err := controller.decortAPICall("POST", K8sWorkerAddAPI, urlValues) _, err := controller.decortAPICall("POST", K8sWorkerAddAPI, urlValues)
if err != nil { if err != nil {

@ -145,6 +145,7 @@ func resourcePfwSchemaMake() map[string]*schema.Schema {
"public_port_end": { "public_port_end": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true,
ForceNew: true, ForceNew: true,
ValidateFunc: validation.IntBetween(1, 65535), ValidateFunc: validation.IntBetween(1, 65535),
Description: "End port number (inclusive) for the ranged rule.", Description: "End port number (inclusive) for the ranged rule.",

@ -39,10 +39,6 @@ func resourceResgroupCreate(d *schema.ResourceData, m interface{}) error {
// Valid account ID is required to create 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 // obtain Account ID by account name - it should not be zero on success
validated_account_id, err := utilityGetAccountIdBySchema(d, m)
if err != nil {
return err
}
rg_name, arg_set := d.GetOk("name") rg_name, arg_set := d.GetOk("name")
if !arg_set { if !arg_set {
@ -62,7 +58,7 @@ func resourceResgroupCreate(d *schema.ResourceData, m interface{}) error {
// all required parameters are set in the schema - we can continue with RG creation // 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", log.Debugf("resourceResgroupCreate: called for RG name %s, account ID %d",
rg_name.(string), validated_account_id) rg_name.(string), d.Get("account_id").(int))
// quota settings are optional // quota settings are optional
set_quota := false set_quota := false
@ -70,17 +66,17 @@ func resourceResgroupCreate(d *schema.ResourceData, m interface{}) error {
arg_value, arg_set := d.GetOk("quota") arg_value, arg_set := d.GetOk("quota")
if arg_set { if arg_set {
log.Debugf("resourceResgroupCreate: setting Quota on RG requested") log.Debugf("resourceResgroupCreate: setting Quota on RG requested")
quota_record, _ = makeQuotaRecord(arg_value.([]interface{})) quota_record = makeQuotaRecord(arg_value.([]interface{}))
set_quota = true set_quota = true
} }
controller := m.(*ControllerCfg) controller := m.(*ControllerCfg)
log.Debugf("resourceResgroupCreate: called by user %q for RG name %s, account ID %d", log.Debugf("resourceResgroupCreate: called by user %q for RG name %s, account ID %d",
controller.getDecortUsername(), controller.getDecortUsername(),
rg_name.(string), validated_account_id) rg_name.(string), d.Get("account_id").(int))
url_values := &url.Values{} url_values := &url.Values{}
url_values.Add("accountId", fmt.Sprintf("%d", validated_account_id)) url_values.Add("accountId", fmt.Sprintf("%d", d.Get("account_id").(int)))
url_values.Add("name", rg_name.(string)) url_values.Add("name", rg_name.(string))
url_values.Add("gid", fmt.Sprintf("%d", DefaultGridID)) // use default Grid ID, similar to disk resource mgmt convention url_values.Add("gid", fmt.Sprintf("%d", DefaultGridID)) // use default Grid ID, similar to disk resource mgmt convention
url_values.Add("owner", controller.getDecortUsername()) url_values.Add("owner", controller.getDecortUsername())
@ -142,7 +138,7 @@ func resourceResgroupCreate(d *schema.ResourceData, m interface{}) error {
} }
func resourceResgroupRead(d *schema.ResourceData, m interface{}) error { func resourceResgroupRead(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceResgroupRead: called for RG name %s, account ID %s", log.Debugf("resourceResgroupRead: called for RG name %s, account ID %d",
d.Get("name").(string), d.Get("account_id").(int)) d.Get("name").(string), d.Get("account_id").(int))
rg_facts, err := utilityResgroupCheckPresence(d, m) rg_facts, err := utilityResgroupCheckPresence(d, m)
@ -199,9 +195,9 @@ func resourceResgroupUpdate(d *schema.ResourceData, m interface{}) error {
quota_value, quota_set := d.GetOk("quota") quota_value, quota_set := d.GetOk("quota")
if quota_set { if quota_set {
log.Debugf("resourceResgroupUpdate: quota specified - looking for deltas from the old quota.") log.Debugf("resourceResgroupUpdate: quota specified - looking for deltas from the old quota.")
quotarecord_new, _ := makeQuotaRecord(quota_value.([]interface{})) quotarecord_new := makeQuotaRecord(quota_value.([]interface{}))
quota_value_old, _ := d.GetChange("quota") // returns old as 1st, new as 2nd return value quota_value_old, _ := d.GetChange("quota") // returns old as 1st, new as 2nd return value
quotarecord_old, _ := makeQuotaRecord(quota_value_old.([]interface{})) quotarecord_old := makeQuotaRecord(quota_value_old.([]interface{}))
if quotarecord_new.Cpu != quotarecord_old.Cpu { if quotarecord_new.Cpu != quotarecord_old.Cpu {
do_general_update = true do_general_update = true
@ -260,11 +256,14 @@ func resourceResgroupUpdate(d *schema.ResourceData, m interface{}) error {
func resourceResgroupDelete(d *schema.ResourceData, m interface{}) error { func resourceResgroupDelete(d *schema.ResourceData, m interface{}) error {
// NOTE: this method forcibly destroys target resource group with flag "permanently", so there is no way to // 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 // restore the destroyed resource group as well all Computes & VINSes that existed in it
log.Debugf("resourceResgroupDelete: called for RG name %s, account ID %s", log.Debugf("resourceResgroupDelete: called for RG name %s, account ID %d",
d.Get("name").(string), d.Get("account_id").(int)) d.Get("name").(string), d.Get("account_id").(int))
rg_facts, err := utilityResgroupCheckPresence(d, m) rg_facts, err := utilityResgroupCheckPresence(d, m)
if rg_facts == "" { if rg_facts == "" {
if err != nil {
return err
}
// the target RG does not exist - in this case according to Terraform best practice // the target RG does not exist - in this case according to Terraform best practice
// we exit from Destroy method without error // we exit from Destroy method without error
return nil return nil

@ -243,8 +243,7 @@ func resourceSepEdit(d *schema.ResourceData, m interface{}) error {
} }
urlValues = &url.Values{} urlValues = &url.Values{}
err := resourceSepRead(d, m) if err := resourceSepRead(d, m); err != nil {
if err != nil {
return err return err
} }
@ -282,8 +281,6 @@ func resourceSepUpdateNodes(d *schema.ResourceDiff, m interface{}) error {
urlValues := &url.Values{} urlValues := &url.Values{}
t1, t2 := d.GetChange("consumed_by") t1, t2 := d.GetChange("consumed_by")
d1 := t1.([]interface{})
d2 := t2.([]interface{})
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int))) urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
@ -291,7 +288,7 @@ func resourceSepUpdateNodes(d *schema.ResourceDiff, m interface{}) error {
temp := "" temp := ""
api := "" api := ""
if len(d1) > len(d2) { if d1, d2 := t1.([]interface{}), t2.([]interface{}); len(d1) > len(d2) {
for _, n := range d2 { for _, n := range d2 {
if !findElInt(d1, n) { if !findElInt(d1, n) {
consumedIds = append(consumedIds, n) consumedIds = append(consumedIds, n)
@ -510,10 +507,7 @@ func resourceSep() *schema.Resource {
CustomizeDiff: customdiff.All( CustomizeDiff: customdiff.All(
customdiff.IfValueChange("enable", func(old, new, meta interface{}) bool { customdiff.IfValueChange("enable", func(old, new, meta interface{}) bool {
if old.(bool) != new.(bool) { return old.(bool) != new.(bool)
return true
}
return false
}, resourceSepChangeEnabled), }, resourceSepChangeEnabled),
customdiff.IfValueChange("consumed_by", func(old, new, meta interface{}) bool { customdiff.IfValueChange("consumed_by", func(old, new, meta interface{}) bool {
o := old.([]interface{}) o := old.([]interface{})
@ -530,10 +524,7 @@ func resourceSep() *schema.Resource {
count++ count++
} }
} }
if count == 0 { return count == 0
return true
}
return false
}, resourceSepUpdateNodes), }, resourceSepUpdateNodes),
customdiff.IfValueChange("provided_by", func(old, new, meta interface{}) bool { customdiff.IfValueChange("provided_by", func(old, new, meta interface{}) bool {
o := old.([]interface{}) o := old.([]interface{})
@ -550,10 +541,7 @@ func resourceSep() *schema.Resource {
count++ count++
} }
} }
if count == 0 { return count == 0
return true
}
return false
}, resourceSepUpdateProviders), }, resourceSepUpdateProviders),
), ),
} }

@ -55,9 +55,7 @@ func resourceSepConfigCreate(d *schema.ResourceData, m interface{}) error {
return errors.New("provided sep id config does not exist") return errors.New("provided sep id config does not exist")
} }
resourceSepConfigRead(d, m) return resourceSepConfigRead(d, m)
return nil
} }
func resourceSepConfigRead(d *schema.ResourceData, m interface{}) error { func resourceSepConfigRead(d *schema.ResourceData, m interface{}) error {

@ -191,7 +191,7 @@ func resourceSnapshot() *schema.Resource {
CustomizeDiff: customdiff.All( CustomizeDiff: customdiff.All(
customdiff.IfValueChange("rollback", func(old, new, meta interface{}) bool { customdiff.IfValueChange("rollback", func(old, new, meta interface{}) bool {
o := old.(bool) o := old.(bool)
if o != new.(bool) && o == false { if o != new.(bool) && !o {
return true return true
} }
return false return false

@ -40,7 +40,7 @@ import (
func ipcidrDiffSupperss(key, oldVal, newVal string, d *schema.ResourceData) bool { func ipcidrDiffSupperss(key, oldVal, newVal string, d *schema.ResourceData) bool {
if oldVal == "" && newVal != "" { if oldVal == "" && newVal != "" {
// if old value for "ipcidr" resource is empty string, it means that we are creating new ViNS // if old value for "ipcidr" resource is empty string, it means that we are creating new ViNS
// and there is a chance that the user will want specific IP address range for this ViNS - // and there is a chance that the user will want specific IP address range for this ViNS -
// check if "ipcidr" is explicitly set in TF file to a non-empty string. // check if "ipcidr" is explicitly set in TF file to a non-empty string.
log.Debugf("ipcidrDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=FALSE", key, oldVal, newVal) log.Debugf("ipcidrDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=FALSE", key, oldVal, newVal)
return false // there is a difference between stored and new value return false // there is a difference between stored and new value
@ -51,7 +51,7 @@ func ipcidrDiffSupperss(key, oldVal, newVal string, d *schema.ResourceData) bool
func resourceVinsCreate(d *schema.ResourceData, m interface{}) error { func resourceVinsCreate(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceVinsCreate: called for ViNS name %s, Account ID %d, RG ID %d", log.Debugf("resourceVinsCreate: called for ViNS name %s, Account ID %d, RG ID %d",
d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int)) d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int))
apiToCall := VinsCreateInAccountAPI apiToCall := VinsCreateInAccountAPI
@ -65,7 +65,7 @@ func resourceVinsCreate(d *schema.ResourceData, m interface{}) error {
apiToCall = VinsCreateInRgAPI apiToCall = VinsCreateInRgAPI
urlValues.Add("rgId", fmt.Sprintf("%d", argVal.(int))) urlValues.Add("rgId", fmt.Sprintf("%d", argVal.(int)))
} else { } else {
// RG ID either not set at all or set to 0 - user may want ViNS at account level // RG ID either not set at all or set to 0 - user may want ViNS at account level
argVal, argSet = d.GetOk("account_id") argVal, argSet = d.GetOk("account_id")
if !argSet || argVal.(int) <= 0 { if !argSet || argVal.(int) <= 0 {
// No valid Account ID (and no RG ID either) - cannot create ViNS // No valid Account ID (and no RG ID either) - cannot create ViNS
@ -79,14 +79,14 @@ func resourceVinsCreate(d *schema.ResourceData, m interface{}) error {
if argVal.(int) > 0 { if argVal.(int) > 0 {
// connect to specific external network // connect to specific external network
urlValues.Add("extNetId", fmt.Sprintf("%d", argVal.(int))) urlValues.Add("extNetId", fmt.Sprintf("%d", argVal.(int)))
/* /*
Commented out, as we've made "ext_net_ip" parameter non-configurable via Terraform! Commented out, as we've made "ext_net_ip" parameter non-configurable via Terraform!
// in case of specific ext net connection user may also want a particular IP address // in case of specific ext net connection user may also want a particular IP address
argVal, argSet = d.GetOk("ext_net_ip") argVal, argSet = d.GetOk("ext_net_ip")
if argSet && argVal.(string) != "" { if argSet && argVal.(string) != "" {
urlValues.Add("extIp", argVal.(string)) urlValues.Add("extIp", argVal.(string))
} }
*/ */
} else { } else {
// ext_net_id is set to a negative value - connect to default external network // ext_net_id is set to a negative value - connect to default external network
@ -100,7 +100,7 @@ func resourceVinsCreate(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceVinsCreate: ipcidr is set to %s", argVal.(string)) log.Debugf("resourceVinsCreate: ipcidr is set to %s", argVal.(string))
urlValues.Add("ipcidr", argVal.(string)) urlValues.Add("ipcidr", argVal.(string))
} }
argVal, argSet = d.GetOk("description") argVal, argSet = d.GetOk("description")
if argSet { if argSet {
urlValues.Add("desc", argVal.(string)) urlValues.Add("desc", argVal.(string))
@ -116,9 +116,9 @@ func resourceVinsCreate(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceVinsCreate: new ViNS ID / name %d / %s creation sequence complete", vinsId, d.Get("name").(string)) log.Debugf("resourceVinsCreate: new ViNS ID / name %d / %s creation sequence complete", vinsId, d.Get("name").(string))
// We may reuse dataSourceVinsRead here as we maintain similarity // We may reuse dataSourceVinsRead here as we maintain similarity
// between ViNS resource and ViNS data source schemas // between ViNS resource and ViNS data source schemas
// ViNS resource read function will also update resource ID on success, so that Terraform // ViNS resource read function will also update resource ID on success, so that Terraform
// will know the resource exists (however, we already did it a few lines before) // will know the resource exists (however, we already did it a few lines before)
return dataSourceVinsRead(d, m) return dataSourceVinsRead(d, m)
} }
@ -138,12 +138,12 @@ func resourceVinsRead(d *schema.ResourceData, m interface{}) error {
func resourceVinsUpdate(d *schema.ResourceData, m interface{}) error { func resourceVinsUpdate(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceVinsUpdate: called for ViNS ID / name %s / %s, Account ID %d, RG ID %d", log.Debugf("resourceVinsUpdate: called for ViNS ID / name %s / %s, Account ID %d, RG ID %d",
d.Id(), d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int)) d.Id(), d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int))
controller := m.(*ControllerCfg) controller := m.(*ControllerCfg)
d.Partial(true) d.Partial(true)
// 1. Handle external network connection change // 1. Handle external network connection change
oldExtNetId, newExtNedId := d.GetChange("ext_net_id") oldExtNetId, newExtNedId := d.GetChange("ext_net_id")
if oldExtNetId.(int) != newExtNedId.(int) { if oldExtNetId.(int) != newExtNedId.(int) {
@ -168,15 +168,15 @@ func resourceVinsUpdate(d *schema.ResourceData, m interface{}) error {
return err return err
} }
} }
d.SetPartial("ext_net_id") d.SetPartial("ext_net_id")
} }
d.Partial(false) d.Partial(false)
// we may reuse dataSourceVinsRead here as we maintain similarity // we may reuse dataSourceVinsRead here as we maintain similarity
// between Compute resource and Compute data source schemas // between Compute resource and Compute data source schemas
return dataSourceVinsRead(d, m) return dataSourceVinsRead(d, m)
} }
func resourceVinsDelete(d *schema.ResourceData, m interface{}) error { func resourceVinsDelete(d *schema.ResourceData, m interface{}) error {
@ -185,6 +185,9 @@ func resourceVinsDelete(d *schema.ResourceData, m interface{}) error {
vinsFacts, err := utilityVinsCheckPresence(d, m) vinsFacts, err := utilityVinsCheckPresence(d, m)
if vinsFacts == "" { if vinsFacts == "" {
if err != nil {
return err
}
// the specified ViNS does not exist - in this case according to Terraform best practice // the specified ViNS does not exist - in this case according to Terraform best practice
// we exit from Destroy method without error // we exit from Destroy method without error
return nil return nil
@ -192,8 +195,8 @@ func resourceVinsDelete(d *schema.ResourceData, m interface{}) error {
params := &url.Values{} params := &url.Values{}
params.Add("vinsId", d.Id()) params.Add("vinsId", d.Id())
params.Add("force", "1") // disconnect all computes before deleting ViNS params.Add("force", "1") // disconnect all computes before deleting ViNS
params.Add("permanently", "1") // delete ViNS immediately bypassing recycle bin params.Add("permanently", "1") // delete ViNS immediately bypassing recycle bin
controller := m.(*ControllerCfg) controller := m.(*ControllerCfg)
_, err = controller.decortAPICall("POST", VinsDeleteAPI, params) _, err = controller.decortAPICall("POST", VinsDeleteAPI, params)
@ -222,10 +225,10 @@ func resourceVinsExists(d *schema.ResourceData, m interface{}) (bool, error) {
func resourceVinsSchemaMake() map[string]*schema.Schema { func resourceVinsSchemaMake() map[string]*schema.Schema {
rets := map[string]*schema.Schema{ rets := map[string]*schema.Schema{
"name": { "name": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
ValidateFunc: validation.StringIsNotEmpty, ValidateFunc: validation.StringIsNotEmpty,
Description: "Name of the ViNS. Names are case sensitive and unique within the context of an account or resource group.", Description: "Name of the ViNS. Names are case sensitive and unique within the context of an account or resource group.",
}, },
/* we do not need ViNS ID as an argument because if we already know this ID, it is not practical to call resource provider. /* we do not need ViNS ID as an argument because if we already know this ID, it is not practical to call resource provider.
@ -246,25 +249,25 @@ func resourceVinsSchemaMake() map[string]*schema.Schema {
}, },
"account_id": { "account_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
ForceNew: true, ForceNew: true,
ValidateFunc: validation.IntAtLeast(1), ValidateFunc: validation.IntAtLeast(1),
Description: "ID of the account, which this ViNS belongs to. For ViNS created at account level, resource group ID is 0.", Description: "ID of the account, which this ViNS belongs to. For ViNS created at account level, resource group ID is 0.",
}, },
"ext_net_id": { "ext_net_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
ValidateFunc: validation.IntAtLeast(0), ValidateFunc: validation.IntAtLeast(0),
Description: "ID of the external network this ViNS is connected to. Pass 0 if no external connection required.", Description: "ID of the external network this ViNS is connected to. Pass 0 if no external connection required.",
}, },
"ipcidr": { "ipcidr": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
DiffSuppressFunc: ipcidrDiffSupperss, DiffSuppressFunc: ipcidrDiffSupperss,
Description: "Network address to use by this ViNS. This parameter is only valid when creating new ViNS.", Description: "Network address to use by this ViNS. This parameter is only valid when creating new ViNS.",
}, },
"description": { "description": {

@ -332,22 +332,13 @@ func resourceVirtualImage() *schema.Resource {
CustomizeDiff: customdiff.All( CustomizeDiff: customdiff.All(
customdiff.IfValueChange("enabled", func(old, new, meta interface{}) bool { customdiff.IfValueChange("enabled", func(old, new, meta interface{}) bool {
if old.(bool) != new.(bool) { return old.(bool) != new.(bool)
return true
}
return false
}, resourceImageChangeEnabled), }, resourceImageChangeEnabled),
customdiff.IfValueChange("link_to", func(old, new, meta interface{}) bool { customdiff.IfValueChange("link_to", func(old, new, meta interface{}) bool {
if old.(int) != new.(int) { return old.(int) != new.(int)
return true
}
return false
}, resourceImageLink), }, resourceImageLink),
customdiff.IfValueChange("name", func(old, new, meta interface{}) bool { customdiff.IfValueChange("name", func(old, new, meta interface{}) bool {
if old.(string) != new.(string) && old.(string) != "" { return old.(string) != new.(string) && old.(string) != ""
return true
}
return false
}, resourceImageEditName), }, resourceImageEditName),
customdiff.IfValueChange("shared_with", func(old, new, meta interface{}) bool { customdiff.IfValueChange("shared_with", func(old, new, meta interface{}) bool {
o := old.([]interface{}) o := old.([]interface{})
@ -364,16 +355,10 @@ func resourceVirtualImage() *schema.Resource {
count++ count++
} }
} }
if count == 0 { return count == 0
return true
}
return false
}, resourceImageShare), }, resourceImageShare),
customdiff.IfValueChange("computeci_id", func(old, new, meta interface{}) bool { customdiff.IfValueChange("computeci_id", func(old, new, meta interface{}) bool {
if old.(int) != new.(int) { return old.(int) != new.(int)
return true
}
return false
}, resourceImageChangeComputeci), }, resourceImageChangeComputeci),
customdiff.IfValueChange("enabled_stacks", func(old, new, meta interface{}) bool { customdiff.IfValueChange("enabled_stacks", func(old, new, meta interface{}) bool {
o := old.([]interface{}) o := old.([]interface{})
@ -390,10 +375,7 @@ func resourceVirtualImage() *schema.Resource {
count++ count++
} }
} }
if count == 0 { return count == 0
return true
}
return false
}, resourceImageUpdateNodes), }, resourceImageUpdateNodes),
), ),

@ -1,104 +0,0 @@
/*
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package decort
import (
"fmt"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
)
/*
func makeSshKeysConfig(arg_list []interface{}) (sshkeys []SshKeyConfig, count int) {
count = len(arg_list)
if count < 1 {
return nil, 0
}
sshkeys = make([]SshKeyConfig, count)
var subres_data map[string]interface{}
for index, value := range arg_list {
subres_data = value.(map[string]interface{})
sshkeys[index].User = subres_data["user"].(string)
sshkeys[index].SshKey = subres_data["public_key"].(string)
sshkeys[index].UserShell = subres_data["shell"].(string)
}
return sshkeys, count
}
*/
func makeSshKeysArgString(arg_list []interface{}) string {
// This function expects arg_list = data.Get("ssh_keys"), where "data" is a populated schema for Compute
// Resource (see func resourceCompute() definition) or Compute Data Source (see func dataSourceCompute())
// Prepare a string with username and public ssh key value in a format recognized by cloud-init utility.
// It is designed to be passed as "userdata" argument of virtual machine create API call.
// The following format is expected:
// '{"users": [{"ssh-authorized-keys": ["SSH_PUBCIC_KEY_VALUE"], "shell": "SHELL_VALUE", "name": "USERNAME_VALUE"}, {...}, ]}'
/*
`%s\n
- name: %s\n
ssh-authorized-keys:
- %s\n
shell: /bin/bash`
*/
if len(arg_list) < 1 {
return ""
}
out := `{"users": [`
const UserdataTemplate = `%s{"ssh-authorized-keys": ["%s"], "shell": "%s", "name": "%s"}, `
const out_suffix = `]}`
for _, value := range arg_list {
subres_data := value.(map[string]interface{})
out = fmt.Sprintf(UserdataTemplate, out, subres_data["public_key"].(string), subres_data["shell"].(string), subres_data["user"].(string))
}
out = fmt.Sprintf("%s %s", out, out_suffix)
return out
}
func sshSubresourceSchemaMake() map[string]*schema.Schema {
rets := map[string]*schema.Schema{
"user": {
Type: schema.TypeString,
Required: true,
Description: "Name of the guest OS user of a new compute, for which the following SSH key will be authorized.",
},
"public_key": {
Type: schema.TypeString,
Required: true,
Description: "Public SSH key to authorize to the specified guest OS user on the compute being created.",
},
"shell": {
Type: schema.TypeString,
Optional: true,
Default: "/bin/bash",
Description: "Guest user shell. This parameter is optional, default is /bin/bash.",
},
}
return rets
}

@ -1,6 +1,6 @@
/* /*
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com> Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -26,131 +26,35 @@ package decort
import ( import (
"encoding/json" "encoding/json"
"fmt"
"net/url" "net/url"
"strconv"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/schema"
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
) )
func utilityAccountCheckPresence(d *schema.ResourceData, m interface{}) (string, error) { func utilityAccountCheckPresence(d *schema.ResourceData, m interface{}) (*AccountWithResources, error) {
account := &AccountWithResources{}
controller := m.(*ControllerCfg) controller := m.(*ControllerCfg)
urlValues := &url.Values{} urlValues := &url.Values{}
accId, argSet := d.GetOk("account_id") if (strconv.Itoa(d.Get("account_id").(int))) != "0" {
if argSet { urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
// get Account right away by its ID } else {
log.Debugf("utilityAccountCheckPresence: locating Account by its ID %d", accId.(int)) urlValues.Add("accountId", d.Id())
urlValues.Add("accountId", fmt.Sprintf("%d", accId.(int)))
apiResp, err := controller.decortAPICall("POST", AccountsGetAPI, urlValues)
if err != nil {
return "", err
}
return apiResp, nil
} }
accName, argSet := d.GetOk("name") log.Debugf("utilityAccountCheckPresence: load account")
if !argSet { accountRaw, err := controller.decortAPICall("POST", accountGetAPI, urlValues)
// neither ID nor name - no account for you!
return "", fmt.Errorf("Cannot check account presence if name is empty and no account ID specified")
}
apiResp, err := controller.decortAPICall("POST", AccountsListAPI, urlValues)
if err != nil {
return "", err
}
// log.Debugf("%s", apiResp)
// log.Debugf("utilityAccountCheckPresence: ready to decode response body from %q", AccountsListAPI)
accList := AccountsListResp{}
err = json.Unmarshal([]byte(apiResp), &accList)
if err != nil { if err != nil {
return "", err return nil, err
}
log.Debugf("utilityAccountCheckPresence: traversing decoded Json of length %d", len(accList))
for index, item := range accList {
// match by account name
if item.Name == accName.(string) {
log.Debugf("utilityAccountCheckPresence: match account name %q / ID %d at index %d",
item.Name, item.ID, index)
// NB: unlike accounts/get API, accounts/list API returns abridged set of account info,
// for instance it does not return quotas
reencodedItem, err := json.Marshal(item)
if err != nil {
return "", err
}
return string(reencodedItem[:]), nil
}
} }
return "", fmt.Errorf("Cannot find account name %q", accName.(string)) err = json.Unmarshal([]byte(accountRaw), &account)
}
func utilityGetAccountIdBySchema(d *schema.ResourceData, m interface{}) (int, error) {
/*
This function expects schema that contains the following two elements:
"account_name": &schema.Schema{
Type: schema.TypeString,
Required: Optional,
Description: "Name of the account, ....",
},
"account_id": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Description: "Unique ID of the account, ....",
},
Then it will check, which argument is set, and if account name is present, it will
initiate API calls to the DECORT cloud controller and try to match relevant account
by the name.
NOTE that for some resources (most notably, Resource Group) "account_name" attribute is
marked as "Computed: true", so the only way to fully identify Resource Group is to specify
"account_id", which is marked as "Required: true"
*/
accId, argSet := d.GetOk("account_id")
if argSet {
if accId.(int) > 0 {
return accId.(int), nil
}
return 0, fmt.Errorf("Account ID must be positive")
}
accName, argSet := d.GetOk("account_name")
if !argSet {
return 0, fmt.Errorf("Either non-empty account name or valid account ID must be specified")
}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
apiResp, err := controller.decortAPICall("POST", AccountsListAPI, urlValues)
if err != nil {
return 0, err
}
model := AccountsListResp{}
err = json.Unmarshal([]byte(apiResp), &model)
if err != nil { if err != nil {
return 0, err return nil, err
}
log.Debugf("utilityGetAccountIdBySchema: traversing decoded Json of length %d", len(model))
for index, item := range model {
// need to match Account by name
if item.Name == accName.(string) {
log.Debugf("utilityGetAccountIdBySchema: match Account name %q / ID %d at index %d",
item.Name, item.ID, index)
return item.ID, nil
}
} }
return 0, fmt.Errorf("Cannot find account %q for the current user. Check account name and your access rights", accName.(string)) return account, nil
} }

@ -0,0 +1,56 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityAccountAuditsListCheckPresence(d *schema.ResourceData, m interface{}) (AccountAuditsList, error) {
accountAuditsList := AccountAuditsList{}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
log.Debugf("utilityAccountAuditsListCheckPresence: load account list")
accountAuditsListRaw, err := controller.decortAPICall("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,56 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityAccountComputesListCheckPresence(d *schema.ResourceData, m interface{}) (AccountComputesList, error) {
accountComputesList := AccountComputesList{}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
log.Debugf("utilityAccountComputesListCheckPresence: load account list")
accountComputesListRaw, err := controller.decortAPICall("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,56 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityAccountConsumedUnitsCheckPresence(d *schema.ResourceData, m interface{}) (*ResourceLimits, error) {
accountConsumedUnits := &ResourceLimits{}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
log.Debugf("utilityAccountConsumedUnitsCheckPresence: load account list")
accountConsumedUnitsRaw, err := controller.decortAPICall("POST", accountGetConsumedUnitsAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(accountConsumedUnitsRaw), accountConsumedUnits)
if err != nil {
return nil, err
}
return accountConsumedUnits, nil
}

@ -0,0 +1,55 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"net/url"
"strconv"
"strings"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityAccountConsumedUnitsByTypeCheckPresence(d *schema.ResourceData, m interface{}) (float64, error) {
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
urlValues.Add("cutype", strings.ToUpper(d.Get("cu_type").(string)))
log.Debugf("utilityAccountConsumedUnitsByTypeCheckPresence")
resultRaw, err := controller.decortAPICall("POST", accountGetConsumedUnitsByTypeAPI, urlValues)
if err != nil {
return 0, err
}
result, err := strconv.ParseFloat(resultRaw, 64)
if err != nil {
return 0, err
}
return result, nil
}

@ -0,0 +1,61 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityAccountDeletedListCheckPresence(d *schema.ResourceData, m interface{}) (AccountCloudApiList, error) {
accountDeletedList := AccountCloudApiList{}
controller := m.(*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 := controller.decortAPICall("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,56 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityAccountDisksListCheckPresence(d *schema.ResourceData, m interface{}) (AccountDisksList, error) {
accountDisksList := AccountDisksList{}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
log.Debugf("utilityAccountDisksListCheckPresence: load account list")
accountDisksListRaw, err := controller.decortAPICall("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,56 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityAccountFlipGroupsListCheckPresence(d *schema.ResourceData, m interface{}) (AccountFlipGroupsList, error) {
accountFlipGroupsList := AccountFlipGroupsList{}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
log.Debugf("utilityAccountFlipGroupsListCheckPresence")
accountFlipGroupsListRaw, err := controller.decortAPICall("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,89 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityAccountListCheckPresence(d *schema.ResourceData, m interface{}) (AccountCloudApiList, error) {
accountList := AccountCloudApiList{}
controller := m.(*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 := controller.decortAPICall("POST", accountListAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(accountListRaw), &accountList)
if err != nil {
return nil, err
}
return accountList, nil
}
/*uncomment for cloudbroker
func utilityAccountListCheckPresence(d *schema.ResourceData, m interface{}) (AccountList, error) {
accountList := AccountList{}
controller := m.(*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 := controller.decortAPICall("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,56 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityAccountReservedUnitsCheckPresence(d *schema.ResourceData, m interface{}) (*ResourceLimits, error) {
accountReservedUnits := &ResourceLimits{}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
log.Debugf("utilityAccountReservedUnitsCheckPresence: load units")
accountReservedUnitsRaw, err := controller.decortAPICall("POST", accountGetReservedUnitsAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(accountReservedUnitsRaw), accountReservedUnits)
if err != nil {
return nil, err
}
return accountReservedUnits, nil
}

@ -0,0 +1,56 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityAccountRGListCheckPresence(d *schema.ResourceData, m interface{}) (AccountRGList, error) {
accountRGList := AccountRGList{}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
log.Debugf("utilityAccountRGListCheckPresence: load account list")
accountRGListRaw, err := controller.decortAPICall("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,56 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityAccountTemplatesListCheckPresence(d *schema.ResourceData, m interface{}) (AccountTemplatesList, error) {
accountTemplatesList := AccountTemplatesList{}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
log.Debugf("utilityAccountTemplatesListCheckPresence: load")
accountTemplatesListRaw, err := controller.decortAPICall("POST", accountListTemplatesAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(accountTemplatesListRaw), &accountTemplatesList)
if err != nil {
return nil, err
}
return accountTemplatesList, nil
}

@ -0,0 +1,56 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityAccountVinsListCheckPresence(d *schema.ResourceData, m interface{}) (AccountVinsList, error) {
accountVinsList := AccountVinsList{}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
log.Debugf("utilityAccountVinsListCheckPresence: load account list")
accountVinsListRaw, err := controller.decortAPICall("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,67 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityBasicServiceDeletedListCheckPresence(d *schema.ResourceData, m interface{}) (BasicServiceList, error) {
basicServiceDeletedList := BasicServiceList{}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
if accountId, ok := d.GetOk("account_id"); ok {
urlValues.Add("accountId", strconv.Itoa(accountId.(int)))
}
if rgId, ok := d.GetOk("rg_id"); ok {
urlValues.Add("rgId", strconv.Itoa(rgId.(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("utilityBasicServiceDeletedListCheckPresence")
basicServiceDeletedListRaw, err := controller.decortAPICall("POST", bserviceListDeletedAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(basicServiceDeletedListRaw), &basicServiceDeletedList)
if err != nil {
return nil, err
}
return basicServiceDeletedList, nil
}

@ -0,0 +1,60 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityBasicServiceCheckPresence(d *schema.ResourceData, m interface{}) (*BasicServiceExtend, error) {
bservice := &BasicServiceExtend{}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
if (strconv.Itoa(d.Get("service_id").(int))) != "0" {
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
} else {
urlValues.Add("serviceId", d.Id())
}
log.Debugf("utilityBasicServiceCheckPresence")
bserviceRaw, err := controller.decortAPICall("POST", bserviceGetAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(bserviceRaw), &bservice)
if err != nil {
return nil, err
}
return bservice, nil
}

@ -0,0 +1,61 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityBasicServiceGroupCheckPresence(d *schema.ResourceData, m interface{}) (*BasicServiceGroup, error) {
bserviceGroup := &BasicServiceGroup{}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
if (strconv.Itoa(d.Get("compgroup_id").(int))) != "0" {
urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int)))
} else {
urlValues.Add("compgroupId", d.Id())
}
log.Debugf("utilityBasicServiceGroupCheckPresence")
bserviceGroupRaw, err := controller.decortAPICall("POST", bserviceGroupGetAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(bserviceGroupRaw), &bserviceGroup)
if err != nil {
return nil, err
}
return bserviceGroup, nil
}

@ -0,0 +1,67 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityBasicServiceListCheckPresence(d *schema.ResourceData, m interface{}) (BasicServiceList, error) {
basicServiceList := BasicServiceList{}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
if accountId, ok := d.GetOk("account_id"); ok {
urlValues.Add("accountId", strconv.Itoa(accountId.(int)))
}
if rgId, ok := d.GetOk("rg_id"); ok {
urlValues.Add("rgId", strconv.Itoa(rgId.(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("utilityBasicServiceListCheckPresence")
basicServiceListRaw, err := controller.decortAPICall("POST", bserviceListAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(basicServiceListRaw), &basicServiceList)
if err != nil {
return nil, err
}
return basicServiceList, nil
}

@ -0,0 +1,58 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityBasicServiceSnapshotListCheckPresence(d *schema.ResourceData, m interface{}) (BasicServiceSnapshots, error) {
basicServiceSnapshotList := BasicServiceSnapshots{}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
if serviceId, ok := d.GetOk("service_id"); ok {
urlValues.Add("serviceId", strconv.Itoa(serviceId.(int)))
}
log.Debugf("utilityBasicServiceSnapshotListCheckPresence")
basicServiceSnapshotListRaw, err := controller.decortAPICall("POST", bserviceSnapshotListAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(basicServiceSnapshotListRaw), &basicServiceSnapshotList)
if err != nil {
return nil, err
}
return basicServiceSnapshotList, nil
}

@ -38,14 +38,14 @@ import (
func (ctrl *ControllerCfg) utilityComputeExtraDisksConfigure(d *schema.ResourceData, do_delta bool) error { func (ctrl *ControllerCfg) utilityComputeExtraDisksConfigure(d *schema.ResourceData, do_delta bool) error {
// d is filled with data according to computeResource schema, so extra disks config is retrieved via "extra_disks" key // 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 // 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 // update compute configuration accordingly
// Otherwise it will apply whatever is found in the new set of "extra_disks" right away. // 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. // 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 // 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. // disks via atomic API calls. However, it will not retry failed manipulation on the same disk.
log.Debugf("utilityComputeExtraDisksConfigure: called for Compute ID %s with do_delta = %b", d.Id(), do_delta) 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 // NB: as of rc-1.25 "extra_disks" are TypeSet with the elem of TypeInt
old_set, new_set := d.GetChange("extra_disks") old_set, new_set := d.GetChange("extra_disks")
@ -71,11 +71,11 @@ func (ctrl *ControllerCfg) utilityComputeExtraDisksConfigure(d *schema.ResourceD
} }
if apiErrCount > 0 { if apiErrCount > 0 {
log.Errorf("utilityComputeExtraDisksConfigure: there were %d error(s) when attaching disks to Compute ID %s. Last error was: %s", log.Errorf("utilityComputeExtraDisksConfigure: there were %d error(s) when attaching disks to Compute ID %s. Last error was: %s",
apiErrCount, d.Id(), lastSavedError) apiErrCount, d.Id(), lastSavedError)
return lastSavedError return lastSavedError
} }
return nil return nil
} }
@ -110,8 +110,8 @@ func (ctrl *ControllerCfg) utilityComputeExtraDisksConfigure(d *schema.ResourceD
} }
if apiErrCount > 0 { if apiErrCount > 0 {
log.Errorf("utilityComputeExtraDisksConfigure: there were %d error(s) when managing disks of Compute ID %s. Last error was: %s", log.Errorf("utilityComputeExtraDisksConfigure: there were %d error(s) when managing disks of Compute ID %s. Last error was: %s",
apiErrCount, d.Id(), lastSavedError) apiErrCount, d.Id(), lastSavedError)
return lastSavedError return lastSavedError
} }
@ -120,11 +120,11 @@ func (ctrl *ControllerCfg) utilityComputeExtraDisksConfigure(d *schema.ResourceD
func (ctrl *ControllerCfg) utilityComputeNetworksConfigure(d *schema.ResourceData, do_delta bool) error { func (ctrl *ControllerCfg) utilityComputeNetworksConfigure(d *schema.ResourceData, do_delta bool) error {
// "d" is filled with data according to computeResource schema, so extra networks config is retrieved via "network" key // "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 // If do_delta is true, this function will identify changes between new and existing specs for network and try to
// update compute configuration accordingly // update compute configuration accordingly
// Otherwise it will apply whatever is found in the new set of "network" right away. // 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. // Primary use of do_delta=false is when calling this function from compute Create handler.
old_set, new_set := d.GetChange("network") old_set, new_set := d.GetChange("network")
apiErrCount := 0 apiErrCount := 0
@ -137,7 +137,7 @@ func (ctrl *ControllerCfg) utilityComputeNetworksConfigure(d *schema.ResourceDat
for _, runner := range new_set.(*schema.Set).List() { for _, runner := range new_set.(*schema.Set).List() {
urlValues := &url.Values{} urlValues := &url.Values{}
net_data := runner.(map[string]interface{}) net_data := runner.(map[string]interface{})
urlValues.Add("computeId", d.Id()) urlValues.Add("computeId", d.Id())
urlValues.Add("netType", net_data["net_type"].(string)) urlValues.Add("netType", net_data["net_type"].(string))
urlValues.Add("netId", fmt.Sprintf("%d", net_data["net_id"].(int))) urlValues.Add("netId", fmt.Sprintf("%d", net_data["net_id"].(int)))
@ -154,8 +154,8 @@ func (ctrl *ControllerCfg) utilityComputeNetworksConfigure(d *schema.ResourceDat
} }
if apiErrCount > 0 { if apiErrCount > 0 {
log.Errorf("utilityComputeNetworksConfigure: there were %d error(s) when managing networks of Compute ID %s. Last error was: %s", log.Errorf("utilityComputeNetworksConfigure: there were %d error(s) when managing networks of Compute ID %s. Last error was: %s",
apiErrCount, d.Id(), lastSavedError) apiErrCount, d.Id(), lastSavedError)
return lastSavedError return lastSavedError
} }
return nil return nil
@ -172,8 +172,8 @@ func (ctrl *ControllerCfg) utilityComputeNetworksConfigure(d *schema.ResourceDat
_, err := ctrl.decortAPICall("POST", ComputeNetDetachAPI, urlValues) _, err := ctrl.decortAPICall("POST", ComputeNetDetachAPI, urlValues)
if err != nil { if err != nil {
// failed to detach this network - there will be partial resource update // 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", 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) net_data["net_id"].(int), net_data["net_type"].(string), d.Id(), err)
apiErrCount++ apiErrCount++
lastSavedError = err lastSavedError = err
} }
@ -185,7 +185,7 @@ func (ctrl *ControllerCfg) utilityComputeNetworksConfigure(d *schema.ResourceDat
urlValues := &url.Values{} urlValues := &url.Values{}
net_data := runner.(map[string]interface{}) net_data := runner.(map[string]interface{})
urlValues.Add("computeId", d.Id()) urlValues.Add("computeId", d.Id())
urlValues.Add("netId", fmt.Sprintf("%d",net_data["net_id"].(int))) urlValues.Add("netId", fmt.Sprintf("%d", net_data["net_id"].(int)))
urlValues.Add("netType", net_data["net_type"].(string)) urlValues.Add("netType", net_data["net_type"].(string))
if net_data["ip_address"].(string) != "" { if net_data["ip_address"].(string) != "" {
urlValues.Add("ipAddr", net_data["ip_address"].(string)) urlValues.Add("ipAddr", net_data["ip_address"].(string))
@ -193,16 +193,16 @@ func (ctrl *ControllerCfg) utilityComputeNetworksConfigure(d *schema.ResourceDat
_, err := ctrl.decortAPICall("POST", ComputeNetAttachAPI, urlValues) _, err := ctrl.decortAPICall("POST", ComputeNetAttachAPI, urlValues)
if err != nil { if err != nil {
// failed to attach this network - there will be partial resource update // 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", 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) net_data["net_id"].(int), net_data["net_type"].(string), d.Id(), err)
apiErrCount++ apiErrCount++
lastSavedError = err lastSavedError = err
} }
} }
if apiErrCount > 0 { if apiErrCount > 0 {
log.Errorf("utilityComputeNetworksConfigure: there were %d error(s) when managing networks of Compute ID %s. Last error was: %s", log.Errorf("utilityComputeNetworksConfigure: there were %d error(s) when managing networks of Compute ID %s. Last error was: %s",
apiErrCount, d.Id(), lastSavedError) apiErrCount, d.Id(), lastSavedError)
return lastSavedError return lastSavedError
} }
@ -262,7 +262,7 @@ func utilityComputeCheckPresence(d *schema.ResourceData, m interface{}) (string,
if !argSet { if !argSet {
return "", fmt.Errorf("Cannot locate compute by name %s if no resource group ID is set", computeName.(string)) 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)) urlValues.Add("rgId", fmt.Sprintf("%d", rgId))
apiResp, err := controller.decortAPICall("POST", RgListComputesAPI, urlValues) apiResp, err := controller.decortAPICall("POST", RgListComputesAPI, urlValues)
if err != nil { if err != nil {

@ -16,16 +16,15 @@ limitations under the License.
*/ */
/* /*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom. Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates. Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/ */
package decort package decort
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/url" "net/url"
@ -36,16 +35,15 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/schema"
) )
func utilityDiskCheckPresence(d *schema.ResourceData, m interface{}) (string, error) { func utilityDiskCheckPresence(d *schema.ResourceData, m interface{}) (string, error) {
// This function tries to locate Disk by one of the following algorithms depending on // This function tries to locate Disk by one of the following algorithms depending on
// the parameters passed: // the parameters passed:
// - if disk ID is specified -> by disk ID // - if disk ID is specified -> by disk ID
// - if disk name is specifeid -> by disk name and either account ID or account name // - if disk name is specifeid -> by disk name and either account ID or account name
// //
// NOTE: disk names are not unique, so the first occurence of this name in the account will // NOTE: disk names are not unique, so the first occurence of this name in the account will
// be returned. There is no such ambiguity when locating disk by its ID. // be returned. There is no such ambiguity when locating disk by its ID.
// //
// If succeeded, it returns non empty string that contains JSON formatted facts about the disk // If succeeded, it returns non empty string that contains JSON formatted facts about the disk
// as returned by disks/get API call. // as returned by disks/get API call.
// Otherwise it returns empty string and meaningful error. // Otherwise it returns empty string and meaningful error.
@ -64,7 +62,7 @@ func utilityDiskCheckPresence(d *schema.ResourceData, m interface{}) (string, er
if err != nil || theId <= 0 { if err != nil || theId <= 0 {
diskId, argSet := d.GetOk("disk_id") diskId, argSet := d.GetOk("disk_id")
if argSet { if argSet {
theId =diskId.(int) theId = diskId.(int)
idSet = true idSet = true
} }
} else { } else {
@ -92,18 +90,14 @@ func utilityDiskCheckPresence(d *schema.ResourceData, m interface{}) (string, er
// Valid account ID is required to locate disks // Valid account ID is required to locate disks
// obtain Account ID by account name - it should not be zero on success // obtain Account ID by account name - it should not be zero on success
validatedAccountId, err := utilityGetAccountIdBySchema(d, m)
if err != nil {
return "", err
}
urlValues.Add("accountId", fmt.Sprintf("%d", validatedAccountId)) urlValues.Add("accountId", fmt.Sprintf("%d", d.Get("account_id").(int)))
diskFacts, err := controller.decortAPICall("POST", DisksListAPI, urlValues) diskFacts, err := controller.decortAPICall("POST", DisksListAPI, urlValues)
if err != nil { if err != nil {
return "", err return "", err
} }
log.Debugf("utilityDiskCheckPresence: ready to unmarshal string %s", diskFacts) log.Debugf("utilityDiskCheckPresence: ready to unmarshal string %s", diskFacts)
disksList := DisksListResp{} disksList := DisksListResp{}
err = json.Unmarshal([]byte(diskFacts), &disksList) err = json.Unmarshal([]byte(diskFacts), &disksList)
@ -119,25 +113,25 @@ func utilityDiskCheckPresence(d *schema.ResourceData, m interface{}) (string, er
log.Debugf("utilityDiskCheckPresence: index %d, matched disk name %q", index, item.Name) log.Debugf("utilityDiskCheckPresence: index %d, matched disk name %q", index, item.Name)
// we found the disk we need - not get detailed information via API call to disks/get // we found the disk we need - not get detailed information via API call to disks/get
/* /*
// TODO: this may not be optimal as it initiates one extra call to the DECORT controller // TODO: this may not be optimal as it initiates one extra call to the DECORT controller
// in spite of the fact that we already have all required information about the disk in // in spite of the fact that we already have all required information about the disk in
// item variable // item variable
// //
get_urlValues := &url.Values{} get_urlValues := &url.Values{}
get_urlValues.Add("diskId", fmt.Sprintf("%d", item.ID)) get_urlValues.Add("diskId", fmt.Sprintf("%d", item.ID))
diskFacts, err = controller.decortAPICall("POST", DisksGetAPI, get_urlValues) diskFacts, err = controller.decortAPICall("POST", DisksGetAPI, get_urlValues)
if err != nil { if err != nil {
return "", err return "", err
} }
return diskFacts, nil return diskFacts, nil
*/ */
reencodedItem, err := json.Marshal(item) reencodedItem, err := json.Marshal(item)
if err != nil { if err != nil {
return "", err return "", err
} }
return string(reencodedItem[:]), nil return string(reencodedItem[:]), nil
} }
} }
return "", nil // there should be no error if disk does not exist return "", nil // there should be no error if disk does not exist
} }

@ -0,0 +1,68 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
"strings"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityDiskListCheckPresence(d *schema.ResourceData, m interface{}) (DisksListResp, error) {
diskList := DisksListResp{}
controller := m.(*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 grid list")
diskListRaw, err := controller.decortAPICall("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,56 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityExtnetCheckPresence(d *schema.ResourceData, m interface{}) (*ExtnetDetailed, error) {
extnet := &ExtnetDetailed{}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("net_id", strconv.Itoa(d.Get("net_id").(int)))
log.Debugf("utilityExtnetCheckPresence")
extnetRaw, err := controller.decortAPICall("POST", extnetGetAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(extnetRaw), &extnet)
if err != nil {
return nil, err
}
return extnet, nil
}

@ -0,0 +1,56 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityExtnetComputesListCheckPresence(d *schema.ResourceData, m interface{}) (ExtnetComputesList, error) {
extnetComputesList := ExtnetComputesList{}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
log.Debugf("utilityExtnetComputesListCheckPresence")
extnetComputesListRaw, err := controller.decortAPICall("POST", extnetListComputesAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(extnetComputesListRaw), &extnetComputesList)
if err != nil {
return nil, err
}
return extnetComputesList, nil
}

@ -0,0 +1,46 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"net/url"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityExtnetDefaultCheckPresence(_ *schema.ResourceData, m interface{}) (string, error) {
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
log.Debugf("utilityExtnetDefaultCheckPresence")
res, err := controller.decortAPICall("POST", extnetGetDefaultAPI, urlValues)
if err != nil {
return "", err
}
return res, nil
}

@ -0,0 +1,64 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityExtnetListCheckPresence(d *schema.ResourceData, m interface{}) (ExtnetList, error) {
extnetList := ExtnetList{}
controller := m.(*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("utilityExtnetListCheckPresence")
extnetListRaw, err := controller.decortAPICall("POST", extnetListAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(extnetListRaw), &extnetList)
if err != nil {
return nil, err
}
return extnetList, nil
}

@ -1,48 +0,0 @@
/*
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"strings"
)
func Jo2JSON(arg_str string) string {
// DECORT API historically returns response in the form of Python dictionary, which generally
// looks like JSON, but does not comply with JSON syntax.
// For Golang JSON Unmarshal to work properly we need to pre-process API response as follows:
ret_string := strings.Replace(string(arg_str), "u'", "\"", -1)
ret_string = strings.Replace(ret_string, "'", "\"", -1)
ret_string = strings.Replace(ret_string, ": False", ": false", -1)
ret_string = strings.Replace(ret_string, ": True", ": true", -1)
ret_string = strings.Replace(ret_string, "null", "\"\"", -1)
ret_string = strings.Replace(ret_string, "None", "\"\"", -1)
// fix for incorrect handling of usage info
// ret_string = strings.Replace(ret_string, "<", "\"", -1)
// ret_string = strings.Replace(ret_string, ">", "\"", -1)
return ret_string
}

@ -27,7 +27,6 @@ package decort
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"net/url" "net/url"
"strconv" "strconv"
@ -44,7 +43,7 @@ func utilityGridCheckPresence(d *schema.ResourceData, m interface{}) (*Grid, err
if gridId, ok := d.GetOk("grid_id"); ok { if gridId, ok := d.GetOk("grid_id"); ok {
urlValues.Add("gridId", strconv.Itoa(gridId.(int))) urlValues.Add("gridId", strconv.Itoa(gridId.(int)))
} else { } else {
return nil, errors.New(fmt.Sprintf("grid_id is required")) return nil, errors.New("grid_id is required")
} }
log.Debugf("utilityGridCheckPresence: load grid") log.Debugf("utilityGridCheckPresence: load grid")

@ -43,21 +43,12 @@ func utilityPcideviceCheckPresence(d *schema.ResourceData, m interface{}) (*Pcid
id, _ := strconv.Atoi(d.Id()) id, _ := strconv.Atoi(d.Id())
pcideviceId = id pcideviceId = id
} }
pcidevice := &Pcidevice{}
flag := false
for _, pd := range pcideviceList { for _, pd := range pcideviceList {
if pd.ID == pcideviceId { if pd.ID == pcideviceId {
pcidevice = &pd return &pd, nil
flag = true
break
} }
} }
if !flag { return nil, nil
return nil, nil
}
return pcidevice, nil
} }

@ -31,7 +31,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/schema"
) )
func utilityPcideviceListCheckPresence(d *schema.ResourceData, m interface{}) (PcideviceList, error) { func utilityPcideviceListCheckPresence(_ *schema.ResourceData, m interface{}) (PcideviceList, error) {
pcideviceList := PcideviceList{} pcideviceList := PcideviceList{}
controller := m.(*ControllerCfg) controller := m.(*ControllerCfg)
urlValues := &url.Values{} urlValues := &url.Values{}

@ -36,38 +36,6 @@ import (
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation" // "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
) )
func (ctrl *ControllerCfg) utilityResgroupConfigGet(rgid int) (*ResgroupGetResp, error) {
urlValues := &url.Values{}
urlValues.Add("rgId", fmt.Sprintf("%d", rgid))
rgFacts, err := ctrl.decortAPICall("POST", ResgroupGetAPI, urlValues)
if err != nil {
return nil, err
}
log.Debugf("utilityResgroupConfigGet: ready to unmarshal string %s", rgFacts)
model := &ResgroupGetResp{}
err = json.Unmarshal([]byte(rgFacts), model)
if err != nil {
return nil, err
}
/*
ret := &ResgroupConfig{}
ret.AccountID = model.AccountID
ret.Location = model.Location
ret.Name = model.Name
ret.ID = rgid
ret.GridID = model.GridID
ret.ExtIP = model.ExtIP // legacy field for VDC - this will eventually become obsoleted by true Resource Groups
// Quota ResgroupQuotaConfig
// Network NetworkConfig
*/
log.Debugf("utilityResgroupConfigGet: account ID %d, GridID %d, Name %s",
model.AccountID, model.GridID, model.Name)
return model, nil
}
// On success this function returns a string, as returned by API rg/get, which could be unmarshalled // On success this function returns a string, as returned by API rg/get, which could be unmarshalled
// into ResgroupGetResp structure // into ResgroupGetResp structure
func utilityResgroupCheckPresence(d *schema.ResourceData, m interface{}) (string, error) { func utilityResgroupCheckPresence(d *schema.ResourceData, m interface{}) (string, error) {
@ -104,7 +72,7 @@ func utilityResgroupCheckPresence(d *schema.ResourceData, m interface{}) (string
} else { } else {
idSet = true idSet = true
} }
if idSet { if idSet {
// go straight for the RG by its ID // go straight for the RG by its ID
log.Debugf("utilityResgroupCheckPresence: locating RG by its ID %d", theId) log.Debugf("utilityResgroupCheckPresence: locating RG by its ID %d", theId)
@ -124,10 +92,6 @@ func utilityResgroupCheckPresence(d *schema.ResourceData, m interface{}) (string
// Valid account ID is required to locate a resource group // Valid account ID is required to locate a resource group
// obtain Account ID by account name - it should not be zero on success // obtain Account ID by account name - it should not be zero on success
validatedAccountId, err := utilityGetAccountIdBySchema(d, m)
if err != nil {
return "", err
}
urlValues.Add("includedeleted", "false") urlValues.Add("includedeleted", "false")
apiResp, err := controller.decortAPICall("POST", ResgroupListAPI, urlValues) apiResp, err := controller.decortAPICall("POST", ResgroupListAPI, urlValues)
@ -145,7 +109,7 @@ func utilityResgroupCheckPresence(d *schema.ResourceData, m interface{}) (string
log.Debugf("utilityResgroupCheckPresence: traversing decoded Json of length %d", len(model)) log.Debugf("utilityResgroupCheckPresence: traversing decoded Json of length %d", len(model))
for index, item := range model { for index, item := range model {
// match by RG name & account ID // match by RG name & account ID
if item.Name == rgName.(string) && item.AccountID == validatedAccountId { 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", log.Debugf("utilityResgroupCheckPresence: match RG name %s / ID %d, account ID %d at index %d",
item.Name, item.ID, item.AccountID, index) item.Name, item.ID, item.AccountID, index)
@ -163,13 +127,5 @@ func utilityResgroupCheckPresence(d *schema.ResourceData, m interface{}) (string
} }
} }
return "", fmt.Errorf("Cannot find RG name %s owned by account ID %d", rgName, validatedAccountId) return "", fmt.Errorf("Cannot find RG name %s owned by account ID %d", rgName, d.Get("account_id").(int))
} }
func utilityResgroupGetDefaultGridID() (interface{}, error) {
if DefaultGridID > 0 {
return fmt.Sprintf("%d", DefaultGridID), nil
}
return "", fmt.Errorf("utilityResgroupGetDefaultGridID: invalid default Grid ID %d", DefaultGridID)
}

@ -0,0 +1,65 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityRgListCheckPresence(d *schema.ResourceData, m interface{}) (ResgroupListResp, error) {
controller := m.(*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 := controller.decortAPICall("POST", ResgroupListAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(rgListRaw), &rgList)
if err != nil {
return nil, err
}
return rgList, nil
}

@ -35,28 +35,6 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/schema"
) )
func (ctrl *ControllerCfg) utilityVinsConfigGet(vinsid int) (*VinsRecord, error) {
urlValues := &url.Values{}
urlValues.Add("vinsId", fmt.Sprintf("%d", vinsid))
vinsFacts, err := ctrl.decortAPICall("POST", VinsGetAPI, urlValues)
if err != nil {
return nil, err
}
log.Debugf("utilityVinsConfigGet: ready to unmarshal string %q", vinsFacts)
model := &VinsRecord{}
err = json.Unmarshal([]byte(vinsFacts), model)
if err != nil {
return nil, err
}
log.Debugf("utilityVinsConfigGet: Name %d, account name:ID %s:%d, RG Name:ID %s:%d",
model.Name, model.AccountName, model.AccountID,
model.RgName, model.RgID)
return model, nil
}
// On success this function returns a string, as returned by API vins/get, which could be unmarshalled // On success this function returns a string, as returned by API vins/get, which could be unmarshalled
// into VinsGetResp structure // into VinsGetResp structure
func utilityVinsCheckPresence(d *schema.ResourceData, m interface{}) (string, error) { func utilityVinsCheckPresence(d *schema.ResourceData, m interface{}) (string, error) {
@ -129,7 +107,7 @@ func utilityVinsCheckPresence(d *schema.ResourceData, m interface{}) (string, er
if err != nil { if err != nil {
return "", err return "", err
} }
// log.Debugf("%s", apiResp) // log.Debugf("%s", apiResp)
// log.Debugf("utilityResgroupCheckPresence: ready to decode response body from %s", VinsSearchAPI) // log.Debugf("utilityResgroupCheckPresence: ready to decode response body from %s", VinsSearchAPI)
model := VinsSearchResp{} model := VinsSearchResp{}
@ -141,24 +119,24 @@ func utilityVinsCheckPresence(d *schema.ResourceData, m interface{}) (string, er
log.Debugf("utilityVinsCheckPresence: traversing decoded Json of length %d", len(model)) log.Debugf("utilityVinsCheckPresence: traversing decoded Json of length %d", len(model))
for index, item := range model { for index, item := range model {
if item.Name == vinsName.(string) { if item.Name == vinsName.(string) {
if ( accountSet && item.AccountID != accountId.(int) ) || if (accountSet && item.AccountID != accountId.(int)) ||
( rgSet && item.RgID != rgId.(int) ) { (rgSet && item.RgID != rgId.(int)) {
// double check that account ID and Rg ID match, if set in the schema // double check that account ID and Rg ID match, if set in the schema
continue continue
} }
log.Debugf("utilityVinsCheckPresence: match ViNS name %s / ID %d, account ID %d, RG ID %d at index %d", log.Debugf("utilityVinsCheckPresence: match ViNS name %s / ID %d, account ID %d, RG ID %d at index %d",
item.Name, item.ID, item.AccountID, item.RgID, index) item.Name, item.ID, item.AccountID, item.RgID, index)
// element returned by API vins/search does not contain all information we may need to // element returned by API vins/search does not contain all information we may need to
// manage ViNS, so we have to get detailed info by calling API vins/get // manage ViNS, so we have to get detailed info by calling API vins/get
rqValues := &url.Values{} rqValues := &url.Values{}
rqValues.Add("vinsId", fmt.Sprintf("%d",item.ID)) rqValues.Add("vinsId", fmt.Sprintf("%d", item.ID))
vinsGetResp, err := controller.decortAPICall("POST", VinsGetAPI, rqValues) vinsGetResp, err := controller.decortAPICall("POST", VinsGetAPI, rqValues)
if err != nil { if err != nil {
return "", err return "", err
} }
return vinsGetResp, nil return vinsGetResp, nil
} }
} }

@ -0,0 +1,64 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityVinsListCheckPresence(d *schema.ResourceData, m interface{}) (VinsList, error) {
vinsList := VinsList{}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
if includeDeleted, ok := d.GetOk("include_deleted"); ok {
urlValues.Add("includeDeleted", strconv.FormatBool(includeDeleted.(bool)))
}
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("utilityVinsListCheckPresence")
vinsListRaw, err := controller.decortAPICall("POST", vinsListAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(vinsListRaw), &vinsList)
if err != nil {
return nil, err
}
return vinsList, nil
}

@ -15,16 +15,42 @@ description: |-
<!-- schema generated by tfplugindocs --> <!-- schema generated by tfplugindocs -->
## Schema ## Schema
### Required
- **account_id** (Number)
### Optional ### Optional
- **account_id** (Number) Unique ID of the account. If account ID is specified, then account name is ignored.
- **id** (String) The ID of this resource. - **id** (String) The ID of this resource.
- **name** (String) Name of the account. Names are case sensitive and unique.
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) - **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
### Read-Only ### Read-Only
- **status** (String) Current status of the account. - **account_name** (String)
- **acl** (List of Object) (see [below for nested schema](#nestedatt--acl))
- **ckey** (String)
- **company** (String)
- **companyurl** (String)
- **computes** (List of Object) (see [below for nested schema](#nestedatt--computes))
- **created_by** (String)
- **created_time** (Number)
- **dc_location** (String)
- **deactivation_time** (Number)
- **deleted_by** (String)
- **deleted_time** (Number)
- **displayname** (String)
- **guid** (Number)
- **machines** (List of Object) (see [below for nested schema](#nestedatt--machines))
- **meta** (List of String)
- **resource_limits** (List of Object) (see [below for nested schema](#nestedatt--resource_limits))
- **resources** (List of Object) (see [below for nested schema](#nestedatt--resources))
- **send_access_emails** (Boolean)
- **service_account** (Boolean)
- **status** (String)
- **updated_time** (Number)
- **version** (Number)
- **vins** (List of Number)
- **vinses** (Number)
<a id="nestedblock--timeouts"></a> <a id="nestedblock--timeouts"></a>
### Nested Schema for `timeouts` ### Nested Schema for `timeouts`
@ -35,3 +61,82 @@ Optional:
- **read** (String) - **read** (String)
<a id="nestedatt--acl"></a>
### Nested Schema for `acl`
Read-Only:
- **can_be_deleted** (Boolean)
- **explicit** (Boolean)
- **guid** (String)
- **right** (String)
- **status** (String)
- **type** (String)
- **user_group_id** (String)
<a id="nestedatt--computes"></a>
### Nested Schema for `computes`
Read-Only:
- **started** (Number)
- **stopped** (Number)
<a id="nestedatt--machines"></a>
### Nested Schema for `machines`
Read-Only:
- **halted** (Number)
- **running** (Number)
<a id="nestedatt--resource_limits"></a>
### Nested Schema for `resource_limits`
Read-Only:
- **cu_c** (Number)
- **cu_d** (Number)
- **cu_i** (Number)
- **cu_m** (Number)
- **cu_np** (Number)
- **gpu_units** (Number)
<a id="nestedatt--resources"></a>
### Nested Schema for `resources`
Read-Only:
- **current** (List of Object) (see [below for nested schema](#nestedobjatt--resources--current))
- **reserved** (List of Object) (see [below for nested schema](#nestedobjatt--resources--reserved))
<a id="nestedobjatt--resources--current"></a>
### Nested Schema for `resources.current`
Read-Only:
- **cpu** (Number)
- **disksize** (Number)
- **extips** (Number)
- **exttraffic** (Number)
- **gpu** (Number)
- **ram** (Number)
<a id="nestedobjatt--resources--reserved"></a>
### Nested Schema for `resources.reserved`
Read-Only:
- **cpu** (Number)
- **disksize** (Number)
- **extips** (Number)
- **exttraffic** (Number)
- **gpu** (Number)
- **ram** (Number)

@ -0,0 +1,51 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "decort_account_audits_list Data Source - terraform-provider-decort"
subcategory: ""
description: |-
---
# decort_account_audits_list (Data Source)
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **account_id** (Number) ID of the account
### Optional
- **id** (String) The ID of this resource.
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
### Read-Only
- **items** (List of Object) Search Result (see [below for nested schema](#nestedatt--items))
<a id="nestedblock--timeouts"></a>
### Nested Schema for `timeouts`
Optional:
- **default** (String)
- **read** (String)
<a id="nestedatt--items"></a>
### Nested Schema for `items`
Read-Only:
- **call** (String)
- **responsetime** (Number)
- **statuscode** (Number)
- **timestamp** (Number)
- **user** (String)

@ -0,0 +1,66 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "decort_account_computes_list Data Source - terraform-provider-decort"
subcategory: ""
description: |-
---
# decort_account_computes_list (Data Source)
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **account_id** (Number) ID of the account
### Optional
- **id** (String) The ID of this resource.
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
### Read-Only
- **items** (List of Object) Search Result (see [below for nested schema](#nestedatt--items))
<a id="nestedblock--timeouts"></a>
### Nested Schema for `timeouts`
Optional:
- **default** (String)
- **read** (String)
<a id="nestedatt--items"></a>
### Nested Schema for `items`
Read-Only:
- **account_id** (Number)
- **account_name** (String)
- **compute_id** (Number)
- **compute_name** (String)
- **cpus** (Number)
- **created_by** (String)
- **created_time** (Number)
- **deleted_by** (String)
- **deleted_time** (Number)
- **ram** (Number)
- **registered** (Boolean)
- **rg_id** (Number)
- **rg_name** (String)
- **status** (String)
- **tech_status** (String)
- **total_disks_size** (Number)
- **updated_by** (String)
- **updated_time** (Number)
- **user_managed** (Boolean)
- **vins_connected** (Number)

@ -0,0 +1,44 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "decort_account_consumed_units Data Source - terraform-provider-decort"
subcategory: ""
description: |-
---
# decort_account_consumed_units (Data Source)
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **account_id** (Number) ID of the account
### Optional
- **id** (String) The ID of this resource.
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
### Read-Only
- **cu_c** (Number)
- **cu_d** (Number)
- **cu_i** (Number)
- **cu_m** (Number)
- **cu_np** (Number)
- **gpu_units** (Number)
<a id="nestedblock--timeouts"></a>
### Nested Schema for `timeouts`
Optional:
- **default** (String)
- **read** (String)

@ -0,0 +1,40 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "decort_account_consumed_units_by_type Data Source - terraform-provider-decort"
subcategory: ""
description: |-
---
# decort_account_consumed_units_by_type (Data Source)
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **account_id** (Number) ID of the account
- **cu_type** (String) cloud unit resource type
### Optional
- **id** (String) The ID of this resource.
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
### Read-Only
- **cu_result** (Number)
<a id="nestedblock--timeouts"></a>
### Nested Schema for `timeouts`
Optional:
- **default** (String)
- **read** (String)

@ -0,0 +1,63 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "decort_account_deleted_list Data Source - terraform-provider-decort"
subcategory: ""
description: |-
---
# decort_account_deleted_list (Data Source)
<!-- schema generated by tfplugindocs -->
## Schema
### Optional
- **id** (String) The ID of this resource.
- **page** (Number) Page number
- **size** (Number) Page size
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
### Read-Only
- **items** (List of Object) (see [below for nested schema](#nestedatt--items))
<a id="nestedblock--timeouts"></a>
### Nested Schema for `timeouts`
Optional:
- **default** (String)
- **read** (String)
<a id="nestedatt--items"></a>
### Nested Schema for `items`
Read-Only:
- **account_id** (Number)
- **account_name** (String)
- **acl** (List of Object) (see [below for nested schema](#nestedobjatt--items--acl))
- **created_time** (Number)
- **deleted_time** (Number)
- **status** (String)
- **updated_time** (Number)
<a id="nestedobjatt--items--acl"></a>
### Nested Schema for `items.acl`
Read-Only:
- **explicit** (Boolean)
- **guid** (String)
- **right** (String)
- **status** (String)
- **type** (String)
- **user_group_id** (String)

@ -0,0 +1,52 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "decort_account_disks_list Data Source - terraform-provider-decort"
subcategory: ""
description: |-
---
# decort_account_disks_list (Data Source)
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **account_id** (Number) ID of the account
### Optional
- **id** (String) The ID of this resource.
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
### Read-Only
- **items** (List of Object) Search Result (see [below for nested schema](#nestedatt--items))
<a id="nestedblock--timeouts"></a>
### Nested Schema for `timeouts`
Optional:
- **default** (String)
- **read** (String)
<a id="nestedatt--items"></a>
### Nested Schema for `items`
Read-Only:
- **disk_id** (Number)
- **disk_name** (String)
- **pool** (String)
- **sep_id** (Number)
- **size_max** (Number)
- **type** (String)

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save