version 3.3.0

This commit is contained in:
KasimBaybikov
2022-12-20 18:05:17 +03:00
parent 0adf28daf6
commit be86069155
55 changed files with 4385 additions and 741 deletions

View File

@@ -32,14 +32,27 @@ Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
package vins
const VinsListAPI = "/restmachine/cloudapi/vins/list"
const VinsGetAPI = "/restmachine/cloudapi/vins/get"
const VinsSearchAPI = "/restmachine/cloudapi/vins/search"
const VinsCreateInAccountAPI = "/restmachine/cloudapi/vins/createInAccount"
const VinsCreateInRgAPI = "/restmachine/cloudapi/vins/createInRG"
const VinsExtNetConnectAPI = "/restmachine/cloudapi/vins/extNetConnect"
const VinsExtNetDisconnectAPI = "/restmachine/cloudapi/vins/extNetDisconnect"
const VinsDeleteAPI = "/restmachine/cloudapi/vins/delete"
const (
VinsAuditsAPI = "/restmachine/cloudapi/vins/audits"
VinsCreateInAccountAPI = "/restmachine/cloudapi/vins/createInAccount"
VinsCreateInRgAPI = "/restmachine/cloudapi/vins/createInRG"
VinsDeleteAPI = "/restmachine/cloudapi/vins/delete"
VinsDisableAPI = "/restmachine/cloudapi/vins/disable"
VinsEnableAPI = "/restmachine/cloudapi/vins/enable"
VinsExtNetConnectAPI = "/restmachine/cloudapi/vins/extNetConnect"
VinsExtNetDisconnectAPI = "/restmachine/cloudapi/vins/extNetDisconnect"
VinsExtNetListAPI = "/restmachine/cloudapi/vins/extNetList"
VinsGetAPI = "/restmachine/cloudapi/vins/get"
VinsIpListAPI = "/restmachine/cloudapi/vins/ipList"
VinsIpReleaseAPI = "/restmachine/cloudapi/vins/ipRelease"
VinsIpReserveAPI = "/restmachine/cloudapi/vins/ipReserve"
VinsListAPI = "/restmachine/cloudapi/vins/list"
VinsListDeletedAPI = "/restmachine/cloudapi/vins/listDeleted"
VinsNatRuleAddAPI = "/restmachine/cloudapi/vins/natRuleAdd"
VinsNatRuleDelAPI = "/restmachine/cloudapi/vins/natRuleDel"
VinsNatRuleListAPI = "/restmachine/cloudapi/vins/natRuleList"
VinsRestoreAPI = "/restmachine/cloudapi/vins/restore"
VinsSearchAPI = "/restmachine/cloudapi/vins/search"
VinsVnfdevRedeployAPI = "/restmachine/cloudapi/vins/vnfdevRedeploy"
VinsVnfdevRestartAPI = "/restmachine/cloudapi/vins/vnfdevRestart"
)

View File

@@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -33,79 +34,863 @@ package vins
import (
"context"
"encoding/json"
"fmt"
"github.com/rudecs/terraform-provider-decort/internal/constants"
log "github.com/sirupsen/logrus"
// "net/url"
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
"github.com/rudecs/terraform-provider-decort/internal/constants"
)
// vins_facts is a response string from API vins/get
func flattenVins(d *schema.ResourceData, vins_facts string) diag.Diagnostics {
// NOTE: this function modifies ResourceData argument - as such it should never be called
// from resourceVinsExists(...) method
// log.Debugf("flattenVins: ready to decode response body from API %s", vins_facts)
vinsRecord := VinsRecord{}
err := json.Unmarshal([]byte(vins_facts), &vinsRecord)
func dataSourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
vins, err := utilityDataVinsCheckPresence(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
log.Debugf("flattenVins: decoded ViNS name:ID %s:%d, account ID %d, RG ID %d",
vinsRecord.Name, vinsRecord.ID, vinsRecord.AccountID, vinsRecord.RgID)
d.SetId(fmt.Sprintf("%d", vinsRecord.ID))
d.Set("name", vinsRecord.Name)
d.Set("account_id", vinsRecord.AccountID)
d.Set("account_name", vinsRecord.AccountName)
d.Set("rg_id", vinsRecord.RgID)
d.Set("description", vinsRecord.Desc)
d.Set("ipcidr", vinsRecord.IPCidr)
noExtNetConnection := true
for _, value := range vinsRecord.VNFs {
if value.Type == "GW" {
log.Debugf("flattenVins: discovered GW VNF ID %d in ViNS ID %d", value.ID, vinsRecord.ID)
extNetID, idOk := value.Config["ext_net_id"] // NOTE: unknown numbers are unmarshalled to float64. This is by design!
extNetIP, ipOk := value.Config["ext_net_ip"]
if idOk && ipOk {
log.Debugf("flattenVins: ViNS ext_net_id=%d, ext_net_ip=%s", int(extNetID.(float64)), extNetIP.(string))
d.Set("ext_ip_addr", extNetIP.(string))
d.Set("ext_net_id", int(extNetID.(float64)))
} else {
return diag.Errorf("Failed to unmarshal VNF GW Config - structure is invalid.")
}
noExtNetConnection = false
break
}
}
if noExtNetConnection {
d.Set("ext_ip_addr", "")
d.Set("ext_net_id", 0)
}
log.Debugf("flattenVins: EXTRA CHECK - schema rg_id=%d, ext_net_id=%d", d.Get("rg_id").(int), d.Get("ext_net_id").(int))
d.SetId(strconv.FormatUint(vins.ID, 10))
flattenVinsData(d, *vins)
return nil
}
func dataSourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
vinsFacts, err := utilityVinsCheckPresence(ctx, d, m)
if vinsFacts == "" {
// if empty string is returned from utilityVinsCheckPresence then there is no
// such ViNS and err tells so - just return it to the calling party
d.SetId("") // ensure ID is empty in this case
return diag.FromErr(err)
func vnfConfigMGMTSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"ip_addr": {
Type: schema.TypeString,
Computed: true,
},
"password": {
Type: schema.TypeString,
Computed: true,
},
"ssh_key": {
Type: schema.TypeString,
Computed: true,
},
"user": {
Type: schema.TypeString,
Computed: true,
},
}
}
return flattenVins(d, vinsFacts)
func vnfConfigResourcesSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"cpu": {
Type: schema.TypeInt,
Computed: true,
},
"ram": {
Type: schema.TypeInt,
Computed: true,
},
"stack_id": {
Type: schema.TypeInt,
Computed: true,
},
"uuid": {
Type: schema.TypeString,
Computed: true,
},
}
}
func qosSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"e_rate": {
Type: schema.TypeInt,
Computed: true,
},
"guid": {
Type: schema.TypeString,
Computed: true,
},
"in_brust": {
Type: schema.TypeInt,
Computed: true,
},
"in_rate": {
Type: schema.TypeInt,
Computed: true,
},
}
}
func vnfInterfaceSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"conn_id": {
Type: schema.TypeInt,
Computed: true,
},
"conn_type": {
Type: schema.TypeString,
Computed: true,
},
"def_gw": {
Type: schema.TypeString,
Computed: true,
},
"flipgroup_id": {
Type: schema.TypeInt,
Computed: true,
},
"guid": {
Type: schema.TypeString,
Computed: true,
},
"ip_address": {
Type: schema.TypeString,
Computed: true,
},
"listen_ssh": {
Type: schema.TypeBool,
Computed: true,
},
"mac": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"net_id": {
Type: schema.TypeInt,
Computed: true,
},
"net_mask": {
Type: schema.TypeInt,
Computed: true,
},
"net_type": {
Type: schema.TypeString,
Computed: true,
},
"pci_slot": {
Type: schema.TypeInt,
Computed: true,
},
"qos": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: qosSchemaMake(),
},
},
"target": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
"vnfs": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
}
}
func vnfConfigSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"mgmt": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: vnfConfigMGMTSchemaMake(),
},
},
"resources": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: vnfConfigResourcesSchemaMake(),
},
},
}
}
func vnfDevSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"_ckey": {
Type: schema.TypeString,
Computed: true,
},
"account_id": {
Type: schema.TypeInt,
Computed: true,
Description: "Unique ID of the account, which this ViNS belongs to.",
},
"capabilities": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"config": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: vnfConfigSchemaMake(),
},
},
"config_saved": {
Type: schema.TypeBool,
Computed: true,
},
"custom_pre_cfg": {
Type: schema.TypeBool,
Computed: true,
},
"desc": {
Type: schema.TypeString,
Computed: true,
},
"gid": {
Type: schema.TypeInt,
Computed: true,
},
"guid": {
Type: schema.TypeInt,
Computed: true,
},
"vnf_id": {
Type: schema.TypeInt,
Computed: true,
},
"interfaces": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: vnfInterfaceSchemaMake(),
},
},
"lock_status": {
Type: schema.TypeString,
Computed: true,
},
"milestones": {
Type: schema.TypeInt,
Computed: true,
},
"vnf_name": {
Type: schema.TypeString,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"tech_status": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
"vins": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
}
}
func vinsComputeSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"compute_id": {
Type: schema.TypeInt,
Computed: true,
},
"compute_name": {
Type: schema.TypeString,
Computed: true,
},
}
}
func reservationSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"client_type": {
Type: schema.TypeString,
Computed: true,
},
"desc": {
Type: schema.TypeString,
Computed: true,
},
"domainname": {
Type: schema.TypeString,
Computed: true,
},
"hostname": {
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,
},
}
}
func dhcpConfigSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"default_gw": {
Type: schema.TypeString,
Computed: true,
},
"dns": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"ip_end": {
Type: schema.TypeString,
Computed: true,
},
"ip_start": {
Type: schema.TypeString,
Computed: true,
},
"lease": {
Type: schema.TypeInt,
Computed: true,
},
"netmask": {
Type: schema.TypeInt,
Computed: true,
},
"network": {
Type: schema.TypeString,
Computed: true,
},
"reservations": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: reservationSchemaMake(),
},
},
}
}
func devicesPrimarySchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"dev_id": {
Type: schema.TypeInt,
Computed: true,
},
"iface01": {
Type: schema.TypeString,
Computed: true,
},
"iface02": {
Type: schema.TypeString,
Computed: true,
},
}
}
func devicesSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"primary": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: devicesPrimarySchemaMake(),
},
},
}
}
func dhcpSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"_ckey": {
Type: schema.TypeString,
Computed: true,
},
"account_id": {
Type: schema.TypeInt,
Computed: true,
},
"config": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: dhcpConfigSchemaMake(),
},
},
"created_time": {
Type: schema.TypeInt,
Computed: true,
},
"devices": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: devicesSchemaMake(),
},
},
"gid": {
Type: schema.TypeInt,
Computed: true,
},
"guid": {
Type: schema.TypeInt,
Computed: true,
},
"dhcp_id": {
Type: schema.TypeInt,
Computed: true,
},
"lock_status": {
Type: schema.TypeString,
Computed: true,
},
"milestones": {
Type: schema.TypeInt,
Computed: true,
},
"owner_id": {
Type: schema.TypeInt,
Computed: true,
},
"owner_type": {
Type: schema.TypeString,
Computed: true,
},
"pure_virtual": {
Type: schema.TypeBool,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"tech_status": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
}
}
func gwConfigSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"default_gw": {
Type: schema.TypeString,
Computed: true,
},
"ext_net_id": {
Type: schema.TypeInt,
Computed: true,
},
"ext_net_ip": {
Type: schema.TypeString,
Computed: true,
},
"ext_netmask": {
Type: schema.TypeInt,
Computed: true,
},
"qos": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: qosSchemaMake(),
},
},
}
}
func gwSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"_ckey": {
Type: schema.TypeString,
Computed: true,
},
"account_id": {
Type: schema.TypeInt,
Computed: true,
},
"config": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: gwConfigSchemaMake(),
},
},
"created_time": {
Type: schema.TypeInt,
Computed: true,
},
"devices": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: devicesSchemaMake(),
},
},
"gid": {
Type: schema.TypeInt,
Computed: true,
},
"guid": {
Type: schema.TypeInt,
Computed: true,
},
"gw_id": {
Type: schema.TypeInt,
Computed: true,
},
"lock_status": {
Type: schema.TypeString,
Computed: true,
},
"milestones": {
Type: schema.TypeInt,
Computed: true,
},
"owner_id": {
Type: schema.TypeInt,
Computed: true,
},
"owner_type": {
Type: schema.TypeString,
Computed: true,
},
"pure_virtual": {
Type: schema.TypeBool,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"tech_status": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
}
}
func rulesSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"rule_id": {
Type: schema.TypeInt,
Computed: true,
},
"local_ip": {
Type: schema.TypeString,
Computed: true,
},
"local_port": {
Type: schema.TypeInt,
Computed: true,
},
"protocol": {
Type: schema.TypeString,
Computed: true,
},
"public_port_end": {
Type: schema.TypeInt,
Computed: true,
},
"public_port_start": {
Type: schema.TypeInt,
Computed: true,
},
"vm_id": {
Type: schema.TypeInt,
Computed: true,
},
"vm_name": {
Type: schema.TypeString,
Computed: true,
},
}
}
func configSchrmaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"net_mask": {
Type: schema.TypeInt,
Computed: true,
},
"network": {
Type: schema.TypeString,
Computed: true,
},
"rules": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: rulesSchemaMake(),
},
},
}
}
func natSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"_ckey": {
Type: schema.TypeString,
Computed: true,
},
"account_id": {
Type: schema.TypeInt,
Computed: true,
},
"created_time": {
Type: schema.TypeInt,
Computed: true,
},
"config": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: configSchrmaMake(),
},
},
"devices": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: devicesSchemaMake(),
},
},
"gid": {
Type: schema.TypeInt,
Computed: true,
},
"guid": {
Type: schema.TypeInt,
Computed: true,
},
"nat_id": {
Type: schema.TypeInt,
Computed: true,
},
"lock_status": {
Type: schema.TypeString,
Computed: true,
},
"milestones": {
Type: schema.TypeInt,
Computed: true,
},
"owner_id": {
Type: schema.TypeInt,
Computed: true,
},
"owner_type": {
Type: schema.TypeString,
Computed: true,
},
"pure_virtual": {
Type: schema.TypeBool,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"tech_status": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
}
}
func vnfsSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"dhcp": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: dhcpSchemaMake(),
},
},
"gw": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: gwSchemaMake(),
},
},
"nat": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: natSchemaMake(),
},
},
}
}
func dataSourceVinsSchemaMake() map[string]*schema.Schema {
rets := map[string]*schema.Schema{
"vins_id": {
Type: schema.TypeInt,
Required: true,
Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.",
},
"vnf_dev": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: vnfDevSchemaMake(),
},
},
"_ckey": {
Type: schema.TypeString,
Computed: true,
},
"account_id": {
Type: schema.TypeInt,
Computed: true,
Description: "Unique ID of the account, which this ViNS belongs to.",
},
"account_name": {
Type: schema.TypeString,
Computed: true,
Description: "Name of the account, which this ViNS belongs to.",
},
"computes": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: vinsComputeSchemaMake(),
},
},
"default_gw": {
Type: schema.TypeString,
Computed: true,
},
"default_qos": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: qosSchemaMake(),
},
},
"desc": {
Type: schema.TypeString,
Computed: true,
Description: "User-defined text description of this ViNS.",
},
"gid": {
Type: schema.TypeInt,
Computed: true,
},
"guid": {
Type: schema.TypeInt,
Computed: true,
},
"lock_status": {
Type: schema.TypeString,
Computed: true,
},
"manager_id": {
Type: schema.TypeInt,
Computed: true,
},
"manager_type": {
Type: schema.TypeString,
Computed: true,
},
"milestones": {
Type: schema.TypeInt,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"net_mask": {
Type: schema.TypeInt,
Computed: true,
},
"network": {
Type: schema.TypeString,
Computed: true,
},
"pre_reservations_num": {
Type: schema.TypeInt,
Computed: true,
},
"redundant": {
Type: schema.TypeBool,
Computed: true,
},
"rg_id": {
Type: schema.TypeInt,
Computed: true,
Description: "Unique ID of the resource group, where this ViNS is belongs to (for ViNS created at resource group level, 0 otherwise).",
},
"rg_name": {
Type: schema.TypeString,
Computed: true,
},
"sec_vnf_dev_id": {
Type: schema.TypeInt,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"user_managed": {
Type: schema.TypeBool,
Computed: true,
},
"vnfs": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: vnfsSchemaMake(),
},
},
"vxlan_id": {
Type: schema.TypeInt,
Computed: true,
},
}
return rets
}
func DataSourceVins() *schema.Resource {
@@ -119,63 +904,6 @@ func DataSourceVins() *schema.Resource {
Default: &constants.Timeout60s,
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
Description: "Name of the ViNS. Names are case sensitive and unique within the context of an account or resource group.",
},
/*
"vins_id": {
Type: schema.TypeInt,
Optional: true,
Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.",
},
*/
"rg_id": {
Type: schema.TypeInt,
Optional: true,
Description: "Unique ID of the resource group, where this ViNS is belongs to (for ViNS created at resource group level, 0 otherwise).",
},
"account_id": {
Type: schema.TypeInt,
Optional: true,
Description: "Unique ID of the account, which this ViNS belongs to.",
},
// the rest of attributes are computed
"account_name": {
Type: schema.TypeString,
Computed: true,
Description: "Name of the account, which this ViNS belongs to.",
},
"description": {
Type: schema.TypeString,
Computed: true,
Description: "User-defined text description of this ViNS.",
},
"ext_ip_addr": {
Type: schema.TypeString,
Computed: true,
Description: "IP address of the external connection (valid for ViNS connected to external network, empty string otherwise).",
},
"ext_net_id": {
Type: schema.TypeInt,
Computed: true,
Description: "ID of the external network this ViNS is connected to (-1 means no external connection).",
},
"ipcidr": {
Type: schema.TypeString,
Computed: true,
Description: "Network address used by this ViNS.",
},
},
Schema: dataSourceVinsSchemaMake(),
}
}

View File

@@ -0,0 +1,106 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://github.com/rudecs/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
*/
package vins
import (
"context"
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/rudecs/terraform-provider-decort/internal/constants"
)
func dataSourceVinsAuditsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
audits, err := utilityVinsAuditsCheckPresence(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
id := uuid.New()
d.SetId(id.String())
d.Set("items", flattenVinsAudits(audits))
return nil
}
func DataSourceVinsAuditsSchemaMake() map[string]*schema.Schema {
rets := map[string]*schema.Schema{
"vins_id": {
Type: schema.TypeInt,
Required: true,
Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.",
},
"items": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"call": {
Type: schema.TypeString,
Computed: true,
},
"response_time": {
Type: schema.TypeFloat,
Computed: true,
},
"statuscode": {
Type: schema.TypeInt,
Computed: true,
},
"timestamp": {
Type: schema.TypeFloat,
Computed: true,
},
"user": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
}
return rets
}
func DataSourceVinsAudits() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
ReadContext: dataSourceVinsAuditsRead,
Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s,
Default: &constants.Timeout60s,
},
Schema: DataSourceVinsAuditsSchemaMake(),
}
}

View File

@@ -0,0 +1,110 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://github.com/rudecs/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
*/
package vins
import (
"context"
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/rudecs/terraform-provider-decort/internal/constants"
)
func dataSourceVinsExtNetListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
extNetList, err := utilityVinsExtNetListCheckPresence(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
id := uuid.New()
d.SetId(id.String())
d.Set("items", flattenVinsExtNetList(extNetList))
return nil
}
func DataSourceVinsExtNetListchemaMake() map[string]*schema.Schema {
rets := map[string]*schema.Schema{
"vins_id": {
Type: schema.TypeInt,
Required: true,
Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.",
},
"items": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"default_gw": {
Type: schema.TypeString,
Computed: true,
},
"ext_net_id": {
Type: schema.TypeInt,
Computed: true,
},
"ip": {
Type: schema.TypeString,
Computed: true,
},
"prefix_len": {
Type: schema.TypeInt,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"tech_status": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
}
return rets
}
func DataSourceVinsExtNetList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
ReadContext: dataSourceVinsExtNetListRead,
Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s,
Default: &constants.Timeout60s,
},
Schema: DataSourceVinsExtNetListchemaMake(),
}
}

View File

@@ -0,0 +1,114 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://github.com/rudecs/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
*/
package vins
import (
"context"
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/rudecs/terraform-provider-decort/internal/constants"
)
func dataSourceVinsIpListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
ips, err := utilityVinsIpListCheckPresence(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
id := uuid.New()
d.SetId(id.String())
d.Set("items", flattenVinsIpList(ips))
return nil
}
func DataSourceVinsIpListSchemaMake() map[string]*schema.Schema {
rets := map[string]*schema.Schema{
"vins_id": {
Type: schema.TypeInt,
Required: true,
Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.",
},
"items": {
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,
},
"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,
},
},
},
},
}
return rets
}
func DataSourceVinsIpList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
ReadContext: dataSourceVinsIpListRead,
Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s,
Default: &constants.Timeout60s,
},
Schema: DataSourceVinsIpListSchemaMake(),
}
}

View File

@@ -1,190 +1,164 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://github.com/rudecs/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
*/
package vins
import (
"context"
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/rudecs/terraform-provider-decort/internal/constants"
)
func 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(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
vinsList, err := utilityVinsListCheckPresence(ctx, d, m)
if err != nil {
return diag.FromErr(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,
ReadContext: dataSourceVinsListRead,
Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s,
Default: &constants.Timeout60s,
},
Schema: dataSourceVinsListSchemaMake(),
}
}
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://github.com/rudecs/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
*/
package vins
import (
"context"
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/rudecs/terraform-provider-decort/internal/constants"
)
func dataSourceVinsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
vinsList, err := utilityVinsListCheckPresence(ctx, d, m)
if err != nil {
return diag.FromErr(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,
ReadContext: dataSourceVinsListRead,
Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s,
Default: &constants.Timeout60s,
},
Schema: dataSourceVinsListSchemaMake(),
}
}

View File

@@ -0,0 +1,158 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://github.com/rudecs/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
*/
package vins
import (
"context"
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/rudecs/terraform-provider-decort/internal/constants"
)
func dataSourceVinsListDeletedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
vinsList, err := utilityVinsListDeletedCheckPresence(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
id := uuid.New()
d.SetId(id.String())
d.Set("items", flattenVinsList(vinsList))
return nil
}
func dataSourceVinsListDeletedSchemaMake() 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{
"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 DataSourceVinsListDeleted() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
ReadContext: dataSourceVinsListDeletedRead,
Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s,
Default: &constants.Timeout60s,
},
Schema: dataSourceVinsListDeletedSchemaMake(),
}
}

View File

@@ -0,0 +1,118 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://github.com/rudecs/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
*/
package vins
import (
"context"
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/rudecs/terraform-provider-decort/internal/constants"
)
func dataSourceVinsNatRuleListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
natRules, err := utilityVinsNatRuleListCheckPresence(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
id := uuid.New()
d.SetId(id.String())
d.Set("items", flattenVinsNatRuleList(natRules))
return nil
}
func DataSourceVinsNatRuleListSchemaMake() map[string]*schema.Schema {
rets := map[string]*schema.Schema{
"vins_id": {
Type: schema.TypeInt,
Required: true,
Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.",
},
"items": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeInt,
Computed: true,
},
"local_ip": {
Type: schema.TypeString,
Computed: true,
},
"local_port": {
Type: schema.TypeInt,
Computed: true,
},
"protocol": {
Type: schema.TypeString,
Computed: true,
},
"public_port_end": {
Type: schema.TypeInt,
Computed: true,
},
"public_port_start": {
Type: schema.TypeInt,
Computed: true,
},
"vm_id": {
Type: schema.TypeInt,
Computed: true,
},
"vm_name": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
}
return rets
}
func DataSourceVinsNatRuleList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
ReadContext: dataSourceVinsNatRuleListRead,
Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s,
Default: &constants.Timeout60s,
},
Schema: DataSourceVinsNatRuleListSchemaMake(),
}
}

View File

@@ -0,0 +1,514 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://github.com/rudecs/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
*/
package vins
import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
func flattenMGMT(mgmt *VNFConfigMGMT) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"ip_addr": mgmt.IPAddr,
"password": mgmt.Password,
"ssh_key": mgmt.SSHKey,
"user": mgmt.User,
}
res = append(res, temp)
return res
}
func flattenResources(resources *VNFConfigResources) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"cpu": resources.CPU,
"ram": resources.RAM,
"stack_id": resources.StackID,
"uuid": resources.UUID,
}
res = append(res, temp)
return res
}
func flattenConfig(config VNFConfig) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"mgmt": flattenMGMT(&config.MGMT),
"resources": flattenResources(&config.Resources),
}
res = append(res, temp)
return res
}
func flattenQOS(qos QOS) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"e_rate": qos.ERate,
"guid": qos.GUID,
"in_brust": qos.InBurst,
"in_rate": qos.InRate,
}
res = append(res, temp)
return res
}
func flattenInterfaces(interfaces VNFInterfaceList) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, vnfInterface := range interfaces {
temp := map[string]interface{}{
"conn_id": vnfInterface.ConnID,
"conn_type": vnfInterface.ConnType,
"def_gw": vnfInterface.DefGW,
"flipgroup_id": vnfInterface.FlipGroupID,
"guid": vnfInterface.GUID,
"ip_address": vnfInterface.IPAddress,
"listen_ssh": vnfInterface.ListenSSH,
"mac": vnfInterface.MAC,
"name": vnfInterface.Name,
"net_id": vnfInterface.NetID,
"net_mask": vnfInterface.NetMask,
"net_type": vnfInterface.NetType,
"pci_slot": vnfInterface.PCISlot,
"qos": flattenQOS(vnfInterface.QOS),
"target": vnfInterface.Target,
"type": vnfInterface.Type,
"vnfs": vnfInterface.VNFS,
}
res = append(res, temp)
}
return res
}
func flattenVNFDev(vnfDev VNFDev) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"_ckey": vnfDev.CKey,
"account_id": vnfDev.AccountID,
"capabilities": vnfDev.Capabilities,
"config": flattenConfig(vnfDev.Config), //in progress
"config_saved": vnfDev.ConfigSaved,
"custom_pre_cfg": vnfDev.CustomPreConfig,
"desc": vnfDev.Description,
"gid": vnfDev.GID,
"guid": vnfDev.GUID,
"vnf_id": vnfDev.ID,
"interfaces": flattenInterfaces(vnfDev.Interfaces),
"lock_status": vnfDev.LockStatus,
"milestones": vnfDev.Milestones,
"vnf_name": vnfDev.Name,
"status": vnfDev.Status,
"tech_status": vnfDev.TechStatus,
"type": vnfDev.Type,
"vins": vnfDev.VINS,
}
res = append(res, temp)
return res
}
func flattenComputes(computes VINSComputeList) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, compute := range computes {
temp := map[string]interface{}{
"compute_id": compute.ID,
"compute_name": compute.Name,
}
res = append(res, temp)
}
return res
}
func flattenReservations(reservations ReservationList) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, reservation := range reservations {
temp := map[string]interface{}{
"client_type": reservation.ClientType,
"desc": reservation.Description,
"domainname": reservation.DomainName,
"hostname": reservation.HostName,
"ip": reservation.IP,
"mac": reservation.MAC,
"type": reservation.Type,
"vm_id": reservation.VMID,
}
res = append(res, temp)
}
return res
}
func flattenDHCPConfig(config DHCPConfig) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"default_gw": config.DefaultGW,
"dns": config.DNS,
"ip_end": config.IPEnd,
"ip_start": config.IPStart,
"lease": config.Lease,
"netmask": config.Netmask,
"network": config.Network,
"reservations": flattenReservations(config.Reservations),
}
res = append(res, temp)
return res
}
func flattenPrimary(primary DevicePrimary) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"dev_id": primary.DevID,
"iface01": primary.IFace01,
"iface02": primary.IFace02,
}
res = append(res, temp)
return res
}
func flattenDevices(devices Devices) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"primary": flattenPrimary(devices.Primary),
}
res = append(res, temp)
return res
}
func flattenDHCP(dhcp DHCP) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"_ckey": dhcp.CKey,
"account_id": dhcp.AccountID,
"config": flattenDHCPConfig(dhcp.Config),
"created_time": dhcp.CreatedTime,
"devices": flattenDevices(dhcp.Devices),
"gid": dhcp.GID,
"guid": dhcp.GUID,
"dhcp_id": dhcp.ID,
"lock_status": dhcp.LockStatus,
"milestones": dhcp.Milestones,
"owner_id": dhcp.OwnerID,
"owner_type": dhcp.OwnerType,
"pure_virtual": dhcp.PureVirtual,
"status": dhcp.Status,
"tech_status": dhcp.TechStatus,
"type": dhcp.Type,
}
res = append(res, temp)
return res
}
func flattenGWConfig(config GWConfig) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"default_gw": config.DefaultGW,
"ext_net_id": config.ExtNetID,
"ext_net_ip": config.ExtNetIP,
"ext_netmask": config.ExtNetMask,
"qos": flattenQOS(config.QOS),
}
res = append(res, temp)
return res
}
func flattenGW(gw GW) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"_ckey": gw.CKey,
"account_id": gw.AccountID,
"config": flattenGWConfig(gw.Config),
"created_time": gw.CreatedTime,
"devices": flattenDevices(gw.Devices),
"gid": gw.GID,
"guid": gw.GUID,
"gw_id": gw.ID,
"lock_status": gw.LockStatus,
"milestones": gw.Milestones,
"owner_id": gw.OwnerID,
"owner_type": gw.OwnerType,
"pure_virtual": gw.PureVirtual,
"status": gw.Status,
"tech_status": gw.TechStatus,
"type": gw.Type,
}
res = append(res, temp)
return res
}
func flattenRules(rules ListNATRules) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, rule := range rules {
tmp := map[string]interface{}{
"rule_id": rule.ID,
"local_ip": rule.LocalIP,
"local_port": rule.LocalPort,
"protocol": rule.Protocol,
"public_port_end": rule.PublicPortEnd,
"public_port_start": rule.PublicPortStart,
"vm_id": rule.VMID,
"vm_name": rule.VMName,
}
res = append(res, tmp)
}
return res
}
func flattenNATConfig(config NATConfig) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"net_mask": config.NetMask,
"network": config.Network,
"rules": flattenRules(config.Rules),
}
res = append(res, temp)
return res
}
func flattenNAT(nat NAT) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"_ckey": nat.CKey,
"account_id": nat.AccountID,
"created_time": nat.CreatedTime,
"config": flattenNATConfig(nat.Config),
"devices": flattenDevices(nat.Devices),
"gid": nat.GID,
"guid": nat.GUID,
"nat_id": nat.ID,
"lock_status": nat.LockStatus,
"milestones": nat.Milestones,
"owner_id": nat.OwnerID,
"owner_type": nat.OwnerType,
"pure_virtual": nat.PureVirtual,
"status": nat.Status,
"tech_status": nat.TechStatus,
"type": nat.Type,
}
res = append(res, temp)
return res
}
func flattenVNFS(vnfs VNFS) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"dhcp": flattenDHCP(vnfs.DHCP),
"gw": flattenGW(vnfs.GW),
"nat": flattenNAT(vnfs.NAT),
}
res = append(res, temp)
return res
}
func flattenRuleBlock(rules ListNATRules) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, rule := range rules {
tmp := map[string]interface{}{
"int_ip": rule.LocalIP,
"int_port": rule.LocalPort,
"ext_port_start": rule.PublicPortStart,
"ext_port_end": rule.PublicPortEnd,
"proto": rule.Protocol,
"rule_id": rule.ID,
}
res = append(res, tmp)
}
return res
}
func flattenVins(d *schema.ResourceData, vins VINSDetailed) {
d.Set("vins_id", vins.ID)
d.Set("vnf_dev", flattenVNFDev(vins.VNFDev))
d.Set("_ckey", vins.CKey)
d.Set("account_id", vins.AccountID)
d.Set("account_name", vins.AccountName)
d.Set("computes", flattenComputes(vins.Computes))
d.Set("default_gw", vins.DefaultGW)
d.Set("default_qos", flattenQOS(vins.DefaultQOS))
d.Set("desc", vins.Description)
d.Set("gid", vins.GID)
d.Set("guid", vins.GUID)
d.Set("lock_status", vins.LockStatus)
d.Set("manager_id", vins.ManagerID)
d.Set("manager_type", vins.ManagerType)
d.Set("milestones", vins.Milestones)
d.Set("name", vins.Name)
d.Set("net_mask", vins.NetMask)
d.Set("network", vins.Network)
d.Set("pre_reservations_num", vins.PreReservaionsNum)
d.Set("redundant", vins.Redundant)
d.Set("rg_id", vins.RGID)
d.Set("rg_name", vins.RGName)
d.Set("sec_vnf_dev_id", vins.SecVNFDevID)
d.Set("status", vins.Status)
d.Set("user_managed", vins.UserManaged)
d.Set("vnfs", flattenVNFS(vins.VNFS))
d.Set("vxlan_id", vins.VXLanID)
d.Set("nat_rule", flattenRuleBlock(vins.VNFS.NAT.Config.Rules))
}
func flattenVinsData(d *schema.ResourceData, vins VINSDetailed) {
d.Set("vins_id", vins.ID)
d.Set("vnf_dev", flattenVNFDev(vins.VNFDev))
d.Set("_ckey", vins.CKey)
d.Set("account_id", vins.AccountID)
d.Set("account_name", vins.AccountName)
d.Set("computes", flattenComputes(vins.Computes))
d.Set("default_gw", vins.DefaultGW)
d.Set("default_qos", flattenQOS(vins.DefaultQOS))
d.Set("desc", vins.Description)
d.Set("gid", vins.GID)
d.Set("guid", vins.GUID)
d.Set("lock_status", vins.LockStatus)
d.Set("manager_id", vins.ManagerID)
d.Set("manager_type", vins.ManagerType)
d.Set("milestones", vins.Milestones)
d.Set("name", vins.Name)
d.Set("net_mask", vins.NetMask)
d.Set("network", vins.Network)
d.Set("pre_reservations_num", vins.PreReservaionsNum)
d.Set("redundant", vins.Redundant)
d.Set("rg_id", vins.RGID)
d.Set("rg_name", vins.RGName)
d.Set("sec_vnf_dev_id", vins.SecVNFDevID)
d.Set("status", vins.Status)
d.Set("user_managed", vins.UserManaged)
d.Set("vnfs", flattenVNFS(vins.VNFS))
d.Set("vxlan_id", vins.VXLanID)
}
func flattenVinsAudits(auidts VINSAuditsList) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, audit := range auidts {
temp := map[string]interface{}{
"call": audit.Call,
"response_time": audit.ResponseTime,
"statuscode": audit.StatusCode,
"timestamp": audit.Timestamp,
"user": audit.User,
}
res = append(res, temp)
}
return res
}
func flattenVinsExtNetList(extNetList ExtNetList) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, extNet := range extNetList {
temp := map[string]interface{}{
"default_gw": extNet.DefaultGW,
"ext_net_id": extNet.ExtNetID,
"ip": extNet.IP,
"prefix_len": extNet.PrefixLen,
"status": extNet.Status,
"tech_status": extNet.TechStatus,
}
res = append(res, temp)
}
return res
}
func flattenVinsIpList(ips IPList) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, ip := range ips {
temp := map[string]interface{}{
"client_type": ip.ClientType,
"domainname": ip.DomainName,
"hostname": ip.HostName,
"ip": ip.IP,
"mac": ip.MAC,
"type": ip.Type,
"vm_id": ip.VMID,
}
res = append(res, temp)
}
return res
}
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 flattenVinsNatRuleList(natRules NATRuleList) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, natRule := range natRules {
temp := map[string]interface{}{
"id": natRule.ID,
"local_ip": natRule.LocalIP,
"local_port": natRule.LocalPort,
"protocol": natRule.Protocol,
"public_port_end": natRule.PublicPortEnd,
"public_port_start": natRule.PublicPortStart,
"vm_id": natRule.VMID,
"vm_name": natRule.VMName,
}
res = append(res, temp)
}
return res
}

View File

@@ -1,94 +1,330 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://github.com/rudecs/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
*/
package vins
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
type VinsSearchResp []VinsSearchRecord
type VnfRecord struct {
ID int `json:"id"`
AccountID int `json:"accountId"`
Type string `json:"type"` // "DHCP", "NAT", "GW" etc
Config map[string]interface{} `json:"config"` // NOTE: VNF specs vary by VNF type
}
type VnfGwConfigRecord struct { // describes GW VNF config structure inside ViNS, as returned by API vins/get
ExtNetID int `json:"ext_net_id"`
ExtNetIP string `json:"ext_net_ip"`
ExtNetMask int `json:"ext_net_mask"`
DefaultGW string `json:"default_gw"`
}
type VinsRecord struct { // represents part of the response from API vins/get
ID int `json:"id"`
Name string `json:"name"`
IPCidr string `json:"network"`
VxLanID int `json:"vxlanId"`
ExternalIP string `json:"externalIP"`
AccountID int `json:"accountId"`
AccountName string `json:"accountName"`
RgID int `json:"rgid"`
RgName string `json:"rgName"`
VNFs map[string]VnfRecord `json:"vnfs"`
Desc string `json:"desc"`
}
type VinsSearchRecord struct {
ID int `json:"id"`
Name string `json:"name"`
IPCidr string `json:"network"`
VxLanID int `json:"vxlanId"`
ExternalIP string `json:"externalIP"`
AccountID int `json:"accountId"`
AccountName string `json:"accountName"`
RgID int `json:"rgId"`
RgName string `json:"rgName"`
}
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://github.com/rudecs/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
*/
package vins
type VINSRecord struct {
AccountID uint64 `json:"accountId"`
AccountName string `json:"accountName"`
CreatedBy string `json:"createdBy"`
CreatedTime uint64 `json:"createdTime"`
DeletedBy string `json:"deletedBy"`
DeletedTime uint64 `json:"deletedTime"`
ExternalIP string `json:"externalIP"`
ID uint64 `json:"id"`
Name string `json:"name"`
Network string `json:"network"`
RGID uint64 `json:"rgId"`
RGName string `json:"rgName"`
Status string `json:"status"`
UpdatedBy string `json:"updatedBy"`
UpdatedTime uint64 `json:"updatedTime"`
VXLANID uint64 `json:"vxlanId"`
}
type VINSList []VINSRecord
type VINSAudits struct {
Call string `json:"call"`
ResponseTime float64 `json:"responsetime"`
StatusCode uint64 `json:"statuscode"`
Timestamp float64 `json:"timestamp"`
User string `json:"user"`
}
type VINSAuditsList []VINSAudits
type VINSExtNet struct {
DefaultGW string `json:"default_gw"`
ExtNetID uint64 `json:"ext_net_id"`
IP string `json:"ip"`
PrefixLen uint64 `json:"prefixlen"`
Status string `json:"status"`
TechStatus string `json:"techStatus"`
}
type ExtNetList []VINSExtNet
type IP struct {
ClientType string `json:"clientType"`
DomainName string `json:"domainname"`
HostName string `json:"hostname"`
IP string `json:"ip"`
MAC string `json:"mac"`
Type string `json:"type"`
VMID uint64 `json:"vmId"`
}
type IPList []IP
type VNFDev struct {
CKey string `json:"_ckey"`
AccountID uint64 `json:"accountId"`
Capabilities []string `json:"capabilities"`
Config VNFConfig `json:"config"`
ConfigSaved bool `json:"configSaved"`
CustomPreConfig bool `json:"customPrecfg"`
Description string `json:"desc"`
GID uint64 `json:"gid"`
GUID uint64 `json:"guid"`
ID uint64 `json:"id"`
Interfaces VNFInterfaceList `json:"interfaces"`
LockStatus string `json:"lockStatus"`
Milestones uint64 `json:"milestones"`
Name string `json:"name"`
Status string `json:"status"`
TechStatus string `json:"techStatus"`
Type string `json:"type"`
VINS []uint64 `json:"vins"`
}
type VNFConfig struct {
MGMT VNFConfigMGMT `json:"mgmt"`
Resources VNFConfigResources `json:"resources"`
}
type VNFConfigMGMT struct {
IPAddr string `json:"ipaddr"`
Password string `json:"password"`
SSHKey string `json:"sshkey"`
User string `json:"user"`
}
type VNFConfigResources struct {
CPU uint64 `json:"cpu"`
RAM uint64 `json:"ram"`
StackID uint64 `json:"stackId"`
UUID string `json:"uuid"`
}
type VNFInterface struct {
ConnID uint64 `json:"connId"`
ConnType string `json:"connType"`
DefGW string `json:"defGw"`
FlipGroupID uint64 `json:"flipgroupId"`
GUID string `json:"guid"`
IPAddress string `json:"ipAddress"`
ListenSSH bool `json:"listenSsh"`
MAC string `json:"mac"`
Name string `json:"name"`
NetID uint64 `json:"netId"`
NetMask uint64 `json:"netMask"`
NetType string `json:"netType"`
PCISlot uint64 `json:"pciSlot"`
QOS QOS `json:"qos"`
Target string `json:"target"`
Type string `json:"type"`
VNFS []uint64 `json:"vnfs"`
}
type QOS struct {
ERate uint64 `json:"eRate"`
GUID string `json:"guid"`
InBurst uint64 `json:"inBurst"`
InRate uint64 `json:"inRate"`
}
type VNFInterfaceList []VNFInterface
type VINSCompute struct {
ID uint64 `json:"id"`
Name string `json:"name"`
}
type VINSComputeList []VINSCompute
type VNFS struct {
DHCP DHCP `json:"DHCP"`
GW GW `json:"GW"`
NAT NAT `json:"NAT"`
}
type NAT struct {
CKey string `json:"_ckey"`
AccountID uint64 `json:"accountId"`
CreatedTime uint64 `json:"createdTime"`
Config NATConfig `json:"config"`
Devices Devices `json:"devices"`
GID uint64 `json:"gid"`
GUID uint64 `json:"guid"`
ID uint64 `json:"id"`
LockStatus string `json:"lockStatus"`
Milestones uint64 `json:"milestones"`
OwnerID uint64 `json:"ownerId"`
OwnerType string `json:"ownerType"`
PureVirtual bool `json:"pureVirtual"`
Status string `json:"status"`
TechStatus string `json:"techStatus"`
Type string `json:"type"`
}
type NATConfig struct {
NetMask uint64 `json:"netmask"`
Network string `json:"network"`
Rules ListNATRules `json:"rules"`
}
type ItemNATRule struct {
ID uint64 `json:"id"`
LocalIP string `json:"localIp"`
LocalPort uint64 `json:"localPort"`
Protocol string `json:"protocol"`
PublicPortEnd uint64 `json:"publicPortEnd"`
PublicPortStart uint64 `json:"publicPortStart"`
VMID uint64 `json:"vmId"`
VMName string `json:"vmName"`
}
type ListNATRules []ItemNATRule
type GW struct {
CKey string `json:"_ckey"`
AccountID uint64 `json:"accountId"`
Config GWConfig `json:"config"`
CreatedTime uint64 `json:"createdTime"`
Devices Devices `json:"devices"`
GID uint64 `json:"gid"`
GUID uint64 `json:"guid"`
ID uint64 `json:"id"`
LockStatus string `json:"lockStatus"`
Milestones uint64 `json:"milestones"`
OwnerID uint64 `json:"ownerId"`
OwnerType string `json:"ownerType"`
PureVirtual bool `json:"pureVirtual"`
Status string `json:"status"`
TechStatus string `json:"techStatus"`
Type string `json:"type"`
}
type GWConfig struct {
DefaultGW string `json:"default_gw"`
ExtNetID uint64 `json:"ext_net_id"`
ExtNetIP string `json:"ext_net_ip"`
ExtNetMask uint64 `json:"ext_netmask"`
QOS QOS `json:"qos"`
}
type Devices struct {
Primary DevicePrimary `json:"primary"`
}
type DevicePrimary struct {
DevID uint64 `json:"devId"`
IFace01 string `json:"iface01"`
IFace02 string `json:"iface02"`
}
type DHCP struct {
CKey string `json:"_ckey"`
AccountID uint64 `json:"accountId"`
Config DHCPConfig `json:"config"`
CreatedTime uint64 `json:"createdTime"`
Devices Devices `json:"devices"`
GID uint64 `json:"gid"`
GUID uint64 `json:"guid"`
ID uint64 `json:"id"`
LockStatus string `json:"lockStatus"`
Milestones uint64 `json:"milestones"`
OwnerID uint64 `json:"ownerId"`
OwnerType string `json:"ownerType"`
PureVirtual bool `json:"pureVirtual"`
Status string `json:"status"`
TechStatus string `json:"techStatus"`
Type string `json:"type"`
}
type DHCPConfig struct {
DefaultGW string `json:"default_gw"`
DNS []string `json:"dns"`
IPEnd string `json:"ip_end"`
IPStart string `json:"ip_start"`
Lease uint64 `json:"lease"`
Netmask uint64 `json:"netmask"`
Network string `json:"network"`
Reservations ReservationList `json:"reservations"`
}
type VINSDetailed struct {
VNFDev VNFDev `json:"VNFDev"`
CKey string `json:"_ckey"`
AccountID uint64 `json:"accountId"`
AccountName string `json:"accountName"`
Computes VINSComputeList `json:"computes"`
DefaultGW string `json:"defaultGW"`
DefaultQOS QOS `json:"defaultQos"`
Description string `json:"desc"`
GID uint64 `json:"gid"`
GUID uint64 `json:"guid"`
ID uint64 `json:"id"`
LockStatus string `json:"lockStatus"`
ManagerID uint64 `json:"managerId"`
ManagerType string `json:"managerType"`
Milestones uint64 `json:"milestones"`
Name string `json:"name"`
NetMask uint64 `json:"netMask"`
Network string `json:"network"`
PreReservaionsNum uint64 `json:"preReservationsNum"`
Redundant bool `json:"redundant"`
RGID uint64 `json:"rgId"`
RGName string `json:"rgName"`
SecVNFDevID uint64 `json:"secVnfDevId"`
Status string `json:"status"`
UserManaged bool `json:"userManaged"`
VNFS VNFS `json:"vnfs"`
VXLanID uint64 `json:"vxlanId"`
}
type Reservation struct {
ClientType string `json:"clientType"`
Description 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 ReservationList []Reservation
type NATRule struct {
ID uint64 `json:"id"`
LocalIP string `json:"localIp"`
LocalPort uint64 `json:"localPort"`
Protocol string `json:"protocol"`
PublicPortEnd uint64 `json:"publicPortEnd"`
PublicPortStart uint64 `json:"publicPortStart"`
VMID uint64 `json:"vmId"`
VMName string `json:"vmName"`
}
type NATRuleList []NATRule

View File

@@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -39,6 +40,8 @@ import (
"github.com/rudecs/terraform-provider-decort/internal/constants"
"github.com/rudecs/terraform-provider-decort/internal/controller"
"github.com/rudecs/terraform-provider-decort/internal/dc"
"github.com/rudecs/terraform-provider-decort/internal/status"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
@@ -46,112 +49,221 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)
func ipcidrDiffSupperss(key, oldVal, newVal string, d *schema.ResourceData) bool {
if oldVal == "" && newVal != "" {
// 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 -
// 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)
return false // there is a difference between stored and new value
}
log.Debugf("ipcidrDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=TRUE", key, oldVal, newVal)
return true // suppress difference
}
func resourceVinsCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
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))
apiToCall := VinsCreateInAccountAPI
c := m.(*controller.ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("name", d.Get("name").(string))
argVal, argSet := d.GetOk("rg_id")
if argSet && argVal.(int) > 0 {
apiToCall = VinsCreateInRgAPI
urlValues.Add("rgId", fmt.Sprintf("%d", argVal.(int)))
} else {
// RG ID either not set at all or set to 0 - user may want ViNS at account level
argVal, argSet = d.GetOk("account_id")
if !argSet || argVal.(int) <= 0 {
// No valid Account ID (and no RG ID either) - cannot create ViNS
return diag.Errorf("resourceVinsCreate: ViNS name %s - no valid account and/or resource group ID specified", d.Id())
}
urlValues.Add("accountId", fmt.Sprintf("%d", argVal.(int)))
rgId, rgOk := d.GetOk("rg_id")
accountId, accountIdOk := d.GetOk("account_id")
if !rgOk && !accountIdOk {
return diag.Errorf("resourceVinsCreate: no valid accountId or resource group ID specified")
}
argVal, argSet = d.GetOk("ext_net_id") // NB: even if ext_net_id value is explicitly set to 0, argSet = false anyway
if argSet {
if argVal.(int) > 0 {
// connect to specific external network
urlValues.Add("extNetId", fmt.Sprintf("%d", argVal.(int)))
/*
Commented out, as we've made "ext_net_ip" parameter non-configurable via Terraform!
if rgOk {
urlValues.Add("name", d.Get("name").(string))
urlValues.Add("rgId", strconv.Itoa(rgId.(int)))
if ipcidr, ok := d.GetOk("ipcidr"); ok {
urlValues.Add("ipcidr", ipcidr.(string))
}
// in case of specific ext net connection user may also want a particular IP address
argVal, argSet = d.GetOk("ext_net_ip")
if argSet && argVal.(string) != "" {
urlValues.Add("extIp", argVal.(string))
//extnet v1
urlValues.Add("extNetId", strconv.Itoa(d.Get("ext_net_id").(int)))
if extIp, ok := d.GetOk("ext_ip_addr"); ok {
urlValues.Add("extIp", extIp.(string))
}
//extnet v2
if extNetResp, ok := d.GetOk("ext_net"); ok {
extNetSl := extNetResp.([]interface{})
extNet := extNetSl[0].(map[string]interface{})
urlValues.Add("vinsId", d.Id())
urlValues.Add("netId", strconv.Itoa(extNet["ext_net_id"].(int)))
urlValues.Add("extIp", extNet["ext_net_ip"].(string))
}
if desc, ok := d.GetOk("desc"); ok {
urlValues.Add("desc", desc.(string))
}
urlValues.Add("preReservationsNum", strconv.Itoa(d.Get("pre_reservations_num").(int)))
id, err := c.DecortAPICall(ctx, "POST", VinsCreateInRgAPI, urlValues)
if err != nil {
return diag.FromErr(err)
}
d.SetId(id)
} else if accountIdOk {
urlValues.Add("name", d.Get("name").(string))
urlValues.Add("accountId", strconv.Itoa(accountId.(int)))
if gid, ok := d.GetOk("gid"); ok {
urlValues.Add("gid", strconv.Itoa(gid.(int)))
}
if ipcidr, ok := d.GetOk("ipcidr"); ok {
urlValues.Add("ipcidr", ipcidr.(string))
}
if desc, ok := d.GetOk("desc"); ok {
urlValues.Add("desc", desc.(string))
}
urlValues.Add("preReservationsNum", strconv.Itoa(d.Get("pre_reservations_num").(int)))
id, err := c.DecortAPICall(ctx, "POST", VinsCreateInAccountAPI, urlValues)
if err != nil {
return diag.FromErr(err)
}
d.SetId(id)
}
warnings := dc.Warnings{}
urlValues = &url.Values{}
if ipRes, ok := d.GetOk("ip"); ok {
ipsSlice := ipRes.([]interface{})
for _, ipInterfase := range ipsSlice {
ip := ipInterfase.(map[string]interface{})
urlValues = &url.Values{}
urlValues.Add("vinsId", d.Id())
urlValues.Add("type", ip["type"].(string))
if ipAddr, ok := ip["ip_addr"]; ok {
urlValues.Add("ipAddr", ipAddr.(string))
}
if macAddr, ok := ip["mac_addr"]; ok {
urlValues.Add("mac", macAddr.(string))
}
if computeId, ok := ip["compute_id"]; ok {
urlValues.Add("computeId", strconv.Itoa(computeId.(int)))
}
_, err := c.DecortAPICall(ctx, "POST", VinsIpReserveAPI, urlValues)
if err != nil {
warnings.Add(err)
}
}
}
urlValues = &url.Values{}
if natRule, ok := d.GetOk("nat_rule"); ok {
addedNatRules := natRule.([]interface{})
if len(addedNatRules) > 0 {
for _, natRuleInterface := range addedNatRules {
urlValues = &url.Values{}
natRule := natRuleInterface.(map[string]interface{})
urlValues.Add("vinsId", d.Id())
urlValues.Add("intIp", natRule["int_ip"].(string))
urlValues.Add("intPort", strconv.Itoa(natRule["int_port"].(int)))
urlValues.Add("extPortStart", strconv.Itoa(natRule["ext_port_start"].(int)))
urlValues.Add("extPortEnd", strconv.Itoa(natRule["ext_port_end"].(int)))
urlValues.Add("proto", natRule["proto"].(string))
_, err := c.DecortAPICall(ctx, "POST", VinsNatRuleAddAPI, urlValues)
if err != nil {
warnings.Add(err)
}
*/
} else {
// ext_net_id is set to a negative value - connect to default external network
// no particular IP address selection in this case
urlValues.Add("extNetId", "0")
}
}
}
argVal, argSet = d.GetOk("ipcidr")
if argSet && argVal.(string) != "" {
log.Debugf("resourceVinsCreate: ipcidr is set to %s", argVal.(string))
urlValues.Add("ipcidr", argVal.(string))
}
argVal, argSet = d.GetOk("description")
if argSet {
urlValues.Add("desc", argVal.(string))
}
apiResp, err := c.DecortAPICall(ctx, "POST", apiToCall, urlValues)
if err != nil {
return diag.FromErr(err)
}
d.SetId(apiResp) // update ID of the resource to tell Terraform that the ViNS resource exists
vinsId, _ := strconv.Atoi(apiResp)
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
// between ViNS resource and ViNS data source schemas
// 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)
return dataSourceVinsRead(ctx, d, m)
defer resourceVinsRead(ctx, d, m)
return warnings.Get()
}
func resourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
vinsFacts, err := utilityVinsCheckPresence(ctx, d, m)
if vinsFacts == "" {
// if empty string is returned from utilityVinsCheckPresence then there is no
// such ViNS and err tells so - just return it to the calling party
d.SetId("") // ensure ID is empty
c := m.(*controller.ControllerCfg)
urlValues := &url.Values{}
warnings := dc.Warnings{}
vins, err := utilityVinsCheckPresence(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
return flattenVins(d, vinsFacts)
hasChangeState := false
if vins.Status == status.Destroyed {
d.SetId("")
d.Set("vins_id", 0)
return resourceVinsCreate(ctx, d, m)
} else if vins.Status == status.Deleted {
hasChangeState = true
urlValues.Add("vinsId", d.Id())
_, err := c.DecortAPICall(ctx, "POST", VinsRestoreAPI, urlValues)
if err != nil {
warnings.Add(err)
}
}
urlValues = &url.Values{}
isEnabled := d.Get("enable").(bool)
if vins.Status == status.Disabled && isEnabled {
hasChangeState = true
urlValues.Add("vinsId", d.Id())
_, err := c.DecortAPICall(ctx, "POST", VinsEnableAPI, urlValues)
if err != nil {
warnings.Add(err)
}
} else if vins.Status == status.Enabled && !isEnabled {
hasChangeState = true
urlValues.Add("vinsId", d.Id())
_, err := c.DecortAPICall(ctx, "POST", VinsDisableAPI, urlValues)
if err != nil {
warnings.Add(err)
}
}
if hasChangeState {
vins, err = utilityVinsCheckPresence(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
}
flattenVins(d, *vins)
return warnings.Get()
}
func isContainsIp(els []interface{}, el interface{}) bool {
for _, elOld := range els {
elOldConv := elOld.(map[string]interface{})
elConv := el.(map[string]interface{})
if elOldConv["ip_addr"].(string) == elConv["ip_addr"].(string) {
return true
}
}
return false
}
func isContinsNatRule(els []interface{}, el interface{}) bool {
for _, elOld := range els {
elOldConv := elOld.(map[string]interface{})
elConv := el.(map[string]interface{})
if elOldConv["int_ip"].(string) == elConv["int_ip"].(string) &&
elOldConv["int_port"].(int) == elConv["int_port"].(int) &&
elOldConv["ext_port_start"].(int) == elConv["ext_port_start"].(int) {
return true
}
}
return false
}
func resourceVinsUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
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))
c := m.(*controller.ControllerCfg)
urlValues := &url.Values{}
warnings := dc.Warnings{}
// 1. Handle external network connection change
enableOld, enableNew := d.GetChange("enable")
if enableOld.(bool) && !enableNew.(bool) {
urlValues.Add("vinsId", d.Id())
_, err := c.DecortAPICall(ctx, "POST", VinsDisableAPI, urlValues)
if err != nil {
warnings.Add(err)
}
} else if !enableOld.(bool) && enableNew.(bool) {
urlValues.Add("vinsId", d.Id())
_, err := c.DecortAPICall(ctx, "POST", VinsEnableAPI, urlValues)
if err != nil {
warnings.Add(err)
}
}
//extnet v1
oldExtNetId, newExtNedId := d.GetChange("ext_net_id")
if oldExtNetId.(int) != newExtNedId.(int) {
log.Debugf("resourceVinsUpdate: changing ViNS ID %s - ext_net_id %d -> %d", d.Id(), oldExtNetId.(int), newExtNedId.(int))
@@ -163,46 +275,178 @@ func resourceVinsUpdate(ctx context.Context, d *schema.ResourceData, m interface
// there was preexisting external net connection - disconnect ViNS
_, err := c.DecortAPICall(ctx, "POST", VinsExtNetDisconnectAPI, extnetParams)
if err != nil {
return diag.FromErr(err)
warnings.Add(err)
}
}
if newExtNedId.(int) > 0 {
// new external network connection requested - connect ViNS
extnetParams.Add("netId", fmt.Sprintf("%d", newExtNedId.(int)))
extNetIp, ok := d.GetOk("ext_net_ip")
if ok && extNetIp.(string) != "" {
urlValues.Add("Ip", extNetIp.(string))
}
_, err := c.DecortAPICall(ctx, "POST", VinsExtNetConnectAPI, extnetParams)
if err != nil {
return diag.FromErr(err)
warnings.Add(err)
}
}
}
// we may reuse dataSourceVinsRead here as we maintain similarity
// between Compute resource and Compute data source schemas
return dataSourceVinsRead(ctx, d, m)
urlValues = &url.Values{}
if d.HasChange("ip") {
deletedIps := make([]interface{}, 0)
addedIps := make([]interface{}, 0)
oldIpInterface, newIpInterface := d.GetChange("ip")
oldIpSlice := oldIpInterface.([]interface{})
newIpSlice := newIpInterface.([]interface{})
for _, el := range oldIpSlice {
if !isContainsIp(newIpSlice, el) {
deletedIps = append(deletedIps, el)
}
}
for _, el := range newIpSlice {
if !isContainsIp(oldIpSlice, el) {
addedIps = append(addedIps, el)
}
}
if len(deletedIps) > 0 {
for _, ipInterfase := range deletedIps {
urlValues = &url.Values{}
ip := ipInterfase.(map[string]interface{})
urlValues.Add("vinsId", d.Id())
if ip["ip_addr"].(string) != "" {
urlValues.Add("ipAddr", ip["ip_addr"].(string))
}
if ip["mac_addr"].(string) != "" {
urlValues.Add("mac", ip["mac_addr"].(string))
}
_, err := c.DecortAPICall(ctx, "POST", VinsIpReleaseAPI, urlValues)
if err != nil {
warnings.Add(err)
}
}
}
if len(addedIps) > 0 {
for _, ipInterfase := range addedIps {
urlValues = &url.Values{}
ip := ipInterfase.(map[string]interface{})
urlValues.Add("vinsId", d.Id())
urlValues.Add("type", ip["type"].(string))
if ip["ip_addr"].(string) != "" {
urlValues.Add("ipAddr", ip["ip_addr"].(string))
}
if ip["mac_addr"].(string) != "" {
urlValues.Add("mac", ip["mac_addr"].(string))
}
if ip["compute_id"].(int) != 0 {
urlValues.Add("computeId", strconv.Itoa(ip["compute_id"].(int)))
}
_, err := c.DecortAPICall(ctx, "POST", VinsIpReserveAPI, urlValues)
if err != nil {
warnings.Add(err)
}
}
}
}
if d.HasChange("nat_rule") {
deletedNatRules := make([]interface{}, 0)
addedNatRules := make([]interface{}, 0)
oldNatRulesInterface, newNatRulesInterface := d.GetChange("nat_rule")
oldNatRulesSlice := oldNatRulesInterface.([]interface{})
newNatRulesSlice := newNatRulesInterface.([]interface{})
for _, el := range oldNatRulesSlice {
if !isContinsNatRule(newNatRulesSlice, el) {
deletedNatRules = append(deletedNatRules, el)
}
}
for _, el := range newNatRulesSlice {
if !isContinsNatRule(oldNatRulesSlice, el) {
addedNatRules = append(addedNatRules, el)
}
}
if len(deletedNatRules) > 0 {
for _, natRuleInterface := range deletedNatRules {
urlValues = &url.Values{}
natRule := natRuleInterface.(map[string]interface{})
urlValues.Add("vinsId", d.Id())
urlValues.Add("ruleId", strconv.Itoa(natRule["rule_id"].(int)))
log.Debug("NAT_RULE_DEL_WITH: ", urlValues.Encode())
_, err := c.DecortAPICall(ctx, "POST", VinsNatRuleDelAPI, urlValues)
if err != nil {
warnings.Add(err)
}
}
}
if len(addedNatRules) > 0 {
for _, natRuleInterface := range addedNatRules {
urlValues = &url.Values{}
natRule := natRuleInterface.(map[string]interface{})
urlValues.Add("vinsId", d.Id())
urlValues.Add("intIp", natRule["int_ip"].(string))
urlValues.Add("intPort", strconv.Itoa(natRule["int_port"].(int)))
urlValues.Add("extPortStart", strconv.Itoa(natRule["ext_port_start"].(int)))
if natRule["ext_port_end"].(int) != 0 {
urlValues.Add("extPortEnd", strconv.Itoa(natRule["ext_port_end"].(int)))
}
if natRule["proto"].(string) != "" {
urlValues.Add("proto", natRule["proto"].(string))
}
log.Debug("NAT_RULE_ADD_WITH: ", urlValues.Encode())
_, err := c.DecortAPICall(ctx, "POST", VinsNatRuleAddAPI, urlValues)
if err != nil {
warnings.Add(err)
}
}
}
}
if oldRestart, newRestart := d.GetChange("vnfdev_restart"); oldRestart == false && newRestart == true {
urlValues = &url.Values{}
urlValues.Add("vinsId", d.Id())
_, err := c.DecortAPICall(ctx, "POST", VinsVnfdevRestartAPI, urlValues)
if err != nil {
warnings.Add(err)
}
}
if oldRedeploy, newRedeploy := d.GetChange("vnfdev_redeploy"); oldRedeploy == false && newRedeploy == true {
urlValues = &url.Values{}
urlValues.Add("vinsId", d.Id())
_, err := c.DecortAPICall(ctx, "POST", VinsVnfdevRedeployAPI, urlValues)
if err != nil {
warnings.Add(err)
}
}
defer resourceVinsRead(ctx, d, m)
return warnings.Get()
}
func resourceVinsDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceVinsDelete: 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))
vinsFacts, err := utilityVinsCheckPresence(ctx, d, m)
if vinsFacts == "" {
if err != nil {
return diag.FromErr(err)
}
// the specified ViNS does not exist - in this case according to Terraform best practice
// we exit from Destroy method without error
return nil
}
params := &url.Values{}
params.Add("vinsId", d.Id())
params.Add("force", "1") // disconnect all computes before deleting ViNS
params.Add("permanently", "1") // delete ViNS immediately bypassing recycle bin
urlValues := &url.Values{}
c := m.(*controller.ControllerCfg)
_, err = c.DecortAPICall(ctx, "POST", VinsDeleteAPI, params)
urlValues.Add("vinsId", d.Id())
urlValues.Add("force", strconv.FormatBool(d.Get("force").(bool)))
urlValues.Add("permanently", strconv.FormatBool(d.Get("permanently").(bool)))
_, err := c.DecortAPICall(ctx, "POST", VinsDeleteAPI, urlValues)
if err != nil {
return diag.FromErr(err)
}
@@ -210,73 +454,184 @@ func resourceVinsDelete(ctx context.Context, d *schema.ResourceData, m interface
return nil
}
func resourceVinsSchemaMake() map[string]*schema.Schema {
rets := map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringIsNotEmpty,
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.
Resource Import will work anyway, as it obtains the ID of ViNS to be imported through another mechanism.
"vins_id": {
Type: schema.TypeInt,
Optional: true,
Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.",
},
*/
"rg_id": {
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
Default: 0,
Description: "ID of the resource group, where this ViNS belongs to. Non-zero for ViNS created at resource group level, 0 otherwise.",
},
"account_id": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
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.",
},
func extNetSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"ext_net_id": {
Type: schema.TypeInt,
Required: true,
ValidateFunc: validation.IntAtLeast(0),
Description: "ID of the external network this ViNS is connected to. Pass 0 if no external connection required.",
Type: schema.TypeInt,
Default: 0,
Optional: true,
},
"ext_net_ip": {
Type: schema.TypeInt,
Optional: true,
Default: "",
},
}
}
"ipcidr": {
Type: schema.TypeString,
Optional: true,
DiffSuppressFunc: ipcidrDiffSupperss,
Description: "Network address to use by this ViNS. This parameter is only valid when creating new ViNS.",
func ipSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"type": {
Type: schema.TypeString,
Required: true,
},
"ip_addr": {
Type: schema.TypeString,
Optional: true,
},
"mac_addr": {
Type: schema.TypeString,
Optional: true,
},
"compute_id": {
Type: schema.TypeInt,
Optional: true,
},
}
}
"description": {
Type: schema.TypeString,
Optional: true,
Default: "",
Description: "Optional user-defined text description of this ViNS.",
func natRuleSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"int_ip": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"int_port": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
},
"ext_port_start": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
},
"ext_port_end": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
},
"proto": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"tcp", "udp"}, false),
Computed: true,
},
"rule_id": {
Type: schema.TypeInt,
Computed: true,
},
}
}
// the rest of attributes are computed
"account_name": {
Type: schema.TypeString,
Computed: true,
Description: "Name of the account, which this ViNS belongs to.",
func resourceVinsSchemaMake() map[string]*schema.Schema {
rets := dataSourceVinsSchemaMake()
rets["name"] = &schema.Schema{
Type: schema.TypeString,
Required: true,
}
rets["rg_id"] = &schema.Schema{
Type: schema.TypeInt,
Optional: true,
}
rets["account_id"] = &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Computed: true,
}
rets["ext_net_id"] = &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Default: -1,
}
rets["ipcidr"] = &schema.Schema{
Type: schema.TypeString,
Optional: true,
}
rets["ext_ip_addr"] = &schema.Schema{
Type: schema.TypeString,
Optional: true,
Default: "",
}
rets["pre_reservations_num"] = &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Default: 32,
}
rets["gid"] = &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Computed: true,
}
rets["enable"] = &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Default: true,
}
rets["permanently"] = &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Default: false,
}
rets["force"] = &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Default: false,
}
rets["ext_net"] = &schema.Schema{
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: extNetSchemaMake(),
},
}
rets["ip"] = &schema.Schema{
Type: schema.TypeList,
Optional: true,
Elem: &schema.Resource{
Schema: ipSchemaMake(),
},
}
rets["nat_rule"] = &schema.Schema{
Type: schema.TypeList,
Optional: true,
Elem: &schema.Resource{
Schema: natRuleSchemaMake(),
},
}
rets["desc"] = &schema.Schema{
Type: schema.TypeString,
Optional: true,
Default: "",
Description: "Optional user-defined text description of this ViNS.",
}
rets["ext_ip_addr"] = &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "IP address of the external connection (valid for ViNS connected to external network, ignored otherwise).",
}
rets["restore"] = &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Default: false,
}
rets["vnfdev_restart"] = &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Default: false,
}
rets["vnfdev_redeploy"] = &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Default: false,
}
"ext_ip_addr": {
Type: schema.TypeString,
Computed: true,
Description: "IP address of the external connection (valid for ViNS connected to external network, ignored otherwise).",
},
rets["vins_id"] = &schema.Schema{
Type: schema.TypeInt,
Computed: true,
Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.",
}
return rets

View File

@@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -34,120 +35,48 @@ package vins
import (
"context"
"encoding/json"
"fmt"
"net/url"
"strconv"
"github.com/rudecs/terraform-provider-decort/internal/controller"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
// On success this function returns a string, as returned by API vins/get, which could be unmarshalled
// into VinsGetResp structure
func utilityVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) {
// This function tries to locate ViNS by one of the following algorithms depending
// on the parameters passed:
// - if resource group ID is specified -> it looks for a ViNS at the RG level
// - if account ID is specifeid -> it looks for a ViNS at the account level
//
// If succeeded, it returns non empty string that contains JSON formatted facts about the
// ViNS as returned by vins/get API call.
// Otherwise it returns empty string and a meaningful error.
//
// This function does not modify its ResourceData argument, so it is safe to use it as core
// method for the Terraform resource Exists method.
//
func utilityDataVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*VINSDetailed, error) {
c := m.(*controller.ControllerCfg)
urlValues := &url.Values{}
vins := &VINSDetailed{}
// make it possible to use "read" & "check presence" functions with ViNS ID set so
// that Import of ViNS resource is possible
idSet := false
theId, err := strconv.Atoi(d.Id())
if err != nil || theId <= 0 {
vinsId, argSet := d.GetOk("vins_id") // NB: vins_id is NOT present in vinsResource schema!
if argSet {
theId = vinsId.(int)
idSet = true
}
} else {
idSet = true
}
if idSet {
// ViNS ID is specified, try to get compute instance straight by this ID
log.Debugf("utilityVinsCheckPresence: locating ViNS by its ID %d", theId)
urlValues.Add("vinsId", fmt.Sprintf("%d", theId))
vinsFacts, err := c.DecortAPICall(ctx, "POST", VinsGetAPI, urlValues)
if err != nil {
return "", err
}
return vinsFacts, nil
}
// ID was not set in the schema upon entering this function - work through ViNS name
// and Account / RG ID
vinsName, argSet := d.GetOk("name")
if !argSet {
// if ViNS name is not set. then we cannot locate ViNS
return "", fmt.Errorf("Cannot check ViNS presence if ViNS name is empty")
}
urlValues.Add("name", vinsName.(string))
urlValues.Add("show_all", "false")
log.Debugf("utilityVinsCheckPresence: preparing to locate ViNS name %s", vinsName.(string))
rgId, rgSet := d.GetOk("rg_id")
if rgSet {
log.Debugf("utilityVinsCheckPresence: limiting ViNS search to RG ID %d", rgId.(int))
urlValues.Add("rgId", fmt.Sprintf("%d", rgId.(int)))
}
accountId, accountSet := d.GetOk("account_id")
if accountSet {
log.Debugf("utilityVinsCheckPresence: limiting ViNS search to Account ID %d", accountId.(int))
urlValues.Add("accountId", fmt.Sprintf("%d", accountId.(int)))
}
apiResp, err := c.DecortAPICall(ctx, "POST", VinsSearchAPI, urlValues)
urlValues.Add("vinsId", strconv.Itoa(d.Get("vins_id").(int)))
vinsRaw, err := c.DecortAPICall(ctx, "POST", VinsGetAPI, urlValues)
if err != nil {
return "", err
return nil, err
}
// log.Debugf("%s", apiResp)
// log.Debugf("utilityResgroupCheckPresence: ready to decode response body from %s", VinsSearchAPI)
model := VinsSearchResp{}
err = json.Unmarshal([]byte(apiResp), &model)
err = json.Unmarshal([]byte(vinsRaw), vins)
if err != nil {
return "", err
return nil, err
}
return vins, nil
}
func utilityVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*VINSDetailed, error) {
c := m.(*controller.ControllerCfg)
urlValues := &url.Values{}
vins := &VINSDetailed{}
urlValues.Add("vinsId", d.Id())
vinsRaw, err := c.DecortAPICall(ctx, "POST", VinsGetAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(vinsRaw), vins)
if err != nil {
return nil, err
}
return vins, nil
log.Debugf("utilityVinsCheckPresence: traversing decoded Json of length %d", len(model))
for index, item := range model {
if item.Name == vinsName.(string) {
if (accountSet && item.AccountID != accountId.(int)) ||
(rgSet && item.RgID != rgId.(int)) {
// double check that account ID and Rg ID match, if set in the schema
continue
}
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)
// 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
rqValues := &url.Values{}
rqValues.Add("vinsId", fmt.Sprintf("%d", item.ID))
vinsGetResp, err := c.DecortAPICall(ctx, "POST", VinsGetAPI, rqValues)
if err != nil {
return "", err
}
return vinsGetResp, nil
}
}
return "", fmt.Errorf("Cannot find ViNS name %s. Check name and/or RG ID & Account ID and your access rights", vinsName.(string))
}

View File

@@ -0,0 +1,61 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://github.com/rudecs/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
*/
package vins
import (
"context"
"encoding/json"
"net/url"
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/rudecs/terraform-provider-decort/internal/controller"
)
func utilityVinsAuditsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (VINSAuditsList, error) {
c := m.(*controller.ControllerCfg)
urlValues := &url.Values{}
auditsList := VINSAuditsList{}
urlValues.Add("vinsId", strconv.Itoa(d.Get("vins_id").(int)))
auidtsRaw, err := c.DecortAPICall(ctx, "POST", VinsAuditsAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(auidtsRaw), &auditsList)
if err != nil {
return nil, err
}
return auditsList, nil
}

View File

@@ -0,0 +1,61 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://github.com/rudecs/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
*/
package vins
import (
"context"
"encoding/json"
"net/url"
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/rudecs/terraform-provider-decort/internal/controller"
)
func utilityVinsExtNetListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ExtNetList, error) {
c := m.(*controller.ControllerCfg)
urlValues := &url.Values{}
extNet := ExtNetList{}
urlValues.Add("vinsId", strconv.Itoa(d.Get("vins_id").(int)))
extNetRaw, err := c.DecortAPICall(ctx, "POST", VinsExtNetListAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(extNetRaw), &extNet)
if err != nil {
return nil, err
}
return extNet, nil
}

View File

@@ -0,0 +1,61 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://github.com/rudecs/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
*/
package vins
import (
"context"
"encoding/json"
"net/url"
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/rudecs/terraform-provider-decort/internal/controller"
)
func utilityVinsIpListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (IPList, error) {
c := m.(*controller.ControllerCfg)
urlValues := &url.Values{}
ips := IPList{}
urlValues.Add("vinsId", strconv.Itoa(d.Get("vins_id").(int)))
auidtsRaw, err := c.DecortAPICall(ctx, "POST", VinsIpListAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(auidtsRaw), &ips)
if err != nil {
return nil, err
}
return ips, nil
}

View File

@@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -43,8 +44,8 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
func utilityVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (VinsList, error) {
vinsList := VinsList{}
func utilityVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (VINSList, error) {
vinsList := VINSList{}
c := m.(*controller.ControllerCfg)
urlValues := &url.Values{}

View File

@@ -0,0 +1,70 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://github.com/rudecs/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
*/
package vins
import (
"context"
"encoding/json"
"net/url"
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/rudecs/terraform-provider-decort/internal/controller"
log "github.com/sirupsen/logrus"
)
func utilityVinsListDeletedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (VINSList, error) {
vinsList := VINSList{}
c := m.(*controller.ControllerCfg)
urlValues := &url.Values{}
if page, ok := d.GetOk("page"); ok {
urlValues.Add("page", strconv.Itoa(page.(int)))
}
if size, ok := d.GetOk("size"); ok {
urlValues.Add("size", strconv.Itoa(size.(int)))
}
log.Debugf("utilityVinsListDeletedCheckPresence")
vinsListRaw, err := c.DecortAPICall(ctx, "POST", VinsListDeletedAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(vinsListRaw), &vinsList)
if err != nil {
return nil, err
}
return vinsList, nil
}

View File

@@ -0,0 +1,61 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://github.com/rudecs/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
*/
package vins
import (
"context"
"encoding/json"
"net/url"
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/rudecs/terraform-provider-decort/internal/controller"
)
func utilityVinsNatRuleListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (NATRuleList, error) {
c := m.(*controller.ControllerCfg)
urlValues := &url.Values{}
natRuleList := NATRuleList{}
urlValues.Add("vinsId", strconv.Itoa(d.Get("vins_id").(int)))
auidtsRaw, err := c.DecortAPICall(ctx, "POST", VinsNatRuleListAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(auidtsRaw), &natRuleList)
if err != nil {
return nil, err
}
return natRuleList, nil
}