Skip to content

Modified fabric_site resource to use `/dna/intent/api/v1/sda/fabricSites #98

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

Merged
merged 1 commit into from
Jul 19, 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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,5 @@ log*.txt
.terraform.lock.hcl
# Transient Terraform backend lock
.terraform.tfstate.lock.info

.envrc
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## 0.1.10 (unreleased)

- BREAKING CHANGE: Modified `fabric_site` resource to use `/dna/intent/api/v1/sda/fabricSites` API endpoint, this resource now only works with Catalyst Center version 2.3.7.5+
- Fix issue with mandatory attributes in `transit_peer_network` resource, [link](https://github.com/CiscoDevNet/terraform-provider-catalystcenter/issues/92)
- BREAKING CHANGE: Fix `ip_pool` update if more than 25 pools are registered
- BREAKING CHANGE: Rename `radio_type_a_power_treshold_v1` attribute of `catalystcenter_wireless_rf_profile` resource to `radio_type_a_power_threshold_v1`
Expand Down
7 changes: 4 additions & 3 deletions docs/data-sources/fabric_site.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ This data source can read the Fabric Site.

```terraform
data "catalystcenter_fabric_site" "example" {
id = "Global/Site1"
id = "76d24097-41c4-4558-a4d0-a8c07ac08470"
}
```

Expand All @@ -24,8 +24,9 @@ data "catalystcenter_fabric_site" "example" {
### Optional

- `id` (String) The id of the object
- `site_name_hierarchy` (String) Existing site name hierarchy available at global level
- `site_id` (String) ID of the network hierarchy

### Read-Only

- `fabric_type` (String) Type of SD-Access Fabric
- `authentication_profile_name` (String) Authentication profile used for this fabric
- `pub_sub_enabled` (Boolean) Specifies whether this fabric site will use pub/sub for control nodes
1 change: 1 addition & 0 deletions docs/guides/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ description: |-

## 0.1.10 (unreleased)

- BREAKING CHANGE: Modified `fabric_site` resource to use `/dna/intent/api/v1/sda/fabricSites` API endpoint, this resource now only works with Catalyst Center version 2.3.7.5+
- Fix issue with mandatory attributes in `transit_peer_network` resource, [link](https://github.com/CiscoDevNet/terraform-provider-catalystcenter/issues/92)
- BREAKING CHANGE: Fix `ip_pool` update if more than 25 pools are registered
- BREAKING CHANGE: Rename `radio_type_a_power_treshold_v1` attribute of `catalystcenter_wireless_rf_profile` resource to `radio_type_a_power_threshold_v1`
Expand Down
22 changes: 10 additions & 12 deletions docs/resources/fabric_site.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,20 @@
page_title: "catalystcenter_fabric_site Resource - terraform-provider-catalystcenter"
subcategory: "SDA"
description: |-
This resource can manage a Fabric Site.
Manages Fabric Sites
---

# catalystcenter_fabric_site (Resource)

This resource can manage a Fabric Site.
Manages Fabric Sites

## Example Usage

```terraform
resource "catalystcenter_fabric_site" "example" {
site_name_hierarchy = "Global/Site1"
fabric_type = "FABRIC_SITE"
site_id = "8e6f7b3a-2b0b-4a7d-8b1c-0d4b1cd5e1b1"
authentication_profile_name = "No Authentication"
pub_sub_enabled = false
}
```

Expand All @@ -24,13 +25,10 @@ resource "catalystcenter_fabric_site" "example" {

### Required

- `site_name_hierarchy` (String) Existing site name hierarchy available at global level

### Optional

- `fabric_type` (String) Type of SD-Access Fabric
- Choices: `FABRIC_SITE`, `FABRIC_ZONE`
- Default value: `FABRIC_SITE`
- `authentication_profile_name` (String) Authentication profile used for this fabric
- Choices: `Closed Authentication`, `Low Impact`, `No Authentication`, `Open Authentication`
- `pub_sub_enabled` (Boolean) Specifies whether this fabric site will use pub/sub for control nodes
- `site_id` (String) ID of the network hierarchy

### Read-Only

Expand All @@ -41,5 +39,5 @@ resource "catalystcenter_fabric_site" "example" {
Import is supported using the following syntax:

```shell
terraform import catalystcenter_fabric_site.example "<site_name_hierarchy>"
terraform import catalystcenter_fabric_site.example "<id>"
```
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
data "catalystcenter_fabric_site" "example" {
id = "Global/Site1"
id = "76d24097-41c4-4558-a4d0-a8c07ac08470"
}
2 changes: 1 addition & 1 deletion examples/resources/catalystcenter_fabric_site/import.sh
Original file line number Diff line number Diff line change
@@ -1 +1 @@
terraform import catalystcenter_fabric_site.example "<site_name_hierarchy>"
terraform import catalystcenter_fabric_site.example "<id>"
5 changes: 3 additions & 2 deletions examples/resources/catalystcenter_fabric_site/resource.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
resource "catalystcenter_fabric_site" "example" {
site_name_hierarchy = "Global/Site1"
fabric_type = "FABRIC_SITE"
site_id = "8e6f7b3a-2b0b-4a7d-8b1c-0d4b1cd5e1b1"
authentication_profile_name = "No Authentication"
pub_sub_enabled = false
}
51 changes: 32 additions & 19 deletions gen/definitions/fabric_site.yaml
Original file line number Diff line number Diff line change
@@ -1,28 +1,41 @@
---
name: Fabric Site
rest_endpoint: /dna/intent/api/v1/business/sda/fabric-site
id_from_attribute: true
id_query_param: siteNameHierarchy
delete_id_query_param: siteNameHierarchy
no_update: true
skip_minimum_test: true
rest_endpoint: /dna/intent/api/v1/sda/fabricSites
get_rest_endpoint: /dna/intent/api/v1/sda/fabricSites?limit=500
res_description: Manages Fabric Sites
id_from_query_path: response
get_from_all: true
put_id_include_path: "0.id"
put_no_id: true
doc_category: SDA
attributes:
- model_name: siteNameHierarchy
type: String
id: true
- model_name: siteId
requires_replace: true
data_path: '0'
match_id: true
data_source_query: true
description: Existing site name hierarchy available at global level
example: Global/Site1
test_value: '"${catalystcenter_area.test.parent_name}/${catalystcenter_area.test.name}"'
- model_name: fabricType
response_data_path: siteId
mandatory: true
type: String
description: ID of the network hierarchy
example: 8e6f7b3a-2b0b-4a7d-8b1c-0d4b1cd5e1b1
test_value: catalystcenter_area.test.id
- model_name: authenticationProfileName
data_path: '0'
response_data_path: authenticationProfileName
mandatory: true
type: String
description: Type of SD-Access Fabric
enum_values: [FABRIC_SITE, FABRIC_ZONE]
write_only: true # when configuring FABRIC_SITE, GET return FABRIC_LAN (v2.3.7.4)
requires_replace: true # PUT not implemented
example: FABRIC_SITE
default_value: FABRIC_SITE
description: Authentication profile used for this fabric
enum_values: [Closed Authentication, Low Impact, No Authentication, Open Authentication]
example: No Authentication
- model_name: isPubSubEnabled
data_path: '0'
response_data_path: isPubSubEnabled
tf_name: pub_sub_enabled
type: Bool
mandatory: true
description: Specifies whether this fabric site will use pub/sub for control nodes
example: false
test_prerequisites: |
resource "catalystcenter_area" "test" {
name = "Area 1"
Expand Down
31 changes: 17 additions & 14 deletions internal/provider/data_source_catalystcenter_fabric_site.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ package provider
import (
"context"
"fmt"
"net/url"

"github.com/hashicorp/terraform-plugin-framework-validators/datasourcevalidator"
"github.com/hashicorp/terraform-plugin-framework/datasource"
Expand Down Expand Up @@ -66,13 +65,17 @@ func (d *FabricSiteDataSource) Schema(ctx context.Context, req datasource.Schema
Optional: true,
Computed: true,
},
"site_name_hierarchy": schema.StringAttribute{
MarkdownDescription: "Existing site name hierarchy available at global level",
"site_id": schema.StringAttribute{
MarkdownDescription: "ID of the network hierarchy",
Optional: true,
Computed: true,
},
"fabric_type": schema.StringAttribute{
MarkdownDescription: "Type of SD-Access Fabric",
"authentication_profile_name": schema.StringAttribute{
MarkdownDescription: "Authentication profile used for this fabric",
Computed: true,
},
"pub_sub_enabled": schema.BoolAttribute{
MarkdownDescription: "Specifies whether this fabric site will use pub/sub for control nodes",
Computed: true,
},
},
Expand All @@ -82,7 +85,7 @@ func (d *FabricSiteDataSource) ConfigValidators(ctx context.Context) []datasourc
return []datasource.ConfigValidator{
datasourcevalidator.ExactlyOneOf(
path.MatchRoot("id"),
path.MatchRoot("site_name_hierarchy"),
path.MatchRoot("site_id"),
),
}
}
Expand All @@ -109,36 +112,36 @@ func (d *FabricSiteDataSource) Read(ctx context.Context, req datasource.ReadRequ
}

tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Read", config.Id.String()))
if config.Id.IsNull() && !config.SiteNameHierarchy.IsNull() {
res, err := d.client.Get(config.getPath())
if config.Id.IsNull() && !config.SiteId.IsNull() {
res, err := d.client.Get("/dna/intent/api/v1/sda/fabricSites?limit=500")
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve objects, got error: %s", err))
return
}
if value := res; len(value.Array()) > 0 {
if value := res.Get("response"); len(value.Array()) > 0 {
value.ForEach(func(k, v gjson.Result) bool {
if config.SiteNameHierarchy.ValueString() == v.Get("siteNameHierarchy").String() {
if config.SiteId.ValueString() == v.Get("siteId").String() {
config.Id = types.StringValue(v.Get("id").String())
tflog.Debug(ctx, fmt.Sprintf("%s: Found object with siteNameHierarchy '%v', id: %v", config.Id.String(), config.SiteNameHierarchy.ValueString(), config.Id.String()))
tflog.Debug(ctx, fmt.Sprintf("%s: Found object with siteId '%v', id: %v", config.Id.String(), config.SiteId.ValueString(), config.Id.String()))
return false
}
return true
})
}

if config.Id.IsNull() {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to find object with siteNameHierarchy: %s", config.SiteNameHierarchy.ValueString()))
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to find object with siteId: %s", config.SiteId.ValueString()))
return
}
}

params := ""
params += "?siteNameHierarchy=" + url.QueryEscape(config.Id.ValueString())
res, err := d.client.Get(config.getPath() + params)
res, err := d.client.Get("/dna/intent/api/v1/sda/fabricSites?limit=500" + params)
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve object, got error: %s", err))
return
}
res = res.Get("response.#(id==\"" + config.Id.ValueString() + "\")")

config.fromBody(ctx, res)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import (
// Section below is generated&owned by "gen/generator.go". //template:begin testAccDataSource
func TestAccDataSourceCcFabricSite(t *testing.T) {
var checks []resource.TestCheckFunc
checks = append(checks, resource.TestCheckResourceAttr("data.catalystcenter_fabric_site.test", "authentication_profile_name", "No Authentication"))
checks = append(checks, resource.TestCheckResourceAttr("data.catalystcenter_fabric_site.test", "pub_sub_enabled", "false"))
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Expand Down Expand Up @@ -56,8 +58,9 @@ resource "catalystcenter_area" "test" {
// Section below is generated&owned by "gen/generator.go". //template:begin testAccDataSourceConfig
func testAccDataSourceCcFabricSiteConfig() string {
config := `resource "catalystcenter_fabric_site" "test" {` + "\n"
config += ` site_name_hierarchy = "${catalystcenter_area.test.parent_name}/${catalystcenter_area.test.name}"` + "\n"
config += ` fabric_type = "FABRIC_SITE"` + "\n"
config += ` site_id = catalystcenter_area.test.id` + "\n"
config += ` authentication_profile_name = "No Authentication"` + "\n"
config += ` pub_sub_enabled = false` + "\n"
config += `}` + "\n"

config += `
Expand Down
61 changes: 46 additions & 15 deletions internal/provider/model_catalystcenter_fabric_site.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,17 @@ import (

// Section below is generated&owned by "gen/generator.go". //template:begin types
type FabricSite struct {
Id types.String `tfsdk:"id"`
SiteNameHierarchy types.String `tfsdk:"site_name_hierarchy"`
FabricType types.String `tfsdk:"fabric_type"`
Id types.String `tfsdk:"id"`
SiteId types.String `tfsdk:"site_id"`
AuthenticationProfileName types.String `tfsdk:"authentication_profile_name"`
PubSubEnabled types.Bool `tfsdk:"pub_sub_enabled"`
}

// End of section. //template:end types

// Section below is generated&owned by "gen/generator.go". //template:begin getPath
func (data FabricSite) getPath() string {
return "/dna/intent/api/v1/business/sda/fabric-site"
return "/dna/intent/api/v1/sda/fabricSites"
}

// End of section. //template:end getPath
Expand All @@ -54,13 +55,17 @@ func (data FabricSite) toBody(ctx context.Context, state FabricSite) string {
put := false
if state.Id.ValueString() != "" {
put = true
body, _ = sjson.Set(body, "0.id", state.Id.ValueString())
}
_ = put
if !data.SiteNameHierarchy.IsNull() {
body, _ = sjson.Set(body, "siteNameHierarchy", data.SiteNameHierarchy.ValueString())
if !data.SiteId.IsNull() {
body, _ = sjson.Set(body, "0.siteId", data.SiteId.ValueString())
}
if !data.FabricType.IsNull() {
body, _ = sjson.Set(body, "fabricType", data.FabricType.ValueString())
if !data.AuthenticationProfileName.IsNull() {
body, _ = sjson.Set(body, "0.authenticationProfileName", data.AuthenticationProfileName.ValueString())
}
if !data.PubSubEnabled.IsNull() {
body, _ = sjson.Set(body, "0.isPubSubEnabled", data.PubSubEnabled.ValueBool())
}
return body
}
Expand All @@ -69,29 +74,55 @@ func (data FabricSite) toBody(ctx context.Context, state FabricSite) string {

// Section below is generated&owned by "gen/generator.go". //template:begin fromBody
func (data *FabricSite) fromBody(ctx context.Context, res gjson.Result) {
if value := res.Get("siteNameHierarchy"); value.Exists() {
data.SiteNameHierarchy = types.StringValue(value.String())
if value := res.Get("siteId"); value.Exists() {
data.SiteId = types.StringValue(value.String())
} else {
data.SiteId = types.StringNull()
}
if value := res.Get("authenticationProfileName"); value.Exists() {
data.AuthenticationProfileName = types.StringValue(value.String())
} else {
data.SiteNameHierarchy = types.StringNull()
data.AuthenticationProfileName = types.StringNull()
}
if value := res.Get("isPubSubEnabled"); value.Exists() {
data.PubSubEnabled = types.BoolValue(value.Bool())
} else {
data.PubSubEnabled = types.BoolNull()
}
}

// End of section. //template:end fromBody

// Section below is generated&owned by "gen/generator.go". //template:begin updateFromBody
func (data *FabricSite) updateFromBody(ctx context.Context, res gjson.Result) {
if value := res.Get("siteNameHierarchy"); value.Exists() && !data.SiteNameHierarchy.IsNull() {
data.SiteNameHierarchy = types.StringValue(value.String())
if value := res.Get("siteId"); value.Exists() && !data.SiteId.IsNull() {
data.SiteId = types.StringValue(value.String())
} else {
data.SiteId = types.StringNull()
}
if value := res.Get("authenticationProfileName"); value.Exists() && !data.AuthenticationProfileName.IsNull() {
data.AuthenticationProfileName = types.StringValue(value.String())
} else {
data.SiteNameHierarchy = types.StringNull()
data.AuthenticationProfileName = types.StringNull()
}
if value := res.Get("isPubSubEnabled"); value.Exists() && !data.PubSubEnabled.IsNull() {
data.PubSubEnabled = types.BoolValue(value.Bool())
} else {
data.PubSubEnabled = types.BoolNull()
}
}

// End of section. //template:end updateFromBody

// Section below is generated&owned by "gen/generator.go". //template:begin isNull
func (data *FabricSite) isNull(ctx context.Context, res gjson.Result) bool {
if !data.FabricType.IsNull() {
if !data.SiteId.IsNull() {
return false
}
if !data.AuthenticationProfileName.IsNull() {
return false
}
if !data.PubSubEnabled.IsNull() {
return false
}
return true
Expand Down
Loading