diff --git a/.github/workflows/ci-testing.yml b/.github/workflows/ci-testing.yml index e6cf0848..6dfdc097 100644 --- a/.github/workflows/ci-testing.yml +++ b/.github/workflows/ci-testing.yml @@ -34,18 +34,18 @@ jobs: fail-fast: false matrix: netbox-version: - # - v4.0.0 has mandatory tenant group - - v4.0.1 - - v4.0.2 - - v4.0.3 - # - v4.0.4 does not exist for some reason - - v4.0.5 - - v4.0.6 - - v4.0.7 - - v4.0.8 - - v4.0.9 - - v4.0.10 - - v4.0.11 + - v4.1.0 + - v4.1.1 + - v4.1.2 + - v4.1.3 + - v4.1.4 + - v4.1.5 + - v4.1.6 + - v4.1.7 + - v4.1.8 + # - v4.1.9 has a regression - do not use + - v4.1.10 + - v4.1.11 steps: - uses: actions/checkout@v4 - name: Set up Go diff --git a/GNUmakefile b/GNUmakefile index 90c26bf3..36cf3421 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,9 +1,9 @@ TEST?=netbox/*.go -TEST_FUNC?=TestAccNetboxEventRule_basic +TEST_FUNC?=TestAccNetboxVirtualMachine* GOFMT_FILES?=$$(find . -name '*.go' | grep -v vendor) DOCKER_COMPOSE=docker compose -export NETBOX_VERSION=v4.0.11 +export NETBOX_VERSION=v4.1.11 export NETBOX_SERVER_URL=http://localhost:8001 export NETBOX_API_TOKEN=0123456789abcdef0123456789abcdef01234567 export NETBOX_TOKEN=$(NETBOX_API_TOKEN) diff --git a/README.md b/README.md index 3c15a466..aff79e49 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,8 @@ Since version [1.6.6](https://github.com/e-breuninger/terraform-provider-netbox/ | Netbox version | Provider version | | --------------- | ---------------- | -| v4.0.0 - 4.0.11 | v3.9.0 and up | +| v4.1.0 - 4.1.11 | v3.10.0 and up | +| v4.0.0 - 4.0.11 | v3.9.0 - 3.9.2 | | v3.7.0 - 3.7.8 | v3.8.0 - 3.8.9 | | v3.6.0 - 3.6.9 | v3.7.0 - 3.7.7 | | v3.5.1 - 3.5.9 | v3.6.x | diff --git a/docs/data-sources/racks.md b/docs/data-sources/racks.md index 39d15e28..4f3061d6 100644 --- a/docs/data-sources/racks.md +++ b/docs/data-sources/racks.md @@ -59,7 +59,7 @@ Read-Only: - `status` (String) - `tags` (Set of String) - `tenant_id` (Number) -- `type` (String) +- `type_id` (Number) - `u_height` (Number) - `weight` (Number) - `weight_unit` (String) diff --git a/docs/data-sources/virtual_machines.md b/docs/data-sources/virtual_machines.md index 204318a2..00c9f6e1 100644 --- a/docs/data-sources/virtual_machines.md +++ b/docs/data-sources/virtual_machines.md @@ -62,7 +62,7 @@ Read-Only: - `description` (String) - `device_id` (Number) - `device_name` (String) -- `disk_size_gb` (Number) +- `disk_size_mb` (Number) - `local_context_data` (String) - `memory_mb` (Number) - `name` (String) diff --git a/docs/data-sources/vlan_group.md b/docs/data-sources/vlan_group.md index de579144..323dbb75 100644 --- a/docs/data-sources/vlan_group.md +++ b/docs/data-sources/vlan_group.md @@ -45,8 +45,6 @@ data "netbox_vlan_group" "example3" { - `description` (String) - `id` (String) The ID of this resource. -- `max_vid` (Number) -- `min_vid` (Number) - `vlan_count` (Number) diff --git a/docs/index.md b/docs/index.md index 4cfabccf..0dbb758a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -16,7 +16,8 @@ Netbox often makes breaking API changes even in non-major releases. Check the ta | Netbox version | Provider version | | --------------- | ---------------- | -| v4.0.0 - 4.0.11 | v3.9.0 and up | +| v4.1.0 - 4.1.11 | v3.10.0 and up | +| v4.0.0 - 4.0.11 | v3.9.0 - 3.9.2 | | v3.7.0 - 3.7.8 | v3.8.0 - 3.8.9 | | v3.6.0 - 3.6.9 | v3.7.0 - 3.7.7 | | v3.5.1 - 3.5.9 | v3.6.x | diff --git a/docs/resources/event_rule.md b/docs/resources/event_rule.md index eb59e94e..1739b70b 100644 --- a/docs/resources/event_rule.md +++ b/docs/resources/event_rule.md @@ -22,11 +22,19 @@ resource "netbox_webhook" "test" { } resource "netbox_event_rule" "test" { - name = "my-event-rule" - content_types = ["dcim.site", "virtualization.cluster"] - action_type = "webhook" - action_object_id = netbox_webhook.test.id - trigger_on_create = true + name = "my-event-rule" + content_types = ["dcim.site", "virtualization.cluster"] + action_type = "webhook" + action_object_id = netbox_webhook.test.id + event_types = [ + "object_created", + "object_updated", + "object_deleted", + "job_started", + "job_completed", + "job_failed", + "job_errored" + ] } ``` @@ -38,6 +46,7 @@ resource "netbox_event_rule" "test" { - `action_object_id` (Number) - `action_type` (String) Valid values are `webhook`. - `content_types` (Set of String) +- `event_types` (Set of String) The types of event which will trigger this rule. By default, valid values are `object_created`, `oject_updated`, `object_deleted`, `job_started`, `job_completed`, `job_failed` and `job_errored`. - `name` (String) ### Optional @@ -46,11 +55,6 @@ resource "netbox_event_rule" "test" { - `description` (String) - `enabled` (Boolean) Defaults to `true`. - `tags` (Set of String) -- `trigger_on_create` (Boolean) At least one of `trigger_on_create`, `trigger_on_update`, `trigger_on_delete`, `trigger_on_job_start` or `trigger_on_job_end` must be given. -- `trigger_on_delete` (Boolean) At least one of `trigger_on_create`, `trigger_on_update`, `trigger_on_delete`, `trigger_on_job_start` or `trigger_on_job_end` must be given. -- `trigger_on_job_end` (Boolean) At least one of `trigger_on_create`, `trigger_on_update`, `trigger_on_delete`, `trigger_on_job_start` or `trigger_on_job_end` must be given. -- `trigger_on_job_start` (Boolean) At least one of `trigger_on_create`, `trigger_on_update`, `trigger_on_delete`, `trigger_on_job_start` or `trigger_on_job_end` must be given. -- `trigger_on_update` (Boolean) At least one of `trigger_on_create`, `trigger_on_update`, `trigger_on_delete`, `trigger_on_job_start` or `trigger_on_job_end` must be given. ### Read-Only diff --git a/docs/resources/permission.md b/docs/resources/permission.md index ab8c9903..cb400e00 100644 --- a/docs/resources/permission.md +++ b/docs/resources/permission.md @@ -20,7 +20,7 @@ This resource manages the object-based permissions for Netbox users, built into ```terraform resource "netbox_user" "test" { username = "johndoe" - password = "abcdefghijkl" + password = "Abcdefghijkl1" active = true staff = true } diff --git a/docs/resources/rack.md b/docs/resources/rack.md index 0e993ecd..2b541ba6 100644 --- a/docs/resources/rack.md +++ b/docs/resources/rack.md @@ -44,8 +44,6 @@ resource "netbox_rack" "test" { - `name` (String) - `site_id` (Number) - `status` (String) Valid values are `reserved`, `available`, `planned`, `active` and `deprecated`. -- `u_height` (Number) -- `width` (Number) Valid values are `10`, `19`, `21` and `23`. ### Optional @@ -55,6 +53,7 @@ resource "netbox_rack" "test" { - `desc_units` (Boolean) If rack units are descending. Defaults to `false`. - `description` (String) - `facility_id` (String) +- `form_factor` (String) Valid values are `2-post-frame`, `4-post-frame`, `4-post-cabinet`, `wall-frame`, `wall-frame-vertical`, `wall-cabinet` and `wall-cabinet-vertical`. - `location_id` (Number) - `max_weight` (Number) - `mounting_depth` (Number) @@ -65,9 +64,10 @@ resource "netbox_rack" "test" { - `serial` (String) - `tags` (Set of String) - `tenant_id` (Number) -- `type` (String) Valid values are `2-post-frame`, `4-post-frame`, `4-post-cabinet`, `wall-frame`, `wall-frame-vertical`, `wall-cabinet` and `wall-cabinet-vertical`. +- `u_height` (Number) - `weight` (Number) - `weight_unit` (String) Valid values are `kg`, `g`, `lb` and `oz`. Required when `weight` and `max_weight` is set. +- `width` (Number) Valid values are `10`, `19`, `21` and `23`. ### Read-Only diff --git a/docs/resources/rack_type.md b/docs/resources/rack_type.md new file mode 100644 index 00000000..863d07d1 --- /dev/null +++ b/docs/resources/rack_type.md @@ -0,0 +1,72 @@ +--- +# generated by https://github.com/fbreckle/terraform-plugin-docs +page_title: "netbox_rack_type Resource - terraform-provider-netbox" +subcategory: "Data Center Inventory Management (DCIM)" +description: |- + From the official documentation https://netboxlabs.com/docs/netbox/en/stable/models/dcim/racktype/: + A rack type defines the physical characteristics of a particular model of rack. +--- + +# netbox_rack_type (Resource) + +From the [official documentation](https://netboxlabs.com/docs/netbox/en/stable/models/dcim/racktype/): + +> A rack type defines the physical characteristics of a particular model of rack. + +## Example Usage + +```terraform +resource "netbox_manufacturer" "test" { + name = "my-manufacturer" +} + +resource "netbox_rack_type" "test" { + model = "mymodel" + manufacturer_id = netbox_manufacturer.test.id + width = 19 + u_height = 48 + starting_unit = 1 + form_factor = "2-post-frame" + description = "My description" + outer_width = 10 + outer_depth = 15 + outer_unit = "mm" + weight = 15 + max_weight = 20 + weight_unit = "kg" + mounting_depth_mm = 21 + comments = "My comments" +} +``` + + +## Schema + +### Required + +- `form_factor` (String) Valid values are `2-post-frame`, `4-post-frame`, `4-post-cabinet`, `wall-frame`, `wall-frame-vertical`, `wall-cabinet` and `wall-cabinet-vertical`. +- `model` (String) +- `starting_unit` (Number) +- `u_height` (Number) +- `width` (Number) Valid values are `10`, `19`, `21` and `23`. + +### Optional + +- `comments` (String) +- `description` (String) +- `manufacturer_id` (Number) +- `max_weight` (Number) +- `mounting_depth_mm` (Number) +- `outer_depth` (Number) +- `outer_unit` (String) Valid values are `mm` and `in`. Required when `outer_width` and `outer_depth` is set. +- `outer_width` (Number) +- `slug` (String) +- `tags` (Set of String) +- `weight` (Number) +- `weight_unit` (String) Valid values are `kg`, `g`, `lb` and `oz`. Required when `weight` and `max_weight` is set. + +### Read-Only + +- `id` (String) The ID of this resource. + + diff --git a/docs/resources/token.md b/docs/resources/token.md index 43e47fce..402fc41d 100644 --- a/docs/resources/token.md +++ b/docs/resources/token.md @@ -18,7 +18,7 @@ From the [official documentation](https://docs.netbox.dev/en/stable/rest-api/aut ```terraform resource "netbox_user" "test" { username = "johndoe" - password = "abcdefghijkl" + password = "Abcdefghijkl1" } resource "netbox_token" "test_basic" { diff --git a/docs/resources/user.md b/docs/resources/user.md index 5ec936fc..25bb8643 100644 --- a/docs/resources/user.md +++ b/docs/resources/user.md @@ -15,7 +15,7 @@ This resource is used to manage users. ```terraform resource "netbox_user" "test" { username = "johndoe" - password = "abcdefghijkl" + password = "Abcdefghijkl1" active = true staff = true } diff --git a/docs/resources/virtual_disk.md b/docs/resources/virtual_disk.md index d5401453..89245554 100644 --- a/docs/resources/virtual_disk.md +++ b/docs/resources/virtual_disk.md @@ -29,7 +29,7 @@ resource "netbox_virtual_machine" "base_vm" { resource "netbox_virtual_disk" "example" { name = "disk-01" description = "Main disk" - size_gb = 50 + size_mb = 50 virtual_machine_id = netbox_virtual_machine.base_vm.id } ``` @@ -40,7 +40,7 @@ resource "netbox_virtual_disk" "example" { ### Required - `name` (String) -- `size_gb` (Number) +- `size_mb` (Number) - `virtual_machine_id` (Number) ### Optional diff --git a/docs/resources/virtual_machine.md b/docs/resources/virtual_machine.md index 9362e7a6..8d0591a7 100644 --- a/docs/resources/virtual_machine.md +++ b/docs/resources/virtual_machine.md @@ -33,7 +33,7 @@ data "netbox_cluster" "vmw_cluster_01" { resource "netbox_virtual_machine" "basic_vm" { cluster_id = data.netbox_cluster.vmw_cluster_01.id name = "myvm-2" - disk_size_gb = 40 + disk_size_mb = 40000 memory_mb = 4092 vcpus = "2" } @@ -50,7 +50,7 @@ data "netbox_tenant" "customer_a" { resource "netbox_virtual_machine" "full_vm" { cluster_id = data.netbox_cluster.vmw_cluster_01.id name = "myvm-3" - disk_size_gb = 40 + disk_size_mb = 40000 memory_mb = 4092 vcpus = "2" role_id = 31 // This corresponds to the Netbox ID for a given role @@ -76,7 +76,7 @@ resource "netbox_virtual_machine" "full_vm" { - `custom_fields` (Map of String) - `description` (String) - `device_id` (Number) -- `disk_size_gb` (Number) +- `disk_size_mb` (Number) - `local_context_data` (String) This is best managed through the use of `jsonencode` and a map of settings. - `memory_mb` (Number) - `platform_id` (Number) diff --git a/docs/resources/vlan_group.md b/docs/resources/vlan_group.md index 8789c7dc..cbddf85f 100644 --- a/docs/resources/vlan_group.md +++ b/docs/resources/vlan_group.md @@ -15,22 +15,19 @@ description: |- ```terraform #Basic VLAN Group example resource "netbox_vlan_group" "example1" { - name = "example1" - slug = "example1" - min_vid = 1 - max_vid = 4094 + name = "example1" + slug = "example1" } #Full VLAN Group example resource "netbox_vlan_group" "example2" { name = "Second Example" slug = "example2" - min_vid = 1 - max_vid = 4094 scope_type = "dcim.site" scope_id = netbox_site.example.id description = "Second Example VLAN Group" tags = [netbox_tag.example.id] + vid_ranges = [[1, 2], [3, 4]] } ``` @@ -39,10 +36,9 @@ resource "netbox_vlan_group" "example2" { ### Required -- `max_vid` (Number) -- `min_vid` (Number) - `name` (String) - `slug` (String) +- `vid_ranges` (List of List of Number) ### Optional diff --git a/example/main.tf b/example/main.tf index 5f33782d..9c980191 100644 --- a/example/main.tf +++ b/example/main.tf @@ -77,7 +77,7 @@ resource "netbox_virtual_machine" "testvm" { comments = "my-test-comment" memory_mb = 1024 vcpus = 4 - disk_size_gb = 512 + disk_size_mb = 512 cluster_id = netbox_cluster.testcluster.id tenant_id = netbox_tenant.testtenant.id platform_id = netbox_platform.testplatform.id diff --git a/examples/resources/netbox_event_rule/resource.tf b/examples/resources/netbox_event_rule/resource.tf index 22159e0a..4c7489d5 100644 --- a/examples/resources/netbox_event_rule/resource.tf +++ b/examples/resources/netbox_event_rule/resource.tf @@ -4,9 +4,17 @@ resource "netbox_webhook" "test" { } resource "netbox_event_rule" "test" { - name = "my-event-rule" - content_types = ["dcim.site", "virtualization.cluster"] - action_type = "webhook" - action_object_id = netbox_webhook.test.id - trigger_on_create = true + name = "my-event-rule" + content_types = ["dcim.site", "virtualization.cluster"] + action_type = "webhook" + action_object_id = netbox_webhook.test.id + event_types = [ + "object_created", + "object_updated", + "object_deleted", + "job_started", + "job_completed", + "job_failed", + "job_errored" + ] } diff --git a/examples/resources/netbox_permission/resource.tf b/examples/resources/netbox_permission/resource.tf index bd8f6810..dae842d0 100644 --- a/examples/resources/netbox_permission/resource.tf +++ b/examples/resources/netbox_permission/resource.tf @@ -1,6 +1,6 @@ resource "netbox_user" "test" { username = "johndoe" - password = "abcdefghijkl" + password = "Abcdefghijkl1" active = true staff = true } diff --git a/examples/resources/netbox_rack_type/resource.tf b/examples/resources/netbox_rack_type/resource.tf new file mode 100644 index 00000000..160a0a47 --- /dev/null +++ b/examples/resources/netbox_rack_type/resource.tf @@ -0,0 +1,21 @@ +resource "netbox_manufacturer" "test" { + name = "my-manufacturer" +} + +resource "netbox_rack_type" "test" { + model = "mymodel" + manufacturer_id = netbox_manufacturer.test.id + width = 19 + u_height = 48 + starting_unit = 1 + form_factor = "2-post-frame" + description = "My description" + outer_width = 10 + outer_depth = 15 + outer_unit = "mm" + weight = 15 + max_weight = 20 + weight_unit = "kg" + mounting_depth_mm = 21 + comments = "My comments" +} diff --git a/examples/resources/netbox_token/resource.tf b/examples/resources/netbox_token/resource.tf index e4cd2fac..f6db0751 100644 --- a/examples/resources/netbox_token/resource.tf +++ b/examples/resources/netbox_token/resource.tf @@ -1,6 +1,6 @@ resource "netbox_user" "test" { username = "johndoe" - password = "abcdefghijkl" + password = "Abcdefghijkl1" } resource "netbox_token" "test_basic" { diff --git a/examples/resources/netbox_user/resource.tf b/examples/resources/netbox_user/resource.tf index 68cf376c..d6f896cc 100644 --- a/examples/resources/netbox_user/resource.tf +++ b/examples/resources/netbox_user/resource.tf @@ -1,6 +1,6 @@ resource "netbox_user" "test" { username = "johndoe" - password = "abcdefghijkl" + password = "Abcdefghijkl1" active = true staff = true } diff --git a/examples/resources/netbox_virtual_disk/resource.tf b/examples/resources/netbox_virtual_disk/resource.tf index e628e584..a8134a5c 100644 --- a/examples/resources/netbox_virtual_disk/resource.tf +++ b/examples/resources/netbox_virtual_disk/resource.tf @@ -11,6 +11,6 @@ resource "netbox_virtual_machine" "base_vm" { resource "netbox_virtual_disk" "example" { name = "disk-01" description = "Main disk" - size_gb = 50 + size_mb = 50 virtual_machine_id = netbox_virtual_machine.base_vm.id } diff --git a/examples/resources/netbox_virtual_machine/resource.tf b/examples/resources/netbox_virtual_machine/resource.tf index bc478cc6..95184279 100644 --- a/examples/resources/netbox_virtual_machine/resource.tf +++ b/examples/resources/netbox_virtual_machine/resource.tf @@ -15,7 +15,7 @@ data "netbox_cluster" "vmw_cluster_01" { resource "netbox_virtual_machine" "basic_vm" { cluster_id = data.netbox_cluster.vmw_cluster_01.id name = "myvm-2" - disk_size_gb = 40 + disk_size_mb = 40000 memory_mb = 4092 vcpus = "2" } @@ -32,7 +32,7 @@ data "netbox_tenant" "customer_a" { resource "netbox_virtual_machine" "full_vm" { cluster_id = data.netbox_cluster.vmw_cluster_01.id name = "myvm-3" - disk_size_gb = 40 + disk_size_mb = 40000 memory_mb = 4092 vcpus = "2" role_id = 31 // This corresponds to the Netbox ID for a given role diff --git a/examples/resources/netbox_vlan_group/resource.tf b/examples/resources/netbox_vlan_group/resource.tf index 48d4975c..58452c29 100644 --- a/examples/resources/netbox_vlan_group/resource.tf +++ b/examples/resources/netbox_vlan_group/resource.tf @@ -1,19 +1,16 @@ #Basic VLAN Group example resource "netbox_vlan_group" "example1" { - name = "example1" - slug = "example1" - min_vid = 1 - max_vid = 4094 + name = "example1" + slug = "example1" } #Full VLAN Group example resource "netbox_vlan_group" "example2" { name = "Second Example" slug = "example2" - min_vid = 1 - max_vid = 4094 scope_type = "dcim.site" scope_id = netbox_site.example.id description = "Second Example VLAN Group" tags = [netbox_tag.example.id] + vid_ranges = [[1, 2], [3, 4]] } diff --git a/go.mod b/go.mod index 78cf5f78..0ce4c331 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.22.0 toolchain go1.23.2 require ( - github.com/fbreckle/go-netbox v0.0.0-20240712203246-697d4aa8d19a + github.com/fbreckle/go-netbox v0.0.0-20250107100759-dedd55c8354b github.com/fbreckle/terraform-plugin-docs v0.0.0-20220812121758-a828466500d3 github.com/go-openapi/runtime v0.28.0 github.com/go-openapi/strfmt v0.23.0 diff --git a/go.sum b/go.sum index 85fd7460..791add69 100644 --- a/go.sum +++ b/go.sum @@ -43,8 +43,8 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= -github.com/fbreckle/go-netbox v0.0.0-20240712203246-697d4aa8d19a h1:6obi0w2aChXRKJVMp3k3PBNOD+84SkKFW2Q8trly1Eg= -github.com/fbreckle/go-netbox v0.0.0-20240712203246-697d4aa8d19a/go.mod h1:3U3/m/hna9Ntd3sbHBYwZ1IqbP2+coRzoXw3mCfu3kM= +github.com/fbreckle/go-netbox v0.0.0-20250107100759-dedd55c8354b h1:wgjuyXonOHXgod6e7kjehzeXn0jQOX7cydEKo+BBNdc= +github.com/fbreckle/go-netbox v0.0.0-20250107100759-dedd55c8354b/go.mod h1:3U3/m/hna9Ntd3sbHBYwZ1IqbP2+coRzoXw3mCfu3kM= github.com/fbreckle/terraform-plugin-docs v0.0.0-20220812121758-a828466500d3 h1:DMSpM0btVedE2Tt1vfDHWQhf2obzjAe1F0/j8/CyfW4= github.com/fbreckle/terraform-plugin-docs v0.0.0-20220812121758-a828466500d3/go.mod h1:j3HmJySEjx6hOAOPDjGzmzpVNDQq9SNnnF+Vm22d2rs= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= diff --git a/netbox/data_source_netbox_device_interfaces_test.go b/netbox/data_source_netbox_device_interfaces_test.go index 8c14217f..f45f240c 100644 --- a/netbox/data_source_netbox_device_interfaces_test.go +++ b/netbox/data_source_netbox_device_interfaces_test.go @@ -11,7 +11,7 @@ func TestAccNetboxDeviceInterfacesDataSource_basic(t *testing.T) { testSlug := "dev_ifaces_ds_basic" testName := testAccGetTestName(testSlug) dependencies := testAccNetboxDeviceInterfacesDataSourceDependencies(testName) - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ Providers: testAccProviders, Steps: []resource.TestStep{ { diff --git a/netbox/data_source_netbox_racks.go b/netbox/data_source_netbox_racks.go index 9325a7a6..59f39cf9 100644 --- a/netbox/data_source_netbox_racks.go +++ b/netbox/data_source_netbox_racks.go @@ -92,8 +92,8 @@ func dataSourceNetboxRacks() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "type": { - Type: schema.TypeString, + "type_id": { + Type: schema.TypeInt, Computed: true, }, "weight": { @@ -203,7 +203,7 @@ func dataSourceNetboxRacksRead(d *schema.ResourceData, m interface{}) error { params.Status = &vString case "tenant_id": params.TenantID = &vString - case "type": + case "type_id": params.Type = &vString case "u_height": params.UHeight = &vString @@ -259,9 +259,7 @@ func dataSourceNetboxRacksRead(d *schema.ResourceData, m interface{}) error { } mapping["serial"] = v.Serial mapping["asset_tag"] = v.AssetTag - if v.Type != nil { - mapping["type"] = v.Type.Value - } + mapping["type_id"] = v.Type mapping["weight"] = v.Weight mapping["max_weight"] = v.MaxWeight mapping["desc_units"] = v.DescUnits diff --git a/netbox/data_source_netbox_tags_test.go b/netbox/data_source_netbox_tags_test.go index 6fe6705c..c5ace180 100644 --- a/netbox/data_source_netbox_tags_test.go +++ b/netbox/data_source_netbox_tags_test.go @@ -28,8 +28,8 @@ func testAccNetboxTagsByName() string { return ` data "netbox_tags" "test" { filter { - name = "name" - value = "Tag1234" + name = "name" + value = "Tag1234" } }` } @@ -38,8 +38,8 @@ func testAccNetboxTagsBySlug() string { return ` data "netbox_tags" "test" { filter { - name = "slug" - value = "weird" + name = "slug" + value = "weird" } }` } diff --git a/netbox/data_source_netbox_virtual_machines.go b/netbox/data_source_netbox_virtual_machines.go index 7b84e84b..c1694d0e 100644 --- a/netbox/data_source_netbox_virtual_machines.go +++ b/netbox/data_source_netbox_virtual_machines.go @@ -77,7 +77,7 @@ func dataSourceNetboxVirtualMachine() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "disk_size_gb": { + "disk_size_mb": { Type: schema.TypeInt, Computed: true, }, @@ -244,7 +244,7 @@ func dataSourceNetboxVirtualMachineRead(d *schema.ResourceData, m interface{}) e mapping["custom_fields"] = v.CustomFields } if v.Disk != nil { - mapping["disk_size_gb"] = *v.Disk + mapping["disk_size_mb"] = *v.Disk } if v.LocalContextData != nil { if localContextData, err := json.Marshal(v.LocalContextData); err == nil { diff --git a/netbox/data_source_netbox_virtual_machines_test.go b/netbox/data_source_netbox_virtual_machines_test.go index 9b7cbb24..4639bd8d 100644 --- a/netbox/data_source_netbox_virtual_machines_test.go +++ b/netbox/data_source_netbox_virtual_machines_test.go @@ -24,7 +24,7 @@ func TestAccNetboxVirtualMachinesDataSource_basic(t *testing.T) { resource.TestCheckResourceAttr("data.netbox_virtual_machines.test", "vms.0.name", testName+"_0"), resource.TestCheckResourceAttr("data.netbox_virtual_machines.test", "vms.0.vcpus", "4"), resource.TestCheckResourceAttr("data.netbox_virtual_machines.test", "vms.0.memory_mb", "1024"), - resource.TestCheckResourceAttr("data.netbox_virtual_machines.test", "vms.0.disk_size_gb", "256"), + resource.TestCheckResourceAttr("data.netbox_virtual_machines.test", "vms.0.disk_size_mb", "256"), resource.TestCheckResourceAttr("data.netbox_virtual_machines.test", "vms.0.comments", "thisisacomment"), resource.TestCheckResourceAttrPair("data.netbox_virtual_machines.test", "vms.0.tenant_id", "netbox_tenant.test", "id"), resource.TestCheckResourceAttrPair("data.netbox_virtual_machines.test", "vms.0.role_id", "netbox_device_role.test", "id"), @@ -126,7 +126,7 @@ resource "netbox_virtual_machine" "test0" { device_id = netbox_device.test.id comments = "thisisacomment" memory_mb = 1024 - disk_size_gb = 256 + disk_size_mb = 256 tenant_id = netbox_tenant.test.id role_id = netbox_device_role.test.id platform_id = netbox_platform.test.id @@ -156,11 +156,11 @@ resource "netbox_virtual_machine" "test3" { func testAccNetboxVirtualMachineDataSourceDependenciesWithTags(testName string) string { return testAccNetboxVirtualMachineFullDependencies(testName) + fmt.Sprintf(` resource "netbox_tag" "servicea" { - name = "%[1]s_service-a" + name = "%[1]s_service-a" } resource "netbox_tag" "serviceb" { - name = "%[1]s_service-b" + name = "%[1]s_service-b" } resource "netbox_virtual_machine" "test0" { @@ -169,33 +169,33 @@ resource "netbox_virtual_machine" "test0" { site_id = netbox_site.test.id comments = "thisisacomment" memory_mb = 1024 - disk_size_gb = 256 + disk_size_mb = 256 tenant_id = netbox_tenant.test.id role_id = netbox_device_role.test.id platform_id = netbox_platform.test.id vcpus = 4 tags = [ - netbox_tag.servicea.name, - netbox_tag.serviceb.name, - ] + netbox_tag.servicea.name, + netbox_tag.serviceb.name, + ] } resource "netbox_virtual_machine" "test1" { name = "%[1]s_1" cluster_id = netbox_cluster.test.id site_id = netbox_site.test.id - tags = [ - netbox_tag.servicea.name, - ] + tags = [ + netbox_tag.servicea.name, + ] } resource "netbox_virtual_machine" "test2" { name = "%[1]s_2_regex" cluster_id = netbox_cluster.test.id site_id = netbox_site.test.id - tags = [ - netbox_tag.serviceb.name, - ] + tags = [ + netbox_tag.serviceb.name, + ] } `, testName) } @@ -242,12 +242,12 @@ data "netbox_virtual_machines" "test" { func testAccNetboxVirtualMachineDataSourceTagA(testName string) string { return fmt.Sprintf(` - data "netbox_virtual_machines" "tag-a" { - filter { - name = "tag" - value = "%[1]s_service-a" - } - }`, testName) +data "netbox_virtual_machines" "tag-a" { + filter { + name = "tag" + value = "%[1]s_service-a" + } +}`, testName) } func testAccNetboxVirtualMachineDataSourceTagB(testName string) string { @@ -256,21 +256,21 @@ data "netbox_virtual_machines" "tag-b" { filter { name = "tag" value = "%[1]s_service-b" - } + } }`, testName) } func testAccNetboxVirtualMachineDataSourceTagAB(testName string) string { return fmt.Sprintf(` data "netbox_virtual_machines" "tag-ab" { - filter { + filter { name = "tag" value = "%[1]s_service-a" - } + } filter { name = "tag" value = "%[1]s_service-b" - } + } }`, testName) } @@ -293,40 +293,40 @@ data "netbox_virtual_machines" "test_decommissioning" { func testAccNetboxVirtualMachineDataSourceDependenciesWithStatus(testName string) string { return testAccNetboxVirtualMachineFullDependencies(testName) + fmt.Sprintf(` resource "netbox_tag" "servicea" { - name = "%[1]s_service-a" + name = "%[1]s_service-a" } resource "netbox_virtual_machine" "test0" { - name = "%[1]s_0" - cluster_id = netbox_cluster.test.id - site_id = netbox_site.test.id - comments = "thisisacomment" - memory_mb = 1024 - disk_size_gb = 256 - tenant_id = netbox_tenant.test.id - role_id = netbox_device_role.test.id - platform_id = netbox_platform.test.id - vcpus = 4 - status = "active" - tags = [ - netbox_tag.servicea.name, - ] + name = "%[1]s_0" + cluster_id = netbox_cluster.test.id + site_id = netbox_site.test.id + comments = "thisisacomment" + memory_mb = 1024 + disk_size_mb = 256 + tenant_id = netbox_tenant.test.id + role_id = netbox_device_role.test.id + platform_id = netbox_platform.test.id + vcpus = 4 + status = "active" + tags = [ + netbox_tag.servicea.name, + ] } resource "netbox_virtual_machine" "test1" { - name = "%[1]s_1" - cluster_id = netbox_cluster.test.id - site_id = netbox_site.test.id - comments = "thisisacomment" - memory_mb = 1024 - disk_size_gb = 256 - tenant_id = netbox_tenant.test.id - role_id = netbox_device_role.test.id - platform_id = netbox_platform.test.id - vcpus = 4 - status = "decommissioning" - tags = [ - netbox_tag.servicea.name, - ] + name = "%[1]s_1" + cluster_id = netbox_cluster.test.id + site_id = netbox_site.test.id + comments = "thisisacomment" + memory_mb = 1024 + disk_size_mb = 256 + tenant_id = netbox_tenant.test.id + role_id = netbox_device_role.test.id + platform_id = netbox_platform.test.id + vcpus = 4 + status = "decommissioning" + tags = [ + netbox_tag.servicea.name, + ] }`, testName) } diff --git a/netbox/data_source_netbox_vlan_group.go b/netbox/data_source_netbox_vlan_group.go index 4ae52051..d3b5a588 100644 --- a/netbox/data_source_netbox_vlan_group.go +++ b/netbox/data_source_netbox_vlan_group.go @@ -39,14 +39,6 @@ func dataSourceNetboxVlanGroup() *schema.Resource { Optional: true, RequiredWith: []string{"scope_type"}, }, - "min_vid": { - Type: schema.TypeInt, - Computed: true, - }, - "max_vid": { - Type: schema.TypeInt, - Computed: true, - }, "vlan_count": { Type: schema.TypeInt, Computed: true, @@ -93,8 +85,6 @@ func dataSourceNetboxVlanGroupRead(d *schema.ResourceData, m interface{}) error d.SetId(strconv.FormatInt(result.ID, 10)) d.Set("name", result.Name) d.Set("slug", result.Slug) - d.Set("min_vid", result.MinVid) - d.Set("max_vid", result.MaxVid) d.Set("vlan_count", result.VlanCount) d.Set("description", result.Description) return nil diff --git a/netbox/data_source_netbox_vlan_group_test.go b/netbox/data_source_netbox_vlan_group_test.go index 3bb9917a..cf267a4f 100644 --- a/netbox/data_source_netbox_vlan_group_test.go +++ b/netbox/data_source_netbox_vlan_group_test.go @@ -43,8 +43,6 @@ func TestAccNetboxVlanGroupDataSource_basic(t *testing.T) { resource.TestCheckResourceAttr("data.netbox_vlan_group.test", "name", testName), resource.TestCheckResourceAttr("data.netbox_vlan_group.test", "slug", testSlug), resource.TestCheckResourceAttr("data.netbox_vlan_group.test", "description", "Test"), - resource.TestCheckResourceAttr("data.netbox_vlan_group.test", "min_vid", "20"), - resource.TestCheckResourceAttr("data.netbox_vlan_group.test", "max_vid", "200"), resource.TestCheckResourceAttr("data.netbox_vlan_group.test", "scope_type", "dcim.site"), resource.TestCheckResourceAttrPair("data.netbox_vlan_group.test", "scope_id", "netbox_site.test", "id"), ), @@ -56,8 +54,6 @@ func TestAccNetboxVlanGroupDataSource_basic(t *testing.T) { resource.TestCheckResourceAttr("data.netbox_vlan_group.test", "name", testName), resource.TestCheckResourceAttr("data.netbox_vlan_group.test", "slug", testSlug), resource.TestCheckResourceAttr("data.netbox_vlan_group.test", "description", "Test"), - resource.TestCheckResourceAttr("data.netbox_vlan_group.test", "min_vid", "20"), - resource.TestCheckResourceAttr("data.netbox_vlan_group.test", "max_vid", "200"), resource.TestCheckResourceAttr("data.netbox_vlan_group.test", "scope_type", "dcim.site"), resource.TestCheckResourceAttrPair("data.netbox_vlan_group.test", "scope_id", "netbox_site.test", "id"), ), @@ -77,18 +73,17 @@ func TestAccNetboxVlanGroupDataSource_basic(t *testing.T) { func testAccNetboxVlanGroupSetUp(testSlug, testName string) string { return fmt.Sprintf(` resource "netbox_site" "test" { - name = "%[2]s" + name = "%[2]s" } resource "netbox_vlan_group" "test" { - slug = "%[1]s" - name = "%[2]s" - description = "Test" - min_vid = 20 - max_vid = 200 - scope_type = "dcim.site" - scope_id = netbox_site.test.id - tags = [] + slug = "%[1]s" + name = "%[2]s" + description = "Test" + scope_type = "dcim.site" + scope_id = netbox_site.test.id + vid_ranges = [[1, 4094]] + tags = [] } `, testSlug, testName) } @@ -96,54 +91,52 @@ resource "netbox_vlan_group" "test" { func testAccNetboxVlanGroupSetUpMore(testSlug, anotherSlug, testName string) string { return fmt.Sprintf(` resource "netbox_vlan_group" "same_name" { - slug = "%[1]s" - name = "%[3]s" - min_vid = 20 - max_vid = 200 + slug = "%[1]s" + name = "%[3]s" + vid_ranges = [[1, 4094]] } resource "netbox_vlan_group" "not_same" { - slug = "%[2]s" - name = "%[3]s_unique" - min_vid = 20 - max_vid = 200 + slug = "%[2]s" + name = "%[3]s_unique" + vid_ranges = [[1, 4094]] } `, testSlug, anotherSlug, testName) } const testAccNetboxVlanGroupDataNoResult = ` data "netbox_vlan_group" "no_result" { - name = "_no_result_" + name = "_no_result_" }` func testAccNetboxVlanGroupDataByName(testName string) string { return fmt.Sprintf(` data "netbox_vlan_group" "test" { - name = "%[1]s" + name = "%[1]s" }`, testName) } func testAccNetboxVlanGroupDataBySlug(testSlug string) string { return fmt.Sprintf(` data "netbox_vlan_group" "test" { - slug = "%[1]s" + slug = "%[1]s" }`, testSlug) } func testAccNetboxVlanGroupDataByNameAndScope(testName string) string { return fmt.Sprintf(` data "netbox_vlan_group" "test" { - name = "%[1]s" - scope_type = "dcim.site" - scope_id = netbox_site.test.id + name = "%[1]s" + scope_type = "dcim.site" + scope_id = netbox_site.test.id }`, testName) } func testAccNetboxVlanGroupDataBySlugAndScope(testSlug string) string { return fmt.Sprintf(` data "netbox_vlan_group" "test" { - slug = "%[1]s" - scope_type = "dcim.site" - scope_id = netbox_site.test.id + slug = "%[1]s" + scope_type = "dcim.site" + scope_id = netbox_site.test.id }`, testSlug) } diff --git a/netbox/provider.go b/netbox/provider.go index 0e29a7df..0f5da73f 100644 --- a/netbox/provider.go +++ b/netbox/provider.go @@ -122,6 +122,7 @@ func Provider() *schema.Provider { "netbox_location": resourceNetboxLocation(), "netbox_site_group": resourceNetboxSiteGroup(), "netbox_rack": resourceNetboxRack(), + "netbox_rack_type": resourceNetboxRackType(), "netbox_rack_role": resourceNetboxRackRole(), "netbox_rack_reservation": resourceNetboxRackReservation(), "netbox_cable": resourceNetboxCable(), @@ -295,7 +296,7 @@ func providerConfigure(ctx context.Context, data *schema.ResourceData) (interfac netboxVersion := res.GetPayload().(map[string]interface{})["netbox-version"].(string) - supportedVersions := []string{"4.0.0", "4.0.1", "4.0.2", "4.0.3", "4.0.5", "4.0.6", "4.0.7", "4.0.8", "4.0.9", "4.0.10", "4.0.11"} + supportedVersions := []string{"4.1.0", "4.1.1", "4.1.2", "4.1.3", "4.1.4", "4.1.5", "4.1.6", "4.1.7", "4.1.8", "4.1.10", "4.1.11"} if !slices.Contains(supportedVersions, netboxVersion) { // Currently, there is no way to test these warnings. There is an issue to track this: https://github.com/hashicorp/terraform-plugin-sdk/issues/864 diff --git a/netbox/resource_netbox_event_rule.go b/netbox/resource_netbox_event_rule.go index ef278485..a53a61b7 100644 --- a/netbox/resource_netbox_event_rule.go +++ b/netbox/resource_netbox_event_rule.go @@ -38,30 +38,14 @@ func resourceNetboxEventRule() *schema.Resource { Required: true, Elem: &schema.Schema{Type: schema.TypeString}, }, - "trigger_on_create": { - Type: schema.TypeBool, - Optional: true, - AtLeastOneOf: []string{"trigger_on_create", "trigger_on_update", "trigger_on_delete", "trigger_on_job_start", "trigger_on_job_end"}, - }, - "trigger_on_update": { - Type: schema.TypeBool, - Optional: true, - AtLeastOneOf: []string{"trigger_on_create", "trigger_on_update", "trigger_on_delete", "trigger_on_job_start", "trigger_on_job_end"}, - }, - "trigger_on_delete": { - Type: schema.TypeBool, - Optional: true, - AtLeastOneOf: []string{"trigger_on_create", "trigger_on_update", "trigger_on_delete", "trigger_on_job_start", "trigger_on_job_end"}, - }, - "trigger_on_job_start": { - Type: schema.TypeBool, - Optional: true, - AtLeastOneOf: []string{"trigger_on_create", "trigger_on_update", "trigger_on_delete", "trigger_on_job_start", "trigger_on_job_end"}, - }, - "trigger_on_job_end": { - Type: schema.TypeBool, - Optional: true, - AtLeastOneOf: []string{"trigger_on_create", "trigger_on_update", "trigger_on_delete", "trigger_on_job_start", "trigger_on_job_end"}, + "event_types": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{ + // We do not enforce event-type validation, because plugins might extend the list of valid events + Type: schema.TypeString, + }, + Description: "The types of event which will trigger this rule. By default, valid values are `object_created`, `oject_updated`, `object_deleted`, `job_started`, `job_completed`, `job_failed` and `job_errored`", }, "enabled": { Type: schema.TypeBool, @@ -109,16 +93,12 @@ func resourceNetboxEventRuleCreate(d *schema.ResourceData, m interface{}) error // Currently, we just support the webhook action type data.ActionObjectType = strToPtr("extras.webhook") - triggerOnCreate := d.Get("trigger_on_create").(bool) - data.TypeCreate = triggerOnCreate - triggerOnUpdate := d.Get("trigger_on_update").(bool) - data.TypeUpdate = triggerOnUpdate - triggerOnDelete := d.Get("trigger_on_delete").(bool) - data.TypeDelete = triggerOnDelete - triggerOnJobStart := d.Get("trigger_on_job_start").(bool) - data.TypeJobStart = triggerOnJobStart - triggerOnJobEnd := d.Get("trigger_on_job_end").(bool) - data.TypeJobEnd = triggerOnJobEnd + eventTypes := make([]string, 0) + for _, eventType := range d.Get("event_types").(*schema.Set).List() { + eventTypes = append(eventTypes, eventType.(string)) + } + data.EventTypes = eventTypes + enabled := d.Get("enabled").(bool) data.Enabled = enabled data.ActionObjectID = getOptionalInt(d, "action_object_id") @@ -176,12 +156,8 @@ func resourceNetboxEventRuleRead(d *schema.ResourceData, m interface{}) error { d.Set("description", eventRule.Description) d.Set("action_type", eventRule.ActionType.Value) d.Set("content_types", eventRule.ObjectTypes) + d.Set("event_types", eventRule.EventTypes) - d.Set("trigger_on_create", eventRule.TypeCreate) - d.Set("trigger_on_update", eventRule.TypeUpdate) - d.Set("trigger_on_delete", eventRule.TypeDelete) - d.Set("trigger_on_job_start", eventRule.TypeJobStart) - d.Set("trigger_on_job_end", eventRule.TypeJobEnd) d.Set("enabled", eventRule.Enabled) d.Set("action_object_id", eventRule.ActionObjectID) @@ -213,16 +189,12 @@ func resourceNetboxEventRuleUpdate(d *schema.ResourceData, m interface{}) error // Currently, we just support the webhook action type data.ActionObjectType = strToPtr("extras.webhook") - triggerOnCreate := d.Get("trigger_on_create").(bool) - data.TypeCreate = triggerOnCreate - triggerOnUpdate := d.Get("trigger_on_update").(bool) - data.TypeUpdate = triggerOnUpdate - triggerOnDelete := d.Get("trigger_on_delete").(bool) - data.TypeDelete = triggerOnDelete - triggerOnJobStart := d.Get("trigger_on_job_start").(bool) - data.TypeJobStart = triggerOnJobStart - triggerOnJobEnd := d.Get("trigger_on_job_end").(bool) - data.TypeJobEnd = triggerOnJobEnd + eventTypes := make([]string, 0) + for _, eventType := range d.Get("event_types").(*schema.Set).List() { + eventTypes = append(eventTypes, eventType.(string)) + } + data.EventTypes = eventTypes + enabled := d.Get("enabled").(bool) data.Enabled = enabled data.ActionObjectID = getOptionalInt(d, "action_object_id") diff --git a/netbox/resource_netbox_event_rule_test.go b/netbox/resource_netbox_event_rule_test.go index 666a58a7..289742fb 100644 --- a/netbox/resource_netbox_event_rule_test.go +++ b/netbox/resource_netbox_event_rule_test.go @@ -27,16 +27,12 @@ resource "netbox_webhook" "test" { } resource "netbox_event_rule" "test" { - name = "%[1]s" - description = "foo description" - content_types = ["dcim.site"] - action_type = "webhook" - action_object_id = netbox_webhook.test.id - trigger_on_create = true - trigger_on_update = true - trigger_on_delete = true - trigger_on_job_start = true - trigger_on_job_end = true + name = "%[1]s" + description = "foo description" + content_types = ["dcim.site"] + action_type = "webhook" + action_object_id = netbox_webhook.test.id + event_types = ["object_created", "object_updated", "object_deleted", "job_started", "job_completed", "job_failed", "job_errored"] }`, testName), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("netbox_event_rule.test", "name", testName), @@ -44,11 +40,7 @@ resource "netbox_event_rule" "test" { resource.TestCheckResourceAttr("netbox_event_rule.test", "content_types.0", "dcim.site"), resource.TestCheckResourceAttr("netbox_event_rule.test", "action_type", "webhook"), resource.TestCheckResourceAttr("netbox_event_rule.test", "description", "foo description"), - resource.TestCheckResourceAttr("netbox_event_rule.test", "trigger_on_create", "true"), - resource.TestCheckResourceAttr("netbox_event_rule.test", "trigger_on_update", "true"), - resource.TestCheckResourceAttr("netbox_event_rule.test", "trigger_on_delete", "true"), - resource.TestCheckResourceAttr("netbox_event_rule.test", "trigger_on_job_start", "true"), - resource.TestCheckResourceAttr("netbox_event_rule.test", "trigger_on_job_end", "true"), + resource.TestCheckResourceAttr("netbox_event_rule.test", "event_types.#", "7"), ), }, { @@ -59,11 +51,11 @@ resource "netbox_webhook" "test" { } resource "netbox_event_rule" "test" { - name = "%[1]s" - content_types = ["dcim.site", "virtualization.cluster"] - action_type = "webhook" - action_object_id = netbox_webhook.test.id - trigger_on_create = true + name = "%[1]s" + content_types = ["dcim.site", "virtualization.cluster"] + action_type = "webhook" + action_object_id = netbox_webhook.test.id + event_types = ["object_created"] }`, testName), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("netbox_event_rule.test", "name", testName), @@ -71,11 +63,7 @@ resource "netbox_event_rule" "test" { resource.TestCheckResourceAttr("netbox_event_rule.test", "content_types.0", "dcim.site"), resource.TestCheckResourceAttr("netbox_event_rule.test", "content_types.1", "virtualization.cluster"), resource.TestCheckResourceAttr("netbox_event_rule.test", "action_type", "webhook"), - resource.TestCheckResourceAttr("netbox_event_rule.test", "trigger_on_create", "true"), - resource.TestCheckResourceAttr("netbox_event_rule.test", "trigger_on_update", "false"), - resource.TestCheckResourceAttr("netbox_event_rule.test", "trigger_on_delete", "false"), - resource.TestCheckResourceAttr("netbox_event_rule.test", "trigger_on_job_start", "false"), - resource.TestCheckResourceAttr("netbox_event_rule.test", "trigger_on_job_end", "false"), + resource.TestCheckResourceAttr("netbox_event_rule.test", "event_types.#", "1"), ), }, { diff --git a/netbox/resource_netbox_primary_ip_test.go b/netbox/resource_netbox_primary_ip_test.go index d14230b9..108eb990 100644 --- a/netbox/resource_netbox_primary_ip_test.go +++ b/netbox/resource_netbox_primary_ip_test.go @@ -64,7 +64,7 @@ resource "netbox_virtual_machine" "test" { site_id = netbox_site.test.id comments = "thisisacomment" memory_mb = 1024 - disk_size_gb = 256 + disk_size_mb = 256 tenant_id = netbox_tenant.test.id role_id = netbox_device_role.test.id platform_id = netbox_platform.test.id @@ -115,7 +115,7 @@ resource "netbox_primary_ip" "test_v4" { resource.TestCheckResourceAttr("netbox_virtual_machine.test", "comments", "thisisacomment"), resource.TestCheckResourceAttr("netbox_virtual_machine.test", "memory_mb", "1024"), resource.TestCheckResourceAttr("netbox_virtual_machine.test", "vcpus", "4"), - resource.TestCheckResourceAttr("netbox_virtual_machine.test", "disk_size_gb", "256"), + resource.TestCheckResourceAttr("netbox_virtual_machine.test", "disk_size_mb", "256"), resource.TestCheckResourceAttr("netbox_virtual_machine.test", "tags.#", "1"), resource.TestCheckResourceAttr("netbox_virtual_machine.test", "tags.0", testName), resource.TestCheckResourceAttr("netbox_virtual_machine.test", "status", "planned"), @@ -159,7 +159,7 @@ resource "netbox_primary_ip" "test_v6" { resource.TestCheckResourceAttr("netbox_virtual_machine.test", "comments", "thisisacomment"), resource.TestCheckResourceAttr("netbox_virtual_machine.test", "memory_mb", "1024"), resource.TestCheckResourceAttr("netbox_virtual_machine.test", "vcpus", "4"), - resource.TestCheckResourceAttr("netbox_virtual_machine.test", "disk_size_gb", "256"), + resource.TestCheckResourceAttr("netbox_virtual_machine.test", "disk_size_mb", "256"), resource.TestCheckResourceAttr("netbox_virtual_machine.test", "tags.#", "1"), resource.TestCheckResourceAttr("netbox_virtual_machine.test", "tags.0", testName), resource.TestCheckResourceAttr("netbox_virtual_machine.test", "status", "planned"), diff --git a/netbox/resource_netbox_rack.go b/netbox/resource_netbox_rack.go index d41d0c52..4ae39021 100644 --- a/netbox/resource_netbox_rack.go +++ b/netbox/resource_netbox_rack.go @@ -11,10 +11,10 @@ import ( ) var resourceNetboxRackStatusOptions = []string{"reserved", "available", "planned", "active", "deprecated"} -var resourceNetboxRackTypeOptions = []string{"2-post-frame", "4-post-frame", "4-post-cabinet", "wall-frame", "wall-frame-vertical", "wall-cabinet", "wall-cabinet-vertical"} var resourceNetboxRackWeightUnitOptions = []string{"kg", "g", "lb", "oz"} var resourceNetboxRackOuterUnitOptions = []string{"mm", "in"} var resourceNetboxRackWidthOptions = []int{10, 19, 21, 23} +var resourceNetboxRackFormFactorOptions = []string{"2-post-frame", "4-post-frame", "4-post-cabinet", "wall-frame", "wall-frame-vertical", "wall-cabinet", "wall-cabinet-vertical"} func resourceNetboxRack() *schema.Resource { return &schema.Resource{ @@ -47,14 +47,16 @@ Each rack is assigned a name and (optionally) a separate facility ID. This is he Description: buildValidValueDescription(resourceNetboxRackStatusOptions), }, "width": { - Type: schema.TypeInt, - Required: true, + Type: schema.TypeInt, + //Required: true, + Optional: true, ValidateFunc: validation.IntInSlice(resourceNetboxRackWidthOptions), Description: "Valid values are `10`, `19`, `21` and `23`", }, "u_height": { - Type: schema.TypeInt, - Required: true, + Type: schema.TypeInt, + //Required: true, + Optional: true, ValidateFunc: validation.IntBetween(1, 100), }, tagsKey: tagsSchema, @@ -84,12 +86,6 @@ Each rack is assigned a name and (optionally) a separate facility ID. This is he Optional: true, ValidateFunc: validation.StringLenBetween(0, 50), }, - "type": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: validation.StringInSlice(resourceNetboxRackTypeOptions, false), - Description: buildValidValueDescription(resourceNetboxRackTypeOptions), - }, "weight": { Type: schema.TypeFloat, Optional: true, @@ -144,6 +140,12 @@ Each rack is assigned a name and (optionally) a separate facility ID. This is he Optional: true, }, customFieldsKey: customFieldsSchema, + "form_factor": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice(resourceNetboxRackFormFactorOptions, false), + Description: buildValidValueDescription(resourceNetboxRackFormFactorOptions), + }, }, Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, @@ -178,7 +180,6 @@ func resourceNetboxRackCreate(d *schema.ResourceData, m interface{}) error { if assetTag := getOptionalStr(d, "asset_tag", false); assetTag != "" { data.AssetTag = &assetTag } - data.Type = getOptionalStr(d, "type", false) data.Weight = getOptionalFloat(d, "weight") data.MaxWeight = getOptionalInt(d, "max_weight") data.WeightUnit = getOptionalStr(d, "weight_unit", false) @@ -193,6 +194,7 @@ func resourceNetboxRackCreate(d *schema.ResourceData, m interface{}) error { data.MountingDepth = getOptionalInt(d, "mounting_depth") data.Description = getOptionalStr(d, "description", false) data.Comments = getOptionalStr(d, "comments", false) + data.FormFactor = getOptionalStr(d, "form_factor", false) data.Tags, _ = getNestedTagListFromResourceDataSet(api, d.Get(tagsKey)) @@ -279,12 +281,6 @@ func resourceNetboxRackRead(d *schema.ResourceData, m interface{}) error { d.Set("serial", rack.Serial) d.Set("asset_tag", rack.AssetTag) - if rack.Type != nil { - d.Set("type", rack.Type.Value) - } else { - d.Set("type", nil) - } - d.Set("weight", rack.Weight) d.Set("max_weight", rack.MaxWeight) @@ -308,6 +304,12 @@ func resourceNetboxRackRead(d *schema.ResourceData, m interface{}) error { d.Set("description", rack.Description) d.Set("comments", rack.Comments) + if rack.FormFactor != nil { + d.Set("form_factor", rack.FormFactor.Value) + } else { + d.Set("form_factor", nil) + } + cf := getCustomFields(res.GetPayload().CustomFields) if cf != nil { d.Set(customFieldsKey, cf) @@ -348,7 +350,6 @@ func resourceNetboxRackUpdate(d *schema.ResourceData, m interface{}) error { if assetTag := getOptionalStr(d, "asset_tag", false); assetTag != "" { data.AssetTag = &assetTag } - data.Type = getOptionalStr(d, "type", false) data.Weight = getOptionalFloat(d, "weight") data.MaxWeight = getOptionalInt(d, "max_weight") data.WeightUnit = getOptionalStr(d, "weight_unit", false) @@ -363,6 +364,7 @@ func resourceNetboxRackUpdate(d *schema.ResourceData, m interface{}) error { data.MountingDepth = getOptionalInt(d, "mounting_depth") data.Description = getOptionalStr(d, "description", true) data.Comments = getOptionalStr(d, "comments", true) + data.FormFactor = getOptionalStr(d, "form_factor", false) data.Tags, _ = getNestedTagListFromResourceDataSet(api, d.Get(tagsKey)) diff --git a/netbox/resource_netbox_rack_test.go b/netbox/resource_netbox_rack_test.go index 5577d405..5595f157 100644 --- a/netbox/resource_netbox_rack_test.go +++ b/netbox/resource_netbox_rack_test.go @@ -50,32 +50,33 @@ func TestAccNetboxRack_basic(t *testing.T) { { Config: testAccNetboxRackFullDependencies(testName) + fmt.Sprintf(` resource "netbox_rack" "test" { - name = "%[1]s" - site_id = netbox_site.test.id - status = "reserved" - width = 19 - u_height = 48 - tags = ["%[1]sa"] - tenant_id = netbox_tenant.test.id + name = "%[1]s" + site_id = netbox_site.test.id + status = "reserved" + width = 19 + u_height = 48 + tags = ["%[1]sa"] + tenant_id = netbox_tenant.test.id facility_id = "%[1]sfacility" location_id = netbox_location.test.id - role_id = netbox_rack_role.test.id - serial = "%[1]sserial" - asset_tag = "%[1]sasset_tag" - type = "4-post-frame" - desc_units = true + role_id = netbox_rack_role.test.id + serial = "%[1]sserial" + asset_tag = "%[1]sasset_tag" + desc_units = true outer_width = 10 outer_depth = 15 - outer_unit = "mm" - comments = "%[1]scomments" + outer_unit = "mm" + comments = "%[1]scomments" + form_factor = "2-post-frame" } + resource "netbox_rack" "test2" { - name = "%[1]s2" - site_id = netbox_site.test.id + name = "%[1]s2" + site_id = netbox_site.test.id location_id = netbox_location.test.id - status = "reserved" - width = 19 - u_height = 48 + status = "reserved" + width = 19 + u_height = 48 } `, testName), Check: resource.ComposeTestCheckFunc( @@ -92,12 +93,12 @@ resource "netbox_rack" "test2" { resource.TestCheckResourceAttrPair("netbox_rack.test", "role_id", "netbox_rack_role.test", "id"), resource.TestCheckResourceAttr("netbox_rack.test", "serial", testName+"serial"), resource.TestCheckResourceAttr("netbox_rack.test", "asset_tag", testName+"asset_tag"), - resource.TestCheckResourceAttr("netbox_rack.test", "type", "4-post-frame"), resource.TestCheckResourceAttr("netbox_rack.test", "desc_units", "true"), resource.TestCheckResourceAttr("netbox_rack.test", "outer_width", "10"), resource.TestCheckResourceAttr("netbox_rack.test", "outer_depth", "15"), resource.TestCheckResourceAttr("netbox_rack.test", "outer_unit", "mm"), resource.TestCheckResourceAttr("netbox_rack.test", "comments", testName+"comments"), + resource.TestCheckResourceAttr("netbox_rack.test", "form_factor", "2-post-frame"), resource.TestCheckResourceAttr("netbox_rack.test2", "name", testName+"2"), resource.TestCheckResourceAttrPair("netbox_rack.test2", "site_id", "netbox_site.test", "id"), @@ -110,10 +111,10 @@ resource "netbox_rack" "test2" { { Config: testAccNetboxRackFullDependencies(testName) + fmt.Sprintf(` resource "netbox_rack" "test" { - name = "%[1]s" - site_id = netbox_site.test.id - status = "reserved" - width = 19 + name = "%[1]s" + site_id = netbox_site.test.id + status = "reserved" + width = 19 u_height = 48 }`, testName), Check: resource.ComposeTestCheckFunc( @@ -129,7 +130,6 @@ resource "netbox_rack" "test" { resource.TestCheckResourceAttr("netbox_rack.test", "role_id", "0"), resource.TestCheckResourceAttr("netbox_rack.test", "serial", ""), resource.TestCheckResourceAttr("netbox_rack.test", "asset_tag", ""), - resource.TestCheckResourceAttr("netbox_rack.test", "type", ""), resource.TestCheckResourceAttr("netbox_rack.test", "weight", "0"), resource.TestCheckResourceAttr("netbox_rack.test", "max_weight", "0"), resource.TestCheckResourceAttr("netbox_rack.test", "weight_unit", ""), @@ -140,6 +140,62 @@ resource "netbox_rack" "test" { resource.TestCheckResourceAttr("netbox_rack.test", "mounting_depth", "0"), resource.TestCheckResourceAttr("netbox_rack.test", "description", ""), resource.TestCheckResourceAttr("netbox_rack.test", "comments", ""), + resource.TestCheckResourceAttr("netbox_rack.test", "form_factor", ""), + ), + }, + { + ResourceName: "netbox_rack.test", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +/* +Not sure if creating a rack from rack type is a sustainable process when using terraform +func TestAccNetboxRack_fromRackType(t *testing.T) { + testSlug := "rack_fromType" + testName := testAccGetTestName(testSlug) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckRackDestroy, + Steps: []resource.TestStep{ + { + Config: fmt.Sprintf(` +resource "netbox_manufacturer" "test" { + name = "%[1]s" +} + +resource "netbox_site" "test" { + name = "%[1]s" + status = "active" +} + +resource "netbox_rack_type" "test" { + model = "%[1]s" + manufacturer_id = netbox_manufacturer.test.id + width = 19 + u_height = 48 + starting_unit = 1 + form_factor = "2-post-frame" +} + +resource "netbox_rack" "test" { + name = "%[1]s" + site_id = netbox_site.test.id + status = "active" + comments = "%[1]scomments" +} +`, testName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netbox_rack.test", "name", testName), + resource.TestCheckResourceAttrPair("netbox_rack.test", "site_id", "netbox_site.test", "id"), + resource.TestCheckResourceAttr("netbox_rack.test", "status", "active"), + resource.TestCheckResourceAttr("netbox_rack.test", "width", "19"), + resource.TestCheckResourceAttr("netbox_rack.test", "u_height", "48"), + resource.TestCheckResourceAttr("netbox_rack.test", "tags.#", "1"), ), }, { @@ -150,6 +206,7 @@ resource "netbox_rack" "test" { }, }) } +*/ func testAccCheckRackDestroy(s *terraform.State) error { // retrieve the connection established in Provider configuration diff --git a/netbox/resource_netbox_rack_type.go b/netbox/resource_netbox_rack_type.go new file mode 100644 index 00000000..311d5065 --- /dev/null +++ b/netbox/resource_netbox_rack_type.go @@ -0,0 +1,363 @@ +package netbox + +import ( + "strconv" + + "github.com/fbreckle/go-netbox/netbox/client" + "github.com/fbreckle/go-netbox/netbox/client/dcim" + "github.com/fbreckle/go-netbox/netbox/models" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +var resourceNetboxRackTypeFormFactorOptions = []string{"2-post-frame", "4-post-frame", "4-post-cabinet", "wall-frame", "wall-frame-vertical", "wall-cabinet", "wall-cabinet-vertical"} +var resourceNetboxRackTypeWeightUnitOptions = []string{"kg", "g", "lb", "oz"} +var resourceNetboxRackTypeOuterUnitOptions = []string{"mm", "in"} +var resourceNetboxRackTypeWidthOptions = []int{10, 19, 21, 23} + +func resourceNetboxRackType() *schema.Resource { + return &schema.Resource{ + Create: resourceNetboxRackTypeCreate, + Read: resourceNetboxRackTypeRead, + Update: resourceNetboxRackTypeUpdate, + Delete: resourceNetboxRackTypeDelete, + + Description: `:meta:subcategory:Data Center Inventory Management (DCIM):From the [official documentation](https://netboxlabs.com/docs/netbox/en/stable/models/dcim/racktype/): + +> A rack type defines the physical characteristics of a particular model of rack.`, + + Schema: map[string]*schema.Schema{ + "model": { + Type: schema.TypeString, + Required: true, + }, + "manufacturer_id": { + Type: schema.TypeInt, + Optional: true, + }, + "slug": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringLenBetween(1, 100), + }, + "form_factor": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(resourceNetboxRackTypeFormFactorOptions, false), + Description: buildValidValueDescription(resourceNetboxRackTypeFormFactorOptions), + }, + "width": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntInSlice(resourceNetboxRackTypeWidthOptions), + Description: "Valid values are `10`, `19`, `21` and `23`", + }, + "u_height": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(1, 100), + }, + "starting_unit": { + Type: schema.TypeInt, + Required: true, + }, + tagsKey: tagsSchema, + "description": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 200), + }, + "outer_width": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validatePositiveInt16, + }, + "outer_depth": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validatePositiveInt16, + }, + "outer_unit": { + Type: schema.TypeString, + Optional: true, + RequiredWith: []string{"outer_width", "outer_depth"}, + ValidateFunc: validation.StringInSlice(resourceNetboxRackTypeOuterUnitOptions, false), + Description: buildValidValueDescription(resourceNetboxRackTypeOuterUnitOptions), + }, + "comments": { + Type: schema.TypeString, + Optional: true, + }, + "weight": { + Type: schema.TypeFloat, + Optional: true, + }, + "max_weight": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validatePositiveInt32, + }, + "weight_unit": { + Type: schema.TypeString, + Optional: true, + RequiredWith: []string{"weight", "max_weight"}, + ValidateFunc: validation.StringInSlice(resourceNetboxRackTypeWeightUnitOptions, false), + Description: buildValidValueDescription(resourceNetboxRackTypeWeightUnitOptions), + }, + "mounting_depth_mm": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validatePositiveInt16, + }, + // "tenant_id": { + // Type: schema.TypeInt, + // Optional: true, + // }, + // "facility_id": { + // Type: schema.TypeString, + // Optional: true, + // }, + // "location_id": { + // Type: schema.TypeInt, + // Optional: true, + // }, + // "role_id": { + // Type: schema.TypeInt, + // Optional: true, + // }, + // "serial": { + // Type: schema.TypeString, + // Optional: true, + // ValidateFunc: validation.StringLenBetween(0, 50), + // }, + // "asset_tag": { + // Type: schema.TypeString, + // Optional: true, + // ValidateFunc: validation.StringLenBetween(0, 50), + // }, + // "type": { + // Type: schema.TypeString, + // Optional: true, + // ValidateFunc: validation.StringInSlice(resourceNetboxRackTypeTypeOptions, false), + // Description: buildValidValueDescription(resourceNetboxRackTypeTypeOptions), + // }, + // "desc_units": { + // Type: schema.TypeBool, + // Optional: true, + // Description: "If rack units are descending", + // Default: false, + // }, + // "outer_width": { + // Type: schema.TypeInt, + // Optional: true, + // ValidateFunc: validatePositiveInt16, + // }, + // "outer_depth": { + // Type: schema.TypeInt, + // Optional: true, + // ValidateFunc: validatePositiveInt16, + // }, + // "outer_unit": { + // Type: schema.TypeString, + // Optional: true, + // RequiredWith: []string{"outer_width", "outer_depth"}, + // ValidateFunc: validation.StringInSlice(resourceNetboxRackTypeOuterUnitOptions, false), + // Description: buildValidValueDescription(resourceNetboxRackTypeOuterUnitOptions), + // }, + // "mounting_depth": { + // Type: schema.TypeInt, + // Optional: true, + // ValidateFunc: validatePositiveInt16, + // }, + // "description": { + // Type: schema.TypeString, + // Optional: true, + // ValidateFunc: validation.StringLenBetween(0, 200), + // }, + // "comments": { + // Type: schema.TypeString, + // Optional: true, + // }, + // customFieldsKey: customFieldsSchema, + }, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + } +} + +func resourceNetboxRackTypeCreate(d *schema.ResourceData, m interface{}) error { + api := m.(*client.NetBoxAPI) + + model := d.Get("model").(string) + formFactor := d.Get("form_factor").(string) + + slugValue, slugOk := d.GetOk("slug") + var slug string + // Default slug to generated slug if not given + if !slugOk { + slug = getSlug(model) + } else { + slug = slugValue.(string) + } + manufacturerID := int64(d.Get("manufacturer_id").(int)) + width := int64(d.Get("width").(int)) + uHeight := int64(d.Get("u_height").(int)) + + data := models.WritableRackTypeRequest{ + Model: &model, + FormFactor: &formFactor, + Slug: &slug, + Manufacturer: &manufacturerID, + Width: &width, + UHeight: uHeight, + Description: getOptionalStr(d, "description", false), + OuterWidth: getOptionalInt(d, "outer_width"), + OuterDepth: getOptionalInt(d, "outer_depth"), + OuterUnit: getOptionalStr(d, "outer_unit", false), + Comments: getOptionalStr(d, "comments", false), + Weight: getOptionalFloat(d, "weight"), + MaxWeight: getOptionalInt(d, "max_weight"), + WeightUnit: getOptionalStr(d, "weight_unit", false), + MountingDepth: getOptionalInt(d, "mounting_depth_mm"), + } + + data.Tags, _ = getNestedTagListFromResourceDataSet(api, d.Get(tagsKey)) + + params := dcim.NewDcimRackTypesCreateParams().WithData(&data) + + res, err := api.Dcim.DcimRackTypesCreate(params, nil) + if err != nil { + return err + } + + d.SetId(strconv.FormatInt(res.GetPayload().ID, 10)) + + return resourceNetboxRackTypeRead(d, m) +} + +func resourceNetboxRackTypeRead(d *schema.ResourceData, m interface{}) error { + api := m.(*client.NetBoxAPI) + id, _ := strconv.ParseInt(d.Id(), 10, 64) + params := dcim.NewDcimRackTypesReadParams().WithID(id) + + res, err := api.Dcim.DcimRackTypesRead(params, nil) + + if err != nil { + if errresp, ok := err.(*dcim.DcimRackTypesReadDefault); ok { + errorcode := errresp.Code() + if errorcode == 404 { + // If the ID is updated to blank, this tells Terraform the resource no longer exists (maybe it was destroyed out of band). Just like the destroy callback, the Read function should gracefully handle this case. https://www.terraform.io/docs/extend/writing-custom-providers.html + d.SetId("") + return nil + } + } + return err + } + + rackType := res.GetPayload() + + d.Set("model", rackType.Model) + d.Set("form_factor", rackType.FormFactor.Value) + d.Set("starting_unit", rackType.StartingUnit) + d.Set("manufacturer_id", rackType.Manufacturer.ID) + + if rackType.Width != nil { + d.Set("width", rackType.Width.Value) + } else { + d.Set("width", nil) + } + + d.Set("u_height", rackType.UHeight) + d.Set(tagsKey, getTagListFromNestedTagList(res.GetPayload().Tags)) + d.Set("description", rackType.Description) + d.Set("comments", rackType.Comments) + + d.Set("outer_width", rackType.OuterWidth) + d.Set("outer_depth", rackType.OuterDepth) + + if rackType.OuterUnit != nil { + d.Set("outer_unit", rackType.OuterUnit.Value) + } else { + d.Set("outer_unit", nil) + } + + d.Set("weight", rackType.Weight) + d.Set("max_weight", rackType.MaxWeight) + + if rackType.WeightUnit != nil { + d.Set("weight_unit", rackType.WeightUnit.Value) + } else { + d.Set("weight_unit", nil) + } + + d.Set("mounting_depth_mm", rackType.MountingDepth) + + return nil +} + +func resourceNetboxRackTypeUpdate(d *schema.ResourceData, m interface{}) error { + api := m.(*client.NetBoxAPI) + + id, _ := strconv.ParseInt(d.Id(), 10, 64) + + model := d.Get("model").(string) + + slugValue, slugOk := d.GetOk("slug") + var slug string + // Default slug to generated slug if not given + if !slugOk { + slug = getSlug(model) + } else { + slug = slugValue.(string) + } + manufacturerID := int64(d.Get("manufacturer_id").(int)) + width := int64(d.Get("width").(int)) + uHeight := int64(d.Get("u_height").(int)) + + data := models.WritableRackTypeRequest{ + Model: &model, + Slug: &slug, + Manufacturer: &manufacturerID, + Width: &width, + UHeight: uHeight, + Description: getOptionalStr(d, "description", true), + OuterWidth: getOptionalInt(d, "outer_width"), + OuterDepth: getOptionalInt(d, "outer_depth"), + OuterUnit: getOptionalStr(d, "outer_unit", true), + Comments: getOptionalStr(d, "comments", true), + Weight: getOptionalFloat(d, "weight"), + MaxWeight: getOptionalInt(d, "max_weight"), + WeightUnit: getOptionalStr(d, "weight_unit", true), + MountingDepth: getOptionalInt(d, "mounting_depth_mm"), + } + + params := dcim.NewDcimRackTypesUpdateParams().WithID(id).WithData(&data) + + _, err := api.Dcim.DcimRackTypesUpdate(params, nil) + if err != nil { + return err + } + + return resourceNetboxRackTypeRead(d, m) +} + +func resourceNetboxRackTypeDelete(d *schema.ResourceData, m interface{}) error { + api := m.(*client.NetBoxAPI) + + id, _ := strconv.ParseInt(d.Id(), 10, 64) + params := dcim.NewDcimRackTypesDeleteParams().WithID(id) + + _, err := api.Dcim.DcimRackTypesDelete(params, nil) + if err != nil { + if errresp, ok := err.(*dcim.DcimRackTypesDeleteDefault); ok { + if errresp.Code() == 404 { + d.SetId("") + return nil + } + } + return err + } + return nil +} diff --git a/netbox/resource_netbox_rack_type_test.go b/netbox/resource_netbox_rack_type_test.go new file mode 100644 index 00000000..c4f9c6c8 --- /dev/null +++ b/netbox/resource_netbox_rack_type_test.go @@ -0,0 +1,143 @@ +package netbox + +import ( + "fmt" + "log" + "strconv" + "strings" + "testing" + + "github.com/fbreckle/go-netbox/netbox/client" + "github.com/fbreckle/go-netbox/netbox/client/dcim" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func testAccNetboxRackTypeFullDependencies(testName string) string { + return fmt.Sprintf(` +resource "netbox_manufacturer" "test" { + name = "%[1]s" +} + +resource "netbox_tag" "test_a" { + name = "%[1]sa" +}`, testName) +} + +func TestAccNetboxRackType_basic(t *testing.T) { + testSlug := "racktype_basic" + testName := testAccGetTestName(testSlug) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckRackTypeDestroy, + Steps: []resource.TestStep{ + { + Config: testAccNetboxRackTypeFullDependencies(testName) + fmt.Sprintf(` +resource "netbox_rack_type" "test" { + model = "%[1]s" + manufacturer_id = netbox_manufacturer.test.id + width = 19 + u_height = 48 + starting_unit = 1 + form_factor = "2-post-frame" + tags = ["%[1]sa"] + description = "%[1]s" + outer_width = 10 + outer_depth = 15 + outer_unit = "mm" + weight = 15 + max_weight = 20 + weight_unit = "kg" + mounting_depth_mm = 21 + comments = "%[1]scomments" +}`, testName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netbox_rack_type.test", "model", testName), + resource.TestCheckResourceAttr("netbox_rack_type.test", "description", testName), + resource.TestCheckResourceAttrPair("netbox_rack_type.test", "manufacturer_id", "netbox_manufacturer.test", "id"), + resource.TestCheckResourceAttr("netbox_rack_type.test", "width", "19"), + resource.TestCheckResourceAttr("netbox_rack_type.test", "u_height", "48"), + resource.TestCheckResourceAttr("netbox_rack_type.test", "tags.#", "1"), + resource.TestCheckResourceAttr("netbox_rack_type.test", "tags.0", testName+"a"), + resource.TestCheckResourceAttr("netbox_rack_type.test", "outer_width", "10"), + resource.TestCheckResourceAttr("netbox_rack_type.test", "outer_depth", "15"), + resource.TestCheckResourceAttr("netbox_rack_type.test", "outer_unit", "mm"), + resource.TestCheckResourceAttr("netbox_rack_type.test", "weight", "15"), + resource.TestCheckResourceAttr("netbox_rack_type.test", "max_weight", "20"), + resource.TestCheckResourceAttr("netbox_rack_type.test", "weight_unit", "kg"), + resource.TestCheckResourceAttr("netbox_rack_type.test", "comments", testName+"comments"), + resource.TestCheckResourceAttr("netbox_rack_type.test", "mounting_depth_mm", "21"), + ), + }, + { + ResourceName: "netbox_rack_type.test", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccCheckRackTypeDestroy(s *terraform.State) error { + // retrieve the connection established in Provider configuration + conn := testAccProvider.Meta().(*client.NetBoxAPI) + + // loop through the resources in state, verifying each rack + // is destroyed + for _, rs := range s.RootModule().Resources { + if rs.Type != "netbox_rack_type" { + continue + } + + // Retrieve our rack by referencing it's state ID for API lookup + stateID, _ := strconv.ParseInt(rs.Primary.ID, 10, 64) + params := dcim.NewDcimRackTypesReadParams().WithID(stateID) + _, err := conn.Dcim.DcimRackTypesRead(params, nil) + + if err == nil { + return fmt.Errorf("rack type (%s) still exists", rs.Primary.ID) + } + + if err != nil { + if errresp, ok := err.(*dcim.DcimRackTypesReadDefault); ok { + errorcode := errresp.Code() + if errorcode == 404 { + return nil + } + } + return err + } + } + return nil +} + +func init() { + resource.AddTestSweepers("netbox_rack_type", &resource.Sweeper{ + Name: "netbox_rack_type", + Dependencies: []string{}, + F: func(region string) error { + m, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("Error getting client: %s", err) + } + api := m.(*client.NetBoxAPI) + params := dcim.NewDcimRackTypesListParams() + res, err := api.Dcim.DcimRackTypesList(params, nil) + if err != nil { + return err + } + for _, RackType := range res.GetPayload().Results { + if strings.HasPrefix(*RackType.Model, testPrefix) { + deleteParams := dcim.NewDcimRackTypesDeleteParams().WithID(RackType.ID) + _, err := api.Dcim.DcimRackTypesDelete(deleteParams, nil) + if err != nil { + return err + } + log.Print("[DEBUG] Deleted a rack type") + } + } + return nil + }, + }) +} diff --git a/netbox/resource_netbox_token_test.go b/netbox/resource_netbox_token_test.go index c0d64633..3b2fbf77 100644 --- a/netbox/resource_netbox_token_test.go +++ b/netbox/resource_netbox_token_test.go @@ -23,7 +23,7 @@ func TestAccNetboxToken_basic(t *testing.T) { Config: fmt.Sprintf(` resource "netbox_user" "test" { username = "%s" - password = "abcdefghijkl" + password = "Abcdefghijkl1" } resource "netbox_token" "test_basic" { diff --git a/netbox/resource_netbox_user_test.go b/netbox/resource_netbox_user_test.go index 34efe95a..ad482bd0 100644 --- a/netbox/resource_netbox_user_test.go +++ b/netbox/resource_netbox_user_test.go @@ -22,7 +22,7 @@ func TestAccNetboxUser_basic(t *testing.T) { Config: fmt.Sprintf(` resource "netbox_user" "test_basic" { username = "%s" - password = "abcdefghijkl" + password = "Abcdefghijkl1" active = true staff = true }`, testName), @@ -56,7 +56,7 @@ resource "netbox_group" "test_group" { resource "netbox_user" "test_group" { username = "%[1]s" - password = "abcdefghijkl" + password = "Abcdefghijkl1" active = true staff = true group_ids = [netbox_group.test_group.id] diff --git a/netbox/resource_netbox_virtual_disk.go b/netbox/resource_netbox_virtual_disk.go index 44b3c653..4aab3c84 100644 --- a/netbox/resource_netbox_virtual_disk.go +++ b/netbox/resource_netbox_virtual_disk.go @@ -30,7 +30,7 @@ func resourceNetboxVirtualDisks() *schema.Resource { Type: schema.TypeString, Optional: true, }, - "size_gb": { + "size_mb": { Type: schema.TypeInt, Required: true, }, @@ -44,6 +44,14 @@ func resourceNetboxVirtualDisks() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, + SchemaVersion: 1, + StateUpgraders: []schema.StateUpgrader{ + { + Type: resourceNetboxVirtualDiskResourceV0().CoreConfigSchema().ImpliedType(), + Upgrade: resourceNetboxVirtualDiskStateUpgradeV0, + Version: 0, + }, + }, } } @@ -51,7 +59,7 @@ func resourceNetboxVirtualDisksCreate(ctx context.Context, d *schema.ResourceDat api := m.(*client.NetBoxAPI) name := d.Get("name").(string) - size := d.Get("size_gb").(int) + size := d.Get("size_mb").(int) virtualMachineID := d.Get("virtual_machine_id").(int) data := models.WritableVirtualDisk{ @@ -110,7 +118,7 @@ func resourceNetboxVirtualDisksRead(ctx context.Context, d *schema.ResourceData, d.Set("description", VirtualDisks.Description) if VirtualDisks.Size != nil { - d.Set("size_gb", *VirtualDisks.Size) + d.Set("size_mb", *VirtualDisks.Size) } if VirtualDisks.VirtualMachine != nil { d.Set("virtual_machine_id", VirtualDisks.VirtualMachine.ID) @@ -132,7 +140,7 @@ func resourceNetboxVirtualDisksUpdate(ctx context.Context, d *schema.ResourceDat data := models.WritableVirtualDisk{} name := d.Get("name").(string) - size := int64(d.Get("size_gb").(int)) + size := int64(d.Get("size_mb").(int)) virtualMachineID := int64(d.Get("virtual_machine_id").(int)) data.Name = &name diff --git a/netbox/resource_netbox_virtual_disk_migrate_v0.go b/netbox/resource_netbox_virtual_disk_migrate_v0.go new file mode 100644 index 00000000..d77c5fcf --- /dev/null +++ b/netbox/resource_netbox_virtual_disk_migrate_v0.go @@ -0,0 +1,53 @@ +package netbox + +import ( + "context" + "log" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceNetboxVirtualDiskResourceV0() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + }, + "size_mb": { + Type: schema.TypeInt, + Required: true, + }, + "virtual_machine_id": { + Type: schema.TypeInt, + Required: true, + }, + tagsKey: tagsSchema, + customFieldsKey: customFieldsSchema, + }, + } +} + +func resourceNetboxVirtualDiskStateUpgradeV0(_ context.Context, rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) { + v, ok := rawState["size_gb"].(float64) + if !ok { + log.Printf("[DEBUG] disk size before migration isnt float64: %#v\n but a %T", rawState["size_gb"], rawState["size_gb"]) + rawState["size_mb"] = float64(0) + delete(rawState, "size_gb") + return rawState, nil + } + + log.Printf("[DEBUG] disk size in GB before migration: %#v\n", rawState["size_gb"]) + + // set new disk size + rawState["size_mb"] = v * 1000 + log.Printf("[DEBUG] disk size in MB after migration: %#v\n", rawState["size_mb"]) + + delete(rawState, "size_gb") + + return rawState, nil +} diff --git a/netbox/resource_netbox_virtual_disk_test.go b/netbox/resource_netbox_virtual_disk_test.go index 77a6702b..862a51fb 100644 --- a/netbox/resource_netbox_virtual_disk_test.go +++ b/netbox/resource_netbox_virtual_disk_test.go @@ -37,7 +37,7 @@ resource "netbox_virtual_machine" "test" { resource "netbox_virtual_disk" "test" { name = "%[1]s" description = "description" - size_gb = 30 + size_mb = 30 virtual_machine_id = netbox_virtual_machine.test.id tags = [netbox_tag.tag_a.name] } @@ -60,7 +60,7 @@ resource "netbox_virtual_machine" "test" { resource "netbox_virtual_disk" "test" { name = "%[1]s_updated" description = "description updated" - size_gb = 60 + size_mb = 60 virtual_machine_id = netbox_virtual_machine.test.id tags = [netbox_tag.tag_a.name] } diff --git a/netbox/resource_netbox_virtual_machine.go b/netbox/resource_netbox_virtual_machine.go index 2d1ae4c7..1422373f 100644 --- a/netbox/resource_netbox_virtual_machine.go +++ b/netbox/resource_netbox_virtual_machine.go @@ -73,7 +73,7 @@ func resourceNetboxVirtualMachine() *schema.Resource { Type: schema.TypeFloat, Optional: true, }, - "disk_size_gb": { + "disk_size_mb": { Type: schema.TypeInt, Optional: true, Computed: true, @@ -104,13 +104,18 @@ func resourceNetboxVirtualMachine() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - SchemaVersion: 1, + SchemaVersion: 2, StateUpgraders: []schema.StateUpgrader{ { Type: resourceNetboxVirtualMachineResourceV0().CoreConfigSchema().ImpliedType(), Upgrade: resourceNetboxVirtualMachineStateUpgradeV0, Version: 0, }, + { + Type: resourceNetboxVirtualMachineResourceV1().CoreConfigSchema().ImpliedType(), + Upgrade: resourceNetboxVirtualMachineStateUpgradeV1, + Version: 1, + }, }, } } @@ -151,7 +156,7 @@ func resourceNetboxVirtualMachineCreate(ctx context.Context, d *schema.ResourceD data.Memory = &memoryMb } - diskSizeValue, ok := d.GetOk("disk_size_gb") + diskSizeValue, ok := d.GetOk("disk_size_mb") if ok { diskSize := int64(diskSizeValue.(int)) data.Disk = &diskSize @@ -308,7 +313,7 @@ func resourceNetboxVirtualMachineRead(ctx context.Context, d *schema.ResourceDat d.Set("vcpus", nil) } d.Set("memory_mb", vm.Memory) - d.Set("disk_size_gb", vm.Disk) + d.Set("disk_size_mb", vm.Disk) if vm.Status != nil { d.Set("status", vm.Status.Value) } else { @@ -381,7 +386,7 @@ func resourceNetboxVirtualMachineUpdate(ctx context.Context, d *schema.ResourceD data.Vcpus = &vcpus } - diskSizeValue, ok := d.GetOk("disk_size_gb") + diskSizeValue, ok := d.GetOk("disk_size_mb") if ok { diskSize := int64(diskSizeValue.(int)) data.Disk = &diskSize diff --git a/netbox/resource_netbox_virtual_machine_migrate_v1.go b/netbox/resource_netbox_virtual_machine_migrate_v1.go new file mode 100644 index 00000000..383b1c08 --- /dev/null +++ b/netbox/resource_netbox_virtual_machine_migrate_v1.go @@ -0,0 +1,105 @@ +package netbox + +import ( + "context" + "log" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceNetboxVirtualMachineResourceV1() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + "cluster_id": { + Type: schema.TypeInt, + Optional: true, + AtLeastOneOf: []string{"site_id", "cluster_id"}, + }, + "tenant_id": { + Type: schema.TypeInt, + Optional: true, + }, + "device_id": { + Type: schema.TypeInt, + Optional: true, + }, + "platform_id": { + Type: schema.TypeInt, + Optional: true, + }, + "role_id": { + Type: schema.TypeInt, + Optional: true, + }, + "site_id": { + Type: schema.TypeInt, + Optional: true, + AtLeastOneOf: []string{"site_id", "cluster_id"}, + }, + "comments": { + Type: schema.TypeString, + Optional: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + }, + "memory_mb": { + Type: schema.TypeInt, + Optional: true, + }, + "vcpus": { + Type: schema.TypeFloat, + Optional: true, + }, + "disk_size_gb": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Optional: true, + Default: "active", + }, + tagsKey: tagsSchema, + "primary_ipv4": { + Type: schema.TypeInt, + Computed: true, + }, + "primary_ipv6": { + Type: schema.TypeInt, + Computed: true, + }, + "local_context_data": { + Type: schema.TypeString, + Optional: true, + Description: "This is best managed through the use of `jsonencode` and a map of settings.", + }, + customFieldsKey: customFieldsSchema, + }, + } +} +func resourceNetboxVirtualMachineStateUpgradeV1(_ context.Context, rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) { + v, ok := rawState["disk_size_gb"].(float64) + if !ok { + log.Printf("[DEBUG] disk size before migration isnt float64: %#v\n but a %T", rawState["disk_size_gb"], rawState["disk_size_gb"]) + rawState["disk_size_mb"] = float64(0) + delete(rawState, "disk_size_gb") + return rawState, nil + } + + log.Printf("[DEBUG] disk size in GB before migration: %#v\n", rawState["disk_size_gb"]) + + // set new disk size + rawState["disk_size_mb"] = v * 1000 + log.Printf("[DEBUG] disk size in MB after migration: %#v\n", rawState["disk_size_mb"]) + + delete(rawState, "disk_size_gb") + + return rawState, nil +} diff --git a/netbox/resource_netbox_virtual_machine_migrate_v1_test.go b/netbox/resource_netbox_virtual_machine_migrate_v1_test.go new file mode 100644 index 00000000..bab46e31 --- /dev/null +++ b/netbox/resource_netbox_virtual_machine_migrate_v1_test.go @@ -0,0 +1,41 @@ +package netbox + +import ( + "context" + "reflect" + "testing" +) + +func TestResourceNetboxVirtualMachineStateUpgradeV1(t *testing.T) { + for _, tt := range []struct { + name string + state map[string]interface{} + expected map[string]interface{} + }{ + { + name: "Zero", + state: map[string]interface{}{"disk_size_gb": float64(0)}, + expected: map[string]interface{}{"disk_size_mb": float64(0)}, + }, + { + name: "NonZero", + state: map[string]interface{}{"disk_size_gb": float64(123)}, + expected: map[string]interface{}{"disk_size_mb": float64(123000)}, + }, + { + name: "Invalid", + state: map[string]interface{}{"disk_size_gb": "foo"}, + expected: map[string]interface{}{"disk_size_mb": float64(0)}, + }, + } { + t.Run(tt.name, func(t *testing.T) { + actual, err := resourceNetboxVirtualMachineStateUpgradeV1(context.Background(), tt.state, nil) + if err != nil { + t.Fatalf("error migrating state: %s", err) + } + if !reflect.DeepEqual(tt.expected, actual) { + t.Fatalf("\n\nexpected:\n\n%#v\n\ngot:\n\n%#v\n\n", tt.expected, actual) + } + }) + } +} diff --git a/netbox/resource_netbox_virtual_machine_test.go b/netbox/resource_netbox_virtual_machine_test.go index 4d6746bc..15c24968 100644 --- a/netbox/resource_netbox_virtual_machine_test.go +++ b/netbox/resource_netbox_virtual_machine_test.go @@ -190,7 +190,7 @@ resource "netbox_virtual_machine" "test" { comments = "thisisacomment" description = "thisisadescription" memory_mb = 1024 - disk_size_gb = 256 + disk_size_mb = 256 tenant_id = netbox_tenant.test.id role_id = netbox_device_role.test.id platform_id = netbox_platform.test.id @@ -210,7 +210,7 @@ resource "netbox_virtual_machine" "test" { resource.TestCheckResourceAttr("netbox_virtual_machine.test", "description", "thisisadescription"), resource.TestCheckResourceAttr("netbox_virtual_machine.test", "memory_mb", "1024"), resource.TestCheckResourceAttr("netbox_virtual_machine.test", "vcpus", "4"), - resource.TestCheckResourceAttr("netbox_virtual_machine.test", "disk_size_gb", "256"), + resource.TestCheckResourceAttr("netbox_virtual_machine.test", "disk_size_mb", "256"), resource.TestCheckResourceAttr("netbox_virtual_machine.test", "status", "active"), resource.TestCheckResourceAttr("netbox_virtual_machine.test", "tags.#", "1"), resource.TestCheckResourceAttr("netbox_virtual_machine.test", "tags.0", testName+"a"), @@ -224,7 +224,7 @@ resource "netbox_virtual_machine" "test" { comments = "thisisacomment" description = "thisisadescription" memory_mb = 1024 - disk_size_gb = 256 + disk_size_mb = 256 tenant_id = netbox_tenant.test.id role_id = netbox_device_role.test.id platform_id = netbox_platform.test.id @@ -242,7 +242,7 @@ resource "netbox_virtual_machine" "test" { resource.TestCheckResourceAttr("netbox_virtual_machine.test", "description", "thisisadescription"), resource.TestCheckResourceAttr("netbox_virtual_machine.test", "memory_mb", "1024"), resource.TestCheckResourceAttr("netbox_virtual_machine.test", "vcpus", "4"), - resource.TestCheckResourceAttr("netbox_virtual_machine.test", "disk_size_gb", "256"), + resource.TestCheckResourceAttr("netbox_virtual_machine.test", "disk_size_mb", "256"), resource.TestCheckResourceAttr("netbox_virtual_machine.test", "status", "active"), resource.TestCheckResourceAttr("netbox_virtual_machine.test", "tags.#", "1"), resource.TestCheckResourceAttr("netbox_virtual_machine.test", "tags.0", testName+"a"), diff --git a/netbox/resource_netbox_vlan_group.go b/netbox/resource_netbox_vlan_group.go index ddfa8488..2dac31d2 100644 --- a/netbox/resource_netbox_vlan_group.go +++ b/netbox/resource_netbox_vlan_group.go @@ -33,16 +33,6 @@ func resourceNetboxVlanGroup() *schema.Resource { Required: true, ValidateFunc: validation.StringLenBetween(1, 100), }, - "min_vid": { - Type: schema.TypeInt, - Required: true, - ValidateFunc: validation.IntBetween(1, 4093), - }, - "max_vid": { - Type: schema.TypeInt, - Required: true, - ValidateFunc: validation.IntBetween(2, 4094), - }, "scope_type": { Type: schema.TypeString, Optional: true, @@ -59,6 +49,16 @@ func resourceNetboxVlanGroup() *schema.Resource { Optional: true, Default: "", }, + "vid_ranges": { + Type: schema.TypeList, + Elem: &schema.Schema{ + Type: schema.TypeList, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + Required: true, + }, tagsKey: tagsSchema, }, Importer: &schema.ResourceImporter{ @@ -73,14 +73,21 @@ func resourceNetboxVlanGroupCreate(d *schema.ResourceData, m interface{}) error name := d.Get("name").(string) slug := d.Get("slug").(string) - minVid := int64(d.Get("min_vid").(int)) - maxVid := int64(d.Get("max_vid").(int)) description := d.Get("description").(string) + vidRanges := d.Get("vid_ranges").([]interface{}) + + var result = make([][]int64, 0) + for _, v := range vidRanges { + inner := v.([]interface{}) + pair := make([]int64, 2) + pair[0] = int64(inner[0].(int)) + pair[1] = int64(inner[1].(int)) + result = append(result, pair) + } + data.VidRanges = result data.Name = &name data.Slug = &slug - data.MinVid = minVid - data.MaxVid = maxVid data.Description = description if scopeType, ok := d.GetOk("scope_type"); ok { @@ -125,9 +132,8 @@ func resourceNetboxVlanGroupRead(d *schema.ResourceData, m interface{}) error { d.Set("name", vlanGroup.Name) d.Set("slug", vlanGroup.Slug) - d.Set("min_vid", vlanGroup.MinVid) - d.Set("max_vid", vlanGroup.MaxVid) d.Set("description", vlanGroup.Description) + d.Set("vid_ranges", vlanGroup.VidRanges) d.Set(tagsKey, getTagListFromNestedTagList(vlanGroup.Tags)) if vlanGroup.ScopeType != nil { @@ -148,14 +154,22 @@ func resourceNetboxVlanGroupUpdate(d *schema.ResourceData, m interface{}) error name := d.Get("name").(string) slug := d.Get("slug").(string) - minVid := int64(d.Get("min_vid").(int)) - maxVid := int64(d.Get("max_vid").(int)) description := d.Get("description").(string) + vidRanges := d.Get("vid_ranges").([]interface{}) + + var result = make([][]int64, 0) + for _, v := range vidRanges { + inner := v.([]interface{}) + pair := make([]int64, 2) + pair[0] = int64(inner[0].(int)) + pair[1] = int64(inner[1].(int)) + result = append(result, pair) + } + data.VidRanges = result + data.Name = &name data.Slug = &slug - data.MinVid = minVid - data.MaxVid = maxVid data.Description = description if scopeType, ok := d.GetOk("scope_type"); ok { diff --git a/netbox/resource_netbox_vlan_group_test.go b/netbox/resource_netbox_vlan_group_test.go index d9de516a..30e36318 100644 --- a/netbox/resource_netbox_vlan_group_test.go +++ b/netbox/resource_netbox_vlan_group_test.go @@ -14,7 +14,7 @@ import ( func testAccNetboxVlanGroupFullDependencies(testName string) string { return fmt.Sprintf(` resource "netbox_tag" "test" { - name = "%[1]s" + name = "%[1]s" } resource "netbox_site" "test" { @@ -26,8 +26,6 @@ resource "netbox_site" "test" { func TestAccNetboxVlanGroup_basic(t *testing.T) { testSlug := "vlan_group_basic" testName := testAccGetTestName(testSlug) - testMinVid := "777" - testMaxVid := "1777" resource.ParallelTest(t, resource.TestCase{ Providers: testAccProviders, PreCheck: func() { testAccPreCheck(t) }, @@ -35,19 +33,20 @@ func TestAccNetboxVlanGroup_basic(t *testing.T) { { Config: testAccNetboxVlanGroupFullDependencies(testName) + fmt.Sprintf(` resource "netbox_vlan_group" "test_basic" { - name = "%s" - slug = "%s" - min_vid = "%s" - max_vid = "%s" - tags = [] -}`, testName, testSlug, testMinVid, testMaxVid), + name = "%s" + slug = "%s" + vid_ranges = [[1, 2], [3, 4]] + tags = [] +}`, testName, testSlug), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("netbox_vlan_group.test_basic", "name", testName), resource.TestCheckResourceAttr("netbox_vlan_group.test_basic", "slug", testSlug), - resource.TestCheckResourceAttr("netbox_vlan_group.test_basic", "min_vid", testMinVid), - resource.TestCheckResourceAttr("netbox_vlan_group.test_basic", "max_vid", testMaxVid), resource.TestCheckResourceAttr("netbox_vlan_group.test_basic", "description", ""), resource.TestCheckResourceAttr("netbox_vlan_group.test_basic", "tags.#", "0"), + resource.TestCheckResourceAttr("netbox_vlan_group.test_basic", "vid_ranges.0.0", "1"), + resource.TestCheckResourceAttr("netbox_vlan_group.test_basic", "vid_ranges.0.1", "2"), + resource.TestCheckResourceAttr("netbox_vlan_group.test_basic", "vid_ranges.1.0", "3"), + resource.TestCheckResourceAttr("netbox_vlan_group.test_basic", "vid_ranges.1.1", "4"), ), }, { @@ -62,8 +61,6 @@ resource "netbox_vlan_group" "test_basic" { func TestAccNetboxVlanGroup_with_dependencies(t *testing.T) { testSlug := "vlan_group_with_dependencies" testName := testAccGetTestName(testSlug) - testMinVid := "777" - testMaxVid := "1777" testDescription := "Test Description" resource.ParallelTest(t, resource.TestCase{ Providers: testAccProviders, @@ -75,17 +72,14 @@ resource "netbox_vlan_group" "test_with_dependencies" { name = "%s" slug = "%s" description = "%s" - min_vid = "%s" - max_vid = "%s" scope_type = "dcim.site" scope_id = netbox_site.test.id + vid_ranges = [[1, 4094]] tags = [netbox_tag.test.name] -}`, testName, testSlug, testDescription, testMinVid, testMaxVid), +}`, testName, testSlug, testDescription), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("netbox_vlan_group.test_with_dependencies", "name", testName), resource.TestCheckResourceAttr("netbox_vlan_group.test_with_dependencies", "slug", testSlug), - resource.TestCheckResourceAttr("netbox_vlan_group.test_with_dependencies", "min_vid", testMinVid), - resource.TestCheckResourceAttr("netbox_vlan_group.test_with_dependencies", "max_vid", testMaxVid), resource.TestCheckResourceAttr("netbox_vlan_group.test_with_dependencies", "description", testDescription), resource.TestCheckResourceAttr("netbox_vlan_group.test_with_dependencies", "scope_type", "dcim.site"), resource.TestCheckResourceAttrPair("netbox_vlan_group.test_with_dependencies", "scope_id", "netbox_site.test", "id"), diff --git a/netbox/resource_netbox_vlan_test.go b/netbox/resource_netbox_vlan_test.go index 6f7fb326..c2bbe7d6 100644 --- a/netbox/resource_netbox_vlan_test.go +++ b/netbox/resource_netbox_vlan_test.go @@ -27,12 +27,11 @@ resource "netbox_site" "test" { } resource "netbox_vlan_group" "test_group" { - name = "%[1]s" - slug = "%[1]s" - min_vid = 1 - max_vid = 4094 - scope_type = "dcim.site" - scope_id = netbox_site.test.id + name = "%[1]s" + slug = "%[1]s" + scope_type = "dcim.site" + scope_id = netbox_site.test.id + vid_ranges = [[1, 4094]] } `, testName) } diff --git a/templates/index.md.tmpl b/templates/index.md.tmpl index 10dcb143..25657c07 100644 --- a/templates/index.md.tmpl +++ b/templates/index.md.tmpl @@ -16,7 +16,8 @@ Netbox often makes breaking API changes even in non-major releases. Check the ta | Netbox version | Provider version | | --------------- | ---------------- | -| v4.0.0 - 4.0.11 | v3.9.0 and up | +| v4.1.0 - 4.1.11 | v3.10.0 and up | +| v4.0.0 - 4.0.11 | v3.9.0 - 3.9.2 | | v3.7.0 - 3.7.8 | v3.8.0 - 3.8.9 | | v3.6.0 - 3.6.9 | v3.7.0 - 3.7.7 | | v3.5.1 - 3.5.9 | v3.6.x |