From b08d688c0db4f08427c88a6de693104635241446 Mon Sep 17 00:00:00 2001 From: Sergey Shubin svs1370 Date: Wed, 17 Mar 2021 14:24:36 +0300 Subject: [PATCH] ViNS data source implemented --- decort/data_source_vins.go | 55 +++++++++++++++++++++++++++----------- decort/models_api.go | 5 ++-- decort/provider.go | 2 +- decort/utility_vins.go | 5 ++-- 4 files changed, 46 insertions(+), 21 deletions(-) diff --git a/decort/data_source_vins.go b/decort/data_source_vins.go index 80876ea..33449cd 100644 --- a/decort/data_source_vins.go +++ b/decort/data_source_vins.go @@ -40,26 +40,49 @@ import ( func flattenVins(d *schema.ResourceData, vins_facts string) error { // 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") - details := VinsGetResp{} - err := json.Unmarshal([]byte(vins_facts), &details) + log.Debugf("flattenVins: ready to decode response body from API %s", vins_facts) + vinsRecord := VinsRecord{} + err := json.Unmarshal([]byte(vins_facts), &vinsRecord) if err != nil { return err } log.Debugf("flattenVins: decoded ViNS name:ID %s:%d, account ID %d, RG ID %d", - details.Name, details.ID, details.AccountID, details.RgID) - - d.SetId(fmt.Sprintf("%d", details.ID)) - d.Set("rg_id", details.ID) - d.Set("name", details.Name) - d.Set("account_name", details.AccountName) - d.Set("account_id", details.AccountID) - d.Set("grid_id", details.GridID) - d.Set("description", details.Desc) - d.Set("status", details.Status) - d.Set("def_net_type", details.DefaultNetType) - d.Set("def_net_id", details.DefaultNetID) + vinsRecord.Name, vinsRecord.ID, vinsRecord.AccountID, vinsRecord.RgID) + + d.SetId(fmt.Sprintf("%d", vinsRecord.ID)) + d.Set("account_id", fmt.Sprintf("%d", vinsRecord.AccountID)) + d.Set("account_name", vinsRecord.AccountName) + d.Set("rg_id", fmt.Sprintf("%d", vinsRecord.RgID)) + d.Set("description", vinsRecord.Desc) + d.Set("ipcidr", vinsRecord.IPCidr) + + 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 { + d.Set("ext_ip_addr", extNetIP.(string)) + d.Set("ext_net_id", fmt.Sprintf("%d", int(extNetID.(float64)))) + log.Debugf("flattenVins: ViNS ext_net_id=%d, ext_net_ip=%s", int(extNetID.(float64)), extNetIP.(string)) + } else { + return fmt.Errorf("Failed to unmarshal VNF GW Config - structure is invalid.") + } + + /* log.Debugf("flattenVins: ready to decode Config string %s", value.Config) + vnfRec := &VnfGwConfigRecord{} + err = json.Unmarshal([]byte(value.Config), vnfRec) + if err != nil { + return err + } + d.Set("ext_ip_addr", vnfRec.ExtNetIP) + d.Set("ext_net_id", fmt.Sprintf("%d", vnfRec.ExtNetID)) + log.Debugf("flattenVins: ViNS ext_net_id=%d, ext_net_ip=%s", vnfRec.ExtNetID, vnfRec.ExtNetIP) + */ + break + } + } return nil } @@ -142,7 +165,7 @@ func dataSourceVins() *schema.Resource { "ipcidr": { Type: schema.TypeString, Computed: true, - Description: "Network address used by this ViNS." + Description: "Network address used by this ViNS.", }, }, } diff --git a/decort/models_api.go b/decort/models_api.go index 9435285..ef19c5d 100644 --- a/decort/models_api.go +++ b/decort/models_api.go @@ -521,10 +521,10 @@ type VnfRecord struct { ID int `json:"id"` AccountID int `json:"accountId"` Type string `json:"type"` // "DHCP", "NAT", "GW" etc - Config string `json:"config"` // NOTE: VNF specs vary by VNF type + Config map[string]interface{} `json:"config"` // NOTE: VNF specs vary by VNF type } -type VnfGwConfigRecord struct { // describes GW VNF config structure +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"` @@ -541,6 +541,7 @@ type VinsRecord struct { // represents part of the response from API vins/get RgID int `json:"rgid"` RgName string `json:"rgName"` VNFs map[string]VnfRecord `json:"vnfs"` + Desc string `json:"desc"` } const VinsGetAPI = "/restmachine/cloudapi/vins/get" diff --git a/decort/provider.go b/decort/provider.go index 060f0c1..ae34136 100644 --- a/decort/provider.go +++ b/decort/provider.go @@ -112,7 +112,7 @@ func Provider() *schema.Provider { "decort_kvmvm": dataSourceCompute(), "decort_image": dataSourceImage(), "decort_disk": dataSourceDisk(), - // "decort_vins": dataSourceVins(), + "decort_vins": dataSourceVins(), // "decort_pfw": dataSourcePfw(), }, diff --git a/decort/utility_vins.go b/decort/utility_vins.go index ce93dfd..22c3680 100644 --- a/decort/utility_vins.go +++ b/decort/utility_vins.go @@ -81,6 +81,7 @@ func utilityVinsCheckPresence(d *schema.ResourceData, m interface{}) (string, er 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: locating ViNS %s", vinsName.(string)) rgId, rgSet := d.GetOk("rg_id") @@ -124,11 +125,11 @@ func utilityVinsCheckPresence(d *schema.ResourceData, m interface{}) (string, er // 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)) - apiResp, err = controller.decortAPICall("POST", VinsGetAPI, rqValues) + vinsGetResp, err := controller.decortAPICall("POST", VinsGetAPI, rqValues) if err != nil { return "", err } - return apiResp, nil + return vinsGetResp, nil } }