Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[minor_change] Add resource and datasource for mso_template (DCNE-217) #309

Merged
merged 3 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions examples/template/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
terraform {
required_providers {
mso = {
source = "CiscoDevNet/mso"
}
}
}

provider "mso" {
username = "" # <MSO username>
password = "" # <MSO pwd>
url = "" # <MSO URL>
insecure = true
}

data "mso_site" "site_1" {
name = "example_site_1"
}

data "mso_site" "site_2" {
name = "example_site_2"
}

data "mso_tenant" "example_tenant" {
name = "example_tenant"
}

# tenant template example

resource "mso_template" "tenant_template" {
template_name = "tenant_template"
template_type = "tenant"
tenant_id = data.mso_tenant.example_tenant.id
sites = [data.mso_site.site_1.id, data.mso_site.site_2.id]
}

# l3out template example

resource "mso_template" "l3out_template" {
template_name = "l3out_template"
template_type = "l3out"
tenant_id = data.mso_tenant.example_tenant.id
sites = [data.mso_site.site_1.id]
}

# fabric policy template example

resource "mso_template" "fabric_policy_template" {
template_name = "fabric_policy_template"
template_type = "fabric_policy"
sites = [data.mso_site.site_1.id, data.mso_site.site_2.id]
}

# fabric resource template example

resource "mso_template" "fabric_resource_template" {
template_name = "fabric_resource_template"
template_type = "fabric_resource"
sites = [data.mso_site.site_1.id, data.mso_site.site_2.id]
}

# monitoring tenant template example

resource "mso_template" "monitoring_tenant_template" {
template_name = "monitoring_tenant_template"
template_type = "monitoring_tenant"
tenant_id = data.mso_tenant.example_tenant.id
sites = [data.mso_site.site_1.id]
}

# monitoring access template example

resource "mso_template" "monitoring_access_template" {
template_name = "monitoring_access_template"
template_type = "monitoring_access"
sites = [data.mso_site.site_1.id]
}

# service device template example

resource "mso_template" "service_device_template" {
template_name = "service_device_template"
template_type = "service_device"
tenant_id = data.mso_tenant.example_tenant.id
sites = [data.mso_site.site_1.id, data.mso_site.site_2.id]
}
84 changes: 84 additions & 0 deletions mso/datasource_mso_template.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package mso

import (
"fmt"
"log"

"github.com/ciscoecosystem/mso-go-client/client"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
)

func datasourceMSOTemplate() *schema.Resource {
return &schema.Resource{

Read: datasourceMSOTemplateRead,

SchemaVersion: version,

Schema: (map[string]*schema.Schema{
"template_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringLenBetween(1, 1000),
},
"template_name": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringLenBetween(1, 1000),
},
"template_type": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{
"tenant",
"l3out",
"fabric_policy",
"fabric_resource",
"monitoring_tenant",
"monitoring_access",
"service_device",
}, false),
},
"tenant_id": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"sites": &schema.Schema{
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
}),
}
}

func datasourceMSOTemplateRead(d *schema.ResourceData, m interface{}) error {
log.Println("[DEBUG] MSO Template Datasource: Beginning Read")

msoClient := m.(*client.Client)
id := d.Get("template_id").(string)
name := d.Get("template_name").(string)
templateType := d.Get("template_type").(string)

if id == "" && name == "" {
return fmt.Errorf("either `template_id` or `template_name` must be provided")
} else if id != "" && name != "" {
return fmt.Errorf("only one of `template_id` or `template_name` must be provided")
} else if name != "" && templateType == "" {
return fmt.Errorf("`template_type` must be provided when `template_name` is provided")
}

ndoTemplate := ndoTemplate{msoClient: msoClient, id: id, templateName: name, templateType: templateType}
err := ndoTemplate.getTemplate(true)
if err != nil {
return err
}
ndoTemplate.SetSchemaResourceData(d)
d.Set("template_id", d.Id())
log.Println("[DEBUG] MSO Template Datasource: Read Completed", d.Id())
return nil

}
143 changes: 143 additions & 0 deletions mso/datasource_mso_template_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package mso

import (
"fmt"
"regexp"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
)

func TestAccMSOTemplateDatasourceTenantErrors(t *testing.T) {

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
PreConfig: func() { fmt.Println("Test: No template_id or template_name provided in Template configuration") },
Config: testAccMSOTemplateDatasourceErrorNoIdOrNameConfig(),
ExpectError: regexp.MustCompile("either `template_id` or `template_name` must be provided"),
},
{
PreConfig: func() { fmt.Println("Test: No template_type with name provided in Template configuration") },
Config: testAccMSOTemplateDatasourceErrorNoTypeConfig(),
ExpectError: regexp.MustCompile("`template_type` must be provided when `template_name` is provided"),
},
{
PreConfig: func() { fmt.Println("Test: Both template_id and template_name provided in Template configuration") },
Config: testAccMSOTemplateDatasourceErrorIdAndNameConfig(),
ExpectError: regexp.MustCompile("only one of `template_id` or `template_name` must be provided"),
},
{
PreConfig: func() { fmt.Println("Test: Non existing template name provided in Template configuration") },
Config: testAccMSOTemplateDatasourceErrorNonExistingConfig(),
ExpectError: regexp.MustCompile("Template with name 'non_existing_template_name' not found."),
},
},
})
}

func TestAccMSOTemplateDatasourceTenantName(t *testing.T) {

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
PreConfig: func() { fmt.Println("Test: Tenant template with name and type provided in Template configuration") },
Config: testAccMSOTemplateDatasourceNameAndTypeConfig(),
Check: resource.ComposeTestCheckFunc(
testAccMSOTemplateState(
"data.mso_template.template_tenant",
&TemplateTest{
TemplateName: "test_template_tenant",
TemplateType: "tenant",
Tenant: msoTemplateTenantName,
Sites: []string{msoTemplateSiteName1, msoTemplateSiteName2},
},
false,
),
),
},
},
})
}

func TestAccMSOTemplateDatasourceTenantId(t *testing.T) {

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
PreConfig: func() { fmt.Println("Test: Tenant template with id provided in Template configuration") },
Config: testAccMSOTemplateDatasourceIdConfig(),
Check: resource.ComposeTestCheckFunc(
testAccMSOTemplateState(
"data.mso_template.template_tenant",
&TemplateTest{
TemplateName: "test_template_tenant",
TemplateType: "tenant",
Tenant: msoTemplateTenantName,
Sites: []string{msoTemplateSiteName1, msoTemplateSiteName2},
},
false,
),
),
},
},
})
}

func testAccMSOTemplateDatasourceNameAndTypeConfig() string {
return fmt.Sprintf(`%s
data "mso_template" "template_tenant" {
template_name = mso_template.template_tenant.template_name
template_type = "tenant"
}
`, testAccMSOTemplateResourceTenanTwoSitesConfig())
}

func testAccMSOTemplateDatasourceIdConfig() string {
return fmt.Sprintf(`%s
data "mso_template" "template_tenant" {
template_id = mso_template.template_tenant.id
}
`, testAccMSOTemplateResourceTenanTwoSitesConfig())
}

func testAccMSOTemplateDatasourceErrorNoIdOrNameConfig() string {
return fmt.Sprintf(`
data "mso_template" "template_tenant" {
template_type = "tenant"
}
`)
}

func testAccMSOTemplateDatasourceErrorNoTypeConfig() string {
return fmt.Sprintf(`
data "mso_template" "template_tenant" {
template_name = "non_existing_template_name"
}
`)
}

func testAccMSOTemplateDatasourceErrorIdAndNameConfig() string {
return fmt.Sprintf(`
data "mso_template" "template_tenant" {
template_id = "non_existing_template_id"
template_name = "non_existing_template_name"
template_type = "tenant"
}
`)
}

func testAccMSOTemplateDatasourceErrorNonExistingConfig() string {
return fmt.Sprintf(`
data "mso_template" "template_tenant" {
template_name = "non_existing_template_name"
template_type = "tenant"
}
`)
}
2 changes: 2 additions & 0 deletions mso/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ func Provider() terraform.ResourceProvider {
"mso_system_config": resourceMSOSystemConfig(),
"mso_schema_site_contract_service_graph": resourceMSOSchemaSiteContractServiceGraph(),
"mso_schema_site_contract_service_graph_listener": resourceMSOSchemaSiteContractServiceGraphListener(),
"mso_template": resourceMSOTemplate(),
},

DataSourcesMap: map[string]*schema.Resource{
Expand Down Expand Up @@ -172,6 +173,7 @@ func Provider() terraform.ResourceProvider {
"mso_rest": datasourceMSORest(),
"mso_schema_site_contract_service_graph": dataSourceMSOSchemaSiteContractServiceGraph(),
"mso_schema_site_contract_service_graph_listener": dataSourceMSOSchemaSiteContractServiceGraphListener(),
"mso_template": datasourceMSOTemplate(),
},

ConfigureFunc: configureClient,
Expand Down
Loading
Loading