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

Dev #159

Closed
wants to merge 6 commits into from
Closed

Dev #159

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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 0.1.18 (unreleased)

- Add `Free Space` allowed value to rf_model attribute in `catalystcenter_floor` resource
- Add import and update support to `catalystcenter_fabric_port_assignment` resource
- Add device unreachability warning to DELETE in `catalystcenter_fabric_l3_handoff_ip_transit`, `catalystcenter_anycast_gateway`, `catalystcenter_fabric_l2_handoff`, `catalystcenter_fabric_device`, `catalystcenter_fabric_port_assignment` and `catalystcenter_provision_device` resources
- Fix issue in `catalystcenter_ip_pool_reservation` resource, [link](https://github.com/CiscoDevNet/terraform-provider-catalystcenter/issues/156)

## 0.1.17

- BREAKING CHANGE: Rename `auth_key_sae_ext_plus_tf` attribute of `catalystcenter_wireless_ssid` resource to `auth_key_sae_ext_plus_ft`
Expand Down
1 change: 1 addition & 0 deletions docs/data-sources/fabric_port_assignment.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Read-Only:
- `connected_device_type` (String) Connected device type of the port assignment
- `data_vlan_name` (String) Data VLAN name of the port assignment
- `fabric_id` (String) ID of the fabric the device is assigned to
- `id` (String) ID of the port assignment
- `interface_description` (String) Interface description of the port assignment
- `interface_name` (String) Interface name of the port assignment
- `network_device_id` (String) Network device ID of the port assignment
Expand Down
7 changes: 7 additions & 0 deletions docs/guides/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ description: |-

# Changelog

## 0.1.18 (unreleased)

- Add `Free Space` allowed value to rf_model attribute in `catalystcenter_floor` resource
- Add import and update support to `catalystcenter_fabric_port_assignment` resource
- Add device unreachability warning to DELETE in `catalystcenter_fabric_l3_handoff_ip_transit`, `catalystcenter_anycast_gateway`, `catalystcenter_fabric_l2_handoff`, `catalystcenter_fabric_device`, `catalystcenter_fabric_port_assignment` and `catalystcenter_provision_device` resources
- Fix issue in `catalystcenter_ip_pool_reservation` resource, [link](https://github.com/CiscoDevNet/terraform-provider-catalystcenter/issues/156)

## 0.1.17

- BREAKING CHANGE: Rename `auth_key_sae_ext_plus_tf` attribute of `catalystcenter_wireless_ssid` resource to `auth_key_sae_ext_plus_ft`
Expand Down
10 changes: 10 additions & 0 deletions docs/resources/fabric_port_assignment.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ resource "catalystcenter_fabric_port_assignment" "example" {
network_device_id = "5e6f7b3a-2b0b-4a7d-8b1c-0d4b1cd5e1b"
port_assignments = [
{
id = "5e6f7b3a-2b0b-4a7d-8b1c-0d4b1cd5e1b1"
fabric_id = "c4b85bb2-ce3f-4db9-a32b-e439a388ac2f"
network_device_id = "5e6f7b3a-2b0b-4a7d-8b1c-0d4b1cd5e1b1"
interface_name = "GigabitEthernet1/0/2"
Expand Down Expand Up @@ -62,6 +63,15 @@ Optional:
- `authenticate_template_name` (String) Authenticate template name of the port assignment
- Choices: `No Authentication`, `Open Authentication`, `Closed Authentication`, `Low Impact`
- `data_vlan_name` (String) Data VLAN name of the port assignment
- `id` (String) ID of the port assignment
- `interface_description` (String) Interface description of the port assignment
- `security_group_name` (String) Security group name of the port assignment
- `voice_vlan_name` (String) Voice VLAN name of the port assignment

## Import

Import is supported using the following syntax:

```shell
terraform import catalystcenter_fabric_port_assignment.example "<fabric_id>,<network_device_id>"
```
2 changes: 1 addition & 1 deletion docs/resources/floor.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ resource "catalystcenter_floor" "example" {
- `name` (String) The name of the floor
- `parent_name` (String) The path of the parent building, e.g. `Global/Building1`
- `rf_model` (String) The RF model
- Choices: `Cubes And Walled Offices`, `Drywall Office Only`, `Indoor High Ceiling`, `Outdoor Open Space`
- Choices: `Cubes And Walled Offices`, `Drywall Office Only`, `Indoor High Ceiling`, `Outdoor Open Space`, `Free Space`
- `width` (Number) Width

### Optional
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
terraform import catalystcenter_fabric_port_assignment.example "<fabric_id>,<network_device_id>"
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ resource "catalystcenter_fabric_port_assignment" "example" {
network_device_id = "5e6f7b3a-2b0b-4a7d-8b1c-0d4b1cd5e1b"
port_assignments = [
{
id = "5e6f7b3a-2b0b-4a7d-8b1c-0d4b1cd5e1b1"
fabric_id = "c4b85bb2-ce3f-4db9-a32b-e439a388ac2f"
network_device_id = "5e6f7b3a-2b0b-4a7d-8b1c-0d4b1cd5e1b1"
interface_name = "GigabitEthernet1/0/2"
Expand Down
8 changes: 7 additions & 1 deletion gen/definitions/discovery.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ attributes:
mandatory: true
match_id: true
description: A name of the discovery.
test_value: '"testing terraform provider"'
test_value: catalystcenter_credentials_cli.test.id
example: disco42
requires_replace: true
- model_name: netconfPort
Expand Down Expand Up @@ -205,3 +205,9 @@ attributes:
exclude_test: true
exclude_example: true
requires_replace: true
test_prerequisites: |
resource "catalystcenter_credentials_cli" "test" {
description = "TestCli1"
username = "user1"
password = "password1"
}
14 changes: 8 additions & 6 deletions gen/definitions/fabric_port_assignment.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
name: Fabric Port Assignment
# Manual modifications in resource file in Create function to compute id of ports
rest_endpoint: /dna/intent/api/v1/sda/portAssignments
res_description: Manages port assignments in SD-Access fabric.
no_update: true
no_import: true
import_no_id: true
data_source_no_id: true
id_from_attribute: true
root_list: true
Expand Down Expand Up @@ -37,23 +37,25 @@ attributes:
mandatory: true
description: List of port assignments in SD-Access fabric
attributes:
- model_name: id
type: String
computed: true
description: ID of the port assignment
example: 5e6f7b3a-2b0b-4a7d-8b1c-0d4b1cd5e1b1
- model_name: fabricId
query_param: true
type: String
mandatory: true
description: ID of the fabric the device is assigned to
example: c4b85bb2-ce3f-4db9-a32b-e439a388ac2f
test_value: catalystcenter_fabric_site.test.id
- model_name: networkDeviceId
match_id: true
query_param: true
mandatory: true
description: Network device ID of the port assignment
type: String
example: 5e6f7b3a-2b0b-4a7d-8b1c-0d4b1cd5e1b1
- model_name: interfaceName
query_param: true
mandatory: true
id: true
type: String
description: Interface name of the port assignment
example: GigabitEthernet1/0/2
Expand Down
2 changes: 1 addition & 1 deletion gen/definitions/fabric_site.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ attributes:
example: false
test_prerequisites: |
resource "catalystcenter_area" "test" {
name = "Area 1"
name = "Area1"
parent_name = "Global"
}
2 changes: 1 addition & 1 deletion gen/definitions/floor.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ attributes:
- model_name: rfModel
data_path: site.floor
type: String
enum_values: ["Cubes And Walled Offices", "Drywall Office Only", "Indoor High Ceiling", "Outdoor Open Space"]
enum_values: ["Cubes And Walled Offices", "Drywall Office Only", "Indoor High Ceiling", "Outdoor Open Space", "Free Space"]
mandatory: true
write_only: true
description: The RF model
Expand Down
1 change: 1 addition & 0 deletions gen/definitions/ip_pool.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ attributes:
enum_values: [IPv4, IPv6]
default_value: IPv4
description: IP address version
write_only: true
example: IPv4
- model_name: type
type: String
Expand Down
10 changes: 4 additions & 6 deletions gen/definitions/ip_pool_reservation.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
name: IP Pool Reservation
# Manual modifications in model file in updateFromBody and fromBody to support dual-stack pools
rest_endpoint: /dna/intent/api/v1/reserve-ip-subpool
id_from_query_path: response.0
id_from_query_path_attribute: id
Expand Down Expand Up @@ -28,9 +29,9 @@ attributes:
- model_name: type
type: String
mandatory: true
write_only: true
response_data_path: response.0.type
exclude_from_put: true
write_only: true
enum_values: [Generic, LAN, WAN, management, service]
description: The type of the IP pool reservation
example: Generic
Expand All @@ -55,14 +56,14 @@ attributes:
example: true
- model_name: ipv4PrefixLength
type: Int64
write_only: true
requires_replace: true
exclude_from_put: true
description: The IPv4 prefix length is required when `ipv4_prefix` value is `true`.
example: 24
minimum_test_value: 24
- model_name: ipv4Subnet
type: String
write_only: true
requires_replace: true
exclude_from_put: true
description: The IPv4 subnet
example: 172.32.1.0
Expand Down Expand Up @@ -112,21 +113,18 @@ attributes:
- model_name: ipv6GateWay
tf_name: ipv6_gateway
type: String
write_only: true
description: The gateway for the IP pool reservation
example: "2001:db8:85a3:0:100::1"
exclude_test: true
- model_name: ipv6DhcpServers
type: Set
element_type: String
write_only: true
description: List of DHCP Server IPs
example: "2001:db8::1234"
exclude_test: true
- model_name: ipv6DnsServers
type: Set
element_type: String
write_only: true
description: List of DNS Server IPs
example: "2001:db8::1234"
exclude_test: true
Expand Down
14 changes: 13 additions & 1 deletion gen/templates/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ func (r *{{camelCase .Name}}Resource) Create(ctx context.Context, req resource.C
failureReason := res.Get("response.failureReason").String()
resp.Diagnostics.AddWarning("Device Unreachability Warning", fmt.Sprintf("Device unreachability detected (error code: %s, reason %s).", errorCode, failureReason))
} else {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (%s), got error: %s, %s", "POST", err, res.String()))
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (%s), got error: %s, %s", {{- if .PutCreate }} "PUT" {{- else }} "POST" {{- end }}, err, res.String()))
return
}
{{- else}}
Expand Down Expand Up @@ -656,8 +656,20 @@ func (r *{{camelCase .Name}}Resource) Delete(ctx context.Context, req resource.D
res, err := r.client.Delete({{if .DeleteRestEndpoint}}state.getPathDelete(){{else}}state.getPath(){{end}} + "/" + url.QueryEscape(state.Id.ValueString()))
{{- end}}
if err != nil {
{{- if .DeviceUnreachabilityWarning}}
errorCode := res.Get("response.errorCode").String()
if errorCode == "NCDP10000" {
// Log a warning and continue execution when device is unreachable
failureReason := res.Get("response.failureReason").String()
resp.Diagnostics.AddWarning("Device Unreachability Warning", fmt.Sprintf("Device unreachability detected (error code: %s, reason %s).", errorCode, failureReason))
} else {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to delete object (%s), got error: %s, %s", "DELETE", err, res.String()))
return
}
{{- else}}
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to delete object (DELETE), got error: %s, %s", err, res.String()))
return
{{- end}}
}
{{- end}}

Expand Down
12 changes: 10 additions & 2 deletions internal/provider/data_source_catalystcenter_discovery_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func TestAccDataSourceCcDiscovery(t *testing.T) {
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccDataSourceCcDiscoveryConfig(),
Config: testAccDataSourceCcDiscoveryPrerequisitesConfig + testAccDataSourceCcDiscoveryConfig(),
Check: resource.ComposeTestCheckFunc(checks...),
},
},
Expand All @@ -49,14 +49,22 @@ func TestAccDataSourceCcDiscovery(t *testing.T) {
// End of section. //template:end testAccDataSource

// Section below is generated&owned by "gen/generator.go". //template:begin testPrerequisites
const testAccDataSourceCcDiscoveryPrerequisitesConfig = `
resource "catalystcenter_credentials_cli" "test" {
description = "TestCli1"
username = "user1"
password = "password1"
}
`

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

// Section below is generated&owned by "gen/generator.go". //template:begin testAccDataSourceConfig
func testAccDataSourceCcDiscoveryConfig() string {
config := `resource "catalystcenter_discovery" "test" {` + "\n"
config += ` discovery_type = "Range"` + "\n"
config += ` ip_address_list = "192.168.0.1-192.168.0.99"` + "\n"
config += ` name = "testing terraform provider"` + "\n"
config += ` name = catalystcenter_credentials_cli.test.id` + "\n"
config += ` netconf_port = "830"` + "\n"
config += ` protocol_order = "SSH"` + "\n"
config += ` retry = 3` + "\n"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ func (d *FabricPortAssignmentDataSource) Schema(ctx context.Context, req datasou
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
MarkdownDescription: "ID of the port assignment",
Computed: true,
},
"fabric_id": schema.StringAttribute{
MarkdownDescription: "ID of the fabric the device is assigned to",
Computed: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func TestAccDataSourceCcFabricPortAssignment(t *testing.T) {
t.Skip("skipping test, set environment variable SDA")
}
var checks []resource.TestCheckFunc
checks = append(checks, resource.TestCheckResourceAttr("data.catalystcenter_fabric_port_assignment.test", "port_assignments.0.id", "5e6f7b3a-2b0b-4a7d-8b1c-0d4b1cd5e1b1"))
checks = append(checks, resource.TestCheckResourceAttr("data.catalystcenter_fabric_port_assignment.test", "port_assignments.0.network_device_id", "5e6f7b3a-2b0b-4a7d-8b1c-0d4b1cd5e1b1"))
checks = append(checks, resource.TestCheckResourceAttr("data.catalystcenter_fabric_port_assignment.test", "port_assignments.0.interface_name", "GigabitEthernet1/0/2"))
checks = append(checks, resource.TestCheckResourceAttr("data.catalystcenter_fabric_port_assignment.test", "port_assignments.0.connected_device_type", "USER_DEVICE"))
Expand Down Expand Up @@ -62,6 +63,7 @@ func testAccDataSourceCcFabricPortAssignmentConfig() string {
config += ` fabric_id = "e02d9911-b0a7-435b-bb46-079d877d7b3e"` + "\n"
config += ` network_device_id = "5e6f7b3a-2b0b-4a7d-8b1c-0d4b1cd5e1b"` + "\n"
config += ` port_assignments = [{` + "\n"
config += ` id = "5e6f7b3a-2b0b-4a7d-8b1c-0d4b1cd5e1b1"` + "\n"
config += ` fabric_id = catalystcenter_fabric_site.test.id` + "\n"
config += ` network_device_id = "5e6f7b3a-2b0b-4a7d-8b1c-0d4b1cd5e1b1"` + "\n"
config += ` interface_name = "GigabitEthernet1/0/2"` + "\n"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func TestAccDataSourceCcFabricSite(t *testing.T) {
// Section below is generated&owned by "gen/generator.go". //template:begin testPrerequisites
const testAccDataSourceCcFabricSitePrerequisitesConfig = `
resource "catalystcenter_area" "test" {
name = "Area 1"
name = "Area1"
parent_name = "Global"
}
`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import (
func TestAccDataSourceCcIPPoolReservation(t *testing.T) {
var checks []resource.TestCheckFunc
checks = append(checks, resource.TestCheckResourceAttr("data.catalystcenter_ip_pool_reservation.test", "name", "MyRes1"))
checks = append(checks, resource.TestCheckResourceAttr("data.catalystcenter_ip_pool_reservation.test", "ipv4_prefix_length", "24"))
checks = append(checks, resource.TestCheckResourceAttr("data.catalystcenter_ip_pool_reservation.test", "ipv4_subnet", "172.32.1.0"))
checks = append(checks, resource.TestCheckResourceAttr("data.catalystcenter_ip_pool_reservation.test", "ipv4_gateway", "172.32.1.1"))
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import (
func TestAccDataSourceCcIPPool(t *testing.T) {
var checks []resource.TestCheckFunc
checks = append(checks, resource.TestCheckResourceAttr("data.catalystcenter_ip_pool.test", "name", "MyPool1"))
checks = append(checks, resource.TestCheckResourceAttr("data.catalystcenter_ip_pool.test", "ip_address_space", "IPv4"))
checks = append(checks, resource.TestCheckResourceAttr("data.catalystcenter_ip_pool.test", "type", "generic"))
checks = append(checks, resource.TestCheckResourceAttr("data.catalystcenter_ip_pool.test", "ip_subnet", "21.1.1.0/24"))
resource.Test(t, resource.TestCase{
Expand Down
18 changes: 16 additions & 2 deletions internal/provider/model_catalystcenter_fabric_port_assignment.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type FabricPortAssignment struct {
}

type FabricPortAssignmentPortAssignments struct {
Id types.String `tfsdk:"id"`
FabricId types.String `tfsdk:"fabric_id"`
NetworkDeviceId types.String `tfsdk:"network_device_id"`
InterfaceName types.String `tfsdk:"interface_name"`
Expand Down Expand Up @@ -79,6 +80,9 @@ func (data FabricPortAssignment) toBody(ctx context.Context, state FabricPortAss
body, _ = sjson.Set(body, "", []interface{}{})
for _, item := range data.PortAssignments {
itemBody := ""
if !item.Id.IsNull() {
itemBody, _ = sjson.Set(itemBody, "id", item.Id.ValueString())
}
if !item.FabricId.IsNull() {
itemBody, _ = sjson.Set(itemBody, "fabricId", item.FabricId.ValueString())
}
Expand Down Expand Up @@ -128,6 +132,11 @@ func (data *FabricPortAssignment) fromBody(ctx context.Context, res gjson.Result
data.PortAssignments = make([]FabricPortAssignmentPortAssignments, 0)
value.ForEach(func(k, v gjson.Result) bool {
item := FabricPortAssignmentPortAssignments{}
if cValue := v.Get("id"); cValue.Exists() {
item.Id = types.StringValue(cValue.String())
} else {
item.Id = types.StringNull()
}
if cValue := v.Get("fabricId"); cValue.Exists() {
item.FabricId = types.StringValue(cValue.String())
} else {
Expand Down Expand Up @@ -186,8 +195,8 @@ func (data *FabricPortAssignment) updateFromBody(ctx context.Context, res gjson.

res = res.Get("response")
for i := range data.PortAssignments {
keys := [...]string{"fabricId", "networkDeviceId", "interfaceName", "connectedDeviceType", "dataVlanName", "voiceVlanName", "authenticateTemplateName", "securityGroupName", "interfaceDescription"}
keyValues := [...]string{data.PortAssignments[i].FabricId.ValueString(), data.PortAssignments[i].NetworkDeviceId.ValueString(), data.PortAssignments[i].InterfaceName.ValueString(), data.PortAssignments[i].ConnectedDeviceType.ValueString(), data.PortAssignments[i].DataVlanName.ValueString(), data.PortAssignments[i].VoiceVlanName.ValueString(), data.PortAssignments[i].AuthenticateTemplateName.ValueString(), data.PortAssignments[i].SecurityGroupName.ValueString(), data.PortAssignments[i].InterfaceDescription.ValueString()}
keys := [...]string{"interfaceName"}
keyValues := [...]string{data.PortAssignments[i].InterfaceName.ValueString()}

var r gjson.Result
res.ForEach(
Expand All @@ -208,6 +217,11 @@ func (data *FabricPortAssignment) updateFromBody(ctx context.Context, res gjson.
return true
},
)
if value := r.Get("id"); value.Exists() && !data.PortAssignments[i].Id.IsNull() {
data.PortAssignments[i].Id = types.StringValue(value.String())
} else {
data.PortAssignments[i].Id = types.StringNull()
}
if value := r.Get("fabricId"); value.Exists() && !data.PortAssignments[i].FabricId.IsNull() {
data.PortAssignments[i].FabricId = types.StringValue(value.String())
} else {
Expand Down
Loading
Loading