version 3.3.0

gos_tech_4.4.3 v3.3.0
KasimBaybikov 2 years ago
parent 0adf28daf6
commit be86069155

@ -1,10 +1,33 @@
### Version 3.2.2
### Version 3.3.0
### Bug fixes
- Fix bug with getting kvmvm data_source
- Fix bug with getting k8s_wg from import
- Fix bug with getting k8s from import
### Features
- Add enable/disable functionality for kvmvm resource
- Add status checker for kvmvm resource
- Add data_source k8s
- Add data_source k8s_list
- Add data_source k8s_list_deleted
- Add data_source k8s_wg_list
- Add data_source k8s_wg
- Add a vins_id to the k8s schema/state
- Add a ips from computes to the k8s group workers in schema/state
- Add a ips from computes to the k8s masters in schema/state
- Add a ips from computes to the k8s_wg in schema/state
- Change data_source vins, the schema/state is aligned with the platform
- Add data_source vins_audits
- Add data_source vins_ext_net_list
- Add data_source vins_ip_list
- Change data_source vins_list, the schema/state is aligned with the platform
- Add data_source vins_list_deleted
- Add data_source vins_nat_rule_list
- Add status checker for vins resource
- Add the ability to create and update ip reservations
- Add the ability to create and update nat_rule reservations
- Add enable/disable functionality for vins resource
- Add the ability to restart vnfDev
- Add the ability to redeploy vnfDev
- Add the ability to import vins
- Add warnings handling, which does not interrupt the work when the state is successfully created

@ -2,7 +2,7 @@ FROM docker.io/hashicorp/terraform:latest
WORKDIR /opt/decort/tf/
COPY provider.tf ./
COPY terraform-provider-decort ./terraform.d/plugins/digitalenergy.online/decort/decort/3.2.2/linux_amd64/
COPY terraform-provider-decort ./terraform.d/plugins/digitalenergy.online/decort/decort/3.3.0/linux_amd64/
RUN terraform init
WORKDIR /tf

@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

@ -0,0 +1,52 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://github.com/rudecs/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
*/
package dc
import "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
type Warnings struct {
diagnostics diag.Diagnostics
}
func (w *Warnings) Add(err error) {
if w.diagnostics == nil {
w.diagnostics = diag.Diagnostics{}
}
diagFromErr := diag.FromErr(err)
diagFromErr[0].Severity = diag.Warning
w.diagnostics = append(w.diagnostics, diagFromErr[0])
}
func (w Warnings) Get() diag.Diagnostics {
return w.diagnostics
}

@ -46,6 +46,12 @@ func NewDataSourcesMap() map[string]*schema.Resource {
"decort_k8s_wg": k8s.DataSourceK8sWg(),
"decort_k8s_wg_list": k8s.DataSourceK8sWgList(),
"decort_vins": vins.DataSourceVins(),
"decort_vins_list": vins.DataSourceVinsList(),
"decort_vins_audits": vins.DataSourceVinsAudits(),
"decort_vins_ip_list": vins.DataSourceVinsIpList(),
"decort_vins_list_deleted": vins.DataSourceVinsListDeleted(),
"decort_vins_ext_net_list": vins.DataSourceVinsExtNetList(),
"decort_vins_nat_rule_list": vins.DataSourceVinsNatRuleList(),
"decort_snapshot_list": snapshot.DataSourceSnapshotList(),
"decort_disk": disks.DataSourceDisk(),
"decort_disk_list": disks.DataSourceDiskList(),
@ -77,7 +83,6 @@ func NewDataSourcesMap() map[string]*schema.Resource {
"decort_extnet_computes_list": extnet.DataSourceExtnetComputesList(),
"decort_extnet": extnet.DataSourceExtnet(),
"decort_extnet_default": extnet.DataSourceExtnetDefault(),
"decort_vins_list": vins.DataSourceVinsList(),
"decort_locations_list": locations.DataSourceLocationsList(),
"decort_location_url": locations.DataSourceLocationUrl(),
"decort_image_list": image.DataSourceImageList(),

@ -173,3 +173,8 @@ type Unattached struct {
}
type UnattachedList []Unattached
type Pair struct {
intPort int
extPortStart int
}

@ -42,6 +42,7 @@ import (
"github.com/rudecs/terraform-provider-decort/internal/constants"
"github.com/rudecs/terraform-provider-decort/internal/controller"
"github.com/rudecs/terraform-provider-decort/internal/dc"
"github.com/rudecs/terraform-provider-decort/internal/status"
log "github.com/sirupsen/logrus"
@ -123,6 +124,7 @@ func resourceDiskCreate(ctx context.Context, d *schema.ResourceData, m interface
func resourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
urlValues := &url.Values{}
c := m.(*controller.ControllerCfg)
warnings := dc.Warnings{}
disk, err := utilityDiskCheckPresence(ctx, d, m)
if disk == nil {
@ -133,17 +135,21 @@ func resourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}
return nil
}
hasChangeState := false
if disk.Status == status.Destroyed || disk.Status == status.Purged {
d.Set("disk_id", 0)
return resourceDiskCreate(ctx, d, m)
} else if disk.Status == status.Deleted {
hasChangeState = true
urlValues.Add("diskId", d.Id())
urlValues.Add("reason", d.Get("reason").(string))
_, err := c.DecortAPICall(ctx, "POST", disksRestoreAPI, urlValues)
if err != nil {
return diag.FromErr(err)
warnings.Add(err)
}
}
if hasChangeState {
urlValues = &url.Values{}
disk, err = utilityDiskCheckPresence(ctx, d, m)
if disk == nil {
@ -202,7 +208,7 @@ func resourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}
d.Set("type", disk.Type)
d.Set("vmid", disk.VMID)
return nil
return warnings.Get()
}
func resourceDiskUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
@ -215,18 +221,6 @@ func resourceDiskUpdate(ctx context.Context, d *schema.ResourceData, m interface
}
return nil
}
if disk.Status == status.Destroyed || disk.Status == status.Purged {
return resourceDiskCreate(ctx, d, m)
} else if disk.Status == status.Deleted {
urlValues.Add("diskId", d.Id())
urlValues.Add("reason", d.Get("reason").(string))
_, err := c.DecortAPICall(ctx, "POST", disksRestoreAPI, urlValues)
if err != nil {
return diag.FromErr(err)
}
urlValues = &url.Values{}
}
if d.HasChange("size_max") {
oldSize, newSize := d.GetChange("size_max")

@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

@ -1,3 +1,35 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://github.com/rudecs/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
*/
package k8s
import (

@ -1,3 +1,35 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://github.com/rudecs/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
*/
package k8s
import (

@ -1,3 +1,35 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://github.com/rudecs/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
*/
package k8s
import (

@ -1,3 +1,35 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://github.com/rudecs/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
*/
package k8s
import (
@ -11,19 +43,6 @@ import (
log "github.com/sirupsen/logrus"
)
func flattenWgData(d *schema.ResourceData, wg K8SGroup, computes []kvmvm.ComputeGetResp) {
d.Set("annotations", wg.Annotations)
d.Set("cpu", wg.CPU)
d.Set("detailed_info", flattenDetailedInfo(wg.DetailedInfo, computes))
d.Set("disk", wg.Disk)
d.Set("guid", wg.GUID)
d.Set("labels", wg.Labels)
d.Set("name", wg.Name)
d.Set("num", wg.Num)
d.Set("ram", wg.RAM)
d.Set("taints", wg.Taints)
}
func dataSourceK8sWgRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("dataSourceK8sWgRead: called with k8s id %d", d.Get("k8s_id").(int))

@ -1,3 +1,35 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://github.com/rudecs/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
*/
package k8s
import (
@ -13,33 +45,6 @@ import (
"github.com/rudecs/terraform-provider-decort/internal/service/cloudapi/kvmvm"
)
func flattenWgList(wgList K8SGroupList, computesMap map[uint64][]kvmvm.ComputeGetResp) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, wg := range wgList {
computes := computesMap[wg.ID]
temp := map[string]interface{}{
"annotations": wg.Annotations,
"cpu": wg.CPU,
"wg_id": wg.ID,
"detailed_info": flattenDetailedInfo(wg.DetailedInfo, computes),
"disk": wg.Disk,
"guid": wg.GUID,
"labels": wg.Labels,
"name": wg.Name,
"num": wg.Num,
"ram": wg.RAM,
"taints": wg.Taints,
}
res = append(res, temp)
}
return res
}
func flattenItemsWg(d *schema.ResourceData, wgList K8SGroupList, computes map[uint64][]kvmvm.ComputeGetResp) {
d.Set("items", flattenWgList(wgList, computes))
}
func utilityK8sWgListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (K8SGroupList, error) {
c := m.(*controller.ControllerCfg)

@ -1,3 +1,35 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://github.com/rudecs/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
*/
package k8s
import (
@ -245,3 +277,43 @@ func flattenResourceK8s(d *schema.ResourceData, k8s K8SRecord, masters []kvmvm.C
d.Set("updated_time", k8s.UpdatedTime)
d.Set("default_wg_id", k8s.K8SGroups.Workers[0].ID)
}
func flattenWgData(d *schema.ResourceData, wg K8SGroup, computes []kvmvm.ComputeGetResp) {
d.Set("annotations", wg.Annotations)
d.Set("cpu", wg.CPU)
d.Set("detailed_info", flattenDetailedInfo(wg.DetailedInfo, computes))
d.Set("disk", wg.Disk)
d.Set("guid", wg.GUID)
d.Set("labels", wg.Labels)
d.Set("name", wg.Name)
d.Set("num", wg.Num)
d.Set("ram", wg.RAM)
d.Set("taints", wg.Taints)
}
func flattenWgList(wgList K8SGroupList, computesMap map[uint64][]kvmvm.ComputeGetResp) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, wg := range wgList {
computes := computesMap[wg.ID]
temp := map[string]interface{}{
"annotations": wg.Annotations,
"cpu": wg.CPU,
"wg_id": wg.ID,
"detailed_info": flattenDetailedInfo(wg.DetailedInfo, computes),
"disk": wg.Disk,
"guid": wg.GUID,
"labels": wg.Labels,
"name": wg.Name,
"num": wg.Num,
"ram": wg.RAM,
"taints": wg.Taints,
}
res = append(res, temp)
}
return res
}
func flattenItemsWg(d *schema.ResourceData, wgList K8SGroupList, computes map[uint64][]kvmvm.ComputeGetResp) {
d.Set("items", flattenWgList(wgList, computes))
}

@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

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

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

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

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

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

@ -41,32 +41,6 @@ import (
"github.com/rudecs/terraform-provider-decort/internal/constants"
)
func flattenVinsList(vl VinsList) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, v := range vl {
temp := map[string]interface{}{
"account_id": v.AccountId,
"account_name": v.AccountName,
"created_by": v.CreatedBy,
"created_time": v.CreatedTime,
"deleted_by": v.DeletedBy,
"deleted_time": v.DeletedTime,
"external_ip": v.ExternalIP,
"vins_id": v.ID,
"vins_name": v.Name,
"network": v.Network,
"rg_id": v.RGID,
"rg_name": v.RGName,
"status": v.Status,
"updated_by": v.UpdatedBy,
"updated_time": v.UpdatedTime,
"vxlan_id": v.VXLanID,
}
res = append(res, temp)
}
return res
}
func dataSourceVinsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
vinsList, err := utilityVinsListCheckPresence(ctx, d, m)
if err != nil {

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

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

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

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

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

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

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

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

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

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

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

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

@ -1,3 +1,35 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://github.com/rudecs/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
*/
package status
type Status = string
@ -12,22 +44,26 @@ var (
// Status available for:
// - Compute
// - Disk
// - Vins
Enabled Status = "ENABLED"
// Enabling in process
// Status available for:
// - Disk
// - Vins
Enabling Status = "ENABLING"
// An object disabled for operations
// Status available for:
// - Compute
// - Disk
// - Vins
Disabled Status = "DISABLED"
// Disabling in process
// Status available for:
// - Disk
// - Vins
Disabling Status = "DISABLING"
// An object model has been created in the database
@ -35,6 +71,7 @@ var (
// - Image
// - Disk
// - Compute
// - Vins
Modeled Status = "MODELED"
// In the process of creation
@ -47,6 +84,7 @@ var (
// - Image
// - Disk
// - Compute
// - Vins
Created Status = "CREATED"
// Physical resources are allocated for the object
@ -63,6 +101,7 @@ var (
// Status available for:
// - Disk
// - Compute
// - Vins
Destroying Status = "DESTROYING"
// Permanently deleted
@ -70,16 +109,19 @@ var (
// - Image
// - Disk
// - Compute
// - Vins
Destroyed Status = "DESTROYED"
// Deleting in progress to Trash
// Status available for:
// - Compute
// - Vins
Deleting Status = "DELETING"
// Deleted to Trash
// Status available for:
// - Compute
// - Vins
Deleted Status = "DELETED"
// Deleted from storage
@ -91,4 +133,9 @@ var (
// Status available for:
// - Compute
Redeploying Status = "REDEPLOYING"
// The resource is not bound to vnf device
// Status available for:
// - vins vnf
Stashed Status = "STASHED"
)

@ -1,3 +1,35 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://github.com/rudecs/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
*/
package techstatus
type TechStatus = string

@ -2,7 +2,7 @@ terraform {
required_providers {
decort = {
source = "digitalenergy.online/decort/decort"
version = "3.2.2"
version = "3.3.0"
}
}
}

@ -0,0 +1,37 @@
/*
Пример использования
Получение информации о k8s кластере
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_k8s" "k8s" {
#id кластера
#обязательный параметр
#тип - число
k8s_id = 49304
}
output "output_k8s" {
value = data.decort_k8s.k8s
}

@ -0,0 +1,50 @@
/*
Пример использования
Получение списка доступных кластеров
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_k8s_list" "k8s_list" {
#включение удаленных k8s в результат
#опциональный параметр
#тип - будев тип
#если не задан - выводятся все неудаленные данные
include_deleted = true
#номер страницы для отображения
#опциональный параметр
#тип - число
#если не задан - выводятся все доступные данные
page = 1
#размер страницы
#опциональный параметр
#тип - число
#если не задан - выводятся все доступные данные
size = 1
}
output "output_k8s_list" {
value = data.decort_k8s_list.k8s_list
}

@ -0,0 +1,45 @@
/*
Пример использования
Получение списка доступных кластеров включая удаленные
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_k8s_list_deleted" "k8s_list_deleted" {
#номер страницы для отображения
#опциональный параметр
#тип - число
#если не задан - выводятся все доступные данные
page = 1
#размер страницы
#опциональный параметр
#тип - число
#если не задан - выводятся все доступные данные
size = 1
}
output "output_k8s_list_deleted" {
value = data.decort_k8s_list_deleted.k8s_list_deleted
}

@ -0,0 +1,42 @@
/*
Пример использования
Получение информации о k8s кластере
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_k8s_wf" "k8s_wg" {
#id кластера
#обязательный параметр
#тип - число
k8s_id = 49304
#id группы воркеров
#обязательный параметр
#тип - число
wg_id = 43329
}
output "output_k8s_wg" {
value = data.decort_k8s.k8s
}

@ -0,0 +1,37 @@
/*
Пример использования
Получение списка доступных групп воркеров в кластере
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_k8s_wg_list" "k8s_wg_list" {
#id кластера
#обязательный параметр
#тип - число
k8s_id = 49304
}
output "output_k8s_wg_list" {
value = data.decort_k8s_wg_list.k8s_wg_list
}

@ -0,0 +1,38 @@
/*
Пример использования
Получение данных о vins
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_vins" "vins" {
#обязательный параметр
#id жедаемого vins
#тип - число
vins_id = 10101
}
output "test" {
value = data.decort_vins.vins
}

@ -0,0 +1,38 @@
/*
Пример использования
Получение списка vins audits
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_vins_audits" "vins_audits" {
#обязательный параметр
#id жедаемого vins
#тип - число
vins_id = 10101
}
output "test" {
value = data.decort_vins_audits.vins_audits
}

@ -0,0 +1,38 @@
/*
Пример использования
Получение списка vins extnet
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_vins_ext_net_list" "vins_ext_net_list" {
#обязательный параметр
#id жедаемого vins
#тип - число
vins_id = 10101
}
output "test" {
value = data.decort_vins_ext_net_list.vins_ext_net_list
}

@ -0,0 +1,39 @@
/*
Пример использования
Получение списка vins_ip
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_vins_ip_list" "vins_ip_list" {
#обязательный параметр
#id жедаемого vins
#тип - число
vins_id = 10101
}
output "test" {
value = data.decort_vins_ip_list.vins_ip_list
}

@ -0,0 +1,42 @@
/*
Пример использования
Получение списка удаленных vins
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_vins_list_deleted" "vinslist_deleted" {
#кол-во страниц для вывода
#опицональный параметр
#тип - число
page = 1
#размер страницы
#опицональный параметр
#тип - число
size = 1
}
output "test" {
value = data.decort_vins_list_deleted.vinslist_deleted
}

@ -0,0 +1,39 @@
/*
Пример использования
Получение списка natRule vins
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_vins_nat_rule_list" "vins_nat_rule_list" {
#обязательный параметр
#id жедаемого vins
#тип - число
vins_id = 10101
}
output "test" {
value = data.decort_vins_nat_rule_list.vins_nat_rule_list
}

@ -0,0 +1,170 @@
/*
Пример использования
Ресурса vins
Ресурс позволяет:
1. Создавать vins
2. Удалять vins
3. Восстанвливать vins
4. Добавлять и убирать подключение к внешней сети
5. Резервировать и освобождать ip для vins
6. Добавлять и удалять natrule
7. Перезапускать и редеплоить vnfdev
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://mr4.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
resource "decort_vins" "vins" {
#обязательный параметр
#имя создаваемого ресурса
#тип - строка
name = "Test_name"
#опциональный параметр
#id ресурсной группы для создаения ресруса
#тип - число
rg_id = 10101
#опциональный параметр
#id аккаунта для создаения ресруса
#тип - число
account_id = 2023
#опциональный параметр
#id внешней сети для подключения к ней ресруса
#тип - число
ext_net_id = 2222
#опциональный параметр
#ip внешней сети для подключения к нему ресруса
#тип - строка
ext_ip_addr = "1.1.1.1"
#опциональный параметр
#private network IP CIDR
#тип - строка
ipcidr = "192.168.0.1"
#опциональный параметр
#количество зарезервированных адресов на момент создания
#тип - число
#значение по умолчанию 32
pre_reservations_num = 2
#опциональный параметр
#grid (platform) ID
#тип - число
gid = 2002
#опциональный параметр
#Description
#тип - строка
desc = "Description"
#опциональный параметр
#ручное подключение и отключение ресурса
#тип - булев тип
enable = true
#опциональный параметр
#удаление навсегда
#тип - булев тип
permanently = true
#опциональный параметр
#удаляет за собой все зависимые ресурсы
#тип - булев тип
force = true
#опциональный параметр
#блок для резервирования ip
#тип - блок
ip {
#обязательный параметр
#тип подключения
#тип - строка
type = "DHCP"
#опциональный параметр
#ip который необходимо зарезервировать
#тип - строка
ip_addr = "192.168.5.5"
#опциональный параметр
#mac который необходимо зарезервировать
#тип - строка
mac_addr = "ff:ff:ff:ff:ff:ff"
}
#опциональный параметр
#блок для добавления natRule
#тип - блок
nat_rule {
#опциональный параметр
#ip внутренний
#тип - строка
int_ip = "192.168.0.28"
#опциональный параметр
#внутренний порт
#тип - число
int_port = 80
#опциональный параметр
#начало диапазона внешних портов
#тип - число
ext_port_start = 8001
#опциональный параметр
#конец диапазона внешних портов
#тип - число
ext_port_end = 8001
#опциональный параметр
#протокол natRule
#тип - строка
proto = "tcp"
}
#опциональный параметр
#восстановление ресурса
#тип - булев тип
restore = true
#опциональный параметр
#перезапуск vnfDev
##тип - булев тип
vnfdev_restart = true
#опциональный параметр
#редеплой vnfDev
#тип - булев тип
vnfdev_redeploy = true
}
output "test" {
value = decort_vins.vins
}
Loading…
Cancel
Save