From 105273af4844085568402af634a4ab96ae0ec69c Mon Sep 17 00:00:00 2001 From: Sergey Shubin svs1370 Date: Fri, 8 Oct 2021 12:17:53 +0300 Subject: [PATCH] Implement more robust create and delete methods for PFW --- decort/data_source_pfw.go | 20 +++++++++++++++++++- decort/resource_compute.go | 1 + decort/resource_pfw.go | 16 +++++++++------- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/decort/data_source_pfw.go b/decort/data_source_pfw.go index be810a5..dafb73c 100644 --- a/decort/data_source_pfw.go +++ b/decort/data_source_pfw.go @@ -33,7 +33,6 @@ import ( func flattenPfw(d *schema.ResourceData, pfwFacts string) error { // NOTE: this function modifies ResourceData argument - as such it should never be called // from resourcePfwExists(...) method - // log.Debugf("flattenPfw: ready to decode response body from API %s", pfwFacts) pfwRecord := ComputePfwListResp{} err := json.Unmarshal([]byte(pfwFacts), &pfwRecord) if err != nil { @@ -44,6 +43,25 @@ func flattenPfw(d *schema.ResourceData, pfwFacts string) error { len(pfwRecord.Rules), pfwRecord.Header.VinsID, pfwRecord.Header.VinsID) /* + Here it gets a little bit interesting. + Unlike compute or disk, port forwaring rules are NOT represented by any cloud + platform resource, which might have had a unique ID. They are just a subset of + rules in the list maintained by the corresponding ViNS instance. However, + Terraform needs a unique ID for each resource it manages so that it could be + stored in the state file and retrieved for use. + + Therefore we need to make up an ID and supply it to Terraform in a standard + way (i.e. by calling d.SetId(...)). + + Fortunately, a combination of Compute ID and ViNS ID with GW VNF, where this + compute is plugged in, makes a unique string, so we use it as an ID for + the PFW ruleset. + + The following few lines are legacy from the first attempt to make an ID + as a hash of concatenated Compute ID & ViNS ID, but it did not work as + expected for a number of reasons, which explanation is not a primary + intent of the comment in the source code. + combo := fmt.Sprintf("%d:%d", compId.(int), pfwRecord.ViNS.VinsID) hasher := fnv.New32a() hasher.Write([]byte(combo)) diff --git a/decort/resource_compute.go b/decort/resource_compute.go index 3e8733c..edc04ee 100644 --- a/decort/resource_compute.go +++ b/decort/resource_compute.go @@ -186,6 +186,7 @@ func resourceComputeRead(d *schema.ResourceData, m interface{}) error { compFacts, err := utilityComputeCheckPresence(d, m) if compFacts == "" { + d.SetId("") if err != nil { return err } diff --git a/decort/resource_pfw.go b/decort/resource_pfw.go index 5021932..0f19673 100644 --- a/decort/resource_pfw.go +++ b/decort/resource_pfw.go @@ -31,7 +31,7 @@ import ( func resourcePfwCreate(d *schema.ResourceData, m interface{}) error { compId := d.Get("compute_id") - rules_set, ok := d.GetOk("rules") + rules_set, ok := d.GetOk("rule") if !ok || rules_set.(*schema.Set).Len() == 0 { log.Debugf("resourcePfwCreate: empty new PFW rules set requested for compute ID %d - nothing to create", compId.(int)) return nil @@ -74,7 +74,7 @@ func resourcePfwCreate(d *schema.ResourceData, m interface{}) error { return lastSavedError } - return nil + return resourcePfwRead(d, m) } func resourcePfwRead(d *schema.ResourceData, m interface{}) error { @@ -94,14 +94,16 @@ func resourcePfwUpdate(d *schema.ResourceData, m interface{}) error { // TODO: update not implemented yet compId := d.Get("compute_id") return fmt.Errorf("resourcePfwUpdate: method is not implemented yet (Compute ID %d)", compId.(int)) + + // return resourcePfwRead(d, m) } func resourcePfwDelete(d *schema.ResourceData, m interface{}) error { compId := d.Get("compute_id") - rules_set, ok := d.GetOk("rules") + rules_set, ok := d.GetOk("rule") if !ok || rules_set.(*schema.Set).Len() == 0 { - log.Debugf("resourcePfwCreate: no PFW rules defined for compute ID %d - nothing to delete", compId.(int)) + log.Debugf("resourcePfwDelete: no PFW rules defined for compute ID %d - nothing to delete", compId.(int)) return nil } @@ -116,16 +118,16 @@ func resourcePfwDelete(d *schema.ResourceData, m interface{}) error { rule := runner.(map[string]interface{}) params := &url.Values{} params.Add("computeId", fmt.Sprintf("%d", compId.(int))) - params.Add("ruleId", fmt.Sprintf("%d", rule["id"].(int))) + params.Add("ruleId", fmt.Sprintf("%d", rule["rule_id"].(int))) log.Debugf("resourcePfwCreate: ready to delete rule ID%s (%d:%d -> %d %s) from Compute ID %d", - rule["id"].(int), + rule["rule_id"].(int), rule["pub_port_start"].(int),rule["pub_port_end"].(int), rule["local_port"].(int), rule["proto"].(string), compId.(int)) _, err, _ := controller.decortAPICall("POST", ComputePfwDelAPI, params) if err != nil { log.Errorf("resourcePfwDelete: error deleting rule ID %d (%d:%d -> %d %s) from Compute ID %d: %s", - rule["id"].(int), + rule["rule_id"].(int), rule["pub_port_start"].(int),rule["pub_port_end"].(int), rule["local_port"].(int), rule["proto"].(string), compId.(int),