From 20cb4cf05273f537a7b1421024c70dbfc7130b0d Mon Sep 17 00:00:00 2001 From: danischm Date: Mon, 21 Mar 2022 15:27:16 +0100 Subject: [PATCH] Add vrf and bridge domain resources --- CHANGELOG.md | 5 +- docs/data-sources/bridge_domain.md | 34 +++ docs/data-sources/vrf.md | 33 +++ docs/data-sources/vrf_container.md | 32 +++ docs/resources/bridge_domain.md | 50 +++++ docs/resources/vrf.md | 46 ++++ docs/resources/vrf_container.md | 41 ++++ .../nxos_bridge_domain/data-source.tf | 3 + examples/data-sources/nxos_vrf/data-source.tf | 3 + .../nxos_vrf_container/data-source.tf | 3 + .../resources/nxos_bridge_domain/import.sh | 1 + .../resources/nxos_bridge_domain/resource.tf | 5 + examples/resources/nxos_vrf/import.sh | 1 + examples/resources/nxos_vrf/resource.tf | 4 + .../resources/nxos_vrf_container/import.sh | 1 + .../resources/nxos_vrf_container/resource.tf | 3 + gen/definitions/bridge_domain.yaml | 27 +++ gen/definitions/vrf.yaml | 20 ++ gen/definitions/vrf_container.yaml | 15 ++ .../data_source_nxos_bridge_domain.go | 85 ++++++++ .../data_source_nxos_bridge_domain_test.go | 35 +++ internal/provider/data_source_nxos_vrf.go | 80 +++++++ .../data_source_nxos_vrf_container.go | 75 +++++++ .../data_source_nxos_vrf_container_test.go | 33 +++ .../provider/data_source_nxos_vrf_test.go | 34 +++ internal/provider/model_nxos_bridge_domain.go | 45 ++++ internal/provider/model_nxos_vrf.go | 42 ++++ internal/provider/model_nxos_vrf_container.go | 39 ++++ internal/provider/provider.go | 6 + .../provider/resource_nxos_bridge_domain.go | 199 ++++++++++++++++++ .../resource_nxos_bridge_domain_test.go | 55 +++++ internal/provider/resource_nxos_vrf.go | 190 +++++++++++++++++ .../provider/resource_nxos_vrf_container.go | 184 ++++++++++++++++ .../resource_nxos_vrf_container_test.go | 51 +++++ internal/provider/resource_nxos_vrf_test.go | 53 +++++ 35 files changed, 1532 insertions(+), 1 deletion(-) create mode 100644 docs/data-sources/bridge_domain.md create mode 100644 docs/data-sources/vrf.md create mode 100644 docs/data-sources/vrf_container.md create mode 100644 docs/resources/bridge_domain.md create mode 100644 docs/resources/vrf.md create mode 100644 docs/resources/vrf_container.md create mode 100644 examples/data-sources/nxos_bridge_domain/data-source.tf create mode 100644 examples/data-sources/nxos_vrf/data-source.tf create mode 100644 examples/data-sources/nxos_vrf_container/data-source.tf create mode 100644 examples/resources/nxos_bridge_domain/import.sh create mode 100644 examples/resources/nxos_bridge_domain/resource.tf create mode 100644 examples/resources/nxos_vrf/import.sh create mode 100644 examples/resources/nxos_vrf/resource.tf create mode 100644 examples/resources/nxos_vrf_container/import.sh create mode 100644 examples/resources/nxos_vrf_container/resource.tf create mode 100644 gen/definitions/bridge_domain.yaml create mode 100644 gen/definitions/vrf.yaml create mode 100644 gen/definitions/vrf_container.yaml create mode 100644 internal/provider/data_source_nxos_bridge_domain.go create mode 100644 internal/provider/data_source_nxos_bridge_domain_test.go create mode 100644 internal/provider/data_source_nxos_vrf.go create mode 100644 internal/provider/data_source_nxos_vrf_container.go create mode 100644 internal/provider/data_source_nxos_vrf_container_test.go create mode 100644 internal/provider/data_source_nxos_vrf_test.go create mode 100644 internal/provider/model_nxos_bridge_domain.go create mode 100644 internal/provider/model_nxos_vrf.go create mode 100644 internal/provider/model_nxos_vrf_container.go create mode 100644 internal/provider/resource_nxos_bridge_domain.go create mode 100644 internal/provider/resource_nxos_bridge_domain_test.go create mode 100644 internal/provider/resource_nxos_vrf.go create mode 100644 internal/provider/resource_nxos_vrf_container.go create mode 100644 internal/provider/resource_nxos_vrf_container_test.go create mode 100644 internal/provider/resource_nxos_vrf_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b5da8f6..b7e3dd4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,10 @@ -## 0.2.2 (unreleased) +## 0.2.2 - Add nxos_ipv4_interface resource and data source - Add nxos_ipv4_interface_address resource and data source +- Add nxos_vrf resource and data source +- Add nxos_vrf_container resource and data source +- Add nxos_bridge_domain resource and data source ## 0.2.1 diff --git a/docs/data-sources/bridge_domain.md b/docs/data-sources/bridge_domain.md new file mode 100644 index 00000000..096780c2 --- /dev/null +++ b/docs/data-sources/bridge_domain.md @@ -0,0 +1,34 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "nxos_bridge_domain Data Source - terraform-provider-nxos" +subcategory: "" +description: |- + This data source can read a bridge domain. +--- + +# nxos_bridge_domain (Data Source) + +This data source can read a bridge domain. + +## Example Usage + +```terraform +data "nxos_bridge_domain" "example" { + fabric_encap = "vlan-10" +} +``` + + +## Schema + +### Required + +- **fabric_encap** (String) Fabric encapsulation. Possible values are `unknown`, `vlan-XX` or `vxlan-XX`. + +### Read-Only + +- **access_encap** (String) Access encapsulation. Possible values are `unknown`, `vlan-XX` or `vxlan-XX`. +- **id** (String) The distinguished name of the object. +- **name** (String) Bridge domain name. + + diff --git a/docs/data-sources/vrf.md b/docs/data-sources/vrf.md new file mode 100644 index 00000000..8ecaf939 --- /dev/null +++ b/docs/data-sources/vrf.md @@ -0,0 +1,33 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "nxos_vrf Data Source - terraform-provider-nxos" +subcategory: "" +description: |- + This data source can read a VRF. +--- + +# nxos_vrf (Data Source) + +This data source can read a VRF. + +## Example Usage + +```terraform +data "nxos_vrf" "example" { + name = "VRF1" +} +``` + + +## Schema + +### Required + +- **name** (String) VRF name. + +### Read-Only + +- **description** (String) VRF description. +- **id** (String) The distinguished name of the object. + + diff --git a/docs/data-sources/vrf_container.md b/docs/data-sources/vrf_container.md new file mode 100644 index 00000000..ebffcb34 --- /dev/null +++ b/docs/data-sources/vrf_container.md @@ -0,0 +1,32 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "nxos_vrf_container Data Source - terraform-provider-nxos" +subcategory: "" +description: |- + This data source can read a VRF container. +--- + +# nxos_vrf_container (Data Source) + +This data source can read a VRF container. + +## Example Usage + +```terraform +data "nxos_vrf_container" "example" { + name = "VRF1" +} +``` + + +## Schema + +### Required + +- **name** (String) VRF name. + +### Read-Only + +- **id** (String) The distinguished name of the object. + + diff --git a/docs/resources/bridge_domain.md b/docs/resources/bridge_domain.md new file mode 100644 index 00000000..d327c33e --- /dev/null +++ b/docs/resources/bridge_domain.md @@ -0,0 +1,50 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "nxos_bridge_domain Resource - terraform-provider-nxos" +subcategory: "" +description: |- + This resource can manage a bridge domain. + API Documentation: ipv4If https://pubhub.devnetcloud.com/media/dme-docs-10-2-2/docs/System/l2:BD/ +--- + +# nxos_bridge_domain (Resource) + +This resource can manage a bridge domain. + +- API Documentation: [ipv4If](https://pubhub.devnetcloud.com/media/dme-docs-10-2-2/docs/System/l2:BD/) + +## Example Usage + +```terraform +resource "nxos_bridge_domain" "example" { + fabric_encap = "vlan-10" + access_encap = "unknown" + name = "VLAN10" +} +``` + + +## Schema + +### Required + +- **fabric_encap** (String) Fabric encapsulation. Possible values are `unknown`, `vlan-XX` or `vxlan-XX`. + - Default value: `unknown` + +### Optional + +- **access_encap** (String) Access encapsulation. Possible values are `unknown`, `vlan-XX` or `vxlan-XX`. + - Default value: `unknown` +- **name** (String) Bridge domain name. + +### Read-Only + +- **id** (String) The distinguished name of the object. + +## Import + +Import is supported using the following syntax: + +```shell +terraform import nxos_bridge_domain.example "sys/bd/bd-[vlan-10]" +``` diff --git a/docs/resources/vrf.md b/docs/resources/vrf.md new file mode 100644 index 00000000..5d2758c2 --- /dev/null +++ b/docs/resources/vrf.md @@ -0,0 +1,46 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "nxos_vrf Resource - terraform-provider-nxos" +subcategory: "" +description: |- + This resource can manage a VRF. + API Documentation: ipv4If https://pubhub.devnetcloud.com/media/dme-docs-10-2-2/docs/System/l3:Inst/ +--- + +# nxos_vrf (Resource) + +This resource can manage a VRF. + +- API Documentation: [ipv4If](https://pubhub.devnetcloud.com/media/dme-docs-10-2-2/docs/System/l3:Inst/) + +## Example Usage + +```terraform +resource "nxos_vrf" "example" { + name = "VRF1" + description = "My VRF1 Description" +} +``` + + +## Schema + +### Required + +- **name** (String) VRF name. + +### Optional + +- **description** (String) VRF description. + +### Read-Only + +- **id** (String) The distinguished name of the object. + +## Import + +Import is supported using the following syntax: + +```shell +terraform import nxos_vrf.example "sys/inst-[VRF1]" +``` diff --git a/docs/resources/vrf_container.md b/docs/resources/vrf_container.md new file mode 100644 index 00000000..cfb18162 --- /dev/null +++ b/docs/resources/vrf_container.md @@ -0,0 +1,41 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "nxos_vrf_container Resource - terraform-provider-nxos" +subcategory: "" +description: |- + This resource can manage a VRF container. + API Documentation: ipv4If https://pubhub.devnetcloud.com/media/dme-docs-10-2-2/docs/System/l3:Inst/ +--- + +# nxos_vrf_container (Resource) + +This resource can manage a VRF container. + +- API Documentation: [ipv4If](https://pubhub.devnetcloud.com/media/dme-docs-10-2-2/docs/System/l3:Inst/) + +## Example Usage + +```terraform +resource "nxos_vrf_container" "example" { + name = "VRF1" +} +``` + + +## Schema + +### Required + +- **name** (String) VRF name. + +### Read-Only + +- **id** (String) The distinguished name of the object. + +## Import + +Import is supported using the following syntax: + +```shell +terraform import nxos_vrf_container.example "sys/ipv4/inst/dom-[VRF1]" +``` diff --git a/examples/data-sources/nxos_bridge_domain/data-source.tf b/examples/data-sources/nxos_bridge_domain/data-source.tf new file mode 100644 index 00000000..05fa2deb --- /dev/null +++ b/examples/data-sources/nxos_bridge_domain/data-source.tf @@ -0,0 +1,3 @@ +data "nxos_bridge_domain" "example" { + fabric_encap = "vlan-10" +} diff --git a/examples/data-sources/nxos_vrf/data-source.tf b/examples/data-sources/nxos_vrf/data-source.tf new file mode 100644 index 00000000..dc4bdd04 --- /dev/null +++ b/examples/data-sources/nxos_vrf/data-source.tf @@ -0,0 +1,3 @@ +data "nxos_vrf" "example" { + name = "VRF1" +} diff --git a/examples/data-sources/nxos_vrf_container/data-source.tf b/examples/data-sources/nxos_vrf_container/data-source.tf new file mode 100644 index 00000000..2f03c4b5 --- /dev/null +++ b/examples/data-sources/nxos_vrf_container/data-source.tf @@ -0,0 +1,3 @@ +data "nxos_vrf_container" "example" { + name = "VRF1" +} diff --git a/examples/resources/nxos_bridge_domain/import.sh b/examples/resources/nxos_bridge_domain/import.sh new file mode 100644 index 00000000..745063e3 --- /dev/null +++ b/examples/resources/nxos_bridge_domain/import.sh @@ -0,0 +1 @@ +terraform import nxos_bridge_domain.example "sys/bd/bd-[vlan-10]" diff --git a/examples/resources/nxos_bridge_domain/resource.tf b/examples/resources/nxos_bridge_domain/resource.tf new file mode 100644 index 00000000..d0d6cdde --- /dev/null +++ b/examples/resources/nxos_bridge_domain/resource.tf @@ -0,0 +1,5 @@ +resource "nxos_bridge_domain" "example" { + fabric_encap = "vlan-10" + access_encap = "unknown" + name = "VLAN10" +} diff --git a/examples/resources/nxos_vrf/import.sh b/examples/resources/nxos_vrf/import.sh new file mode 100644 index 00000000..9727d738 --- /dev/null +++ b/examples/resources/nxos_vrf/import.sh @@ -0,0 +1 @@ +terraform import nxos_vrf.example "sys/inst-[VRF1]" diff --git a/examples/resources/nxos_vrf/resource.tf b/examples/resources/nxos_vrf/resource.tf new file mode 100644 index 00000000..5fce88f4 --- /dev/null +++ b/examples/resources/nxos_vrf/resource.tf @@ -0,0 +1,4 @@ +resource "nxos_vrf" "example" { + name = "VRF1" + description = "My VRF1 Description" +} diff --git a/examples/resources/nxos_vrf_container/import.sh b/examples/resources/nxos_vrf_container/import.sh new file mode 100644 index 00000000..383a257f --- /dev/null +++ b/examples/resources/nxos_vrf_container/import.sh @@ -0,0 +1 @@ +terraform import nxos_vrf_container.example "sys/ipv4/inst/dom-[VRF1]" diff --git a/examples/resources/nxos_vrf_container/resource.tf b/examples/resources/nxos_vrf_container/resource.tf new file mode 100644 index 00000000..a3a0378d --- /dev/null +++ b/examples/resources/nxos_vrf_container/resource.tf @@ -0,0 +1,3 @@ +resource "nxos_vrf_container" "example" { + name = "VRF1" +} diff --git a/gen/definitions/bridge_domain.yaml b/gen/definitions/bridge_domain.yaml new file mode 100644 index 00000000..1b3e560e --- /dev/null +++ b/gen/definitions/bridge_domain.yaml @@ -0,0 +1,27 @@ +--- +name: Bridge Domain +class_name: l2BD +dn: sys/bd/bd-[%s] +ds_description: |- + This data source can read a bridge domain. +res_description: |- + This resource can manage a bridge domain.\n\n- API Documentation: [ipv4If](https://pubhub.devnetcloud.com/media/dme-docs-10-2-2/docs/System/l2:BD/) +attributes: + - nxos_name: fabEncap + tf_name: fabric_encap + type: String + id: true + description: 'Fabric encapsulation. Possible values are `unknown`, `vlan-XX` or `vxlan-XX`.' + default_value: unknown + example: vlan-10 + - nxos_name: accEncap + tf_name: access_encap + type: String + description: 'Access encapsulation. Possible values are `unknown`, `vlan-XX` or `vxlan-XX`.' + default_value: unknown + example: unknown + - nxos_name: name + tf_name: name + type: String + description: 'Bridge domain name.' + example: VLAN10 diff --git a/gen/definitions/vrf.yaml b/gen/definitions/vrf.yaml new file mode 100644 index 00000000..b147d374 --- /dev/null +++ b/gen/definitions/vrf.yaml @@ -0,0 +1,20 @@ +--- +name: VRF +class_name: l3Inst +dn: sys/inst-[%s] +ds_description: |- + This data source can read a VRF. +res_description: |- + This resource can manage a VRF.\n\n- API Documentation: [ipv4If](https://pubhub.devnetcloud.com/media/dme-docs-10-2-2/docs/System/l3:Inst/) +attributes: + - nxos_name: name + tf_name: name + type: String + id: true + description: 'VRF name.' + example: 'VRF1' + - nxos_name: descr + tf_name: description + type: String + description: 'VRF description.' + example: My VRF1 Description diff --git a/gen/definitions/vrf_container.yaml b/gen/definitions/vrf_container.yaml new file mode 100644 index 00000000..e1d005dd --- /dev/null +++ b/gen/definitions/vrf_container.yaml @@ -0,0 +1,15 @@ +--- +name: VRF Container +class_name: ipv4Dom +dn: sys/ipv4/inst/dom-[%s] +ds_description: |- + This data source can read a VRF container. +res_description: |- + This resource can manage a VRF container.\n\n- API Documentation: [ipv4If](https://pubhub.devnetcloud.com/media/dme-docs-10-2-2/docs/System/l3:Inst/) +attributes: + - nxos_name: name + tf_name: name + type: String + id: true + description: 'VRF name.' + example: 'VRF1' diff --git a/internal/provider/data_source_nxos_bridge_domain.go b/internal/provider/data_source_nxos_bridge_domain.go new file mode 100644 index 00000000..a5382c14 --- /dev/null +++ b/internal/provider/data_source_nxos_bridge_domain.go @@ -0,0 +1,85 @@ +// Code generated by "gen/generator.go"; DO NOT EDIT. + +package provider + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-log/tflog" +) + +type dataSourceBridgeDomainType struct{} + +func (t dataSourceBridgeDomainType) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) { + return tfsdk.Schema{ + // This description is used by the documentation generator and the language server. + MarkdownDescription: "This data source can read a bridge domain.", + + Attributes: map[string]tfsdk.Attribute{ + "id": { + MarkdownDescription: "The distinguished name of the object.", + Type: types.StringType, + Computed: true, + }, + "fabric_encap": { + MarkdownDescription: "Fabric encapsulation. Possible values are `unknown`, `vlan-XX` or `vxlan-XX`.", + Type: types.StringType, + Required: true, + }, + "access_encap": { + MarkdownDescription: "Access encapsulation. Possible values are `unknown`, `vlan-XX` or `vxlan-XX`.", + Type: types.StringType, + Computed: true, + }, + "name": { + MarkdownDescription: "Bridge domain name.", + Type: types.StringType, + Computed: true, + }, + }, + }, nil +} + +func (t dataSourceBridgeDomainType) NewDataSource(ctx context.Context, in tfsdk.Provider) (tfsdk.DataSource, diag.Diagnostics) { + provider, diags := convertProviderType(in) + + return dataSourceBridgeDomain{ + provider: provider, + }, diags +} + +type dataSourceBridgeDomain struct { + provider provider +} + +func (d dataSourceBridgeDomain) Read(ctx context.Context, req tfsdk.ReadDataSourceRequest, resp *tfsdk.ReadDataSourceResponse) { + var config, state BridgeDomain + + // Read config + diags := req.Config.Get(ctx, &config) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Read", config.getDn())) + + res, err := d.provider.client.GetDn(config.getDn()) + + if err != nil { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve object, got error: %s", err)) + return + } + + state.fromBody(res) + state.fromPlan(config) + + tflog.Debug(ctx, fmt.Sprintf("%s: Read finished successfully", config.getDn())) + + diags = resp.State.Set(ctx, &state) + resp.Diagnostics.Append(diags...) +} diff --git a/internal/provider/data_source_nxos_bridge_domain_test.go b/internal/provider/data_source_nxos_bridge_domain_test.go new file mode 100644 index 00000000..340254bf --- /dev/null +++ b/internal/provider/data_source_nxos_bridge_domain_test.go @@ -0,0 +1,35 @@ +// Code generated by "gen/generator.go"; DO NOT EDIT. + +package provider + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccDataSourceNxosBridgeDomain(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccNxosBridgeDomainConfig_all(), + }, + { + Config: testAccDataSourceNxosBridgeDomainConfig, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("data.nxos_bridge_domain.test", "fabric_encap", "vlan-10"), + resource.TestCheckResourceAttr("data.nxos_bridge_domain.test", "access_encap", "unknown"), + resource.TestCheckResourceAttr("data.nxos_bridge_domain.test", "name", "VLAN10"), + ), + }, + }, + }) +} + +const testAccDataSourceNxosBridgeDomainConfig = ` +data "nxos_bridge_domain" "test" { + fabric_encap = "vlan-10" +} +` diff --git a/internal/provider/data_source_nxos_vrf.go b/internal/provider/data_source_nxos_vrf.go new file mode 100644 index 00000000..1d757212 --- /dev/null +++ b/internal/provider/data_source_nxos_vrf.go @@ -0,0 +1,80 @@ +// Code generated by "gen/generator.go"; DO NOT EDIT. + +package provider + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-log/tflog" +) + +type dataSourceVRFType struct{} + +func (t dataSourceVRFType) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) { + return tfsdk.Schema{ + // This description is used by the documentation generator and the language server. + MarkdownDescription: "This data source can read a VRF.", + + Attributes: map[string]tfsdk.Attribute{ + "id": { + MarkdownDescription: "The distinguished name of the object.", + Type: types.StringType, + Computed: true, + }, + "name": { + MarkdownDescription: "VRF name.", + Type: types.StringType, + Required: true, + }, + "description": { + MarkdownDescription: "VRF description.", + Type: types.StringType, + Computed: true, + }, + }, + }, nil +} + +func (t dataSourceVRFType) NewDataSource(ctx context.Context, in tfsdk.Provider) (tfsdk.DataSource, diag.Diagnostics) { + provider, diags := convertProviderType(in) + + return dataSourceVRF{ + provider: provider, + }, diags +} + +type dataSourceVRF struct { + provider provider +} + +func (d dataSourceVRF) Read(ctx context.Context, req tfsdk.ReadDataSourceRequest, resp *tfsdk.ReadDataSourceResponse) { + var config, state VRF + + // Read config + diags := req.Config.Get(ctx, &config) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Read", config.getDn())) + + res, err := d.provider.client.GetDn(config.getDn()) + + if err != nil { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve object, got error: %s", err)) + return + } + + state.fromBody(res) + state.fromPlan(config) + + tflog.Debug(ctx, fmt.Sprintf("%s: Read finished successfully", config.getDn())) + + diags = resp.State.Set(ctx, &state) + resp.Diagnostics.Append(diags...) +} diff --git a/internal/provider/data_source_nxos_vrf_container.go b/internal/provider/data_source_nxos_vrf_container.go new file mode 100644 index 00000000..dcf9827e --- /dev/null +++ b/internal/provider/data_source_nxos_vrf_container.go @@ -0,0 +1,75 @@ +// Code generated by "gen/generator.go"; DO NOT EDIT. + +package provider + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-log/tflog" +) + +type dataSourceVRFContainerType struct{} + +func (t dataSourceVRFContainerType) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) { + return tfsdk.Schema{ + // This description is used by the documentation generator and the language server. + MarkdownDescription: "This data source can read a VRF container.", + + Attributes: map[string]tfsdk.Attribute{ + "id": { + MarkdownDescription: "The distinguished name of the object.", + Type: types.StringType, + Computed: true, + }, + "name": { + MarkdownDescription: "VRF name.", + Type: types.StringType, + Required: true, + }, + }, + }, nil +} + +func (t dataSourceVRFContainerType) NewDataSource(ctx context.Context, in tfsdk.Provider) (tfsdk.DataSource, diag.Diagnostics) { + provider, diags := convertProviderType(in) + + return dataSourceVRFContainer{ + provider: provider, + }, diags +} + +type dataSourceVRFContainer struct { + provider provider +} + +func (d dataSourceVRFContainer) Read(ctx context.Context, req tfsdk.ReadDataSourceRequest, resp *tfsdk.ReadDataSourceResponse) { + var config, state VRFContainer + + // Read config + diags := req.Config.Get(ctx, &config) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Read", config.getDn())) + + res, err := d.provider.client.GetDn(config.getDn()) + + if err != nil { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve object, got error: %s", err)) + return + } + + state.fromBody(res) + state.fromPlan(config) + + tflog.Debug(ctx, fmt.Sprintf("%s: Read finished successfully", config.getDn())) + + diags = resp.State.Set(ctx, &state) + resp.Diagnostics.Append(diags...) +} diff --git a/internal/provider/data_source_nxos_vrf_container_test.go b/internal/provider/data_source_nxos_vrf_container_test.go new file mode 100644 index 00000000..c07f2231 --- /dev/null +++ b/internal/provider/data_source_nxos_vrf_container_test.go @@ -0,0 +1,33 @@ +// Code generated by "gen/generator.go"; DO NOT EDIT. + +package provider + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccDataSourceNxosVRFContainer(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccNxosVRFContainerConfig_all(), + }, + { + Config: testAccDataSourceNxosVRFContainerConfig, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("data.nxos_vrf_container.test", "name", "VRF1"), + ), + }, + }, + }) +} + +const testAccDataSourceNxosVRFContainerConfig = ` +data "nxos_vrf_container" "test" { + name = "VRF1" +} +` diff --git a/internal/provider/data_source_nxos_vrf_test.go b/internal/provider/data_source_nxos_vrf_test.go new file mode 100644 index 00000000..067847a8 --- /dev/null +++ b/internal/provider/data_source_nxos_vrf_test.go @@ -0,0 +1,34 @@ +// Code generated by "gen/generator.go"; DO NOT EDIT. + +package provider + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccDataSourceNxosVRF(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccNxosVRFConfig_all(), + }, + { + Config: testAccDataSourceNxosVRFConfig, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("data.nxos_vrf.test", "name", "VRF1"), + resource.TestCheckResourceAttr("data.nxos_vrf.test", "description", "My VRF1 Description"), + ), + }, + }, + }) +} + +const testAccDataSourceNxosVRFConfig = ` +data "nxos_vrf" "test" { + name = "VRF1" +} +` diff --git a/internal/provider/model_nxos_bridge_domain.go b/internal/provider/model_nxos_bridge_domain.go new file mode 100644 index 00000000..4abfbc19 --- /dev/null +++ b/internal/provider/model_nxos_bridge_domain.go @@ -0,0 +1,45 @@ +// Code generated by "gen/generator.go"; DO NOT EDIT. + +package provider + +import ( + "fmt" + + + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/netascode/go-nxos" + "github.com/tidwall/gjson" +) + +type BridgeDomain struct { + Dn types.String `tfsdk:"id"` + FabEncap types.String `tfsdk:"fabric_encap"` + AccEncap types.String `tfsdk:"access_encap"` + Name types.String `tfsdk:"name"` +} + +func (data BridgeDomain) getDn() string { + return fmt.Sprintf("sys/bd/bd-[%s]", data.FabEncap.Value) +} + +func (data BridgeDomain) getClassName() string { + return "l2BD" +} + +func (data BridgeDomain) toBody() nxos.Body { + attrs := nxos.Body{}. + Set("fabEncap", data.FabEncap.Value). + Set("accEncap", data.AccEncap.Value). + Set("name", data.Name.Value) + return nxos.Body{}.SetRaw(data.getClassName()+".attributes", attrs.Str) +} + +func (data *BridgeDomain) fromBody(res gjson.Result) { + data.Dn.Value = res.Get("*.attributes.dn").String() + data.FabEncap.Value = res.Get("*.attributes.fabEncap").String() + data.AccEncap.Value = res.Get("*.attributes.accEncap").String() + data.Name.Value = res.Get("*.attributes.name").String() +} + +func (data *BridgeDomain) fromPlan(plan BridgeDomain) { +} diff --git a/internal/provider/model_nxos_vrf.go b/internal/provider/model_nxos_vrf.go new file mode 100644 index 00000000..2560c12b --- /dev/null +++ b/internal/provider/model_nxos_vrf.go @@ -0,0 +1,42 @@ +// Code generated by "gen/generator.go"; DO NOT EDIT. + +package provider + +import ( + "fmt" + + + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/netascode/go-nxos" + "github.com/tidwall/gjson" +) + +type VRF struct { + Dn types.String `tfsdk:"id"` + Name types.String `tfsdk:"name"` + Descr types.String `tfsdk:"description"` +} + +func (data VRF) getDn() string { + return fmt.Sprintf("sys/inst-[%s]", data.Name.Value) +} + +func (data VRF) getClassName() string { + return "l3Inst" +} + +func (data VRF) toBody() nxos.Body { + attrs := nxos.Body{}. + Set("name", data.Name.Value). + Set("descr", data.Descr.Value) + return nxos.Body{}.SetRaw(data.getClassName()+".attributes", attrs.Str) +} + +func (data *VRF) fromBody(res gjson.Result) { + data.Dn.Value = res.Get("*.attributes.dn").String() + data.Name.Value = res.Get("*.attributes.name").String() + data.Descr.Value = res.Get("*.attributes.descr").String() +} + +func (data *VRF) fromPlan(plan VRF) { +} diff --git a/internal/provider/model_nxos_vrf_container.go b/internal/provider/model_nxos_vrf_container.go new file mode 100644 index 00000000..5417bb64 --- /dev/null +++ b/internal/provider/model_nxos_vrf_container.go @@ -0,0 +1,39 @@ +// Code generated by "gen/generator.go"; DO NOT EDIT. + +package provider + +import ( + "fmt" + + + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/netascode/go-nxos" + "github.com/tidwall/gjson" +) + +type VRFContainer struct { + Dn types.String `tfsdk:"id"` + Name types.String `tfsdk:"name"` +} + +func (data VRFContainer) getDn() string { + return fmt.Sprintf("sys/ipv4/inst/dom-[%s]", data.Name.Value) +} + +func (data VRFContainer) getClassName() string { + return "ipv4Dom" +} + +func (data VRFContainer) toBody() nxos.Body { + attrs := nxos.Body{}. + Set("name", data.Name.Value) + return nxos.Body{}.SetRaw(data.getClassName()+".attributes", attrs.Str) +} + +func (data *VRFContainer) fromBody(res gjson.Result) { + data.Dn.Value = res.Get("*.attributes.dn").String() + data.Name.Value = res.Get("*.attributes.name").String() +} + +func (data *VRFContainer) fromPlan(plan VRFContainer) { +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 0ee414c3..8476165c 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -224,6 +224,9 @@ func (p *provider) GetResources(ctx context.Context) (map[string]tfsdk.ResourceT "nxos_physical_interface": resourcePhysicalInterfaceType{}, "nxos_ipv4_interface": resourceIPv4InterfaceType{}, "nxos_ipv4_interface_address": resourceIPv4InterfaceAddressType{}, + "nxos_vrf": resourceVRFType{}, + "nxos_vrf_container": resourceVRFContainerType{}, + "nxos_bridge_domain": resourceBridgeDomainType{}, }, nil } @@ -233,6 +236,9 @@ func (p *provider) GetDataSources(ctx context.Context) (map[string]tfsdk.DataSou "nxos_physical_interface": dataSourcePhysicalInterfaceType{}, "nxos_ipv4_interface": dataSourceIPv4InterfaceType{}, "nxos_ipv4_interface_address": dataSourceIPv4InterfaceAddressType{}, + "nxos_vrf": dataSourceVRFType{}, + "nxos_vrf_container": dataSourceVRFContainerType{}, + "nxos_bridge_domain": dataSourceBridgeDomainType{}, }, nil } diff --git a/internal/provider/resource_nxos_bridge_domain.go b/internal/provider/resource_nxos_bridge_domain.go new file mode 100644 index 00000000..5fa18a32 --- /dev/null +++ b/internal/provider/resource_nxos_bridge_domain.go @@ -0,0 +1,199 @@ +// Code generated by "gen/generator.go"; DO NOT EDIT. + +package provider + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-go/tftypes" + "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/netascode/go-nxos" + "github.com/netascode/terraform-provider-nxos/internal/provider/helpers" +) + +type resourceBridgeDomainType struct{} + +func (t resourceBridgeDomainType) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) { + return tfsdk.Schema{ + // This description is used by the documentation generator and the language server. + MarkdownDescription: "This resource can manage a bridge domain.\n\n- API Documentation: [ipv4If](https://pubhub.devnetcloud.com/media/dme-docs-10-2-2/docs/System/l2:BD/)", + + Attributes: map[string]tfsdk.Attribute{ + "id": { + MarkdownDescription: "The distinguished name of the object.", + Type: types.StringType, + Computed: true, + PlanModifiers: tfsdk.AttributePlanModifiers{ + tfsdk.UseStateForUnknown(), + }, + }, + "fabric_encap": { + MarkdownDescription: helpers.NewDescription("Fabric encapsulation. Possible values are `unknown`, `vlan-XX` or `vxlan-XX`.").AddDefaultValueDescription("unknown").String, + Type: types.StringType, + Required: true, + PlanModifiers: tfsdk.AttributePlanModifiers{ + tfsdk.RequiresReplace(), + }, + }, + "access_encap": { + MarkdownDescription: helpers.NewDescription("Access encapsulation. Possible values are `unknown`, `vlan-XX` or `vxlan-XX`.").AddDefaultValueDescription("unknown").String, + Type: types.StringType, + Optional: true, + Computed: true, + PlanModifiers: tfsdk.AttributePlanModifiers{ + helpers.StringDefaultModifier("unknown"), + }, + }, + "name": { + MarkdownDescription: helpers.NewDescription("Bridge domain name.").String, + Type: types.StringType, + Optional: true, + Computed: true, + }, + }, + }, nil +} + +func (t resourceBridgeDomainType) NewResource(ctx context.Context, in tfsdk.Provider) (tfsdk.Resource, diag.Diagnostics) { + provider, diags := convertProviderType(in) + + return resourceBridgeDomain{ + provider: provider, + }, diags +} + +type resourceBridgeDomain struct { + provider provider +} + +func (r resourceBridgeDomain) Create(ctx context.Context, req tfsdk.CreateResourceRequest, resp *tfsdk.CreateResourceResponse) { + var plan, state BridgeDomain + + // Read plan + diags := req.Plan.Get(ctx, &plan) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Create", plan.getDn())) + + // Post object + body := plan.toBody() + _, err := r.provider.client.Post(plan.getDn(), body.Str) + if err != nil { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to post object, got error: %s", err)) + return + } + + // Read object + res, err := r.provider.client.GetDn(plan.getDn(), nxos.Query("rsp-prop-include", "config-only")) + if err != nil { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve object, got error: %s", err)) + return + } + + state.fromBody(res) + state.fromPlan(plan) + + tflog.Debug(ctx, fmt.Sprintf("%s: Create finished successfully", plan.getDn())) + + diags = resp.State.Set(ctx, &state) + resp.Diagnostics.Append(diags...) +} + +func (r resourceBridgeDomain) Read(ctx context.Context, req tfsdk.ReadResourceRequest, resp *tfsdk.ReadResourceResponse) { + var state BridgeDomain + + // Read state + diags := req.State.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Read", state.Dn.Value)) + + res, err := r.provider.client.GetDn(state.Dn.Value, nxos.Query("rsp-prop-include", "config-only")) + if err != nil { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve object, got error: %s", err)) + return + } + + state.fromBody(res) + + tflog.Debug(ctx, fmt.Sprintf("%s: Read finished successfully", state.Dn.Value)) + + diags = resp.State.Set(ctx, &state) + resp.Diagnostics.Append(diags...) +} + +func (r resourceBridgeDomain) Update(ctx context.Context, req tfsdk.UpdateResourceRequest, resp *tfsdk.UpdateResourceResponse) { + var plan, state BridgeDomain + + // Read plan + diags := req.Plan.Get(ctx, &plan) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Update", plan.getDn())) + + body := plan.toBody() + _, err := r.provider.client.Post(plan.getDn(), body.Str) + if err != nil { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to update object, got error: %s", err)) + return + } + + // Read object + res, err := r.provider.client.GetDn(plan.getDn(), nxos.Query("rsp-prop-include", "config-only")) + if err != nil { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve object, got error: %s", err)) + return + } + + state.fromBody(res) + state.fromPlan(plan) + + tflog.Debug(ctx, fmt.Sprintf("%s: Update finished successfully", plan.getDn())) + + diags = resp.State.Set(ctx, &state) + resp.Diagnostics.Append(diags...) +} + +func (r resourceBridgeDomain) Delete(ctx context.Context, req tfsdk.DeleteResourceRequest, resp *tfsdk.DeleteResourceResponse) { + var state BridgeDomain + + // Read state + diags := req.State.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Delete", state.Dn.Value)) + + res, err := r.provider.client.DeleteDn(state.Dn.Value) + if err != nil { + errCode := res.Get("imdata.0.error.attributes.code").Str + // Ignore errors of type "Cannot delete object" + if errCode != "107" { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to update object, got error: %s", err)) + return + } + } + + tflog.Debug(ctx, fmt.Sprintf("%s: Delete finished successfully", state.Dn.Value)) + + resp.State.RemoveResource(ctx) +} + +func (r resourceBridgeDomain) ImportState(ctx context.Context, req tfsdk.ImportResourceStateRequest, resp *tfsdk.ImportResourceStateResponse) { + tfsdk.ResourceImportStatePassthroughID(ctx, tftypes.NewAttributePath().WithAttributeName("id"), req, resp) +} diff --git a/internal/provider/resource_nxos_bridge_domain_test.go b/internal/provider/resource_nxos_bridge_domain_test.go new file mode 100644 index 00000000..a15ca207 --- /dev/null +++ b/internal/provider/resource_nxos_bridge_domain_test.go @@ -0,0 +1,55 @@ +// Code generated by "gen/generator.go"; DO NOT EDIT. + +package provider + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccNxosBridgeDomain(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config:testAccNxosBridgeDomainConfig_minimum(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("nxos_bridge_domain.test", "fabric_encap", "vlan-10"), + ), + }, + { + Config:testAccNxosBridgeDomainConfig_all(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("nxos_bridge_domain.test", "fabric_encap", "vlan-10"), + resource.TestCheckResourceAttr("nxos_bridge_domain.test", "access_encap", "unknown"), + resource.TestCheckResourceAttr("nxos_bridge_domain.test", "name", "VLAN10"), + ), + }, + { + ResourceName: "nxos_bridge_domain.test", + ImportState: true, + ImportStateId: "sys/bd/bd-[vlan-10]", + }, + }, + }) +} + +func testAccNxosBridgeDomainConfig_minimum() string { + return ` + resource "nxos_bridge_domain" "test" { + fabric_encap = "vlan-10" + } + ` +} + +func testAccNxosBridgeDomainConfig_all() string { + return ` + resource "nxos_bridge_domain" "test" { + fabric_encap = "vlan-10" + access_encap = "unknown" + name = "VLAN10" + } + ` +} diff --git a/internal/provider/resource_nxos_vrf.go b/internal/provider/resource_nxos_vrf.go new file mode 100644 index 00000000..2b031e54 --- /dev/null +++ b/internal/provider/resource_nxos_vrf.go @@ -0,0 +1,190 @@ +// Code generated by "gen/generator.go"; DO NOT EDIT. + +package provider + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-go/tftypes" + "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/netascode/go-nxos" + "github.com/netascode/terraform-provider-nxos/internal/provider/helpers" +) + +type resourceVRFType struct{} + +func (t resourceVRFType) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) { + return tfsdk.Schema{ + // This description is used by the documentation generator and the language server. + MarkdownDescription: "This resource can manage a VRF.\n\n- API Documentation: [ipv4If](https://pubhub.devnetcloud.com/media/dme-docs-10-2-2/docs/System/l3:Inst/)", + + Attributes: map[string]tfsdk.Attribute{ + "id": { + MarkdownDescription: "The distinguished name of the object.", + Type: types.StringType, + Computed: true, + PlanModifiers: tfsdk.AttributePlanModifiers{ + tfsdk.UseStateForUnknown(), + }, + }, + "name": { + MarkdownDescription: helpers.NewDescription("VRF name.").String, + Type: types.StringType, + Required: true, + PlanModifiers: tfsdk.AttributePlanModifiers{ + tfsdk.RequiresReplace(), + }, + }, + "description": { + MarkdownDescription: helpers.NewDescription("VRF description.").String, + Type: types.StringType, + Optional: true, + Computed: true, + }, + }, + }, nil +} + +func (t resourceVRFType) NewResource(ctx context.Context, in tfsdk.Provider) (tfsdk.Resource, diag.Diagnostics) { + provider, diags := convertProviderType(in) + + return resourceVRF{ + provider: provider, + }, diags +} + +type resourceVRF struct { + provider provider +} + +func (r resourceVRF) Create(ctx context.Context, req tfsdk.CreateResourceRequest, resp *tfsdk.CreateResourceResponse) { + var plan, state VRF + + // Read plan + diags := req.Plan.Get(ctx, &plan) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Create", plan.getDn())) + + // Post object + body := plan.toBody() + _, err := r.provider.client.Post(plan.getDn(), body.Str) + if err != nil { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to post object, got error: %s", err)) + return + } + + // Read object + res, err := r.provider.client.GetDn(plan.getDn(), nxos.Query("rsp-prop-include", "config-only")) + if err != nil { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve object, got error: %s", err)) + return + } + + state.fromBody(res) + state.fromPlan(plan) + + tflog.Debug(ctx, fmt.Sprintf("%s: Create finished successfully", plan.getDn())) + + diags = resp.State.Set(ctx, &state) + resp.Diagnostics.Append(diags...) +} + +func (r resourceVRF) Read(ctx context.Context, req tfsdk.ReadResourceRequest, resp *tfsdk.ReadResourceResponse) { + var state VRF + + // Read state + diags := req.State.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Read", state.Dn.Value)) + + res, err := r.provider.client.GetDn(state.Dn.Value, nxos.Query("rsp-prop-include", "config-only")) + if err != nil { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve object, got error: %s", err)) + return + } + + state.fromBody(res) + + tflog.Debug(ctx, fmt.Sprintf("%s: Read finished successfully", state.Dn.Value)) + + diags = resp.State.Set(ctx, &state) + resp.Diagnostics.Append(diags...) +} + +func (r resourceVRF) Update(ctx context.Context, req tfsdk.UpdateResourceRequest, resp *tfsdk.UpdateResourceResponse) { + var plan, state VRF + + // Read plan + diags := req.Plan.Get(ctx, &plan) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Update", plan.getDn())) + + body := plan.toBody() + _, err := r.provider.client.Post(plan.getDn(), body.Str) + if err != nil { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to update object, got error: %s", err)) + return + } + + // Read object + res, err := r.provider.client.GetDn(plan.getDn(), nxos.Query("rsp-prop-include", "config-only")) + if err != nil { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve object, got error: %s", err)) + return + } + + state.fromBody(res) + state.fromPlan(plan) + + tflog.Debug(ctx, fmt.Sprintf("%s: Update finished successfully", plan.getDn())) + + diags = resp.State.Set(ctx, &state) + resp.Diagnostics.Append(diags...) +} + +func (r resourceVRF) Delete(ctx context.Context, req tfsdk.DeleteResourceRequest, resp *tfsdk.DeleteResourceResponse) { + var state VRF + + // Read state + diags := req.State.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Delete", state.Dn.Value)) + + res, err := r.provider.client.DeleteDn(state.Dn.Value) + if err != nil { + errCode := res.Get("imdata.0.error.attributes.code").Str + // Ignore errors of type "Cannot delete object" + if errCode != "107" { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to update object, got error: %s", err)) + return + } + } + + tflog.Debug(ctx, fmt.Sprintf("%s: Delete finished successfully", state.Dn.Value)) + + resp.State.RemoveResource(ctx) +} + +func (r resourceVRF) ImportState(ctx context.Context, req tfsdk.ImportResourceStateRequest, resp *tfsdk.ImportResourceStateResponse) { + tfsdk.ResourceImportStatePassthroughID(ctx, tftypes.NewAttributePath().WithAttributeName("id"), req, resp) +} diff --git a/internal/provider/resource_nxos_vrf_container.go b/internal/provider/resource_nxos_vrf_container.go new file mode 100644 index 00000000..b2c655c0 --- /dev/null +++ b/internal/provider/resource_nxos_vrf_container.go @@ -0,0 +1,184 @@ +// Code generated by "gen/generator.go"; DO NOT EDIT. + +package provider + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-go/tftypes" + "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/netascode/go-nxos" + "github.com/netascode/terraform-provider-nxos/internal/provider/helpers" +) + +type resourceVRFContainerType struct{} + +func (t resourceVRFContainerType) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) { + return tfsdk.Schema{ + // This description is used by the documentation generator and the language server. + MarkdownDescription: "This resource can manage a VRF container.\n\n- API Documentation: [ipv4If](https://pubhub.devnetcloud.com/media/dme-docs-10-2-2/docs/System/l3:Inst/)", + + Attributes: map[string]tfsdk.Attribute{ + "id": { + MarkdownDescription: "The distinguished name of the object.", + Type: types.StringType, + Computed: true, + PlanModifiers: tfsdk.AttributePlanModifiers{ + tfsdk.UseStateForUnknown(), + }, + }, + "name": { + MarkdownDescription: helpers.NewDescription("VRF name.").String, + Type: types.StringType, + Required: true, + PlanModifiers: tfsdk.AttributePlanModifiers{ + tfsdk.RequiresReplace(), + }, + }, + }, + }, nil +} + +func (t resourceVRFContainerType) NewResource(ctx context.Context, in tfsdk.Provider) (tfsdk.Resource, diag.Diagnostics) { + provider, diags := convertProviderType(in) + + return resourceVRFContainer{ + provider: provider, + }, diags +} + +type resourceVRFContainer struct { + provider provider +} + +func (r resourceVRFContainer) Create(ctx context.Context, req tfsdk.CreateResourceRequest, resp *tfsdk.CreateResourceResponse) { + var plan, state VRFContainer + + // Read plan + diags := req.Plan.Get(ctx, &plan) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Create", plan.getDn())) + + // Post object + body := plan.toBody() + _, err := r.provider.client.Post(plan.getDn(), body.Str) + if err != nil { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to post object, got error: %s", err)) + return + } + + // Read object + res, err := r.provider.client.GetDn(plan.getDn(), nxos.Query("rsp-prop-include", "config-only")) + if err != nil { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve object, got error: %s", err)) + return + } + + state.fromBody(res) + state.fromPlan(plan) + + tflog.Debug(ctx, fmt.Sprintf("%s: Create finished successfully", plan.getDn())) + + diags = resp.State.Set(ctx, &state) + resp.Diagnostics.Append(diags...) +} + +func (r resourceVRFContainer) Read(ctx context.Context, req tfsdk.ReadResourceRequest, resp *tfsdk.ReadResourceResponse) { + var state VRFContainer + + // Read state + diags := req.State.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Read", state.Dn.Value)) + + res, err := r.provider.client.GetDn(state.Dn.Value, nxos.Query("rsp-prop-include", "config-only")) + if err != nil { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve object, got error: %s", err)) + return + } + + state.fromBody(res) + + tflog.Debug(ctx, fmt.Sprintf("%s: Read finished successfully", state.Dn.Value)) + + diags = resp.State.Set(ctx, &state) + resp.Diagnostics.Append(diags...) +} + +func (r resourceVRFContainer) Update(ctx context.Context, req tfsdk.UpdateResourceRequest, resp *tfsdk.UpdateResourceResponse) { + var plan, state VRFContainer + + // Read plan + diags := req.Plan.Get(ctx, &plan) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Update", plan.getDn())) + + body := plan.toBody() + _, err := r.provider.client.Post(plan.getDn(), body.Str) + if err != nil { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to update object, got error: %s", err)) + return + } + + // Read object + res, err := r.provider.client.GetDn(plan.getDn(), nxos.Query("rsp-prop-include", "config-only")) + if err != nil { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve object, got error: %s", err)) + return + } + + state.fromBody(res) + state.fromPlan(plan) + + tflog.Debug(ctx, fmt.Sprintf("%s: Update finished successfully", plan.getDn())) + + diags = resp.State.Set(ctx, &state) + resp.Diagnostics.Append(diags...) +} + +func (r resourceVRFContainer) Delete(ctx context.Context, req tfsdk.DeleteResourceRequest, resp *tfsdk.DeleteResourceResponse) { + var state VRFContainer + + // Read state + diags := req.State.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Delete", state.Dn.Value)) + + res, err := r.provider.client.DeleteDn(state.Dn.Value) + if err != nil { + errCode := res.Get("imdata.0.error.attributes.code").Str + // Ignore errors of type "Cannot delete object" + if errCode != "107" { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to update object, got error: %s", err)) + return + } + } + + tflog.Debug(ctx, fmt.Sprintf("%s: Delete finished successfully", state.Dn.Value)) + + resp.State.RemoveResource(ctx) +} + +func (r resourceVRFContainer) ImportState(ctx context.Context, req tfsdk.ImportResourceStateRequest, resp *tfsdk.ImportResourceStateResponse) { + tfsdk.ResourceImportStatePassthroughID(ctx, tftypes.NewAttributePath().WithAttributeName("id"), req, resp) +} diff --git a/internal/provider/resource_nxos_vrf_container_test.go b/internal/provider/resource_nxos_vrf_container_test.go new file mode 100644 index 00000000..c58ba3bc --- /dev/null +++ b/internal/provider/resource_nxos_vrf_container_test.go @@ -0,0 +1,51 @@ +// Code generated by "gen/generator.go"; DO NOT EDIT. + +package provider + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccNxosVRFContainer(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config:testAccNxosVRFContainerConfig_minimum(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("nxos_vrf_container.test", "name", "VRF1"), + ), + }, + { + Config:testAccNxosVRFContainerConfig_all(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("nxos_vrf_container.test", "name", "VRF1"), + ), + }, + { + ResourceName: "nxos_vrf_container.test", + ImportState: true, + ImportStateId: "sys/ipv4/inst/dom-[VRF1]", + }, + }, + }) +} + +func testAccNxosVRFContainerConfig_minimum() string { + return ` + resource "nxos_vrf_container" "test" { + name = "VRF1" + } + ` +} + +func testAccNxosVRFContainerConfig_all() string { + return ` + resource "nxos_vrf_container" "test" { + name = "VRF1" + } + ` +} diff --git a/internal/provider/resource_nxos_vrf_test.go b/internal/provider/resource_nxos_vrf_test.go new file mode 100644 index 00000000..2e853b26 --- /dev/null +++ b/internal/provider/resource_nxos_vrf_test.go @@ -0,0 +1,53 @@ +// Code generated by "gen/generator.go"; DO NOT EDIT. + +package provider + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccNxosVRF(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config:testAccNxosVRFConfig_minimum(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("nxos_vrf.test", "name", "VRF1"), + ), + }, + { + Config:testAccNxosVRFConfig_all(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("nxos_vrf.test", "name", "VRF1"), + resource.TestCheckResourceAttr("nxos_vrf.test", "description", "My VRF1 Description"), + ), + }, + { + ResourceName: "nxos_vrf.test", + ImportState: true, + ImportStateId: "sys/inst-[VRF1]", + }, + }, + }) +} + +func testAccNxosVRFConfig_minimum() string { + return ` + resource "nxos_vrf" "test" { + name = "VRF1" + } + ` +} + +func testAccNxosVRFConfig_all() string { + return ` + resource "nxos_vrf" "test" { + name = "VRF1" + description = "My VRF1 Description" + } + ` +}