diff --git a/README-BULK.md b/README-BULK.md new file mode 100644 index 000000000..661ccab53 --- /dev/null +++ b/README-BULK.md @@ -0,0 +1,32 @@ +# Added BULK mode to BD and EPG + +- **Branch source: v2.7.0** +- **Goal: improve Create, Read and Update performance for Bridge Domain and Endpoint Group resources** + +This code adds BULK mode to the CREATE, READ, and UPDATE operations for Bridge Domain and Endpoint Group resources. + +BULK mode refers to the ability to CREATE, READ and UPDATE the available relationships for the above resources in a single bulk operation instead of one at a time. + +This brings absolute performance increases in the READ operation, performance increases proportional to the number of relations involved in the CREATE and UPDATE operations. + +The BULK mode can be enabled operation by operation resource by resource, to facilitate debugging and allow for a correct evaluation of performance while still having the traditional operating mode by default. + + +## Added examples for BULK operations + +In the files bd.tf, epg.tf, bd1.tf.ste, bd2.tf.ste, epg1.tf.ste, epg2.tf.ste, available in the directory examples/bulk, configure the Terrafom Meta-Argument consistently with your strategy (we tested the performance of BULK operations by setting instead of the default ). + +There are two families of tests, with the purpose of modifying the parameters to test the BULK update operation. + +The t1-test-suite.sh and t2-test-suite.sh scripts reconfigure the environment with the corresponding test family. + +The run.sh script runs the selected test suite, the plan.sh script runs the scheduling (mainly used to check the performance of BULK Read operations). + +Both scripts report the start time and end time automatically. + + +## Warnings + +This plugin adds the bulk operations fields to Terraform's state file. + +Bulk operations are experimental, be careful using them in production setups. diff --git a/aci/resource_aci_fvaepg.go b/aci/resource_aci_fvaepg.go index 4be67142c..7940acf5f 100644 --- a/aci/resource_aci_fvaepg.go +++ b/aci/resource_aci_fvaepg.go @@ -225,6 +225,21 @@ func resourceAciApplicationEPG() *schema.Resource { Optional: true, Set: schema.HashString, }, + "bulk_create": &schema.Schema{ + Type: schema.TypeBool, + + Optional: true, + }, + "bulk_read": &schema.Schema{ + Type: schema.TypeBool, + + Optional: true, + }, + "bulk_update": &schema.Schema{ + Type: schema.TypeBool, + + Optional: true, + }, }), } } @@ -306,7 +321,15 @@ func resourceAciApplicationEPGImport(d *schema.ResourceData, m interface{}) ([]* } func resourceAciApplicationEPGCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Printf("[DEBUG] ApplicationEPG: Beginning Creation") + if _, ok := d.GetOk("bulk_create"); ok { + return resourceAciApplicationEPGCreateBulk(ctx, d, m) + } else { + return resourceAciApplicationEPGCreateOrig(ctx, d, m) + } +} + +func resourceAciApplicationEPGCreateBulk(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Printf("[DEBUG] ApplicationEPG: Beginning Bulk Creation") aciClient := m.(*client.Client) desc := d.Get("description").(string) @@ -450,184 +473,1187 @@ func resourceAciApplicationEPGCreate(ctx context.Context, d *schema.ResourceData checkDns = append(checkDns, relationParam) } - if relationTofvRsIntraEpg, ok := d.GetOk("relation_fv_rs_intra_epg"); ok { - relationParamList := toStringList(relationTofvRsIntraEpg.(*schema.Set).List()) - for _, relationParam := range relationParamList { - checkDns = append(checkDns, relationParam) + if relationTofvRsIntraEpg, ok := d.GetOk("relation_fv_rs_intra_epg"); ok { + relationParamList := toStringList(relationTofvRsIntraEpg.(*schema.Set).List()) + for _, relationParam := range relationParamList { + checkDns = append(checkDns, relationParam) + } + } + + d.Partial(true) + err = checkTDn(aciClient, checkDns) + if err != nil { + return diag.FromErr(err) + } + d.Partial(false) + + var fvRsAllData [][]byte + var fvRs []byte + + if relationTofvRsBd, ok := d.GetOk("relation_fv_rs_bd"); ok { + relationParam := relationTofvRsBd.(string) + relationParamName := GetMOName(relationParam) + /* + err = aciClient.CreateRelationfvRsBdFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsBdFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + fvRsAllData = append(fvRsAllData, fvRs) + } + if relationTofvRsCustQosPol, ok := d.GetOk("relation_fv_rs_cust_qos_pol"); ok { + relationParam := relationTofvRsCustQosPol.(string) + relationParamName := GetMOName(relationParam) + /* + err = aciClient.CreateRelationfvRsCustQosPolFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsCustQosPolFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + fvRsAllData = append(fvRsAllData, fvRs) + } + if relationTofvRsFcPathAtt, ok := d.GetOk("relation_fv_rs_fc_path_att"); ok { + relationParamList := toStringList(relationTofvRsFcPathAtt.(*schema.Set).List()) + for _, relationParam := range relationParamList { + /* + err = aciClient.CreateRelationfvRsFcPathAttFromApplicationEPG(fvAEPg.DistinguishedName, relationParam) + + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsFcPathAttFromApplicationEPG(fvAEPg.DistinguishedName, relationParam) + fvRsAllData = append(fvRsAllData, fvRs) + } + } + if relationTofvRsProv, ok := d.GetOk("relation_fv_rs_prov"); ok { + relationParamList := toStringList(relationTofvRsProv.(*schema.Set).List()) + for _, relationParam := range relationParamList { + relationParamName := GetMOName(relationParam) + /* + err = aciClient.CreateRelationfvRsProvFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsProvFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + fvRsAllData = append(fvRsAllData, fvRs) + } + } + if relationTofvRsConsIf, ok := d.GetOk("relation_fv_rs_cons_if"); ok { + relationParamList := toStringList(relationTofvRsConsIf.(*schema.Set).List()) + for _, relationParam := range relationParamList { + relationParamName := GetMOName(relationParam) + /* + err = aciClient.CreateRelationfvRsConsIfFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsConsIfFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + fvRsAllData = append(fvRsAllData, fvRs) + } + } + if relationTofvRsSecInherited, ok := d.GetOk("relation_fv_rs_sec_inherited"); ok { + relationParamList := toStringList(relationTofvRsSecInherited.(*schema.Set).List()) + for _, relationParam := range relationParamList { + /* + err = aciClient.CreateRelationfvRsSecInheritedFromApplicationEPG(fvAEPg.DistinguishedName, relationParam) + + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsSecInheritedFromApplicationEPG(fvAEPg.DistinguishedName, relationParam) + fvRsAllData = append(fvRsAllData, fvRs) + } + } + if relationTofvRsNodeAtt, ok := d.GetOk("relation_fv_rs_node_att"); ok { + relationParamList := toStringList(relationTofvRsNodeAtt.(*schema.Set).List()) + for _, relationParam := range relationParamList { + /* + err = aciClient.CreateRelationfvRsNodeAttFromApplicationEPG(fvAEPg.DistinguishedName, relationParam) + + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsNodeAttFromApplicationEPG(fvAEPg.DistinguishedName, relationParam) + fvRsAllData = append(fvRsAllData, fvRs) + } + } + if relationTofvRsDppPol, ok := d.GetOk("relation_fv_rs_dpp_pol"); ok { + relationParam := relationTofvRsDppPol.(string) + relationParamName := GetMOName(relationParam) + /* + err = aciClient.CreateRelationfvRsDppPolFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsDppPolFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + fvRsAllData = append(fvRsAllData, fvRs) + } + if relationTofvRsCons, ok := d.GetOk("relation_fv_rs_cons"); ok { + relationParamList := toStringList(relationTofvRsCons.(*schema.Set).List()) + for _, relationParam := range relationParamList { + relationParamName := GetMOName(relationParam) + /* + err = aciClient.CreateRelationfvRsConsFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsConsFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + fvRsAllData = append(fvRsAllData, fvRs) + } + } + if relationTofvRsProvDef, ok := d.GetOk("relation_fv_rs_prov_def"); ok { + relationParamList := toStringList(relationTofvRsProvDef.(*schema.Set).List()) + for _, relationParam := range relationParamList { + /* + err = aciClient.CreateRelationfvRsProvDefFromApplicationEPG(fvAEPg.DistinguishedName, relationParam) + + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsProvDefFromApplicationEPG(fvAEPg.DistinguishedName, relationParam) + fvRsAllData = append(fvRsAllData, fvRs) + } + } + if relationTofvRsTrustCtrl, ok := d.GetOk("relation_fv_rs_trust_ctrl"); ok { + relationParam := relationTofvRsTrustCtrl.(string) + relationParamName := GetMOName(relationParam) + /* + err = aciClient.CreateRelationfvRsTrustCtrlFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsTrustCtrlFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + fvRsAllData = append(fvRsAllData, fvRs) + } + if relationTofvRsPathAtt, ok := d.GetOk("relation_fv_rs_path_att"); ok { + relationParamList := toStringList(relationTofvRsPathAtt.(*schema.Set).List()) + for _, relationParam := range relationParamList { + /* + err = aciClient.CreateRelationfvRsPathAttFromApplicationEPG(fvAEPg.DistinguishedName, relationParam) + + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsPathAttFromApplicationEPG(fvAEPg.DistinguishedName, relationParam) + fvRsAllData = append(fvRsAllData, fvRs) + } + } + if relationTofvRsProtBy, ok := d.GetOk("relation_fv_rs_prot_by"); ok { + relationParamList := toStringList(relationTofvRsProtBy.(*schema.Set).List()) + for _, relationParam := range relationParamList { + relationParamName := GetMOName(relationParam) + /* + err = aciClient.CreateRelationfvRsProtByFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsProtByFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + fvRsAllData = append(fvRsAllData, fvRs) + } + } + if relationTofvRsAEPgMonPol, ok := d.GetOk("relation_fv_rs_aepg_mon_pol"); ok { + relationParam := relationTofvRsAEPgMonPol.(string) + relationParamName := GetMOName(relationParam) + /* + err = aciClient.CreateRelationfvRsAEPgMonPolFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsAEPgMonPolFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + fvRsAllData = append(fvRsAllData, fvRs) + } + if relationTofvRsIntraEpg, ok := d.GetOk("relation_fv_rs_intra_epg"); ok { + relationParamList := toStringList(relationTofvRsIntraEpg.(*schema.Set).List()) + for _, relationParam := range relationParamList { + relationParamName := GetMOName(relationParam) + /* + err = aciClient.CreateRelationfvRsIntraEpgFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsIntraEpgFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + fvRsAllData = append(fvRsAllData, fvRs) + } + } + + if len(fvRsAllData) > 0 { + err = aciClient.RenderRelationfvRsAllFromApplicationEPG(fvAEPg, fvRsAllData) + if err != nil { + return diag.FromErr(err) + } + } + + d.SetId(fvAEPg.DistinguishedName) + log.Printf("[DEBUG] %s: Bulk Creation finished successfully", d.Id()) + + return resourceAciApplicationEPGRead(ctx, d, m) +} + +func resourceAciApplicationEPGCreateOrig(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Printf("[DEBUG] ApplicationEPG: Beginning Creation") + aciClient := m.(*client.Client) + desc := d.Get("description").(string) + + name := d.Get("name").(string) + + ApplicationProfileDn := d.Get("application_profile_dn").(string) + + fvAEPgAttr := models.ApplicationEPGAttributes{} + if Annotation, ok := d.GetOk("annotation"); ok { + fvAEPgAttr.Annotation = Annotation.(string) + } else { + fvAEPgAttr.Annotation = "{}" + } + if ExceptionTag, ok := d.GetOk("exception_tag"); ok { + fvAEPgAttr.ExceptionTag = ExceptionTag.(string) + } + if FloodOnEncap, ok := d.GetOk("flood_on_encap"); ok { + fvAEPgAttr.FloodOnEncap = FloodOnEncap.(string) + } + if FwdCtrl, ok := d.GetOk("fwd_ctrl"); ok { + fvAEPgAttr.FwdCtrl = FwdCtrl.(string) + } + if HasMcastSource, ok := d.GetOk("has_mcast_source"); ok { + fvAEPgAttr.HasMcastSource = HasMcastSource.(string) + } + if IsAttrBasedEPg, ok := d.GetOk("is_attr_based_epg"); ok { + fvAEPgAttr.IsAttrBasedEPg = IsAttrBasedEPg.(string) + } + if MatchT, ok := d.GetOk("match_t"); ok { + fvAEPgAttr.MatchT = MatchT.(string) + } + if NameAlias, ok := d.GetOk("name_alias"); ok { + fvAEPgAttr.NameAlias = NameAlias.(string) + } + if PcEnfPref, ok := d.GetOk("pc_enf_pref"); ok { + fvAEPgAttr.PcEnfPref = PcEnfPref.(string) + } + if PrefGrMemb, ok := d.GetOk("pref_gr_memb"); ok { + fvAEPgAttr.PrefGrMemb = PrefGrMemb.(string) + } + if Prio, ok := d.GetOk("prio"); ok { + fvAEPgAttr.Prio = Prio.(string) + } + if Shutdown, ok := d.GetOk("shutdown"); ok { + fvAEPgAttr.Shutdown = Shutdown.(string) + } + fvAEPg := models.NewApplicationEPG(fmt.Sprintf("epg-%s", name), ApplicationProfileDn, desc, fvAEPgAttr) + + err := aciClient.Save(fvAEPg) + if err != nil { + return diag.FromErr(err) + } + + checkDns := make([]string, 0, 1) + + if relationTofvRsBd, ok := d.GetOk("relation_fv_rs_bd"); ok { + relationParam := relationTofvRsBd.(string) + checkDns = append(checkDns, relationParam) + } + + if relationTofvRsCustQosPol, ok := d.GetOk("relation_fv_rs_cust_qos_pol"); ok { + relationParam := relationTofvRsCustQosPol.(string) + checkDns = append(checkDns, relationParam) + } + + if relationTofvRsFcPathAtt, ok := d.GetOk("relation_fv_rs_fc_path_att"); ok { + relationParamList := toStringList(relationTofvRsFcPathAtt.(*schema.Set).List()) + for _, relationParam := range relationParamList { + checkDns = append(checkDns, relationParam) + } + } + + if relationTofvRsProv, ok := d.GetOk("relation_fv_rs_prov"); ok { + relationParamList := toStringList(relationTofvRsProv.(*schema.Set).List()) + for _, relationParam := range relationParamList { + checkDns = append(checkDns, relationParam) + } + } + + if relationTofvRsConsIf, ok := d.GetOk("relation_fv_rs_cons_if"); ok { + relationParamList := toStringList(relationTofvRsConsIf.(*schema.Set).List()) + for _, relationParam := range relationParamList { + checkDns = append(checkDns, relationParam) + } + } + + if relationTofvRsSecInherited, ok := d.GetOk("relation_fv_rs_sec_inherited"); ok { + relationParamList := toStringList(relationTofvRsSecInherited.(*schema.Set).List()) + for _, relationParam := range relationParamList { + checkDns = append(checkDns, relationParam) + } + } + + if relationTofvRsNodeAtt, ok := d.GetOk("relation_fv_rs_node_att"); ok { + relationParamList := toStringList(relationTofvRsNodeAtt.(*schema.Set).List()) + for _, relationParam := range relationParamList { + checkDns = append(checkDns, relationParam) + } + } + + if relationTofvRsDppPol, ok := d.GetOk("relation_fv_rs_dpp_pol"); ok { + relationParam := relationTofvRsDppPol.(string) + checkDns = append(checkDns, relationParam) + } + + if relationTofvRsCons, ok := d.GetOk("relation_fv_rs_cons"); ok { + relationParamList := toStringList(relationTofvRsCons.(*schema.Set).List()) + for _, relationParam := range relationParamList { + checkDns = append(checkDns, relationParam) + } + } + + if relationTofvRsProvDef, ok := d.GetOk("relation_fv_rs_prov_def"); ok { + relationParamList := toStringList(relationTofvRsProvDef.(*schema.Set).List()) + for _, relationParam := range relationParamList { + checkDns = append(checkDns, relationParam) + } + } + + if relationTofvRsTrustCtrl, ok := d.GetOk("relation_fv_rs_trust_ctrl"); ok { + relationParam := relationTofvRsTrustCtrl.(string) + checkDns = append(checkDns, relationParam) + } + + if relationTofvRsPathAtt, ok := d.GetOk("relation_fv_rs_path_att"); ok { + relationParamList := toStringList(relationTofvRsPathAtt.(*schema.Set).List()) + for _, relationParam := range relationParamList { + checkDns = append(checkDns, relationParam) + } + } + + if relationTofvRsProtBy, ok := d.GetOk("relation_fv_rs_prot_by"); ok { + relationParamList := toStringList(relationTofvRsProtBy.(*schema.Set).List()) + for _, relationParam := range relationParamList { + checkDns = append(checkDns, relationParam) + } + } + + if relationTofvRsAEPgMonPol, ok := d.GetOk("relation_fv_rs_aepg_mon_pol"); ok { + relationParam := relationTofvRsAEPgMonPol.(string) + checkDns = append(checkDns, relationParam) + } + + if relationTofvRsIntraEpg, ok := d.GetOk("relation_fv_rs_intra_epg"); ok { + relationParamList := toStringList(relationTofvRsIntraEpg.(*schema.Set).List()) + for _, relationParam := range relationParamList { + checkDns = append(checkDns, relationParam) + } + } + + d.Partial(true) + err = checkTDn(aciClient, checkDns) + if err != nil { + return diag.FromErr(err) + } + d.Partial(false) + + if relationTofvRsBd, ok := d.GetOk("relation_fv_rs_bd"); ok { + relationParam := relationTofvRsBd.(string) + relationParamName := GetMOName(relationParam) + err = aciClient.CreateRelationfvRsBdFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + if err != nil { + return diag.FromErr(err) + } + } + if relationTofvRsCustQosPol, ok := d.GetOk("relation_fv_rs_cust_qos_pol"); ok { + relationParam := relationTofvRsCustQosPol.(string) + relationParamName := GetMOName(relationParam) + err = aciClient.CreateRelationfvRsCustQosPolFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + if err != nil { + return diag.FromErr(err) + } + + } + if relationTofvRsFcPathAtt, ok := d.GetOk("relation_fv_rs_fc_path_att"); ok { + relationParamList := toStringList(relationTofvRsFcPathAtt.(*schema.Set).List()) + for _, relationParam := range relationParamList { + err = aciClient.CreateRelationfvRsFcPathAttFromApplicationEPG(fvAEPg.DistinguishedName, relationParam) + + if err != nil { + return diag.FromErr(err) + } + } + } + if relationTofvRsProv, ok := d.GetOk("relation_fv_rs_prov"); ok { + relationParamList := toStringList(relationTofvRsProv.(*schema.Set).List()) + for _, relationParam := range relationParamList { + relationParamName := GetMOName(relationParam) + err = aciClient.CreateRelationfvRsProvFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + + if err != nil { + return diag.FromErr(err) + } + + } + } + if relationTofvRsConsIf, ok := d.GetOk("relation_fv_rs_cons_if"); ok { + relationParamList := toStringList(relationTofvRsConsIf.(*schema.Set).List()) + for _, relationParam := range relationParamList { + relationParamName := GetMOName(relationParam) + err = aciClient.CreateRelationfvRsConsIfFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + + if err != nil { + return diag.FromErr(err) + } + + } + } + if relationTofvRsSecInherited, ok := d.GetOk("relation_fv_rs_sec_inherited"); ok { + relationParamList := toStringList(relationTofvRsSecInherited.(*schema.Set).List()) + for _, relationParam := range relationParamList { + err = aciClient.CreateRelationfvRsSecInheritedFromApplicationEPG(fvAEPg.DistinguishedName, relationParam) + + if err != nil { + return diag.FromErr(err) + } + + } + } + if relationTofvRsNodeAtt, ok := d.GetOk("relation_fv_rs_node_att"); ok { + relationParamList := toStringList(relationTofvRsNodeAtt.(*schema.Set).List()) + for _, relationParam := range relationParamList { + err = aciClient.CreateRelationfvRsNodeAttFromApplicationEPG(fvAEPg.DistinguishedName, relationParam) + + if err != nil { + return diag.FromErr(err) + } + + } + } + if relationTofvRsDppPol, ok := d.GetOk("relation_fv_rs_dpp_pol"); ok { + relationParam := relationTofvRsDppPol.(string) + relationParamName := GetMOName(relationParam) + err = aciClient.CreateRelationfvRsDppPolFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + if err != nil { + return diag.FromErr(err) + } + + } + if relationTofvRsCons, ok := d.GetOk("relation_fv_rs_cons"); ok { + relationParamList := toStringList(relationTofvRsCons.(*schema.Set).List()) + for _, relationParam := range relationParamList { + relationParamName := GetMOName(relationParam) + err = aciClient.CreateRelationfvRsConsFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + + if err != nil { + return diag.FromErr(err) + } + } + } + if relationTofvRsProvDef, ok := d.GetOk("relation_fv_rs_prov_def"); ok { + relationParamList := toStringList(relationTofvRsProvDef.(*schema.Set).List()) + for _, relationParam := range relationParamList { + err = aciClient.CreateRelationfvRsProvDefFromApplicationEPG(fvAEPg.DistinguishedName, relationParam) + + if err != nil { + return diag.FromErr(err) + } + } + } + if relationTofvRsTrustCtrl, ok := d.GetOk("relation_fv_rs_trust_ctrl"); ok { + relationParam := relationTofvRsTrustCtrl.(string) + relationParamName := GetMOName(relationParam) + err = aciClient.CreateRelationfvRsTrustCtrlFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + if err != nil { + return diag.FromErr(err) + } + + } + if relationTofvRsPathAtt, ok := d.GetOk("relation_fv_rs_path_att"); ok { + relationParamList := toStringList(relationTofvRsPathAtt.(*schema.Set).List()) + for _, relationParam := range relationParamList { + err = aciClient.CreateRelationfvRsPathAttFromApplicationEPG(fvAEPg.DistinguishedName, relationParam) + + if err != nil { + return diag.FromErr(err) + } + + } + } + if relationTofvRsProtBy, ok := d.GetOk("relation_fv_rs_prot_by"); ok { + relationParamList := toStringList(relationTofvRsProtBy.(*schema.Set).List()) + for _, relationParam := range relationParamList { + relationParamName := GetMOName(relationParam) + err = aciClient.CreateRelationfvRsProtByFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + + if err != nil { + return diag.FromErr(err) + } + + } + } + if relationTofvRsAEPgMonPol, ok := d.GetOk("relation_fv_rs_aepg_mon_pol"); ok { + relationParam := relationTofvRsAEPgMonPol.(string) + relationParamName := GetMOName(relationParam) + err = aciClient.CreateRelationfvRsAEPgMonPolFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + if err != nil { + return diag.FromErr(err) + } + + } + if relationTofvRsIntraEpg, ok := d.GetOk("relation_fv_rs_intra_epg"); ok { + relationParamList := toStringList(relationTofvRsIntraEpg.(*schema.Set).List()) + for _, relationParam := range relationParamList { + relationParamName := GetMOName(relationParam) + err = aciClient.CreateRelationfvRsIntraEpgFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + + if err != nil { + return diag.FromErr(err) + } + + } + } + + d.SetId(fvAEPg.DistinguishedName) + log.Printf("[DEBUG] %s: Creation finished successfully", d.Id()) + + return resourceAciApplicationEPGRead(ctx, d, m) +} + +func resourceAciApplicationEPGUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + if _, ok := d.GetOk("bulk_create"); ok { + return resourceAciApplicationEPGUpdateBulk(ctx, d, m) + } else { + return resourceAciApplicationEPGUpdateOrig(ctx, d, m) + } +} + +func resourceAciApplicationEPGUpdateBulk(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Printf("[DEBUG] ApplicationEPG: Beginning Update") + + aciClient := m.(*client.Client) + desc := d.Get("description").(string) + + name := d.Get("name").(string) + + ApplicationProfileDn := d.Get("application_profile_dn").(string) + + fvAEPgAttr := models.ApplicationEPGAttributes{} + if Annotation, ok := d.GetOk("annotation"); ok { + fvAEPgAttr.Annotation = Annotation.(string) + } else { + fvAEPgAttr.Annotation = "{}" + } + if ExceptionTag, ok := d.GetOk("exception_tag"); ok { + fvAEPgAttr.ExceptionTag = ExceptionTag.(string) + } + if FloodOnEncap, ok := d.GetOk("flood_on_encap"); ok { + fvAEPgAttr.FloodOnEncap = FloodOnEncap.(string) + } + if FwdCtrl, ok := d.GetOk("fwd_ctrl"); ok { + fvAEPgAttr.FwdCtrl = FwdCtrl.(string) + } + if HasMcastSource, ok := d.GetOk("has_mcast_source"); ok { + fvAEPgAttr.HasMcastSource = HasMcastSource.(string) + } + if IsAttrBasedEPg, ok := d.GetOk("is_attr_based_epg"); ok { + fvAEPgAttr.IsAttrBasedEPg = IsAttrBasedEPg.(string) + } + if MatchT, ok := d.GetOk("match_t"); ok { + fvAEPgAttr.MatchT = MatchT.(string) + } + if NameAlias, ok := d.GetOk("name_alias"); ok { + fvAEPgAttr.NameAlias = NameAlias.(string) + } + if PcEnfPref, ok := d.GetOk("pc_enf_pref"); ok { + fvAEPgAttr.PcEnfPref = PcEnfPref.(string) + } + if PrefGrMemb, ok := d.GetOk("pref_gr_memb"); ok { + fvAEPgAttr.PrefGrMemb = PrefGrMemb.(string) + } + if Prio, ok := d.GetOk("prio"); ok { + fvAEPgAttr.Prio = Prio.(string) + } + if Shutdown, ok := d.GetOk("shutdown"); ok { + fvAEPgAttr.Shutdown = Shutdown.(string) + } + fvAEPg := models.NewApplicationEPG(fmt.Sprintf("epg-%s", name), ApplicationProfileDn, desc, fvAEPgAttr) + + fvAEPg.Status = "modified" + + err := aciClient.Save(fvAEPg) + + if err != nil { + return diag.FromErr(err) + } + + checkDns := make([]string, 0, 1) + + if d.HasChange("relation_fv_rs_bd") { + _, newRelParam := d.GetChange("relation_fv_rs_bd") + checkDns = append(checkDns, newRelParam.(string)) + } + + if d.HasChange("relation_fv_rs_cust_qos_pol") { + _, newRelParam := d.GetChange("relation_fv_rs_cust_qos_pol") + checkDns = append(checkDns, newRelParam.(string)) + } + + if d.HasChange("relation_fv_rs_fc_path_att") { + oldRel, newRel := d.GetChange("relation_fv_rs_fc_path_att") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) + + for _, relDn := range relToCreate { + checkDns = append(checkDns, relDn) + } + } + + if d.HasChange("relation_fv_rs_prov") { + oldRel, newRel := d.GetChange("relation_fv_rs_prov") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) + + for _, relDn := range relToCreate { + checkDns = append(checkDns, relDn) + } + } + + if d.HasChange("relation_fv_rs_cons_if") { + oldRel, newRel := d.GetChange("relation_fv_rs_cons_if") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) + + for _, relDn := range relToCreate { + checkDns = append(checkDns, relDn) + } + } + + if d.HasChange("relation_fv_rs_sec_inherited") { + oldRel, newRel := d.GetChange("relation_fv_rs_sec_inherited") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) + + for _, relDn := range relToCreate { + checkDns = append(checkDns, relDn) + } + } + + if d.HasChange("relation_fv_rs_node_att") { + oldRel, newRel := d.GetChange("relation_fv_rs_node_att") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) + + for _, relDn := range relToCreate { + checkDns = append(checkDns, relDn) + } + } + + if d.HasChange("relation_fv_rs_dpp_pol") { + _, newRelParam := d.GetChange("relation_fv_rs_dpp_pol") + checkDns = append(checkDns, newRelParam.(string)) + } + + if d.HasChange("relation_fv_rs_cons") { + oldRel, newRel := d.GetChange("relation_fv_rs_cons") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) + + for _, relDn := range relToCreate { + checkDns = append(checkDns, relDn) + } + } + + if d.HasChange("relation_fv_rs_prov_def") { + oldRel, newRel := d.GetChange("relation_fv_rs_prov_def") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) + + for _, relDn := range relToCreate { + checkDns = append(checkDns, relDn) + } + } + + if d.HasChange("relation_fv_rs_trust_ctrl") { + _, newRelParam := d.GetChange("relation_fv_rs_trust_ctrl") + checkDns = append(checkDns, newRelParam.(string)) + + } + if d.HasChange("relation_fv_rs_path_att") { + oldRel, newRel := d.GetChange("relation_fv_rs_path_att") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) + + for _, relDn := range relToCreate { + checkDns = append(checkDns, relDn) + } + } + + if d.HasChange("relation_fv_rs_prot_by") { + oldRel, newRel := d.GetChange("relation_fv_rs_prot_by") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) + + for _, relDn := range relToCreate { + checkDns = append(checkDns, relDn) + } + } + + if d.HasChange("relation_fv_rs_aepg_mon_pol") { + _, newRelParam := d.GetChange("relation_fv_rs_aepg_mon_pol") + checkDns = append(checkDns, newRelParam.(string)) + } + + if d.HasChange("relation_fv_rs_intra_epg") { + oldRel, newRel := d.GetChange("relation_fv_rs_intra_epg") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) + + for _, relDn := range relToCreate { + checkDns = append(checkDns, relDn) + } + } + + d.Partial(true) + err = checkTDn(aciClient, checkDns) + if err != nil { + return diag.FromErr(err) + } + d.Partial(false) + + var fvRsAllDataD [][]byte + var fvRsAllDataC [][]byte + var fvRs []byte + + if d.HasChange("relation_fv_rs_bd") { + _, newRelParam := d.GetChange("relation_fv_rs_bd") + newRelParamName := GetMOName(newRelParam.(string)) + /* + err = aciClient.CreateRelationfvRsBdFromApplicationEPG(fvAEPg.DistinguishedName, newRelParamName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsBdFromApplicationEPG(fvAEPg.DistinguishedName, newRelParamName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) + } + if d.HasChange("relation_fv_rs_cust_qos_pol") { + _, newRelParam := d.GetChange("relation_fv_rs_cust_qos_pol") + newRelParamName := GetMOName(newRelParam.(string)) + /* + err = aciClient.CreateRelationfvRsCustQosPolFromApplicationEPG(fvAEPg.DistinguishedName, newRelParamName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsCustQosPolFromApplicationEPG(fvAEPg.DistinguishedName, newRelParamName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) + } + if d.HasChange("relation_fv_rs_fc_path_att") { + oldRel, newRel := d.GetChange("relation_fv_rs_fc_path_att") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToDelete := toStringList(oldRelSet.Difference(newRelSet).List()) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) + + for _, relDn := range relToDelete { + /* + err = aciClient.DeleteRelationfvRsFcPathAttFromApplicationEPG(fvAEPg.DistinguishedName, relDn) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupDeleteRelationfvRsFcPathAttFromApplicationEPG(fvAEPg.DistinguishedName, relDn) + fvRsAllDataD = append(fvRsAllDataD, fvRs) + } + + for _, relDn := range relToCreate { + /* + err = aciClient.CreateRelationfvRsFcPathAttFromApplicationEPG(fvAEPg.DistinguishedName, relDn) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsFcPathAttFromApplicationEPG(fvAEPg.DistinguishedName, relDn) + fvRsAllDataC = append(fvRsAllDataC, fvRs) + } + + } + if d.HasChange("relation_fv_rs_prov") { + oldRel, newRel := d.GetChange("relation_fv_rs_prov") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToDelete := toStringList(oldRelSet.Difference(newRelSet).List()) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) + + for _, relDn := range relToDelete { + relDnName := GetMOName(relDn) + /* + err = aciClient.DeleteRelationfvRsProvFromApplicationEPG(fvAEPg.DistinguishedName, relDnName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupDeleteRelationfvRsProvFromApplicationEPG(fvAEPg.DistinguishedName, relDnName) + fvRsAllDataD = append(fvRsAllDataD, fvRs) + } + + for _, relDn := range relToCreate { + relDnName := GetMOName(relDn) + /* + err = aciClient.CreateRelationfvRsProvFromApplicationEPG(fvAEPg.DistinguishedName, relDnName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsProvFromApplicationEPG(fvAEPg.DistinguishedName, relDnName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) + } + + } + if d.HasChange("relation_fv_rs_cons_if") { + oldRel, newRel := d.GetChange("relation_fv_rs_cons_if") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToDelete := toStringList(oldRelSet.Difference(newRelSet).List()) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) + + for _, relDn := range relToDelete { + relDnName := GetMOName(relDn) + /* + err = aciClient.DeleteRelationfvRsConsIfFromApplicationEPG(fvAEPg.DistinguishedName, relDnName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupDeleteRelationfvRsConsIfFromApplicationEPG(fvAEPg.DistinguishedName, relDnName) + fvRsAllDataD = append(fvRsAllDataD, fvRs) + } + + for _, relDn := range relToCreate { + relDnName := GetMOName(relDn) + /* + err = aciClient.CreateRelationfvRsConsIfFromApplicationEPG(fvAEPg.DistinguishedName, relDnName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsConsIfFromApplicationEPG(fvAEPg.DistinguishedName, relDnName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) + } + + } + if d.HasChange("relation_fv_rs_sec_inherited") { + oldRel, newRel := d.GetChange("relation_fv_rs_sec_inherited") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToDelete := toStringList(oldRelSet.Difference(newRelSet).List()) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) + + for _, relDn := range relToDelete { + /* + err = aciClient.DeleteRelationfvRsSecInheritedFromApplicationEPG(fvAEPg.DistinguishedName, relDn) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupDeleteRelationfvRsSecInheritedFromApplicationEPG(fvAEPg.DistinguishedName, relDn) + fvRsAllDataD = append(fvRsAllDataD, fvRs) + } + + for _, relDn := range relToCreate { + /* + err = aciClient.CreateRelationfvRsSecInheritedFromApplicationEPG(fvAEPg.DistinguishedName, relDn) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsSecInheritedFromApplicationEPG(fvAEPg.DistinguishedName, relDn) + fvRsAllDataC = append(fvRsAllDataC, fvRs) } - } - d.Partial(true) - err = checkTDn(aciClient, checkDns) - if err != nil { - return diag.FromErr(err) } - d.Partial(false) + if d.HasChange("relation_fv_rs_node_att") { + oldRel, newRel := d.GetChange("relation_fv_rs_node_att") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToDelete := toStringList(oldRelSet.Difference(newRelSet).List()) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) - if relationTofvRsBd, ok := d.GetOk("relation_fv_rs_bd"); ok { - relationParam := relationTofvRsBd.(string) - relationParamName := GetMOName(relationParam) - err = aciClient.CreateRelationfvRsBdFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) - if err != nil { - return diag.FromErr(err) + for _, relDn := range relToDelete { + /* + err = aciClient.DeleteRelationfvRsNodeAttFromApplicationEPG(fvAEPg.DistinguishedName, relDn) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupDeleteRelationfvRsNodeAttFromApplicationEPG(fvAEPg.DistinguishedName, relDn) + fvRsAllDataD = append(fvRsAllDataD, fvRs) } - } - if relationTofvRsCustQosPol, ok := d.GetOk("relation_fv_rs_cust_qos_pol"); ok { - relationParam := relationTofvRsCustQosPol.(string) - relationParamName := GetMOName(relationParam) - err = aciClient.CreateRelationfvRsCustQosPolFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) - if err != nil { - return diag.FromErr(err) + + for _, relDn := range relToCreate { + /* + err = aciClient.CreateRelationfvRsNodeAttFromApplicationEPG(fvAEPg.DistinguishedName, relDn) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsNodeAttFromApplicationEPG(fvAEPg.DistinguishedName, relDn) + fvRsAllDataC = append(fvRsAllDataC, fvRs) } } - if relationTofvRsFcPathAtt, ok := d.GetOk("relation_fv_rs_fc_path_att"); ok { - relationParamList := toStringList(relationTofvRsFcPathAtt.(*schema.Set).List()) - for _, relationParam := range relationParamList { - err = aciClient.CreateRelationfvRsFcPathAttFromApplicationEPG(fvAEPg.DistinguishedName, relationParam) - + if d.HasChange("relation_fv_rs_dpp_pol") { + _, newRelParam := d.GetChange("relation_fv_rs_dpp_pol") + newRelParamName := GetMOName(newRelParam.(string)) + /* + err = aciClient.DeleteRelationfvRsDppPolFromApplicationEPG(fvAEPg.DistinguishedName) if err != nil { return diag.FromErr(err) } - } - } - if relationTofvRsProv, ok := d.GetOk("relation_fv_rs_prov"); ok { - relationParamList := toStringList(relationTofvRsProv.(*schema.Set).List()) - for _, relationParam := range relationParamList { - relationParamName := GetMOName(relationParam) - err = aciClient.CreateRelationfvRsProvFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + */ + fvRs = aciClient.SetupDeleteRelationfvRsDppPolFromApplicationEPG(fvAEPg.DistinguishedName) + fvRsAllDataD = append(fvRsAllDataD, fvRs) + /* + err = aciClient.CreateRelationfvRsDppPolFromApplicationEPG(fvAEPg.DistinguishedName, newRelParamName) if err != nil { return diag.FromErr(err) } - - } + */ + fvRs = aciClient.SetupCreateRelationfvRsDppPolFromApplicationEPG(fvAEPg.DistinguishedName, newRelParamName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) } - if relationTofvRsConsIf, ok := d.GetOk("relation_fv_rs_cons_if"); ok { - relationParamList := toStringList(relationTofvRsConsIf.(*schema.Set).List()) - for _, relationParam := range relationParamList { - relationParamName := GetMOName(relationParam) - err = aciClient.CreateRelationfvRsConsIfFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + if d.HasChange("relation_fv_rs_cons") { + oldRel, newRel := d.GetChange("relation_fv_rs_cons") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToDelete := toStringList(oldRelSet.Difference(newRelSet).List()) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) - if err != nil { - return diag.FromErr(err) - } + for _, relDn := range relToDelete { + relDnName := GetMOName(relDn) + /* + err = aciClient.DeleteRelationfvRsConsFromApplicationEPG(fvAEPg.DistinguishedName, relDnName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupDeleteRelationfvRsConsFromApplicationEPG(fvAEPg.DistinguishedName, relDnName) + fvRsAllDataD = append(fvRsAllDataD, fvRs) + } + for _, relDn := range relToCreate { + relDnName := GetMOName(relDn) + /* + err = aciClient.CreateRelationfvRsConsFromApplicationEPG(fvAEPg.DistinguishedName, relDnName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsConsFromApplicationEPG(fvAEPg.DistinguishedName, relDnName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) } + } - if relationTofvRsSecInherited, ok := d.GetOk("relation_fv_rs_sec_inherited"); ok { - relationParamList := toStringList(relationTofvRsSecInherited.(*schema.Set).List()) - for _, relationParam := range relationParamList { - err = aciClient.CreateRelationfvRsSecInheritedFromApplicationEPG(fvAEPg.DistinguishedName, relationParam) + if d.HasChange("relation_fv_rs_prov_def") { + oldRel, newRel := d.GetChange("relation_fv_rs_prov_def") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) + for _, relDn := range relToCreate { + /* + err = aciClient.CreateRelationfvRsProvDefFromApplicationEPG(fvAEPg.DistinguishedName, relDn) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsProvDefFromApplicationEPG(fvAEPg.DistinguishedName, relDn) + fvRsAllDataC = append(fvRsAllDataC, fvRs) + } + + } + if d.HasChange("relation_fv_rs_trust_ctrl") { + _, newRelParam := d.GetChange("relation_fv_rs_trust_ctrl") + newRelParamName := GetMOName(newRelParam.(string)) + /* + err = aciClient.DeleteRelationfvRsTrustCtrlFromApplicationEPG(fvAEPg.DistinguishedName) if err != nil { return diag.FromErr(err) } + */ + fvRs = aciClient.SetupDeleteRelationfvRsTrustCtrlFromApplicationEPG(fvAEPg.DistinguishedName) + fvRsAllDataD = append(fvRsAllDataD, fvRs) - } - } - if relationTofvRsNodeAtt, ok := d.GetOk("relation_fv_rs_node_att"); ok { - relationParamList := toStringList(relationTofvRsNodeAtt.(*schema.Set).List()) - for _, relationParam := range relationParamList { - err = aciClient.CreateRelationfvRsNodeAttFromApplicationEPG(fvAEPg.DistinguishedName, relationParam) - + /* + err = aciClient.CreateRelationfvRsTrustCtrlFromApplicationEPG(fvAEPg.DistinguishedName, newRelParamName) if err != nil { return diag.FromErr(err) } + */ + fvRs = aciClient.SetupCreateRelationfvRsTrustCtrlFromApplicationEPG(fvAEPg.DistinguishedName, newRelParamName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) + } + if d.HasChange("relation_fv_rs_path_att") { + oldRel, newRel := d.GetChange("relation_fv_rs_path_att") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToDelete := toStringList(oldRelSet.Difference(newRelSet).List()) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) + for _, relDn := range relToDelete { + /* + err = aciClient.DeleteRelationfvRsPathAttFromApplicationEPG(fvAEPg.DistinguishedName, relDn) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupDeleteRelationfvRsPathAttFromApplicationEPG(fvAEPg.DistinguishedName, relDn) + fvRsAllDataD = append(fvRsAllDataD, fvRs) } - } - if relationTofvRsDppPol, ok := d.GetOk("relation_fv_rs_dpp_pol"); ok { - relationParam := relationTofvRsDppPol.(string) - relationParamName := GetMOName(relationParam) - err = aciClient.CreateRelationfvRsDppPolFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) - if err != nil { - return diag.FromErr(err) + + for _, relDn := range relToCreate { + /* + err = aciClient.CreateRelationfvRsPathAttFromApplicationEPG(fvAEPg.DistinguishedName, relDn) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsPathAttFromApplicationEPG(fvAEPg.DistinguishedName, relDn) + fvRsAllDataC = append(fvRsAllDataC, fvRs) } } - if relationTofvRsCons, ok := d.GetOk("relation_fv_rs_cons"); ok { - relationParamList := toStringList(relationTofvRsCons.(*schema.Set).List()) - for _, relationParam := range relationParamList { - relationParamName := GetMOName(relationParam) - err = aciClient.CreateRelationfvRsConsFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + if d.HasChange("relation_fv_rs_prot_by") { + oldRel, newRel := d.GetChange("relation_fv_rs_prot_by") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToDelete := toStringList(oldRelSet.Difference(newRelSet).List()) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) - if err != nil { - return diag.FromErr(err) - } + for _, relDn := range relToDelete { + relDnName := GetMOName(relDn) + /* + err = aciClient.DeleteRelationfvRsProtByFromApplicationEPG(fvAEPg.DistinguishedName, relDnName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupDeleteRelationfvRsProtByFromApplicationEPG(fvAEPg.DistinguishedName, relDnName) + fvRsAllDataD = append(fvRsAllDataD, fvRs) } - } - if relationTofvRsProvDef, ok := d.GetOk("relation_fv_rs_prov_def"); ok { - relationParamList := toStringList(relationTofvRsProvDef.(*schema.Set).List()) - for _, relationParam := range relationParamList { - err = aciClient.CreateRelationfvRsProvDefFromApplicationEPG(fvAEPg.DistinguishedName, relationParam) - if err != nil { - return diag.FromErr(err) - } - } - } - if relationTofvRsTrustCtrl, ok := d.GetOk("relation_fv_rs_trust_ctrl"); ok { - relationParam := relationTofvRsTrustCtrl.(string) - relationParamName := GetMOName(relationParam) - err = aciClient.CreateRelationfvRsTrustCtrlFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) - if err != nil { - return diag.FromErr(err) + for _, relDn := range relToCreate { + relDnName := GetMOName(relDn) + /* + err = aciClient.CreateRelationfvRsProtByFromApplicationEPG(fvAEPg.DistinguishedName, relDnName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsProtByFromApplicationEPG(fvAEPg.DistinguishedName, relDnName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) } } - if relationTofvRsPathAtt, ok := d.GetOk("relation_fv_rs_path_att"); ok { - relationParamList := toStringList(relationTofvRsPathAtt.(*schema.Set).List()) - for _, relationParam := range relationParamList { - err = aciClient.CreateRelationfvRsPathAttFromApplicationEPG(fvAEPg.DistinguishedName, relationParam) - + if d.HasChange("relation_fv_rs_aepg_mon_pol") { + _, newRelParam := d.GetChange("relation_fv_rs_aepg_mon_pol") + newRelParamName := GetMOName(newRelParam.(string)) + /* + err = aciClient.DeleteRelationfvRsAEPgMonPolFromApplicationEPG(fvAEPg.DistinguishedName) if err != nil { return diag.FromErr(err) } + */ + fvRs = aciClient.SetupDeleteRelationfvRsAEPgMonPolFromApplicationEPG(fvAEPg.DistinguishedName) + fvRsAllDataD = append(fvRsAllDataD, fvRs) - } - } - if relationTofvRsProtBy, ok := d.GetOk("relation_fv_rs_prot_by"); ok { - relationParamList := toStringList(relationTofvRsProtBy.(*schema.Set).List()) - for _, relationParam := range relationParamList { - relationParamName := GetMOName(relationParam) - err = aciClient.CreateRelationfvRsProtByFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) - + /* + err = aciClient.CreateRelationfvRsAEPgMonPolFromApplicationEPG(fvAEPg.DistinguishedName, newRelParamName) if err != nil { return diag.FromErr(err) } + */ + fvRs = aciClient.SetupCreateRelationfvRsAEPgMonPolFromApplicationEPG(fvAEPg.DistinguishedName, newRelParamName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) + } + if d.HasChange("relation_fv_rs_intra_epg") { + oldRel, newRel := d.GetChange("relation_fv_rs_intra_epg") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToDelete := toStringList(oldRelSet.Difference(newRelSet).List()) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) + for _, relDn := range relToDelete { + relDnName := GetMOName(relDn) + /* + err = aciClient.DeleteRelationfvRsIntraEpgFromApplicationEPG(fvAEPg.DistinguishedName, relDnName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupDeleteRelationfvRsIntraEpgFromApplicationEPG(fvAEPg.DistinguishedName, relDnName) + fvRsAllDataD = append(fvRsAllDataD, fvRs) + } + + for _, relDn := range relToCreate { + relDnName := GetMOName(relDn) + /* + err = aciClient.CreateRelationfvRsIntraEpgFromApplicationEPG(fvAEPg.DistinguishedName, relDnName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsIntraEpgFromApplicationEPG(fvAEPg.DistinguishedName, relDnName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) } + } - if relationTofvRsAEPgMonPol, ok := d.GetOk("relation_fv_rs_aepg_mon_pol"); ok { - relationParam := relationTofvRsAEPgMonPol.(string) - relationParamName := GetMOName(relationParam) - err = aciClient.CreateRelationfvRsAEPgMonPolFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) + + if len(fvRsAllDataD) > 0 { + err = aciClient.RenderRelationfvRsAllFromApplicationEPG(fvAEPg, fvRsAllDataD) if err != nil { return diag.FromErr(err) } - } - if relationTofvRsIntraEpg, ok := d.GetOk("relation_fv_rs_intra_epg"); ok { - relationParamList := toStringList(relationTofvRsIntraEpg.(*schema.Set).List()) - for _, relationParam := range relationParamList { - relationParamName := GetMOName(relationParam) - err = aciClient.CreateRelationfvRsIntraEpgFromApplicationEPG(fvAEPg.DistinguishedName, relationParamName) - - if err != nil { - return diag.FromErr(err) - } + if len(fvRsAllDataC) > 0 { + err = aciClient.RenderRelationfvRsAllFromApplicationEPG(fvAEPg, fvRsAllDataC) + if err != nil { + return diag.FromErr(err) } } d.SetId(fvAEPg.DistinguishedName) - log.Printf("[DEBUG] %s: Creation finished successfully", d.Id()) + log.Printf("[DEBUG] %s: Update finished successfully", d.Id()) return resourceAciApplicationEPGRead(ctx, d, m) + } -func resourceAciApplicationEPGUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +func resourceAciApplicationEPGUpdateOrig(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Printf("[DEBUG] ApplicationEPG: Beginning Update") aciClient := m.(*client.Client) @@ -1137,6 +2163,195 @@ func resourceAciApplicationEPGUpdate(ctx context.Context, d *schema.ResourceData } func resourceAciApplicationEPGRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + if _, ok := d.GetOk("bulk_read"); ok { + return resourceAciApplicationEPGReadBulk(ctx, d, m) + } else { + return resourceAciApplicationEPGReadOrig(ctx, d, m) + } +} + +func resourceAciApplicationEPGReadBulk(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Printf("[DEBUG] %s: Beginning Bulk Read", d.Id()) + + aciClient := m.(*client.Client) + + dn := d.Id() + fvAEPg, err := getRemoteApplicationEPG(aciClient, dn) + + if err != nil { + return errorForObjectNotFound(err, dn, d) + } + _, err = setApplicationEPGAttributes(fvAEPg, d) + if err != nil { + d.SetId("") + return nil + } + + fvRsAllData, err := aciClient.ReadRelationfvRsAllEPG(dn) + + if len(fvRsAllData) > 0 { + //fvRsBdData, err := aciClient.ReadRelationfvRsBdFromApplicationEPG(dn) + //if err != nil { + fvRsBdData := fvRsAllData["fvRsBd"] + if fvRsBdData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsBd %v", err) + d.Set("relation_fv_rs_bd", "") + + } else { + setRelationAttribute(d, "relation_fv_rs_bd", fvRsBdData.(string)) + } + + //fvRsCustQosPolData, err := aciClient.ReadRelationfvRsCustQosPolFromApplicationEPG(dn) + //if err != nil { + fvRsCustQosPolData := fvRsAllData["fvRsCustQosPol"] + if fvRsCustQosPolData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsCustQosPol %v", err) + d.Set("relation_fv_rs_cust_qos_pol", "") + + } else { + setRelationAttribute(d, "relation_fv_rs_cust_qos_pol", fvRsCustQosPolData.(string)) + } + + //fvRsFcPathAttData, err := aciClient.ReadRelationfvRsFcPathAttFromApplicationEPG(dn) + //if err != nil { + fvRsFcPathAttData := fvRsAllData["fvRsFcPathAtt"] + if fvRsFcPathAttData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsFcPathAtt %v", err) + setRelationAttribute(d, "relation_fv_rs_fc_path_att", make([]interface{}, 0, 1)) + } else { + setRelationAttribute(d, "relation_fv_rs_fc_path_att", toStringList(fvRsFcPathAttData.(*schema.Set).List())) + } + + //fvRsProvData, err := aciClient.ReadRelationfvRsProvFromApplicationEPG(dn) + //if err != nil { + fvRsProvData := fvRsAllData["fvRsProv"] + if fvRsProvData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsProv %v", err) + setRelationAttribute(d, "relation_fv_rs_prov", make([]interface{}, 0, 1)) + } else { + setRelationAttribute(d, "relation_fv_rs_prov", toStringList(fvRsProvData.(*schema.Set).List())) + } + + //fvRsConsIfData, err := aciClient.ReadRelationfvRsConsIfFromApplicationEPG(dn) + //if err != nil { + fvRsConsIfData := fvRsAllData["fvRsConsIf"] + if fvRsConsIfData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsConsIf %v", err) + setRelationAttribute(d, "relation_fv_rs_cons_if", make([]interface{}, 0, 1)) + } else { + setRelationAttribute(d, "relation_fv_rs_cons_if", toStringList(fvRsConsIfData.(*schema.Set).List())) + } + + //fvRsSecInheritedData, err := aciClient.ReadRelationfvRsSecInheritedFromApplicationEPG(dn) + //if err != nil { + fvRsSecInheritedData := fvRsAllData["fvRsSecInherited"] + if fvRsSecInheritedData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsSecInherited %v", err) + setRelationAttribute(d, "relation_fv_rs_sec_inherited", make([]interface{}, 0, 1)) + } else { + setRelationAttribute(d, "relation_fv_rs_sec_inherited", toStringList(fvRsSecInheritedData.(*schema.Set).List())) + } + + //fvRsNodeAttData, err := aciClient.ReadRelationfvRsNodeAttFromApplicationEPG(dn) + //if err != nil { + fvRsNodeAttData := fvRsAllData["fvRsNodeAtt"] + if fvRsNodeAttData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsNodeAtt %v", err) + setRelationAttribute(d, "relation_fv_rs_node_att", make([]interface{}, 0, 1)) + } else { + setRelationAttribute(d, "relation_fv_rs_node_att", toStringList(fvRsNodeAttData.(*schema.Set).List())) + } + + //fvRsDppPolData, err := aciClient.ReadRelationfvRsDppPolFromApplicationEPG(dn) + //if err != nil { + fvRsDppPolData := fvRsAllData["fvRsDppPol"] + if fvRsDppPolData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsDppPol %v", err) + d.Set("relation_fv_rs_dpp_pol", "") + + } else { + setRelationAttribute(d, "relation_fv_rs_dpp_pol", fvRsDppPolData.(string)) + } + + //fvRsConsData, err := aciClient.ReadRelationfvRsConsFromApplicationEPG(dn) + //if err != nil { + fvRsConsData := fvRsAllData["fvRsCons"] + if fvRsConsData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsCons %v", err) + setRelationAttribute(d, "relation_fv_rs_cons", make([]interface{}, 0, 1)) + } else { + setRelationAttribute(d, "relation_fv_rs_cons", toStringList(fvRsConsData.(*schema.Set).List())) + } + + //fvRsProvDefData, err := aciClient.ReadRelationfvRsProvDefFromApplicationEPG(dn) + //if err != nil { + fvRsProvDefData := fvRsAllData["fvRsProvDef"] + if fvRsProvDefData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsProvDef %v", err) + setRelationAttribute(d, "relation_fv_rs_prov_def", make([]interface{}, 0, 1)) + } else { + setRelationAttribute(d, "relation_fv_rs_prov_def", toStringList(fvRsProvDefData.(*schema.Set).List())) + } + + //fvRsTrustCtrlData, err := aciClient.ReadRelationfvRsTrustCtrlFromApplicationEPG(dn) + //if err != nil { + fvRsTrustCtrlData := fvRsAllData["fvRsTrustCtrl"] + if fvRsTrustCtrlData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsTrustCtrl %v", err) + d.Set("relation_fv_rs_trust_ctrl", "") + + } else { + setRelationAttribute(d, "relation_fv_rs_trust_ctrl", fvRsTrustCtrlData.(string)) + } + + //fvRsPathAttData, err := aciClient.ReadRelationfvRsPathAttFromApplicationEPG(dn) + //if err != nil { + fvRsPathAttData := fvRsAllData["fvRsPathAtt"] + if fvRsPathAttData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsPathAtt %v", err) + setRelationAttribute(d, "relation_fv_rs_path_att", make([]interface{}, 0, 1)) + } else { + setRelationAttribute(d, "relation_fv_rs_path_att", toStringList(fvRsPathAttData.(*schema.Set).List())) + } + + //fvRsProtByData, err := aciClient.ReadRelationfvRsProtByFromApplicationEPG(dn) + //if err != nil { + fvRsProtByData := fvRsAllData["fvRsProtBy"] + if fvRsProtByData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsProtBy %v", err) + setRelationAttribute(d, "relation_fv_rs_prot_by", make([]interface{}, 0, 1)) + } else { + setRelationAttribute(d, "relation_fv_rs_prot_by", toStringList(fvRsProtByData.(*schema.Set).List())) + } + + //fvRsAEPgMonPolData, err := aciClient.ReadRelationfvRsAEPgMonPolFromApplicationEPG(dn) + //if err != nil { + fvRsAEPgMonPolData := fvRsAllData["fvRsAEPgMonPol"] + if fvRsAEPgMonPolData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsAEPgMonPol %v", err) + d.Set("relation_fv_rs_aepg_mon_pol", "") + + } else { + setRelationAttribute(d, "relation_fv_rs_aepg_mon_pol", fvRsAEPgMonPolData.(string)) + } + + //fvRsIntraEpgData, err := aciClient.ReadRelationfvRsIntraEpgFromApplicationEPG(dn) + //if err != nil { + fvRsIntraEpgData := fvRsAllData["fvRsIntraEpg"] + if fvRsIntraEpgData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsIntraEpg %v", err) + setRelationAttribute(d, "relation_fv_rs_intra_epg", make([]interface{}, 0, 1)) + } else { + setRelationAttribute(d, "relation_fv_rs_intra_epg", toStringList(fvRsIntraEpgData.(*schema.Set).List())) + } + } + + log.Printf("[DEBUG] %s: Bulk Read finished successfully", d.Id()) + + return nil +} + +func resourceAciApplicationEPGReadOrig(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Printf("[DEBUG] %s: Beginning Read", d.Id()) aciClient := m.(*client.Client) diff --git a/aci/resource_aci_fvbd.go b/aci/resource_aci_fvbd.go index 13cc58093..c8744cbac 100644 --- a/aci/resource_aci_fvbd.go +++ b/aci/resource_aci_fvbd.go @@ -301,6 +301,21 @@ func resourceAciBridgeDomain() *schema.Resource { Optional: true, Set: schema.HashString, }, + "bulk_create": &schema.Schema{ + Type: schema.TypeBool, + + Optional: true, + }, + "bulk_read": &schema.Schema{ + Type: schema.TypeBool, + + Optional: true, + }, + "bulk_update": &schema.Schema{ + Type: schema.TypeBool, + + Optional: true, + }, }), } } @@ -541,7 +556,15 @@ func checkForSubnetConflict(client *client.Client, bdDN, ctxRelation string) err } func resourceAciBridgeDomainCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Printf("[DEBUG] BridgeDomain: Beginning Creation") + if _, ok := d.GetOk("bulk_create"); ok { + return resourceAciBridgeDomainCreateBulk(ctx, d, m) + } else { + return resourceAciBridgeDomainCreateOrig(ctx, d, m) + } +} + +func resourceAciBridgeDomainCreateBulk(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Printf("[DEBUG] BridgeDomain: Beginning Bulk Creation") aciClient := m.(*client.Client) desc := d.Get("description").(string) @@ -699,130 +722,177 @@ func resourceAciBridgeDomainCreate(ctx context.Context, d *schema.ResourceData, } d.Partial(false) + var fvRsAllDataC [][]byte + var fvRs []byte + if relationTofvRsBDToProfile, ok := d.GetOk("relation_fv_rs_bd_to_profile"); ok { relationParam := relationTofvRsBDToProfile.(string) relationParamName := GetMOName(relationParam) - err = aciClient.CreateRelationfvRsBDToProfileFromBridgeDomain(fvBD.DistinguishedName, relationParamName) - if err != nil { - return diag.FromErr(err) - } - + /* + err = aciClient.CreateRelationfvRsBDToProfileFromBridgeDomain(fvBD.DistinguishedName, relationParamName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsBDToProfileFromBridgeDomain(fvBD.DistinguishedName, relationParamName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) } if relationTofvRsMldsn, ok := d.GetOk("relation_fv_rs_mldsn"); ok { relationParam := relationTofvRsMldsn.(string) relationParamName := GetMOName(relationParam) - err = aciClient.CreateRelationfvRsMldsnFromBridgeDomain(fvBD.DistinguishedName, relationParamName) - if err != nil { - return diag.FromErr(err) - } - + /* + err = aciClient.CreateRelationfvRsMldsnFromBridgeDomain(fvBD.DistinguishedName, relationParamName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsMldsnFromBridgeDomain(fvBD.DistinguishedName, relationParamName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) } if relationTofvRsABDPolMonPol, ok := d.GetOk("relation_fv_rs_abd_pol_mon_pol"); ok { relationParam := relationTofvRsABDPolMonPol.(string) relationParamName := GetMOName(relationParam) - err = aciClient.CreateRelationfvRsABDPolMonPolFromBridgeDomain(fvBD.DistinguishedName, relationParamName) - if err != nil { - return diag.FromErr(err) - } - + /* + err = aciClient.CreateRelationfvRsABDPolMonPolFromBridgeDomain(fvBD.DistinguishedName, relationParamName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsABDPolMonPolFromBridgeDomain(fvBD.DistinguishedName, relationParamName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) } if relationTofvRsBDToNdP, ok := d.GetOk("relation_fv_rs_bd_to_nd_p"); ok { relationParam := relationTofvRsBDToNdP.(string) relationParamName := GetMOName(relationParam) - err = aciClient.CreateRelationfvRsBDToNdPFromBridgeDomain(fvBD.DistinguishedName, relationParamName) - if err != nil { - return diag.FromErr(err) - } - + /* + err = aciClient.CreateRelationfvRsBDToNdPFromBridgeDomain(fvBD.DistinguishedName, relationParamName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsBDToNdPFromBridgeDomain(fvBD.DistinguishedName, relationParamName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) } if relationTofvRsBdFloodTo, ok := d.GetOk("relation_fv_rs_bd_flood_to"); ok { relationParamList := toStringList(relationTofvRsBdFloodTo.(*schema.Set).List()) for _, relationParam := range relationParamList { - err = aciClient.CreateRelationfvRsBdFloodToFromBridgeDomain(fvBD.DistinguishedName, relationParam) + /* + err = aciClient.CreateRelationfvRsBdFloodToFromBridgeDomain(fvBD.DistinguishedName, relationParam) - if err != nil { - return diag.FromErr(err) - } + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsBdFloodToFromBridgeDomain(fvBD.DistinguishedName, relationParam) + fvRsAllDataC = append(fvRsAllDataC, fvRs) } } if relationTofvRsBDToFhs, ok := d.GetOk("relation_fv_rs_bd_to_fhs"); ok { relationParam := relationTofvRsBDToFhs.(string) relationParamName := GetMOName(relationParam) - err = aciClient.CreateRelationfvRsBDToFhsFromBridgeDomain(fvBD.DistinguishedName, relationParamName) - if err != nil { - return diag.FromErr(err) - } - + /* + err = aciClient.CreateRelationfvRsBDToFhsFromBridgeDomain(fvBD.DistinguishedName, relationParamName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsBDToFhsFromBridgeDomain(fvBD.DistinguishedName, relationParamName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) } if relationTofvRsBDToRelayP, ok := d.GetOk("relation_fv_rs_bd_to_relay_p"); ok { relationParam := relationTofvRsBDToRelayP.(string) relationParamName := GetMOName(relationParam) - err = aciClient.CreateRelationfvRsBDToRelayPFromBridgeDomain(fvBD.DistinguishedName, relationParamName) - if err != nil { - return diag.FromErr(err) - } - + /* + err = aciClient.CreateRelationfvRsBDToRelayPFromBridgeDomain(fvBD.DistinguishedName, relationParamName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsBDToRelayPFromBridgeDomain(fvBD.DistinguishedName, relationParamName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) } if relationTofvRsCtx, ok := d.GetOk("relation_fv_rs_ctx"); ok { relationParam := relationTofvRsCtx.(string) relationParamName := GetMOName(relationParam) - err = aciClient.CreateRelationfvRsCtxFromBridgeDomain(fvBD.DistinguishedName, relationParamName) - if err != nil { - return diag.FromErr(err) - } - + /* + err = aciClient.CreateRelationfvRsCtxFromBridgeDomain(fvBD.DistinguishedName, relationParamName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsCtxFromBridgeDomain(fvBD.DistinguishedName, relationParamName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) } if relationTofvRsBDToNetflowMonitorPol, ok := d.GetOk("relation_fv_rs_bd_to_netflow_monitor_pol"); ok { relationParamList := relationTofvRsBDToNetflowMonitorPol.(*schema.Set).List() for _, relationParam := range relationParamList { paramMap := relationParam.(map[string]interface{}) - err = aciClient.CreateRelationfvRsBDToNetflowMonitorPolFromBridgeDomain(fvBD.DistinguishedName, GetMOName(paramMap["tn_netflow_monitor_pol_name"].(string)), paramMap["flt_type"].(string)) - if err != nil { - return diag.FromErr(err) - } + /* + err = aciClient.CreateRelationfvRsBDToNetflowMonitorPolFromBridgeDomain(fvBD.DistinguishedName, GetMOName(paramMap["tn_netflow_monitor_pol_name"].(string)), paramMap["flt_type"].(string)) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsBDToNetflowMonitorPolFromBridgeDomain(fvBD.DistinguishedName, GetMOName(paramMap["tn_netflow_monitor_pol_name"].(string)), paramMap["flt_type"].(string)) + fvRsAllDataC = append(fvRsAllDataC, fvRs) } - } if relationTofvRsIgmpsn, ok := d.GetOk("relation_fv_rs_igmpsn"); ok { relationParam := relationTofvRsIgmpsn.(string) relationParamName := GetMOName(relationParam) - err = aciClient.CreateRelationfvRsIgmpsnFromBridgeDomain(fvBD.DistinguishedName, relationParamName) - if err != nil { - return diag.FromErr(err) - } - + /* + err = aciClient.CreateRelationfvRsIgmpsnFromBridgeDomain(fvBD.DistinguishedName, relationParamName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsIgmpsnFromBridgeDomain(fvBD.DistinguishedName, relationParamName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) } if relationTofvRsBdToEpRet, ok := d.GetOk("relation_fv_rs_bd_to_ep_ret"); ok { relationParam := relationTofvRsBdToEpRet.(string) relationParamName := GetMOName(relationParam) - err = aciClient.CreateRelationfvRsBdToEpRetFromBridgeDomain(fvBD.DistinguishedName, relationParamName) - if err != nil { - return diag.FromErr(err) - } - + /* + err = aciClient.CreateRelationfvRsBdToEpRetFromBridgeDomain(fvBD.DistinguishedName, relationParamName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsBdToEpRetFromBridgeDomain(fvBD.DistinguishedName, relationParamName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) } if relationTofvRsBDToOut, ok := d.GetOk("relation_fv_rs_bd_to_out"); ok { relationParamList := toStringList(relationTofvRsBDToOut.(*schema.Set).List()) for _, relationParam := range relationParamList { relationParamName := GetMOName(relationParam) - err = aciClient.CreateRelationfvRsBDToOutFromBridgeDomain(fvBD.DistinguishedName, relationParamName) + /* + err = aciClient.CreateRelationfvRsBDToOutFromBridgeDomain(fvBD.DistinguishedName, relationParamName) - if err != nil { - return diag.FromErr(err) - } + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsBDToOutFromBridgeDomain(fvBD.DistinguishedName, relationParamName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) + } + } + + if len(fvRsAllDataC) > 0 { + err = aciClient.RenderRelationfvRsAllFromBridgeDomain(fvBD, fvRsAllDataC) + if err != nil { + return diag.FromErr(err) } } d.SetId(fvBD.DistinguishedName) - log.Printf("[DEBUG] %s: Creation finished successfully", d.Id()) + log.Printf("[DEBUG] %s: Bulk Creation finished successfully", d.Id()) return resourceAciBridgeDomainRead(ctx, d, m) } -func resourceAciBridgeDomainUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Printf("[DEBUG] BridgeDomain: Beginning Update") - +func resourceAciBridgeDomainCreateOrig(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Printf("[DEBUG] BridgeDomain: Beginning Creation") aciClient := m.(*client.Client) desc := d.Get("description").(string) @@ -907,80 +977,69 @@ func resourceAciBridgeDomainUpdate(ctx context.Context, d *schema.ResourceData, } fvBD := models.NewBridgeDomain(fmt.Sprintf("BD-%s", name), TenantDn, desc, fvBDAttr) - fvBD.Status = "modified" - err := aciClient.Save(fvBD) - if err != nil { return diag.FromErr(err) } checkDns := make([]string, 0, 1) - if d.HasChange("relation_fv_rs_bd_to_profile") { - _, newRelParam := d.GetChange("relation_fv_rs_bd_to_profile") - checkDns = append(checkDns, newRelParam.(string)) + if relationTofvRsBDToProfile, ok := d.GetOk("relation_fv_rs_bd_to_profile"); ok { + relationParam := relationTofvRsBDToProfile.(string) + checkDns = append(checkDns, relationParam) } - if d.HasChange("relation_fv_rs_mldsn") { - _, newRelParam := d.GetChange("relation_fv_rs_mldsn") - checkDns = append(checkDns, newRelParam.(string)) + if relationTofvRsMldsn, ok := d.GetOk("relation_fv_rs_mldsn"); ok { + relationParam := relationTofvRsMldsn.(string) + checkDns = append(checkDns, relationParam) } - if d.HasChange("relation_fv_rs_abd_pol_mon_pol") { - _, newRelParam := d.GetChange("relation_fv_rs_abd_pol_mon_pol") - checkDns = append(checkDns, newRelParam.(string)) + if relationTofvRsABDPolMonPol, ok := d.GetOk("relation_fv_rs_abd_pol_mon_pol"); ok { + relationParam := relationTofvRsABDPolMonPol.(string) + checkDns = append(checkDns, relationParam) } - if d.HasChange("relation_fv_rs_bd_to_nd_p") { - _, newRelParam := d.GetChange("relation_fv_rs_bd_to_nd_p") - checkDns = append(checkDns, newRelParam.(string)) + if relationTofvRsBDToNdP, ok := d.GetOk("relation_fv_rs_bd_to_nd_p"); ok { + relationParam := relationTofvRsBDToNdP.(string) + checkDns = append(checkDns, relationParam) } - if d.HasChange("relation_fv_rs_bd_flood_to") { - oldRel, newRel := d.GetChange("relation_fv_rs_bd_flood_to") - oldRelSet := oldRel.(*schema.Set) - newRelSet := newRel.(*schema.Set) - relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) - - for _, relDn := range relToCreate { - checkDns = append(checkDns, relDn) + if relationTofvRsBdFloodTo, ok := d.GetOk("relation_fv_rs_bd_flood_to"); ok { + relationParamList := toStringList(relationTofvRsBdFloodTo.(*schema.Set).List()) + for _, relationParam := range relationParamList { + checkDns = append(checkDns, relationParam) } } - if d.HasChange("relation_fv_rs_bd_to_fhs") { - _, newRelParam := d.GetChange("relation_fv_rs_bd_to_fhs") - checkDns = append(checkDns, newRelParam.(string)) + if relationTofvRsBDToFhs, ok := d.GetOk("relation_fv_rs_bd_to_fhs"); ok { + relationParam := relationTofvRsBDToFhs.(string) + checkDns = append(checkDns, relationParam) } - if d.HasChange("relation_fv_rs_bd_to_relay_p") { - _, newRelParam := d.GetChange("relation_fv_rs_bd_to_relay_p") - checkDns = append(checkDns, newRelParam.(string)) + if relationTofvRsBDToRelayP, ok := d.GetOk("relation_fv_rs_bd_to_relay_p"); ok { + relationParam := relationTofvRsBDToRelayP.(string) + checkDns = append(checkDns, relationParam) } - if d.HasChange("relation_fv_rs_ctx") { - _, newRelParam := d.GetChange("relation_fv_rs_ctx") - checkDns = append(checkDns, newRelParam.(string)) + if relationTofvRsCtx, ok := d.GetOk("relation_fv_rs_ctx"); ok { + relationParam := relationTofvRsCtx.(string) + checkDns = append(checkDns, relationParam) } - if d.HasChange("relation_fv_rs_igmpsn") { - _, newRelParam := d.GetChange("relation_fv_rs_igmpsn") - checkDns = append(checkDns, newRelParam.(string)) + if relationTofvRsIgmpsn, ok := d.GetOk("relation_fv_rs_igmpsn"); ok { + relationParam := relationTofvRsIgmpsn.(string) + checkDns = append(checkDns, relationParam) } - if d.HasChange("relation_fv_rs_bd_to_ep_ret") { - _, newRelParam := d.GetChange("relation_fv_rs_bd_to_ep_ret") - checkDns = append(checkDns, newRelParam.(string)) + if relationTofvRsBdToEpRet, ok := d.GetOk("relation_fv_rs_bd_to_ep_ret"); ok { + relationParam := relationTofvRsBdToEpRet.(string) + checkDns = append(checkDns, relationParam) } - if d.HasChange("relation_fv_rs_bd_to_out") { - oldRel, newRel := d.GetChange("relation_fv_rs_bd_to_out") - oldRelSet := oldRel.(*schema.Set) - newRelSet := newRel.(*schema.Set) - relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) - - for _, relDn := range relToCreate { - checkDns = append(checkDns, relDn) + if relationTofvRsBDToOut, ok := d.GetOk("relation_fv_rs_bd_to_out"); ok { + relationParamList := toStringList(relationTofvRsBDToOut.(*schema.Set).List()) + for _, relationParam := range relationParamList { + checkDns = append(checkDns, relationParam) } } @@ -991,83 +1050,814 @@ func resourceAciBridgeDomainUpdate(ctx context.Context, d *schema.ResourceData, } d.Partial(false) - if d.HasChange("relation_fv_rs_bd_to_profile") { - _, newRelParam := d.GetChange("relation_fv_rs_bd_to_profile") - newRelParamName := GetMOName(newRelParam.(string)) - err = aciClient.DeleteRelationfvRsBDToProfileFromBridgeDomain(fvBD.DistinguishedName) - if err != nil { - return diag.FromErr(err) - } - err = aciClient.CreateRelationfvRsBDToProfileFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + if relationTofvRsBDToProfile, ok := d.GetOk("relation_fv_rs_bd_to_profile"); ok { + relationParam := relationTofvRsBDToProfile.(string) + relationParamName := GetMOName(relationParam) + err = aciClient.CreateRelationfvRsBDToProfileFromBridgeDomain(fvBD.DistinguishedName, relationParamName) if err != nil { return diag.FromErr(err) } } - if d.HasChange("relation_fv_rs_mldsn") { - _, newRelParam := d.GetChange("relation_fv_rs_mldsn") - newRelParamName := GetMOName(newRelParam.(string)) - err = aciClient.CreateRelationfvRsMldsnFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + if relationTofvRsMldsn, ok := d.GetOk("relation_fv_rs_mldsn"); ok { + relationParam := relationTofvRsMldsn.(string) + relationParamName := GetMOName(relationParam) + err = aciClient.CreateRelationfvRsMldsnFromBridgeDomain(fvBD.DistinguishedName, relationParamName) if err != nil { return diag.FromErr(err) } } - if d.HasChange("relation_fv_rs_abd_pol_mon_pol") { - _, newRelParam := d.GetChange("relation_fv_rs_abd_pol_mon_pol") - newRelParamName := GetMOName(newRelParam.(string)) - err = aciClient.DeleteRelationfvRsABDPolMonPolFromBridgeDomain(fvBD.DistinguishedName) - if err != nil { - return diag.FromErr(err) - } - err = aciClient.CreateRelationfvRsABDPolMonPolFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + if relationTofvRsABDPolMonPol, ok := d.GetOk("relation_fv_rs_abd_pol_mon_pol"); ok { + relationParam := relationTofvRsABDPolMonPol.(string) + relationParamName := GetMOName(relationParam) + err = aciClient.CreateRelationfvRsABDPolMonPolFromBridgeDomain(fvBD.DistinguishedName, relationParamName) if err != nil { return diag.FromErr(err) } } - if d.HasChange("relation_fv_rs_bd_to_nd_p") { - _, newRelParam := d.GetChange("relation_fv_rs_bd_to_nd_p") - newRelParamName := GetMOName(newRelParam.(string)) - err = aciClient.CreateRelationfvRsBDToNdPFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + if relationTofvRsBDToNdP, ok := d.GetOk("relation_fv_rs_bd_to_nd_p"); ok { + relationParam := relationTofvRsBDToNdP.(string) + relationParamName := GetMOName(relationParam) + err = aciClient.CreateRelationfvRsBDToNdPFromBridgeDomain(fvBD.DistinguishedName, relationParamName) if err != nil { return diag.FromErr(err) } } - if d.HasChange("relation_fv_rs_bd_flood_to") { - oldRel, newRel := d.GetChange("relation_fv_rs_bd_flood_to") - oldRelSet := oldRel.(*schema.Set) - newRelSet := newRel.(*schema.Set) - relToDelete := toStringList(oldRelSet.Difference(newRelSet).List()) - relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) - - for _, relDn := range relToDelete { - err = aciClient.DeleteRelationfvRsBdFloodToFromBridgeDomain(fvBD.DistinguishedName, relDn) - if err != nil { - return diag.FromErr(err) - } - - } + if relationTofvRsBdFloodTo, ok := d.GetOk("relation_fv_rs_bd_flood_to"); ok { + relationParamList := toStringList(relationTofvRsBdFloodTo.(*schema.Set).List()) + for _, relationParam := range relationParamList { + err = aciClient.CreateRelationfvRsBdFloodToFromBridgeDomain(fvBD.DistinguishedName, relationParam) - for _, relDn := range relToCreate { - err = aciClient.CreateRelationfvRsBdFloodToFromBridgeDomain(fvBD.DistinguishedName, relDn) if err != nil { return diag.FromErr(err) } - } - } - if d.HasChange("relation_fv_rs_bd_to_fhs") { - _, newRelParam := d.GetChange("relation_fv_rs_bd_to_fhs") - newRelParamName := GetMOName(newRelParam.(string)) - err = aciClient.DeleteRelationfvRsBDToFhsFromBridgeDomain(fvBD.DistinguishedName) + if relationTofvRsBDToFhs, ok := d.GetOk("relation_fv_rs_bd_to_fhs"); ok { + relationParam := relationTofvRsBDToFhs.(string) + relationParamName := GetMOName(relationParam) + err = aciClient.CreateRelationfvRsBDToFhsFromBridgeDomain(fvBD.DistinguishedName, relationParamName) if err != nil { return diag.FromErr(err) } - err = aciClient.CreateRelationfvRsBDToFhsFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) - if err != nil { + + } + if relationTofvRsBDToRelayP, ok := d.GetOk("relation_fv_rs_bd_to_relay_p"); ok { + relationParam := relationTofvRsBDToRelayP.(string) + relationParamName := GetMOName(relationParam) + err = aciClient.CreateRelationfvRsBDToRelayPFromBridgeDomain(fvBD.DistinguishedName, relationParamName) + if err != nil { + return diag.FromErr(err) + } + + } + if relationTofvRsCtx, ok := d.GetOk("relation_fv_rs_ctx"); ok { + relationParam := relationTofvRsCtx.(string) + relationParamName := GetMOName(relationParam) + err = aciClient.CreateRelationfvRsCtxFromBridgeDomain(fvBD.DistinguishedName, relationParamName) + if err != nil { + return diag.FromErr(err) + } + + } + if relationTofvRsBDToNetflowMonitorPol, ok := d.GetOk("relation_fv_rs_bd_to_netflow_monitor_pol"); ok { + + relationParamList := relationTofvRsBDToNetflowMonitorPol.(*schema.Set).List() + for _, relationParam := range relationParamList { + paramMap := relationParam.(map[string]interface{}) + err = aciClient.CreateRelationfvRsBDToNetflowMonitorPolFromBridgeDomain(fvBD.DistinguishedName, GetMOName(paramMap["tn_netflow_monitor_pol_name"].(string)), paramMap["flt_type"].(string)) + if err != nil { + return diag.FromErr(err) + } + } + + } + if relationTofvRsIgmpsn, ok := d.GetOk("relation_fv_rs_igmpsn"); ok { + relationParam := relationTofvRsIgmpsn.(string) + relationParamName := GetMOName(relationParam) + err = aciClient.CreateRelationfvRsIgmpsnFromBridgeDomain(fvBD.DistinguishedName, relationParamName) + if err != nil { + return diag.FromErr(err) + } + + } + if relationTofvRsBdToEpRet, ok := d.GetOk("relation_fv_rs_bd_to_ep_ret"); ok { + relationParam := relationTofvRsBdToEpRet.(string) + relationParamName := GetMOName(relationParam) + err = aciClient.CreateRelationfvRsBdToEpRetFromBridgeDomain(fvBD.DistinguishedName, relationParamName) + if err != nil { + return diag.FromErr(err) + } + + } + if relationTofvRsBDToOut, ok := d.GetOk("relation_fv_rs_bd_to_out"); ok { + relationParamList := toStringList(relationTofvRsBDToOut.(*schema.Set).List()) + for _, relationParam := range relationParamList { + relationParamName := GetMOName(relationParam) + err = aciClient.CreateRelationfvRsBDToOutFromBridgeDomain(fvBD.DistinguishedName, relationParamName) + + if err != nil { + return diag.FromErr(err) + } + } + } + + d.SetId(fvBD.DistinguishedName) + log.Printf("[DEBUG] %s: Creation finished successfully", d.Id()) + + return resourceAciBridgeDomainRead(ctx, d, m) +} + +func resourceAciBridgeDomainUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + if _, ok := d.GetOk("bulk_create"); ok { + return resourceAciBridgeDomainUpdateBulk(ctx, d, m) + } else { + return resourceAciBridgeDomainUpdateOrig(ctx, d, m) + } +} + +func resourceAciBridgeDomainUpdateBulk(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Printf("[DEBUG] BridgeDomain: Beginning Bulk Update") + + aciClient := m.(*client.Client) + desc := d.Get("description").(string) + + name := d.Get("name").(string) + + TenantDn := d.Get("tenant_dn").(string) + + fvBDAttr := models.BridgeDomainAttributes{} + if OptimizeWanBandwidth, ok := d.GetOk("optimize_wan_bandwidth"); ok { + fvBDAttr.OptimizeWanBandwidth = OptimizeWanBandwidth.(string) + } + if Annotation, ok := d.GetOk("annotation"); ok { + fvBDAttr.Annotation = Annotation.(string) + } else { + fvBDAttr.Annotation = "{}" + } + if ArpFlood, ok := d.GetOk("arp_flood"); ok { + fvBDAttr.ArpFlood = ArpFlood.(string) + } + if EpClear, ok := d.GetOk("ep_clear"); ok { + fvBDAttr.EpClear = EpClear.(string) + } + + if EpMoveDetectMode, ok := d.GetOk("ep_move_detect_mode"); ok { + if EpMoveDetectMode == "disable" { + fvBDAttr.EpMoveDetectMode = "{}" + } else { + fvBDAttr.EpMoveDetectMode = EpMoveDetectMode.(string) + } + } + + if HostBasedRouting, ok := d.GetOk("host_based_routing"); ok { + fvBDAttr.HostBasedRouting = HostBasedRouting.(string) + } + if IntersiteBumTrafficAllow, ok := d.GetOk("intersite_bum_traffic_allow"); ok { + fvBDAttr.IntersiteBumTrafficAllow = IntersiteBumTrafficAllow.(string) + } + if IntersiteL2Stretch, ok := d.GetOk("intersite_l2_stretch"); ok { + fvBDAttr.IntersiteL2Stretch = IntersiteL2Stretch.(string) + } + if IpLearning, ok := d.GetOk("ip_learning"); ok { + fvBDAttr.IpLearning = IpLearning.(string) + } + if Ipv6McastAllow, ok := d.GetOk("ipv6_mcast_allow"); ok { + fvBDAttr.Ipv6McastAllow = Ipv6McastAllow.(string) + } + if LimitIpLearnToSubnets, ok := d.GetOk("limit_ip_learn_to_subnets"); ok { + fvBDAttr.LimitIpLearnToSubnets = LimitIpLearnToSubnets.(string) + } + if LlAddr, ok := d.GetOk("ll_addr"); ok { + fvBDAttr.LlAddr = LlAddr.(string) + } + if Mac, ok := d.GetOk("mac"); ok { + fvBDAttr.Mac = Mac.(string) + } + if McastAllow, ok := d.GetOk("mcast_allow"); ok { + fvBDAttr.McastAllow = McastAllow.(string) + } + if MultiDstPktAct, ok := d.GetOk("multi_dst_pkt_act"); ok { + fvBDAttr.MultiDstPktAct = MultiDstPktAct.(string) + } + if NameAlias, ok := d.GetOk("name_alias"); ok { + fvBDAttr.NameAlias = NameAlias.(string) + } + if BridgeDomain_type, ok := d.GetOk("bridge_domain_type"); ok { + fvBDAttr.BridgeDomain_type = BridgeDomain_type.(string) + } + if UnicastRoute, ok := d.GetOk("unicast_route"); ok { + fvBDAttr.UnicastRoute = UnicastRoute.(string) + } + if UnkMacUcastAct, ok := d.GetOk("unk_mac_ucast_act"); ok { + fvBDAttr.UnkMacUcastAct = UnkMacUcastAct.(string) + } + if UnkMcastAct, ok := d.GetOk("unk_mcast_act"); ok { + fvBDAttr.UnkMcastAct = UnkMcastAct.(string) + } + if V6unkMcastAct, ok := d.GetOk("v6unk_mcast_act"); ok { + fvBDAttr.V6unkMcastAct = V6unkMcastAct.(string) + } + if Vmac, ok := d.GetOk("vmac"); ok { + fvBDAttr.Vmac = Vmac.(string) + } + fvBD := models.NewBridgeDomain(fmt.Sprintf("BD-%s", name), TenantDn, desc, fvBDAttr) + + fvBD.Status = "modified" + + err := aciClient.Save(fvBD) + + if err != nil { + return diag.FromErr(err) + } + + checkDns := make([]string, 0, 1) + + if d.HasChange("relation_fv_rs_bd_to_profile") { + _, newRelParam := d.GetChange("relation_fv_rs_bd_to_profile") + checkDns = append(checkDns, newRelParam.(string)) + } + + if d.HasChange("relation_fv_rs_mldsn") { + _, newRelParam := d.GetChange("relation_fv_rs_mldsn") + checkDns = append(checkDns, newRelParam.(string)) + } + + if d.HasChange("relation_fv_rs_abd_pol_mon_pol") { + _, newRelParam := d.GetChange("relation_fv_rs_abd_pol_mon_pol") + checkDns = append(checkDns, newRelParam.(string)) + } + + if d.HasChange("relation_fv_rs_bd_to_nd_p") { + _, newRelParam := d.GetChange("relation_fv_rs_bd_to_nd_p") + checkDns = append(checkDns, newRelParam.(string)) + } + + if d.HasChange("relation_fv_rs_bd_flood_to") { + oldRel, newRel := d.GetChange("relation_fv_rs_bd_flood_to") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) + + for _, relDn := range relToCreate { + checkDns = append(checkDns, relDn) + } + } + + if d.HasChange("relation_fv_rs_bd_to_fhs") { + _, newRelParam := d.GetChange("relation_fv_rs_bd_to_fhs") + checkDns = append(checkDns, newRelParam.(string)) + } + + if d.HasChange("relation_fv_rs_bd_to_relay_p") { + _, newRelParam := d.GetChange("relation_fv_rs_bd_to_relay_p") + checkDns = append(checkDns, newRelParam.(string)) + } + + if d.HasChange("relation_fv_rs_ctx") { + _, newRelParam := d.GetChange("relation_fv_rs_ctx") + checkDns = append(checkDns, newRelParam.(string)) + } + + if d.HasChange("relation_fv_rs_igmpsn") { + _, newRelParam := d.GetChange("relation_fv_rs_igmpsn") + checkDns = append(checkDns, newRelParam.(string)) + } + + if d.HasChange("relation_fv_rs_bd_to_ep_ret") { + _, newRelParam := d.GetChange("relation_fv_rs_bd_to_ep_ret") + checkDns = append(checkDns, newRelParam.(string)) + } + + if d.HasChange("relation_fv_rs_bd_to_out") { + oldRel, newRel := d.GetChange("relation_fv_rs_bd_to_out") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) + + for _, relDn := range relToCreate { + checkDns = append(checkDns, relDn) + } + } + + d.Partial(true) + err = checkTDn(aciClient, checkDns) + if err != nil { + return diag.FromErr(err) + } + d.Partial(false) + + var fvRsAllDataD [][]byte + var fvRsAllDataC [][]byte + var fvRs []byte + + if d.HasChange("relation_fv_rs_bd_to_profile") { + _, newRelParam := d.GetChange("relation_fv_rs_bd_to_profile") + newRelParamName := GetMOName(newRelParam.(string)) + /* + err = aciClient.DeleteRelationfvRsBDToProfileFromBridgeDomain(fvBD.DistinguishedName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupDeleteRelationfvRsBDToProfileFromBridgeDomain(fvBD.DistinguishedName) + fvRsAllDataD = append(fvRsAllDataD, fvRs) + /* + err = aciClient.CreateRelationfvRsBDToProfileFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsBDToProfileFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) + } + if d.HasChange("relation_fv_rs_mldsn") { + _, newRelParam := d.GetChange("relation_fv_rs_mldsn") + newRelParamName := GetMOName(newRelParam.(string)) + /* + err = aciClient.CreateRelationfvRsMldsnFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsMldsnFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) + } + if d.HasChange("relation_fv_rs_abd_pol_mon_pol") { + _, newRelParam := d.GetChange("relation_fv_rs_abd_pol_mon_pol") + newRelParamName := GetMOName(newRelParam.(string)) + /* + err = aciClient.DeleteRelationfvRsABDPolMonPolFromBridgeDomain(fvBD.DistinguishedName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupDeleteRelationfvRsABDPolMonPolFromBridgeDomain(fvBD.DistinguishedName) + fvRsAllDataD = append(fvRsAllDataD, fvRs) + /* + err = aciClient.CreateRelationfvRsABDPolMonPolFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsABDPolMonPolFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) + } + if d.HasChange("relation_fv_rs_bd_to_nd_p") { + _, newRelParam := d.GetChange("relation_fv_rs_bd_to_nd_p") + newRelParamName := GetMOName(newRelParam.(string)) + /* + err = aciClient.CreateRelationfvRsBDToNdPFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsBDToNdPFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) + } + if d.HasChange("relation_fv_rs_bd_flood_to") { + oldRel, newRel := d.GetChange("relation_fv_rs_bd_flood_to") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToDelete := toStringList(oldRelSet.Difference(newRelSet).List()) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) + + for _, relDn := range relToDelete { + /* + err = aciClient.DeleteRelationfvRsBdFloodToFromBridgeDomain(fvBD.DistinguishedName, relDn) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupDeleteRelationfvRsBdFloodToFromBridgeDomain(fvBD.DistinguishedName, relDn) + fvRsAllDataD = append(fvRsAllDataD, fvRs) + } + + for _, relDn := range relToCreate { + /* + err = aciClient.CreateRelationfvRsBdFloodToFromBridgeDomain(fvBD.DistinguishedName, relDn) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsBdFloodToFromBridgeDomain(fvBD.DistinguishedName, relDn) + fvRsAllDataC = append(fvRsAllDataC, fvRs) + } + + } + if d.HasChange("relation_fv_rs_bd_to_fhs") { + _, newRelParam := d.GetChange("relation_fv_rs_bd_to_fhs") + newRelParamName := GetMOName(newRelParam.(string)) + /* + err = aciClient.DeleteRelationfvRsBDToFhsFromBridgeDomain(fvBD.DistinguishedName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupDeleteRelationfvRsBDToFhsFromBridgeDomain(fvBD.DistinguishedName) + fvRsAllDataD = append(fvRsAllDataD, fvRs) + /* + err = aciClient.CreateRelationfvRsBDToFhsFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsBDToFhsFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) + + } + if d.HasChange("relation_fv_rs_bd_to_relay_p") { + _, newRelParam := d.GetChange("relation_fv_rs_bd_to_relay_p") + newRelParamName := GetMOName(newRelParam.(string)) + /* + err = aciClient.DeleteRelationfvRsBDToRelayPFromBridgeDomain(fvBD.DistinguishedName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupDeleteRelationfvRsBDToRelayPFromBridgeDomain(fvBD.DistinguishedName) + fvRsAllDataD = append(fvRsAllDataD, fvRs) + /* + err = aciClient.CreateRelationfvRsBDToRelayPFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsBDToRelayPFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) + } + if d.HasChange("relation_fv_rs_ctx") { + _, newRelParam := d.GetChange("relation_fv_rs_ctx") + err := checkForSubnetConflict(aciClient, d.Id(), newRelParam.(string)) + if err != nil { + return diag.FromErr(err) + } + newRelParamName := GetMOName(newRelParam.(string)) + /* + err = aciClient.CreateRelationfvRsCtxFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsCtxFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) + } + if d.HasChange("relation_fv_rs_bd_to_netflow_monitor_pol") { + oldRel, newRel := d.GetChange("relation_fv_rs_bd_to_netflow_monitor_pol") + oldRelList := oldRel.(*schema.Set).List() + newRelList := newRel.(*schema.Set).List() + for _, relationParam := range oldRelList { + paramMap := relationParam.(map[string]interface{}) + /* + err = aciClient.DeleteRelationfvRsBDToNetflowMonitorPolFromBridgeDomain(fvBD.DistinguishedName, GetMOName(paramMap["tn_netflow_monitor_pol_name"].(string)), paramMap["flt_type"].(string)) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupDeleteRelationfvRsBDToNetflowMonitorPolFromBridgeDomain(fvBD.DistinguishedName, GetMOName(paramMap["tn_netflow_monitor_pol_name"].(string)), paramMap["flt_type"].(string)) + fvRsAllDataD = append(fvRsAllDataD, fvRs) + } + for _, relationParam := range newRelList { + paramMap := relationParam.(map[string]interface{}) + /* + err = aciClient.CreateRelationfvRsBDToNetflowMonitorPolFromBridgeDomain(fvBD.DistinguishedName, GetMOName(paramMap["tn_netflow_monitor_pol_name"].(string)), paramMap["flt_type"].(string)) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsBDToNetflowMonitorPolFromBridgeDomain(fvBD.DistinguishedName, GetMOName(paramMap["tn_netflow_monitor_pol_name"].(string)), paramMap["flt_type"].(string)) + fvRsAllDataC = append(fvRsAllDataC, fvRs) + } + } + if d.HasChange("relation_fv_rs_igmpsn") { + _, newRelParam := d.GetChange("relation_fv_rs_igmpsn") + newRelParamName := GetMOName(newRelParam.(string)) + /* + err = aciClient.CreateRelationfvRsIgmpsnFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsIgmpsnFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) + } + if d.HasChange("relation_fv_rs_bd_to_ep_ret") { + _, newRelParam := d.GetChange("relation_fv_rs_bd_to_ep_ret") + newRelParamName := GetMOName(newRelParam.(string)) + /* + err = aciClient.CreateRelationfvRsBdToEpRetFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsBdToEpRetFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) + } + if d.HasChange("relation_fv_rs_bd_to_out") { + oldRel, newRel := d.GetChange("relation_fv_rs_bd_to_out") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToDelete := toStringList(oldRelSet.Difference(newRelSet).List()) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) + + for _, relDn := range relToDelete { + relDnName := GetMOName(relDn) + /* + err = aciClient.DeleteRelationfvRsBDToOutFromBridgeDomain(fvBD.DistinguishedName, relDnName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupDeleteRelationfvRsBDToOutFromBridgeDomain(fvBD.DistinguishedName, relDnName) + fvRsAllDataD = append(fvRsAllDataD, fvRs) + } + + for _, relDn := range relToCreate { + relDnName := GetMOName(relDn) + /* + err = aciClient.CreateRelationfvRsBDToOutFromBridgeDomain(fvBD.DistinguishedName, relDnName) + if err != nil { + return diag.FromErr(err) + } + */ + fvRs = aciClient.SetupCreateRelationfvRsBDToOutFromBridgeDomain(fvBD.DistinguishedName, relDnName) + fvRsAllDataC = append(fvRsAllDataC, fvRs) + } + + } + + if len(fvRsAllDataD) > 0 { + err = aciClient.RenderRelationfvRsAllFromBridgeDomain(fvBD, fvRsAllDataD) + if err != nil { + return diag.FromErr(err) + } + } + + if len(fvRsAllDataC) > 0 { + err = aciClient.RenderRelationfvRsAllFromBridgeDomain(fvBD, fvRsAllDataC) + if err != nil { + return diag.FromErr(err) + } + } + + d.SetId(fvBD.DistinguishedName) + log.Printf("[DEBUG] %s: Bulk Update finished successfully", d.Id()) + + return resourceAciBridgeDomainRead(ctx, d, m) + +} + +func resourceAciBridgeDomainUpdateOrig(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Printf("[DEBUG] BridgeDomain: Beginning Update") + + aciClient := m.(*client.Client) + desc := d.Get("description").(string) + + name := d.Get("name").(string) + + TenantDn := d.Get("tenant_dn").(string) + + fvBDAttr := models.BridgeDomainAttributes{} + if OptimizeWanBandwidth, ok := d.GetOk("optimize_wan_bandwidth"); ok { + fvBDAttr.OptimizeWanBandwidth = OptimizeWanBandwidth.(string) + } + if Annotation, ok := d.GetOk("annotation"); ok { + fvBDAttr.Annotation = Annotation.(string) + } else { + fvBDAttr.Annotation = "{}" + } + if ArpFlood, ok := d.GetOk("arp_flood"); ok { + fvBDAttr.ArpFlood = ArpFlood.(string) + } + if EpClear, ok := d.GetOk("ep_clear"); ok { + fvBDAttr.EpClear = EpClear.(string) + } + + if EpMoveDetectMode, ok := d.GetOk("ep_move_detect_mode"); ok { + if EpMoveDetectMode == "disable" { + fvBDAttr.EpMoveDetectMode = "{}" + } else { + fvBDAttr.EpMoveDetectMode = EpMoveDetectMode.(string) + } + } + + if HostBasedRouting, ok := d.GetOk("host_based_routing"); ok { + fvBDAttr.HostBasedRouting = HostBasedRouting.(string) + } + if IntersiteBumTrafficAllow, ok := d.GetOk("intersite_bum_traffic_allow"); ok { + fvBDAttr.IntersiteBumTrafficAllow = IntersiteBumTrafficAllow.(string) + } + if IntersiteL2Stretch, ok := d.GetOk("intersite_l2_stretch"); ok { + fvBDAttr.IntersiteL2Stretch = IntersiteL2Stretch.(string) + } + if IpLearning, ok := d.GetOk("ip_learning"); ok { + fvBDAttr.IpLearning = IpLearning.(string) + } + if Ipv6McastAllow, ok := d.GetOk("ipv6_mcast_allow"); ok { + fvBDAttr.Ipv6McastAllow = Ipv6McastAllow.(string) + } + if LimitIpLearnToSubnets, ok := d.GetOk("limit_ip_learn_to_subnets"); ok { + fvBDAttr.LimitIpLearnToSubnets = LimitIpLearnToSubnets.(string) + } + if LlAddr, ok := d.GetOk("ll_addr"); ok { + fvBDAttr.LlAddr = LlAddr.(string) + } + if Mac, ok := d.GetOk("mac"); ok { + fvBDAttr.Mac = Mac.(string) + } + if McastAllow, ok := d.GetOk("mcast_allow"); ok { + fvBDAttr.McastAllow = McastAllow.(string) + } + if MultiDstPktAct, ok := d.GetOk("multi_dst_pkt_act"); ok { + fvBDAttr.MultiDstPktAct = MultiDstPktAct.(string) + } + if NameAlias, ok := d.GetOk("name_alias"); ok { + fvBDAttr.NameAlias = NameAlias.(string) + } + if BridgeDomain_type, ok := d.GetOk("bridge_domain_type"); ok { + fvBDAttr.BridgeDomain_type = BridgeDomain_type.(string) + } + if UnicastRoute, ok := d.GetOk("unicast_route"); ok { + fvBDAttr.UnicastRoute = UnicastRoute.(string) + } + if UnkMacUcastAct, ok := d.GetOk("unk_mac_ucast_act"); ok { + fvBDAttr.UnkMacUcastAct = UnkMacUcastAct.(string) + } + if UnkMcastAct, ok := d.GetOk("unk_mcast_act"); ok { + fvBDAttr.UnkMcastAct = UnkMcastAct.(string) + } + if V6unkMcastAct, ok := d.GetOk("v6unk_mcast_act"); ok { + fvBDAttr.V6unkMcastAct = V6unkMcastAct.(string) + } + if Vmac, ok := d.GetOk("vmac"); ok { + fvBDAttr.Vmac = Vmac.(string) + } + fvBD := models.NewBridgeDomain(fmt.Sprintf("BD-%s", name), TenantDn, desc, fvBDAttr) + + fvBD.Status = "modified" + + err := aciClient.Save(fvBD) + + if err != nil { + return diag.FromErr(err) + } + + checkDns := make([]string, 0, 1) + + if d.HasChange("relation_fv_rs_bd_to_profile") { + _, newRelParam := d.GetChange("relation_fv_rs_bd_to_profile") + checkDns = append(checkDns, newRelParam.(string)) + } + + if d.HasChange("relation_fv_rs_mldsn") { + _, newRelParam := d.GetChange("relation_fv_rs_mldsn") + checkDns = append(checkDns, newRelParam.(string)) + } + + if d.HasChange("relation_fv_rs_abd_pol_mon_pol") { + _, newRelParam := d.GetChange("relation_fv_rs_abd_pol_mon_pol") + checkDns = append(checkDns, newRelParam.(string)) + } + + if d.HasChange("relation_fv_rs_bd_to_nd_p") { + _, newRelParam := d.GetChange("relation_fv_rs_bd_to_nd_p") + checkDns = append(checkDns, newRelParam.(string)) + } + + if d.HasChange("relation_fv_rs_bd_flood_to") { + oldRel, newRel := d.GetChange("relation_fv_rs_bd_flood_to") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) + + for _, relDn := range relToCreate { + checkDns = append(checkDns, relDn) + } + } + + if d.HasChange("relation_fv_rs_bd_to_fhs") { + _, newRelParam := d.GetChange("relation_fv_rs_bd_to_fhs") + checkDns = append(checkDns, newRelParam.(string)) + } + + if d.HasChange("relation_fv_rs_bd_to_relay_p") { + _, newRelParam := d.GetChange("relation_fv_rs_bd_to_relay_p") + checkDns = append(checkDns, newRelParam.(string)) + } + + if d.HasChange("relation_fv_rs_ctx") { + _, newRelParam := d.GetChange("relation_fv_rs_ctx") + checkDns = append(checkDns, newRelParam.(string)) + } + + if d.HasChange("relation_fv_rs_igmpsn") { + _, newRelParam := d.GetChange("relation_fv_rs_igmpsn") + checkDns = append(checkDns, newRelParam.(string)) + } + + if d.HasChange("relation_fv_rs_bd_to_ep_ret") { + _, newRelParam := d.GetChange("relation_fv_rs_bd_to_ep_ret") + checkDns = append(checkDns, newRelParam.(string)) + } + + if d.HasChange("relation_fv_rs_bd_to_out") { + oldRel, newRel := d.GetChange("relation_fv_rs_bd_to_out") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) + + for _, relDn := range relToCreate { + checkDns = append(checkDns, relDn) + } + } + + d.Partial(true) + err = checkTDn(aciClient, checkDns) + if err != nil { + return diag.FromErr(err) + } + d.Partial(false) + + if d.HasChange("relation_fv_rs_bd_to_profile") { + _, newRelParam := d.GetChange("relation_fv_rs_bd_to_profile") + newRelParamName := GetMOName(newRelParam.(string)) + err = aciClient.DeleteRelationfvRsBDToProfileFromBridgeDomain(fvBD.DistinguishedName) + if err != nil { + return diag.FromErr(err) + } + err = aciClient.CreateRelationfvRsBDToProfileFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + if err != nil { + return diag.FromErr(err) + } + + } + if d.HasChange("relation_fv_rs_mldsn") { + _, newRelParam := d.GetChange("relation_fv_rs_mldsn") + newRelParamName := GetMOName(newRelParam.(string)) + err = aciClient.CreateRelationfvRsMldsnFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + if err != nil { + return diag.FromErr(err) + } + + } + if d.HasChange("relation_fv_rs_abd_pol_mon_pol") { + _, newRelParam := d.GetChange("relation_fv_rs_abd_pol_mon_pol") + newRelParamName := GetMOName(newRelParam.(string)) + err = aciClient.DeleteRelationfvRsABDPolMonPolFromBridgeDomain(fvBD.DistinguishedName) + if err != nil { + return diag.FromErr(err) + } + err = aciClient.CreateRelationfvRsABDPolMonPolFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + if err != nil { + return diag.FromErr(err) + } + + } + if d.HasChange("relation_fv_rs_bd_to_nd_p") { + _, newRelParam := d.GetChange("relation_fv_rs_bd_to_nd_p") + newRelParamName := GetMOName(newRelParam.(string)) + err = aciClient.CreateRelationfvRsBDToNdPFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + if err != nil { + return diag.FromErr(err) + } + + } + if d.HasChange("relation_fv_rs_bd_flood_to") { + oldRel, newRel := d.GetChange("relation_fv_rs_bd_flood_to") + oldRelSet := oldRel.(*schema.Set) + newRelSet := newRel.(*schema.Set) + relToDelete := toStringList(oldRelSet.Difference(newRelSet).List()) + relToCreate := toStringList(newRelSet.Difference(oldRelSet).List()) + + for _, relDn := range relToDelete { + err = aciClient.DeleteRelationfvRsBdFloodToFromBridgeDomain(fvBD.DistinguishedName, relDn) + if err != nil { + return diag.FromErr(err) + } + + } + + for _, relDn := range relToCreate { + err = aciClient.CreateRelationfvRsBdFloodToFromBridgeDomain(fvBD.DistinguishedName, relDn) + if err != nil { + return diag.FromErr(err) + } + + } + + } + if d.HasChange("relation_fv_rs_bd_to_fhs") { + _, newRelParam := d.GetChange("relation_fv_rs_bd_to_fhs") + newRelParamName := GetMOName(newRelParam.(string)) + err = aciClient.DeleteRelationfvRsBDToFhsFromBridgeDomain(fvBD.DistinguishedName) + if err != nil { + return diag.FromErr(err) + } + err = aciClient.CreateRelationfvRsBDToFhsFromBridgeDomain(fvBD.DistinguishedName, newRelParamName) + if err != nil { return diag.FromErr(err) } @@ -1172,6 +1962,183 @@ func resourceAciBridgeDomainUpdate(ctx context.Context, d *schema.ResourceData, } func resourceAciBridgeDomainRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + if _, ok := d.GetOk("bulk_read"); ok { + return resourceAciBridgeDomainReadBulk(ctx, d, m) + } else { + return resourceAciBridgeDomainReadOrig(ctx, d, m) + } +} + +func resourceAciBridgeDomainReadBulk(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Printf("[DEBUG] %s: Beginning Bulk Read", d.Id()) + + aciClient := m.(*client.Client) + + dn := d.Id() + fvBD, err := getRemoteBridgeDomain(aciClient, dn) + + if err != nil { + return errorForObjectNotFound(err, dn, d) + } + + if fvBD.EpMoveDetectMode == "" { + fvBD.EpMoveDetectMode = "disable" + } + + _, err = setBridgeDomainAttributes(fvBD, d) + + if err != nil { + d.SetId("") + return nil + } + + fvRsAllDataR, err := aciClient.ReadRelationfvRsAllBridgeDomain(dn) + + if len(fvRsAllDataR) > 0 { + //fvRsBDToProfileData, err := aciClient.ReadRelationfvRsBDToProfileFromBridgeDomain(dn) + //if err != nil { + fvRsBDToProfileData := fvRsAllDataR["fvRsBDToProfile"] + if fvRsBDToProfileData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsBDToProfile %v", err) + d.Set("relation_fv_rs_bd_to_profile", "") + + } else { + setRelationAttribute(d, "relation_fv_rs_bd_to_profile", fvRsBDToProfileData.(string)) + } + + //fvRsMldsnData, err := aciClient.ReadRelationfvRsMldsnFromBridgeDomain(dn) + //if err != nil { + fvRsMldsnData := fvRsAllDataR["fvRsMldsn"] + if fvRsMldsnData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsMldsn %v", err) + d.Set("relation_fv_rs_mldsn", "") + + } else { + setRelationAttribute(d, "relation_fv_rs_mldsn", fvRsMldsnData.(string)) + } + + //fvRsABDPolMonPolData, err := aciClient.ReadRelationfvRsABDPolMonPolFromBridgeDomain(dn) + //if err != nil { + fvRsABDPolMonPolData := fvRsAllDataR["fvRsABDPolMonPol"] + if fvRsABDPolMonPolData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsABDPolMonPol %v", err) + d.Set("relation_fv_rs_abd_pol_mon_pol", "") + + } else { + setRelationAttribute(d, "relation_fv_rs_abd_pol_mon_pol", fvRsABDPolMonPolData.(string)) + } + + //fvRsBDToNdPData, err := aciClient.ReadRelationfvRsBDToNdPFromBridgeDomain(dn) + //if err != nil { + fvRsBDToNdPData := fvRsAllDataR["fvRsBDToNdP"] + if fvRsBDToNdPData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsBDToNdP %v", err) + d.Set("relation_fv_rs_bd_to_nd_p", "") + + } else { + setRelationAttribute(d, "relation_fv_rs_bd_to_nd_p", fvRsBDToNdPData.(string)) + } + + //fvRsBdFloodToData, err := aciClient.ReadRelationfvRsBdFloodToFromBridgeDomain(dn) + //if err != nil { + fvRsBdFloodToData := fvRsAllDataR["fvRsBdFloodTo"] + if fvRsBdFloodToData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsBdFloodTo %v", err) + setRelationAttribute(d, "relation_fv_rs_bd_flood_to", make([]interface{}, 0, 1)) + } else { + setRelationAttribute(d, "relation_fv_rs_bd_flood_to", fvRsBdFloodToData) + } + + //fvRsBDToFhsData, err := aciClient.ReadRelationfvRsBDToFhsFromBridgeDomain(dn) + //if err != nil { + fvRsBDToFhsData := fvRsAllDataR["fvRsBDToFhs"] + if fvRsBDToFhsData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsBDToFhs %v", err) + d.Set("relation_fv_rs_bd_to_fhs", "") + + } else { + setRelationAttribute(d, "relation_fv_rs_bd_to_fhs", fvRsBDToFhsData.(string)) + } + + //fvRsBDToRelayPData, err := aciClient.ReadRelationfvRsBDToRelayPFromBridgeDomain(dn) + //if err != nil { + fvRsBDToRelayPData := fvRsAllDataR["fvRsBDToRelayP"] + if fvRsBDToRelayPData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsBDToRelayP %v", err) + d.Set("relation_fv_rs_bd_to_relay_p", "") + + } else { + setRelationAttribute(d, "relation_fv_rs_bd_to_relay_p", fvRsBDToRelayPData.(string)) + } + + //fvRsCtxData, err := aciClient.ReadRelationfvRsCtxFromBridgeDomain(dn) + //if err != nil { + fvRsCtxData := fvRsAllDataR["fvRsCtx"] + if fvRsCtxData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsCtx %v", err) + d.Set("relation_fv_rs_ctx", "") + + } else { + setRelationAttribute(d, "relation_fv_rs_ctx", fvRsCtxData.(string)) + } + + //fvRsBDToNetflowMonitorPolData, err := aciClient.ReadRelationfvRsBDToNetflowMonitorPolFromBridgeDomain(dn) + //if err != nil { + fvRsBDToNetflowMonitorPolData := fvRsAllDataR["fvRsBDToNetflowMonitorPol"] + if fvRsBDToNetflowMonitorPolData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsBDToNetflowMonitorPol %v", err) + + } else { + listRelMap := make([]map[string]string, 0, 1) + listfvRsBDToNetflowMonitorPolData := fvRsBDToNetflowMonitorPolData.([]map[string]string) + for _, obj := range listfvRsBDToNetflowMonitorPolData { + listRelMap = append(listRelMap, map[string]string{ + "tn_netflow_monitor_pol_name": obj["tnNetflowMonitorPolName"], + "flt_type": obj["fltType"], + }) + } + d.Set("relation_fv_rs_bd_to_netflow_monitor_pol", listRelMap) + } + + //fvRsIgmpsnData, err := aciClient.ReadRelationfvRsIgmpsnFromBridgeDomain(dn) + //if err != nil { + fvRsIgmpsnData := fvRsAllDataR["fvRsIgmpsn"] + if fvRsIgmpsnData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsIgmpsn %v", err) + d.Set("relation_fv_rs_igmpsn", "") + + } else { + setRelationAttribute(d, "relation_fv_rs_igmpsn", fvRsIgmpsnData.(string)) + } + + //fvRsBdToEpRetData, err := aciClient.ReadRelationfvRsBdToEpRetFromBridgeDomain(dn) + //if err != nil { + fvRsBdToEpRetData := fvRsAllDataR["fvRsBdToEpRet"] + if fvRsBdToEpRetData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsBdToEpRet %v", err) + d.Set("relation_fv_rs_bd_to_ep_ret", "") + + } else { + setRelationAttribute(d, "relation_fv_rs_bd_to_ep_ret", fvRsBdToEpRetData.(string)) + } + + //fvRsBDToOutData, err := aciClient.ReadRelationfvRsBDToOutFromBridgeDomain(dn) + //if err != nil { + fvRsBDToOutData := fvRsAllDataR["fvRsBDToOut"] + if fvRsBDToOutData == nil { + log.Printf("[DEBUG] Error while reading relation fvRsBDToOut %v", err) + setRelationAttribute(d, "relation_fv_rs_bd_to_out", make([]interface{}, 0, 1)) + } else { + setRelationAttribute(d, "relation_fv_rs_bd_to_out", toStringList(fvRsBDToOutData.(*schema.Set).List())) + } + } + + log.Printf("[DEBUG] %s: Bulk Read finished successfully", d.Id()) + + return nil +} + +func resourceAciBridgeDomainReadOrig(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Printf("[DEBUG] %s: Beginning Read", d.Id()) aciClient := m.(*client.Client) diff --git a/examples/bulk/: b/examples/bulk/: new file mode 100644 index 000000000..978cfaa23 --- /dev/null +++ b/examples/bulk/: @@ -0,0 +1,15 @@ +erraform { + required_providers { + aci = { + source = "ciscodevnet/aci" + } + } +} + +provider "aci" { + username = "admin" # + password = "Redmoon0" # + url = "https://10.0.2.214" # + insecure = true +} + diff --git a/examples/bulk/bd.tf b/examples/bulk/bd.tf new file mode 100644 index 000000000..7e50553b0 --- /dev/null +++ b/examples/bulk/bd.tf @@ -0,0 +1,52 @@ +resource "aci_bridge_domain" "bd_for_rel" { + count = 1 + tenant_dn = aci_tenant.tenant_for_benchmark.id + name = "test_tf_bd_rel-${count.index+1}" + description = "This bridge domain is created by terraform ACI provider" + mac = "00:22:BD:F8:19:FF" + optimize_wan_bandwidth = "no" + arp_flood = "yes" + ep_clear = "no" + ep_move_detect_mode = "garp" + intersite_bum_traffic_allow = "yes" + intersite_l2_stretch = "yes" + ip_learning = "yes" + limit_ip_learn_to_subnets = "yes" + mcast_allow = "yes" + multi_dst_pkt_act = "bd-flood" + bridge_domain_type = "regular" + unicast_route = "yes" + unk_mac_ucast_act = "flood" + unk_mcast_act = "flood" + vmac = "not-applicable" + relation_fv_rs_ctx = aci_vrf.test_tf_vrf-1.id # relation to VRF + relation_fv_rs_bd_to_profile = aci_route_control_profile.example.id # Relation to L3Outs Route Map For Import and Export Route Control + relation_fv_rs_bd_to_relay_p = aci_rest.rest_dhcp_RelayP.id # Relation to DHCP Relay policy + relation_fv_rs_abd_pol_mon_pol = aci_rest.rest_mon_epg_pol.id # Relation to Monitors policy + relation_fv_rs_bd_flood_to = [aci_filter.bd_flood_filter.id, aci_filter.bd_flood_filter2.id] # Relation to Contract Filters + relation_fv_rs_bd_to_fhs = aci_rest.rest_fhs_bd_pol.id # Relation to FHS policy. Requires unicast_route to be set to "yes" + + relation_fv_rs_bd_to_netflow_monitor_pol { + tn_netflow_monitor_pol_name = aci_rest.rest_net_flow_pol.id + flt_type = "ipv4" + } + + relation_fv_rs_bd_to_netflow_monitor_pol { + tn_netflow_monitor_pol_name = aci_rest.rest_net_flow_pol2.id + flt_type = "ipv6" + } + + relation_fv_rs_bd_to_out = [aci_rest.rest_l3_ext_out.id, aci_rest.rest_l3_ext_out2.id] # Relation to L3Outs + + ### + + relation_fv_rs_mldsn = aci_rest.rest_mld_snoop_pol.id + relation_fv_rs_igmpsn = aci_rest.rest_igmp_snoop_pol.id + relation_fv_rs_bd_to_ep_ret = aci_rest.rest_endpoint_ret_pol.id + relation_fv_rs_bd_to_nd_p = aci_rest.rest_nd_if_pol.id + + bulk_create = true + bulk_read = false + bulk_update = true +} + diff --git a/examples/bulk/bd1.tf.ste b/examples/bulk/bd1.tf.ste new file mode 100644 index 000000000..7e50553b0 --- /dev/null +++ b/examples/bulk/bd1.tf.ste @@ -0,0 +1,52 @@ +resource "aci_bridge_domain" "bd_for_rel" { + count = 1 + tenant_dn = aci_tenant.tenant_for_benchmark.id + name = "test_tf_bd_rel-${count.index+1}" + description = "This bridge domain is created by terraform ACI provider" + mac = "00:22:BD:F8:19:FF" + optimize_wan_bandwidth = "no" + arp_flood = "yes" + ep_clear = "no" + ep_move_detect_mode = "garp" + intersite_bum_traffic_allow = "yes" + intersite_l2_stretch = "yes" + ip_learning = "yes" + limit_ip_learn_to_subnets = "yes" + mcast_allow = "yes" + multi_dst_pkt_act = "bd-flood" + bridge_domain_type = "regular" + unicast_route = "yes" + unk_mac_ucast_act = "flood" + unk_mcast_act = "flood" + vmac = "not-applicable" + relation_fv_rs_ctx = aci_vrf.test_tf_vrf-1.id # relation to VRF + relation_fv_rs_bd_to_profile = aci_route_control_profile.example.id # Relation to L3Outs Route Map For Import and Export Route Control + relation_fv_rs_bd_to_relay_p = aci_rest.rest_dhcp_RelayP.id # Relation to DHCP Relay policy + relation_fv_rs_abd_pol_mon_pol = aci_rest.rest_mon_epg_pol.id # Relation to Monitors policy + relation_fv_rs_bd_flood_to = [aci_filter.bd_flood_filter.id, aci_filter.bd_flood_filter2.id] # Relation to Contract Filters + relation_fv_rs_bd_to_fhs = aci_rest.rest_fhs_bd_pol.id # Relation to FHS policy. Requires unicast_route to be set to "yes" + + relation_fv_rs_bd_to_netflow_monitor_pol { + tn_netflow_monitor_pol_name = aci_rest.rest_net_flow_pol.id + flt_type = "ipv4" + } + + relation_fv_rs_bd_to_netflow_monitor_pol { + tn_netflow_monitor_pol_name = aci_rest.rest_net_flow_pol2.id + flt_type = "ipv6" + } + + relation_fv_rs_bd_to_out = [aci_rest.rest_l3_ext_out.id, aci_rest.rest_l3_ext_out2.id] # Relation to L3Outs + + ### + + relation_fv_rs_mldsn = aci_rest.rest_mld_snoop_pol.id + relation_fv_rs_igmpsn = aci_rest.rest_igmp_snoop_pol.id + relation_fv_rs_bd_to_ep_ret = aci_rest.rest_endpoint_ret_pol.id + relation_fv_rs_bd_to_nd_p = aci_rest.rest_nd_if_pol.id + + bulk_create = true + bulk_read = false + bulk_update = true +} + diff --git a/examples/bulk/bd2.tf.ste b/examples/bulk/bd2.tf.ste new file mode 100644 index 000000000..4901f6921 --- /dev/null +++ b/examples/bulk/bd2.tf.ste @@ -0,0 +1,51 @@ +resource "aci_bridge_domain" "bd_for_rel" { + count = 1 + tenant_dn = aci_tenant.tenant_for_benchmark.id + name = "test_tf_bd_rel-${count.index+1}" + description = "This bridge domain is created by terraform ACI provider" + mac = "00:22:BD:F8:19:FF" + optimize_wan_bandwidth = "no" + arp_flood = "yes" + ep_clear = "no" + ep_move_detect_mode = "garp" + intersite_bum_traffic_allow = "yes" + intersite_l2_stretch = "yes" + ip_learning = "yes" + limit_ip_learn_to_subnets = "yes" + mcast_allow = "yes" + multi_dst_pkt_act = "bd-flood" + bridge_domain_type = "regular" + unicast_route = "yes" + unk_mac_ucast_act = "flood" + unk_mcast_act = "flood" + vmac = "not-applicable" + relation_fv_rs_ctx = aci_vrf.test_tf_vrf-1.id # relation to VRF + relation_fv_rs_bd_to_profile = aci_route_control_profile.example.id # Relation to L3Outs Route Map For Import and Export Route Control + relation_fv_rs_bd_to_relay_p = aci_rest.rest_dhcp_RelayP.id # Relation to DHCP Relay policy + relation_fv_rs_abd_pol_mon_pol = aci_rest.rest_mon_epg_pol.id # Relation to Monitors policy + relation_fv_rs_bd_flood_to = [aci_filter.bd_flood_filter.id, aci_filter.bd_flood_filter3.id] # Relation to Contract Filters + relation_fv_rs_bd_to_fhs = aci_rest.rest_fhs_bd_pol.id # Relation to FHS policy. Requires unicast_route to be set to "yes" + + relation_fv_rs_bd_to_netflow_monitor_pol { + tn_netflow_monitor_pol_name = aci_rest.rest_net_flow_pol.id + flt_type = "ipv4" + } + + relation_fv_rs_bd_to_netflow_monitor_pol { + tn_netflow_monitor_pol_name = aci_rest.rest_net_flow_pol2.id + flt_type = "ipv6" + } + + relation_fv_rs_bd_to_out = [aci_rest.rest_l3_ext_out.id, aci_rest.rest_l3_ext_out3.id] # Relation to L3Outs + + ### + + relation_fv_rs_mldsn = aci_rest.rest_mld_snoop_pol.id + relation_fv_rs_igmpsn = aci_rest.rest_igmp_snoop_pol.id + relation_fv_rs_bd_to_ep_ret = aci_rest.rest_endpoint_ret_pol.id + relation_fv_rs_bd_to_nd_p = aci_rest.rest_nd_if_pol.id + + bulk_create = true + bulk_read = false + bulk_update = true +} diff --git a/examples/bulk/contract.tf b/examples/bulk/contract.tf new file mode 100644 index 000000000..1346c3eca --- /dev/null +++ b/examples/bulk/contract.tf @@ -0,0 +1,137 @@ +resource "aci_l4_l7_service_graph_template" "rest_abs_graph" { + tenant_dn = data.aci_tenant.tenant_for_contract.id + name = "testgraph" +} + +resource "aci_l4_l7_service_graph_template" "rest_abs_graph2" { + tenant_dn = data.aci_tenant.tenant_for_contract.id + name = "testgraph2" +} + +resource "aci_l4_l7_service_graph_template" "rest_abs_graph3" { + tenant_dn = data.aci_tenant.tenant_for_contract.id + name = "testgraph3" +} + +resource "aci_contract" "rs_prov_contract" { + tenant_dn = data.aci_tenant.tenant_for_contract.id + name = "rs_prov_contract" + description = "This contract is created by terraform ACI provider" + scope = "context" + target_dscp = "VA" + prio = "unspecified" + relation_vz_rs_graph_att = aci_l4_l7_service_graph_template.rest_abs_graph.id +} + +resource "aci_contract" "rs_prov_contract2" { + tenant_dn = data.aci_tenant.tenant_for_contract.id + name = "rs_prov_contract2" + description = "This contract is created by terraform ACI provider" + scope = "context" + target_dscp = "VA" + prio = "unspecified" + relation_vz_rs_graph_att = aci_l4_l7_service_graph_template.rest_abs_graph2.id +} + +resource "aci_contract" "rs_prov_contract3" { + tenant_dn = data.aci_tenant.tenant_for_contract.id + name = "rs_prov_contract3" + description = "This contract is created by terraform ACI provider" + scope = "context" + target_dscp = "VA" + prio = "unspecified" + relation_vz_rs_graph_att = aci_l4_l7_service_graph_template.rest_abs_graph3.id +} + +resource "aci_contract" "rs_cons_contract" { + tenant_dn = data.aci_tenant.tenant_for_contract.id + name = "rs_cons_contract" + description = "This contract is created by terraform ACI provider" + scope = "context" + target_dscp = "VA" + prio = "unspecified" + relation_vz_rs_graph_att = aci_l4_l7_service_graph_template.rest_abs_graph.id +} + +resource "aci_contract" "rs_cons_contract2" { + tenant_dn = data.aci_tenant.tenant_for_contract.id + name = "rs_cons_contract2" + description = "This contract is created by terraform ACI provider" + scope = "context" + target_dscp = "VA" + prio = "unspecified" + relation_vz_rs_graph_att = aci_l4_l7_service_graph_template.rest_abs_graph2.id +} + +resource "aci_contract" "rs_cons_contract3" { + tenant_dn = data.aci_tenant.tenant_for_contract.id + name = "rs_cons_contract3" + description = "This contract is created by terraform ACI provider" + scope = "context" + target_dscp = "VA" + prio = "unspecified" + relation_vz_rs_graph_att = aci_l4_l7_service_graph_template.rest_abs_graph2.id +} + +resource "aci_contract" "intra_epg_contract" { + tenant_dn = data.aci_tenant.tenant_for_contract.id + name = "intra_epg_contract" + description = "This contract is created by terraform ACI provider" + scope = "context" + target_dscp = "VA" + prio = "unspecified" + relation_vz_rs_graph_att = aci_l4_l7_service_graph_template.rest_abs_graph.id +} + +resource "aci_contract" "intra_epg_contract2" { + tenant_dn = data.aci_tenant.tenant_for_contract.id + name = "intra_epg_contract2" + description = "This contract is created by terraform ACI provider" + scope = "context" + target_dscp = "VA" + prio = "unspecified" + relation_vz_rs_graph_att = aci_l4_l7_service_graph_template.rest_abs_graph2.id +} + +resource "aci_contract" "intra_epg_contract3" { + tenant_dn = data.aci_tenant.tenant_for_contract.id + name = "intra_epg_contract3" + description = "This contract is created by terraform ACI provider" + scope = "context" + target_dscp = "VA" + prio = "unspecified" + relation_vz_rs_graph_att = aci_l4_l7_service_graph_template.rest_abs_graph3.id +} + +// Taboo Contract +resource "aci_taboo_contract" "rest_taboo_con" { + tenant_dn = aci_tenant.tenant_for_benchmark.id + name = "testtaboo" +} + +resource "aci_taboo_contract" "rest_taboo_con2" { + tenant_dn = aci_tenant.tenant_for_benchmark.id + name = "testtaboo2" +} + +resource "aci_taboo_contract" "rest_taboo_con3" { + tenant_dn = aci_tenant.tenant_for_benchmark.id + name = "testtaboo3" +} + +// Imported Contract +resource "aci_imported_contract" "rest_vz_cons_if" { + tenant_dn = aci_tenant.tenant_for_benchmark.id + name = "testcontract" +} + +resource "aci_imported_contract" "rest_vz_cons_if2" { + tenant_dn = aci_tenant.tenant_for_benchmark.id + name = "testcontract2" +} + +resource "aci_imported_contract" "rest_vz_cons_if3" { + tenant_dn = aci_tenant.tenant_for_benchmark.id + name = "testcontract3" +} + diff --git a/examples/bulk/epg.tf b/examples/bulk/epg.tf new file mode 100644 index 000000000..fbcd1096c --- /dev/null +++ b/examples/bulk/epg.tf @@ -0,0 +1,53 @@ +resource "aci_application_profile" "app_profile_for_epg" { + tenant_dn = aci_tenant.tenant_for_benchmark.id + name = "ap_for_epg" + description = "This app profile is created by terraform ACI providers" +} + +resource "aci_application_epg" "inherit_epg" { + application_profile_dn = aci_application_profile.app_profile_for_epg.id + name = "inherit_epg" + description = "epg to create relation sec_inherited" +} + +resource "aci_application_epg" "inherit_epg2" { + application_profile_dn = aci_application_profile.app_profile_for_epg.id + name = "inherit_epg2" + description = "epg to create relation sec_inherited" +} + + +// Creation of Monitoring policy +resource "aci_monitoring_policy" "rest_mon_epg_pol" { + tenant_dn = aci_tenant.tenant_for_benchmark.id + name = "testpol" +} + +resource "aci_application_epg" "demoepg" { + count = 1 + application_profile_dn = aci_application_profile.app_profile_for_epg.id + name = "tf_test_epg-${count.index+1}" + description = "This epg is created by terraform ACI providers" + flood_on_encap = "disabled" + fwd_ctrl = "none" + is_attr_based_epg = "no" + match_t = "None" + pc_enf_pref = "unenforced" + pref_gr_memb = "include" + prio = "unspecified" + relation_fv_rs_bd = aci_bridge_domain.bd_for_rel[count.index].id # Relations to Bridge Domain + relation_fv_rs_cust_qos_pol = aci_rest.rest_qos_custom_pol.id # Relation to Custom Quality of Service - QoS traffic policy + relation_fv_rs_prov = [aci_contract.rs_prov_contract.id, aci_contract.rs_prov_contract2.id] # Relations to Provided Contracts + relation_fv_rs_cons_if = [aci_imported_contract.rest_vz_cons_if.id, aci_imported_contract.rest_vz_cons_if2.id] # Relations to Imported Contracts + relation_fv_rs_sec_inherited = [aci_application_epg.inherit_epg.id, aci_application_epg.inherit_epg2.id] # Relations to inherit security configuration from another EPG + relation_fv_rs_dpp_pol = aci_rest.rest_qos_dpp_pol.id # Relation to Data Plane Policing + relation_fv_rs_cons = [aci_contract.rs_cons_contract.id, aci_contract.rs_cons_contract2.id] # Relations to Consumed Contracts + relation_fv_rs_trust_ctrl = aci_rest.rest_trust_ctrl_pol.id # Relation to First Hop Security trust control + relation_fv_rs_prot_by = [aci_taboo_contract.rest_taboo_con.id, aci_taboo_contract.rest_taboo_con2.id] # Relations to vzTaboo Taboo Contracts + relation_fv_rs_aepg_mon_pol = aci_monitoring_policy.rest_mon_epg_pol.id # Relation to Monitoring policy + relation_fv_rs_intra_epg = [aci_contract.intra_epg_contract.id, aci_contract.intra_epg_contract2.id] # Relations to Intra EPG Contracts + + bulk_create = true + bulk_read = false + bulk_update = true +} diff --git a/examples/bulk/epg1.tf.ste b/examples/bulk/epg1.tf.ste new file mode 100644 index 000000000..fbcd1096c --- /dev/null +++ b/examples/bulk/epg1.tf.ste @@ -0,0 +1,53 @@ +resource "aci_application_profile" "app_profile_for_epg" { + tenant_dn = aci_tenant.tenant_for_benchmark.id + name = "ap_for_epg" + description = "This app profile is created by terraform ACI providers" +} + +resource "aci_application_epg" "inherit_epg" { + application_profile_dn = aci_application_profile.app_profile_for_epg.id + name = "inherit_epg" + description = "epg to create relation sec_inherited" +} + +resource "aci_application_epg" "inherit_epg2" { + application_profile_dn = aci_application_profile.app_profile_for_epg.id + name = "inherit_epg2" + description = "epg to create relation sec_inherited" +} + + +// Creation of Monitoring policy +resource "aci_monitoring_policy" "rest_mon_epg_pol" { + tenant_dn = aci_tenant.tenant_for_benchmark.id + name = "testpol" +} + +resource "aci_application_epg" "demoepg" { + count = 1 + application_profile_dn = aci_application_profile.app_profile_for_epg.id + name = "tf_test_epg-${count.index+1}" + description = "This epg is created by terraform ACI providers" + flood_on_encap = "disabled" + fwd_ctrl = "none" + is_attr_based_epg = "no" + match_t = "None" + pc_enf_pref = "unenforced" + pref_gr_memb = "include" + prio = "unspecified" + relation_fv_rs_bd = aci_bridge_domain.bd_for_rel[count.index].id # Relations to Bridge Domain + relation_fv_rs_cust_qos_pol = aci_rest.rest_qos_custom_pol.id # Relation to Custom Quality of Service - QoS traffic policy + relation_fv_rs_prov = [aci_contract.rs_prov_contract.id, aci_contract.rs_prov_contract2.id] # Relations to Provided Contracts + relation_fv_rs_cons_if = [aci_imported_contract.rest_vz_cons_if.id, aci_imported_contract.rest_vz_cons_if2.id] # Relations to Imported Contracts + relation_fv_rs_sec_inherited = [aci_application_epg.inherit_epg.id, aci_application_epg.inherit_epg2.id] # Relations to inherit security configuration from another EPG + relation_fv_rs_dpp_pol = aci_rest.rest_qos_dpp_pol.id # Relation to Data Plane Policing + relation_fv_rs_cons = [aci_contract.rs_cons_contract.id, aci_contract.rs_cons_contract2.id] # Relations to Consumed Contracts + relation_fv_rs_trust_ctrl = aci_rest.rest_trust_ctrl_pol.id # Relation to First Hop Security trust control + relation_fv_rs_prot_by = [aci_taboo_contract.rest_taboo_con.id, aci_taboo_contract.rest_taboo_con2.id] # Relations to vzTaboo Taboo Contracts + relation_fv_rs_aepg_mon_pol = aci_monitoring_policy.rest_mon_epg_pol.id # Relation to Monitoring policy + relation_fv_rs_intra_epg = [aci_contract.intra_epg_contract.id, aci_contract.intra_epg_contract2.id] # Relations to Intra EPG Contracts + + bulk_create = true + bulk_read = false + bulk_update = true +} diff --git a/examples/bulk/epg2.tf.ste b/examples/bulk/epg2.tf.ste new file mode 100644 index 000000000..c7b0c7d51 --- /dev/null +++ b/examples/bulk/epg2.tf.ste @@ -0,0 +1,58 @@ +resource "aci_application_profile" "app_profile_for_epg" { + tenant_dn = aci_tenant.tenant_for_benchmark.id + name = "ap_for_epg" + description = "This app profile is created by terraform ACI providers" +} + +resource "aci_application_epg" "inherit_epg" { + application_profile_dn = aci_application_profile.app_profile_for_epg.id + name = "inherit_epg" + description = "epg to create relation sec_inherited" +} + +resource "aci_application_epg" "inherit_epg2" { + application_profile_dn = aci_application_profile.app_profile_for_epg.id + name = "inherit_epg2" + description = "epg to create relation sec_inherited" +} + +resource "aci_application_epg" "inherit_epg3" { + application_profile_dn = aci_application_profile.app_profile_for_epg.id + name = "inherit_epg3" + description = "epg to create relation sec_inherited" +} + +// Creation of Monitoring policy +resource "aci_monitoring_policy" "rest_mon_epg_pol" { + tenant_dn = aci_tenant.tenant_for_benchmark.id + name = "testpol" +} + +resource "aci_application_epg" "demoepg" { + count = 1 + application_profile_dn = aci_application_profile.app_profile_for_epg.id + name = "tf_test_epg-${count.index+1}" + description = "This epg is created by terraform ACI providers" + flood_on_encap = "disabled" + fwd_ctrl = "none" + is_attr_based_epg = "no" + match_t = "None" + pc_enf_pref = "unenforced" + pref_gr_memb = "include" + prio = "unspecified" + relation_fv_rs_bd = aci_bridge_domain.bd_for_rel[count.index].id # Relations to Bridge Domain + relation_fv_rs_cust_qos_pol = aci_rest.rest_qos_custom_pol.id # Relation to Custom Quality of Service - QoS traffic policy + relation_fv_rs_prov = [aci_contract.rs_prov_contract.id, aci_contract.rs_prov_contract3.id] # Relations to Provided Contracts + relation_fv_rs_cons_if = [aci_imported_contract.rest_vz_cons_if.id, aci_imported_contract.rest_vz_cons_if3.id] # Relations to Imported Contracts + relation_fv_rs_sec_inherited = [aci_application_epg.inherit_epg.id, aci_application_epg.inherit_epg3.id] # Relations to inherit security configuration from another EPG + relation_fv_rs_dpp_pol = aci_rest.rest_qos_dpp_pol.id # Relation to Data Plane Policing + relation_fv_rs_cons = [aci_contract.rs_cons_contract.id, aci_contract.rs_cons_contract3.id] # Relations to Consumed Contracts + relation_fv_rs_trust_ctrl = aci_rest.rest_trust_ctrl_pol.id # Relation to First Hop Security trust control + relation_fv_rs_prot_by = [aci_taboo_contract.rest_taboo_con.id, aci_taboo_contract.rest_taboo_con3.id] # Relations to vzTaboo Taboo Contracts + relation_fv_rs_aepg_mon_pol = aci_monitoring_policy.rest_mon_epg_pol.id # Relation to Monitoring policy + relation_fv_rs_intra_epg = [aci_contract.intra_epg_contract.id, aci_contract.intra_epg_contract3.id] # Relations to Intra EPG Contracts + + bulk_create = true + bulk_read = false + bulk_update = true +} diff --git a/examples/bulk/filter.tf b/examples/bulk/filter.tf new file mode 100644 index 000000000..cb5cec0b5 --- /dev/null +++ b/examples/bulk/filter.tf @@ -0,0 +1,22 @@ +resource "aci_tenant" "tenant_for_filter" { + name = "_ACI-BENCHMARK_FOR_FILTER" + description = "This tenant is created by terraform ACI provider" +} + +resource "aci_filter" "bd_flood_filter" { + tenant_dn = aci_tenant.tenant_for_filter.id + name = "test_bdfloodfilter" + description = "This filter is created by terraform ACI provider." +} + +resource "aci_filter" "bd_flood_filter2" { + tenant_dn = aci_tenant.tenant_for_filter.id + name = "test_bdfloodfilter2" + description = "This filter is created by terraform ACI provider." +} + +resource "aci_filter" "bd_flood_filter3" { + tenant_dn = aci_tenant.tenant_for_filter.id + name = "test_bdfloodfilter3" + description = "This filter is created by terraform ACI provider." +} diff --git a/examples/bulk/main.tf b/examples/bulk/main.tf new file mode 100644 index 000000000..170c836d4 --- /dev/null +++ b/examples/bulk/main.tf @@ -0,0 +1,17 @@ +terraform { + required_providers { + aci = { + #source = "local/providers/aci" + source = "ciscodevnet/aci" + #version = "2.6.1" + } + } + required_version = ">= 0.13" +} + +provider "aci" { + username = "" + password = "" + url = "http://" + insecure = true +} diff --git a/examples/bulk/plan.sh b/examples/bulk/plan.sh new file mode 100755 index 000000000..4d5fd06bd --- /dev/null +++ b/examples/bulk/plan.sh @@ -0,0 +1,8 @@ +!/bin/sh +rm start.txt +rm end.txt +date > start.txt +terraform plan +date > end.txt +cat end.txt +cat start.txt diff --git a/examples/bulk/rest.tf b/examples/bulk/rest.tf new file mode 100644 index 000000000..aa4ec90e1 --- /dev/null +++ b/examples/bulk/rest.tf @@ -0,0 +1,160 @@ +resource "aci_rest" "rest_l3_ext_out" { + path = "api/node/mo/${aci_tenant.tenant_for_benchmark.id}/out-testext.json" + class_name = "l3extOut" + + content = { + "name" = "testext" + } +} + +resource "aci_rest" "rest_l3_ext_out2" { + path = "api/node/mo/${aci_tenant.tenant_for_benchmark.id}/out-testext2.json" + class_name = "l3extOut" + + content = { + "name" = "testext2" + } +} + +resource "aci_rest" "rest_l3_ext_out3" { + path = "api/node/mo/${aci_tenant.tenant_for_benchmark.id}/out-testext3.json" + class_name = "l3extOut" + + content = { + "name" = "testext3" + } +} + +resource "aci_route_control_profile" "example" { + parent_dn = aci_tenant.tenant_for_benchmark.id + name = "testprof" +} + +resource "aci_rest" "rest_dhcp_RelayP" { + path = "api/node/mo/${aci_tenant.tenant_for_benchmark.id}/relayp-testrelay.json" + class_name = "dhcpRelayP" + + content = { + "name" = "testrelay" + } +} + +resource "aci_rest" "rest_mon_epg_pol" { + path = "api/node/mo/${aci_tenant.tenant_for_benchmark.id}/monepg-testpol.json" + class_name = "monEPGPol" + + content = { + "name" = "testpol" + } +} + +resource "aci_rest" "rest_fhs_bd_pol" { + path = "api/node/mo/${aci_tenant.tenant_for_benchmark.id}/bdpol-testpolbd.json" + class_name = "fhsBDPol" + + content = { + "name" = "testpolbd" + } +} + +resource "aci_rest" "rest_net_flow_pol" { + path = "api/node/mo/${aci_tenant.tenant_for_benchmark.id}/monitorpol-testpolflow.json" + class_name = "netflowMonitorPol" + + content = { + "name" = "testpolflow" + } +} + +resource "aci_rest" "rest_net_flow_pol2" { + path = "api/node/mo/${aci_tenant.tenant_for_benchmark.id}/monitorpol-testpolflow2.json" + class_name = "netflowMonitorPol" + + content = { + "name" = "testpolflow2" + } +} + +resource "aci_rest" "rest_net_flow_pol3" { + path = "api/node/mo/${aci_tenant.tenant_for_benchmark.id}/monitorpol-testpolflow3.json" + class_name = "netflowMonitorPol" + + content = { + "name" = "testpolflow3" + } +} + +resource "aci_rest" "rest_qos_custom_pol" { + path = "api/node/mo/${aci_tenant.tenant_for_benchmark.id}/qoscustom-testpol.json" + class_name = "qosCustomPol" + + content = { + "name" = "testpol" + } +} + +resource "aci_rest" "rest_qos_dpp_pol" { + path = "api/node/mo/${aci_tenant.tenant_for_benchmark.id}/qosdpppol-testqospol.json" + class_name = "qosDppPol" + + content = { + "name" = "testqospol" + } +} + +resource "aci_rest" "rest_trust_ctrl_pol" { + path = "api/node/mo/${aci_tenant.tenant_for_benchmark.id}/trustctrlpol-testtrustpol.json" + class_name = "fhsTrustCtrlPol" + + content = { + "name" = "testtrustpol" + } +} + +### + +resource "aci_rest" "rest_mld_snoop_pol" { + path = "api/node/mo/${aci_tenant.tenant_for_benchmark.id}/mldsnoopPol-testmldsnooppol.json" + class_name = "mldSnoopPol" + + content = { + "name" = "testmldsnooppol" + } +} + +resource "aci_rest" "rest_igmp_snoop_pol" { + path = "api/node/mo/${aci_tenant.tenant_for_benchmark.id}/snPol-testigmpsnooppol.json" + class_name = "igmpSnoopPol" + + content = { + "name" = "testigmpsnooppol" + } +} + +resource "aci_rest" "rest_endpoint_ret_pol" { + path = "api/node/mo/${aci_tenant.tenant_for_benchmark.id}/epRPol-testendpretpol.json" + class_name = "fvEpRetPol" + + content = { + "name" = "testendpretpol" + } +} + +resource "aci_rest" "rest_nd_if_pol" { + path = "api/node/mo/${aci_tenant.tenant_for_benchmark.id}/ndifpol-testndifpol.json" + class_name = "ndIfPol" + + content = { + "name" = "testndifpol" + } +} +/* +resource "aci_rest" "rest_fab_node_pol" { + path = "api/node/mo/topology/pod-101.json" + class_name = "fabricNode" + + content = { + "name" = "testfabnodepol" + } +} +*/ diff --git a/examples/bulk/run.sh b/examples/bulk/run.sh new file mode 100755 index 000000000..326f19ad9 --- /dev/null +++ b/examples/bulk/run.sh @@ -0,0 +1,8 @@ +!/bin/sh +rm start.txt +rm end.txt +date > start.txt +terraform apply -auto-approve +date > end.txt +cat end.txt +cat start.txt diff --git a/examples/bulk/t1-test-suite.sh b/examples/bulk/t1-test-suite.sh new file mode 100755 index 000000000..f2ea1187a --- /dev/null +++ b/examples/bulk/t1-test-suite.sh @@ -0,0 +1,3 @@ +#!/bin/sh +cp bd1.tf.ste bd.tf +cp epg1.tf.ste epg.tf diff --git a/examples/bulk/t2-test-suite.sh b/examples/bulk/t2-test-suite.sh new file mode 100755 index 000000000..9889240f0 --- /dev/null +++ b/examples/bulk/t2-test-suite.sh @@ -0,0 +1,3 @@ +#!/bin/sh +cp bd2.tf.ste bd.tf +cp epg2.tf.ste epg.tf diff --git a/examples/bulk/tenant.tf b/examples/bulk/tenant.tf new file mode 100644 index 000000000..6c2264e22 --- /dev/null +++ b/examples/bulk/tenant.tf @@ -0,0 +1,8 @@ +data "aci_tenant" "tenant_for_contract" { + name = "common" +} + +resource "aci_tenant" "tenant_for_benchmark" { + name = "_ACI-BENCHMARK" + description = "This tenant is created by terraform ACI provider" +} diff --git a/examples/bulk/vrf.tf b/examples/bulk/vrf.tf new file mode 100644 index 000000000..715626798 --- /dev/null +++ b/examples/bulk/vrf.tf @@ -0,0 +1,12 @@ +resource "aci_vrf" "test_tf_vrf-1" { + tenant_dn = aci_tenant.tenant_for_benchmark.id + name = "test_tf_vrf-1" + description = "from terraform" + annotation = "tag_vrf" + bd_enforced_enable = "no" + ip_data_plane_learning = "enabled" + knw_mcast_act = "permit" + name_alias = "alias_vrf-1" + pc_enf_dir = "egress" + pc_enf_pref = "unenforced" +} diff --git a/vendor/github.com/ciscoecosystem/aci-go-client/v2/client/client.go b/vendor/github.com/ciscoecosystem/aci-go-client/v2/client/client.go index e59eb5630..938765f12 100644 --- a/vendor/github.com/ciscoecosystem/aci-go-client/v2/client/client.go +++ b/vendor/github.com/ciscoecosystem/aci-go-client/v2/client/client.go @@ -79,6 +79,41 @@ type Client struct { // singleton implementation of a client var clientImpl *Client +// Support for fastpath optimization +type fvRsDescr struct { + Id string + TypeSet bool +} + +var fvRsClassesBD = [...]fvRsDescr{ + {"fvRsBDToProfile", false}, {"fvRsMldsn", false}, {"fvRsABDPolMonPol", false}, {"fvRsBDToNdP", false}, + {"fvRsBdFloodTo", true}, {"fvRsBDToFhs", false}, {"fvRsBDToRelayP", false}, {"fvRsCtx", false}, + {"fvRsBDToNetflowMonitorPol", true}, {"fvRsIgmpsn", false}, {"fvRsBdToEpRet", false}, {"fvRsBDToOut", true}} + +var fvRsClassesBDFilter string + +var fvRsClassesEPG = [...]fvRsDescr{ + {"fvRsBd", false}, {"fvRsCustQosPol", false}, {"fvRsFcPathAtt", true}, {"fvRsProv", true}, + {"fvRsConsIf", true}, {"fvRsSecInherited", true}, {"fvRsNodeAtt", true}, {"fvRsDppPol", false}, + {"fvRsCons", true}, {"fvRsProvDef", true}, {"fvRsTrustCtrl", false}, {"fvRsPathAtt", true}, + {"fvRsProtBy", true}, {"fvRsAEPgMonPol", false}, {"fvRsIntraEpg", true}} + +var fvRsClassesEPGFilter string + +var maxSizeOfPOST int + +func init() { + for _, fvRsClassBD := range fvRsClassesBD { + fvRsClassesBDFilter += "&rsp-subtree-class=" + fvRsClassBD.Id + } + + for _, fvRsClassEPG := range fvRsClassesEPG { + fvRsClassesEPGFilter += "&rsp-subtree-class=" + fvRsClassEPG.Id + } + + maxSizeOfPOST = 1048576 +} + type Option func(*Client) func Insecure(insecure bool) Option { diff --git a/vendor/github.com/ciscoecosystem/aci-go-client/v2/client/fvAEPg_service.go b/vendor/github.com/ciscoecosystem/aci-go-client/v2/client/fvAEPg_service.go index 2e8c0d8c4..41cecf55d 100644 --- a/vendor/github.com/ciscoecosystem/aci-go-client/v2/client/fvAEPg_service.go +++ b/vendor/github.com/ciscoecosystem/aci-go-client/v2/client/fvAEPg_service.go @@ -54,6 +54,78 @@ func (sm *ServiceManager) ListApplicationEPG(application_profile string, tenant return list, err } +func (sm *ServiceManager) SetupCreateRelationfvRsBdFromApplicationEPG(parentDn, tnFvBDName string) []byte { + dn := fmt.Sprintf("%s/rsbd", parentDn) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","tnFvBDName": "%s","annotation":"orchestrator:terraform" + + } + } + }`, "fvRsBd", dn, tnFvBDName)) + + return containerJSON +} + +func (sm *ServiceManager) RenderRelationfvRsAllFromApplicationEPG(fvAEPg *models.ApplicationEPG, fvRsAllData [][]byte) error { + dn := fmt.Sprintf("%s", fvAEPg.DistinguishedName) + headerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s" + }, + "children": + [`, "fvAEPg", dn)) + + containerJSON := []byte{} + + fvRsItemIdx := 0 + fvRsAllDataItems := len(fvRsAllData) + + for { + containerJSON = append(containerJSON, headerJSON...) + sizeOfPOST := len(containerJSON) + 3 + + for next := true; next; next = fvRsItemIdx < fvRsAllDataItems { + if sizeOfPOST+len(fvRsAllData[fvRsItemIdx]) <= maxSizeOfPOST { + containerJSON = append(containerJSON, fvRsAllData[fvRsItemIdx]...) + containerJSON = append(containerJSON, ',') + sizeOfPOST = len(containerJSON) + fvRsItemIdx++ + } else { + break + } + } + + containerJSON[sizeOfPOST-1] = ']' + containerJSON = append(containerJSON, "}}"...) + + jsonPayload, err := container.ParseJSON(containerJSON) + if err != nil { + return err + } + + req, err := sm.client.MakeRestRequest("POST", fmt.Sprintf("%s.json", sm.MOURL), jsonPayload, true) + if err != nil { + return err + } + + _, _, err = sm.client.Do(req) + if err != nil { + return err + } + + if fvRsItemIdx == fvRsAllDataItems { + break + } + + containerJSON = nil + } + + return nil +} + func (sm *ServiceManager) CreateRelationfvRsBdFromApplicationEPG(parentDn, tnFvBDName string) error { dn := fmt.Sprintf("%s/rsbd", parentDn) containerJSON := []byte(fmt.Sprintf(`{ @@ -83,6 +155,41 @@ func (sm *ServiceManager) CreateRelationfvRsBdFromApplicationEPG(parentDn, tnFvB return nil } +func (sm *ServiceManager) ReadRelationfvRsAllEPG(parentDn string) (map[string]interface{}, error) { + baseurlStr := "/api/node/class" + //dnUrl := fmt.Sprintf("%s/%s.json?rsp-subtree=children&query-target-filter=eq(fvAEPg.dn,\"%s\")", baseurlStr, "fvAEPg", parentDn) + dnUrl := fmt.Sprintf("%s/%s.json?rsp-subtree=children&query-target-filter=eq(fvAEPg.dn,\"%s\")%s", baseurlStr, "fvAEPg", parentDn, fvRsClassesEPGFilter) + cont, err := sm.GetViaURL(dnUrl) + if err != nil { + return nil, err + } + contList := models.ListFromContainer2(cont, "fvAEPg") + + fvRsChildren := make(map[string]interface{}) + + for _, fvRsClass := range fvRsClassesEPG { + fvRsBlock := contList[0].S(fvRsClass.Id, "attributes") + if fvRsBlock != nil { + if fvRsClass.TypeSet { + fvRsBlockLen := len((fvRsBlock.Data()).([]interface{})) + st := &schema.Set{ + F: schema.HashString, + } + for i := 0; i < fvRsBlockLen; i++ { + dat := models.G((fvRsBlock).Index(i), "tDn") + st.Add(dat) + } + fvRsChildren[fvRsClass.Id] = st + } else { + dat := models.G((fvRsBlock).Index(0), "tDn") + fvRsChildren[fvRsClass.Id] = dat + } + } + } + + return fvRsChildren, err +} + func (sm *ServiceManager) ReadRelationfvRsBdFromApplicationEPG(parentDn string) (interface{}, error) { baseurlStr := "/api/node/class" dnUrl := fmt.Sprintf("%s/%s/%s.json", baseurlStr, parentDn, "fvRsBd") @@ -98,6 +205,21 @@ func (sm *ServiceManager) ReadRelationfvRsBdFromApplicationEPG(parentDn string) } } + +func (sm *ServiceManager) SetupCreateRelationfvRsCustQosPolFromApplicationEPG(parentDn, tnQosCustomPolName string) []byte { + dn := fmt.Sprintf("%s/rscustQosPol", parentDn) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","tnQosCustomPolName": "%s","annotation":"orchestrator:terraform" + + } + } + }`, "fvRsCustQosPol", dn, tnQosCustomPolName)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsCustQosPolFromApplicationEPG(parentDn, tnQosCustomPolName string) error { dn := fmt.Sprintf("%s/rscustQosPol", parentDn) containerJSON := []byte(fmt.Sprintf(`{ @@ -142,6 +264,20 @@ func (sm *ServiceManager) ReadRelationfvRsCustQosPolFromApplicationEPG(parentDn } } + +func (sm *ServiceManager) SetupCreateRelationfvRsDomAttFromApplicationEPG(parentDn, tDn string) []byte { + dn := fmt.Sprintf("%s/rsdomAtt-[%s]", parentDn, tDn) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","annotation":"orchestrator:terraform" + } + } + }`, "fvRsDomAtt", dn)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsDomAttFromApplicationEPG(parentDn, tDn string) error { dn := fmt.Sprintf("%s/rsdomAtt-[%s]", parentDn, tDn) containerJSON := []byte(fmt.Sprintf(`{ @@ -170,6 +306,11 @@ func (sm *ServiceManager) CreateRelationfvRsDomAttFromApplicationEPG(parentDn, t return nil } +func (sm *ServiceManager) SetupDeleteRelationfvRsDomAttFromApplicationEPG(parentDn, tDn string) []byte { + dn := fmt.Sprintf("%s/rsdomAtt-[%s]", parentDn, tDn) + return sm.SetupDeleteByDn(dn, "fvRsDomAtt") +} + func (sm *ServiceManager) DeleteRelationfvRsDomAttFromApplicationEPG(parentDn, tDn string) error { dn := fmt.Sprintf("%s/rsdomAtt-[%s]", parentDn, tDn) return sm.DeleteByDn(dn, "fvRsDomAtt") @@ -192,6 +333,20 @@ func (sm *ServiceManager) ReadRelationfvRsDomAttFromApplicationEPG(parentDn stri return st, err } + +func (sm *ServiceManager) SetupCreateRelationfvRsFcPathAttFromApplicationEPG(parentDn, tDn string) []byte { + dn := fmt.Sprintf("%s/rsfcPathAtt-[%s]", parentDn, tDn) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","annotation":"orchestrator:terraform" + } + } + }`, "fvRsFcPathAtt", dn)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsFcPathAttFromApplicationEPG(parentDn, tDn string) error { dn := fmt.Sprintf("%s/rsfcPathAtt-[%s]", parentDn, tDn) containerJSON := []byte(fmt.Sprintf(`{ @@ -220,6 +375,11 @@ func (sm *ServiceManager) CreateRelationfvRsFcPathAttFromApplicationEPG(parentDn return nil } +func (sm *ServiceManager) SetupDeleteRelationfvRsFcPathAttFromApplicationEPG(parentDn, tDn string) []byte { + dn := fmt.Sprintf("%s/rsfcPathAtt-[%s]", parentDn, tDn) + return sm.SetupDeleteByDn(dn, "fvRsFcPathAtt") +} + func (sm *ServiceManager) DeleteRelationfvRsFcPathAttFromApplicationEPG(parentDn, tDn string) error { dn := fmt.Sprintf("%s/rsfcPathAtt-[%s]", parentDn, tDn) return sm.DeleteByDn(dn, "fvRsFcPathAtt") @@ -242,6 +402,20 @@ func (sm *ServiceManager) ReadRelationfvRsFcPathAttFromApplicationEPG(parentDn s return st, err } + +func (sm *ServiceManager) SetupCreateRelationfvRsProvFromApplicationEPG(parentDn, tnVzBrCPName string) []byte { + dn := fmt.Sprintf("%s/rsprov-%s", parentDn, tnVzBrCPName) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","annotation":"orchestrator:terraform" + } + } + }`, "fvRsProv", dn)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsProvFromApplicationEPG(parentDn, tnVzBrCPName string) error { dn := fmt.Sprintf("%s/rsprov-%s", parentDn, tnVzBrCPName) containerJSON := []byte(fmt.Sprintf(`{ @@ -270,6 +444,11 @@ func (sm *ServiceManager) CreateRelationfvRsProvFromApplicationEPG(parentDn, tnV return nil } +func (sm *ServiceManager) SetupDeleteRelationfvRsProvFromApplicationEPG(parentDn, tnVzBrCPName string) []byte { + dn := fmt.Sprintf("%s/rsprov-%s", parentDn, tnVzBrCPName) + return sm.SetupDeleteByDn(dn, "fvRsProv") +} + func (sm *ServiceManager) DeleteRelationfvRsProvFromApplicationEPG(parentDn, tnVzBrCPName string) error { dn := fmt.Sprintf("%s/rsprov-%s", parentDn, tnVzBrCPName) return sm.DeleteByDn(dn, "fvRsProv") @@ -292,6 +471,20 @@ func (sm *ServiceManager) ReadRelationfvRsProvFromApplicationEPG(parentDn string return st, err } + +func (sm *ServiceManager) SetupCreateRelationfvRsGraphDefFromApplicationEPG(parentDn, tDn string) []byte { + dn := fmt.Sprintf("%s/rsgraphDef-[%s]", parentDn, tDn) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s" + } + } + }`, "fvRsGraphDef", dn)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsGraphDefFromApplicationEPG(parentDn, tDn string) error { dn := fmt.Sprintf("%s/rsgraphDef-[%s]", parentDn, tDn) containerJSON := []byte(fmt.Sprintf(`{ @@ -337,6 +530,20 @@ func (sm *ServiceManager) ReadRelationfvRsGraphDefFromApplicationEPG(parentDn st return st, err } + +func (sm *ServiceManager) SetupCreateRelationfvRsConsIfFromApplicationEPG(parentDn, tnVzCPIfName string) []byte { + dn := fmt.Sprintf("%s/rsconsIf-%s", parentDn, tnVzCPIfName) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","annotation":"orchestrator:terraform" + } + } + }`, "fvRsConsIf", dn)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsConsIfFromApplicationEPG(parentDn, tnVzCPIfName string) error { dn := fmt.Sprintf("%s/rsconsIf-%s", parentDn, tnVzCPIfName) containerJSON := []byte(fmt.Sprintf(`{ @@ -365,6 +572,11 @@ func (sm *ServiceManager) CreateRelationfvRsConsIfFromApplicationEPG(parentDn, t return nil } +func (sm *ServiceManager) SetupDeleteRelationfvRsConsIfFromApplicationEPG(parentDn, tnVzCPIfName string) []byte { + dn := fmt.Sprintf("%s/rsconsIf-%s", parentDn, tnVzCPIfName) + return sm.SetupDeleteByDn(dn, "fvRsConsIf") +} + func (sm *ServiceManager) DeleteRelationfvRsConsIfFromApplicationEPG(parentDn, tnVzCPIfName string) error { dn := fmt.Sprintf("%s/rsconsIf-%s", parentDn, tnVzCPIfName) return sm.DeleteByDn(dn, "fvRsConsIf") @@ -387,6 +599,20 @@ func (sm *ServiceManager) ReadRelationfvRsConsIfFromApplicationEPG(parentDn stri return st, err } + +func (sm *ServiceManager) SetupCreateRelationfvRsSecInheritedFromApplicationEPG(parentDn, tDn string) []byte { + dn := fmt.Sprintf("%s/rssecInherited-[%s]", parentDn, tDn) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","annotation":"orchestrator:terraform" + } + } + }`, "fvRsSecInherited", dn)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsSecInheritedFromApplicationEPG(parentDn, tDn string) error { dn := fmt.Sprintf("%s/rssecInherited-[%s]", parentDn, tDn) containerJSON := []byte(fmt.Sprintf(`{ @@ -415,6 +641,11 @@ func (sm *ServiceManager) CreateRelationfvRsSecInheritedFromApplicationEPG(paren return nil } +func (sm *ServiceManager) SetupDeleteRelationfvRsSecInheritedFromApplicationEPG(parentDn, tDn string) []byte { + dn := fmt.Sprintf("%s/rssecInherited-[%s]", parentDn, tDn) + return sm.SetupDeleteByDn(dn, "fvRsSecInherited") +} + func (sm *ServiceManager) DeleteRelationfvRsSecInheritedFromApplicationEPG(parentDn, tDn string) error { dn := fmt.Sprintf("%s/rssecInherited-[%s]", parentDn, tDn) return sm.DeleteByDn(dn, "fvRsSecInherited") @@ -437,6 +668,20 @@ func (sm *ServiceManager) ReadRelationfvRsSecInheritedFromApplicationEPG(parentD return st, err } + +func (sm *ServiceManager) SetupCreateRelationfvRsNodeAttFromApplicationEPG(parentDn, tDn string) []byte { + dn := fmt.Sprintf("%s/rsnodeAtt-[%s]", parentDn, tDn) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","annotation":"orchestrator:terraform" + } + } + }`, "fvRsNodeAtt", dn)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsNodeAttFromApplicationEPG(parentDn, tDn string) error { dn := fmt.Sprintf("%s/rsnodeAtt-[%s]", parentDn, tDn) containerJSON := []byte(fmt.Sprintf(`{ @@ -465,6 +710,11 @@ func (sm *ServiceManager) CreateRelationfvRsNodeAttFromApplicationEPG(parentDn, return nil } +func (sm *ServiceManager) SetupDeleteRelationfvRsNodeAttFromApplicationEPG(parentDn, tDn string) []byte { + dn := fmt.Sprintf("%s/rsnodeAtt-[%s]", parentDn, tDn) + return sm.SetupDeleteByDn(dn, "fvRsNodeAtt") +} + func (sm *ServiceManager) DeleteRelationfvRsNodeAttFromApplicationEPG(parentDn, tDn string) error { dn := fmt.Sprintf("%s/rsnodeAtt-[%s]", parentDn, tDn) return sm.DeleteByDn(dn, "fvRsNodeAtt") @@ -487,6 +737,21 @@ func (sm *ServiceManager) ReadRelationfvRsNodeAttFromApplicationEPG(parentDn str return st, err } + +func (sm *ServiceManager) SetupCreateRelationfvRsDppPolFromApplicationEPG(parentDn, tnQosDppPolName string) []byte { + dn := fmt.Sprintf("%s/rsdppPol", parentDn) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","tnQosDppPolName": "%s","annotation":"orchestrator:terraform" + + } + } + }`, "fvRsDppPol", dn, tnQosDppPolName)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsDppPolFromApplicationEPG(parentDn, tnQosDppPolName string) error { dn := fmt.Sprintf("%s/rsdppPol", parentDn) containerJSON := []byte(fmt.Sprintf(`{ @@ -516,6 +781,11 @@ func (sm *ServiceManager) CreateRelationfvRsDppPolFromApplicationEPG(parentDn, t return nil } +func (sm *ServiceManager) SetupDeleteRelationfvRsDppPolFromApplicationEPG(parentDn string) []byte { + dn := fmt.Sprintf("%s/rsdppPol", parentDn) + return sm.SetupDeleteByDn(dn, "fvRsDppPol") +} + func (sm *ServiceManager) DeleteRelationfvRsDppPolFromApplicationEPG(parentDn string) error { dn := fmt.Sprintf("%s/rsdppPol", parentDn) return sm.DeleteByDn(dn, "fvRsDppPol") @@ -536,6 +806,20 @@ func (sm *ServiceManager) ReadRelationfvRsDppPolFromApplicationEPG(parentDn stri } } + +func (sm *ServiceManager) SetupCreateRelationfvRsConsFromApplicationEPG(parentDn, tnVzBrCPName string) []byte { + dn := fmt.Sprintf("%s/rscons-%s", parentDn, tnVzBrCPName) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","annotation":"orchestrator:terraform" + } + } + }`, "fvRsCons", dn)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsConsFromApplicationEPG(parentDn, tnVzBrCPName string) error { dn := fmt.Sprintf("%s/rscons-%s", parentDn, tnVzBrCPName) containerJSON := []byte(fmt.Sprintf(`{ @@ -564,6 +848,11 @@ func (sm *ServiceManager) CreateRelationfvRsConsFromApplicationEPG(parentDn, tnV return nil } +func (sm *ServiceManager) SetupDeleteRelationfvRsConsFromApplicationEPG(parentDn, tnVzBrCPName string) []byte { + dn := fmt.Sprintf("%s/rscons-%s", parentDn, tnVzBrCPName) + return sm.SetupDeleteByDn(dn, "fvRsCons") +} + func (sm *ServiceManager) DeleteRelationfvRsConsFromApplicationEPG(parentDn, tnVzBrCPName string) error { dn := fmt.Sprintf("%s/rscons-%s", parentDn, tnVzBrCPName) return sm.DeleteByDn(dn, "fvRsCons") @@ -586,6 +875,20 @@ func (sm *ServiceManager) ReadRelationfvRsConsFromApplicationEPG(parentDn string return st, err } + +func (sm *ServiceManager) SetupCreateRelationfvRsProvDefFromApplicationEPG(parentDn, tDn string) []byte { + dn := fmt.Sprintf("%s/rsprovDef-[%s]", parentDn, tDn) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s" + } + } + }`, "fvRsProvDef", dn)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsProvDefFromApplicationEPG(parentDn, tDn string) error { dn := fmt.Sprintf("%s/rsprovDef-[%s]", parentDn, tDn) containerJSON := []byte(fmt.Sprintf(`{ @@ -631,6 +934,21 @@ func (sm *ServiceManager) ReadRelationfvRsProvDefFromApplicationEPG(parentDn str return st, err } + +func (sm *ServiceManager) SetupCreateRelationfvRsTrustCtrlFromApplicationEPG(parentDn, tnFhsTrustCtrlPolName string) []byte { + dn := fmt.Sprintf("%s/rstrustCtrl", parentDn) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","tnFhsTrustCtrlPolName": "%s","annotation":"orchestrator:terraform" + + } + } + }`, "fvRsTrustCtrl", dn, tnFhsTrustCtrlPolName)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsTrustCtrlFromApplicationEPG(parentDn, tnFhsTrustCtrlPolName string) error { dn := fmt.Sprintf("%s/rstrustCtrl", parentDn) containerJSON := []byte(fmt.Sprintf(`{ @@ -660,6 +978,11 @@ func (sm *ServiceManager) CreateRelationfvRsTrustCtrlFromApplicationEPG(parentDn return nil } +func (sm *ServiceManager) SetupDeleteRelationfvRsTrustCtrlFromApplicationEPG(parentDn string) []byte { + dn := fmt.Sprintf("%s/rstrustCtrl", parentDn) + return sm.SetupDeleteByDn(dn, "fvRsTrustCtrl") +} + func (sm *ServiceManager) DeleteRelationfvRsTrustCtrlFromApplicationEPG(parentDn string) error { dn := fmt.Sprintf("%s/rstrustCtrl", parentDn) return sm.DeleteByDn(dn, "fvRsTrustCtrl") @@ -680,6 +1003,20 @@ func (sm *ServiceManager) ReadRelationfvRsTrustCtrlFromApplicationEPG(parentDn s } } + +func (sm *ServiceManager) SetupCreateRelationfvRsPathAttFromApplicationEPG(parentDn, tDn string) []byte { + dn := fmt.Sprintf("%s/rspathAtt-[%s]", parentDn, tDn) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","annotation":"orchestrator:terraform" + } + } + }`, "fvRsPathAtt", dn)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsPathAttFromApplicationEPG(parentDn, tDn string) error { dn := fmt.Sprintf("%s/rspathAtt-[%s]", parentDn, tDn) containerJSON := []byte(fmt.Sprintf(`{ @@ -708,6 +1045,11 @@ func (sm *ServiceManager) CreateRelationfvRsPathAttFromApplicationEPG(parentDn, return nil } +func (sm *ServiceManager) SetupDeleteRelationfvRsPathAttFromApplicationEPG(parentDn, tDn string) []byte { + dn := fmt.Sprintf("%s/rspathAtt-[%s]", parentDn, tDn) + return sm.SetupDeleteByDn(dn, "fvRsPathAtt") +} + func (sm *ServiceManager) DeleteRelationfvRsPathAttFromApplicationEPG(parentDn, tDn string) error { dn := fmt.Sprintf("%s/rspathAtt-[%s]", parentDn, tDn) return sm.DeleteByDn(dn, "fvRsPathAtt") @@ -730,6 +1072,20 @@ func (sm *ServiceManager) ReadRelationfvRsPathAttFromApplicationEPG(parentDn str return st, err } + +func (sm *ServiceManager) SetupCreateRelationfvRsProtByFromApplicationEPG(parentDn, tnVzTabooName string) []byte { + dn := fmt.Sprintf("%s/rsprotBy-%s", parentDn, tnVzTabooName) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","annotation":"orchestrator:terraform" + } + } + }`, "fvRsProtBy", dn)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsProtByFromApplicationEPG(parentDn, tnVzTabooName string) error { dn := fmt.Sprintf("%s/rsprotBy-%s", parentDn, tnVzTabooName) containerJSON := []byte(fmt.Sprintf(`{ @@ -758,6 +1114,11 @@ func (sm *ServiceManager) CreateRelationfvRsProtByFromApplicationEPG(parentDn, t return nil } +func (sm *ServiceManager) SetupDeleteRelationfvRsProtByFromApplicationEPG(parentDn, tnVzTabooName string) []byte { + dn := fmt.Sprintf("%s/rsprotBy-%s", parentDn, tnVzTabooName) + return sm.SetupDeleteByDn(dn, "fvRsProtBy") +} + func (sm *ServiceManager) DeleteRelationfvRsProtByFromApplicationEPG(parentDn, tnVzTabooName string) error { dn := fmt.Sprintf("%s/rsprotBy-%s", parentDn, tnVzTabooName) return sm.DeleteByDn(dn, "fvRsProtBy") @@ -780,6 +1141,21 @@ func (sm *ServiceManager) ReadRelationfvRsProtByFromApplicationEPG(parentDn stri return st, err } + +func (sm *ServiceManager) SetupCreateRelationfvRsAEPgMonPolFromApplicationEPG(parentDn, tnMonEPGPolName string) []byte { + dn := fmt.Sprintf("%s/rsAEPgMonPol", parentDn) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","tnMonEPGPolName": "%s","annotation":"orchestrator:terraform" + + } + } + }`, "fvRsAEPgMonPol", dn, tnMonEPGPolName)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsAEPgMonPolFromApplicationEPG(parentDn, tnMonEPGPolName string) error { dn := fmt.Sprintf("%s/rsAEPgMonPol", parentDn) containerJSON := []byte(fmt.Sprintf(`{ @@ -809,6 +1185,11 @@ func (sm *ServiceManager) CreateRelationfvRsAEPgMonPolFromApplicationEPG(parentD return nil } +func (sm *ServiceManager) SetupDeleteRelationfvRsAEPgMonPolFromApplicationEPG(parentDn string) []byte { + dn := fmt.Sprintf("%s/rsAEPgMonPol", parentDn) + return sm.SetupDeleteByDn(dn, "fvRsAEPgMonPol") +} + func (sm *ServiceManager) DeleteRelationfvRsAEPgMonPolFromApplicationEPG(parentDn string) error { dn := fmt.Sprintf("%s/rsAEPgMonPol", parentDn) return sm.DeleteByDn(dn, "fvRsAEPgMonPol") @@ -829,6 +1210,20 @@ func (sm *ServiceManager) ReadRelationfvRsAEPgMonPolFromApplicationEPG(parentDn } } + +func (sm *ServiceManager) SetupCreateRelationfvRsIntraEpgFromApplicationEPG(parentDn, tnVzBrCPName string) []byte { + dn := fmt.Sprintf("%s/rsintraEpg-%s", parentDn, tnVzBrCPName) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","annotation":"orchestrator:terraform" + } + } + }`, "fvRsIntraEpg", dn)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsIntraEpgFromApplicationEPG(parentDn, tnVzBrCPName string) error { dn := fmt.Sprintf("%s/rsintraEpg-%s", parentDn, tnVzBrCPName) containerJSON := []byte(fmt.Sprintf(`{ @@ -857,6 +1252,11 @@ func (sm *ServiceManager) CreateRelationfvRsIntraEpgFromApplicationEPG(parentDn, return nil } +func (sm *ServiceManager) SetupDeleteRelationfvRsIntraEpgFromApplicationEPG(parentDn, tnVzBrCPName string) []byte { + dn := fmt.Sprintf("%s/rsintraEpg-%s", parentDn, tnVzBrCPName) + return sm.SetupDeleteByDn(dn, "fvRsIntraEpg") +} + func (sm *ServiceManager) DeleteRelationfvRsIntraEpgFromApplicationEPG(parentDn, tnVzBrCPName string) error { dn := fmt.Sprintf("%s/rsintraEpg-%s", parentDn, tnVzBrCPName) return sm.DeleteByDn(dn, "fvRsIntraEpg") diff --git a/vendor/github.com/ciscoecosystem/aci-go-client/v2/client/fvBD_service.go b/vendor/github.com/ciscoecosystem/aci-go-client/v2/client/fvBD_service.go index 0571cf735..0b45c8655 100644 --- a/vendor/github.com/ciscoecosystem/aci-go-client/v2/client/fvBD_service.go +++ b/vendor/github.com/ciscoecosystem/aci-go-client/v2/client/fvBD_service.go @@ -54,6 +54,78 @@ func (sm *ServiceManager) ListBridgeDomain(tenant string) ([]*models.BridgeDomai return list, err } +func (sm *ServiceManager) SetupCreateRelationfvRsBDToProfileFromBridgeDomain(parentDn, tnRtctrlProfileName string) []byte { + dn := fmt.Sprintf("%s/rsBDToProfile", parentDn) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","tnRtctrlProfileName": "%s","annotation":"orchestrator:terraform" + + } + } + }`, "fvRsBDToProfile", dn, tnRtctrlProfileName)) + + return containerJSON +} + +func (sm *ServiceManager) RenderRelationfvRsAllFromBridgeDomain(fvBD *models.BridgeDomain, fvRsAllData [][]byte) error { + dn := fmt.Sprintf("%s", fvBD.DistinguishedName) + headerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s" + }, + "children": + [`, "fvBD", dn)) + + containerJSON := []byte{} + + fvRsItemIdx := 0 + fvRsAllDataItems := len(fvRsAllData) + + for { + containerJSON = append(containerJSON, headerJSON...) + sizeOfPOST := len(containerJSON) + 3 + + for next := true; next; next = fvRsItemIdx < fvRsAllDataItems { + if sizeOfPOST+len(fvRsAllData[fvRsItemIdx]) <= maxSizeOfPOST { + containerJSON = append(containerJSON, fvRsAllData[fvRsItemIdx]...) + containerJSON = append(containerJSON, ',') + sizeOfPOST = len(containerJSON) + fvRsItemIdx++ + } else { + break + } + } + + containerJSON[sizeOfPOST-1] = ']' + containerJSON = append(containerJSON, "}}"...) + + jsonPayload, err := container.ParseJSON(containerJSON) + if err != nil { + return err + } + + req, err := sm.client.MakeRestRequest("POST", fmt.Sprintf("%s.json", sm.MOURL), jsonPayload, true) + if err != nil { + return err + } + + _, _, err = sm.client.Do(req) + if err != nil { + return err + } + + if fvRsItemIdx == fvRsAllDataItems { + break + } + + containerJSON = nil + } + + return nil +} + func (sm *ServiceManager) CreateRelationfvRsBDToProfileFromBridgeDomain(parentDn, tnRtctrlProfileName string) error { dn := fmt.Sprintf("%s/rsBDToProfile", parentDn) containerJSON := []byte(fmt.Sprintf(`{ @@ -83,11 +155,63 @@ func (sm *ServiceManager) CreateRelationfvRsBDToProfileFromBridgeDomain(parentDn return nil } +func (sm *ServiceManager) SetupDeleteRelationfvRsBDToProfileFromBridgeDomain(parentDn string) []byte { + dn := fmt.Sprintf("%s/rsBDToProfile", parentDn) + return sm.SetupDeleteByDn(dn, "fvRsBDToProfile") +} + func (sm *ServiceManager) DeleteRelationfvRsBDToProfileFromBridgeDomain(parentDn string) error { dn := fmt.Sprintf("%s/rsBDToProfile", parentDn) return sm.DeleteByDn(dn, "fvRsBDToProfile") } +func (sm *ServiceManager) ReadRelationfvRsAllBridgeDomain(parentDn string) (map[string]interface{}, error) { + baseurlStr := "/api/node/class" + //dnUrl := fmt.Sprintf("%s/%s.json?rsp-subtree=children&query-target-filter=eq(fvBD.dn,\"%s\")", baseurlStr, "fvBD", parentDn) + dnUrl := fmt.Sprintf("%s/%s.json?rsp-subtree=children&query-target-filter=eq(fvBD.dn,\"%s\")%s", baseurlStr, "fvBD", parentDn, fvRsClassesBDFilter) + cont, err := sm.GetViaURL(dnUrl) + if err != nil { + return nil, err + } + contList := models.ListFromContainer2(cont, "fvBD") + + fvRsChildren := make(map[string]interface{}) + + for _, fvRsClass := range fvRsClassesBD { + fvRsBlock := contList[0].S(fvRsClass.Id, "attributes") + if fvRsBlock != nil { + if fvRsClass.TypeSet { + fvRsBlockLen := len((fvRsBlock.Data()).([]interface{})) + if fvRsClass.Id == "fvRsBDToNetflowMonitorPol" { + st := make([]map[string]string, 0) + for i := 0; i < fvRsBlockLen; i++ { + paramMap := make(map[string]string) + paramMap["tnNetflowMonitorPolName"] = models.G((fvRsBlock).Index(i), "tDn") + paramMap["fltType"] = models.G((fvRsBlock).Index(i), "fltType") + + st = append(st, paramMap) + } + fvRsChildren[fvRsClass.Id] = st + } else { + st := &schema.Set{ + F: schema.HashString, + } + for i := 0; i < fvRsBlockLen; i++ { + dat := models.G((fvRsBlock).Index(i), "tDn") + st.Add(dat) + } + fvRsChildren[fvRsClass.Id] = st + } + } else { + dat := models.G((fvRsBlock).Index(0), "tDn") + fvRsChildren[fvRsClass.Id] = dat + } + } + } + + return fvRsChildren, err +} + func (sm *ServiceManager) ReadRelationfvRsBDToProfileFromBridgeDomain(parentDn string) (interface{}, error) { baseurlStr := "/api/node/class" dnUrl := fmt.Sprintf("%s/%s/%s.json", baseurlStr, parentDn, "fvRsBDToProfile") @@ -103,6 +227,21 @@ func (sm *ServiceManager) ReadRelationfvRsBDToProfileFromBridgeDomain(parentDn s } } + +func (sm *ServiceManager) SetupCreateRelationfvRsMldsnFromBridgeDomain(parentDn, tnMldSnoopPolName string) []byte { + dn := fmt.Sprintf("%s/rsmldsn", parentDn) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","tnMldSnoopPolName": "%s","annotation":"orchestrator:terraform" + + } + } + }`, "fvRsMldsn", dn, tnMldSnoopPolName)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsMldsnFromBridgeDomain(parentDn, tnMldSnoopPolName string) error { dn := fmt.Sprintf("%s/rsmldsn", parentDn) containerJSON := []byte(fmt.Sprintf(`{ @@ -147,6 +286,21 @@ func (sm *ServiceManager) ReadRelationfvRsMldsnFromBridgeDomain(parentDn string) } } + +func (sm *ServiceManager) SetupCreateRelationfvRsABDPolMonPolFromBridgeDomain(parentDn, tnMonEPGPolName string) []byte { + dn := fmt.Sprintf("%s/rsABDPolMonPol", parentDn) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","tnMonEPGPolName": "%s","annotation":"orchestrator:terraform" + + } + } + }`, "fvRsABDPolMonPol", dn, tnMonEPGPolName)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsABDPolMonPolFromBridgeDomain(parentDn, tnMonEPGPolName string) error { dn := fmt.Sprintf("%s/rsABDPolMonPol", parentDn) containerJSON := []byte(fmt.Sprintf(`{ @@ -176,6 +330,11 @@ func (sm *ServiceManager) CreateRelationfvRsABDPolMonPolFromBridgeDomain(parentD return nil } +func (sm *ServiceManager) SetupDeleteRelationfvRsABDPolMonPolFromBridgeDomain(parentDn string) []byte { + dn := fmt.Sprintf("%s/rsABDPolMonPol", parentDn) + return sm.SetupDeleteByDn(dn, "fvRsABDPolMonPol") +} + func (sm *ServiceManager) DeleteRelationfvRsABDPolMonPolFromBridgeDomain(parentDn string) error { dn := fmt.Sprintf("%s/rsABDPolMonPol", parentDn) return sm.DeleteByDn(dn, "fvRsABDPolMonPol") @@ -196,6 +355,21 @@ func (sm *ServiceManager) ReadRelationfvRsABDPolMonPolFromBridgeDomain(parentDn } } + +func (sm *ServiceManager) SetupCreateRelationfvRsBDToNdPFromBridgeDomain(parentDn, tnNdIfPolName string) []byte { + dn := fmt.Sprintf("%s/rsBDToNdP", parentDn) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","tnNdIfPolName": "%s","annotation":"orchestrator:terraform" + + } + } + }`, "fvRsBDToNdP", dn, tnNdIfPolName)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsBDToNdPFromBridgeDomain(parentDn, tnNdIfPolName string) error { dn := fmt.Sprintf("%s/rsBDToNdP", parentDn) containerJSON := []byte(fmt.Sprintf(`{ @@ -240,6 +414,20 @@ func (sm *ServiceManager) ReadRelationfvRsBDToNdPFromBridgeDomain(parentDn strin } } + +func (sm *ServiceManager) SetupCreateRelationfvRsBdFloodToFromBridgeDomain(parentDn, tDn string) []byte { + dn := fmt.Sprintf("%s/rsbdFloodTo-[%s]", parentDn, tDn) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","annotation":"orchestrator:terraform" + } + } + }`, "fvRsBdFloodTo", dn)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsBdFloodToFromBridgeDomain(parentDn, tDn string) error { dn := fmt.Sprintf("%s/rsbdFloodTo-[%s]", parentDn, tDn) containerJSON := []byte(fmt.Sprintf(`{ @@ -268,6 +456,11 @@ func (sm *ServiceManager) CreateRelationfvRsBdFloodToFromBridgeDomain(parentDn, return nil } +func (sm *ServiceManager) SetupDeleteRelationfvRsBdFloodToFromBridgeDomain(parentDn, tDn string) []byte { + dn := fmt.Sprintf("%s/rsbdFloodTo-[%s]", parentDn, tDn) + return sm.SetupDeleteByDn(dn, "fvRsBdFloodTo") +} + func (sm *ServiceManager) DeleteRelationfvRsBdFloodToFromBridgeDomain(parentDn, tDn string) error { dn := fmt.Sprintf("%s/rsbdFloodTo-[%s]", parentDn, tDn) return sm.DeleteByDn(dn, "fvRsBdFloodTo") @@ -290,6 +483,21 @@ func (sm *ServiceManager) ReadRelationfvRsBdFloodToFromBridgeDomain(parentDn str return st, err } + +func (sm *ServiceManager) SetupCreateRelationfvRsBDToFhsFromBridgeDomain(parentDn, tnFhsBDPolName string) []byte { + dn := fmt.Sprintf("%s/rsBDToFhs", parentDn) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","tnFhsBDPolName": "%s","annotation":"orchestrator:terraform" + + } + } + }`, "fvRsBDToFhs", dn, tnFhsBDPolName)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsBDToFhsFromBridgeDomain(parentDn, tnFhsBDPolName string) error { dn := fmt.Sprintf("%s/rsBDToFhs", parentDn) containerJSON := []byte(fmt.Sprintf(`{ @@ -319,6 +527,11 @@ func (sm *ServiceManager) CreateRelationfvRsBDToFhsFromBridgeDomain(parentDn, tn return nil } +func (sm *ServiceManager) SetupDeleteRelationfvRsBDToFhsFromBridgeDomain(parentDn string) []byte { + dn := fmt.Sprintf("%s/rsBDToFhs", parentDn) + return sm.SetupDeleteByDn(dn, "fvRsBDToFhs") +} + func (sm *ServiceManager) DeleteRelationfvRsBDToFhsFromBridgeDomain(parentDn string) error { dn := fmt.Sprintf("%s/rsBDToFhs", parentDn) return sm.DeleteByDn(dn, "fvRsBDToFhs") @@ -339,6 +552,21 @@ func (sm *ServiceManager) ReadRelationfvRsBDToFhsFromBridgeDomain(parentDn strin } } + +func (sm *ServiceManager) SetupCreateRelationfvRsBDToRelayPFromBridgeDomain(parentDn, tnDhcpRelayPName string) []byte { + dn := fmt.Sprintf("%s/rsBDToRelayP", parentDn) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","tnDhcpRelayPName": "%s","annotation":"orchestrator:terraform" + + } + } + }`, "fvRsBDToRelayP", dn, tnDhcpRelayPName)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsBDToRelayPFromBridgeDomain(parentDn, tnDhcpRelayPName string) error { dn := fmt.Sprintf("%s/rsBDToRelayP", parentDn) containerJSON := []byte(fmt.Sprintf(`{ @@ -368,6 +596,11 @@ func (sm *ServiceManager) CreateRelationfvRsBDToRelayPFromBridgeDomain(parentDn, return nil } +func (sm *ServiceManager) SetupDeleteRelationfvRsBDToRelayPFromBridgeDomain(parentDn string) []byte { + dn := fmt.Sprintf("%s/rsBDToRelayP", parentDn) + return sm.SetupDeleteByDn(dn, "fvRsBDToRelayP") +} + func (sm *ServiceManager) DeleteRelationfvRsBDToRelayPFromBridgeDomain(parentDn string) error { dn := fmt.Sprintf("%s/rsBDToRelayP", parentDn) return sm.DeleteByDn(dn, "fvRsBDToRelayP") @@ -388,6 +621,21 @@ func (sm *ServiceManager) ReadRelationfvRsBDToRelayPFromBridgeDomain(parentDn st } } + +func (sm *ServiceManager) SetupCreateRelationfvRsCtxFromBridgeDomain(parentDn, tnFvCtxName string) []byte { + dn := fmt.Sprintf("%s/rsctx", parentDn) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","tnFvCtxName": "%s","annotation":"orchestrator:terraform" + + } + } + }`, "fvRsCtx", dn, tnFvCtxName)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsCtxFromBridgeDomain(parentDn, tnFvCtxName string) error { dn := fmt.Sprintf("%s/rsctx", parentDn) containerJSON := []byte(fmt.Sprintf(`{ @@ -432,6 +680,20 @@ func (sm *ServiceManager) ReadRelationfvRsCtxFromBridgeDomain(parentDn string) ( } } + +func (sm *ServiceManager) SetupCreateRelationfvRsBDToNetflowMonitorPolFromBridgeDomain(parentDn, tnNetflowMonitorPolName, fltType string) []byte { + dn := fmt.Sprintf("%s/rsBDToNetflowMonitorPol-[%s]-%s", parentDn, tnNetflowMonitorPolName, fltType) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","annotation":"orchestrator:terraform" + } + } + }`, "fvRsBDToNetflowMonitorPol", dn)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsBDToNetflowMonitorPolFromBridgeDomain(parentDn, tnNetflowMonitorPolName, fltType string) error { dn := fmt.Sprintf("%s/rsBDToNetflowMonitorPol-[%s]-%s", parentDn, tnNetflowMonitorPolName, fltType) containerJSON := []byte(fmt.Sprintf(`{ @@ -460,6 +722,11 @@ func (sm *ServiceManager) CreateRelationfvRsBDToNetflowMonitorPolFromBridgeDomai return nil } +func (sm *ServiceManager) SetupDeleteRelationfvRsBDToNetflowMonitorPolFromBridgeDomain(parentDn, tnNetflowMonitorPolName, fltType string) []byte { + dn := fmt.Sprintf("%s/rsBDToNetflowMonitorPol-[%s]-%s", parentDn, tnNetflowMonitorPolName, fltType) + return sm.SetupDeleteByDn(dn, "fvRsBDToNetflowMonitorPol") +} + func (sm *ServiceManager) DeleteRelationfvRsBDToNetflowMonitorPolFromBridgeDomain(parentDn, tnNetflowMonitorPolName, fltType string) error { dn := fmt.Sprintf("%s/rsBDToNetflowMonitorPol-[%s]-%s", parentDn, tnNetflowMonitorPolName, fltType) return sm.DeleteByDn(dn, "fvRsBDToNetflowMonitorPol") @@ -486,6 +753,21 @@ func (sm *ServiceManager) ReadRelationfvRsBDToNetflowMonitorPolFromBridgeDomain( return st, err } + +func (sm *ServiceManager) SetupCreateRelationfvRsIgmpsnFromBridgeDomain(parentDn, tnIgmpSnoopPolName string) []byte { + dn := fmt.Sprintf("%s/rsigmpsn", parentDn) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","tnIgmpSnoopPolName": "%s","annotation":"orchestrator:terraform" + + } + } + }`, "fvRsIgmpsn", dn, tnIgmpSnoopPolName)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsIgmpsnFromBridgeDomain(parentDn, tnIgmpSnoopPolName string) error { dn := fmt.Sprintf("%s/rsigmpsn", parentDn) containerJSON := []byte(fmt.Sprintf(`{ @@ -530,6 +812,21 @@ func (sm *ServiceManager) ReadRelationfvRsIgmpsnFromBridgeDomain(parentDn string } } + +func (sm *ServiceManager) SetupCreateRelationfvRsBdToEpRetFromBridgeDomain(parentDn, tnFvEpRetPolName string) []byte { + dn := fmt.Sprintf("%s/rsbdToEpRet", parentDn) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","tnFvEpRetPolName": "%s","annotation":"orchestrator:terraform" + + } + } + }`, "fvRsBdToEpRet", dn, tnFvEpRetPolName)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsBdToEpRetFromBridgeDomain(parentDn, tnFvEpRetPolName string) error { dn := fmt.Sprintf("%s/rsbdToEpRet", parentDn) containerJSON := []byte(fmt.Sprintf(`{ @@ -574,6 +871,20 @@ func (sm *ServiceManager) ReadRelationfvRsBdToEpRetFromBridgeDomain(parentDn str } } + +func (sm *ServiceManager) SetupCreateRelationfvRsBDToOutFromBridgeDomain(parentDn, tnL3extOutName string) []byte { + dn := fmt.Sprintf("%s/rsBDToOut-%s", parentDn, tnL3extOutName) + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s","annotation":"orchestrator:terraform" + } + } + }`, "fvRsBDToOut", dn)) + + return containerJSON +} + func (sm *ServiceManager) CreateRelationfvRsBDToOutFromBridgeDomain(parentDn, tnL3extOutName string) error { dn := fmt.Sprintf("%s/rsBDToOut-%s", parentDn, tnL3extOutName) containerJSON := []byte(fmt.Sprintf(`{ @@ -602,6 +913,11 @@ func (sm *ServiceManager) CreateRelationfvRsBDToOutFromBridgeDomain(parentDn, tn return nil } +func (sm *ServiceManager) SetupDeleteRelationfvRsBDToOutFromBridgeDomain(parentDn, tnL3extOutName string) []byte { + dn := fmt.Sprintf("%s/rsBDToOut-%s", parentDn, tnL3extOutName) + return sm.SetupDeleteByDn(dn, "fvRsBDToOut") +} + func (sm *ServiceManager) DeleteRelationfvRsBDToOutFromBridgeDomain(parentDn, tnL3extOutName string) error { dn := fmt.Sprintf("%s/rsBDToOut-%s", parentDn, tnL3extOutName) return sm.DeleteByDn(dn, "fvRsBDToOut") diff --git a/vendor/github.com/ciscoecosystem/aci-go-client/v2/client/service_manager.go b/vendor/github.com/ciscoecosystem/aci-go-client/v2/client/service_manager.go index f15240161..038e03a00 100644 --- a/vendor/github.com/ciscoecosystem/aci-go-client/v2/client/service_manager.go +++ b/vendor/github.com/ciscoecosystem/aci-go-client/v2/client/service_manager.go @@ -206,6 +206,19 @@ func (sm *ServiceManager) GetViaURL(url string) (*container.Container, error) { } +func (sm *ServiceManager) SetupDeleteByDn(dn, className string) []byte { + containerJSON := []byte(fmt.Sprintf(`{ + "%s": { + "attributes": { + "dn": "%s", + "status": "deleted" + } + } + }`, className, dn)) + + return containerJSON +} + func (sm *ServiceManager) DeleteByDn(dn, className string) error { containerJSON := []byte(fmt.Sprintf(`{ "%s": { diff --git a/vendor/github.com/ciscoecosystem/aci-go-client/v2/models/util.go b/vendor/github.com/ciscoecosystem/aci-go-client/v2/models/util.go index 0eb91561a..4f47d99be 100644 --- a/vendor/github.com/ciscoecosystem/aci-go-client/v2/models/util.go +++ b/vendor/github.com/ciscoecosystem/aci-go-client/v2/models/util.go @@ -83,6 +83,17 @@ func ListFromContainer(cont *container.Container, klass string) []*container.Con } +func ListFromContainer2(cont *container.Container, klass string) []*container.Container { + length, _ := strconv.Atoi(G(cont, "totalCount")) + arr := make([]*container.Container, length) + for i := 0; i < length; i++ { + + arr[i] = cont.S("imdata").Index(i).S(klass, "children") + } + return arr + +} + func CurlyBraces(value string) string { if value == "{}" { return ""