4.5.1
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Sergey Kisil, <svkisil@digitalenergy.online>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -33,66 +34,23 @@ package vins
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
|
||||
// "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"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
func flattenVins(d *schema.ResourceData, vinsRecord *vins.RecordVINS) diag.Diagnostics {
|
||||
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.Description)
|
||||
d.Set("ipcidr", vinsRecord.Network)
|
||||
|
||||
noExtNetConnection := true
|
||||
gw := vinsRecord.VNFs.GW
|
||||
if !reflect.ValueOf(gw).IsZero() {
|
||||
log.Debugf("flattenVins: discovered GW VNF ID %d in ViNS ID %d", gw.ID, vinsRecord.ID)
|
||||
extNetID := gw.Config.ExtNetID
|
||||
extNetIP := gw.Config.ExtNetIP
|
||||
if extNetID != 0 && extNetIP != "" {
|
||||
log.Debugf("flattenVins: ViNS ext_net_id=%d, ext_net_ip=%s", extNetID, extNetIP)
|
||||
d.Set("ext_ip_addr", extNetIP)
|
||||
d.Set("ext_net_id", extNetID)
|
||||
} else {
|
||||
return diag.Errorf("Failed to unmarshal VNF GW Config - structure is invalid.")
|
||||
}
|
||||
noExtNetConnection = false
|
||||
}
|
||||
|
||||
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))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func dataSourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
vinsFacts, err := utilityVinsCheckPresence(ctx, d, m)
|
||||
if vinsFacts == nil {
|
||||
vins, err := utilityVinsCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
return flattenVins(d, vinsFacts)
|
||||
flattenVinsData(d, vins)
|
||||
d.SetId(strconv.FormatUint(vins.ID, 10))
|
||||
return nil
|
||||
}
|
||||
|
||||
func DataSourceVins() *schema.Resource {
|
||||
@@ -105,64 +63,6 @@ func DataSourceVins() *schema.Resource {
|
||||
Read: &constants.Timeout30s,
|
||||
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(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,190 +1,71 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package vins
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
func flattenVinsList(vl *vins.ListVINS) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, v := range vl.Data {
|
||||
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-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package vins
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
func dataSourceVinsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
vinsList, err := utilityVinsListCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
id := uuid.New()
|
||||
d.SetId(id.String())
|
||||
d.Set("items", flattenVinsList(vinsList))
|
||||
d.Set("entry_count", vinsList.EntryCount)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func DataSourceVinsList() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
ReadContext: dataSourceVinsListRead,
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Read: &constants.Timeout30s,
|
||||
Default: &constants.Timeout60s,
|
||||
},
|
||||
|
||||
Schema: dataSourceVinsListSchemaMake(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Sergey Kisil, <svkisil@digitalenergy.online>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -39,83 +40,53 @@ import (
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/status"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
||||
)
|
||||
|
||||
func 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))
|
||||
|
||||
createInAcc := true
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
inAccReq := vins.CreateInAccountRequest{
|
||||
Name: d.Get("name").(string),
|
||||
}
|
||||
inRGReq := vins.CreateInRGRequest{
|
||||
Name: d.Get("name").(string),
|
||||
|
||||
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("rg_id")
|
||||
if argSet && argVal.(int) > 0 {
|
||||
createInAcc = false
|
||||
inRGReq.RGID = uint64(argVal.(int))
|
||||
} else {
|
||||
argVal, argSet = d.GetOk("account_id")
|
||||
if !argSet || argVal.(int) <= 0 {
|
||||
return diag.Errorf("resourceVinsCreate: ViNS name %s - no valid account and/or resource group ID specified", d.Id())
|
||||
}
|
||||
inAccReq.AccountID = uint64(argVal.(int))
|
||||
}
|
||||
|
||||
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 {
|
||||
inRGReq.ExtNetID = uint64(argVal.(int))
|
||||
} else {
|
||||
inRGReq.ExtNetID = 0
|
||||
}
|
||||
}
|
||||
|
||||
argVal, argSet = d.GetOk("ipcidr")
|
||||
if argSet && argVal.(string) != "" {
|
||||
log.Debugf("resourceVinsCreate: ipcidr is set to %s", argVal.(string))
|
||||
inAccReq.IPCIDR = argVal.(string)
|
||||
inRGReq.IPCIDR = argVal.(string)
|
||||
}
|
||||
|
||||
argVal, argSet = d.GetOk("description")
|
||||
if argSet {
|
||||
inAccReq.Description = argVal.(string)
|
||||
inRGReq.Description = argVal.(string)
|
||||
if rgOk && accountIdOk {
|
||||
return diag.Errorf("resourceVinsCreate: either accountId or resource group ID should be specified")
|
||||
}
|
||||
|
||||
var vinsID uint64
|
||||
if createInAcc {
|
||||
apiResp, err := c.CloudBroker().VINS().CreateInAccount(ctx, inAccReq)
|
||||
if accountIdOk {
|
||||
req, diags := createVinsInAcc(ctx, d, m, uint64(AccountID.(int)))
|
||||
if diags != nil {
|
||||
return diags
|
||||
}
|
||||
|
||||
apiResp, err := c.CloudBroker().VINS().CreateInAccount(ctx, req)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
vinsID = apiResp
|
||||
} else {
|
||||
apiResp, err := c.CloudBroker().VINS().CreateInRG(ctx, inRGReq)
|
||||
} else if rgOk {
|
||||
req, diags := createVinsInRG(ctx, d, m, uint64(RGID.(int)))
|
||||
if diags != nil {
|
||||
return diags
|
||||
}
|
||||
|
||||
apiResp, err := c.CloudBroker().VINS().CreateInRG(ctx, req)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
@@ -123,20 +94,103 @@ func resourceVinsCreate(ctx context.Context, d *schema.ResourceData, m interface
|
||||
}
|
||||
|
||||
d.SetId(strconv.FormatUint(vinsID, 10))
|
||||
d.Set("vins_id", vinsID)
|
||||
|
||||
log.Debugf("resourceVinsCreate: new ViNS ID / name %d / %s creation sequence complete", vinsID, d.Get("name").(string))
|
||||
|
||||
return dataSourceVinsRead(ctx, d, m)
|
||||
warnings := dc.Warnings{}
|
||||
if _, ok := d.GetOk("ip"); ok {
|
||||
if errs := resourceVinsIpReserve(ctx, d, m, vinsID); len(errs) != 0 {
|
||||
for _, err := range errs {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := d.GetOk("nat_rule"); ok {
|
||||
if errs := resourceVinsNatRuleAdd(ctx, d, m, vinsID); len(errs) != 0 {
|
||||
for _, err := range errs {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return append(warnings.Get(), resourceVinsRead(ctx, d, m)...)
|
||||
}
|
||||
|
||||
func resourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
vinsFacts, err := utilityVinsCheckPresence(ctx, d, m)
|
||||
if vinsFacts == nil {
|
||||
log.Debugf("resourceVinsRead: called for vins id %s, name %s",
|
||||
d.Id(), d.Get("name").(string))
|
||||
|
||||
warnings := dc.Warnings{}
|
||||
|
||||
vinsData, err := utilityVinsCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
return flattenVins(d, vinsFacts)
|
||||
isEnabled := d.Get("enable").(bool)
|
||||
|
||||
hasChangeState := false
|
||||
|
||||
switch vinsData.Status {
|
||||
case status.Destroyed:
|
||||
d.Set("vins_id", 0)
|
||||
d.SetId("")
|
||||
return diag.Errorf("The resource cannot be read because it has been destroyed")
|
||||
// return resourceVinsCreate(ctx, d, m)
|
||||
case status.Deleted:
|
||||
// hasChangeState = true
|
||||
|
||||
// req := vins.RestoreRequest{
|
||||
// VINSID: vinsData.ID,
|
||||
// }
|
||||
// if reason, ok := d.GetOk("reason"); ok {
|
||||
// req.Reason = reason.(string)
|
||||
// }
|
||||
|
||||
// _, err := c.CloudBroker().VINS().Restore(ctx, req)
|
||||
// if err != nil {
|
||||
// warnings.Add(err)
|
||||
// }
|
||||
case status.Modeled:
|
||||
return diag.Errorf("ViNS are in status: %s, please, contact support for more information", vinsData.Status)
|
||||
case status.Created:
|
||||
case status.Enabled:
|
||||
if !isEnabled {
|
||||
hasChangeState = true
|
||||
if err := resourceVinsDisable(ctx, d, m, vinsData.ID); err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
case status.Enabling:
|
||||
case status.Disabled:
|
||||
if isEnabled {
|
||||
hasChangeState = true
|
||||
if err := resourceVinsEnable(ctx, d, m, vinsData.ID); err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
case status.Disabling:
|
||||
case status.Deleting:
|
||||
return diag.Errorf("ViNS are in progress with status: %s", vinsData.Status)
|
||||
}
|
||||
|
||||
if hasChangeState {
|
||||
vinsData, err = utilityVinsCheckPresence(ctx, d, m)
|
||||
if vinsData == nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
flattenVins(d, vinsData)
|
||||
|
||||
log.Debugf("resourceVinsRead: after flattenVins: vins_id %s, name %s",
|
||||
d.Id(), d.Get("name").(string))
|
||||
|
||||
return warnings.Get()
|
||||
}
|
||||
|
||||
func resourceVinsUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
@@ -144,137 +198,588 @@ func resourceVinsUpdate(ctx context.Context, d *schema.ResourceData, m interface
|
||||
d.Id(), d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int))
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
vinsID, _ := strconv.ParseUint(d.Id(), 10, 64)
|
||||
|
||||
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))
|
||||
if diags := checkParamsExistenceUpdate(ctx, d, c); diags != nil {
|
||||
return diags
|
||||
}
|
||||
|
||||
if oldExtNetId.(int) > 0 {
|
||||
// there was preexisting external net connection - disconnect ViNS
|
||||
req := vins.ExtNetDisconnectRequest{VINSID: vinsID}
|
||||
vinsData, err := utilityVinsCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().VINS().ExtNetDisconnect(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
isEnabled := d.Get("enable").(bool)
|
||||
|
||||
hasChangeState := false
|
||||
|
||||
warnings := dc.Warnings{}
|
||||
switch vinsData.Status {
|
||||
case status.Destroyed:
|
||||
d.Set("vins_id", 0)
|
||||
d.SetId("")
|
||||
return diag.Errorf("The resource cannot be updated because it has been destroyed")
|
||||
// return resourceVinsCreate(ctx, d, m)
|
||||
case status.Deleted:
|
||||
hasChangeState = true
|
||||
|
||||
if err := resourceVinsRestore(ctx, d, m, vinsData.ID); err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
case status.Modeled:
|
||||
return diag.Errorf("ViNS are in status: %s, please, contact support for more information", vinsData.Status)
|
||||
case status.Created:
|
||||
case status.Enabled:
|
||||
if !isEnabled {
|
||||
hasChangeState = true
|
||||
if err := resourceVinsDisable(ctx, d, m, vinsData.ID); err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
|
||||
if newExtNedId.(int) > 0 {
|
||||
req := vins.ExtNetConnectRequest{
|
||||
VINSID: vinsID,
|
||||
NetID: uint64(newExtNedId.(int)),
|
||||
case status.Enabling:
|
||||
case status.Disabled:
|
||||
if isEnabled {
|
||||
hasChangeState = true
|
||||
if err := resourceVinsEnable(ctx, d, m, vinsData.ID); err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
case status.Disabling:
|
||||
case status.Deleting:
|
||||
return diag.Errorf("ViNS are in progress with status: %s", vinsData.Status)
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().VINS().ExtNetConnect(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
if hasChangeState {
|
||||
vinsData, err = utilityVinsCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange("enable") {
|
||||
if err := resourceVinsChangeEnabled(ctx, d, m); err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange("ext_net_id") {
|
||||
if err := resourceVinsChangeExtNetId(ctx, d, m); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange("ip") {
|
||||
if errs := resourceVinsChangeIp(ctx, d, m); len(errs) != 0 {
|
||||
for _, err := range errs {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
if d.HasChange("nat_rule") {
|
||||
if errs := resourceVinsChangeNatRule(ctx, d, m); len(errs) != 0 {
|
||||
for _, err := range errs {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dataSourceVinsRead(ctx, d, m)
|
||||
if d.HasChange("default_qos") {
|
||||
if err := resourceVinsChangeDefaultQos(ctx, d, m); err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange("vnfdev_redeploy") {
|
||||
if err := resourceVinsChangeVnfRedeploy(ctx, d, m); err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange("vnfdev_restart") {
|
||||
if err := resourceVinsChangeVnfRestart(ctx, d, m); err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange("vnfdev_reset") {
|
||||
if err := resourceVinsChangeVnfReset(ctx, d, m); err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange("vnfdev_start") {
|
||||
if err := resourceVinsChangeVnfStartStop(ctx, d, m); err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
|
||||
return append(warnings.Get(), dataSourceVinsRead(ctx, d, m)...)
|
||||
}
|
||||
|
||||
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 == nil {
|
||||
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
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := vins.DeleteRequest{
|
||||
VINSID: vinsFacts.ID,
|
||||
Force: true,
|
||||
Permanently: true,
|
||||
|
||||
vinsItem, err := utilityVinsCheckPresence(ctx, d, m)
|
||||
if vinsItem == nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
_, err = c.CloudBroker().VINS().Delete(ctx, req)
|
||||
if err != nil {
|
||||
req := vins.DeleteRequest{VINSID: vinsItem.ID}
|
||||
|
||||
if force, ok := d.GetOk("force"); ok {
|
||||
req.Force = force.(bool)
|
||||
}
|
||||
if permanently, ok := d.GetOk("permanently"); ok {
|
||||
req.Permanently = permanently.(bool)
|
||||
}
|
||||
if reason, ok := d.GetOk("reason"); ok {
|
||||
req.Reason = reason.(string)
|
||||
}
|
||||
|
||||
if _, err := c.CloudBroker().VINS().Delete(ctx, req); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId("")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceVinsEnable(ctx context.Context, d *schema.ResourceData, m interface{}, vinsId uint64) error {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
req := vins.EnableRequest{
|
||||
VINSID: vinsId,
|
||||
}
|
||||
if reason, ok := d.GetOk("reason"); ok {
|
||||
req.Reason = reason.(string)
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().VINS().Enable(ctx, req)
|
||||
return err
|
||||
}
|
||||
|
||||
func resourceVinsDisable(ctx context.Context, d *schema.ResourceData, m interface{}, vinsId uint64) error {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
req := vins.DisableRequest{
|
||||
VINSID: vinsId,
|
||||
}
|
||||
if reason, ok := d.GetOk("reason"); ok {
|
||||
req.Reason = reason.(string)
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().VINS().Disable(ctx, req)
|
||||
return err
|
||||
}
|
||||
|
||||
func resourceVinsRestore(ctx context.Context, d *schema.ResourceData, m interface{}, vinsId uint64) error {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
req := vins.RestoreRequest{
|
||||
VINSID: vinsId,
|
||||
}
|
||||
if reason, ok := d.GetOk("reason"); ok {
|
||||
req.Reason = reason.(string)
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().VINS().Restore(ctx, req)
|
||||
return err
|
||||
}
|
||||
|
||||
func resourceVinsIpReserve(ctx context.Context, d *schema.ResourceData, m interface{}, vinsId uint64) []error {
|
||||
var errs []error
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
ipRes := d.Get("ip")
|
||||
|
||||
ipsSlice := ipRes.([]interface{})
|
||||
for _, ipInterfase := range ipsSlice {
|
||||
ip := ipInterfase.(map[string]interface{})
|
||||
|
||||
req := vins.IPReserveRequest{
|
||||
VINSID: vinsId,
|
||||
Type: ip["type"].(string),
|
||||
}
|
||||
if ipAddr, ok := ip["ip_addr"]; ok {
|
||||
req.IPAddr = ipAddr.(string)
|
||||
}
|
||||
if macAddr, ok := ip["mac"]; ok {
|
||||
req.MAC = macAddr.(string)
|
||||
}
|
||||
if computeId, ok := ip["compute_id"]; ok {
|
||||
req.ComputeID = uint64(computeId.(int))
|
||||
}
|
||||
if reason, ok := ip["reason"]; ok {
|
||||
req.Reason = reason.(string)
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().VINS().IPReserve(ctx, req)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
func resourceVinsNatRuleAdd(ctx context.Context, d *schema.ResourceData, m interface{}, vinsId uint64) []error {
|
||||
var errs []error
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
natRule := d.Get("nat_rule")
|
||||
|
||||
addedNatRules := natRule.([]interface{})
|
||||
if len(addedNatRules) > 0 {
|
||||
for _, natRuleInterface := range addedNatRules {
|
||||
natRule := natRuleInterface.(map[string]interface{})
|
||||
|
||||
req := vins.NATRuleAddRequest{
|
||||
VINSID: vinsId,
|
||||
IntIP: natRule["int_ip"].(string),
|
||||
IntPort: uint64(natRule["int_port"].(int)),
|
||||
ExtPortStart: uint64(natRule["ext_port_start"].(int)),
|
||||
}
|
||||
if extPortEnd, ok := natRule["ext_port_end"]; ok {
|
||||
req.ExtPortEnd = uint64(extPortEnd.(int))
|
||||
}
|
||||
if proto, ok := natRule["proto"]; ok {
|
||||
req.Proto = proto.(string)
|
||||
}
|
||||
if reason, ok := natRule["reason"]; ok {
|
||||
req.Reason = reason.(string)
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().VINS().NATRuleAdd(ctx, req)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
func resourceVinsChangeEnabled(ctx context.Context, d *schema.ResourceData, m interface{}) error {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
vinsId := uint64(d.Get("vins_id").(int))
|
||||
|
||||
_, enableNew := d.GetChange("enable")
|
||||
if enableNew.(bool) {
|
||||
req := vins.EnableRequest{
|
||||
VINSID: vinsId,
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().VINS().Enable(ctx, req)
|
||||
return err
|
||||
}
|
||||
|
||||
req := vins.DisableRequest{
|
||||
VINSID: vinsId,
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().VINS().Disable(ctx, req)
|
||||
return err
|
||||
}
|
||||
|
||||
func resourceVinsChangeExtNetId(ctx context.Context, d *schema.ResourceData, m interface{}) error {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
vinsId := uint64(d.Get("vins_id").(int))
|
||||
oldExtNetId, newExtNedId := d.GetChange("ext_net_id")
|
||||
log.Debugf("resourceVinsUpdate - resourceVinsChangeExtNetId: changing ViNS ID %s - ext_net_id %d -> %d", d.Id(), oldExtNetId.(int), newExtNedId.(int))
|
||||
|
||||
if oldExtNetId.(int) > 0 {
|
||||
// there was preexisting external net connection - disconnect ViNS
|
||||
req := vins.ExtNetDisconnectRequest{VINSID: vinsId}
|
||||
|
||||
if reason, ok := d.GetOk("reason"); ok {
|
||||
req.Reason = reason.(string)
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().VINS().ExtNetDisconnect(ctx, req)
|
||||
return err
|
||||
}
|
||||
|
||||
if newExtNedId.(int) > 0 {
|
||||
req := vins.ExtNetConnectRequest{
|
||||
VINSID: vinsId,
|
||||
NetID: uint64(newExtNedId.(int)),
|
||||
}
|
||||
if ip, ok := d.GetOk("ext_ip"); ok && ip != "" {
|
||||
req.IP = ip.(string)
|
||||
}
|
||||
if reason, ok := d.GetOk("reason"); ok {
|
||||
req.Reason = reason.(string)
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().VINS().ExtNetConnect(ctx, req)
|
||||
return err
|
||||
}
|
||||
|
||||
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.",
|
||||
},
|
||||
func resourceVinsChangeIp(ctx context.Context, d *schema.ResourceData, m interface{}) []error {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
/* 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.",
|
||||
},
|
||||
*/
|
||||
var errs []error
|
||||
|
||||
"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.",
|
||||
},
|
||||
vinsId := uint64(d.Get("vins_id").(int))
|
||||
deletedIps := make([]interface{}, 0)
|
||||
addedIps := make([]interface{}, 0)
|
||||
|
||||
"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.",
|
||||
},
|
||||
oldIpInterface, newIpInterface := d.GetChange("ip")
|
||||
oldIpSlice := oldIpInterface.([]interface{})
|
||||
newIpSlice := newIpInterface.([]interface{})
|
||||
|
||||
"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.",
|
||||
},
|
||||
|
||||
"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.",
|
||||
},
|
||||
|
||||
"description": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Default: "",
|
||||
Description: "Optional user-defined text description of this ViNS.",
|
||||
},
|
||||
|
||||
// the rest of attributes are computed
|
||||
"account_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Name of the account, which this ViNS belongs to.",
|
||||
},
|
||||
|
||||
"ext_ip_addr": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "IP address of the external connection (valid for ViNS connected to external network, ignored otherwise).",
|
||||
},
|
||||
for _, el := range oldIpSlice {
|
||||
if !isContainsIp(newIpSlice, el) {
|
||||
deletedIps = append(deletedIps, el)
|
||||
}
|
||||
}
|
||||
|
||||
return rets
|
||||
for _, el := range newIpSlice {
|
||||
if !isContainsIp(oldIpSlice, el) {
|
||||
addedIps = append(addedIps, el)
|
||||
}
|
||||
}
|
||||
|
||||
if len(deletedIps) > 0 {
|
||||
for _, ipInterface := range deletedIps {
|
||||
ip := ipInterface.(map[string]interface{})
|
||||
req := vins.IPReleaseRequest{VINSID: vinsId}
|
||||
|
||||
if ip["ip_addr"].(string) != "" {
|
||||
req.IPAddr = ip["ip_addr"].(string)
|
||||
}
|
||||
if ip["mac"].(string) != "" {
|
||||
req.MAC = ip["mac"].(string)
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().VINS().IPRelease(ctx, req)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(addedIps) > 0 {
|
||||
for _, ipInterface := range addedIps {
|
||||
ip := ipInterface.(map[string]interface{})
|
||||
req := vins.IPReserveRequest{
|
||||
VINSID: vinsId,
|
||||
Type: ip["type"].(string),
|
||||
}
|
||||
|
||||
if ip["ip_addr"].(string) != "" {
|
||||
req.IPAddr = ip["ip_addr"].(string)
|
||||
}
|
||||
if ip["mac"].(string) != "" {
|
||||
req.MAC = ip["mac"].(string)
|
||||
}
|
||||
if ip["compute_id"].(int) != 0 {
|
||||
req.ComputeID = uint64(ip["compute_id"].(int))
|
||||
}
|
||||
if ip["reason"].(string) != "" {
|
||||
req.Reason = ip["reason"].(string)
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().VINS().IPReserve(ctx, req)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
func resourceVinsChangeNatRule(ctx context.Context, d *schema.ResourceData, m interface{}) []error {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
var errs []error
|
||||
|
||||
vinsId := uint64(d.Get("vins_id").(int))
|
||||
|
||||
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 !isContainsNatRule(newNatRulesSlice, el) {
|
||||
deletedNatRules = append(deletedNatRules, el)
|
||||
}
|
||||
}
|
||||
|
||||
for _, el := range newNatRulesSlice {
|
||||
if !isContainsNatRule(oldNatRulesSlice, el) {
|
||||
addedNatRules = append(addedNatRules, el)
|
||||
}
|
||||
}
|
||||
|
||||
if len(deletedNatRules) > 0 {
|
||||
for _, natRuleInterface := range deletedNatRules {
|
||||
natRule := natRuleInterface.(map[string]interface{})
|
||||
req := vins.NATRuleDelRequest{
|
||||
VINSID: vinsId,
|
||||
RuleID: int64(natRule["rule_id"].(int)),
|
||||
}
|
||||
if natRule["reason"].(string) != "" {
|
||||
req.Reason = natRule["reason"].(string)
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().VINS().NATRuleDel(ctx, req)
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(addedNatRules) > 0 {
|
||||
for _, natRuleInterface := range addedNatRules {
|
||||
natRule := natRuleInterface.(map[string]interface{})
|
||||
req := vins.NATRuleAddRequest{
|
||||
VINSID: vinsId,
|
||||
IntIP: natRule["int_ip"].(string),
|
||||
IntPort: uint64(natRule["int_port"].(int)),
|
||||
ExtPortStart: uint64(natRule["ext_port_start"].(int)),
|
||||
}
|
||||
|
||||
if natRule["ext_port_end"].(int) != 0 {
|
||||
req.ExtPortEnd = uint64(natRule["ext_port_end"].(int))
|
||||
}
|
||||
if natRule["proto"].(string) != "" {
|
||||
req.Proto = natRule["proto"].(string)
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().VINS().NATRuleAdd(ctx, req)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
func resourceVinsChangeDefaultQos(ctx context.Context, d *schema.ResourceData, m interface{}) error {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
vinsId := uint64(d.Get("vins_id").(int))
|
||||
|
||||
defaultQosInterface := d.Get("default_qos").([]interface{})
|
||||
|
||||
if len(defaultQosInterface) > 0 {
|
||||
defaultQos := defaultQosInterface[0].(map[string]interface{})
|
||||
req := vins.DefaultQOSUpdateRequest{VINSID: vinsId}
|
||||
if inRate, ok := defaultQos["in_rate"]; ok {
|
||||
req.IngressRate = uint64(inRate.(int))
|
||||
}
|
||||
if inBurst, ok := defaultQos["in_burst"]; ok {
|
||||
req.IngressBirst = uint64(inBurst.(int))
|
||||
}
|
||||
if eRate, ok := defaultQos["e_rate"]; ok {
|
||||
req.EgressRate = uint64(eRate.(int))
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().VINS().DefaultQOSUpdate(ctx, req)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceVinsChangeVnfRedeploy(ctx context.Context, d *schema.ResourceData, m interface{}) error {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
vinsId := uint64(d.Get("vins_id").(int))
|
||||
|
||||
_, newRedeploy := d.GetChange("vnfdev_redeploy")
|
||||
if newRedeploy.(bool) {
|
||||
req := vins.VNFDevRedeployRequest{VINSID: vinsId}
|
||||
if reason, ok := d.GetOk("reason"); ok {
|
||||
req.Reason = reason.(string)
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().VINS().VNFDevRedeploy(ctx, req)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceVinsChangeVnfRestart(ctx context.Context, d *schema.ResourceData, m interface{}) error {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
vinsId := uint64(d.Get("vins_id").(int))
|
||||
|
||||
_, newRestart := d.GetChange("vnfdev_restart")
|
||||
if newRestart.(bool) {
|
||||
req := vins.VNFDevRestartRequest{VINSID: vinsId}
|
||||
if reason, ok := d.GetOk("reason"); ok {
|
||||
req.Reason = reason.(string)
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().VINS().VNFDevRestart(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceVinsChangeVnfReset(ctx context.Context, d *schema.ResourceData, m interface{}) error {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
vinsId := uint64(d.Get("vins_id").(int))
|
||||
|
||||
_, newRestart := d.GetChange("vnfdev_reset")
|
||||
if newRestart.(bool) {
|
||||
req := vins.VNFDevResetRequest{VINSID: vinsId}
|
||||
if reason, ok := d.GetOk("reason"); ok {
|
||||
req.Reason = reason.(string)
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().VINS().VNFDevReset(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceVinsChangeVnfStartStop(ctx context.Context, d *schema.ResourceData, m interface{}) error {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
vinsId := uint64(d.Get("vins_id").(int))
|
||||
|
||||
_, newStart := d.GetChange("vnfdev_start")
|
||||
if newStart.(bool) {
|
||||
req := vins.VNFDevStartRequest{VINSID: vinsId}
|
||||
if reason, ok := d.GetOk("reason"); ok {
|
||||
req.Reason = reason.(string)
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().VINS().VNFDevStart(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
req := vins.VNFDevStopRequest{VINSID: vinsId}
|
||||
if reason, ok := d.GetOk("reason"); ok {
|
||||
req.Reason = reason.(string)
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().VINS().VNFDevStop(ctx, req)
|
||||
return err
|
||||
}
|
||||
|
||||
func ResourceVins() *schema.Resource {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Sergey Kisil, <svkisil@digitalenergy.online>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -33,7 +34,6 @@ package vins
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
@@ -46,78 +46,24 @@ import (
|
||||
func utilityVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.RecordVINS, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
idSet := false
|
||||
vinsID, err := strconv.ParseUint(d.Id(), 10, 64)
|
||||
if err != nil || vinsID <= 0 {
|
||||
vinsId, argSet := d.GetOk("vins_id") // NB: vins_id is NOT present in vinsResource schema!
|
||||
if argSet {
|
||||
vinsID = uint64(vinsId.(int))
|
||||
idSet = true
|
||||
}
|
||||
log.Debug("utilityVinsCheckPresence: locating ViNS by its ID")
|
||||
req := vins.GetRequest{}
|
||||
|
||||
if d.Id() != "" {
|
||||
id, _ := strconv.ParseUint(d.Id(), 10, 64)
|
||||
req.VINSID = id
|
||||
} else {
|
||||
idSet = true
|
||||
req.VINSID = uint64(d.Get("vins_id").(int))
|
||||
}
|
||||
|
||||
if idSet {
|
||||
log.Debugf("utilityVinsCheckPresence: locating ViNS by its ID %d", vinsID)
|
||||
req := vins.GetRequest{VINSID: vinsID}
|
||||
|
||||
vinsFacts, err := c.CloudBroker().VINS().Get(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return vinsFacts, nil
|
||||
if reason, ok := d.GetOk("reason"); ok {
|
||||
req.Reason = reason.(string)
|
||||
}
|
||||
|
||||
vinsName, argSet := d.GetOk("name")
|
||||
if !argSet {
|
||||
return nil, fmt.Errorf("Cannot check ViNS presence if ViNS name is empty")
|
||||
}
|
||||
req := vins.SearchRequest{
|
||||
Name: vinsName.(string),
|
||||
ShowAll: 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))
|
||||
req.RGID = uint64(rgId.(int))
|
||||
}
|
||||
|
||||
accountId, accountSet := d.GetOk("account_id")
|
||||
if accountSet {
|
||||
log.Debugf("utilityVinsCheckPresence: limiting ViNS search to Account ID %d", accountId.(int))
|
||||
req.AccountID = uint64(accountId.(int))
|
||||
}
|
||||
|
||||
vinsList, err := c.CloudBroker().VINS().Search(ctx, req)
|
||||
vins, err := c.CloudBroker().VINS().Get(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Debugf("utilityVinsCheckPresence: traversing decoded Json of length %d", len(vinsList))
|
||||
for index, item := range vinsList {
|
||||
if item.Name == vinsName.(string) {
|
||||
if (accountSet && item.AccountID != uint64(accountId.(int))) ||
|
||||
(rgSet && item.RGID != uint64(rgId.(int))) {
|
||||
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)
|
||||
|
||||
req := vins.GetRequest{VINSID: item.ID}
|
||||
|
||||
vinsGetResp, err := c.CloudBroker().VINS().Get(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return vinsGetResp, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("Cannot find ViNS name %s. Check name and/or RG ID & Account ID and your access rights", vinsName.(string))
|
||||
return vins, nil
|
||||
}
|
||||
|
||||
@@ -1,62 +1,80 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package vins
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilityVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.ListVINS, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := vins.ListRequest{}
|
||||
|
||||
if page, ok := d.GetOk("page"); ok {
|
||||
req.Page = uint64(page.(int))
|
||||
}
|
||||
if size, ok := d.GetOk("size"); ok {
|
||||
req.Size = uint64(size.(int))
|
||||
}
|
||||
|
||||
log.Debugf("utilityVinsListCheckPresence")
|
||||
vinsList, err := c.CloudBroker().VINS().List(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return vinsList, nil
|
||||
}
|
||||
/*
|
||||
Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package vins
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilityVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.ListVINS, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := vins.ListRequest{}
|
||||
|
||||
if byId, ok := d.GetOk("by_id"); ok {
|
||||
req.ByID = uint64(byId.(int))
|
||||
}
|
||||
if name, ok := d.GetOk("name"); ok {
|
||||
req.Name = name.(string)
|
||||
}
|
||||
if accountId, ok := d.GetOk("account_id"); ok {
|
||||
req.AccountID = uint64(accountId.(int))
|
||||
}
|
||||
if rgId, ok := d.GetOk("rg_id"); ok {
|
||||
req.RGID = uint64(rgId.(int))
|
||||
}
|
||||
if extIp, ok := d.GetOk("ext_ip"); ok {
|
||||
req.ExtIP = extIp.(string)
|
||||
}
|
||||
if page, ok := d.GetOk("page"); ok {
|
||||
req.Page = uint64(page.(int))
|
||||
}
|
||||
if size, ok := d.GetOk("size"); ok {
|
||||
req.Size = uint64(size.(int))
|
||||
}
|
||||
if includeDeleted, ok := d.GetOk("include_deleted"); ok {
|
||||
req.IncludeDeleted = includeDeleted.(bool)
|
||||
}
|
||||
|
||||
log.Debugf("utilityVinsListCheckPresence")
|
||||
vinsList, err := c.CloudBroker().VINS().List(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return vinsList, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user