diff --git a/examples/fabric_policies_ptp_policy/main.tf b/examples/fabric_policies_ptp_policy/main.tf new file mode 100644 index 00000000..91332631 --- /dev/null +++ b/examples/fabric_policies_ptp_policy/main.tf @@ -0,0 +1,38 @@ +terraform { + required_providers { + mso = { + source = "CiscoDevNet/mso" + } + } +} + +provider "mso" { + username = "" # + password = "" # + url = "" # + insecure = true +} + +# fabric policy template example + +resource "mso_template" "fabric_policy_template" { + template_name = "fabric_policy_template" + template_type = "fabric_policy" +} + +# fabric policies ptp policy example + +resource "mso_fabric_policies_ptp_policy" "ptp_policy" { + template_id = mso_template.fabric_policy_template.id + name = "ptp_policy" + description = "Example description" + admin_state = "enabled" + global_priority1 = 250 + global_priority2 = 100 + global_domain = 99 + fabric_profile_template = "aes67" + fabric_announce_interval = 1 + fabric_sync_interval = -3 + fabric_delay_interval = -2 + fabric_announce_timeout = 3 +} diff --git a/examples/fabric_policies_ptp_policy_profile/main.tf b/examples/fabric_policies_ptp_policy_profile/main.tf new file mode 100644 index 00000000..60228df3 --- /dev/null +++ b/examples/fabric_policies_ptp_policy_profile/main.tf @@ -0,0 +1,53 @@ +terraform { + required_providers { + mso = { + source = "CiscoDevNet/mso" + } + } +} + +provider "mso" { + username = "" # + password = "" # + url = "" # + insecure = true +} + +# fabric policy template example + +resource "mso_template" "fabric_policy_template" { + template_name = "fabric_policy_template" + template_type = "fabric_policy" +} + +# fabric policies ptp policy example + +resource "mso_fabric_policies_ptp_policy" "ptp_policy" { + template_id = mso_template.fabric_policy_template.id + name = "ptp_policy" + description = "Example description" + admin_state = "enabled" + global_priority1 = 250 + global_priority2 = 100 + global domain = 99 + fabric_profile_template = "aes67" + fabric_announce_interval = 1 + fabric_sync_interval = -3 + fabric_delay_interval = -2 + fabric_announce_timeout = 3 +} + +# fabric policies ptp policy profile example + +resource "mso_fabric_policies_ptp_policy_profile" "ptp_policy_profile" { + template_id = mso_template.fabric_policy_template.id + ptp_policy_uuid = mso_fabric_policies_ptp_policy.ptp_policy.uuid + name = "ptp_policy_profile" + description = "Example description" + delay_interval = -2 + sync_interval = -3 + announce_timeout = 3 + announce_interval = 1 + profile_template = "aes67" + override_node_profile = false +} diff --git a/mso/constants.go b/mso/constants.go index a2b6eb46..b2305458 100644 --- a/mso/constants.go +++ b/mso/constants.go @@ -95,3 +95,25 @@ var loadBalanceHashingMap = map[string]string{ "layer_4_source_ip": "l4-src-port", "source_ip": "src-ip", } + +var ptpProfileTemplateMap = map[string]string{ + "aes67": "aes67", + "default": "default", + "smpte": "smpte", + "telecom": "telecomFullPath", + "telecomFullPath": "telecom", +} + +var ptpDestinationMacMap = map[string]string{ + "forwardable": "forwardable", + "non_forwardable": "nonForwardable", + "nonForwardable": "non_forwardable", +} + +var ptpMismatchedMacHandlingMap = map[string]string{ + "drop": "drop", + "reply_with_config_mac": "replyWithCfgMac", + "replyWithCfgMac": "reply_with_config_mac", + "reply_with_received_mac": "replyWithRxMac", + "replyWithRxMac": "reply_with_received_mac", +} diff --git a/mso/datasource_mso_fabric_policies_ptp_policy.go b/mso/datasource_mso_fabric_policies_ptp_policy.go new file mode 100644 index 00000000..c14c257f --- /dev/null +++ b/mso/datasource_mso_fabric_policies_ptp_policy.go @@ -0,0 +1,81 @@ +package mso + +import ( + "log" + + "github.com/ciscoecosystem/mso-go-client/client" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func datasourceMSOPtpPolicy() *schema.Resource { + return &schema.Resource{ + Read: dataSourcePtpPolicyRead, + + Schema: map[string]*schema.Schema{ + "template_id": { + Type: schema.TypeString, + Required: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "uuid": { + Type: schema.TypeString, + Computed: true, + }, + "admin_state": { + Type: schema.TypeString, + Computed: true, + }, + "global_priority1": { + Type: schema.TypeInt, + Computed: true, + }, + "global_priority2": { + Type: schema.TypeInt, + Computed: true, + }, + "global_domain": { + Type: schema.TypeInt, + Computed: true, + }, + "fabric_profile_template": { + Type: schema.TypeString, + Computed: true, + }, + "fabric_announce_interval": { + Type: schema.TypeInt, + Computed: true, + }, + "fabric_sync_interval": { + Type: schema.TypeInt, + Computed: true, + }, + "fabric_delay_interval": { + Type: schema.TypeInt, + Computed: true, + }, + "fabric_announce_timeout": { + Type: schema.TypeInt, + Computed: true, + }, + }, + } +} + +func dataSourcePtpPolicyRead(d *schema.ResourceData, m interface{}) error { + log.Printf("[DEBUG] MSO PTP Policy Data Source - Beginning Read") + msoClient := m.(*client.Client) + + templateId := d.Get("template_id").(string) + policyName := d.Get("name").(string) + + setPtpPolicyData(d, msoClient, templateId, policyName) + log.Printf("[DEBUG] MSO PTP Policy Data Source - Read Complete : %v", d.Id()) + return nil +} diff --git a/mso/datasource_mso_fabric_policies_ptp_policy_profile.go b/mso/datasource_mso_fabric_policies_ptp_policy_profile.go new file mode 100644 index 00000000..42a11188 --- /dev/null +++ b/mso/datasource_mso_fabric_policies_ptp_policy_profile.go @@ -0,0 +1,81 @@ +package mso + +import ( + "log" + + "github.com/ciscoecosystem/mso-go-client/client" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func datasourceMSOPtpPolicyProfile() *schema.Resource { + return &schema.Resource{ + Read: dataSourcePtpPolicyProfileRead, + + Schema: map[string]*schema.Schema{ + "template_id": { + Type: schema.TypeString, + Required: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + }, + "ptp_policy_uuid": { + Type: schema.TypeString, + Computed: true, + }, + "uuid": { + Type: schema.TypeString, + Computed: true, + }, + "profile_template": { + Type: schema.TypeString, + Computed: true, + }, + "delay_interval": { + Type: schema.TypeInt, + Computed: true, + }, + "sync_interval": { + Type: schema.TypeInt, + Computed: true, + }, + "announce_interval": { + Type: schema.TypeInt, + Computed: true, + }, + "announce_timeout": { + Type: schema.TypeInt, + Computed: true, + }, + "override_node_profile": { + Type: schema.TypeBool, + Computed: true, + }, + "local_priority": { + Type: schema.TypeInt, + Computed: true, + }, + "destination_mac_type": { + Type: schema.TypeString, + Computed: true, + }, + "mismatched_mac_handling": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func dataSourcePtpPolicyProfileRead(d *schema.ResourceData, m interface{}) error { + log.Printf("[DEBUG] MSO PTP Policy Profile Data Source - Beginning Read") + msoClient := m.(*client.Client) + + templateId := d.Get("template_id").(string) + policyName := d.Get("name").(string) + + setPtpPolicyProfileData(d, msoClient, templateId, policyName) + log.Printf("[DEBUG] MSO PTP Policy Profile Data Source - Read Complete : %v", d.Id()) + return nil +} diff --git a/mso/datasource_mso_fabric_policies_ptp_policy_profile_test.go b/mso/datasource_mso_fabric_policies_ptp_policy_profile_test.go new file mode 100644 index 00000000..34e66da6 --- /dev/null +++ b/mso/datasource_mso_fabric_policies_ptp_policy_profile_test.go @@ -0,0 +1,61 @@ +package mso + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +func TestAccMSOPtpPolicyProfileDataSource(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + PreConfig: func() { fmt.Println("Test: PTP Policy Profile Data Source") }, + Config: testAccMSOPtpPolicyProfileDataSource(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "name", "tf_ptp_profile"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "profile_template", "telecom"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "delay_interval", "-4"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "sync_interval", "-4"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "announce_interval", "-3"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "announce_timeout", "3"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "local_priority", "120"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "destination_mac_type", "forwardable"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "mismatched_mac_handling", "reply_with_config_mac"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "override_node_profile", "false"), + resource.TestCheckResourceAttrSet("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "uuid"), + resource.TestCheckResourceAttrSet("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "ptp_policy_uuid"), + ), + }, + }, + }) +} + +func testAccMSOPtpPolicyProfileConfig() string { + return fmt.Sprintf(`%s + resource "mso_fabric_policies_ptp_policy_profile" "ptp_policy_profile" { + template_id = mso_template.template_fabric_policy.id + ptp_policy_uuid = mso_fabric_policies_ptp_policy.ptp_policy.uuid + name = "tf_ptp_profile" + profile_template = "telecom" + announce_interval = -3 + delay_interval = -4 + sync_interval = -4 + announce_timeout = 3 + local_priority = 120 + destination_mac_type = "forwardable" + mismatched_mac_handling = "reply_with_config_mac" + override_node_profile = "false" + }`, testAccMSOPtpPolicyConfigCreate()) +} + +func testAccMSOPtpPolicyProfileDataSource() string { + return fmt.Sprintf(`%s + data "mso_fabric_policies_ptp_policy_profile" "ptp_policy_profile" { + template_id = mso_fabric_policies_ptp_policy_profile.ptp_policy_profile.template_id + name = "tf_ptp_profile" + }`, testAccMSOPtpPolicyProfileConfig()) +} diff --git a/mso/datasource_mso_fabric_policies_ptp_policy_test.go b/mso/datasource_mso_fabric_policies_ptp_policy_test.go new file mode 100644 index 00000000..54c034fe --- /dev/null +++ b/mso/datasource_mso_fabric_policies_ptp_policy_test.go @@ -0,0 +1,43 @@ +package mso + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +func TestAccMSOPtpPolicyDataSource(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + PreConfig: func() { fmt.Println("Test: PTP Policy Data Source") }, + Config: testAccMSOPtpPolicyDataSource(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "name", "tf_test_ptp_policy"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "description", "Terraform test PTP Policy"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "admin_state", "enabled"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "fabric_profile_template", "default"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "global_priority1", "255"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "global_priority2", "254"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "global_domain", "100"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "fabric_announce_interval", "1"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "fabric_sync_interval", "-1"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "fabric_delay_interval", "1"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "fabric_announce_timeout", "3"), + resource.TestCheckResourceAttrSet("mso_fabric_policies_ptp_policy.ptp_policy", "uuid"), + ), + }, + }, + }) +} + +func testAccMSOPtpPolicyDataSource() string { + return fmt.Sprintf(`%s + data "mso_fabric_policies_ptp_policy" "ptp_policy" { + template_id = mso_fabric_policies_ptp_policy.ptp_policy.template_id + name = "tf_test_ptp_policy" + }`, testAccMSOPtpPolicyConfigCreate()) +} diff --git a/mso/provider.go b/mso/provider.go index 18d1c7ab..3e549a2d 100644 --- a/mso/provider.go +++ b/mso/provider.go @@ -142,6 +142,8 @@ func Provider() terraform.ResourceProvider { "mso_tenant_policies_ipsla_track_list": resourceMSOIPSLATrackList(), "mso_tenant_policies_l3out_interface_routing_policy": resourceMSOL3OutInterfaceRoutingPolicy(), "mso_fabric_policies_interface_setting": resourceMSOInterfaceSetting(), + "mso_fabric_policies_ptp_policy": resourceMSOPtpPolicy(), + "mso_fabric_policies_ptp_policy_profile": resourceMSOPtpPolicyProfile(), }, DataSourcesMap: map[string]*schema.Resource{ @@ -217,6 +219,8 @@ func Provider() terraform.ResourceProvider { "mso_tenant_policies_ipsla_track_list": datasourceMSOIPSLATrackList(), "mso_tenant_policies_l3out_interface_routing_policy": datasourceMSOL3OutInterfaceRoutingPolicy(), "mso_fabric_policies_interface_setting": datasourceMSOInterfaceSetting(), + "mso_fabric_policies_ptp_policy": datasourceMSOPtpPolicy(), + "mso_fabric_policies_ptp_policy_profile": datasourceMSOPtpPolicyProfile(), }, ConfigureFunc: configureClient, diff --git a/mso/resource_mso_fabric_policies_ptp_policy.go b/mso/resource_mso_fabric_policies_ptp_policy.go new file mode 100644 index 00000000..9143541e --- /dev/null +++ b/mso/resource_mso_fabric_policies_ptp_policy.go @@ -0,0 +1,338 @@ +package mso + +import ( + "fmt" + "log" + + "github.com/ciscoecosystem/mso-go-client/client" + "github.com/ciscoecosystem/mso-go-client/container" + "github.com/ciscoecosystem/mso-go-client/models" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" +) + +func resourceMSOPtpPolicy() *schema.Resource { + return &schema.Resource{ + Create: resourceMSOPtpPolicyCreate, + Read: resourceMSOPtpPolicyRead, + Update: resourceMSOPtpPolicyUpdate, + Delete: resourceMSOPtpPolicyDelete, + Importer: &schema.ResourceImporter{ + State: resourceMSOPtpPolicyImport, + }, + + SchemaVersion: 1, + Schema: map[string]*schema.Schema{ + "template_id": { + Type: schema.TypeString, + ForceNew: true, + Required: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(1, 64), + }, + "description": { + Type: schema.TypeString, + Optional: true, + }, + "uuid": { + Type: schema.TypeString, + Computed: true, + }, + "admin_state": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + "enabled", "disabled", + }, false), + }, + "fabric_profile_template": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + "aes67", "default", "smpte", + }, false), + }, + "global_priority1": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(1, 255), + }, + "global_priority2": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(0, 255), + }, + "global_domain": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(0, 128), + }, + "fabric_sync_interval": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(-4, 1), + }, + "fabric_delay_interval": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(-4, 5), + }, + "fabric_announce_interval": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(-3, 4), + }, + "fabric_announce_timeout": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(2, 10), + }, + }, + } +} + +func setPtpPolicyData(d *schema.ResourceData, msoClient *client.Client, templateId, policyName string) error { + + response, err := msoClient.GetViaURL(fmt.Sprintf("api/v1/templates/%s", templateId)) + if err != nil { + return err + } + + policy, err := GetPolicyByName(response, policyName, "fabricPolicyTemplate", "template", "ptpPolicy") + if err != nil { + return err + } + + d.SetId(fmt.Sprintf("templateId/%s/ptpPolicy/%s", templateId, models.StripQuotes(policy.S("name").String()))) + d.Set("template_id", templateId) + d.Set("name", models.StripQuotes(policy.S("name").String())) + d.Set("description", models.StripQuotes(policy.S("description").String())) + d.Set("uuid", models.StripQuotes(policy.S("global").S("uuid").String())) + + globalCont := policy.S("global") + d.Set("admin_state", models.StripQuotes(globalCont.S("adminState").String())) + d.Set("global_priority1", globalCont.S("prio1").Data().(float64)) + d.Set("global_priority2", globalCont.S("prio2").Data().(float64)) + d.Set("global_domain", globalCont.S("globalDomain").Data().(float64)) + d.Set("fabric_profile_template", models.StripQuotes(globalCont.S("fabProfileTemplate").String())) + d.Set("fabric_announce_interval", globalCont.S("fabAnnounceIntvl").Data().(float64)) + d.Set("fabric_sync_interval", globalCont.S("fabSyncIntvl").Data().(float64)) + d.Set("fabric_delay_interval", globalCont.S("fabDelayIntvl").Data().(float64)) + d.Set("fabric_announce_timeout", globalCont.S("fabAnnounceTimeout").Data().(float64)) + + return nil +} + +func resourceMSOPtpPolicyImport(d *schema.ResourceData, m any) ([]*schema.ResourceData, error) { + log.Printf("[DEBUG] MSO PTP Policy Resource - Beginning Import: %v", d.Id()) + msoClient := m.(*client.Client) + + templateId, err := GetTemplateIdFromResourceId(d.Id()) + if err != nil { + return nil, err + } + + policyName, err := GetPolicyNameFromResourceId(d.Id(), "ptpPolicy") + if err != nil { + return nil, err + } + + setPtpPolicyData(d, msoClient, templateId, policyName) + log.Printf("[DEBUG] MSO PTP Policy Resource - Import Complete: %v", d.Id()) + return []*schema.ResourceData{d}, nil +} + +func resourceMSOPtpPolicyCreate(d *schema.ResourceData, m any) error { + log.Printf("[DEBUG] MSO PTP Policy Resource - Beginning Create: %v", d.Id()) + msoClient := m.(*client.Client) + + payload := map[string]any{} + + payload["name"] = d.Get("name").(string) + + if description, ok := d.GetOk("description"); ok { + payload["description"] = description.(string) + } + + globalParams := make(map[string]any) + + if adminState, ok := d.GetOk("admin_state"); ok { + globalParams["adminState"] = adminState.(string) + } + + if profileTemplate, ok := d.GetOk("fabric_profile_template"); ok { + globalParams["fabProfileTemplate"] = profileTemplate.(string) + } + + if prio1, ok := d.GetOk("global_priority1"); ok { + globalParams["prio1"] = prio1.(int) + } + + if prio2, ok := d.GetOk("global_priority2"); ok { + globalParams["prio2"] = prio2.(int) + } + + if globalDomain, ok := d.GetOk("global_domain"); ok { + globalParams["globalDomain"] = globalDomain.(int) + } + + if fabAnnounceIntvl, ok := d.GetOk("fabric_announce_interval"); ok { + globalParams["fabAnnounceIntvl"] = fabAnnounceIntvl.(int) + } + + if fabSyncIntvl, ok := d.GetOk("fabric_sync_interval"); ok { + globalParams["fabSyncIntvl"] = fabSyncIntvl.(int) + } + + if fabDelayIntvl, ok := d.GetOk("fabric_delay_interval"); ok { + globalParams["fabDelayIntvl"] = fabDelayIntvl.(int) + } + + if fabAnnounceTimeout, ok := d.GetOk("fabric_announce_timeout"); ok { + globalParams["fabAnnounceTimeout"] = fabAnnounceTimeout.(int) + } + + if len(globalParams) > 0 { + payload["global"] = globalParams + } + + payloadModel := models.GetPatchPayload("add", "/fabricPolicyTemplate/template/ptpPolicy", payload) + templateId := d.Get("template_id").(string) + + _, err := msoClient.PatchbyID(fmt.Sprintf("api/v1/templates/%s", templateId), payloadModel) + if err != nil { + return err + } + + d.SetId(fmt.Sprintf("templateId/%s/ptpPolicy/%s", templateId, d.Get("name").(string))) + log.Printf("[DEBUG] MSO PTP Policy Resource - Create Complete: %v", d.Id()) + return resourceMSOPtpPolicyRead(d, m) +} + +func resourceMSOPtpPolicyRead(d *schema.ResourceData, m any) error { + log.Printf("[DEBUG] MSO PTP Policy Resource - Beginning Read: %v", d.Id()) + msoClient := m.(*client.Client) + + templateId := d.Get("template_id").(string) + policyName := d.Get("name").(string) + + setPtpPolicyData(d, msoClient, templateId, policyName) + log.Printf("[DEBUG] MSO PTP Policy Resource - Read Complete : %v", d.Id()) + return nil +} + +func resourceMSOPtpPolicyUpdate(d *schema.ResourceData, m any) error { + log.Printf("[DEBUG] MSO PTP Policy Resource - Beginning Update: %v", d.Id()) + msoClient := m.(*client.Client) + templateId := d.Get("template_id").(string) + + updatePath := "/fabricPolicyTemplate/template/ptpPolicy" + + payloadCont := container.New() + payloadCont.Array() + + if d.HasChange("name") { + err := addPatchPayloadToContainer(payloadCont, "replace", fmt.Sprintf("%s/name", updatePath), d.Get("name").(string)) + if err != nil { + return err + } + } + + if d.HasChange("description") { + err := addPatchPayloadToContainer(payloadCont, "replace", fmt.Sprintf("%s/description", updatePath), d.Get("description").(string)) + if err != nil { + return err + } + } + + if d.HasChange("admin_state") { + err := addPatchPayloadToContainer(payloadCont, "replace", fmt.Sprintf("%s/global/adminState", updatePath), d.Get("admin_state").(string)) + if err != nil { + return err + } + } + + if d.HasChange("fabric_profile_template") { + err := addPatchPayloadToContainer(payloadCont, "replace", fmt.Sprintf("%s/global/fabProfileTemplate", updatePath), d.Get("fabric_profile_template").(string)) + if err != nil { + return err + } + } + + if d.HasChange("global_priority1") { + err := addPatchPayloadToContainer(payloadCont, "replace", fmt.Sprintf("%s/global/prio1", updatePath), d.Get("global_priority1").(int)) + if err != nil { + return err + } + } + + if d.HasChange("global_priority2") { + err := addPatchPayloadToContainer(payloadCont, "replace", fmt.Sprintf("%s/global/prio2", updatePath), d.Get("global_priority2").(int)) + if err != nil { + return err + } + } + + if d.HasChange("global_domain") { + err := addPatchPayloadToContainer(payloadCont, "replace", fmt.Sprintf("%s/global/globalDomain", updatePath), d.Get("global_domain").(int)) + if err != nil { + return err + } + } + + if d.HasChange("fabric_announce_interval") { + err := addPatchPayloadToContainer(payloadCont, "replace", fmt.Sprintf("%s/global/fabAnnounceIntvl", updatePath), d.Get("fabric_announce_interval").(int)) + if err != nil { + return err + } + } + + if d.HasChange("fabric_sync_interval") { + err := addPatchPayloadToContainer(payloadCont, "replace", fmt.Sprintf("%s/global/fabSyncIntvl", updatePath), d.Get("fabric_sync_interval").(int)) + if err != nil { + return err + } + } + + if d.HasChange("fabric_delay_interval") { + err := addPatchPayloadToContainer(payloadCont, "replace", fmt.Sprintf("%s/global/fabDelayIntvl", updatePath), d.Get("fabric_delay_interval").(int)) + if err != nil { + return err + } + } + + if d.HasChange("fabric_announce_timeout") { + err := addPatchPayloadToContainer(payloadCont, "replace", fmt.Sprintf("%s/global/fabAnnounceTimeout", updatePath), d.Get("fabric_announce_timeout").(int)) + if err != nil { + return err + } + } + + err := doPatchRequest(msoClient, fmt.Sprintf("api/v1/templates/%s", templateId), payloadCont) + if err != nil { + return err + } + + d.SetId(fmt.Sprintf("templateId/%s/ptpPolicy/%s", templateId, d.Get("name").(string))) + log.Printf("[DEBUG] MSO PTP Policy Resource - Update Complete: %v", d.Id()) + return resourceMSOPtpPolicyRead(d, m) +} + +func resourceMSOPtpPolicyDelete(d *schema.ResourceData, m any) error { + log.Printf("[DEBUG] MSO PTP Policy Resource - Beginning Delete: %v", d.Id()) + msoClient := m.(*client.Client) + + payloadModel := models.GetRemovePatchPayload("/fabricPolicyTemplate/template/ptpPolicy") + + _, err := msoClient.PatchbyID(fmt.Sprintf("api/v1/templates/%s", d.Get("template_id").(string)), payloadModel) + if err != nil { + return err + } + + d.SetId("") + log.Printf("[DEBUG] MSO PTP Policy Resource - Delete Complete: %v", d.Id()) + return nil +} diff --git a/mso/resource_mso_fabric_policies_ptp_policy_profile.go b/mso/resource_mso_fabric_policies_ptp_policy_profile.go new file mode 100644 index 00000000..ddc666ad --- /dev/null +++ b/mso/resource_mso_fabric_policies_ptp_policy_profile.go @@ -0,0 +1,359 @@ +package mso + +import ( + "fmt" + "log" + + "github.com/ciscoecosystem/mso-go-client/client" + "github.com/ciscoecosystem/mso-go-client/container" + "github.com/ciscoecosystem/mso-go-client/models" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" +) + +func resourceMSOPtpPolicyProfile() *schema.Resource { + return &schema.Resource{ + Create: resourceMSOPtpPolicyProfileCreate, + Read: resourceMSOPtpPolicyProfileRead, + Update: resourceMSOPtpPolicyProfileUpdate, + Delete: resourceMSOPtpPolicyProfileDelete, + Importer: &schema.ResourceImporter{ + State: resourceMSOPtpPolicyProfileImport, + }, + + SchemaVersion: 1, + Schema: map[string]*schema.Schema{ + "template_id": { + Type: schema.TypeString, + ForceNew: true, + Required: true, + }, + "ptp_policy_uuid": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(1, 16), + }, + "uuid": { + Type: schema.TypeString, + Computed: true, + }, + "profile_template": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + "aes67", "default", "smpte", "telecom", + }, false), + }, + "delay_interval": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(-4, 5), + }, + "sync_interval": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(-4, 1), + }, + "announce_interval": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(-3, 4), + }, + "announce_timeout": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(2, 10), + }, + "override_node_profile": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "local_priority": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "destination_mac_type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{ + "forwardable", "non_forwardable", + }, false), + }, + "mismatched_mac_handling": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{ + "drop", "reply_with_config_mac", "reply_with_received_mac", + }, false), + }, + }, + } +} + +func setPtpPolicyProfileData(d *schema.ResourceData, msoClient *client.Client, templateId, policyName string) error { + response, err := msoClient.GetViaURL(fmt.Sprintf("api/v1/templates/%s", templateId)) + if err != nil { + return err + } + + ptp_policy_uuid, ok := response.S("fabricPolicyTemplate", "template", "ptpPolicy", "uuid").Data().(string) + if !ok { + return fmt.Errorf("PTP Policy not found") + } + + policy, err := GetPolicyByName(response, policyName, "fabricPolicyTemplate", "template", "ptpPolicy", "profiles") + if err != nil { + return err + } + + name := models.StripQuotes(policy.S("name").String()) + d.SetId(fmt.Sprintf("templateId/%s/ptpPolicyProfile/%s", templateId, name)) + d.Set("template_id", templateId) + d.Set("name", name) + d.Set("ptp_policy_uuid", ptp_policy_uuid) + d.Set("uuid", models.StripQuotes(policy.S("uuid").String())) + d.Set("delay_interval", policy.S("delayIntvl").Data().(float64)) + d.Set("sync_interval", policy.S("syncIntvl").Data().(float64)) + d.Set("announce_interval", policy.S("announceIntvl").Data().(float64)) + d.Set("announce_timeout", policy.S("announceTimeout").Data().(float64)) + d.Set("profile_template", convertValueWithMap(models.StripQuotes(policy.S("profileTemplate").String()), ptpProfileTemplateMap)) + if policy.Exists("nodeProfileOverride") { + d.Set("override_node_profile", policy.S("nodeProfileOverride").Data().(bool)) + } + if policy.Exists("localPriority") { + d.Set("local_priority", policy.S("localPriority").Data().(float64)) + } + if policy.Exists("dstMacType") { + d.Set("destination_mac_type", convertValueWithMap(models.StripQuotes(policy.S("dstMacType").String()), ptpDestinationMacMap)) + } + if policy.Exists("dstMacRxNoMatch") { + d.Set("mismatched_mac_handling", convertValueWithMap(models.StripQuotes(policy.S("dstMacRxNoMatch").String()), ptpMismatchedMacHandlingMap)) + } + + return nil +} + +func resourceMSOPtpPolicyProfileImport(d *schema.ResourceData, m any) ([]*schema.ResourceData, error) { + log.Printf("[DEBUG] MSO PTP Policy Profile Resource - Beginning Import: %v", d.Id()) + msoClient := m.(*client.Client) + + templateId, err := GetTemplateIdFromResourceId(d.Id()) + if err != nil { + return nil, err + } + + policyName, err := GetPolicyNameFromResourceId(d.Id(), "ptpPolicyProfile") + if err != nil { + return nil, err + } + + setPtpPolicyProfileData(d, msoClient, templateId, policyName) + log.Printf("[DEBUG] MSO PTP Policy Profile Resource - Import Complete: %v", d.Id()) + return []*schema.ResourceData{d}, nil +} + +func resourceMSOPtpPolicyProfileCreate(d *schema.ResourceData, m any) error { + log.Printf("[DEBUG] MSO PTP Policy Profile Resource - Beginning Create: %v", d.Id()) + msoClient := m.(*client.Client) + + payload := map[string]any{} + + payload["name"] = d.Get("name").(string) + + if profile_template, ok := d.GetOk("profile_template"); ok { + payload["profileTemplate"] = convertValueWithMap(profile_template.(string), ptpProfileTemplateMap) + } + + if announce_interval, ok := d.GetOk("announce_interval"); ok { + payload["announceIntvl"] = announce_interval.(int) + } + + if sync_interval, ok := d.GetOk("sync_interval"); ok { + payload["syncIntvl"] = sync_interval.(int) + } + + if delay_interval, ok := d.GetOk("delay_interval"); ok { + payload["delayIntvl"] = delay_interval.(int) + } + + if announce_timeout, ok := d.GetOk("announce_timeout"); ok { + payload["announceTimeout"] = announce_timeout.(int) + } + + if override_node_profile, ok := d.GetOk("override_node_profile"); ok { + if override_node_profile.(bool) { + payload["announceIntvl"] = override_node_profile.(bool) + } + } + + if local_priority, ok := d.GetOk("local_priority"); ok { + payload["localPriority"] = local_priority.(int) + } + + if destination_mac_type, ok := d.GetOk("destination_mac_type"); ok { + payload["dstMacType"] = convertValueWithMap(destination_mac_type.(string), ptpDestinationMacMap) + } + + if mismatched_mac_handling, ok := d.GetOk("mismatched_mac_handling"); ok { + payload["dstMacRxNoMatch"] = convertValueWithMap(mismatched_mac_handling.(string), ptpMismatchedMacHandlingMap) + } + + payloadModel := models.GetPatchPayload("add", "/fabricPolicyTemplate/template/ptpPolicy/profiles/-", payload) + templateId := d.Get("template_id").(string) + + _, err := msoClient.PatchbyID(fmt.Sprintf("api/v1/templates/%s", templateId), payloadModel) + if err != nil { + return err + } + + d.SetId(fmt.Sprintf("templateId/%s/ptpPolicyProfile/%s", templateId, d.Get("name").(string))) + log.Printf("[DEBUG] MSO PTP Policy Profile Resource - Create Complete: %v", d.Id()) + return resourceMSOPtpPolicyProfileRead(d, m) +} + +func resourceMSOPtpPolicyProfileRead(d *schema.ResourceData, m any) error { + log.Printf("[DEBUG] MSO PTP Policy Profile Resource - Beginning Read: %v", d.Id()) + msoClient := m.(*client.Client) + + templateId := d.Get("template_id").(string) + policyName := d.Get("name").(string) + + setPtpPolicyProfileData(d, msoClient, templateId, policyName) + log.Printf("[DEBUG] MSO PTP Policy Profile Resource - Read Complete : %v", d.Id()) + return nil +} + +func resourceMSOPtpPolicyProfileUpdate(d *schema.ResourceData, m any) error { + log.Printf("[DEBUG] MSO PTP Policy Profile Resource - Beginning Update: %v", d.Id()) + msoClient := m.(*client.Client) + templateId := d.Get("template_id").(string) + + templateCont, err := msoClient.GetViaURL(fmt.Sprintf("api/v1/templates/%s", templateId)) + if err != nil { + return err + } + + policyIndex, err := GetPolicyIndexByKeyAndValue(templateCont, "uuid", d.Get("uuid").(string), "fabricPolicyTemplate", "template", "ptpPolicy", "profiles") + if err != nil { + return err + } + + updatePath := fmt.Sprintf("/fabricPolicyTemplate/template/ptpPolicy/profiles/%d", policyIndex) + + payloadCont := container.New() + payloadCont.Array() + if d.HasChange("name") { + err := addPatchPayloadToContainer(payloadCont, "replace", fmt.Sprintf("%s/name", updatePath), d.Get("name").(string)) + if err != nil { + return err + } + } + + if d.HasChange("profile_template") { + err := addPatchPayloadToContainer(payloadCont, "replace", fmt.Sprintf("%s/profileTemplate", updatePath), convertValueWithMap(d.Get("profile_template").(string), ptpProfileTemplateMap)) + if err != nil { + return err + } + } + + if d.HasChange("announce_interval") { + err := addPatchPayloadToContainer(payloadCont, "replace", fmt.Sprintf("%s/announceIntvl", updatePath), d.Get("announce_interval").(int)) + if err != nil { + return err + } + } + + if d.HasChange("sync_interval") { + err := addPatchPayloadToContainer(payloadCont, "replace", fmt.Sprintf("%s/syncIntvl", updatePath), d.Get("sync_interval").(int)) + if err != nil { + return err + } + } + + if d.HasChange("delay_interval") { + err := addPatchPayloadToContainer(payloadCont, "replace", fmt.Sprintf("%s/delayIntvl", updatePath), d.Get("delay_interval").(int)) + if err != nil { + return err + } + } + + if d.HasChange("announce_timeout") { + err := addPatchPayloadToContainer(payloadCont, "replace", fmt.Sprintf("%s/announceTimeout", updatePath), d.Get("announce_timeout").(int)) + if err != nil { + return err + } + } + + if d.HasChange("override_node_profile") { + override := d.Get("override_node_profile").(bool) + err := addPatchPayloadToContainer(payloadCont, "replace", fmt.Sprintf("%s/nodeProfileOverride", updatePath), override) + if err != nil { + return err + } + } + + if d.HasChange("local_priority") { + err := addPatchPayloadToContainer(payloadCont, "replace", fmt.Sprintf("%s/localPriority", updatePath), d.Get("local_priority").(int)) + if err != nil { + return err + } + } + + if d.HasChange("destination_mac_type") { + err := addPatchPayloadToContainer(payloadCont, "replace", fmt.Sprintf("%s/dstMacType", updatePath), convertValueWithMap(d.Get("destination_mac_type").(string), ptpDestinationMacMap)) + if err != nil { + return err + } + } + + if d.HasChange("mismatched_mac_handling") { + err := addPatchPayloadToContainer(payloadCont, "replace", fmt.Sprintf("%s/dstMacRxNoMatch", updatePath), convertValueWithMap(d.Get("mismatched_mac_handling").(string), ptpMismatchedMacHandlingMap)) + if err != nil { + return err + } + } + + err = doPatchRequest(msoClient, fmt.Sprintf("api/v1/templates/%s", templateId), payloadCont) + if err != nil { + return err + } + + d.SetId(fmt.Sprintf("templateId/%s/ptpPolicyProfile/%s", templateId, d.Get("name").(string))) + log.Printf("[DEBUG] MSO PTP Policy Profile Resource - Update Complete: %v", d.Id()) + return resourceMSOPtpPolicyProfileRead(d, m) +} + +func resourceMSOPtpPolicyProfileDelete(d *schema.ResourceData, m any) error { + log.Printf("[DEBUG] MSO PTP Policy Profile Resource - Beginning Delete: %v", d.Id()) + msoClient := m.(*client.Client) + + templateCont, err := msoClient.GetViaURL(fmt.Sprintf("api/v1/templates/%s", d.Get("template_id").(string))) + if err != nil { + return err + } + + policyIndex, err := GetPolicyIndexByKeyAndValue(templateCont, "uuid", d.Get("uuid").(string), "fabricPolicyTemplate", "template", "ptpPolicy", "profiles") + if err != nil { + return err + } + + payloadModel := models.GetRemovePatchPayload(fmt.Sprintf("/fabricPolicyTemplate/template/ptpPolicy/profiles/%d", policyIndex)) + + _, err = msoClient.PatchbyID(fmt.Sprintf("api/v1/templates/%s", d.Get("template_id").(string)), payloadModel) + if err != nil { + return err + } + + d.SetId("") + log.Printf("[DEBUG] MSO PTP Policy Profile Resource - Delete Complete: %v", d.Id()) + return nil +} diff --git a/mso/resource_mso_fabric_policies_ptp_policy_profile_test.go b/mso/resource_mso_fabric_policies_ptp_policy_profile_test.go new file mode 100644 index 00000000..01af2c1f --- /dev/null +++ b/mso/resource_mso_fabric_policies_ptp_policy_profile_test.go @@ -0,0 +1,159 @@ +package mso + +import ( + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "testing" +) + +func TestAccMSOPtpPolicyProfileResource(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + PreConfig: func() { fmt.Println("Test: Create PTP Policy Profile") }, + Config: testAccMSOPtpPolicyProfileConfigCreate(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "name", "tf_ptp_profile"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "profile_template", "aes67"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "delay_interval", "-2"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "sync_interval", "-3"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "announce_interval", "1"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "announce_timeout", "3"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "override_node_profile", "false"), + resource.TestCheckResourceAttrSet("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "uuid"), + resource.TestCheckResourceAttrSet("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "ptp_policy_uuid"), + ), + }, + { + PreConfig: func() { fmt.Println("Test: Update PTP Policy Profile") }, + Config: testAccMSOPtpPolicyProfileConfigUpdate(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "name", "tf_ptp_profile_1"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "profile_template", "smpte"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "delay_interval", "-2"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "sync_interval", "-2"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "announce_interval", "-3"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "announce_timeout", "10"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "override_node_profile", "true"), + resource.TestCheckResourceAttrSet("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "uuid"), + resource.TestCheckResourceAttrSet("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", "ptp_policy_uuid"), + ), + }, + { + PreConfig: func() { fmt.Println("Test: Create Telecom PTP Policy Profile") }, + Config: testAccMSOPtpPolicyProfileConfigCreateTelecom(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile_2", "name", "tf_ptp_profile_2"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile_2", "profile_template", "telecom"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile_2", "delay_interval", "-4"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile_2", "sync_interval", "-4"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile_2", "announce_interval", "-3"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile_2", "announce_timeout", "3"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile_2", "local_priority", "120"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile_2", "destination_mac_type", "forwardable"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile_2", "mismatched_mac_handling", "reply_with_config_mac"), + resource.TestCheckNoResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile_2", "override_node_profile"), + resource.TestCheckResourceAttrSet("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile_2", "uuid"), + resource.TestCheckResourceAttrSet("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile_2", "ptp_policy_uuid"), + ), + }, + { + PreConfig: func() { fmt.Println("Test: Update Telecom PTP Policy Profile") }, + Config: testAccMSOPtpPolicyProfileConfigUpdateTelecom(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile_2", "name", "tf_ptp_profile_2"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile_2", "profile_template", "telecom"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile_2", "delay_interval", "-4"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile_2", "sync_interval", "-4"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile_2", "announce_interval", "-3"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile_2", "announce_timeout", "2"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile_2", "local_priority", "99"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile_2", "destination_mac_type", "non_forwardable"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile_2", "mismatched_mac_handling", "reply_with_received_mac"), + resource.TestCheckNoResourceAttr("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile_2", "override_node_profile"), + resource.TestCheckResourceAttrSet("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile_2", "uuid"), + resource.TestCheckResourceAttrSet("mso_fabric_policies_ptp_policy_profile.ptp_policy_profile_2", "ptp_policy_uuid"), + ), + }, + { + PreConfig: func() { fmt.Println("Test: Import PTP Policy Profile") }, + ResourceName: "mso_fabric_policies_ptp_policy_profile.ptp_policy_profile", + ImportState: true, + ImportStateVerify: true, + }, + }, + CheckDestroy: testCheckResourceDestroyPolicyWithPathAttributesAndArguments("mso_fabric_policies_ptp_policy_profile", "fabricPolicyTemplate", "template", "ptpPolicy", "profiles"), + }) +} + +func testAccMSOPtpPolicyProfileConfigCreate() string { + return fmt.Sprintf(`%s + resource "mso_fabric_policies_ptp_policy_profile" "ptp_policy_profile" { + template_id = mso_template.template_fabric_policy.id + ptp_policy_uuid = mso_fabric_policies_ptp_policy.ptp_policy.uuid + name = "tf_ptp_profile" + profile_template = "aes67" + delay_interval = -2 + sync_interval = -3 + announce_timeout = 3 + announce_interval = 1 + override_node_profile = false + }`, testAccMSOPtpPolicyConfigCreate()) +} + +func testAccMSOPtpPolicyProfileConfigUpdate() string { + return fmt.Sprintf(`%s + resource "mso_fabric_policies_ptp_policy_profile" "ptp_policy_profile" { + template_id = mso_template.template_fabric_policy.id + ptp_policy_uuid = mso_fabric_policies_ptp_policy.ptp_policy.uuid + name = "tf_ptp_profile_1" + profile_template = "smpte" + delay_interval = -2 + sync_interval = -2 + announce_timeout = 10 + announce_interval = -3 + override_node_profile = true + }`, testAccMSOPtpPolicyConfigCreate()) +} + +func testAccMSOPtpPolicyProfileConfigCreateTelecom() string { + return fmt.Sprintf(`%s + resource "mso_fabric_policies_ptp_policy_profile" "ptp_policy_profile_2" { + template_id = mso_template.template_fabric_policy.id + ptp_policy_uuid = mso_fabric_policies_ptp_policy.ptp_policy.uuid + name = "tf_ptp_profile_2" + profile_template = "telecom" + announce_interval = -3 + delay_interval = -4 + sync_interval = -4 + announce_timeout = 3 + local_priority = 120 + destination_mac_type = "forwardable" + mismatched_mac_handling = "reply_with_config_mac" + }`, testAccMSOPtpPolicyProfileConfigUpdate()) +} + +func testAccMSOPtpPolicyProfileConfigUpdateTelecom() string { + return fmt.Sprintf(`%s + resource "mso_fabric_policies_ptp_policy_profile" "ptp_policy_profile_2" { + template_id = mso_template.template_fabric_policy.id + ptp_policy_uuid = mso_fabric_policies_ptp_policy.ptp_policy.uuid + name = "tf_ptp_profile_2" + profile_template = "telecom" + announce_interval = -3 + delay_interval = -4 + sync_interval = -4 + announce_timeout = 2 + local_priority = 99 + destination_mac_type = "non_forwardable" + mismatched_mac_handling = "reply_with_received_mac" + + # Explicit dependency on first PTP Profile + # This is to ensure the test deletes the profiles in order. + depends_on = [ + mso_fabric_policies_ptp_policy_profile.ptp_policy_profile + ] + }`, testAccMSOPtpPolicyProfileConfigUpdate()) +} diff --git a/mso/resource_mso_fabric_policies_ptp_policy_test.go b/mso/resource_mso_fabric_policies_ptp_policy_test.go new file mode 100644 index 00000000..a4fc56a0 --- /dev/null +++ b/mso/resource_mso_fabric_policies_ptp_policy_test.go @@ -0,0 +1,131 @@ +package mso + +import ( + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "testing" +) + +func TestAccMSOPtpPolicyResource(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + PreConfig: func() { fmt.Println("Test: Create PTP Policy") }, + Config: testAccMSOPtpPolicyConfigCreate(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "name", "tf_test_ptp_policy"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "description", "Terraform test PTP Policy"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "admin_state", "enabled"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "fabric_profile_template", "default"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "global_priority1", "255"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "global_priority2", "254"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "global_domain", "100"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "fabric_announce_interval", "1"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "fabric_sync_interval", "-1"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "fabric_delay_interval", "1"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "fabric_announce_timeout", "3"), + resource.TestCheckResourceAttrSet("mso_fabric_policies_ptp_policy.ptp_policy", "uuid"), + ), + }, + { + PreConfig: func() { fmt.Println("Test: Update PTP Policy disabled state") }, + Config: testAccMSOPtpPolicyConfigUpdateDisable(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "name", "tf_test_ptp_policy_new"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "description", ""), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "admin_state", "disabled"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "fabric_profile_template", "default"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "global_priority1", "255"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "global_priority2", "254"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "global_domain", "100"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "fabric_announce_interval", "1"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "fabric_sync_interval", "-1"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "fabric_delay_interval", "1"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "fabric_announce_timeout", "3"), + resource.TestCheckResourceAttrSet("mso_fabric_policies_ptp_policy.ptp_policy", "uuid"), + ), + }, + { + PreConfig: func() { fmt.Println("Test: Update PTP Policy changing the profile template") }, + Config: testAccMSOPtpPolicyConfigUpdateChangingTemplate(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "name", "tf_test_ptp_policy_new"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "description", "Terraform test PTP Policy"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "admin_state", "enabled"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "fabric_profile_template", "smpte"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "global_priority1", "200"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "global_priority2", "250"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "global_domain", "99"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "fabric_announce_interval", "-3"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "fabric_sync_interval", "-4"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "fabric_delay_interval", "-2"), + resource.TestCheckResourceAttr("mso_fabric_policies_ptp_policy.ptp_policy", "fabric_announce_timeout", "10"), + resource.TestCheckResourceAttrSet("mso_fabric_policies_ptp_policy.ptp_policy", "uuid"), + ), + }, + { + PreConfig: func() { fmt.Println("Test: Import PTP Policy") }, + ResourceName: "mso_fabric_policies_ptp_policy.ptp_policy", + ImportState: true, + ImportStateVerify: true, + }, + }, + CheckDestroy: testCheckResourceDestroyPolicyWithPathAttributesAndArguments("mso_fabric_policies_ptp_policy", "fabricPolicyTemplate", "template", "ptpPolicy"), + }) +} + +func testAccMSOPtpPolicyConfigCreate() string { + return fmt.Sprintf(`%s + resource "mso_fabric_policies_ptp_policy" "ptp_policy" { + template_id = mso_template.template_fabric_policy.id + name = "tf_test_ptp_policy" + description = "Terraform test PTP Policy" + admin_state = "enabled" + fabric_profile_template = "default" + global_priority1 = 255 + global_priority2 = 254 + global_domain = 100 + fabric_announce_interval = 1 + fabric_sync_interval = -1 + fabric_delay_interval = 1 + fabric_announce_timeout = 3 + }`, testAccMSOTemplateResourceFabricPolicyConfig()) +} + +func testAccMSOPtpPolicyConfigUpdateDisable() string { + return fmt.Sprintf(`%s + resource "mso_fabric_policies_ptp_policy" "ptp_policy" { + template_id = mso_template.template_fabric_policy.id + name = "tf_test_ptp_policy_new" + description = "" + admin_state = "disabled" + fabric_profile_template = "default" + global_priority1 = 255 + global_priority2 = 254 + global_domain = 100 + fabric_announce_interval = 1 + fabric_sync_interval = -1 + fabric_delay_interval = 1 + fabric_announce_timeout = 3 + }`, testAccMSOTemplateResourceFabricPolicyConfig()) +} + +func testAccMSOPtpPolicyConfigUpdateChangingTemplate() string { + return fmt.Sprintf(`%s + resource "mso_fabric_policies_ptp_policy" "ptp_policy" { + template_id = mso_template.template_fabric_policy.id + name = "tf_test_ptp_policy_new" + description = "Terraform test PTP Policy" + admin_state = "enabled" + fabric_profile_template = "smpte" + global_priority1 = 200 + global_priority2 = 250 + global_domain = 99 + fabric_announce_interval = -3 + fabric_sync_interval = -4 + fabric_delay_interval = -2 + fabric_announce_timeout = 10 + }`, testAccMSOTemplateResourceFabricPolicyConfig()) +} diff --git a/website/docs/d/fabric_policies_ptp_policy.html.markdown b/website/docs/d/fabric_policies_ptp_policy.html.markdown new file mode 100644 index 00000000..ca03f1f2 --- /dev/null +++ b/website/docs/d/fabric_policies_ptp_policy.html.markdown @@ -0,0 +1,44 @@ +--- +layout: "mso" +page_title: "MSO: mso_fabric_policies_ptp_policy" +sidebar_current: "docs-mso-data-source-fabric_policies_ptp_policy" +description: |- + Data source for the PTP Policy on Cisco Nexus Dashboard Orchestrator (NDO) +--- + +# mso_fabric_policies_ptp_policy # + +Data source for the (Precision Time Protocol) PTP Policy on Cisco Nexus Dashboard Orchestrator (NDO). This data source is supported in NDO v4.3(1) or higher. + +## GUI Information ## + +* `Location` - Manage -> Fabric Template -> Fabric Policies -> PTP Policy + +## Example Usage ## + +```hcl +data "mso_fabric_policies_ptp_policy" "ptp_policy" { + template_id = mso_template.fabric_policy_template.id + name = "ptp_policy" +} +``` + +## Argument Reference ## + +* `template_id` - (Required) The unique ID of the Fabric Policy template. +* `name` - (Required) The name of the PTP Policy. + +## Attribute Reference ## + +* `uuid` - (Read-Only) The NDO UUID of the PTP Policy. +* `id` - (Read-Only) The unique Terraform identifier of the PTP Policy. +* `description` - (Read-Only) The description of the PTP Policy. +* `admin_state` - (Read-Only) The administrative state of the PTP Policy. +* `global_priority1` - (Read-Only) The global priority1 of the PTP Policy. +* `global_priority2` - (Read-Only) The global priority2 of the PTP Policy. +* `global_domain` - (Read-Only) The global domain of the PTP Policy. +* `fabric_profile_template` - (Read-Only) The fabric profile template of the PTP Policy. +* `fabric_announce_interval` - (Read-Only) The fabric announce interval of the PTP Policy. +* `fabric_sync_interval` - (Read-Only) The fabric sync interval of the PTP Policy. +* `fabric_delay_interval` - (Read-Only) The fabric delay interval of the PTP Policy. +* `fabric_announce_timeout` - (Read-Only) The fabric announce timeout of the PTP Policy. diff --git a/website/docs/d/fabric_policies_ptp_policy_profile.html.markdown b/website/docs/d/fabric_policies_ptp_policy_profile.html.markdown new file mode 100644 index 00000000..afc45a6a --- /dev/null +++ b/website/docs/d/fabric_policies_ptp_policy_profile.html.markdown @@ -0,0 +1,45 @@ +--- +layout: "mso" +page_title: "MSO: mso_fabric_policies_ptp_policy_profile" +sidebar_current: "docs-mso-data-source-fabric_policies_ptp_policy" +description: |- + Data source for PTP Profiles on Cisco Nexus Dashboard Orchestrator (NDO) +--- + +# mso_fabric_policies_ptp_policy_profile # + +Data source for (Precision Time Protocol) PTP Policy Profiles on Cisco Nexus Dashboard Orchestrator (NDO). This data source is supported in NDO v4.3(1) or higher. + +## GUI Information ## + +* `Location` - Manage -> Fabric Template -> Fabric Policies -> PTP Policy -> Profiles + +## Example Usage ## + +```hcl +data "mso_fabric_policies_ptp_policy_profile" "ptp_policy_profile" { + template_id = mso_template.fabric_policy_template.id + name = "ptp_profile" +} +``` + +## Argument Reference ## + +* `template_id` - (Required) The unique ID of the Fabric Policy template. +* `name` - (Required) The name of the PTP Profile. + +## Attribute Reference ## + +* `uuid` - (Read-Only) The NDO UUID of the PTP Profile. +* `ptp_policy_uuid` - (Read-Only) The NDO UUID of the PTP Policy. +* `id` - (Read-Only) The unique Terraform identifier of the PTP Profile. +* `description` - (Read-Only) The description of the PTP Profile. +* `delay_interval` - (Read-Only) The delay interval of the PTP Profile. +* `profile_template` - (Read-Only) The profile template of the PTP Profile. +* `sync_interval` - (Read-Only) The sync interval of the PTP Profile. +* `override_node_profile` - (Read-Only) The node profile override of the PTP Profile. +* `announce_timeout` - (Read-Only) The announce timeout of the PTP Profile. +* `announce_interval` - (Read-Only) The announce interval of the PTP Profile. +* `local_priority` - (Read-Only) The local priority of the PTP Profile. +* `destination_mac_type` - (Read-Only) The destination MAC for PTP messages of the PTP Profile. +* `mismatched_mac_handling` - (Read-Only) The mismatched destination MAC handling of the PTP Profile. diff --git a/website/docs/r/fabric_policies_ptp_policy.html.markdown b/website/docs/r/fabric_policies_ptp_policy.html.markdown new file mode 100644 index 00000000..5f2a5d01 --- /dev/null +++ b/website/docs/r/fabric_policies_ptp_policy.html.markdown @@ -0,0 +1,62 @@ +--- +layout: "mso" +page_title: "MSO: mso_fabric_policies_ptp_policy" +sidebar_current: "docs-mso-resource-fabric_policies_ptp_policy" +description: |- + Manages PTP Policies on Cisco Nexus Dashboard Orchestrator (NDO) +--- + +# mso_fabric_policies_ptp_policy # + +Manages PTP Policies on Cisco Nexus Dashboard Orchestrator (NDO). This resource is supported in NDO v4.3(1) or higher. + +## GUI Information ## + +* `Location` - Manage -> Fabric Template -> Fabric Policies -> PTP Policy + +## Example Usage ## + +```hcl +resource "mso_fabric_policies_ptp_policy" "ptp_policy" { + template_id = mso_template.fabric_policy_template.id + name = "ptp_policy" + description = "Example description" + admin_state = "enabled" + global_priority1 = 250 + global_priority2 = 100 + global_domain = 99 + fabric_profile_template = "aes67" + fabric_announce_interval = 1 + fabric_sync_interval = -3 + fabric_delay_interval = -2 + fabric_announce_timeout = 3 +} +``` + +## Argument Reference ## + +* `template_id` - (Required) The unique ID of the Fabric Policy template. +* `name` - (Required) The name of the PTP Policy. +* `description` - (Optional) The description of the PTP Policy. If this argument is omitted, the value defaults to an empty string (`""`). +* `admin_state` - (Required) The administrative state of the PTP Policy. Allowed values are `enabled` or `disabled`. +* `global_priority1` - (Required) The global priority1 of the PTP Policy. Valid range: 1-255. +* `global_priority2` - (Required) The global priority2 of the PTP Policy. Valid range: 0-255. +* `global_domain` - (Required) The global domain of the PTP Policy. Valid range: 0-128. +* `fabric_profile_template` - (Required) The fabric profile template of the PTP Policy. Allowed values are `default`, `aes67`, or `smpte`. +* `fabric_announce_interval` - (Required) The fabric announce interval in log base 2 seconds of the PTP Policy. Valid range: -3 to 4. +* `fabric_sync_interval` - (Required) The fabric sync interval in log base 2 seconds of the PTP Policy. Valid range: -4 to 1. +* `fabric_delay_interval` - (Required) The fabric delay interval in log base 2 seconds of the PTP Policy. Valid range: -4 to 5. +* `fabric_announce_timeout` - (Required) The fabric announce interval timeout count of the PTP Policy. Valid range: 2 to 10. + +## Attribute Reference ## + +* `uuid` - (Read-Only) The NDO UUID of the PTP Policy. +* `id` - (Read-Only) The unique Terraform identifier of the PTP Policy. + +## Importing ## + +An existing MSO PTP Policy can be [imported][docs-import] into this resource via its ID/path, via the following command: [docs-import]: + +```bash +terraform import mso_fabric_policies_ptp_policy.ptp_policy templateId/{template_id}/ptpPolicy/{name} +``` diff --git a/website/docs/r/fabric_policies_ptp_policy_profile.html.markdown b/website/docs/r/fabric_policies_ptp_policy_profile.html.markdown new file mode 100644 index 00000000..294cf833 --- /dev/null +++ b/website/docs/r/fabric_policies_ptp_policy_profile.html.markdown @@ -0,0 +1,61 @@ +--- +layout: "mso" +page_title: "MSO: mso_fabric_policies_ptp_policy_profile" +sidebar_current: "docs-mso-resource-fabric_policies_ptp_policy_profile" +description: |- + Manages PTP Policy Profiles on Cisco Nexus Dashboard Orchestrator (NDO) +--- + +# mso_fabric_policies_ptp_policy_profile # + +Manages (Precision Time Protocol) PTP Policy Profiles on Cisco Nexus Dashboard Orchestrator (NDO). This resource is supported in NDO v4.3(1) or higher. + +## GUI Information ## + +* `Location` - Manage -> Fabric Template -> Fabric Policies -> PTP Policy -> Profiles + +## Example Usage ## + +```hcl +resource "mso_fabric_policies_ptp_policy_profile" "ptp_policy_profile" { + template_id = mso_template.fabric_policy_template.id + ptp_policy_uuid = mso_fabric_policies_ptp_policy.ptp_policy.uuid + name = "ptp_policy_profile" + description = "Example description" + delay_interval = -2 + sync_interval = -3 + announce_timeout = 3 + announce_interval = 1 + profile_template = "aes67" + override_node_profile = false +} +``` + +## Argument Reference ## + +* `template_id` - (Required) The unique ID of the Fabric Policy template. +* `ptp_policy_uuid` - (Required) The NDO UUID of the PTP Policy. +* `name` - (Required) The name of the PTP Profile. +* `description` - (Optional) The description of the PTP Profile. +* `profile_template` - (Required) The profile template of the PTP Profile. Allowed values are `default`, `aes67`, `smpte` or `telecom`. +* `delay_interval` - (Required) The minimum delay request interval in log base 2 seconds of the PTP Profile. Valid range: -4 to 5. +* `announce_timeout` - (Required) The announce interval timeout count of the PTP Profile. Valid range: 2 to 10. +* `announce_interval` - (Required) The announce interval in log base 2 seconds of the PTP Profile. Valid range: -3 to 4. +* `sync_interval` - (Required) The sync interval in log base 2 seconds of the PTP Profile.Valid range: -4 to 1. +* `override_node_profile` - (Optional) The node profile override of the PTP Profile. This parameter is not applicable when `profile_template` is `telecom`. Allowed Values: `true` or `false`. +* `local_priority` - (Optional) The local priority of the PTP Profile. This parameter is only applicable when `profile_template` is `telecom`. Valid range: 1 to 128. +* `destination_mac_type` - (Optional) The destination MAC for PTP messages of the PTP Profile. This parameter is only applicable when `profile_template` is `telecom`. Allowed values are `forwardable` or `non_forwardable`. +* `mismatched_mac_handling` - (Optional) The mismatched destination MAC handling of the PTP Profile. This parameter is only applicable when `profile_template` is `telecom`. Allowed values are `drop`, `reply_with_config_mac` or `reply_with_received_mac`. + +## Attribute Reference ## + +* `uuid` - (Read-Only) The NDO UUID of the PTP Profile. +* `id` - (Read-Only) The unique Terraform identifier of the PTP Profile. + +## Importing ## + +An existing MSO PTP Profile can be [imported][docs-import] into this resource via its ID/path, via the following command: [docs-import]: + +```bash +terraform import mso_fabric_policies_ptp_policy_profile.ptp_policy_profile templateId/{template_id}/ptpPolicyProfile/{name} +```