diff --git a/.gitignore b/.gitignore index caf894e5..2b254036 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,6 @@ **/terraform.tfstate **/terraform.tfstate.backup **/.vscode +**/.vscode/* **/.terraform.lock.hcl +**/*.log \ No newline at end of file diff --git a/examples/schema_site_l3out/main.tf b/examples/schema_site_l3out/main.tf new file mode 100644 index 00000000..bc03e72b --- /dev/null +++ b/examples/schema_site_l3out/main.tf @@ -0,0 +1,66 @@ +terraform { + required_providers { + mso = { + source = "CiscoDevNet/mso" + } + } +} + +provider "mso" { + username = "" # + password = "" # + url = "" # + insecure = true +} + +data "mso_site" "example" { + name = "example" +} + +data "mso_tenant" "example" { + name = "example" + display_name = "example" +} + +resource "mso_schema" "example" { + name = "example" + template_name = "example" + tenant_id = data.mso_tenant.example.id +} + +resource "mso_schema_template_vrf" "vrf" { + schema_id = mso_schema.example.id + template = mso_schema.example.template_name + name = "example" +} + +resource "mso_schema_template_l3out" "l3out" { + schema_id = mso_schema.example.id + template_name = mso_schema.example.template_name + l3out_name = "example" + vrf_name = mso_schema_template_vrf.vrf.id + vrf_schema_id = mso_schema_template_vrf.vrf.schema_id + vrf_template_name = mso_schema_template_vrf.vrf.template +} + + +resource "mso_schema_site" "example" { + schema_id = mso_schema.example.id + site_id = data.mso_site.example.id + template_name = "example" +} + +resource "mso_schema_site_vrf" "example" { + template_name = mso_schema_site.example.template_name + site_id = mso_schema_site.example.site_id + schema_id = mso_schema_site.example.schema_id + vrf_name = mso_schema_template_vrf.example.name +} + +resource "mso_schema_site_l3out" "example" { + schema_id = mso_schema_site.example.schema_id + l3out_name = mso_schema_template_l3out.l3out.l3out_name + template_name = mso_schema_site.example.template_name + vrf_name = mso_schema_site_vrf.example.vrf_name + site_id = mso_schema_site.example.site_id +} \ No newline at end of file diff --git a/mso/datasource_mso_schema_site_l3out.go b/mso/datasource_mso_schema_site_l3out.go new file mode 100644 index 00000000..5e420ffe --- /dev/null +++ b/mso/datasource_mso_schema_site_l3out.go @@ -0,0 +1,70 @@ +package mso + +import ( + "log" + + "github.com/ciscoecosystem/mso-go-client/client" + "github.com/ciscoecosystem/mso-go-client/models" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" +) + +func datasourceMSOSchemaSiteL3out() *schema.Resource { + return &schema.Resource{ + Read: datasourceMSOSchemaSiteL3outRead, + SchemaVersion: 1, + Schema: map[string]*schema.Schema{ + "l3out_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(1, 1000), + }, + "vrf_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(1, 1000), + }, + "template_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(1, 1000), + }, + "site_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(1, 1000), + }, + "schema_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(1, 1000), + }, + }, + } +} + +func datasourceMSOSchemaSiteL3outRead(d *schema.ResourceData, m interface{}) error { + log.Println("[DEBUG] Schema Site L3out: Beginning Read") + msoClient := m.(*client.Client) + schemaId := d.Get("schema_id").(string) + siteId := d.Get("site_id").(string) + templateName := d.Get("template_name").(string) + vrfName := d.Get("vrf_name").(string) + l3outName := d.Get("l3out_name").(string) + l3outMap := models.IntersiteL3outs{ + SchemaID: schemaId, + SiteId: siteId, + TemplateName: templateName, + VRFName: vrfName, + L3outName: l3outName, + } + l3outMapRemote, err := msoClient.ReadIntersiteL3outs(&l3outMap) + if err != nil { + d.SetId("") + return err + } + setMSOSchemaSiteL3outAttributes(l3outMapRemote, d) + d.SetId(L3outModelToL3outId(&l3outMap)) + log.Println("[DEBUG] Schema Site L3out: Reading Completed", d.Id()) + return nil +} diff --git a/mso/provider.go b/mso/provider.go index 8f511389..5cc93ac5 100644 --- a/mso/provider.go +++ b/mso/provider.go @@ -51,7 +51,7 @@ func Provider() terraform.ResourceProvider { "platform": &schema.Schema{ Type: schema.TypeString, Optional: true, - DefaultFunc: schema.EnvDefaultFunc("MSO_PLATFORM", nil), + DefaultFunc: schema.EnvDefaultFunc("MSO_PLATFORM", "mso"), Description: "Parameter that specifies where MSO is installed", // defaults to "mso" ValidateFunc: validation.StringInSlice([]string{ "mso", @@ -94,6 +94,7 @@ func Provider() terraform.ResourceProvider { "mso_schema_site_vrf_route_leak": resourceMSOSchemaSiteVrfRouteLeak(), "mso_schema_site_vrf_region": resourceMSOSchemaSiteVrfRegion(), "mso_schema_site_bd_subnet": resourceMSOSchemaSiteBdSubnet(), + "mso_schema_site_l3out": resourceMSOSchemaSiteL3out(), "mso_rest": resourceMSORest(), "mso_schema_template_deploy": resourceMSOSchemaTemplateDeploy(), "mso_schema_template_deploy_ndo": resourceNDOSchemaTemplateDeploy(), @@ -155,6 +156,7 @@ func Provider() terraform.ResourceProvider { "mso_schema_site_vrf_region": dataSourceMSOSchemaSiteVrfRegion(), "mso_schema_site_vrf_route_leak": dataSourceMSOSchemaSiteVrfRouteLeak(), "mso_schema_site_bd_subnet": dataSourceMSOSchemaSiteBdSubnet(), + "mso_schema_site_l3out": datasourceMSOSchemaSiteL3out(), "mso_schema_site_vrf_region_cidr_subnet": dataSourceMSOSchemaSiteVrfRegionCidrSubnet(), "mso_schema_site_vrf_region_cidr": dataSourceMSOSchemaSiteVrfRegionCidr(), "mso_schema_template_anp_epg_selector": datasourceMSOSchemaTemplateAnpEpgSelector(), diff --git a/mso/resource_mso_schema_site_l3out.go b/mso/resource_mso_schema_site_l3out.go new file mode 100644 index 00000000..2f9d33d6 --- /dev/null +++ b/mso/resource_mso_schema_site_l3out.go @@ -0,0 +1,162 @@ +package mso + +import ( + "fmt" + "log" + "strings" + + "github.com/ciscoecosystem/mso-go-client/client" + "github.com/ciscoecosystem/mso-go-client/models" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" +) + +func resourceMSOSchemaSiteL3out() *schema.Resource { + return &schema.Resource{ + Create: resourceMSOSchemaSiteL3outCreate, + Read: resourceMSOSchemaSiteL3outRead, + Delete: resourceMSOSchemaSiteL3outDelete, + Importer: &schema.ResourceImporter{ + State: resourceMSOSchemaSiteL3outImport, + }, + SchemaVersion: 1, + Schema: map[string]*schema.Schema{ + "l3out_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(1, 1000), + }, + "vrf_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(1, 1000), + }, + "template_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(1, 1000), + }, + "site_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(1, 1000), + }, + "schema_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(1, 1000), + }, + }, + } +} + +func setMSOSchemaSiteL3outAttributes(l3outMap *models.IntersiteL3outs, d *schema.ResourceData) { + d.Set("l3out_name", l3outMap.L3outName) + d.Set("vrf_name", l3outMap.VRFName) + d.Set("template_name", l3outMap.TemplateName) + d.Set("site_id", l3outMap.SiteId) + d.Set("schema_id", l3outMap.SchemaID) +} + +func resourceMSOSchemaSiteL3outImport(d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) { + log.Println("[DEBUG] Schema Site L3out: Beginning Import", d.Id()) + msoClient := m.(*client.Client) + id := d.Id() + L3out, err := L3outIdToL3outModel(id) + if err != nil { + return nil, err + } + l3outMapRemote, err := msoClient.ReadIntersiteL3outs(L3out) + if err != nil { + return nil, err + } + setMSOSchemaSiteL3outAttributes(l3outMapRemote, d) + d.SetId(id) + log.Println("[DEBUG] Schema Site L3out: Import Completed", d.Id()) + return []*schema.ResourceData{d}, nil +} + +func resourceMSOSchemaSiteL3outCreate(d *schema.ResourceData, m interface{}) error { + log.Printf("[DEBUG] Schema Site L3out: Beginning Creation") + msoClient := m.(*client.Client) + schemaId := d.Get("schema_id").(string) + siteId := d.Get("site_id").(string) + templateName := d.Get("template_name").(string) + vrfName := d.Get("vrf_name").(string) + l3outName := d.Get("l3out_name").(string) + l3outMap := models.IntersiteL3outs{ + L3outName: l3outName, + VRFName: vrfName, + SiteId: siteId, + TemplateName: templateName, + SchemaID: schemaId, + } + err := msoClient.CreateIntersiteL3outs(&l3outMap) + if err != nil { + return err + } + l3outId := L3outModelToL3outId(&l3outMap) + d.SetId(l3outId) + log.Printf("[DEBUG] Schema Site L3out: Creation Completed") + return resourceMSOSchemaSiteL3outRead(d, m) +} + +func resourceMSOSchemaSiteL3outRead(d *schema.ResourceData, m interface{}) error { + log.Println("[DEBUG] Schema Site L3out: Beginning Read", d.Id()) + msoClient := m.(*client.Client) + id := d.Id() + l3out, err := L3outIdToL3outModel(id) + if err != nil { + return err + } + l3outMapRemote, err := msoClient.ReadIntersiteL3outs(l3out) + if err != nil { + d.SetId("") + return nil + } + setMSOSchemaSiteL3outAttributes(l3outMapRemote, d) + d.SetId(L3outModelToL3outId(l3out)) + log.Println("[DEBUG] Schema Site L3out: Reading Completed", d.Id()) + return nil +} + +func resourceMSOSchemaSiteL3outDelete(d *schema.ResourceData, m interface{}) error { + log.Println("[DEBUG] Schema Site L3out: Beginning Destroy", d.Id()) + msoClient := m.(*client.Client) + id := d.Id() + l3out, err := L3outIdToL3outModel(id) + if err != nil { + return err + } + err = msoClient.DeleteIntersiteL3outs(l3out) + if err != nil { + return err + } + log.Println("[DEBUG] Schema Site L3out: Beginning Destroy", d.Id()) + d.SetId("") + return err +} + +func L3outModelToL3outId(m *models.IntersiteL3outs) string { + return fmt.Sprintf("%s/site/%s/template/%s/vrf/%s/l3out/%s", m.SchemaID, m.SiteId, m.TemplateName, m.VRFName, m.L3outName) +} + +func L3outIdToL3outModel(id string) (*models.IntersiteL3outs, error) { + getAttributes := strings.Split(id, "/") + if len(getAttributes) != 9 || getAttributes[1] != "site" || getAttributes[3] != "template" || getAttributes[5] != "vrf" || getAttributes[7] != "l3out" { + return nil, fmt.Errorf("invalid mso_schema_site_l3out id format") + } + l3outMap := models.IntersiteL3outs{ + SchemaID: getAttributes[0], + SiteId: getAttributes[2], + TemplateName: getAttributes[4], + VRFName: getAttributes[6], + L3outName: getAttributes[8], + } + return &l3outMap, nil +} diff --git a/website/docs/d/schema_site_l3out.html.markdown b/website/docs/d/schema_site_l3out.html.markdown new file mode 100644 index 00000000..340ae304 --- /dev/null +++ b/website/docs/d/schema_site_l3out.html.markdown @@ -0,0 +1,34 @@ +--- +layout: "mso" +page_title: "MSO: mso_schema_site_l3out" +sidebar_current: "docs-mso-data-source-schema_site_l3out" +description: |- + Data source for MSO Schema Site L3out +--- + +# mso_schema_site_l3out # + +Data source for MSO schema site L3out, to fetch the MSO schema site L3out details. + +## Example Usage ## + +```hcl +data "mso_schema_site_l3out" "exmple" { + vrf_name = mso_schema_site_vrf.example.vrf_name + l3out_name = mso_schema_site_l3out.example.l3out_name + template_name = mso_site.example.template_name + site_id = mso_site.example.site_id + schema_id = mso_site.example.schema_id +} +``` + +## Argument Reference ## +* `schema_id` - (Required) The schema-id where L3out is added. +* `l3out_name` - (Required) Name of the added L3out. +* `template_name` - (Required) Template name associated with the L3out. +* `vrf_name` - (Required) VRF name associated with the L3out. +* `site_id` - (Required) SiteID associated with the L3out. + +## Attribute Reference ## + +No attributes are exported. \ No newline at end of file diff --git a/website/docs/r/schema_site_l3out.html.markdown b/website/docs/r/schema_site_l3out.html.markdown new file mode 100644 index 00000000..d874ec3a --- /dev/null +++ b/website/docs/r/schema_site_l3out.html.markdown @@ -0,0 +1,42 @@ +--- +layout: "mso" +page_title: "MSO: mso_schema_site_l3out" +sidebar_current: "docs-mso-resource-schema_site_l3out" +description: |- + Manages MSO Schema Site L3out +--- + +# mso_schema_site_l3out # + +Manages MSO Schema Site L3out. + +## Example Usage ## + +```hcl +resource "mso_schema_site_l3out" "example" { + vrf_name = mso_schema_site_vrf.example.vrf_name + l3out_name = "example" + template_name = mso_site.example.template_name + site_id = mso_site.example.site_id + schema_id = mso_site.example.schema_id +} + +``` + +## Argument Reference ## +* `schema_id` - (Required) The schema-id where user wants to add L3out. +* `l3out_name` - (Required) Name of the L3out that user wants to add. +* `template_name` - (Required) Template name associated with the L3out. +* `vrf_name` - (Required) VRF name associated with the L3out. +* `site_id` - (Required) SiteID associated with the L3out. + +## Attribute Reference ## +The only Attribute exposed for this resource is `id`. Which is set to the node name of Service Node created. + +## Importing ## + +An existing MSO Schema Site L3out can be [imported][docs-import] into this resource via its Id/path, via the following command: [docs-import]: + +```bash +terraform import mso_schema_site_l3out.example {schema_id}/site/{site_id}/template/{template_name}/vrf/{vrf_name}/l3out/{l3out_name} +``` \ No newline at end of file