diff --git a/CHANGELOG.md b/CHANGELOG.md index a307713..85d60d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,33 @@ -### Version 3.2.2 +### Version 3.3.0 ### Bug fixes -- Fix bug with getting kvmvm data_source +- Fix bug with getting k8s_wg from import +- Fix bug with getting k8s from import ### Features -- Add enable/disable functionality for kvmvm resource -- Add status checker for kvmvm resource +- Add data_source k8s +- Add data_source k8s_list +- Add data_source k8s_list_deleted +- Add data_source k8s_wg_list +- Add data_source k8s_wg +- Add a vins_id to the k8s schema/state +- Add a ips from computes to the k8s group workers in schema/state +- Add a ips from computes to the k8s masters in schema/state +- Add a ips from computes to the k8s_wg in schema/state +- Change data_source vins, the schema/state is aligned with the platform +- Add data_source vins_audits +- Add data_source vins_ext_net_list +- Add data_source vins_ip_list +- Change data_source vins_list, the schema/state is aligned with the platform +- Add data_source vins_list_deleted +- Add data_source vins_nat_rule_list +- Add status checker for vins resource +- Add the ability to create and update ip reservations +- Add the ability to create and update nat_rule reservations +- Add enable/disable functionality for vins resource +- Add the ability to restart vnfDev +- Add the ability to redeploy vnfDev +- Add the ability to import vins +- Add warnings handling, which does not interrupt the work when the state is successfully created diff --git a/Dockerfile b/Dockerfile index 13e6cf7..15a8a6b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ FROM docker.io/hashicorp/terraform:latest WORKDIR /opt/decort/tf/ COPY provider.tf ./ -COPY terraform-provider-decort ./terraform.d/plugins/digitalenergy.online/decort/decort/3.2.2/linux_amd64/ +COPY terraform-provider-decort ./terraform.d/plugins/digitalenergy.online/decort/decort/3.3.0/linux_amd64/ RUN terraform init WORKDIR /tf diff --git a/Makefile b/Makefile index 558254b..12d2ac9 100644 --- a/Makefile +++ b/Makefile @@ -52,4 +52,4 @@ test: echo $(TEST) | xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4 testacc: - TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout 120m \ No newline at end of file + TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout 120m diff --git a/internal/constants/constants.go b/internal/constants/constants.go index 436d647..5603a95 100644 --- a/internal/constants/constants.go +++ b/internal/constants/constants.go @@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Authors: Petr Krutov, Stanislav Solovev, +Kasim Baybikov, Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/constants/timeouts.go b/internal/constants/timeouts.go index c7dce44..3b0962f 100644 --- a/internal/constants/timeouts.go +++ b/internal/constants/timeouts.go @@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Authors: Petr Krutov, Stanislav Solovev, +Kasim Baybikov, Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/dc/warnings.go b/internal/dc/warnings.go new file mode 100644 index 0000000..0d0f99a --- /dev/null +++ b/internal/dc/warnings.go @@ -0,0 +1,52 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +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 +} diff --git a/internal/provider/cloudapi/data_sources_map.go b/internal/provider/cloudapi/data_sources_map.go index 8bdd737..c083b6a 100644 --- a/internal/provider/cloudapi/data_sources_map.go +++ b/internal/provider/cloudapi/data_sources_map.go @@ -46,6 +46,12 @@ func NewDataSourcesMap() map[string]*schema.Resource { "decort_k8s_wg": k8s.DataSourceK8sWg(), "decort_k8s_wg_list": k8s.DataSourceK8sWgList(), "decort_vins": vins.DataSourceVins(), + "decort_vins_list": vins.DataSourceVinsList(), + "decort_vins_audits": vins.DataSourceVinsAudits(), + "decort_vins_ip_list": vins.DataSourceVinsIpList(), + "decort_vins_list_deleted": vins.DataSourceVinsListDeleted(), + "decort_vins_ext_net_list": vins.DataSourceVinsExtNetList(), + "decort_vins_nat_rule_list": vins.DataSourceVinsNatRuleList(), "decort_snapshot_list": snapshot.DataSourceSnapshotList(), "decort_disk": disks.DataSourceDisk(), "decort_disk_list": disks.DataSourceDiskList(), @@ -77,7 +83,6 @@ func NewDataSourcesMap() map[string]*schema.Resource { "decort_extnet_computes_list": extnet.DataSourceExtnetComputesList(), "decort_extnet": extnet.DataSourceExtnet(), "decort_extnet_default": extnet.DataSourceExtnetDefault(), - "decort_vins_list": vins.DataSourceVinsList(), "decort_locations_list": locations.DataSourceLocationsList(), "decort_location_url": locations.DataSourceLocationUrl(), "decort_image_list": image.DataSourceImageList(), diff --git a/internal/service/cloudapi/disks/models.go b/internal/service/cloudapi/disks/models.go index 6ae2f09..a8f77ba 100644 --- a/internal/service/cloudapi/disks/models.go +++ b/internal/service/cloudapi/disks/models.go @@ -173,3 +173,8 @@ type Unattached struct { } type UnattachedList []Unattached + +type Pair struct { + intPort int + extPortStart int +} diff --git a/internal/service/cloudapi/disks/resource_disk.go b/internal/service/cloudapi/disks/resource_disk.go index 50d2f20..cf51128 100644 --- a/internal/service/cloudapi/disks/resource_disk.go +++ b/internal/service/cloudapi/disks/resource_disk.go @@ -42,6 +42,7 @@ import ( "github.com/rudecs/terraform-provider-decort/internal/constants" "github.com/rudecs/terraform-provider-decort/internal/controller" + "github.com/rudecs/terraform-provider-decort/internal/dc" "github.com/rudecs/terraform-provider-decort/internal/status" log "github.com/sirupsen/logrus" @@ -123,6 +124,7 @@ func resourceDiskCreate(ctx context.Context, d *schema.ResourceData, m interface func resourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { urlValues := &url.Values{} c := m.(*controller.ControllerCfg) + warnings := dc.Warnings{} disk, err := utilityDiskCheckPresence(ctx, d, m) if disk == nil { @@ -133,17 +135,21 @@ func resourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{} return nil } + hasChangeState := false if disk.Status == status.Destroyed || disk.Status == status.Purged { d.Set("disk_id", 0) return resourceDiskCreate(ctx, d, m) } else if disk.Status == status.Deleted { + hasChangeState = true urlValues.Add("diskId", d.Id()) urlValues.Add("reason", d.Get("reason").(string)) _, err := c.DecortAPICall(ctx, "POST", disksRestoreAPI, urlValues) if err != nil { - return diag.FromErr(err) + warnings.Add(err) } + } + if hasChangeState { urlValues = &url.Values{} disk, err = utilityDiskCheckPresence(ctx, d, m) if disk == nil { @@ -202,7 +208,7 @@ func resourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{} d.Set("type", disk.Type) d.Set("vmid", disk.VMID) - return nil + return warnings.Get() } func resourceDiskUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { @@ -215,18 +221,6 @@ func resourceDiskUpdate(ctx context.Context, d *schema.ResourceData, m interface } return nil } - if disk.Status == status.Destroyed || disk.Status == status.Purged { - return resourceDiskCreate(ctx, d, m) - } else if disk.Status == status.Deleted { - urlValues.Add("diskId", d.Id()) - urlValues.Add("reason", d.Get("reason").(string)) - - _, err := c.DecortAPICall(ctx, "POST", disksRestoreAPI, urlValues) - if err != nil { - return diag.FromErr(err) - } - urlValues = &url.Values{} - } if d.HasChange("size_max") { oldSize, newSize := d.GetChange("size_max") diff --git a/internal/service/cloudapi/k8s/api.go b/internal/service/cloudapi/k8s/api.go index 5cdb7c0..38a7e17 100644 --- a/internal/service/cloudapi/k8s/api.go +++ b/internal/service/cloudapi/k8s/api.go @@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Authors: Petr Krutov, Stanislav Solovev, +Kasim Baybikov, Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/service/cloudapi/k8s/data_source_k8s.go b/internal/service/cloudapi/k8s/data_source_k8s.go index 48bb523..2a0c4fe 100644 --- a/internal/service/cloudapi/k8s/data_source_k8s.go +++ b/internal/service/cloudapi/k8s/data_source_k8s.go @@ -1,3 +1,35 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://github.com/rudecs/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://github.com/rudecs/terraform-provider-decort/wiki +*/ + package k8s import ( diff --git a/internal/service/cloudapi/k8s/data_source_k8s_list.go b/internal/service/cloudapi/k8s/data_source_k8s_list.go index 93a5029..bf95f2c 100644 --- a/internal/service/cloudapi/k8s/data_source_k8s_list.go +++ b/internal/service/cloudapi/k8s/data_source_k8s_list.go @@ -1,3 +1,35 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://github.com/rudecs/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://github.com/rudecs/terraform-provider-decort/wiki +*/ + package k8s import ( diff --git a/internal/service/cloudapi/k8s/data_source_k8s_list_deleted.go b/internal/service/cloudapi/k8s/data_source_k8s_list_deleted.go index 6083319..ce00079 100644 --- a/internal/service/cloudapi/k8s/data_source_k8s_list_deleted.go +++ b/internal/service/cloudapi/k8s/data_source_k8s_list_deleted.go @@ -1,3 +1,35 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://github.com/rudecs/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://github.com/rudecs/terraform-provider-decort/wiki +*/ + package k8s import ( diff --git a/internal/service/cloudapi/k8s/data_source_wg.go b/internal/service/cloudapi/k8s/data_source_k8s_wg.go similarity index 74% rename from internal/service/cloudapi/k8s/data_source_wg.go rename to internal/service/cloudapi/k8s/data_source_k8s_wg.go index ed53e30..5d34a2a 100644 --- a/internal/service/cloudapi/k8s/data_source_wg.go +++ b/internal/service/cloudapi/k8s/data_source_k8s_wg.go @@ -1,3 +1,35 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://github.com/rudecs/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://github.com/rudecs/terraform-provider-decort/wiki +*/ + package k8s import ( @@ -11,19 +43,6 @@ import ( log "github.com/sirupsen/logrus" ) -func flattenWgData(d *schema.ResourceData, wg K8SGroup, computes []kvmvm.ComputeGetResp) { - d.Set("annotations", wg.Annotations) - d.Set("cpu", wg.CPU) - d.Set("detailed_info", flattenDetailedInfo(wg.DetailedInfo, computes)) - d.Set("disk", wg.Disk) - d.Set("guid", wg.GUID) - d.Set("labels", wg.Labels) - d.Set("name", wg.Name) - d.Set("num", wg.Num) - d.Set("ram", wg.RAM) - d.Set("taints", wg.Taints) -} - func dataSourceK8sWgRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("dataSourceK8sWgRead: called with k8s id %d", d.Get("k8s_id").(int)) diff --git a/internal/service/cloudapi/k8s/data_source_k8s_wg_list.go b/internal/service/cloudapi/k8s/data_source_k8s_wg_list.go index 030fe6d..43b8df3 100644 --- a/internal/service/cloudapi/k8s/data_source_k8s_wg_list.go +++ b/internal/service/cloudapi/k8s/data_source_k8s_wg_list.go @@ -1,3 +1,35 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://github.com/rudecs/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://github.com/rudecs/terraform-provider-decort/wiki +*/ + package k8s import ( @@ -13,33 +45,6 @@ import ( "github.com/rudecs/terraform-provider-decort/internal/service/cloudapi/kvmvm" ) -func flattenWgList(wgList K8SGroupList, computesMap map[uint64][]kvmvm.ComputeGetResp) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - for _, wg := range wgList { - computes := computesMap[wg.ID] - temp := map[string]interface{}{ - "annotations": wg.Annotations, - "cpu": wg.CPU, - "wg_id": wg.ID, - "detailed_info": flattenDetailedInfo(wg.DetailedInfo, computes), - "disk": wg.Disk, - "guid": wg.GUID, - "labels": wg.Labels, - "name": wg.Name, - "num": wg.Num, - "ram": wg.RAM, - "taints": wg.Taints, - } - - res = append(res, temp) - } - return res -} - -func flattenItemsWg(d *schema.ResourceData, wgList K8SGroupList, computes map[uint64][]kvmvm.ComputeGetResp) { - d.Set("items", flattenWgList(wgList, computes)) -} - func utilityK8sWgListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (K8SGroupList, error) { c := m.(*controller.ControllerCfg) diff --git a/internal/service/cloudapi/k8s/flattens.go b/internal/service/cloudapi/k8s/flattens.go index a0f4159..73a601d 100644 --- a/internal/service/cloudapi/k8s/flattens.go +++ b/internal/service/cloudapi/k8s/flattens.go @@ -1,3 +1,35 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://github.com/rudecs/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://github.com/rudecs/terraform-provider-decort/wiki +*/ + package k8s import ( @@ -245,3 +277,43 @@ func flattenResourceK8s(d *schema.ResourceData, k8s K8SRecord, masters []kvmvm.C d.Set("updated_time", k8s.UpdatedTime) d.Set("default_wg_id", k8s.K8SGroups.Workers[0].ID) } + +func flattenWgData(d *schema.ResourceData, wg K8SGroup, computes []kvmvm.ComputeGetResp) { + d.Set("annotations", wg.Annotations) + d.Set("cpu", wg.CPU) + d.Set("detailed_info", flattenDetailedInfo(wg.DetailedInfo, computes)) + d.Set("disk", wg.Disk) + d.Set("guid", wg.GUID) + d.Set("labels", wg.Labels) + d.Set("name", wg.Name) + d.Set("num", wg.Num) + d.Set("ram", wg.RAM) + d.Set("taints", wg.Taints) +} + +func flattenWgList(wgList K8SGroupList, computesMap map[uint64][]kvmvm.ComputeGetResp) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, wg := range wgList { + computes := computesMap[wg.ID] + temp := map[string]interface{}{ + "annotations": wg.Annotations, + "cpu": wg.CPU, + "wg_id": wg.ID, + "detailed_info": flattenDetailedInfo(wg.DetailedInfo, computes), + "disk": wg.Disk, + "guid": wg.GUID, + "labels": wg.Labels, + "name": wg.Name, + "num": wg.Num, + "ram": wg.RAM, + "taints": wg.Taints, + } + + res = append(res, temp) + } + return res +} + +func flattenItemsWg(d *schema.ResourceData, wgList K8SGroupList, computes map[uint64][]kvmvm.ComputeGetResp) { + d.Set("items", flattenWgList(wgList, computes)) +} diff --git a/internal/service/cloudapi/k8s/models.go b/internal/service/cloudapi/k8s/models.go index 38e701b..242cb60 100644 --- a/internal/service/cloudapi/k8s/models.go +++ b/internal/service/cloudapi/k8s/models.go @@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Authors: Petr Krutov, Stanislav Solovev, +Kasim Baybikov, Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/service/cloudapi/k8s/node_subresource.go b/internal/service/cloudapi/k8s/node_subresource.go index 2229bd0..70e7d72 100644 --- a/internal/service/cloudapi/k8s/node_subresource.go +++ b/internal/service/cloudapi/k8s/node_subresource.go @@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Authors: Petr Krutov, Stanislav Solovev, +Kasim Baybikov, Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/service/cloudapi/k8s/resource_k8s.go b/internal/service/cloudapi/k8s/resource_k8s.go index e05c9e2..a813fea 100644 --- a/internal/service/cloudapi/k8s/resource_k8s.go +++ b/internal/service/cloudapi/k8s/resource_k8s.go @@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Authors: Petr Krutov, Stanislav Solovev, +Kasim Baybikov, Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/service/cloudapi/k8s/resource_k8s_wg.go b/internal/service/cloudapi/k8s/resource_k8s_wg.go index c459b87..4e4476e 100644 --- a/internal/service/cloudapi/k8s/resource_k8s_wg.go +++ b/internal/service/cloudapi/k8s/resource_k8s_wg.go @@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Authors: Petr Krutov, Stanislav Solovev, +Kasim Baybikov, Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/service/cloudapi/k8s/utility_k8s.go b/internal/service/cloudapi/k8s/utility_k8s.go index 6f572a1..d0253ef 100644 --- a/internal/service/cloudapi/k8s/utility_k8s.go +++ b/internal/service/cloudapi/k8s/utility_k8s.go @@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Authors: Petr Krutov, Stanislav Solovev, +Kasim Baybikov, Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/service/cloudapi/k8s/utility_k8s_wg.go b/internal/service/cloudapi/k8s/utility_k8s_wg.go index 711b826..53d6e96 100644 --- a/internal/service/cloudapi/k8s/utility_k8s_wg.go +++ b/internal/service/cloudapi/k8s/utility_k8s_wg.go @@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Authors: Petr Krutov, Stanislav Solovev, +Kasim Baybikov, Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/service/cloudapi/vins/api.go b/internal/service/cloudapi/vins/api.go index 049b8a4..3958114 100644 --- a/internal/service/cloudapi/vins/api.go +++ b/internal/service/cloudapi/vins/api.go @@ -32,14 +32,27 @@ Documentation: https://github.com/rudecs/terraform-provider-decort/wiki package vins -const VinsListAPI = "/restmachine/cloudapi/vins/list" -const VinsGetAPI = "/restmachine/cloudapi/vins/get" -const VinsSearchAPI = "/restmachine/cloudapi/vins/search" - -const VinsCreateInAccountAPI = "/restmachine/cloudapi/vins/createInAccount" -const VinsCreateInRgAPI = "/restmachine/cloudapi/vins/createInRG" - -const VinsExtNetConnectAPI = "/restmachine/cloudapi/vins/extNetConnect" -const VinsExtNetDisconnectAPI = "/restmachine/cloudapi/vins/extNetDisconnect" - -const VinsDeleteAPI = "/restmachine/cloudapi/vins/delete" +const ( + VinsAuditsAPI = "/restmachine/cloudapi/vins/audits" + VinsCreateInAccountAPI = "/restmachine/cloudapi/vins/createInAccount" + VinsCreateInRgAPI = "/restmachine/cloudapi/vins/createInRG" + VinsDeleteAPI = "/restmachine/cloudapi/vins/delete" + VinsDisableAPI = "/restmachine/cloudapi/vins/disable" + VinsEnableAPI = "/restmachine/cloudapi/vins/enable" + VinsExtNetConnectAPI = "/restmachine/cloudapi/vins/extNetConnect" + VinsExtNetDisconnectAPI = "/restmachine/cloudapi/vins/extNetDisconnect" + VinsExtNetListAPI = "/restmachine/cloudapi/vins/extNetList" + VinsGetAPI = "/restmachine/cloudapi/vins/get" + VinsIpListAPI = "/restmachine/cloudapi/vins/ipList" + VinsIpReleaseAPI = "/restmachine/cloudapi/vins/ipRelease" + VinsIpReserveAPI = "/restmachine/cloudapi/vins/ipReserve" + VinsListAPI = "/restmachine/cloudapi/vins/list" + VinsListDeletedAPI = "/restmachine/cloudapi/vins/listDeleted" + VinsNatRuleAddAPI = "/restmachine/cloudapi/vins/natRuleAdd" + VinsNatRuleDelAPI = "/restmachine/cloudapi/vins/natRuleDel" + VinsNatRuleListAPI = "/restmachine/cloudapi/vins/natRuleList" + VinsRestoreAPI = "/restmachine/cloudapi/vins/restore" + VinsSearchAPI = "/restmachine/cloudapi/vins/search" + VinsVnfdevRedeployAPI = "/restmachine/cloudapi/vins/vnfdevRedeploy" + VinsVnfdevRestartAPI = "/restmachine/cloudapi/vins/vnfdevRestart" +) diff --git a/internal/service/cloudapi/vins/data_source_vins.go b/internal/service/cloudapi/vins/data_source_vins.go index 2bcd362..36030df 100644 --- a/internal/service/cloudapi/vins/data_source_vins.go +++ b/internal/service/cloudapi/vins/data_source_vins.go @@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Authors: Petr Krutov, Stanislav Solovev, +Kasim Baybikov, Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -33,149 +34,876 @@ package vins import ( "context" - "encoding/json" - "fmt" - - "github.com/rudecs/terraform-provider-decort/internal/constants" - log "github.com/sirupsen/logrus" - - // "net/url" + "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - // "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + "github.com/rudecs/terraform-provider-decort/internal/constants" ) -// vins_facts is a response string from API vins/get -func flattenVins(d *schema.ResourceData, vins_facts string) diag.Diagnostics { - // NOTE: this function modifies ResourceData argument - as such it should never be called - // from resourceVinsExists(...) method - // log.Debugf("flattenVins: ready to decode response body from API %s", vins_facts) - vinsRecord := VinsRecord{} - err := json.Unmarshal([]byte(vins_facts), &vinsRecord) +func dataSourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + vins, err := utilityDataVinsCheckPresence(ctx, d, m) if err != nil { return diag.FromErr(err) } - log.Debugf("flattenVins: decoded ViNS name:ID %s:%d, account ID %d, RG ID %d", - vinsRecord.Name, vinsRecord.ID, vinsRecord.AccountID, vinsRecord.RgID) + d.SetId(strconv.FormatUint(vins.ID, 10)) + flattenVinsData(d, *vins) + return nil +} - d.SetId(fmt.Sprintf("%d", vinsRecord.ID)) - d.Set("name", vinsRecord.Name) - d.Set("account_id", vinsRecord.AccountID) - d.Set("account_name", vinsRecord.AccountName) - d.Set("rg_id", vinsRecord.RgID) - d.Set("description", vinsRecord.Desc) - d.Set("ipcidr", vinsRecord.IPCidr) +func vnfConfigMGMTSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "ip_addr": { + Type: schema.TypeString, + Computed: true, + }, + "password": { + Type: schema.TypeString, + Computed: true, + }, + "ssh_key": { + Type: schema.TypeString, + Computed: true, + }, + "user": { + Type: schema.TypeString, + Computed: true, + }, + } +} - noExtNetConnection := true - for _, value := range vinsRecord.VNFs { - if value.Type == "GW" { - log.Debugf("flattenVins: discovered GW VNF ID %d in ViNS ID %d", value.ID, vinsRecord.ID) - extNetID, idOk := value.Config["ext_net_id"] // NOTE: unknown numbers are unmarshalled to float64. This is by design! - extNetIP, ipOk := value.Config["ext_net_ip"] - if idOk && ipOk { - log.Debugf("flattenVins: ViNS ext_net_id=%d, ext_net_ip=%s", int(extNetID.(float64)), extNetIP.(string)) - d.Set("ext_ip_addr", extNetIP.(string)) - d.Set("ext_net_id", int(extNetID.(float64))) - } else { - return diag.Errorf("Failed to unmarshal VNF GW Config - structure is invalid.") - } - noExtNetConnection = false - break - } +func vnfConfigResourcesSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "stack_id": { + Type: schema.TypeInt, + Computed: true, + }, + "uuid": { + Type: schema.TypeString, + Computed: true, + }, } +} - if noExtNetConnection { - d.Set("ext_ip_addr", "") - d.Set("ext_net_id", 0) +func qosSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "e_rate": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "in_brust": { + Type: schema.TypeInt, + Computed: true, + }, + "in_rate": { + Type: schema.TypeInt, + Computed: true, + }, } +} - 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 { - vinsFacts, err := utilityVinsCheckPresence(ctx, d, m) - if vinsFacts == "" { - // if empty string is returned from utilityVinsCheckPresence then there is no - // such ViNS and err tells so - just return it to the calling party - d.SetId("") // ensure ID is empty in this case - return diag.FromErr(err) +func vnfDevSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "_ckey": { + Type: schema.TypeString, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Unique ID of the account, which this ViNS belongs to.", + }, + "capabilities": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "config": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: vnfConfigSchemaMake(), + }, + }, + "config_saved": { + Type: schema.TypeBool, + Computed: true, + }, + "custom_pre_cfg": { + Type: schema.TypeBool, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "vnf_id": { + Type: schema.TypeInt, + Computed: true, + }, + "interfaces": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: vnfInterfaceSchemaMake(), + }, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "vnf_name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vins": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, } +} - 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 { - return &schema.Resource{ - SchemaVersion: 1, +func reservationSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "client_type": { + Type: schema.TypeString, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "domainname": { + Type: schema.TypeString, + Computed: true, + }, + "hostname": { + Type: schema.TypeString, + Computed: true, + }, + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "mac": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + } +} - 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{ - Read: &constants.Timeout30s, - Default: &constants.Timeout60s, +func devicesPrimarySchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "dev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "iface01": { + Type: schema.TypeString, + Computed: true, }, + "iface02": { + Type: schema.TypeString, + Computed: true, + }, + } +} - Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Required: true, - Description: "Name of the ViNS. Names are case sensitive and unique within the context of an account or resource group.", +func devicesSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "primary": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: devicesPrimarySchemaMake(), }, + }, + } +} - /* - "vins_id": { - Type: schema.TypeInt, - Optional: true, - Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.", - }, - */ - - "rg_id": { - Type: schema.TypeInt, - Optional: true, - Description: "Unique ID of the resource group, where this ViNS is belongs to (for ViNS created at resource group level, 0 otherwise).", +func dhcpSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "_ckey": { + Type: schema.TypeString, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "config": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: dhcpConfigSchemaMake(), + }, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "devices": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: devicesSchemaMake(), }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "dhcp_id": { + Type: schema.TypeInt, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "owner_id": { + Type: schema.TypeInt, + Computed: true, + }, + "owner_type": { + Type: schema.TypeString, + Computed: true, + }, + "pure_virtual": { + Type: schema.TypeBool, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + } +} - "account_id": { - Type: schema.TypeInt, - Optional: true, - Description: "Unique ID of the account, which this ViNS belongs to.", +func gwConfigSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "default_gw": { + Type: schema.TypeString, + Computed: true, + }, + "ext_net_id": { + Type: schema.TypeInt, + Computed: true, + }, + "ext_net_ip": { + Type: schema.TypeString, + Computed: true, + }, + "ext_netmask": { + Type: schema.TypeInt, + Computed: true, + }, + "qos": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: qosSchemaMake(), }, + }, + } +} - // the rest of attributes are computed - "account_name": { - Type: schema.TypeString, - Computed: true, - Description: "Name of the account, which this ViNS belongs to.", +func gwSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "_ckey": { + Type: schema.TypeString, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "config": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: gwConfigSchemaMake(), }, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "devices": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: devicesSchemaMake(), + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "gw_id": { + Type: schema.TypeInt, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "owner_id": { + Type: schema.TypeInt, + Computed: true, + }, + "owner_type": { + Type: schema.TypeString, + Computed: true, + }, + "pure_virtual": { + Type: schema.TypeBool, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + } +} - "description": { - Type: schema.TypeString, - Computed: true, - Description: "User-defined text description of this ViNS.", +func rulesSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "rule_id": { + Type: schema.TypeInt, + Computed: true, + }, + "local_ip": { + Type: schema.TypeString, + Computed: true, + }, + "local_port": { + Type: schema.TypeInt, + Computed: true, + }, + "protocol": { + Type: schema.TypeString, + Computed: true, + }, + "public_port_end": { + Type: schema.TypeInt, + Computed: true, + }, + "public_port_start": { + Type: schema.TypeInt, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + "vm_name": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func configSchrmaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "net_mask": { + Type: schema.TypeInt, + Computed: true, + }, + "network": { + Type: schema.TypeString, + Computed: true, + }, + "rules": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: rulesSchemaMake(), }, + }, + } +} - "ext_ip_addr": { - Type: schema.TypeString, - Computed: true, - Description: "IP address of the external connection (valid for ViNS connected to external network, empty string otherwise).", +func natSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "_ckey": { + Type: schema.TypeString, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "config": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: configSchrmaMake(), + }, + }, + "devices": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: devicesSchemaMake(), }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "nat_id": { + Type: schema.TypeInt, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "owner_id": { + Type: schema.TypeInt, + Computed: true, + }, + "owner_type": { + Type: schema.TypeString, + Computed: true, + }, + "pure_virtual": { + Type: schema.TypeBool, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + } +} - "ext_net_id": { - Type: schema.TypeInt, - Computed: true, - Description: "ID of the external network this ViNS is connected to (-1 means no external connection).", +func vnfsSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "dhcp": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: dhcpSchemaMake(), + }, + }, + "gw": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: gwSchemaMake(), }, + }, + "nat": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: natSchemaMake(), + }, + }, + } +} + +func dataSourceVinsSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "vins_id": { + Type: schema.TypeInt, + Required: true, + Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.", + }, - "ipcidr": { - Type: schema.TypeString, - Computed: true, - Description: "Network address used by this ViNS.", + "vnf_dev": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: vnfDevSchemaMake(), + }, + }, + "_ckey": { + Type: schema.TypeString, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Unique ID of the account, which this ViNS belongs to.", + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the account, which this ViNS belongs to.", + }, + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: vinsComputeSchemaMake(), }, }, + "default_gw": { + Type: schema.TypeString, + Computed: true, + }, + "default_qos": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: qosSchemaMake(), + }, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + Description: "User-defined text description of this ViNS.", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "manager_id": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_type": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "net_mask": { + Type: schema.TypeInt, + Computed: true, + }, + "network": { + Type: schema.TypeString, + Computed: true, + }, + "pre_reservations_num": { + Type: schema.TypeInt, + Computed: true, + }, + "redundant": { + Type: schema.TypeBool, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Unique ID of the resource group, where this ViNS is belongs to (for ViNS created at resource group level, 0 otherwise).", + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "sec_vnf_dev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + "vnfs": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: vnfsSchemaMake(), + }, + }, + "vxlan_id": { + Type: schema.TypeInt, + Computed: true, + }, + } + return rets +} + +func DataSourceVins() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceVinsRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceVinsSchemaMake(), } } diff --git a/internal/service/cloudapi/vins/data_source_vins_audits.go b/internal/service/cloudapi/vins/data_source_vins_audits.go new file mode 100644 index 0000000..77f2aec --- /dev/null +++ b/internal/service/cloudapi/vins/data_source_vins_audits.go @@ -0,0 +1,106 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +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(), + } +} diff --git a/internal/service/cloudapi/vins/data_source_vins_ext_net_list.go b/internal/service/cloudapi/vins/data_source_vins_ext_net_list.go new file mode 100644 index 0000000..eb6f586 --- /dev/null +++ b/internal/service/cloudapi/vins/data_source_vins_ext_net_list.go @@ -0,0 +1,110 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +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(), + } +} diff --git a/internal/service/cloudapi/vins/data_source_vins_ip_list.go b/internal/service/cloudapi/vins/data_source_vins_ip_list.go new file mode 100644 index 0000000..b49fb3a --- /dev/null +++ b/internal/service/cloudapi/vins/data_source_vins_ip_list.go @@ -0,0 +1,114 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +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(), + } +} diff --git a/internal/service/cloudapi/vins/data_source_vins_list.go b/internal/service/cloudapi/vins/data_source_vins_list.go index ba9d84a..1f21fda 100644 --- a/internal/service/cloudapi/vins/data_source_vins_list.go +++ b/internal/service/cloudapi/vins/data_source_vins_list.go @@ -1,190 +1,164 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://github.com/rudecs/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://github.com/rudecs/terraform-provider-decort/wiki -*/ - -package vins - -import ( - "context" - - "github.com/google/uuid" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/rudecs/terraform-provider-decort/internal/constants" -) - -func flattenVinsList(vl VinsList) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - for _, v := range vl { - temp := map[string]interface{}{ - "account_id": v.AccountId, - "account_name": v.AccountName, - "created_by": v.CreatedBy, - "created_time": v.CreatedTime, - "deleted_by": v.DeletedBy, - "deleted_time": v.DeletedTime, - "external_ip": v.ExternalIP, - "vins_id": v.ID, - "vins_name": v.Name, - "network": v.Network, - "rg_id": v.RGID, - "rg_name": v.RGName, - "status": v.Status, - "updated_by": v.UpdatedBy, - "updated_time": v.UpdatedTime, - "vxlan_id": v.VXLanID, - } - res = append(res, temp) - } - return res -} - -func dataSourceVinsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - vinsList, err := utilityVinsListCheckPresence(ctx, d, m) - if err != nil { - return diag.FromErr(err) - } - - id := uuid.New() - d.SetId(id.String()) - d.Set("items", flattenVinsList(vinsList)) - - return nil -} - -func dataSourceVinsListSchemaMake() map[string]*schema.Schema { - res := map[string]*schema.Schema{ - "include_deleted": { - Type: schema.TypeBool, - Optional: true, - Default: false, - Description: "include deleted computes", - }, - "page": { - Type: schema.TypeInt, - Optional: true, - Description: "Page number", - }, - "size": { - Type: schema.TypeInt, - Optional: true, - Description: "Page size", - }, - "items": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "account_id": { - Type: schema.TypeInt, - Computed: true, - }, - "account_name": { - Type: schema.TypeString, - Computed: true, - }, - "created_by": { - Type: schema.TypeString, - Computed: true, - }, - "created_time": { - Type: schema.TypeInt, - Computed: true, - }, - "deleted_by": { - Type: schema.TypeString, - Computed: true, - }, - "deleted_time": { - Type: schema.TypeInt, - Computed: true, - }, - "external_ip": { - Type: schema.TypeString, - Computed: true, - }, - "vins_id": { - Type: schema.TypeInt, - Computed: true, - }, - "vins_name": { - Type: schema.TypeString, - Computed: true, - }, - "network": { - Type: schema.TypeString, - Computed: true, - }, - "rg_id": { - Type: schema.TypeInt, - Computed: true, - }, - "rg_name": { - Type: schema.TypeString, - Computed: true, - }, - "status": { - Type: schema.TypeString, - Computed: true, - }, - "updated_by": { - Type: schema.TypeString, - Computed: true, - }, - "updated_time": { - Type: schema.TypeInt, - Computed: true, - }, - "vxlan_id": { - Type: schema.TypeInt, - Computed: true, - }, - }, - }, - }, - } - return res -} - -func DataSourceVinsList() *schema.Resource { - return &schema.Resource{ - SchemaVersion: 1, - - ReadContext: dataSourceVinsListRead, - - Timeouts: &schema.ResourceTimeout{ - Read: &constants.Timeout30s, - Default: &constants.Timeout60s, - }, - - Schema: dataSourceVinsListSchemaMake(), - } -} +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://github.com/rudecs/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://github.com/rudecs/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/rudecs/terraform-provider-decort/internal/constants" +) + +func dataSourceVinsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + vinsList, err := utilityVinsListCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenVinsList(vinsList)) + + return nil +} + +func dataSourceVinsListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "include_deleted": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "include deleted computes", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "external_ip": { + Type: schema.TypeString, + Computed: true, + }, + "vins_id": { + Type: schema.TypeInt, + Computed: true, + }, + "vins_name": { + Type: schema.TypeString, + Computed: true, + }, + "network": { + Type: schema.TypeString, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vxlan_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + } + return res +} + +func DataSourceVinsList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceVinsListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceVinsListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/vins/data_source_vins_list_deleted.go b/internal/service/cloudapi/vins/data_source_vins_list_deleted.go new file mode 100644 index 0000000..99d765b --- /dev/null +++ b/internal/service/cloudapi/vins/data_source_vins_list_deleted.go @@ -0,0 +1,158 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +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(), + } +} diff --git a/internal/service/cloudapi/vins/data_source_vins_nat_rule_list.go b/internal/service/cloudapi/vins/data_source_vins_nat_rule_list.go new file mode 100644 index 0000000..a07b0b1 --- /dev/null +++ b/internal/service/cloudapi/vins/data_source_vins_nat_rule_list.go @@ -0,0 +1,118 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +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(), + } +} diff --git a/internal/service/cloudapi/vins/flattens.go b/internal/service/cloudapi/vins/flattens.go new file mode 100644 index 0000000..fd20746 --- /dev/null +++ b/internal/service/cloudapi/vins/flattens.go @@ -0,0 +1,514 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +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 +} diff --git a/internal/service/cloudapi/vins/models.go b/internal/service/cloudapi/vins/models.go index e8b95d1..0c1754a 100644 --- a/internal/service/cloudapi/vins/models.go +++ b/internal/service/cloudapi/vins/models.go @@ -1,94 +1,330 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://github.com/rudecs/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://github.com/rudecs/terraform-provider-decort/wiki -*/ - -package vins - -type Vins struct { - AccountId int `json:"accountId"` - AccountName string `json:"accountName"` - CreatedBy string `json:"createdBy"` - CreatedTime int `json:"createdTime"` - DeletedBy string `json:"deletedBy"` - DeletedTime int `json:"deletedTime"` - ExternalIP string `json:"externalIP"` - ID int `json:"id"` - Name string `json:"name"` - Network string `json:"network"` - RGID int `json:"rgId"` - RGName string `json:"rgName"` - Status string `json:"status"` - UpdatedBy string `json:"updatedBy"` - UpdatedTime int `json:"updatedTime"` - VXLanID int `json:"vxlanId"` -} - -type VinsList []Vins - -type VinsSearchResp []VinsSearchRecord - -type VnfRecord struct { - ID int `json:"id"` - AccountID int `json:"accountId"` - Type string `json:"type"` // "DHCP", "NAT", "GW" etc - Config map[string]interface{} `json:"config"` // NOTE: VNF specs vary by VNF type -} - -type VnfGwConfigRecord struct { // describes GW VNF config structure inside ViNS, as returned by API vins/get - ExtNetID int `json:"ext_net_id"` - ExtNetIP string `json:"ext_net_ip"` - ExtNetMask int `json:"ext_net_mask"` - DefaultGW string `json:"default_gw"` -} -type VinsRecord struct { // represents part of the response from API vins/get - ID int `json:"id"` - Name string `json:"name"` - IPCidr string `json:"network"` - VxLanID int `json:"vxlanId"` - ExternalIP string `json:"externalIP"` - AccountID int `json:"accountId"` - AccountName string `json:"accountName"` - RgID int `json:"rgid"` - RgName string `json:"rgName"` - VNFs map[string]VnfRecord `json:"vnfs"` - Desc string `json:"desc"` -} - -type VinsSearchRecord struct { - ID int `json:"id"` - Name string `json:"name"` - IPCidr string `json:"network"` - VxLanID int `json:"vxlanId"` - ExternalIP string `json:"externalIP"` - AccountID int `json:"accountId"` - AccountName string `json:"accountName"` - RgID int `json:"rgId"` - RgName string `json:"rgName"` -} +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://github.com/rudecs/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://github.com/rudecs/terraform-provider-decort/wiki +*/ + +package vins + +type VINSRecord struct { + AccountID uint64 `json:"accountId"` + AccountName string `json:"accountName"` + CreatedBy string `json:"createdBy"` + CreatedTime uint64 `json:"createdTime"` + DeletedBy string `json:"deletedBy"` + DeletedTime uint64 `json:"deletedTime"` + ExternalIP string `json:"externalIP"` + ID uint64 `json:"id"` + Name string `json:"name"` + Network string `json:"network"` + RGID uint64 `json:"rgId"` + RGName string `json:"rgName"` + Status string `json:"status"` + UpdatedBy string `json:"updatedBy"` + UpdatedTime uint64 `json:"updatedTime"` + VXLANID uint64 `json:"vxlanId"` +} + +type VINSList []VINSRecord + +type VINSAudits struct { + Call string `json:"call"` + ResponseTime float64 `json:"responsetime"` + StatusCode uint64 `json:"statuscode"` + Timestamp float64 `json:"timestamp"` + User string `json:"user"` +} + +type VINSAuditsList []VINSAudits + +type VINSExtNet struct { + DefaultGW string `json:"default_gw"` + ExtNetID uint64 `json:"ext_net_id"` + IP string `json:"ip"` + PrefixLen uint64 `json:"prefixlen"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` +} + +type ExtNetList []VINSExtNet + +type IP struct { + ClientType string `json:"clientType"` + DomainName string `json:"domainname"` + HostName string `json:"hostname"` + IP string `json:"ip"` + MAC string `json:"mac"` + Type string `json:"type"` + VMID uint64 `json:"vmId"` +} + +type IPList []IP + +type VNFDev struct { + CKey string `json:"_ckey"` + AccountID uint64 `json:"accountId"` + Capabilities []string `json:"capabilities"` + Config VNFConfig `json:"config"` + ConfigSaved bool `json:"configSaved"` + CustomPreConfig bool `json:"customPrecfg"` + Description string `json:"desc"` + GID uint64 `json:"gid"` + GUID uint64 `json:"guid"` + ID uint64 `json:"id"` + Interfaces VNFInterfaceList `json:"interfaces"` + LockStatus string `json:"lockStatus"` + Milestones uint64 `json:"milestones"` + Name string `json:"name"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` + Type string `json:"type"` + VINS []uint64 `json:"vins"` +} + +type VNFConfig struct { + MGMT VNFConfigMGMT `json:"mgmt"` + Resources VNFConfigResources `json:"resources"` +} + +type VNFConfigMGMT struct { + IPAddr string `json:"ipaddr"` + Password string `json:"password"` + SSHKey string `json:"sshkey"` + User string `json:"user"` +} + +type VNFConfigResources struct { + CPU uint64 `json:"cpu"` + RAM uint64 `json:"ram"` + StackID uint64 `json:"stackId"` + UUID string `json:"uuid"` +} + +type VNFInterface struct { + ConnID uint64 `json:"connId"` + ConnType string `json:"connType"` + DefGW string `json:"defGw"` + FlipGroupID uint64 `json:"flipgroupId"` + GUID string `json:"guid"` + IPAddress string `json:"ipAddress"` + ListenSSH bool `json:"listenSsh"` + MAC string `json:"mac"` + Name string `json:"name"` + NetID uint64 `json:"netId"` + NetMask uint64 `json:"netMask"` + NetType string `json:"netType"` + PCISlot uint64 `json:"pciSlot"` + QOS QOS `json:"qos"` + Target string `json:"target"` + Type string `json:"type"` + VNFS []uint64 `json:"vnfs"` +} + +type QOS struct { + ERate uint64 `json:"eRate"` + GUID string `json:"guid"` + InBurst uint64 `json:"inBurst"` + InRate uint64 `json:"inRate"` +} + +type VNFInterfaceList []VNFInterface + +type VINSCompute struct { + ID uint64 `json:"id"` + Name string `json:"name"` +} + +type VINSComputeList []VINSCompute + +type VNFS struct { + DHCP DHCP `json:"DHCP"` + GW GW `json:"GW"` + NAT NAT `json:"NAT"` +} + +type NAT struct { + CKey string `json:"_ckey"` + AccountID uint64 `json:"accountId"` + CreatedTime uint64 `json:"createdTime"` + Config NATConfig `json:"config"` + Devices Devices `json:"devices"` + GID uint64 `json:"gid"` + GUID uint64 `json:"guid"` + ID uint64 `json:"id"` + LockStatus string `json:"lockStatus"` + Milestones uint64 `json:"milestones"` + OwnerID uint64 `json:"ownerId"` + OwnerType string `json:"ownerType"` + PureVirtual bool `json:"pureVirtual"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` + Type string `json:"type"` +} + +type NATConfig struct { + NetMask uint64 `json:"netmask"` + Network string `json:"network"` + Rules ListNATRules `json:"rules"` +} + +type ItemNATRule struct { + ID uint64 `json:"id"` + LocalIP string `json:"localIp"` + LocalPort uint64 `json:"localPort"` + Protocol string `json:"protocol"` + PublicPortEnd uint64 `json:"publicPortEnd"` + PublicPortStart uint64 `json:"publicPortStart"` + VMID uint64 `json:"vmId"` + VMName string `json:"vmName"` +} + +type ListNATRules []ItemNATRule + +type GW struct { + CKey string `json:"_ckey"` + AccountID uint64 `json:"accountId"` + Config GWConfig `json:"config"` + CreatedTime uint64 `json:"createdTime"` + Devices Devices `json:"devices"` + GID uint64 `json:"gid"` + GUID uint64 `json:"guid"` + ID uint64 `json:"id"` + LockStatus string `json:"lockStatus"` + Milestones uint64 `json:"milestones"` + OwnerID uint64 `json:"ownerId"` + OwnerType string `json:"ownerType"` + PureVirtual bool `json:"pureVirtual"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` + Type string `json:"type"` +} + +type GWConfig struct { + DefaultGW string `json:"default_gw"` + ExtNetID uint64 `json:"ext_net_id"` + ExtNetIP string `json:"ext_net_ip"` + ExtNetMask uint64 `json:"ext_netmask"` + QOS QOS `json:"qos"` +} + +type Devices struct { + Primary DevicePrimary `json:"primary"` +} + +type DevicePrimary struct { + DevID uint64 `json:"devId"` + IFace01 string `json:"iface01"` + IFace02 string `json:"iface02"` +} + +type DHCP struct { + CKey string `json:"_ckey"` + AccountID uint64 `json:"accountId"` + Config DHCPConfig `json:"config"` + CreatedTime uint64 `json:"createdTime"` + Devices Devices `json:"devices"` + GID uint64 `json:"gid"` + GUID uint64 `json:"guid"` + ID uint64 `json:"id"` + LockStatus string `json:"lockStatus"` + Milestones uint64 `json:"milestones"` + OwnerID uint64 `json:"ownerId"` + OwnerType string `json:"ownerType"` + PureVirtual bool `json:"pureVirtual"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` + Type string `json:"type"` +} + +type DHCPConfig struct { + DefaultGW string `json:"default_gw"` + DNS []string `json:"dns"` + IPEnd string `json:"ip_end"` + IPStart string `json:"ip_start"` + Lease uint64 `json:"lease"` + Netmask uint64 `json:"netmask"` + Network string `json:"network"` + Reservations ReservationList `json:"reservations"` +} + +type VINSDetailed struct { + VNFDev VNFDev `json:"VNFDev"` + CKey string `json:"_ckey"` + AccountID uint64 `json:"accountId"` + AccountName string `json:"accountName"` + Computes VINSComputeList `json:"computes"` + DefaultGW string `json:"defaultGW"` + DefaultQOS QOS `json:"defaultQos"` + Description string `json:"desc"` + GID uint64 `json:"gid"` + GUID uint64 `json:"guid"` + ID uint64 `json:"id"` + LockStatus string `json:"lockStatus"` + ManagerID uint64 `json:"managerId"` + ManagerType string `json:"managerType"` + Milestones uint64 `json:"milestones"` + Name string `json:"name"` + NetMask uint64 `json:"netMask"` + Network string `json:"network"` + PreReservaionsNum uint64 `json:"preReservationsNum"` + Redundant bool `json:"redundant"` + RGID uint64 `json:"rgId"` + RGName string `json:"rgName"` + SecVNFDevID uint64 `json:"secVnfDevId"` + Status string `json:"status"` + UserManaged bool `json:"userManaged"` + VNFS VNFS `json:"vnfs"` + VXLanID uint64 `json:"vxlanId"` +} + +type Reservation struct { + ClientType string `json:"clientType"` + Description string `json:"desc"` + DomainName string `json:"domainname"` + HostName string `json:"hostname"` + IP string `json:"ip"` + MAC string `json:"mac"` + Type string `json:"type"` + VMID int `json:"vmId"` +} + +type ReservationList []Reservation + +type NATRule struct { + ID uint64 `json:"id"` + LocalIP string `json:"localIp"` + LocalPort uint64 `json:"localPort"` + Protocol string `json:"protocol"` + PublicPortEnd uint64 `json:"publicPortEnd"` + PublicPortStart uint64 `json:"publicPortStart"` + VMID uint64 `json:"vmId"` + VMName string `json:"vmName"` +} + +type NATRuleList []NATRule diff --git a/internal/service/cloudapi/vins/resource_vins.go b/internal/service/cloudapi/vins/resource_vins.go index c8aa317..a151dcd 100644 --- a/internal/service/cloudapi/vins/resource_vins.go +++ b/internal/service/cloudapi/vins/resource_vins.go @@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Authors: Petr Krutov, Stanislav Solovev, +Kasim Baybikov, Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -39,6 +40,8 @@ import ( "github.com/rudecs/terraform-provider-decort/internal/constants" "github.com/rudecs/terraform-provider-decort/internal/controller" + "github.com/rudecs/terraform-provider-decort/internal/dc" + "github.com/rudecs/terraform-provider-decort/internal/status" log "github.com/sirupsen/logrus" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" @@ -46,112 +49,221 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" ) -func ipcidrDiffSupperss(key, oldVal, newVal string, d *schema.ResourceData) bool { - if oldVal == "" && newVal != "" { - // if old value for "ipcidr" resource is empty string, it means that we are creating new ViNS - // and there is a chance that the user will want specific IP address range for this ViNS - - // check if "ipcidr" is explicitly set in TF file to a non-empty string. - log.Debugf("ipcidrDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=FALSE", key, oldVal, newVal) - return false // there is a difference between stored and new value +func resourceVinsCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + c := m.(*controller.ControllerCfg) + urlValues := &url.Values{} + + rgId, rgOk := d.GetOk("rg_id") + accountId, accountIdOk := d.GetOk("account_id") + if !rgOk && !accountIdOk { + return diag.Errorf("resourceVinsCreate: no valid accountId or resource group ID specified") } - log.Debugf("ipcidrDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=TRUE", key, oldVal, newVal) - return true // suppress difference -} -func resourceVinsCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Debugf("resourceVinsCreate: called for ViNS name %s, Account ID %d, RG ID %d", - d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int)) + if rgOk { + urlValues.Add("name", d.Get("name").(string)) + urlValues.Add("rgId", strconv.Itoa(rgId.(int))) + if ipcidr, ok := d.GetOk("ipcidr"); ok { + urlValues.Add("ipcidr", ipcidr.(string)) + } - 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) - urlValues := &url.Values{} + //extnet v2 + if extNetResp, ok := d.GetOk("ext_net"); ok { + extNetSl := extNetResp.([]interface{}) + extNet := extNetSl[0].(map[string]interface{}) + urlValues.Add("vinsId", d.Id()) + urlValues.Add("netId", strconv.Itoa(extNet["ext_net_id"].(int))) + urlValues.Add("extIp", extNet["ext_net_ip"].(string)) + } - urlValues.Add("name", d.Get("name").(string)) - - argVal, argSet := d.GetOk("rg_id") - if argSet && argVal.(int) > 0 { - apiToCall = VinsCreateInRgAPI - urlValues.Add("rgId", fmt.Sprintf("%d", argVal.(int))) - } else { - // RG ID either not set at all or set to 0 - user may want ViNS at account level - argVal, argSet = d.GetOk("account_id") - if !argSet || argVal.(int) <= 0 { - // No valid Account ID (and no RG ID either) - cannot create ViNS - return diag.Errorf("resourceVinsCreate: ViNS name %s - no valid account and/or resource group ID specified", d.Id()) + if desc, ok := d.GetOk("desc"); ok { + urlValues.Add("desc", desc.(string)) + } + urlValues.Add("preReservationsNum", strconv.Itoa(d.Get("pre_reservations_num").(int))) + id, err := c.DecortAPICall(ctx, "POST", VinsCreateInRgAPI, urlValues) + if err != nil { + return diag.FromErr(err) + } + d.SetId(id) + } else if accountIdOk { + urlValues.Add("name", d.Get("name").(string)) + urlValues.Add("accountId", strconv.Itoa(accountId.(int))) + if gid, ok := d.GetOk("gid"); ok { + urlValues.Add("gid", strconv.Itoa(gid.(int))) + } + if ipcidr, ok := d.GetOk("ipcidr"); ok { + urlValues.Add("ipcidr", ipcidr.(string)) + } + if desc, ok := d.GetOk("desc"); ok { + urlValues.Add("desc", desc.(string)) + } + urlValues.Add("preReservationsNum", strconv.Itoa(d.Get("pre_reservations_num").(int))) + id, err := c.DecortAPICall(ctx, "POST", VinsCreateInAccountAPI, urlValues) + if err != nil { + return diag.FromErr(err) } - 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 - if argSet { - if argVal.(int) > 0 { - // connect to specific external network - urlValues.Add("extNetId", fmt.Sprintf("%d", argVal.(int))) - /* - Commented out, as we've made "ext_net_ip" parameter non-configurable via Terraform! + warnings := dc.Warnings{} + urlValues = &url.Values{} + if ipRes, ok := d.GetOk("ip"); ok { + ipsSlice := ipRes.([]interface{}) + for _, ipInterfase := range ipsSlice { + ip := ipInterfase.(map[string]interface{}) + urlValues = &url.Values{} + urlValues.Add("vinsId", d.Id()) + urlValues.Add("type", ip["type"].(string)) + if ipAddr, ok := ip["ip_addr"]; ok { + urlValues.Add("ipAddr", ipAddr.(string)) + } + if macAddr, ok := ip["mac_addr"]; ok { + urlValues.Add("mac", macAddr.(string)) + } + if computeId, ok := ip["compute_id"]; ok { + urlValues.Add("computeId", strconv.Itoa(computeId.(int))) + } + _, err := c.DecortAPICall(ctx, "POST", VinsIpReserveAPI, urlValues) + if err != nil { + warnings.Add(err) + } + } + } - // in case of specific ext net connection user may also want a particular IP address - argVal, argSet = d.GetOk("ext_net_ip") - if argSet && argVal.(string) != "" { - urlValues.Add("extIp", argVal.(string)) + urlValues = &url.Values{} + if natRule, ok := d.GetOk("nat_rule"); ok { + addedNatRules := natRule.([]interface{}) + if len(addedNatRules) > 0 { + for _, natRuleInterface := range addedNatRules { + urlValues = &url.Values{} + natRule := natRuleInterface.(map[string]interface{}) + + urlValues.Add("vinsId", d.Id()) + urlValues.Add("intIp", natRule["int_ip"].(string)) + urlValues.Add("intPort", strconv.Itoa(natRule["int_port"].(int))) + urlValues.Add("extPortStart", strconv.Itoa(natRule["ext_port_start"].(int))) + urlValues.Add("extPortEnd", strconv.Itoa(natRule["ext_port_end"].(int))) + urlValues.Add("proto", natRule["proto"].(string)) + + _, err := c.DecortAPICall(ctx, "POST", VinsNatRuleAddAPI, urlValues) + if err != nil { + warnings.Add(err) } - */ - } else { - // ext_net_id is set to a negative value - connect to default external network - // no particular IP address selection in this case - urlValues.Add("extNetId", "0") + } } } - argVal, argSet = d.GetOk("ipcidr") - if argSet && argVal.(string) != "" { - log.Debugf("resourceVinsCreate: ipcidr is set to %s", argVal.(string)) - urlValues.Add("ipcidr", argVal.(string)) - } + defer resourceVinsRead(ctx, d, m) + return warnings.Get() +} - argVal, argSet = d.GetOk("description") - if argSet { - urlValues.Add("desc", argVal.(string)) - } +func resourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + c := m.(*controller.ControllerCfg) + urlValues := &url.Values{} + warnings := dc.Warnings{} - apiResp, err := c.DecortAPICall(ctx, "POST", apiToCall, urlValues) + vins, err := utilityVinsCheckPresence(ctx, d, m) if err != nil { + d.SetId("") return diag.FromErr(err) } - d.SetId(apiResp) // update ID of the resource to tell Terraform that the ViNS resource exists - vinsId, _ := strconv.Atoi(apiResp) + hasChangeState := false + if vins.Status == status.Destroyed { + d.SetId("") + d.Set("vins_id", 0) + return resourceVinsCreate(ctx, d, m) + } else if vins.Status == status.Deleted { + hasChangeState = true - log.Debugf("resourceVinsCreate: new ViNS ID / name %d / %s creation sequence complete", vinsId, d.Get("name").(string)) + urlValues.Add("vinsId", d.Id()) + _, err := c.DecortAPICall(ctx, "POST", VinsRestoreAPI, urlValues) + if err != nil { + warnings.Add(err) + } + } + urlValues = &url.Values{} - // We may reuse dataSourceVinsRead here as we maintain similarity - // between ViNS resource and ViNS data source schemas - // ViNS resource read function will also update resource ID on success, so that Terraform - // will know the resource exists (however, we already did it a few lines before) - return dataSourceVinsRead(ctx, d, m) -} + isEnabled := d.Get("enable").(bool) + if vins.Status == status.Disabled && isEnabled { + hasChangeState = true -func resourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - vinsFacts, err := utilityVinsCheckPresence(ctx, d, m) - if vinsFacts == "" { - // if empty string is returned from utilityVinsCheckPresence then there is no - // such ViNS and err tells so - just return it to the calling party - d.SetId("") // ensure ID is empty - return diag.FromErr(err) + urlValues.Add("vinsId", d.Id()) + _, err := c.DecortAPICall(ctx, "POST", VinsEnableAPI, urlValues) + if err != nil { + warnings.Add(err) + } + } else if vins.Status == status.Enabled && !isEnabled { + hasChangeState = true + + urlValues.Add("vinsId", d.Id()) + _, err := c.DecortAPICall(ctx, "POST", VinsDisableAPI, urlValues) + if err != nil { + warnings.Add(err) + } + } + if hasChangeState { + vins, err = utilityVinsCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } } - return flattenVins(d, vinsFacts) + flattenVins(d, *vins) + return warnings.Get() } -func resourceVinsUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +func isContainsIp(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["ip_addr"].(string) == elConv["ip_addr"].(string) { + return true + } + } + return false +} - log.Debugf("resourceVinsUpdate: called for ViNS ID / name %s / %s, Account ID %d, RG ID %d", - d.Id(), d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int)) +func isContinsNatRule(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["int_ip"].(string) == elConv["int_ip"].(string) && + elOldConv["int_port"].(int) == elConv["int_port"].(int) && + elOldConv["ext_port_start"].(int) == elConv["ext_port_start"].(int) { + return true + } + } + return false +} +func resourceVinsUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { c := m.(*controller.ControllerCfg) + urlValues := &url.Values{} + warnings := dc.Warnings{} + + 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") if oldExtNetId.(int) != newExtNedId.(int) { log.Debugf("resourceVinsUpdate: changing ViNS ID %s - ext_net_id %d -> %d", d.Id(), oldExtNetId.(int), newExtNedId.(int)) @@ -163,46 +275,178 @@ func resourceVinsUpdate(ctx context.Context, d *schema.ResourceData, m interface // there was preexisting external net connection - disconnect ViNS _, err := c.DecortAPICall(ctx, "POST", VinsExtNetDisconnectAPI, extnetParams) if err != nil { - return diag.FromErr(err) + warnings.Add(err) } } if newExtNedId.(int) > 0 { // new external network connection requested - connect ViNS extnetParams.Add("netId", fmt.Sprintf("%d", newExtNedId.(int))) + extNetIp, ok := d.GetOk("ext_net_ip") + if ok && extNetIp.(string) != "" { + urlValues.Add("Ip", extNetIp.(string)) + } _, err := c.DecortAPICall(ctx, "POST", VinsExtNetConnectAPI, extnetParams) if err != nil { - return diag.FromErr(err) + warnings.Add(err) } } } - // we may reuse dataSourceVinsRead here as we maintain similarity - // between Compute resource and Compute data source schemas - return dataSourceVinsRead(ctx, d, m) -} + urlValues = &url.Values{} + if d.HasChange("ip") { + deletedIps := make([]interface{}, 0) + addedIps := make([]interface{}, 0) -func resourceVinsDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Debugf("resourceVinsDelete: called for ViNS ID / name %s / %s, Account ID %d, RG ID %d", - d.Id(), d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int)) + oldIpInterface, newIpInterface := d.GetChange("ip") + oldIpSlice := oldIpInterface.([]interface{}) + newIpSlice := newIpInterface.([]interface{}) + + 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 vinsFacts == "" { + if len(addedIps) > 0 { + for _, ipInterfase := range addedIps { + urlValues = &url.Values{} + ip := ipInterfase.(map[string]interface{}) + + urlValues.Add("vinsId", d.Id()) + urlValues.Add("type", ip["type"].(string)) + if ip["ip_addr"].(string) != "" { + urlValues.Add("ipAddr", ip["ip_addr"].(string)) + } + if ip["mac_addr"].(string) != "" { + urlValues.Add("mac", ip["mac_addr"].(string)) + } + if ip["compute_id"].(int) != 0 { + urlValues.Add("computeId", strconv.Itoa(ip["compute_id"].(int))) + } + _, err := c.DecortAPICall(ctx, "POST", VinsIpReserveAPI, urlValues) + if err != nil { + warnings.Add(err) + } + } + } + } + + if d.HasChange("nat_rule") { + deletedNatRules := make([]interface{}, 0) + addedNatRules := make([]interface{}, 0) + + oldNatRulesInterface, newNatRulesInterface := d.GetChange("nat_rule") + oldNatRulesSlice := oldNatRulesInterface.([]interface{}) + newNatRulesSlice := newNatRulesInterface.([]interface{}) + + for _, el := range oldNatRulesSlice { + if !isContinsNatRule(newNatRulesSlice, el) { + deletedNatRules = append(deletedNatRules, el) + } + } + + for _, el := range newNatRulesSlice { + if !isContinsNatRule(oldNatRulesSlice, el) { + addedNatRules = append(addedNatRules, el) + } + } + + if len(deletedNatRules) > 0 { + for _, natRuleInterface := range deletedNatRules { + urlValues = &url.Values{} + natRule := natRuleInterface.(map[string]interface{}) + + urlValues.Add("vinsId", d.Id()) + urlValues.Add("ruleId", strconv.Itoa(natRule["rule_id"].(int))) + log.Debug("NAT_RULE_DEL_WITH: ", urlValues.Encode()) + _, err := c.DecortAPICall(ctx, "POST", VinsNatRuleDelAPI, urlValues) + if err != nil { + warnings.Add(err) + } + } + } + + if len(addedNatRules) > 0 { + for _, natRuleInterface := range addedNatRules { + urlValues = &url.Values{} + natRule := natRuleInterface.(map[string]interface{}) + + urlValues.Add("vinsId", d.Id()) + urlValues.Add("intIp", natRule["int_ip"].(string)) + urlValues.Add("intPort", strconv.Itoa(natRule["int_port"].(int))) + urlValues.Add("extPortStart", strconv.Itoa(natRule["ext_port_start"].(int))) + if natRule["ext_port_end"].(int) != 0 { + urlValues.Add("extPortEnd", strconv.Itoa(natRule["ext_port_end"].(int))) + } + if natRule["proto"].(string) != "" { + urlValues.Add("proto", natRule["proto"].(string)) + } + + log.Debug("NAT_RULE_ADD_WITH: ", urlValues.Encode()) + _, err := c.DecortAPICall(ctx, "POST", VinsNatRuleAddAPI, urlValues) + if err != nil { + warnings.Add(err) + } + } + } + } + + if oldRestart, newRestart := d.GetChange("vnfdev_restart"); oldRestart == false && newRestart == true { + urlValues = &url.Values{} + urlValues.Add("vinsId", d.Id()) + _, err := c.DecortAPICall(ctx, "POST", VinsVnfdevRestartAPI, urlValues) if err != nil { - 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{} - params.Add("vinsId", d.Id()) - params.Add("force", "1") // disconnect all computes before deleting ViNS - params.Add("permanently", "1") // delete ViNS immediately bypassing recycle bin + if oldRedeploy, newRedeploy := d.GetChange("vnfdev_redeploy"); oldRedeploy == false && newRedeploy == true { + urlValues = &url.Values{} + urlValues.Add("vinsId", d.Id()) + _, err := c.DecortAPICall(ctx, "POST", VinsVnfdevRedeployAPI, urlValues) + if err != nil { + warnings.Add(err) + } + } + + defer resourceVinsRead(ctx, d, m) + return warnings.Get() +} +func resourceVinsDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + urlValues := &url.Values{} c := m.(*controller.ControllerCfg) - _, err = c.DecortAPICall(ctx, "POST", VinsDeleteAPI, params) + + urlValues.Add("vinsId", d.Id()) + urlValues.Add("force", strconv.FormatBool(d.Get("force").(bool))) + urlValues.Add("permanently", strconv.FormatBool(d.Get("permanently").(bool))) + _, err := c.DecortAPICall(ctx, "POST", VinsDeleteAPI, urlValues) if err != nil { return diag.FromErr(err) } @@ -210,74 +454,185 @@ func resourceVinsDelete(ctx context.Context, d *schema.ResourceData, m interface return nil } -func resourceVinsSchemaMake() map[string]*schema.Schema { - rets := map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringIsNotEmpty, - Description: "Name of the ViNS. Names are case sensitive and unique within the context of an account or resource group.", +func extNetSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "ext_net_id": { + Type: schema.TypeInt, + Default: 0, + Optional: true, + }, + "ext_net_ip": { + Type: schema.TypeInt, + Optional: true, + Default: "", }, + } +} - /* we do not need ViNS ID as an argument because if we already know this ID, it is not practical to call resource provider. - Resource Import will work anyway, as it obtains the ID of ViNS to be imported through another mechanism. - "vins_id": { - Type: schema.TypeInt, - Optional: true, - Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.", +func ipSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Required: true, }, - */ - - "rg_id": { - Type: schema.TypeInt, - Optional: true, - ForceNew: true, - Default: 0, - Description: "ID of the resource group, where this ViNS belongs to. Non-zero for ViNS created at resource group level, 0 otherwise.", + "ip_addr": { + Type: schema.TypeString, + Optional: true, }, - - "account_id": { - Type: schema.TypeInt, - Required: true, - ForceNew: true, - ValidateFunc: validation.IntAtLeast(1), - Description: "ID of the account, which this ViNS belongs to. For ViNS created at account level, resource group ID is 0.", + "mac_addr": { + Type: schema.TypeString, + Optional: true, }, - - "ext_net_id": { - Type: schema.TypeInt, - Required: true, - ValidateFunc: validation.IntAtLeast(0), - Description: "ID of the external network this ViNS is connected to. Pass 0 if no external connection required.", + "compute_id": { + Type: schema.TypeInt, + Optional: true, }, + } +} - "ipcidr": { - Type: schema.TypeString, - Optional: true, - DiffSuppressFunc: ipcidrDiffSupperss, - Description: "Network address to use by this ViNS. This parameter is only valid when creating new ViNS.", +func natRuleSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "int_ip": { + Type: schema.TypeString, + Optional: true, + Computed: true, }, - - "description": { - Type: schema.TypeString, - Optional: true, - Default: "", - Description: "Optional user-defined text description of this ViNS.", + "int_port": { + Type: schema.TypeInt, + Optional: true, + Computed: true, }, - - // the rest of attributes are computed - "account_name": { - Type: schema.TypeString, - Computed: true, - Description: "Name of the account, which this ViNS belongs to.", + "ext_port_start": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "ext_port_end": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "proto": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"tcp", "udp"}, false), + Computed: true, + }, + "rule_id": { + Type: schema.TypeInt, + Computed: true, }, + } +} - "ext_ip_addr": { - Type: schema.TypeString, - Computed: true, - Description: "IP address of the external connection (valid for ViNS connected to external network, ignored otherwise).", +func resourceVinsSchemaMake() map[string]*schema.Schema { + rets := dataSourceVinsSchemaMake() + rets["name"] = &schema.Schema{ + Type: schema.TypeString, + Required: true, + } + rets["rg_id"] = &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + } + rets["account_id"] = &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + Computed: true, + } + rets["ext_net_id"] = &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + Default: -1, + } + rets["ipcidr"] = &schema.Schema{ + Type: schema.TypeString, + Optional: true, + } + rets["ext_ip_addr"] = &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Default: "", + } + rets["pre_reservations_num"] = &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + Default: 32, + } + rets["gid"] = &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + Computed: true, + } + rets["enable"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: true, + } + rets["permanently"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: false, + } + rets["force"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: false, + } + rets["ext_net"] = &schema.Schema{ + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: extNetSchemaMake(), + }, + } + rets["ip"] = &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: ipSchemaMake(), + }, + } + rets["nat_rule"] = &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: natRuleSchemaMake(), }, } + rets["desc"] = &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Default: "", + Description: "Optional user-defined text description of this ViNS.", + } + rets["ext_ip_addr"] = &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "IP address of the external connection (valid for ViNS connected to external network, ignored otherwise).", + } + rets["restore"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: false, + } + rets["vnfdev_restart"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: false, + } + rets["vnfdev_redeploy"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: false, + } + + 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 } diff --git a/internal/service/cloudapi/vins/utility_vins.go b/internal/service/cloudapi/vins/utility_vins.go index a53ea85..7c17c76 100644 --- a/internal/service/cloudapi/vins/utility_vins.go +++ b/internal/service/cloudapi/vins/utility_vins.go @@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Authors: Petr Krutov, Stanislav Solovev, +Kasim Baybikov, Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -34,120 +35,48 @@ package vins import ( "context" "encoding/json" - "fmt" "net/url" "strconv" "github.com/rudecs/terraform-provider-decort/internal/controller" - log "github.com/sirupsen/logrus" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -// On success this function returns a string, as returned by API vins/get, which could be unmarshalled -// into VinsGetResp structure -func utilityVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) { - // This function tries to locate ViNS by one of the following algorithms depending - // on the parameters passed: - // - if resource group ID is specified -> it looks for a ViNS at the RG level - // - if account ID is specifeid -> it looks for a ViNS at the account level - // - // If succeeded, it returns non empty string that contains JSON formatted facts about the - // ViNS as returned by vins/get API call. - // Otherwise it returns empty string and a meaningful error. - // - // This function does not modify its ResourceData argument, so it is safe to use it as core - // method for the Terraform resource Exists method. - // - +func utilityDataVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*VINSDetailed, error) { c := m.(*controller.ControllerCfg) urlValues := &url.Values{} + vins := &VINSDetailed{} - // make it possible to use "read" & "check presence" functions with ViNS ID set so - // that Import of ViNS resource is possible - idSet := false - theId, err := strconv.Atoi(d.Id()) - if err != nil || theId <= 0 { - vinsId, argSet := d.GetOk("vins_id") // NB: vins_id is NOT present in vinsResource schema! - if argSet { - theId = vinsId.(int) - idSet = true - } - } else { - idSet = true + urlValues.Add("vinsId", strconv.Itoa(d.Get("vins_id").(int))) + vinsRaw, err := c.DecortAPICall(ctx, "POST", VinsGetAPI, urlValues) + if err != nil { + return nil, err } - if idSet { - // ViNS ID is specified, try to get compute instance straight by this ID - log.Debugf("utilityVinsCheckPresence: locating ViNS by its ID %d", theId) - urlValues.Add("vinsId", fmt.Sprintf("%d", theId)) - vinsFacts, err := c.DecortAPICall(ctx, "POST", VinsGetAPI, urlValues) - if err != nil { - return "", err - } - return vinsFacts, nil + err = json.Unmarshal([]byte(vinsRaw), vins) + if err != nil { + return nil, err } + 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") - if accountSet { - log.Debugf("utilityVinsCheckPresence: limiting ViNS search to Account ID %d", accountId.(int)) - urlValues.Add("accountId", fmt.Sprintf("%d", accountId.(int))) - } +func utilityVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*VINSDetailed, error) { + c := m.(*controller.ControllerCfg) + urlValues := &url.Values{} + 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 { - return "", err + return nil, err } - // log.Debugf("%s", apiResp) - // log.Debugf("utilityResgroupCheckPresence: ready to decode response body from %s", VinsSearchAPI) - model := VinsSearchResp{} - err = json.Unmarshal([]byte(apiResp), &model) + err = json.Unmarshal([]byte(vinsRaw), vins) if err != nil { - return "", err - } - - 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 nil, err } + return vins, nil - return "", fmt.Errorf("Cannot find ViNS name %s. Check name and/or RG ID & Account ID and your access rights", vinsName.(string)) } diff --git a/internal/service/cloudapi/vins/utility_vins_audits.go b/internal/service/cloudapi/vins/utility_vins_audits.go new file mode 100644 index 0000000..d01a821 --- /dev/null +++ b/internal/service/cloudapi/vins/utility_vins_audits.go @@ -0,0 +1,61 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +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 +} diff --git a/internal/service/cloudapi/vins/utility_vins_ext_net_list.go b/internal/service/cloudapi/vins/utility_vins_ext_net_list.go new file mode 100644 index 0000000..b95c048 --- /dev/null +++ b/internal/service/cloudapi/vins/utility_vins_ext_net_list.go @@ -0,0 +1,61 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +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 +} diff --git a/internal/service/cloudapi/vins/utility_vins_ip_list.go b/internal/service/cloudapi/vins/utility_vins_ip_list.go new file mode 100644 index 0000000..3a0f159 --- /dev/null +++ b/internal/service/cloudapi/vins/utility_vins_ip_list.go @@ -0,0 +1,61 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +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 +} diff --git a/internal/service/cloudapi/vins/utility_vins_list.go b/internal/service/cloudapi/vins/utility_vins_list.go index 4746f23..b834b6f 100644 --- a/internal/service/cloudapi/vins/utility_vins_list.go +++ b/internal/service/cloudapi/vins/utility_vins_list.go @@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Authors: Petr Krutov, Stanislav Solovev, +Kasim Baybikov, Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -43,8 +44,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (VinsList, error) { - vinsList := VinsList{} +func utilityVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (VINSList, error) { + vinsList := VINSList{} c := m.(*controller.ControllerCfg) urlValues := &url.Values{} diff --git a/internal/service/cloudapi/vins/utility_vins_list_deleted.go b/internal/service/cloudapi/vins/utility_vins_list_deleted.go new file mode 100644 index 0000000..93d9f7a --- /dev/null +++ b/internal/service/cloudapi/vins/utility_vins_list_deleted.go @@ -0,0 +1,70 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +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 +} diff --git a/internal/service/cloudapi/vins/utility_vins_nat_rule_list.go b/internal/service/cloudapi/vins/utility_vins_nat_rule_list.go new file mode 100644 index 0000000..6aa9950 --- /dev/null +++ b/internal/service/cloudapi/vins/utility_vins_nat_rule_list.go @@ -0,0 +1,61 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +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 +} diff --git a/internal/status/status.go b/internal/status/status.go index 6459dc0..e5c2193 100644 --- a/internal/status/status.go +++ b/internal/status/status.go @@ -1,3 +1,35 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://github.com/rudecs/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://github.com/rudecs/terraform-provider-decort/wiki +*/ + package status type Status = string @@ -12,22 +44,26 @@ var ( // Status available for: // - Compute // - Disk + // - Vins Enabled Status = "ENABLED" // Enabling in process // Status available for: // - Disk + // - Vins Enabling Status = "ENABLING" // An object disabled for operations // Status available for: // - Compute // - Disk + // - Vins Disabled Status = "DISABLED" // Disabling in process // Status available for: // - Disk + // - Vins Disabling Status = "DISABLING" // An object model has been created in the database @@ -35,6 +71,7 @@ var ( // - Image // - Disk // - Compute + // - Vins Modeled Status = "MODELED" // In the process of creation @@ -47,6 +84,7 @@ var ( // - Image // - Disk // - Compute + // - Vins Created Status = "CREATED" // Physical resources are allocated for the object @@ -63,6 +101,7 @@ var ( // Status available for: // - Disk // - Compute + // - Vins Destroying Status = "DESTROYING" // Permanently deleted @@ -70,16 +109,19 @@ var ( // - Image // - Disk // - Compute + // - Vins Destroyed Status = "DESTROYED" // Deleting in progress to Trash // Status available for: // - Compute + // - Vins Deleting Status = "DELETING" // Deleted to Trash // Status available for: // - Compute + // - Vins Deleted Status = "DELETED" // Deleted from storage @@ -91,4 +133,9 @@ var ( // Status available for: // - Compute Redeploying Status = "REDEPLOYING" + + // The resource is not bound to vnf device + // Status available for: + // - vins vnf + Stashed Status = "STASHED" ) diff --git a/internal/techstatus/techstatus.go b/internal/techstatus/techstatus.go index 661d1fd..cf25850 100644 --- a/internal/techstatus/techstatus.go +++ b/internal/techstatus/techstatus.go @@ -1,3 +1,35 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://github.com/rudecs/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://github.com/rudecs/terraform-provider-decort/wiki +*/ + package techstatus type TechStatus = string diff --git a/provider.tf b/provider.tf index 0f556df..c57af65 100644 --- a/provider.tf +++ b/provider.tf @@ -2,7 +2,7 @@ terraform { required_providers { decort = { source = "digitalenergy.online/decort/decort" - version = "3.2.2" + version = "3.3.0" } } } diff --git a/samples/cloudapi/data_k8s/main.tf b/samples/cloudapi/data_k8s/main.tf new file mode 100644 index 0000000..29722c3 --- /dev/null +++ b/samples/cloudapi/data_k8s/main.tf @@ -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 = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_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 +} diff --git a/samples/cloudapi/data_k8s_list/main.tf b/samples/cloudapi/data_k8s_list/main.tf new file mode 100644 index 0000000..d404cc6 --- /dev/null +++ b/samples/cloudapi/data_k8s_list/main.tf @@ -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 = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_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 +} diff --git a/samples/cloudapi/data_k8s_list_deleted/main.tf b/samples/cloudapi/data_k8s_list_deleted/main.tf new file mode 100644 index 0000000..831c873 --- /dev/null +++ b/samples/cloudapi/data_k8s_list_deleted/main.tf @@ -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 = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_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 +} + diff --git a/samples/cloudapi/data_k8s_wg/main.tf b/samples/cloudapi/data_k8s_wg/main.tf new file mode 100644 index 0000000..06160b0 --- /dev/null +++ b/samples/cloudapi/data_k8s_wg/main.tf @@ -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 = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_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 +} diff --git a/samples/cloudapi/data_k8s_wg_list/main.tf b/samples/cloudapi/data_k8s_wg_list/main.tf new file mode 100644 index 0000000..de6d8ee --- /dev/null +++ b/samples/cloudapi/data_k8s_wg_list/main.tf @@ -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 = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_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 +} diff --git a/samples/cloudapi/data_vins/main.tf b/samples/cloudapi/data_vins/main.tf new file mode 100644 index 0000000..479590b --- /dev/null +++ b/samples/cloudapi/data_vins/main.tf @@ -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 = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_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 +} diff --git a/samples/cloudapi/data_vins_audits/main.tf b/samples/cloudapi/data_vins_audits/main.tf new file mode 100644 index 0000000..328c8e8 --- /dev/null +++ b/samples/cloudapi/data_vins_audits/main.tf @@ -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 = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_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 +} diff --git a/samples/cloudapi/data_vins_ext_net_list/main.tf b/samples/cloudapi/data_vins_ext_net_list/main.tf new file mode 100644 index 0000000..14c7e6a --- /dev/null +++ b/samples/cloudapi/data_vins_ext_net_list/main.tf @@ -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 = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_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 +} diff --git a/samples/cloudapi/data_vins_ip_list/main.tf b/samples/cloudapi/data_vins_ip_list/main.tf new file mode 100644 index 0000000..387ec12 --- /dev/null +++ b/samples/cloudapi/data_vins_ip_list/main.tf @@ -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 = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_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 +} + diff --git a/samples/cloudapi/data_vins_list_deleted/main.tf b/samples/cloudapi/data_vins_list_deleted/main.tf new file mode 100644 index 0000000..2b784eb --- /dev/null +++ b/samples/cloudapi/data_vins_list_deleted/main.tf @@ -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 = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_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 +} diff --git a/samples/cloudapi/data_vins_nat_rule_list/main.tf b/samples/cloudapi/data_vins_nat_rule_list/main.tf new file mode 100644 index 0000000..15736e6 --- /dev/null +++ b/samples/cloudapi/data_vins_nat_rule_list/main.tf @@ -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 = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_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 +} + diff --git a/samples/cloudapi/resource_vins/main.tf b/samples/cloudapi/resource_vins/main.tf new file mode 100644 index 0000000..2d5b440 --- /dev/null +++ b/samples/cloudapi/resource_vins/main.tf @@ -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 = + controller_url = "https://mr4.digitalenergy.online" + #oauth2_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 +}