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 ### 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 ### Features
- Add enable/disable functionality for kvmvm resource - Add data_source k8s
- Add status checker for kvmvm resource - 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/ WORKDIR /opt/decort/tf/
COPY provider.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 RUN terraform init
WORKDIR /tf WORKDIR /tf

@ -52,4 +52,4 @@ test:
echo $(TEST) | xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4 echo $(TEST) | xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4
testacc: testacc:
TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout 120m TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout 120m

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

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

@ -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": k8s.DataSourceK8sWg(),
"decort_k8s_wg_list": k8s.DataSourceK8sWgList(), "decort_k8s_wg_list": k8s.DataSourceK8sWgList(),
"decort_vins": vins.DataSourceVins(), "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_snapshot_list": snapshot.DataSourceSnapshotList(),
"decort_disk": disks.DataSourceDisk(), "decort_disk": disks.DataSourceDisk(),
"decort_disk_list": disks.DataSourceDiskList(), "decort_disk_list": disks.DataSourceDiskList(),
@ -77,7 +83,6 @@ func NewDataSourcesMap() map[string]*schema.Resource {
"decort_extnet_computes_list": extnet.DataSourceExtnetComputesList(), "decort_extnet_computes_list": extnet.DataSourceExtnetComputesList(),
"decort_extnet": extnet.DataSourceExtnet(), "decort_extnet": extnet.DataSourceExtnet(),
"decort_extnet_default": extnet.DataSourceExtnetDefault(), "decort_extnet_default": extnet.DataSourceExtnetDefault(),
"decort_vins_list": vins.DataSourceVinsList(),
"decort_locations_list": locations.DataSourceLocationsList(), "decort_locations_list": locations.DataSourceLocationsList(),
"decort_location_url": locations.DataSourceLocationUrl(), "decort_location_url": locations.DataSourceLocationUrl(),
"decort_image_list": image.DataSourceImageList(), "decort_image_list": image.DataSourceImageList(),

@ -173,3 +173,8 @@ type Unattached struct {
} }
type UnattachedList []Unattached 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/constants"
"github.com/rudecs/terraform-provider-decort/internal/controller" "github.com/rudecs/terraform-provider-decort/internal/controller"
"github.com/rudecs/terraform-provider-decort/internal/dc"
"github.com/rudecs/terraform-provider-decort/internal/status" "github.com/rudecs/terraform-provider-decort/internal/status"
log "github.com/sirupsen/logrus" 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 { func resourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
urlValues := &url.Values{} urlValues := &url.Values{}
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
warnings := dc.Warnings{}
disk, err := utilityDiskCheckPresence(ctx, d, m) disk, err := utilityDiskCheckPresence(ctx, d, m)
if disk == nil { if disk == nil {
@ -133,17 +135,21 @@ func resourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}
return nil return nil
} }
hasChangeState := false
if disk.Status == status.Destroyed || disk.Status == status.Purged { if disk.Status == status.Destroyed || disk.Status == status.Purged {
d.Set("disk_id", 0) d.Set("disk_id", 0)
return resourceDiskCreate(ctx, d, m) return resourceDiskCreate(ctx, d, m)
} else if disk.Status == status.Deleted { } else if disk.Status == status.Deleted {
hasChangeState = true
urlValues.Add("diskId", d.Id()) urlValues.Add("diskId", d.Id())
urlValues.Add("reason", d.Get("reason").(string)) urlValues.Add("reason", d.Get("reason").(string))
_, err := c.DecortAPICall(ctx, "POST", disksRestoreAPI, urlValues) _, err := c.DecortAPICall(ctx, "POST", disksRestoreAPI, urlValues)
if err != nil { if err != nil {
return diag.FromErr(err) warnings.Add(err)
} }
}
if hasChangeState {
urlValues = &url.Values{} urlValues = &url.Values{}
disk, err = utilityDiskCheckPresence(ctx, d, m) disk, err = utilityDiskCheckPresence(ctx, d, m)
if disk == nil { if disk == nil {
@ -202,7 +208,7 @@ func resourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}
d.Set("type", disk.Type) d.Set("type", disk.Type)
d.Set("vmid", disk.VMID) d.Set("vmid", disk.VMID)
return nil return warnings.Get()
} }
func resourceDiskUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { 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 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") { if d.HasChange("size_max") {
oldSize, newSize := d.GetChange("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: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -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 package k8s
import ( 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 package k8s
import ( 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 package k8s
import ( 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 package k8s
import ( import (
@ -11,19 +43,6 @@ import (
log "github.com/sirupsen/logrus" 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 { 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)) 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 package k8s
import ( import (
@ -13,33 +45,6 @@ import (
"github.com/rudecs/terraform-provider-decort/internal/service/cloudapi/kvmvm" "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) { func utilityK8sWgListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (K8SGroupList, error) {
c := m.(*controller.ControllerCfg) 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 package k8s
import ( import (
@ -245,3 +277,43 @@ func flattenResourceK8s(d *schema.ResourceData, k8s K8SRecord, masters []kvmvm.C
d.Set("updated_time", k8s.UpdatedTime) d.Set("updated_time", k8s.UpdatedTime)
d.Set("default_wg_id", k8s.K8SGroups.Workers[0].ID) 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: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

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

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

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

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

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

@ -32,14 +32,27 @@ Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
package vins package vins
const VinsListAPI = "/restmachine/cloudapi/vins/list" const (
const VinsGetAPI = "/restmachine/cloudapi/vins/get" VinsAuditsAPI = "/restmachine/cloudapi/vins/audits"
const VinsSearchAPI = "/restmachine/cloudapi/vins/search" VinsCreateInAccountAPI = "/restmachine/cloudapi/vins/createInAccount"
VinsCreateInRgAPI = "/restmachine/cloudapi/vins/createInRG"
const VinsCreateInAccountAPI = "/restmachine/cloudapi/vins/createInAccount" VinsDeleteAPI = "/restmachine/cloudapi/vins/delete"
const VinsCreateInRgAPI = "/restmachine/cloudapi/vins/createInRG" VinsDisableAPI = "/restmachine/cloudapi/vins/disable"
VinsEnableAPI = "/restmachine/cloudapi/vins/enable"
const VinsExtNetConnectAPI = "/restmachine/cloudapi/vins/extNetConnect" VinsExtNetConnectAPI = "/restmachine/cloudapi/vins/extNetConnect"
const VinsExtNetDisconnectAPI = "/restmachine/cloudapi/vins/extNetDisconnect" VinsExtNetDisconnectAPI = "/restmachine/cloudapi/vins/extNetDisconnect"
VinsExtNetListAPI = "/restmachine/cloudapi/vins/extNetList"
const VinsDeleteAPI = "/restmachine/cloudapi/vins/delete" 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: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -33,149 +34,876 @@ package vins
import ( import (
"context" "context"
"encoding/json" "strconv"
"fmt"
"github.com/rudecs/terraform-provider-decort/internal/constants"
log "github.com/sirupsen/logrus"
// "net/url"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/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 dataSourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
func flattenVins(d *schema.ResourceData, vins_facts string) diag.Diagnostics { vins, err := utilityDataVinsCheckPresence(ctx, d, m)
// 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)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
log.Debugf("flattenVins: decoded ViNS name:ID %s:%d, account ID %d, RG ID %d", d.SetId(strconv.FormatUint(vins.ID, 10))
vinsRecord.Name, vinsRecord.ID, vinsRecord.AccountID, vinsRecord.RgID) flattenVinsData(d, *vins)
return nil
}
d.SetId(fmt.Sprintf("%d", vinsRecord.ID)) func vnfConfigMGMTSchemaMake() map[string]*schema.Schema {
d.Set("name", vinsRecord.Name) return map[string]*schema.Schema{
d.Set("account_id", vinsRecord.AccountID) "ip_addr": {
d.Set("account_name", vinsRecord.AccountName) Type: schema.TypeString,
d.Set("rg_id", vinsRecord.RgID) Computed: true,
d.Set("description", vinsRecord.Desc) },
d.Set("ipcidr", vinsRecord.IPCidr) "password": {
Type: schema.TypeString,
Computed: true,
},
"ssh_key": {
Type: schema.TypeString,
Computed: true,
},
"user": {
Type: schema.TypeString,
Computed: true,
},
}
}
noExtNetConnection := true func vnfConfigResourcesSchemaMake() map[string]*schema.Schema {
for _, value := range vinsRecord.VNFs { return map[string]*schema.Schema{
if value.Type == "GW" { "cpu": {
log.Debugf("flattenVins: discovered GW VNF ID %d in ViNS ID %d", value.ID, vinsRecord.ID) Type: schema.TypeInt,
extNetID, idOk := value.Config["ext_net_id"] // NOTE: unknown numbers are unmarshalled to float64. This is by design! Computed: true,
extNetIP, ipOk := value.Config["ext_net_ip"] },
if idOk && ipOk { "ram": {
log.Debugf("flattenVins: ViNS ext_net_id=%d, ext_net_ip=%s", int(extNetID.(float64)), extNetIP.(string)) Type: schema.TypeInt,
d.Set("ext_ip_addr", extNetIP.(string)) Computed: true,
d.Set("ext_net_id", int(extNetID.(float64))) },
} else { "stack_id": {
return diag.Errorf("Failed to unmarshal VNF GW Config - structure is invalid.") Type: schema.TypeInt,
} Computed: true,
noExtNetConnection = false },
break "uuid": {
} Type: schema.TypeString,
Computed: true,
},
} }
}
if noExtNetConnection { func qosSchemaMake() map[string]*schema.Schema {
d.Set("ext_ip_addr", "") return map[string]*schema.Schema{
d.Set("ext_net_id", 0) "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,
},
} }
}
log.Debugf("flattenVins: EXTRA CHECK - schema rg_id=%d, ext_net_id=%d", d.Get("rg_id").(int), d.Get("ext_net_id").(int)) func vnfInterfaceSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"conn_id": {
Type: schema.TypeInt,
Computed: true,
},
"conn_type": {
Type: schema.TypeString,
Computed: true,
},
"def_gw": {
Type: schema.TypeString,
Computed: true,
},
"flipgroup_id": {
Type: schema.TypeInt,
Computed: true,
},
"guid": {
Type: schema.TypeString,
Computed: true,
},
"ip_address": {
Type: schema.TypeString,
Computed: true,
},
"listen_ssh": {
Type: schema.TypeBool,
Computed: true,
},
"mac": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"net_id": {
Type: schema.TypeInt,
Computed: true,
},
"net_mask": {
Type: schema.TypeInt,
Computed: true,
},
"net_type": {
Type: schema.TypeString,
Computed: true,
},
"pci_slot": {
Type: schema.TypeInt,
Computed: true,
},
"qos": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: qosSchemaMake(),
},
},
"target": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
"vnfs": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
}
}
return nil 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 dataSourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func vnfDevSchemaMake() map[string]*schema.Schema {
vinsFacts, err := utilityVinsCheckPresence(ctx, d, m) return map[string]*schema.Schema{
if vinsFacts == "" { "_ckey": {
// if empty string is returned from utilityVinsCheckPresence then there is no Type: schema.TypeString,
// such ViNS and err tells so - just return it to the calling party Computed: true,
d.SetId("") // ensure ID is empty in this case },
return diag.FromErr(err) "account_id": {
Type: schema.TypeInt,
Computed: true,
Description: "Unique ID of the account, which this ViNS belongs to.",
},
"capabilities": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"config": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: vnfConfigSchemaMake(),
},
},
"config_saved": {
Type: schema.TypeBool,
Computed: true,
},
"custom_pre_cfg": {
Type: schema.TypeBool,
Computed: true,
},
"desc": {
Type: schema.TypeString,
Computed: true,
},
"gid": {
Type: schema.TypeInt,
Computed: true,
},
"guid": {
Type: schema.TypeInt,
Computed: true,
},
"vnf_id": {
Type: schema.TypeInt,
Computed: true,
},
"interfaces": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: vnfInterfaceSchemaMake(),
},
},
"lock_status": {
Type: schema.TypeString,
Computed: true,
},
"milestones": {
Type: schema.TypeInt,
Computed: true,
},
"vnf_name": {
Type: schema.TypeString,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"tech_status": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
"vins": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
} }
}
return flattenVins(d, vinsFacts) func vinsComputeSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"compute_id": {
Type: schema.TypeInt,
Computed: true,
},
"compute_name": {
Type: schema.TypeString,
Computed: true,
},
}
} }
func DataSourceVins() *schema.Resource { func reservationSchemaMake() map[string]*schema.Schema {
return &schema.Resource{ return map[string]*schema.Schema{
SchemaVersion: 1, "client_type": {
Type: schema.TypeString,
Computed: true,
},
"desc": {
Type: schema.TypeString,
Computed: true,
},
"domainname": {
Type: schema.TypeString,
Computed: true,
},
"hostname": {
Type: schema.TypeString,
Computed: true,
},
"ip": {
Type: schema.TypeString,
Computed: true,
},
"mac": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
"vm_id": {
Type: schema.TypeInt,
Computed: true,
},
}
}
ReadContext: dataSourceVinsRead, func dhcpConfigSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"default_gw": {
Type: schema.TypeString,
Computed: true,
},
"dns": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"ip_end": {
Type: schema.TypeString,
Computed: true,
},
"ip_start": {
Type: schema.TypeString,
Computed: true,
},
"lease": {
Type: schema.TypeInt,
Computed: true,
},
"netmask": {
Type: schema.TypeInt,
Computed: true,
},
"network": {
Type: schema.TypeString,
Computed: true,
},
"reservations": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: reservationSchemaMake(),
},
},
}
}
Timeouts: &schema.ResourceTimeout{ func devicesPrimarySchemaMake() map[string]*schema.Schema {
Read: &constants.Timeout30s, return map[string]*schema.Schema{
Default: &constants.Timeout60s, "dev_id": {
Type: schema.TypeInt,
Computed: true,
},
"iface01": {
Type: schema.TypeString,
Computed: true,
}, },
"iface02": {
Type: schema.TypeString,
Computed: true,
},
}
}
Schema: map[string]*schema.Schema{ func devicesSchemaMake() map[string]*schema.Schema {
"name": { return map[string]*schema.Schema{
Type: schema.TypeString, "primary": {
Required: true, Type: schema.TypeList,
Description: "Name of the ViNS. Names are case sensitive and unique within the context of an account or resource group.", Computed: true,
Elem: &schema.Resource{
Schema: devicesPrimarySchemaMake(),
}, },
},
}
}
/* func dhcpSchemaMake() map[string]*schema.Schema {
"vins_id": { return map[string]*schema.Schema{
Type: schema.TypeInt, "_ckey": {
Optional: true, Type: schema.TypeString,
Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.", Computed: true,
}, },
*/ "account_id": {
Type: schema.TypeInt,
"rg_id": { Computed: true,
Type: schema.TypeInt, },
Optional: true, "config": {
Description: "Unique ID of the resource group, where this ViNS is belongs to (for ViNS created at resource group level, 0 otherwise).", 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,
},
}
}
"account_id": { func gwConfigSchemaMake() map[string]*schema.Schema {
Type: schema.TypeInt, return map[string]*schema.Schema{
Optional: true, "default_gw": {
Description: "Unique ID of the account, which this ViNS belongs to.", 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(),
}, },
},
}
}
// the rest of attributes are computed func gwSchemaMake() map[string]*schema.Schema {
"account_name": { return map[string]*schema.Schema{
Type: schema.TypeString, "_ckey": {
Computed: true, Type: schema.TypeString,
Description: "Name of the account, which this ViNS belongs to.", 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,
},
}
}
"description": { func rulesSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString, return map[string]*schema.Schema{
Computed: true, "rule_id": {
Description: "User-defined text description of this ViNS.", 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(),
}, },
},
}
}
"ext_ip_addr": { func natSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString, return map[string]*schema.Schema{
Computed: true, "_ckey": {
Description: "IP address of the external connection (valid for ViNS connected to external network, empty string otherwise).", 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,
},
}
}
"ext_net_id": { func vnfsSchemaMake() map[string]*schema.Schema {
Type: schema.TypeInt, return map[string]*schema.Schema{
Computed: true, "dhcp": {
Description: "ID of the external network this ViNS is connected to (-1 means no external connection).", 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.",
},
"ipcidr": { "vnf_dev": {
Type: schema.TypeString, Type: schema.TypeList,
Computed: true, Computed: true,
Description: "Network address used by this ViNS.", 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(),
}
}

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

@ -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
}

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

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

@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -34,120 +35,48 @@ package vins
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"fmt"
"net/url" "net/url"
"strconv" "strconv"
"github.com/rudecs/terraform-provider-decort/internal/controller" "github.com/rudecs/terraform-provider-decort/internal/controller"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "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 func utilityDataVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*VINSDetailed, error) {
// 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.
//
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
urlValues := &url.Values{} urlValues := &url.Values{}
vins := &VINSDetailed{}
// make it possible to use "read" & "check presence" functions with ViNS ID set so urlValues.Add("vinsId", strconv.Itoa(d.Get("vins_id").(int)))
// that Import of ViNS resource is possible vinsRaw, err := c.DecortAPICall(ctx, "POST", VinsGetAPI, urlValues)
idSet := false if err != nil {
theId, err := strconv.Atoi(d.Id()) return nil, err
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 { err = json.Unmarshal([]byte(vinsRaw), vins)
// ViNS ID is specified, try to get compute instance straight by this ID if err != nil {
log.Debugf("utilityVinsCheckPresence: locating ViNS by its ID %d", theId) return nil, err
urlValues.Add("vinsId", fmt.Sprintf("%d", theId))
vinsFacts, err := c.DecortAPICall(ctx, "POST", VinsGetAPI, urlValues)
if err != nil {
return "", err
}
return vinsFacts, nil
} }
return vins, nil
// ID was not set in the schema upon entering this function - work through ViNS name }
// and Account / RG ID
vinsName, argSet := d.GetOk("name")
if !argSet {
// if ViNS name is not set. then we cannot locate ViNS
return "", fmt.Errorf("Cannot check ViNS presence if ViNS name is empty")
}
urlValues.Add("name", vinsName.(string))
urlValues.Add("show_all", "false")
log.Debugf("utilityVinsCheckPresence: preparing to locate ViNS name %s", vinsName.(string))
rgId, rgSet := d.GetOk("rg_id")
if rgSet {
log.Debugf("utilityVinsCheckPresence: limiting ViNS search to RG ID %d", rgId.(int))
urlValues.Add("rgId", fmt.Sprintf("%d", rgId.(int)))
}
accountId, accountSet := d.GetOk("account_id") func utilityVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*VINSDetailed, error) {
if accountSet { c := m.(*controller.ControllerCfg)
log.Debugf("utilityVinsCheckPresence: limiting ViNS search to Account ID %d", accountId.(int)) urlValues := &url.Values{}
urlValues.Add("accountId", fmt.Sprintf("%d", accountId.(int))) vins := &VINSDetailed{}
}
apiResp, err := c.DecortAPICall(ctx, "POST", VinsSearchAPI, urlValues) urlValues.Add("vinsId", d.Id())
vinsRaw, err := c.DecortAPICall(ctx, "POST", VinsGetAPI, urlValues)
if err != nil { if err != nil {
return "", err return nil, err
} }
// log.Debugf("%s", apiResp) err = json.Unmarshal([]byte(vinsRaw), vins)
// log.Debugf("utilityResgroupCheckPresence: ready to decode response body from %s", VinsSearchAPI)
model := VinsSearchResp{}
err = json.Unmarshal([]byte(apiResp), &model)
if err != nil { 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)
if err != nil {
return "", err
}
return vinsGetResp, nil
}
} }
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: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -43,8 +44,8 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
func utilityVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (VinsList, error) { func utilityVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (VINSList, error) {
vinsList := VinsList{} vinsList := VINSList{}
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
urlValues := &url.Values{} 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 package status
type Status = string type Status = string
@ -12,22 +44,26 @@ var (
// Status available for: // Status available for:
// - Compute // - Compute
// - Disk // - Disk
// - Vins
Enabled Status = "ENABLED" Enabled Status = "ENABLED"
// Enabling in process // Enabling in process
// Status available for: // Status available for:
// - Disk // - Disk
// - Vins
Enabling Status = "ENABLING" Enabling Status = "ENABLING"
// An object disabled for operations // An object disabled for operations
// Status available for: // Status available for:
// - Compute // - Compute
// - Disk // - Disk
// - Vins
Disabled Status = "DISABLED" Disabled Status = "DISABLED"
// Disabling in process // Disabling in process
// Status available for: // Status available for:
// - Disk // - Disk
// - Vins
Disabling Status = "DISABLING" Disabling Status = "DISABLING"
// An object model has been created in the database // An object model has been created in the database
@ -35,6 +71,7 @@ var (
// - Image // - Image
// - Disk // - Disk
// - Compute // - Compute
// - Vins
Modeled Status = "MODELED" Modeled Status = "MODELED"
// In the process of creation // In the process of creation
@ -47,6 +84,7 @@ var (
// - Image // - Image
// - Disk // - Disk
// - Compute // - Compute
// - Vins
Created Status = "CREATED" Created Status = "CREATED"
// Physical resources are allocated for the object // Physical resources are allocated for the object
@ -63,6 +101,7 @@ var (
// Status available for: // Status available for:
// - Disk // - Disk
// - Compute // - Compute
// - Vins
Destroying Status = "DESTROYING" Destroying Status = "DESTROYING"
// Permanently deleted // Permanently deleted
@ -70,16 +109,19 @@ var (
// - Image // - Image
// - Disk // - Disk
// - Compute // - Compute
// - Vins
Destroyed Status = "DESTROYED" Destroyed Status = "DESTROYED"
// Deleting in progress to Trash // Deleting in progress to Trash
// Status available for: // Status available for:
// - Compute // - Compute
// - Vins
Deleting Status = "DELETING" Deleting Status = "DELETING"
// Deleted to Trash // Deleted to Trash
// Status available for: // Status available for:
// - Compute // - Compute
// - Vins
Deleted Status = "DELETED" Deleted Status = "DELETED"
// Deleted from storage // Deleted from storage
@ -91,4 +133,9 @@ var (
// Status available for: // Status available for:
// - Compute // - Compute
Redeploying Status = "REDEPLOYING" 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 package techstatus
type TechStatus = string type TechStatus = string

@ -2,7 +2,7 @@ terraform {
required_providers { required_providers {
decort = { decort = {
source = "digitalenergy.online/decort/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