1.0.1
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins"
|
||||
)
|
||||
|
||||
func VINSDataSourceCheckPresence(ctx context.Context, vinsId uint64, c *decort.DecortClient) (*vins.RecordVINS, diag.Diagnostics) {
|
||||
tflog.Info(ctx, fmt.Sprintf("VINSDataSourceCheckPresence: Get info about vins with ID - %v", vinsId))
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
recordVINS, err := c.CloudBroker().VINS().Get(ctx, vins.GetRequest{VINSID: vinsId})
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("Cannot get info about vins with ID %v", vinsId), err.Error())
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "VINSDataSourceCheckPresence: response from CloudBroker().VINS().Get", map[string]any{"vins_id": vinsId, "response": recordVINS})
|
||||
|
||||
return recordVINS, nil
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins"
|
||||
)
|
||||
|
||||
func VINSAuditsDataSourceCheckPresence(ctx context.Context, vinsId uint64, c *decort.DecortClient) (*vins.ListAudits, diag.Diagnostics) {
|
||||
tflog.Info(ctx, fmt.Sprintf("VINSAuditsDataSourceCheckPresence: Get info about vins audit with vins ID - %v", vinsId))
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
audits, err := c.CloudBroker().VINS().Audits(ctx, vins.AuditsRequest{VINSID: vinsId})
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("Cannot get info about audits for vins with ID %v", vinsId), err.Error())
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "VINSAuditsDataSourceCheckPresence: successful response from CloudBroker().VINS().Audits", map[string]any{"vins_id": vinsId})
|
||||
|
||||
return &audits, nil
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins"
|
||||
)
|
||||
|
||||
func VINSExtNetListDataSourceCheckPresence(ctx context.Context, vinsId uint64, c *decort.DecortClient) (*vins.ListExtNets, diag.Diagnostics) {
|
||||
tflog.Info(ctx, fmt.Sprintf("VINSExtNetListDataSourceCheckPresence: Get info about vins audit with vins ID - %v", vinsId))
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
extnetList, err := c.CloudBroker().VINS().ExtNetList(ctx, vins.ExtNetListRequest{VINSID: vinsId})
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("Cannot get info about extnet list for vins with ID %v", vinsId), err.Error())
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "VINSExtNetListDataSourceCheckPresence: successful response from CloudBroker().VINS().ExtNetList", map[string]any{"vins_id": vinsId})
|
||||
|
||||
return extnetList, nil
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins"
|
||||
)
|
||||
|
||||
func VINSIPListDataSourceCheckPresence(ctx context.Context, vinsId uint64, c *decort.DecortClient) (*vins.ListIPs, diag.Diagnostics) {
|
||||
tflog.Info(ctx, fmt.Sprintf("VINSIPListDataSourceCheckPresence: Get info about vins audit with vins ID - %v", vinsId))
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
ipList, err := c.CloudBroker().VINS().IPList(ctx, vins.IPListRequest{VINSID: vinsId})
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("Cannot get info about ip list for vins with ID %v", vinsId), err.Error())
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "VINSIPListDataSourceCheckPresence: successful response from CloudBroker().VINS().IPList", map[string]any{"vins_id": vinsId})
|
||||
|
||||
return ipList, nil
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudbroker/vins/models"
|
||||
)
|
||||
|
||||
func VINSListDataSourceCheckPresence(ctx context.Context, plan *models.DataSourceVINSListModel, c *decort.DecortClient) (*vins.ListVINS, diag.Diagnostics) {
|
||||
tflog.Info(ctx, "VINSListDataSourceCheckPresence: Get info about vins list")
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
listReq := vins.ListRequest{}
|
||||
if !plan.ByID.IsNull() {
|
||||
listReq.ByID = uint64(plan.ByID.ValueInt64())
|
||||
}
|
||||
if !plan.Name.IsNull() {
|
||||
listReq.Name = plan.Name.ValueString()
|
||||
}
|
||||
if !plan.AccountID.IsNull() {
|
||||
listReq.AccountID = uint64(plan.AccountID.ValueInt64())
|
||||
}
|
||||
if !plan.RGID.IsNull() {
|
||||
listReq.RGID = uint64(plan.RGID.ValueInt64())
|
||||
}
|
||||
if !plan.ExtIP.IsNull() {
|
||||
listReq.ExtIP = plan.ExtIP.ValueString()
|
||||
}
|
||||
if !plan.VNFDevID.IsNull() {
|
||||
listReq.VNFDevID = uint64(plan.VNFDevID.ValueInt64())
|
||||
}
|
||||
if !plan.IncludeDeleted.IsNull() {
|
||||
listReq.IncludeDeleted = plan.IncludeDeleted.ValueBool()
|
||||
}
|
||||
if !plan.SortBy.IsNull() {
|
||||
listReq.SortBy = plan.SortBy.ValueString()
|
||||
}
|
||||
if !plan.Page.IsNull() {
|
||||
listReq.Page = uint64(plan.Page.ValueInt64())
|
||||
}
|
||||
if !plan.Size.IsNull() {
|
||||
listReq.Size = uint64(plan.Size.ValueInt64())
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "VINSListDataSourceCheckPresence: before call CloudBroker().VINS().List", map[string]any{"req": listReq})
|
||||
list, err := c.CloudBroker().VINS().List(ctx, listReq)
|
||||
if err != nil {
|
||||
diags.AddError("Cannot get info about vins list", err.Error())
|
||||
return nil, diags
|
||||
}
|
||||
tflog.Info(ctx, "VINSListDataSourceCheckPresence: successful response from CloudBroker().VINS().List")
|
||||
|
||||
return list, nil
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudbroker/vins/models"
|
||||
)
|
||||
|
||||
func VINSListDeletedDataSourceCheckPresence(ctx context.Context, plan *models.DataSourceVINSListDeletedModel, c *decort.DecortClient) (*vins.ListVINS, diag.Diagnostics) {
|
||||
tflog.Info(ctx, "VINSListDeletedDataSourceCheckPresence: Get info about vins list")
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
listReq := vins.ListDeletedRequest{}
|
||||
if !plan.ByID.IsNull() {
|
||||
listReq.ByID = uint64(plan.ByID.ValueInt64())
|
||||
}
|
||||
if !plan.Name.IsNull() {
|
||||
listReq.Name = plan.Name.ValueString()
|
||||
}
|
||||
if !plan.AccountID.IsNull() {
|
||||
listReq.AccountID = uint64(plan.AccountID.ValueInt64())
|
||||
}
|
||||
if !plan.RGID.IsNull() {
|
||||
listReq.RGID = uint64(plan.RGID.ValueInt64())
|
||||
}
|
||||
if !plan.ExtIP.IsNull() {
|
||||
listReq.ExtIP = plan.ExtIP.ValueString()
|
||||
}
|
||||
if !plan.SortBy.IsNull() {
|
||||
listReq.SortBy = plan.SortBy.ValueString()
|
||||
}
|
||||
if !plan.Page.IsNull() {
|
||||
listReq.Page = uint64(plan.Page.ValueInt64())
|
||||
}
|
||||
if !plan.Size.IsNull() {
|
||||
listReq.Size = uint64(plan.Size.ValueInt64())
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "VINSListDeletedDataSourceCheckPresence: before call CloudBroker().VINS().ListDeleted", map[string]any{"req": listReq})
|
||||
list, err := c.CloudBroker().VINS().ListDeleted(ctx, listReq)
|
||||
if err != nil {
|
||||
diags.AddError("Cannot get info about vins deleted list", err.Error())
|
||||
return nil, diags
|
||||
}
|
||||
tflog.Info(ctx, "VINSListDeletedDataSourceCheckPresence: successful response from CloudBroker().VINS().ListDeleted")
|
||||
|
||||
return list, nil
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudbroker/vins/models"
|
||||
)
|
||||
|
||||
func VINSNATRuleListDataSourceCheckPresence(ctx context.Context, state *models.DataSourceVINSNATRuleListModel, c *decort.DecortClient) (*vins.ListNATRules, diag.Diagnostics) {
|
||||
tflog.Info(ctx, "VINSNATRuleListDataSourceCheckPresence: Get info about vins nat rule list")
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
req := vins.NATRuleListRequest{
|
||||
VINSID: uint64(state.VinsID.ValueInt64()),
|
||||
}
|
||||
|
||||
if !state.Reason.IsNull() {
|
||||
req.Reason = state.Reason.ValueString()
|
||||
}
|
||||
|
||||
natRuleList, err := c.CloudBroker().VINS().NATRuleList(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddError("Cannot get info about vins nat rule list", err.Error())
|
||||
return nil, diags
|
||||
}
|
||||
tflog.Info(ctx, "VINSNATRuleListDataSourceCheckPresence: successful response from CloudBroker().VINS().NATRuleList")
|
||||
|
||||
return natRuleList, nil
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins"
|
||||
)
|
||||
|
||||
func VINSStaticRouteDataSourceCheckPresence(ctx context.Context, vinsId, routeId uint64, c *decort.DecortClient) (*vins.ItemRoutes, diag.Diagnostics) {
|
||||
tflog.Info(ctx, "VINSStaticRouteDataSourceCheckPresence: Get info about vins static route", map[string]any{
|
||||
"vins_id": vinsId,
|
||||
"route_id": routeId,
|
||||
})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
routesList, err := c.CloudBroker().VINS().StaticRouteList(ctx, vins.StaticRouteListRequest{VINSID: vinsId})
|
||||
if err != nil {
|
||||
diags.AddError("Cannot get info about vins static route", err.Error())
|
||||
return nil, diags
|
||||
}
|
||||
tflog.Info(ctx, "VINSStaticRouteDataSourceCheckPresence: successful response from CloudBroker().VINS().StaticRouteList")
|
||||
|
||||
staticRoute := &vins.ItemRoutes{}
|
||||
for _, route := range routesList.Data {
|
||||
if routeId == route.ID {
|
||||
staticRoute = &route
|
||||
return staticRoute, nil
|
||||
}
|
||||
}
|
||||
|
||||
diags.AddError("Static route not found",
|
||||
fmt.Sprintf("Static route with id %d not found for vins with id %d", routeId, vinsId))
|
||||
return nil, diags
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins"
|
||||
)
|
||||
|
||||
func VINSStaticRouteListDataSourceCheckPresence(ctx context.Context, vinsId uint64, c *decort.DecortClient) (*vins.ListStaticRoutes, diag.Diagnostics) {
|
||||
tflog.Info(ctx, "VINSStaticRouteListDataSourceCheckPresence: Get info about vins static route list")
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
routesList, err := c.CloudBroker().VINS().StaticRouteList(ctx, vins.StaticRouteListRequest{VINSID: vinsId})
|
||||
if err != nil {
|
||||
diags.AddError("Cannot get info about vins static route list", err.Error())
|
||||
return nil, diags
|
||||
}
|
||||
tflog.Info(ctx, "VINSStaticRouteListDataSourceCheckPresence: successful response from CloudBroker().VINS().StaticRouteList")
|
||||
|
||||
return routesList, nil
|
||||
}
|
||||
@@ -0,0 +1,948 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudbroker/vins/models"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/status"
|
||||
)
|
||||
|
||||
func VINSResourceCheckPresence(ctx context.Context, vinsId uint64, c *decort.DecortClient) (*vins.RecordVINS, diag.Diagnostics) {
|
||||
tflog.Info(ctx, fmt.Sprintf("VINSResourceCheckPresence: Get info about vins with ID - %v", vinsId))
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
recordVINS, err := c.CloudBroker().VINS().Get(ctx, vins.GetRequest{VINSID: vinsId})
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("Cannot get info about vins with ID %v", vinsId), err.Error())
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "VINSResourceCheckPresence: response from CloudBroker().VINS().Get", map[string]any{"vins_id": vinsId, "response": recordVINS})
|
||||
|
||||
return recordVINS, nil
|
||||
}
|
||||
|
||||
// CreateInRGResourceVINS creates vins in resource group based on plan.
|
||||
// Returns vins_id for created vins and errors in case of failures.
|
||||
func CreateInRGResourceVINS(ctx context.Context, plan *models.ResourceVINSModel, c *decort.DecortClient) (uint64, diag.Diagnostics) {
|
||||
tflog.Info(ctx, fmt.Sprintf("Start CreateInRGResourceVINS: vins_name %s", plan.Name.ValueString()))
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
createReq := vins.CreateInRGRequest{
|
||||
Name: plan.Name.ValueString(),
|
||||
RGID: uint64(plan.RGID.ValueInt64()),
|
||||
}
|
||||
|
||||
if !plan.IPCIDR.IsNull() { // IPCIDR is optional
|
||||
createReq.IPCIDR = plan.IPCIDR.ValueString()
|
||||
}
|
||||
|
||||
if !plan.ExtNet.IsNull() { // ExtNet is optional
|
||||
var extnetPlan models.ExtNetModel
|
||||
tflog.Info(ctx, "CreateInRGResourceVINS: extnet specified", map[string]any{"name": plan.Name.ValueString()})
|
||||
diags.Append(plan.ExtNet.As(ctx, &extnetPlan, basetypes.ObjectAsOptions{UnhandledNullAsEmpty: true})...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "CreateInRGResourceVINS: cannot populate extnet with plan.ExtNet object element")
|
||||
return 0, diags
|
||||
}
|
||||
|
||||
if extnetPlan.ExtNetID.IsNull() {
|
||||
createReq.ExtNetID = -1 // default value
|
||||
} else {
|
||||
createReq.ExtNetID = extnetPlan.ExtNetID.ValueInt64()
|
||||
}
|
||||
|
||||
if !extnetPlan.ExtNetIP.IsNull() {
|
||||
createReq.ExtIP = extnetPlan.ExtNetIP.ValueString()
|
||||
}
|
||||
} else {
|
||||
createReq.ExtNetID = -1 // default value
|
||||
}
|
||||
|
||||
if !plan.Description.IsNull() { // Description is optional
|
||||
createReq.Description = plan.Description.ValueString()
|
||||
}
|
||||
if plan.PreReservationsNum.IsUnknown() { // PreReservationsNum is optional & computed
|
||||
createReq.PreReservationsNum = uint64(32) // default value
|
||||
} else {
|
||||
createReq.PreReservationsNum = uint64(plan.PreReservationsNum.ValueInt64())
|
||||
}
|
||||
if !plan.Reason.IsNull() {
|
||||
createReq.Reason = plan.Reason.ValueString()
|
||||
}
|
||||
if !plan.DNS.IsNull() {
|
||||
result := make([]string, 0, len(plan.DNS.Elements()))
|
||||
for _, val := range plan.DNS.Elements() {
|
||||
result = append(result, strings.Trim(val.String(), "\""))
|
||||
}
|
||||
createReq.DNSList = result
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "CreateInRGResourceVINS: before call CloudBroker().VINS().CreateInRG", map[string]any{"req": createReq})
|
||||
|
||||
vinsId, err := c.CloudBroker().VINS().CreateInRG(ctx, createReq)
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"Create resourceVINS: unable to Create VINS in RG",
|
||||
err.Error(),
|
||||
)
|
||||
return 0, diags
|
||||
}
|
||||
tflog.Info(ctx, "CreateInRGResourceVINS: vins created", map[string]any{"vins_id": vinsId, "vins_name": plan.Name.ValueString()})
|
||||
|
||||
return vinsId, nil
|
||||
}
|
||||
|
||||
// CreateInAccountResourceVINS creates vins in account based on plan.
|
||||
// Returns vins_id for created vins and errors in case of failures.
|
||||
func CreateInAccountResourceVINS(ctx context.Context, plan *models.ResourceVINSModel, c *decort.DecortClient) (uint64, diag.Diagnostics) {
|
||||
tflog.Info(ctx, fmt.Sprintf("Start CreateInAccountResourceVINS: vins_name %s", plan.Name.ValueString()))
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
createReq := vins.CreateInAccountRequest{
|
||||
Name: plan.Name.ValueString(),
|
||||
AccountID: uint64(plan.AccountID.ValueInt64()),
|
||||
}
|
||||
|
||||
if !plan.GID.IsUnknown() { // IPCIDR is optional & computed
|
||||
createReq.GID = uint64(plan.GID.ValueInt64())
|
||||
}
|
||||
|
||||
if !plan.IPCIDR.IsNull() { // IPCIDR is optional
|
||||
createReq.IPCIDR = plan.IPCIDR.ValueString()
|
||||
}
|
||||
|
||||
if !plan.Description.IsNull() { // Description is optional
|
||||
createReq.Description = plan.Description.ValueString()
|
||||
}
|
||||
|
||||
if plan.PreReservationsNum.IsNull() { // PreReservationsNum is optional
|
||||
createReq.PreReservationsNum = uint64(32) // default value
|
||||
} else {
|
||||
createReq.PreReservationsNum = uint64(plan.PreReservationsNum.ValueInt64())
|
||||
}
|
||||
|
||||
if !plan.Reason.IsNull() {
|
||||
createReq.Reason = plan.Reason.ValueString()
|
||||
}
|
||||
|
||||
if !plan.DNS.IsNull() {
|
||||
result := make([]string, 0, len(plan.DNS.Elements()))
|
||||
for _, val := range plan.DNS.Elements() {
|
||||
result = append(result, strings.Trim(val.String(), "\""))
|
||||
}
|
||||
createReq.DNSList = result
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "CreateInAccountResourceVINS: before call CloudBroker().VINS().CreateInAccount", map[string]any{"req": createReq})
|
||||
|
||||
vinsId, err := c.CloudBroker().VINS().CreateInAccount(ctx, createReq)
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"Create resourceVINS: unable to Create VINS in Account",
|
||||
err.Error(),
|
||||
)
|
||||
return 0, diags
|
||||
}
|
||||
tflog.Info(ctx, "CreateInAccountResourceVINS: vins created", map[string]any{"vins_id": vinsId, "vins_name": plan.Name.ValueString()})
|
||||
|
||||
return vinsId, nil
|
||||
}
|
||||
|
||||
// IPCreateVINS reserves ips that user specified in ip field for created resource.
|
||||
// In case of failure returns warnings.
|
||||
func IPCreateVINS(ctx context.Context, vinsId uint64, plan *models.ResourceVINSModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
// plan.IP is not null as it was checked before call
|
||||
ipPlan := make([]models.IPModel, 0, len(plan.IP.Elements()))
|
||||
tflog.Info(ctx, "IPCreateVINS: new ip specified", map[string]any{"vins_id": vinsId})
|
||||
diagsItem := plan.IP.ElementsAs(ctx, &ipPlan, true)
|
||||
if diagsItem.HasError() {
|
||||
tflog.Error(ctx, fmt.Sprintf("IPCreateVINS: cannot populate ipPlan with plan.IP list elements: %v", diagsItem))
|
||||
diags.AddWarning("IPCreateVINS: Unable to read ip for vins",
|
||||
fmt.Sprintf("%v", diagsItem))
|
||||
return diags
|
||||
}
|
||||
|
||||
for _, ip := range ipPlan {
|
||||
ipReserveReq := vins.IPReserveRequest{
|
||||
VINSID: vinsId,
|
||||
Type: ip.Type.ValueString(),
|
||||
}
|
||||
|
||||
if ip.IPAddr.ValueString() != "" {
|
||||
ipReserveReq.IPAddr = ip.IPAddr.ValueString()
|
||||
}
|
||||
if ip.MacAddr.ValueString() != "" {
|
||||
ipReserveReq.MAC = ip.MacAddr.ValueString()
|
||||
}
|
||||
if ip.ComputeID.ValueInt64() != 0 {
|
||||
ipReserveReq.ComputeID = uint64(ip.ComputeID.ValueInt64())
|
||||
}
|
||||
if ip.Reason.ValueString() != "" {
|
||||
ipReserveReq.Reason = ip.Reason.ValueString()
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "IPCreateVINS: before calling CloudBroker().VINS().IPReserve", map[string]any{
|
||||
"vins_id": vinsId,
|
||||
"ipReserveReq": ipReserveReq})
|
||||
res, err := c.CloudBroker().VINS().IPReserve(ctx, ipReserveReq)
|
||||
if err != nil {
|
||||
diags.AddWarning("IPCreateVINS: Unable to reserve ip for vins",
|
||||
err.Error())
|
||||
}
|
||||
tflog.Info(ctx, "IPCreateVINS: response from CloudBroker().VINS().IPReserve", map[string]any{
|
||||
"vins_id": vinsId,
|
||||
"response": res})
|
||||
}
|
||||
|
||||
return diags
|
||||
}
|
||||
|
||||
// IPUpdateVINS reserves/releases ips that user specified in ip field for updated resource.
|
||||
// In case of failure returns errors.
|
||||
func IPUpdateVINS(ctx context.Context, vinsId uint64, plan, state *models.ResourceVINSModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "Start IPUpdateVINS: new ip specified", map[string]any{"vins_id": vinsId})
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
ipPlan := make([]models.IPModel, 0, len(plan.IP.Elements()))
|
||||
tflog.Info(ctx, "IPUpdateVINS: new ip specified", map[string]any{"vins_id": vinsId})
|
||||
diags.Append(plan.IP.ElementsAs(ctx, &ipPlan, true)...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "IPUpdateVINS: cannot populate ipPlan with plan.IP list elements")
|
||||
return diags
|
||||
}
|
||||
|
||||
ipState := make([]models.IPModel, 0, len(state.IP.Elements()))
|
||||
tflog.Info(ctx, "IPUpdateVINS: new ip specified", map[string]any{"vins_id": vinsId})
|
||||
diags.Append(state.IP.ElementsAs(ctx, &ipState, true)...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "IPUpdateVINS: cannot populate ipState with state.IP list elements")
|
||||
return diags
|
||||
}
|
||||
|
||||
// define ip to be released and release them
|
||||
var deletedIP []models.IPModel
|
||||
for _, ipStateElem := range ipState {
|
||||
if !ipStateElem.Contains(ipPlan) {
|
||||
deletedIP = append(deletedIP, ipStateElem)
|
||||
}
|
||||
}
|
||||
if len(deletedIP) == 0 {
|
||||
tflog.Info(ctx, "IPUpdateVINS: no ip needs to be release", map[string]any{"vins_id": plan.Id.ValueString()})
|
||||
}
|
||||
if len(deletedIP) > 0 {
|
||||
tflog.Info(ctx, "IPUpdateVINS: ip needs to be released", map[string]any{
|
||||
"vins_id": plan.Id.ValueString(),
|
||||
"deletedIP": deletedIP})
|
||||
|
||||
for _, deletedIPItem := range deletedIP {
|
||||
releaseIPReq := vins.IPReleaseRequest{
|
||||
VINSID: vinsId,
|
||||
IPAddr: deletedIPItem.IPAddr.ValueString(),
|
||||
MAC: deletedIPItem.MacAddr.ValueString(),
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "IPUpdateVINS: before calling CloudBroker().VINS().IPRelese", map[string]any{"vins_id": plan.Id.ValueString(), "req": releaseIPReq})
|
||||
res, err := c.CloudBroker().VINS().IPRelease(ctx, releaseIPReq)
|
||||
tflog.Info(ctx, "IPUpdateVINS: response from CloudBroker().VINS().IPRelese", map[string]any{"vins_id": plan.Id.ValueString(), "response": res})
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"IPUpdateVINS: can not release ip for VINS",
|
||||
err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// define ips to be reserved and reserve them
|
||||
var addedIP []models.IPModel
|
||||
for _, ipPlanElem := range ipPlan {
|
||||
if !ipPlanElem.Contains(ipState) {
|
||||
addedIP = append(addedIP, ipPlanElem)
|
||||
}
|
||||
}
|
||||
|
||||
if len(addedIP) == 0 {
|
||||
tflog.Info(ctx, "IPUpdateVINS: no ip needs to be reserved", map[string]any{"vins_id": plan.Id.ValueString()})
|
||||
}
|
||||
if len(addedIP) > 0 {
|
||||
tflog.Info(ctx, "IPUpdateVINS: ip needs to be reserved", map[string]any{
|
||||
"vins_id": plan.Id.ValueString(),
|
||||
"addedIP": addedIP})
|
||||
|
||||
for _, addedIPItem := range addedIP {
|
||||
ipReserveReq := vins.IPReserveRequest{
|
||||
VINSID: vinsId,
|
||||
Type: addedIPItem.Type.ValueString(),
|
||||
}
|
||||
|
||||
if addedIPItem.IPAddr.ValueString() != "" {
|
||||
ipReserveReq.IPAddr = addedIPItem.IPAddr.ValueString()
|
||||
}
|
||||
if addedIPItem.MacAddr.ValueString() != "" {
|
||||
ipReserveReq.MAC = addedIPItem.MacAddr.ValueString()
|
||||
}
|
||||
if addedIPItem.ComputeID.ValueInt64() != 0 {
|
||||
ipReserveReq.ComputeID = uint64(addedIPItem.ComputeID.ValueInt64())
|
||||
}
|
||||
if addedIPItem.Reason.ValueString() != "" {
|
||||
ipReserveReq.MAC = addedIPItem.Reason.ValueString()
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "IPUpdateVINS: before calling CloudBroker().VINS().IPReserve", map[string]any{
|
||||
"vins_id": vinsId,
|
||||
"ipReserveReq": ipReserveReq})
|
||||
res, err := c.CloudBroker().VINS().IPReserve(ctx, ipReserveReq)
|
||||
if err != nil {
|
||||
diags.AddError("IPUpdateVINS: Unable to reserve ip for vins",
|
||||
err.Error())
|
||||
}
|
||||
tflog.Info(ctx, "IPUpdateVINS: response from CloudBroker().VINS().IPReserve", map[string]any{
|
||||
"vins_id": vinsId,
|
||||
"response": res})
|
||||
}
|
||||
}
|
||||
|
||||
return diags
|
||||
}
|
||||
|
||||
// ExtNetUpdateVINS updates ext_net_id and/or ext_net_ip that user specified in ext_net block for updated resource.
|
||||
// In case of failure returns errors.
|
||||
func ExtNetUpdateVINS(ctx context.Context, vinsId uint64, plan, state *models.ResourceVINSModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "Start ExtNetUpdateVINS: new ext_net specified", map[string]any{
|
||||
"vins_id": vinsId,
|
||||
})
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
if !state.ExtNet.IsNull() {
|
||||
disconReq := vins.ExtNetDisconnectRequest{
|
||||
VINSID: vinsId,
|
||||
}
|
||||
tflog.Info(ctx, "ExtNetUpdateVINS: before calling CloudBroker().VINS().ExtNetDisconnect", map[string]any{"vins_id": plan.Id.ValueString(), "req": disconReq})
|
||||
res, err := c.CloudBroker().VINS().ExtNetDisconnect(ctx, disconReq)
|
||||
tflog.Info(ctx, "ExtNetUpdateVINS: response from CloudBroker().VINS().ExtNetDisconnect", map[string]any{"vins_id": plan.Id.ValueString(), "response": res})
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"ExtNetUpdateVINS: can not disconnect extnet for VINS",
|
||||
err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
if !plan.ExtNet.IsNull() {
|
||||
var extnetPlan models.ExtNetModel
|
||||
tflog.Info(ctx, "ExtNetUpdateVINS: new extnet specified", map[string]any{"name": plan.Name.ValueString()})
|
||||
diags.Append(plan.ExtNet.As(ctx, &extnetPlan, basetypes.ObjectAsOptions{UnhandledNullAsEmpty: true})...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "ExtNetUpdateVINS: cannot populate extnet with plan.ExtNet object element")
|
||||
return diags
|
||||
}
|
||||
|
||||
conReq := vins.ExtNetConnectRequest{
|
||||
VINSID: vinsId,
|
||||
}
|
||||
if !extnetPlan.ExtNetID.IsNull() {
|
||||
conReq.NetID = uint64(extnetPlan.ExtNetID.ValueInt64())
|
||||
}
|
||||
if !extnetPlan.ExtNetIP.IsNull() {
|
||||
conReq.IP = extnetPlan.ExtNetIP.ValueString()
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "ExtNetUpdateVINS: before calling CloudBroker().VINS().ExtNetConnect", map[string]any{"vins_id": plan.Id.ValueString(), "req": conReq})
|
||||
res, err := c.CloudBroker().VINS().ExtNetConnect(ctx, conReq)
|
||||
tflog.Info(ctx, "ExtNetUpdateVINS: response from CloudBroker().VINS().ExtNetConnect", map[string]any{"vins_id": plan.Id.ValueString(), "response": res})
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"ExtNetUpdateVINS: can not connect extnet to VINS",
|
||||
err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
return diags
|
||||
}
|
||||
|
||||
// NATRuleCreateVINS adds nat rules that user specified in nat_rule field for created resource.
|
||||
// In case of failure returns warnings.
|
||||
func NATRuleCreateVINS(ctx context.Context, vinsId uint64, plan *models.ResourceVINSModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
// plan.NatRule is not null as it was checked before call
|
||||
natRulePlan := make([]models.NatRuleResourceModel, 0, len(plan.NatRule.Elements()))
|
||||
tflog.Info(ctx, "NATRuleCreateVINS: new natRule specified", map[string]any{"vins_id": vinsId})
|
||||
diagsItem := plan.NatRule.ElementsAs(ctx, &natRulePlan, false)
|
||||
if diagsItem.HasError() {
|
||||
tflog.Error(ctx, fmt.Sprintf("NATRuleCreateVINS: cannot populate natRulePlan with plan.NatRule list elements: %v", diagsItem))
|
||||
diags.AddWarning("NATRuleCreateVINS: Unable to add nat rule for vins",
|
||||
fmt.Sprintf("%v", diagsItem))
|
||||
return diags
|
||||
}
|
||||
|
||||
for _, nat := range natRulePlan {
|
||||
natAddReq := vins.NATRuleAddRequest{
|
||||
VINSID: vinsId,
|
||||
IntIP: nat.IntIP.ValueString(),
|
||||
IntPort: uint64(nat.IntPort.ValueInt64()),
|
||||
ExtPortStart: uint64(nat.ExtPortStart.ValueInt64()),
|
||||
}
|
||||
|
||||
if !nat.ExtPortEnd.IsUnknown() {
|
||||
natAddReq.ExtPortEnd = uint64(nat.ExtPortEnd.ValueInt64())
|
||||
}
|
||||
if !nat.Proto.IsUnknown() {
|
||||
natAddReq.Proto = nat.Proto.ValueString()
|
||||
}
|
||||
if !nat.Reason.IsNull() {
|
||||
natAddReq.Reason = nat.Reason.ValueString()
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "NATRuleCreateVINS: before calling CloudBroker().VINS().NATRuleAdd", map[string]any{
|
||||
"vins_id": vinsId,
|
||||
"natAddReq": natAddReq})
|
||||
res, err := c.CloudBroker().VINS().NATRuleAdd(ctx, natAddReq)
|
||||
if err != nil {
|
||||
diags.AddWarning("NATRuleCreateVINS: Unable to add nat rule for vins",
|
||||
err.Error())
|
||||
}
|
||||
tflog.Info(ctx, "NATRuleCreateVINS: response from CloudBroker().VINS().NATRuleAdd", map[string]any{
|
||||
"vins_id": vinsId,
|
||||
"response": res})
|
||||
}
|
||||
|
||||
return diags
|
||||
}
|
||||
|
||||
// DefaultQosCreateVINS update qos that user specified in defaultQos field for created resource.
|
||||
// In case of failure returns warnings.
|
||||
func DefaultQosCreateVINS(ctx context.Context, vinsId uint64, plan *models.ResourceVINSModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
// plan.DefaultQOS is not null as it was checked before call
|
||||
var defaultQosPlan models.QOSModel
|
||||
tflog.Info(ctx, "DefaultQosCreateVINS: defaultQos specified", map[string]any{"name": plan.Name.ValueString()})
|
||||
diags.Append(plan.DefaultQOS.As(ctx, &defaultQosPlan, basetypes.ObjectAsOptions{UnhandledNullAsEmpty: true})...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "DefaultQosCreateVINS: cannot populate defaultQosPlan with plan.DefaultQOS object")
|
||||
diags.AddWarning("DefaultQosCreateVINS: Unable to update defaultQos for vins",
|
||||
fmt.Sprintf("cannot populate defaultQosPlan with plan.DefaultQOS object"))
|
||||
return diags
|
||||
}
|
||||
|
||||
qosReq := vins.DefaultQOSUpdateRequest{
|
||||
VINSID: vinsId,
|
||||
}
|
||||
|
||||
if !defaultQosPlan.InRate.IsUnknown() {
|
||||
qosReq.IngressRate = uint64(defaultQosPlan.InRate.ValueInt64())
|
||||
}
|
||||
if !defaultQosPlan.InBurst.IsUnknown() {
|
||||
qosReq.IngressBirst = uint64(defaultQosPlan.InBurst.ValueInt64())
|
||||
}
|
||||
if !defaultQosPlan.ERate.IsUnknown() {
|
||||
qosReq.EgressRate = uint64(defaultQosPlan.ERate.ValueInt64())
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "DefaultQosCreateVINS: before calling CloudBroker().VINS().DefaultQOSUpdate", map[string]any{
|
||||
"vins_id": vinsId,
|
||||
"natAddReq": qosReq})
|
||||
res, err := c.CloudBroker().VINS().DefaultQOSUpdate(ctx, qosReq)
|
||||
if err != nil {
|
||||
diags.AddWarning("DefaultQosCreateVINS: Unable to update defaultQos for vins",
|
||||
err.Error())
|
||||
}
|
||||
tflog.Info(ctx, "DefaultQosCreateVINS: response from CloudBroker().VINS().DefaultQOSUpdate", map[string]any{
|
||||
"vins_id": vinsId,
|
||||
"response": res})
|
||||
|
||||
return diags
|
||||
}
|
||||
|
||||
// NATRuleUpdateVINS adds/deleted nat rules that user specified in nat_rule field for updated resource.
|
||||
// In case of failure returns errors.
|
||||
func NATRuleUpdateVINS(ctx context.Context, vinsId uint64, plan, state *models.ResourceVINSModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "Start NATRuleUpdateVINS: new natRule specified", map[string]any{"vins_id": vinsId})
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
itemsNatRulePlan := make([]models.NatRuleResourceModel, 0, len(plan.NatRule.Elements()))
|
||||
diags.Append(plan.NatRule.ElementsAs(ctx, &itemsNatRulePlan, false)...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "NATRuleUpdateVINS: cannot populate natRulePlan with plan.NatRule list elements")
|
||||
return diags
|
||||
}
|
||||
|
||||
itemsNatRuleState := make([]models.NatRuleResourceModel, 0, len(state.NatRule.Elements()))
|
||||
diags.Append(state.NatRule.ElementsAs(ctx, &itemsNatRuleState, false)...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "NATRuleUpdateVINS: cannot populate natRuleState with state.NatRule list elements")
|
||||
return diags
|
||||
}
|
||||
|
||||
// define nat rules to be deleted and delete them
|
||||
var deletedNatRule []models.NatRuleResourceModel
|
||||
for _, natRuleStateElem := range itemsNatRuleState {
|
||||
if !natRuleStateElem.Contains(itemsNatRulePlan) {
|
||||
deletedNatRule = append(deletedNatRule, natRuleStateElem)
|
||||
}
|
||||
}
|
||||
|
||||
if len(deletedNatRule) == 0 {
|
||||
tflog.Info(ctx, "NATRuleUpdateVINS: no natRule needs to be deleted", map[string]any{"vins_id": plan.Id.ValueString()})
|
||||
}
|
||||
if len(deletedNatRule) > 0 {
|
||||
tflog.Info(ctx, "NATRuleUpdateVINS: natRule needs to be deleted", map[string]any{
|
||||
"vins_id": plan.Id.ValueString(),
|
||||
"deletedNatRule": deletedNatRule})
|
||||
|
||||
for _, deletedNatRuleItem := range deletedNatRule {
|
||||
deleteNATReq := vins.NATRuleDelRequest{
|
||||
VINSID: vinsId,
|
||||
RuleID: deletedNatRuleItem.RuleID.ValueInt64(),
|
||||
}
|
||||
|
||||
if deletedNatRuleItem.Reason.ValueString() != "" {
|
||||
deleteNATReq.Reason = deletedNatRuleItem.Reason.ValueString()
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "NATRuleUpdateVINS: before calling CloudBroker().VINS().NATRuleDel", map[string]any{"vins_id": plan.Id.ValueString(), "req": deleteNATReq})
|
||||
res, err := c.CloudBroker().VINS().NATRuleDel(ctx, deleteNATReq)
|
||||
tflog.Info(ctx, "NATRuleUpdateVINS: response from CloudBroker().VINS().NATRuleDel", map[string]any{"vins_id": plan.Id.ValueString(), "response": res})
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"NATRuleUpdateVINS: can not delete nat rule for VINS",
|
||||
err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// define nat rules to be added and add them
|
||||
var addedNatRules []models.NatRuleResourceModel
|
||||
for _, natRulePlanElem := range itemsNatRulePlan {
|
||||
if !natRulePlanElem.Contains(itemsNatRuleState) {
|
||||
addedNatRules = append(addedNatRules, natRulePlanElem)
|
||||
}
|
||||
}
|
||||
|
||||
if len(addedNatRules) == 0 {
|
||||
tflog.Info(ctx, "NATRuleUpdateVINS: no nat rule needs to be added", map[string]any{"vins_id": plan.Id.ValueString()})
|
||||
}
|
||||
if len(addedNatRules) > 0 {
|
||||
tflog.Info(ctx, "NATRuleUpdateVINS: nat rule needs to be added", map[string]any{
|
||||
"vins_id": plan.Id.ValueString(),
|
||||
"addedNatRules": addedNatRules})
|
||||
|
||||
for _, addedNatRuleItem := range addedNatRules {
|
||||
natAddReq := vins.NATRuleAddRequest{
|
||||
VINSID: vinsId,
|
||||
IntIP: addedNatRuleItem.IntIP.ValueString(),
|
||||
IntPort: uint64(addedNatRuleItem.IntPort.ValueInt64()),
|
||||
ExtPortStart: uint64(addedNatRuleItem.ExtPortStart.ValueInt64()),
|
||||
}
|
||||
if !addedNatRuleItem.ExtPortEnd.IsUnknown() {
|
||||
natAddReq.ExtPortEnd = uint64(addedNatRuleItem.ExtPortEnd.ValueInt64())
|
||||
}
|
||||
if !addedNatRuleItem.Proto.IsUnknown() {
|
||||
natAddReq.Proto = addedNatRuleItem.Proto.ValueString()
|
||||
}
|
||||
if !addedNatRuleItem.Reason.IsUnknown() {
|
||||
natAddReq.Reason = addedNatRuleItem.Reason.ValueString()
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "NATRuleUpdateVINS: before calling CloudBroker().VINS().NATRuleAdd", map[string]any{
|
||||
"vins_id": vinsId,
|
||||
"natAddReq": natAddReq})
|
||||
res, err := c.CloudBroker().VINS().NATRuleAdd(ctx, natAddReq)
|
||||
if err != nil {
|
||||
diags.AddError("NATRuleUpdateVINS: Unable to add nat rule for vins",
|
||||
err.Error())
|
||||
}
|
||||
tflog.Info(ctx, "NATRuleUpdateVINS: response from CloudBroker().VINS().NATRuleAdd", map[string]any{
|
||||
"vins_id": vinsId,
|
||||
"response": res})
|
||||
}
|
||||
}
|
||||
|
||||
return diags
|
||||
}
|
||||
|
||||
// VINSReadStatus loads vins resource by ids id, gets it current status. Performs restore and enable if needed for
|
||||
// Deleted status.
|
||||
// In case of failure returns errors.
|
||||
func VINSReadStatus(ctx context.Context, state *models.ResourceVINSModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "VINSReadStatus: Read status vins with ID", map[string]any{"vins_id": state.Id.ValueString()})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
vinsId, err := strconv.ParseUint(state.Id.ValueString(), 10, 64)
|
||||
if err != nil {
|
||||
diags.AddError("VINSReadStatus: Cannot parse vins ID from state", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
recordVINS, diags := VINSResourceCheckPresence(ctx, vinsId, c)
|
||||
if err != nil {
|
||||
diags.AddError("VINSReadStatus: Unable to Read/Update VINS before status check", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
// check resource status
|
||||
switch recordVINS.Status {
|
||||
case status.Modeled:
|
||||
diags.AddError(
|
||||
"VINS is in status Modeled",
|
||||
"please, contact support for more information",
|
||||
)
|
||||
return diags
|
||||
case status.Deleted:
|
||||
// attempt to restore vins
|
||||
tflog.Info(ctx, "VINSReadStatus: vins with status.Deleted is being read or updated, attempt to restore it", map[string]any{
|
||||
"vins_id": recordVINS.ID,
|
||||
"status": recordVINS.Status})
|
||||
if state.Restore.IsNull() || state.Restore.ValueBool() { // default true or user set-up true
|
||||
diags.Append(RestoreVINS(ctx, vinsId, c)...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "VINSReadStatus: cannot restore vins")
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "VINSReadStatus: vins restored successfully", map[string]any{"vins_id": vinsId})
|
||||
|
||||
if state.Enable.IsNull() || state.Enable.ValueBool() {
|
||||
diags.Append(EnableVINS(ctx, vinsId, c)...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "VINSReadStatus: cannot enable vins")
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "VINSReadStatus: vins enabled successfully", map[string]any{"vins_id": vinsId})
|
||||
}
|
||||
|
||||
state.LastUpdated = types.StringValue(time.Now().Format(time.RFC850))
|
||||
}
|
||||
case status.Enabled:
|
||||
if !state.Enable.ValueBool() && !state.Enable.IsNull() {
|
||||
tflog.Info(ctx, "VINSReadStatus: vins with status.Enabled is being read or updated but should not be according to configuration (enable=false), attempt to disable it", map[string]any{
|
||||
"vins_id": recordVINS.ID,
|
||||
"status": recordVINS.Status})
|
||||
diags.Append(DisableVINS(ctx, vinsId, c)...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "VINSReadStatus: cannot disable vins")
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "VINSReadStatus: vins disabled successfully", map[string]any{"vins_id": vinsId})
|
||||
state.LastUpdated = types.StringValue(time.Now().Format(time.RFC850))
|
||||
}
|
||||
case status.Disabled:
|
||||
if state.Enable.ValueBool() {
|
||||
tflog.Info(ctx, "VINSReadStatus: vins with status.Disabled is being read or updated but should not be according to configuration (enable=true), attempt to enable it", map[string]any{
|
||||
"vins_id": recordVINS.ID,
|
||||
"status": recordVINS.Status})
|
||||
diags.Append(EnableVINS(ctx, vinsId, c)...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "VINSReadStatus: cannot enable vins")
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "VINSReadStatus: vins enabled successfully", map[string]any{"vins_id": vinsId})
|
||||
state.LastUpdated = types.StringValue(time.Now().Format(time.RFC850))
|
||||
}
|
||||
case status.Destroyed:
|
||||
diags.AddError(
|
||||
"VINSReadStatus: vins is in status Destroyed",
|
||||
fmt.Sprintf("the resource with vins_id %d cannot be read or updated because it has been destroyed", vinsId),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RestoreVINS performs vins Restore request.
|
||||
// Returns error in case of failures.
|
||||
func RestoreVINS(ctx context.Context, vinsId uint64, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
tflog.Info(ctx, "RestoreVINS: before calling CloudBroker().VINS().Restore", map[string]any{"vinsId": vinsId, "req": vins.RestoreRequest{VINSID: vinsId}})
|
||||
|
||||
res, err := c.CloudBroker().VINS().Restore(ctx, vins.RestoreRequest{VINSID: vinsId})
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"RestoreVINS: cannot restore vins",
|
||||
err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "RestoreVINS: response from CloudBroker().VINS().Restore", map[string]any{"vinsId": vinsId, "response": res})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DisableVINS performs vins Disable request.
|
||||
// Returns error in case of failures.
|
||||
func DisableVINS(ctx context.Context, vinsId uint64, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
tflog.Info(ctx, "DisableVINS: before calling CloudBroker().VINS().Disable", map[string]any{"vinsId": vinsId})
|
||||
|
||||
res, err := c.CloudBroker().VINS().Disable(ctx, vins.DisableRequest{VINSID: vinsId})
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"DisableVINS: cannot disable vins",
|
||||
err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "DisableVINS: response from CloudBroker().VINS().Disable", map[string]any{"vinsId": vinsId, "response": res})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// EnableVINS performs vins Enable request.
|
||||
// Returns error in case of failures.
|
||||
func EnableVINS(ctx context.Context, vinsId uint64, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
tflog.Info(ctx, "EnableVINS: before calling CloudBroker().VINS().Enable", map[string]any{"vinsId": vinsId})
|
||||
|
||||
res, err := c.CloudBroker().VINS().Enable(ctx, vins.EnableRequest{VINSID: vinsId})
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"EnableVINS: cannot enable vins",
|
||||
err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "EnableVINS: response from CloudBroker().VINS().Enable", map[string]any{"vinsId": vinsId, "response": res})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// EnableDisableUpdateVINS performs vins Enable/disable request.
|
||||
// Returns errors in case of failures.
|
||||
func EnableDisableUpdateVINS(ctx context.Context, vinsId uint64, plan *models.ResourceVINSModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
enable := plan.Enable.ValueBool()
|
||||
tflog.Info(ctx, "Start EnableDisableUpdateVINS", map[string]any{"vinsId": vinsId, "enable": enable})
|
||||
|
||||
if enable {
|
||||
diags.Append(EnableVINS(ctx, vinsId, c)...)
|
||||
return diags
|
||||
}
|
||||
|
||||
if !enable {
|
||||
diags.Append(DisableVINS(ctx, vinsId, c)...)
|
||||
return diags
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// VnfdevRestartUpdateVINS restarts vnf_dev for vins.
|
||||
// Returns error in case of failures.
|
||||
func VnfdevRestartUpdateVINS(ctx context.Context, vinsId uint64, plan *models.ResourceVINSModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
tflog.Info(ctx, "VnfdevRestartUpdateVINS: before calling CloudBroker().VINS().VNFDevRestart", map[string]any{"vinsId": vinsId})
|
||||
|
||||
req := vins.VNFDevRestartRequest{
|
||||
VINSID: vinsId,
|
||||
}
|
||||
|
||||
if !plan.Reason.IsNull() {
|
||||
req.Reason = plan.Reason.ValueString()
|
||||
}
|
||||
|
||||
res, err := c.CloudBroker().VINS().VNFDevRestart(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"VnfdevRestartUpdateVINS: cannot restart vnf_dev for vins",
|
||||
err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "VnfdevRestartUpdateVINS: response from CloudBroker().VINS().VNFDevRestart", map[string]any{"vinsId": vinsId, "response": res})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// VnfdevRedeployUpdateVINS redeploys vnf_dev for vins.
|
||||
// Returns error in case of failures.
|
||||
func VnfdevRedeployUpdateVINS(ctx context.Context, vinsId uint64, plan *models.ResourceVINSModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
tflog.Info(ctx, "VnfdevRedeployUpdateVINS: before calling CloudBroker().VINS().VNFDevRedeploy", map[string]any{"vinsId": vinsId})
|
||||
|
||||
req := vins.VNFDevRedeployRequest{
|
||||
VINSID: vinsId,
|
||||
}
|
||||
|
||||
if !plan.Reason.IsNull() {
|
||||
req.Reason = plan.Reason.ValueString()
|
||||
}
|
||||
|
||||
res, err := c.CloudBroker().VINS().VNFDevRedeploy(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"VnfdevRedeployUpdateVINS: cannot redeploy vnf_dev for vins",
|
||||
err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "VnfdevRedeployUpdateVINS: response from CloudBroker().VINS().VNFDevRedeploy", map[string]any{"vinsId": vinsId, "response": res})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// VnfdevResetUpdateVINS reset vnf_dev for vins.
|
||||
// Returns error in case of failures.
|
||||
func VnfdevResetUpdateVINS(ctx context.Context, vinsId uint64, plan *models.ResourceVINSModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
tflog.Info(ctx, "VnfdevResetUpdateVINS: before calling CloudBroker().VINS().VNFDevReset", map[string]any{"vinsId": vinsId})
|
||||
|
||||
req := vins.VNFDevResetRequest{
|
||||
VINSID: vinsId,
|
||||
}
|
||||
|
||||
if !plan.Reason.IsNull() {
|
||||
req.Reason = plan.Reason.ValueString()
|
||||
}
|
||||
|
||||
res, err := c.CloudBroker().VINS().VNFDevReset(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"VnfdevResetUpdateVINS: cannot reset vnf_dev for vins",
|
||||
err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "VnfdevResetUpdateVINS: response from CloudBroker().VINS().VNFDevReset", map[string]any{"vinsId": vinsId, "response": res})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// VnfdevStartStopUpdateVINS start/stop vnf_dev for vins.
|
||||
// Returns error in case of failures.
|
||||
func VnfdevStartStopUpdateVINS(ctx context.Context, vinsId uint64, plan *models.ResourceVINSModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
if plan.VnfdevStart.ValueBool() {
|
||||
req := vins.VNFDevStartRequest{
|
||||
VINSID: vinsId,
|
||||
}
|
||||
if !plan.Reason.IsNull() {
|
||||
req.Reason = plan.Reason.ValueString()
|
||||
}
|
||||
tflog.Info(ctx, "VnfdevResetUpdateVINS: before calling CloudBroker().VINS().VNFDevStart", map[string]any{"vinsId": vinsId})
|
||||
res, err := c.CloudBroker().VINS().VNFDevStart(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"VnfdevResetUpdateVINS: cannot start vnf_dev for vins",
|
||||
err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "VnfdevResetUpdateVINS: response from CloudBroker().VINS().VNFDevStart", map[string]any{"vinsId": vinsId, "response": res})
|
||||
return nil
|
||||
}
|
||||
|
||||
req := vins.VNFDevStopRequest{
|
||||
VINSID: vinsId,
|
||||
}
|
||||
if !plan.Reason.IsNull() {
|
||||
req.Reason = plan.Reason.ValueString()
|
||||
}
|
||||
tflog.Info(ctx, "VnfdevResetUpdateVINS: before calling CloudBroker().VINS().VNFDevStop", map[string]any{"vinsId": vinsId})
|
||||
res, err := c.CloudBroker().VINS().VNFDevStop(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"VnfdevResetUpdateVINS: cannot start vnf_dev for vins",
|
||||
err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "VnfdevResetUpdateVINS: response from CloudBroker().VINS().VNFDevStop", map[string]any{"vinsId": vinsId, "response": res})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateDNSlistVINS apply new DNS list in VINS
|
||||
// Returns error in case of failures.
|
||||
func UpdateDNSlistVINS(ctx context.Context, vinsId uint64, plan *models.ResourceVINSModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
req := vins.DNSApplyRequest{
|
||||
VINSID: vinsId,
|
||||
}
|
||||
dnsList := make([]string, 0, len(plan.DNS.Elements()))
|
||||
for _, val := range plan.DNS.Elements() {
|
||||
dnsList = append(dnsList, strings.Trim(val.String(), "\""))
|
||||
}
|
||||
req.DNSList = dnsList
|
||||
|
||||
tflog.Info(ctx, "UpdateDNSListVINS: before calling CloudBroker().VINS().DNSApply", map[string]any{"vinsId": vinsId})
|
||||
|
||||
res, err := c.CloudBroker().VINS().DNSApply(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"UpdateDNSListVINS: cannot apply DNSList for vins",
|
||||
err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "UpdateDNSListVINS: after calling CloudBroker().VINS().DNSApply", map[string]any{"vinsId": vinsId, "response": res})
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
// UpdateDefaultQosVINS update qos that user specified in defaultQos field for update resource.
|
||||
// In case of failure returns error.
|
||||
func UpdateDefaultQosVINS(ctx context.Context, vinsId uint64, plan *models.ResourceVINSModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
// plan.DefaultQOS is not null as it was checked before call
|
||||
var defaultQosPlan models.QOSModel
|
||||
tflog.Info(ctx, "DefaultQosUpdateVINS: defaultQos specified", map[string]any{"name": plan.Name.ValueString()})
|
||||
diags.Append(plan.DefaultQOS.As(ctx, &defaultQosPlan, basetypes.ObjectAsOptions{UnhandledNullAsEmpty: true})...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "DefaultQosUpdateVINS: cannot populate defaultQosPlan with plan.DefaultQOS object")
|
||||
return diags
|
||||
}
|
||||
|
||||
qosReq := vins.DefaultQOSUpdateRequest{
|
||||
VINSID: vinsId,
|
||||
}
|
||||
|
||||
if !defaultQosPlan.InRate.IsUnknown() {
|
||||
qosReq.IngressRate = uint64(defaultQosPlan.InRate.ValueInt64())
|
||||
}
|
||||
if !defaultQosPlan.InBurst.IsUnknown() {
|
||||
qosReq.IngressBirst = uint64(defaultQosPlan.InBurst.ValueInt64())
|
||||
}
|
||||
if !defaultQosPlan.ERate.IsUnknown() {
|
||||
qosReq.EgressRate = uint64(defaultQosPlan.ERate.ValueInt64())
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "DefaultQosUpdateVINS: before calling CloudBroker().VINS().DefaultQOSUpdate", map[string]any{
|
||||
"vins_id": vinsId,
|
||||
"natAddReq": qosReq})
|
||||
res, err := c.CloudBroker().VINS().DefaultQOSUpdate(ctx, qosReq)
|
||||
if err != nil {
|
||||
diags.AddError("DefaultQosUpdateVINS: Unable to update defaultQos for vins",
|
||||
err.Error())
|
||||
}
|
||||
tflog.Info(ctx, "DefaultQosUpdateVINS: response from CloudBroker().VINS().DefaultQOSUpdate", map[string]any{
|
||||
"vins_id": vinsId,
|
||||
"response": res})
|
||||
|
||||
return diags
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudbroker/vins/models"
|
||||
)
|
||||
|
||||
func VINSStaticRouteResourceCheckPresence(ctx context.Context, vinsId, routeId uint64, c *decort.DecortClient) (*vins.ItemRoutes, diag.Diagnostics) {
|
||||
tflog.Info(ctx, "VINSStaticRouteResourceCheckPresence: Get info about vins static route")
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
tflog.Info(ctx, "VINSStaticRouteResourceCheckPresence: before call to CloudBroker().VINS().StaticRouteList", map[string]any{"vins_id": vinsId, "route_id": routeId})
|
||||
staticRouteList, err := c.CloudBroker().VINS().StaticRouteList(ctx, vins.StaticRouteListRequest{VINSID: vinsId})
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
fmt.Sprintf("VINSStaticRouteResourceCheckPresence: Cannot get info about vins static route %v", vinsId),
|
||||
err.Error())
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "VINSStaticRouteResourceCheckPresence: response from CloudBroker().VINS().StaticRouteList", map[string]any{"vins_id": vinsId, "response": staticRouteList})
|
||||
|
||||
staticRoute := &vins.ItemRoutes{}
|
||||
for _, route := range staticRouteList.Data {
|
||||
if routeId == route.ID {
|
||||
staticRoute = &route
|
||||
return staticRoute, nil
|
||||
}
|
||||
}
|
||||
|
||||
diags.AddError(
|
||||
"VINSStaticRouteResourceCheckPresence: static route not found",
|
||||
fmt.Sprintf("static route not found for route_id=%d and vins_id=%d", routeId, vinsId))
|
||||
|
||||
return nil, diags
|
||||
|
||||
}
|
||||
|
||||
func GetVinsIDAndRouteID(ctx context.Context, plan *models.ResourceVINSStaticRouteModel) (uint64, uint64, diag.Diagnostics) {
|
||||
tflog.Info(ctx, "Start GetVinsIDAndRouteID")
|
||||
|
||||
var err error
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
vinsId := uint64(plan.VinsID.ValueInt64())
|
||||
routeId := uint64(plan.RouteID.ValueInt64())
|
||||
|
||||
if plan.Id.ValueString() != "" {
|
||||
vals := strings.Split(plan.Id.ValueString(), "#")
|
||||
if len(vals) != 2 {
|
||||
diags.AddError(
|
||||
"GetVinsIDAndRouteID: broken state id",
|
||||
fmt.Sprintf("state id expected: <vins_id>#<route_id>, got: %v", plan.Id.ValueString()))
|
||||
return 0, 0, diags
|
||||
}
|
||||
|
||||
vinsId, err = strconv.ParseUint(vals[0], 10, 64)
|
||||
if err != nil {
|
||||
diags.AddError("GetVinsIDAndRouteID: can not parse vinsId from state", err.Error())
|
||||
return 0, 0, diags
|
||||
}
|
||||
|
||||
routeId, err = strconv.ParseUint(vals[1], 10, 64)
|
||||
if err != nil {
|
||||
diags.AddError("GetVinsIDAndRouteID: can not parse routeId from state", err.Error())
|
||||
return 0, 0, diags
|
||||
}
|
||||
}
|
||||
|
||||
return vinsId, routeId, nil
|
||||
}
|
||||
|
||||
func GetStaticRouteID(ctx context.Context, plan *models.ResourceVINSStaticRouteModel, c *decort.DecortClient) (uint64, diag.Diagnostics) {
|
||||
tflog.Info(ctx, "Start GetStaticRouteID")
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
vinsId := uint64(plan.VinsID.ValueInt64())
|
||||
|
||||
tflog.Info(ctx, "GetStaticRouteID: before call to CloudBroker().VINS().StaticRouteList", map[string]any{"vins_id": vinsId})
|
||||
staticRouteList, err := c.CloudBroker().VINS().StaticRouteList(ctx, vins.StaticRouteListRequest{VINSID: vinsId})
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
fmt.Sprintf("GetStaticRouteID: Cannot get info about vins static routes %v", vinsId),
|
||||
err.Error())
|
||||
return 0, diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "GetStaticRouteID: response from CloudBroker().VINS().StaticRouteList", map[string]any{"vins_id": vinsId, "response": staticRouteList})
|
||||
|
||||
destination := plan.Destination.ValueString()
|
||||
gateway := plan.Gateway.ValueString()
|
||||
|
||||
staticRoute := &vins.ItemRoutes{}
|
||||
for _, route := range staticRouteList.Data {
|
||||
if destination == route.Destination && gateway == route.Gateway {
|
||||
staticRoute = &route
|
||||
return staticRoute.ID, nil
|
||||
}
|
||||
}
|
||||
|
||||
diags.AddError(
|
||||
"GetStaticRouteID: static route not found",
|
||||
fmt.Sprintf("Static route (destination=%s, gateway=%s) not found for vins with vins_id=%d", destination, gateway, vinsId))
|
||||
|
||||
return 0, diags
|
||||
}
|
||||
|
||||
func UpdateComputeIDsVINSStaticRoute(ctx context.Context, plan, state *models.ResourceVINSStaticRouteModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "Start UpdateComputeIDsVINSStaticRoute", map[string]any{"id": plan.Id.ValueString()})
|
||||
|
||||
vinsId, routeId, diags := GetVinsIDAndRouteID(ctx, plan)
|
||||
if diags.HasError() {
|
||||
return diags
|
||||
}
|
||||
|
||||
computesPlan := make([]uint64, 0, len(plan.ComputeIDs.Elements()))
|
||||
diags = plan.ComputeIDs.ElementsAs(ctx, &computesPlan, false)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "UpdateComputeIDsVINSStaticRoute: cannot populate computes with plan.ComputeIDs List elements")
|
||||
return diags
|
||||
}
|
||||
|
||||
computesState := make([]uint64, 0, len(state.ComputeIDs.Elements()))
|
||||
diags = state.ComputeIDs.ElementsAs(ctx, &computesState, false)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "UpdateComputeIDsVINSStaticRoute: cannot populate computes with state.ComputeIDs List elements")
|
||||
return diags
|
||||
}
|
||||
|
||||
var deletedComputes []uint64
|
||||
for _, comp := range computesState {
|
||||
if !contains(comp, computesPlan) {
|
||||
deletedComputes = append(deletedComputes, comp)
|
||||
}
|
||||
}
|
||||
if len(deletedComputes) != 0 {
|
||||
revokeReq := vins.StaticRouteAccessRevokeRequest{
|
||||
VINSID: vinsId,
|
||||
RouteId: routeId,
|
||||
ComputeIds: deletedComputes,
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "UpdateComputeIDsVINSStaticRoute: before call to CloudBroker().VINS().StaticRouteAccessRevoke", map[string]any{"revokeReq": revokeReq})
|
||||
_, err := c.CloudBroker().VINS().StaticRouteAccessRevoke(ctx, revokeReq)
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
fmt.Sprintf("UpdateComputeIDsVINSStaticRoute: Cannot revoke static routes for vins with id %v", vinsId),
|
||||
err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
var addedComputes []uint64
|
||||
for _, comp := range computesPlan {
|
||||
if !contains(comp, computesState) {
|
||||
addedComputes = append(addedComputes, comp)
|
||||
}
|
||||
}
|
||||
if len(addedComputes) != 0 {
|
||||
grantReq := vins.StaticRouteAccessGrantRequest{
|
||||
VINSID: vinsId,
|
||||
RouteId: routeId,
|
||||
ComputeIds: addedComputes,
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "UpdateComputeIDsVINSStaticRoute: before call to CloudBroker().VINS().StaticRouteAccessGrant", map[string]any{"grantReq": grantReq})
|
||||
_, err := c.CloudBroker().VINS().StaticRouteAccessGrant(ctx, grantReq)
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
fmt.Sprintf("UpdateComputeIDsVINSStaticRoute: Cannot grant static routes for vins with id %v", vinsId),
|
||||
err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
return diags
|
||||
}
|
||||
|
||||
// contains returns true if slice contains element. Otherwise it returns false.
|
||||
func contains(element uint64, slice []uint64) bool {
|
||||
for _, s := range slice {
|
||||
if s == element {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user