diff --git a/docs/data-sources/device.md b/docs/data-sources/device.md
new file mode 100644
index 00000000..91254dde
--- /dev/null
+++ b/docs/data-sources/device.md
@@ -0,0 +1,62 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "maas_device Data Source - terraform-provider-maas"
+subcategory: ""
+description: |-
+ Provides details about an existing MAAS device.
+---
+
+# maas_device (Data Source)
+
+Provides details about an existing MAAS device.
+
+## Example Usage
+
+```terraform
+resource "maas_dns_domain" "test_domain" {
+ name = "domain"
+ ttl = 3600
+ authoritative = true
+}
+
+resource "maas_device" "test_device" {
+ description = "Test description"
+ domain = "maas"
+ hostname = "test-device"
+ zone = "default"
+ network_interfaces {
+ mac_address = "12:23:45:67:89:de"
+ }
+}
+
+data "maas_device" "test_device" {
+ hostname = maas_device.test_device.hostname
+}
+```
+
+
+## Schema
+
+### Required
+
+- `hostname` (String) The device hostname.
+
+### Read-Only
+
+- `description` (String) The description of the device.
+- `domain` (String) The domain of the device.
+- `fqdn` (String) The device FQDN.
+- `id` (String) The ID of this resource.
+- `ip_addresses` (Set of String) A set of IP addressed assigned to the device.
+- `network_interfaces` (Set of Object) A set of network interfaces attached to the device. (see [below for nested schema](#nestedatt--network_interfaces))
+- `owner` (String) The owner of the device.
+- `zone` (String) The zone of the device.
+
+
+### Nested Schema for `network_interfaces`
+
+Read-Only:
+
+- `id` (Number)
+- `mac_address` (String)
+- `name` (String)
diff --git a/docs/resources/device.md b/docs/resources/device.md
new file mode 100644
index 00000000..f5efaac9
--- /dev/null
+++ b/docs/resources/device.md
@@ -0,0 +1,73 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "maas_device Resource - terraform-provider-maas"
+subcategory: ""
+description: |-
+ Provides a resource to manage MAAS devices.
+---
+
+# maas_device (Resource)
+
+Provides a resource to manage MAAS devices.
+
+## Example Usage
+
+```terraform
+resource "maas_dns_domain" "test_domain" {
+ name = "domain"
+ ttl = 3600
+ authoritative = true
+}
+
+resource "maas_device" "test_device" {
+ description = "Test description"
+ domain = maas_dns_domain.test_domain.name
+ hostname = "test-device"
+ zone = "default"
+ network_interfaces {
+ mac_address = "12:23:45:67:89:de"
+ }
+}
+```
+
+
+## Schema
+
+### Required
+
+- `network_interfaces` (Block Set, Min: 1) A set of network interfaces attached to the device. (see [below for nested schema](#nestedblock--network_interfaces))
+
+### Optional
+
+- `description` (String) The description of the device.
+- `domain` (String) The domain of the device.
+- `hostname` (String) The device hostname.
+- `zone` (String) The zone of the device.
+
+### Read-Only
+
+- `fqdn` (String) The device FQDN.
+- `id` (String) The ID of this resource.
+- `ip_addresses` (Set of String) A set of IP addressed assigned to the device.
+- `owner` (String) The owner of the device.
+
+
+### Nested Schema for `network_interfaces`
+
+Required:
+
+- `mac_address` (String) MAC address of the network interface.
+
+Read-Only:
+
+- `id` (Number) The id of the network interface.
+- `name` (String) The name of the network interface.
+
+## Import
+
+Import is supported using the following syntax:
+
+```shell
+# Devices can be imported using their ID or hostname. e.g.
+$ terraform import maas_device.test_device test-device
+```
diff --git a/examples/data-sources/maas_device/data-source.tf b/examples/data-sources/maas_device/data-source.tf
new file mode 100644
index 00000000..53eb5b53
--- /dev/null
+++ b/examples/data-sources/maas_device/data-source.tf
@@ -0,0 +1,19 @@
+resource "maas_dns_domain" "test_domain" {
+ name = "domain"
+ ttl = 3600
+ authoritative = true
+}
+
+resource "maas_device" "test_device" {
+ description = "Test description"
+ domain = "maas"
+ hostname = "test-device"
+ zone = "default"
+ network_interfaces {
+ mac_address = "12:23:45:67:89:de"
+ }
+}
+
+data "maas_device" "test_device" {
+ hostname = maas_device.test_device.hostname
+}
diff --git a/examples/resources/maas_device/import.sh b/examples/resources/maas_device/import.sh
new file mode 100644
index 00000000..3f42eeff
--- /dev/null
+++ b/examples/resources/maas_device/import.sh
@@ -0,0 +1,2 @@
+# Devices can be imported using their ID or hostname. e.g.
+$ terraform import maas_device.test_device test-device
diff --git a/examples/resources/maas_device/resource.tf b/examples/resources/maas_device/resource.tf
new file mode 100644
index 00000000..12cb4a77
--- /dev/null
+++ b/examples/resources/maas_device/resource.tf
@@ -0,0 +1,15 @@
+resource "maas_dns_domain" "test_domain" {
+ name = "domain"
+ ttl = 3600
+ authoritative = true
+}
+
+resource "maas_device" "test_device" {
+ description = "Test description"
+ domain = maas_dns_domain.test_domain.name
+ hostname = "test-device"
+ zone = "default"
+ network_interfaces {
+ mac_address = "12:23:45:67:89:de"
+ }
+}
diff --git a/maas/data_source_maas_device.go b/maas/data_source_maas_device.go
new file mode 100644
index 00000000..2e239865
--- /dev/null
+++ b/maas/data_source_maas_device.go
@@ -0,0 +1,147 @@
+package maas
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+ "github.com/maas/gomaasclient/client"
+ "github.com/maas/gomaasclient/entity"
+)
+
+func dataSourceMaasDevice() *schema.Resource {
+ return &schema.Resource{
+ Description: "Provides details about an existing MAAS device.",
+ ReadContext: dataSourceDeviceRead,
+
+ Schema: map[string]*schema.Schema{
+ "description": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The description of the device.",
+ },
+ "domain": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The domain of the device.",
+ },
+ "fqdn": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The device FQDN.",
+ },
+ "hostname": {
+ Type: schema.TypeString,
+ Required: true,
+ Description: "The device hostname.",
+ },
+ "ip_addresses": {
+ Type: schema.TypeSet,
+ Computed: true,
+ Description: "A set of IP addressed assigned to the device.",
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ },
+ },
+ "network_interfaces": {
+ Type: schema.TypeSet,
+ Computed: true,
+ Description: "A set of network interfaces attached to the device.",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "id": {
+ Type: schema.TypeInt,
+ Computed: true,
+ Description: "The id of the network interface.",
+ },
+ "mac_address": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "MAC address of the network interface.",
+ },
+ "name": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The name of the network interface.",
+ },
+ },
+ },
+ },
+ "owner": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The owner of the device.",
+ },
+ "zone": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The zone of the device.",
+ },
+ },
+ }
+}
+
+func dataSourceDeviceRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
+ client := meta.(*client.Client)
+
+ device, err := getDevice(client, d.Get("hostname").(string))
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ d.SetId(device.SystemID)
+
+ d.Set("description", device.Description)
+ d.Set("domain", device.Domain.Name)
+ d.Set("fqdn", device.FQDN)
+ d.Set("hostname", device.Hostname)
+ d.Set("owner", device.Owner)
+ d.Set("zone", device.Zone.Name)
+
+ ipAddresses := make([]string, len(device.IPAddresses))
+ for i, ip := range device.IPAddresses {
+ ipAddresses[i] = ip.String()
+ }
+ if err := d.Set("ip_addresses", ipAddresses); err != nil {
+ return diag.FromErr(err)
+ }
+
+ networkInterfaces := make([]map[string]interface{}, len(device.InterfaceSet))
+ for i, networkInterface := range device.InterfaceSet {
+ networkInterfaces[i] = map[string]interface{}{
+ "id": networkInterface.ID,
+ "mac_address": networkInterface.MACAddress,
+ "name": networkInterface.Name,
+ }
+ }
+ if err := d.Set("network_interfaces", networkInterfaces); err != nil {
+ return diag.FromErr(err)
+ }
+
+ return nil
+}
+
+func getDevice(client *client.Client, identifier string) (*entity.Device, error) {
+ device, err := findDevice(client, identifier)
+ if err != nil {
+ return nil, err
+ }
+ if device == nil {
+ return nil, fmt.Errorf("device (%s) was not found", identifier)
+ }
+ return device, nil
+}
+
+func findDevice(client *client.Client, identifier string) (*entity.Device, error) {
+ devices, err := client.Devices.Get()
+ if err != nil {
+ return nil, err
+ }
+ for _, d := range devices {
+ if d.SystemID == identifier || d.Hostname == identifier {
+ return &d, nil
+ }
+ }
+ return nil, nil
+}
diff --git a/maas/data_source_maas_device_test.go b/maas/data_source_maas_device_test.go
new file mode 100644
index 00000000..2b7fbb43
--- /dev/null
+++ b/maas/data_source_maas_device_test.go
@@ -0,0 +1,58 @@
+package maas_test
+
+import (
+ "fmt"
+ "terraform-provider-maas/maas/testutils"
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
+ "github.com/maas/gomaasclient/entity"
+)
+
+func TestAccDataSourceMaasDevice_basic(t *testing.T) {
+
+ var device entity.Device
+ description := "Test description"
+ domain := "test-data-domain"
+ hostname := "test-data-device"
+ zone := "default"
+ mac_address := "12:23:45:67:89:fa"
+
+ checks := []resource.TestCheckFunc{
+ testAccMaasDeviceCheckExists("maas_device.test", &device),
+ resource.TestCheckResourceAttr("maas_device.test", "description", description),
+ resource.TestCheckResourceAttr("maas_device.test", "domain", domain),
+ resource.TestCheckResourceAttr("maas_device.test", "fqdn", fmt.Sprintf("%s.%s", hostname, domain)),
+ resource.TestCheckResourceAttr("maas_device.test", "hostname", hostname),
+ resource.TestCheckResourceAttr("maas_device.test", "zone", zone),
+ resource.TestCheckResourceAttr("maas_device.test", "ip_addresses.#", "0"),
+ resource.TestCheckResourceAttr("maas_device.test", "network_interfaces.#", "1"),
+ resource.TestCheckResourceAttrSet("maas_device.test", "network_interfaces.0.id"),
+ resource.TestCheckResourceAttr("maas_device.test", "network_interfaces.0.mac_address", mac_address),
+ resource.TestCheckResourceAttr("maas_device.test", "network_interfaces.0.name", "eth0"),
+ resource.TestCheckResourceAttrSet("maas_device.test", "owner"),
+ }
+
+ resource.ParallelTest(t, resource.TestCase{
+ PreCheck: func() { testutils.PreCheck(t) },
+ Providers: testutils.TestAccProviders,
+ CheckDestroy: testAccCheckMaasDeviceDestroy,
+ ErrorCheck: func(err error) error { return err },
+ Steps: []resource.TestStep{
+ {
+ Config: testAccDataSourceMaasDevice(description, domain, hostname, zone, mac_address),
+ Check: resource.ComposeTestCheckFunc(checks...),
+ },
+ },
+ })
+}
+
+func testAccDataSourceMaasDevice(description string, domain string, hostname string, zone string, mac_address string) string {
+ return fmt.Sprintf(`
+%s
+
+data "maas_device" "test" {
+ hostname = maas_device.test.hostname
+}
+`, testAccMaasDevice(description, domain, hostname, zone, mac_address))
+}
diff --git a/maas/provider.go b/maas/provider.go
index 3e94eaf7..04fe2e4a 100644
--- a/maas/provider.go
+++ b/maas/provider.go
@@ -44,6 +44,7 @@ func Provider() *schema.Provider {
},
},
ResourcesMap: map[string]*schema.Resource{
+ "maas_device": resourceMaasDevice(),
"maas_instance": resourceMaasInstance(),
"maas_vm_host": resourceMaasVMHost(),
"maas_vm_host_machine": resourceMaasVMHostMachine(),
@@ -67,6 +68,7 @@ func Provider() *schema.Provider {
"maas_subnet": dataSourceMaasSubnet(),
"maas_machine": dataSourceMaasMachine(),
"maas_network_interface_physical": dataSourceMaasNetworkInterfacePhysical(),
+ "maas_device": dataSourceMaasDevice(),
},
ConfigureContextFunc: providerConfigure,
}
diff --git a/maas/provider_test.go b/maas/provider_test.go
index b8d7ea4d..7150de4f 100644
--- a/maas/provider_test.go
+++ b/maas/provider_test.go
@@ -1,17 +1,18 @@
-package maas
+package maas_test
import (
+ "terraform-provider-maas/maas"
"testing"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
func TestProvider(t *testing.T) {
- if err := Provider().InternalValidate(); err != nil {
+ if err := maas.Provider().InternalValidate(); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestProvider_impl(t *testing.T) {
- var _ *schema.Provider = Provider()
+ var _ *schema.Provider = maas.Provider()
}
diff --git a/maas/resource_maas_device.go b/maas/resource_maas_device.go
new file mode 100644
index 00000000..2a9b3def
--- /dev/null
+++ b/maas/resource_maas_device.go
@@ -0,0 +1,191 @@
+package maas
+
+import (
+ "context"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+ "github.com/maas/gomaasclient/client"
+ "github.com/maas/gomaasclient/entity"
+)
+
+func resourceMaasDevice() *schema.Resource {
+ return &schema.Resource{
+ Description: "Provides a resource to manage MAAS devices.",
+ CreateContext: resourceDeviceCreate,
+ ReadContext: resourceDeviceRead,
+ UpdateContext: resourceDeviceUpdate,
+ DeleteContext: resourceDeviceDelete,
+ Importer: &schema.ResourceImporter{
+ StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
+ client := meta.(*client.Client)
+ device, err := getDevice(client, d.Id())
+ if err != nil {
+ return nil, err
+ }
+ d.SetId(device.SystemID)
+ return []*schema.ResourceData{d}, nil
+ },
+ },
+
+ Schema: map[string]*schema.Schema{
+ "description": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "The description of the device.",
+ },
+ "domain": {
+ Type: schema.TypeString,
+ Optional: true,
+ Computed: true,
+ Description: "The domain of the device.",
+ },
+ "fqdn": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The device FQDN.",
+ },
+ "hostname": {
+ Type: schema.TypeString,
+ Optional: true,
+ ForceNew: true,
+ Description: "The device hostname.",
+ },
+ "ip_addresses": {
+ Type: schema.TypeSet,
+ Computed: true,
+ Description: "A set of IP addressed assigned to the device.",
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ },
+ },
+ "network_interfaces": {
+ Type: schema.TypeSet,
+ Required: true,
+ Description: "A set of network interfaces attached to the device.",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "id": {
+ Type: schema.TypeInt,
+ Computed: true,
+ Description: "The id of the network interface.",
+ },
+ "mac_address": {
+ Type: schema.TypeString,
+ Required: true,
+ Description: "MAC address of the network interface.",
+ },
+ "name": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The name of the network interface.",
+ },
+ },
+ },
+ },
+ "owner": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The owner of the device.",
+ },
+ "zone": {
+ Type: schema.TypeString,
+ Optional: true,
+ Computed: true,
+ Description: "The zone of the device.",
+ },
+ },
+ }
+}
+
+func expandNetworkInterfacesItems(items []interface{}) []string {
+ networkInterfacesItems := make([]string, 0)
+ for _, item := range items {
+ itemMap := item.(map[string]interface{})
+ networkInterfacesItems = append(networkInterfacesItems, itemMap["mac_address"].(string))
+ }
+ return networkInterfacesItems
+}
+
+func resourceDeviceCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
+ client := meta.(*client.Client)
+
+ deviceParams := entity.DeviceCreateParams{
+ Description: d.Get("description").(string),
+ Domain: d.Get("domain").(string),
+ Hostname: d.Get("hostname").(string),
+ MacAddresses: expandNetworkInterfacesItems(d.Get("network_interfaces").(*schema.Set).List()),
+ }
+
+ device, err := client.Devices.Create(&deviceParams)
+ if err != nil {
+ return diag.FromErr(err)
+ }
+ d.SetId(device.SystemID)
+
+ return resourceDeviceRead(ctx, d, meta)
+}
+
+func resourceDeviceUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
+ client := meta.(*client.Client)
+
+ deviceParams := entity.DeviceUpdateParams{
+ Description: d.Get("description").(string),
+ Domain: d.Get("domain").(string),
+ Hostname: d.Get("hostname").(string),
+ Zone: d.Get("zone").(string),
+ }
+
+ device, err := client.Device.Update(d.Id(), &deviceParams)
+ if err != nil {
+ return diag.FromErr(err)
+ }
+ d.SetId(device.SystemID)
+
+ return resourceDeviceRead(ctx, d, meta)
+}
+
+func resourceDeviceDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
+ client := meta.(*client.Client)
+ return diag.FromErr(client.Device.Delete(d.Id()))
+}
+
+func resourceDeviceRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
+ client := meta.(*client.Client)
+
+ device, err := getDevice(client, d.Id())
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ d.SetId(device.SystemID)
+
+ d.Set("description", device.Description)
+ d.Set("domain", device.Domain.Name)
+ d.Set("fqdn", device.FQDN)
+ d.Set("hostname", device.Hostname)
+ d.Set("owner", device.Owner)
+ d.Set("zone", device.Zone.Name)
+
+ ipAddresses := make([]string, len(device.IPAddresses))
+ for i, ip := range device.IPAddresses {
+ ipAddresses[i] = ip.String()
+ }
+ if err := d.Set("ip_addresses", ipAddresses); err != nil {
+ return diag.FromErr(err)
+ }
+
+ networkInterfaces := make([]map[string]interface{}, len(device.InterfaceSet))
+ for i, networkInterface := range device.InterfaceSet {
+ networkInterfaces[i] = map[string]interface{}{
+ "id": networkInterface.ID,
+ "mac_address": networkInterface.MACAddress,
+ "name": networkInterface.Name,
+ }
+ }
+ if err := d.Set("network_interfaces", networkInterfaces); err != nil {
+ return diag.FromErr(err)
+ }
+
+ return nil
+}
diff --git a/maas/resource_maas_device_test.go b/maas/resource_maas_device_test.go
new file mode 100644
index 00000000..ab576539
--- /dev/null
+++ b/maas/resource_maas_device_test.go
@@ -0,0 +1,148 @@
+package maas_test
+
+import (
+ "fmt"
+ "strings"
+ "terraform-provider-maas/maas/testutils"
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
+ "github.com/maas/gomaasclient/client"
+ "github.com/maas/gomaasclient/entity"
+)
+
+func TestAccResourceMaasDevice_basic(t *testing.T) {
+
+ var device entity.Device
+ description := "Test description"
+ domain := "test-domain"
+ hostname := "test-device"
+ zone := "default"
+ mac_address := "12:23:45:67:89:de"
+
+ checks := []resource.TestCheckFunc{
+ testAccMaasDeviceCheckExists("maas_device.test", &device),
+ resource.TestCheckResourceAttr("maas_device.test", "description", description),
+ resource.TestCheckResourceAttr("maas_device.test", "domain", domain),
+ resource.TestCheckResourceAttr("maas_device.test", "fqdn", fmt.Sprintf("%s.%s", hostname, domain)),
+ resource.TestCheckResourceAttr("maas_device.test", "hostname", hostname),
+ resource.TestCheckResourceAttr("maas_device.test", "zone", zone),
+ resource.TestCheckResourceAttr("maas_device.test", "ip_addresses.#", "0"),
+ resource.TestCheckResourceAttr("maas_device.test", "network_interfaces.#", "1"),
+ resource.TestCheckResourceAttrSet("maas_device.test", "network_interfaces.0.id"),
+ resource.TestCheckResourceAttr("maas_device.test", "network_interfaces.0.mac_address", mac_address),
+ resource.TestCheckResourceAttr("maas_device.test", "network_interfaces.0.name", "eth0"),
+ resource.TestCheckResourceAttrSet("maas_device.test", "owner"),
+ }
+
+ resource.ParallelTest(t, resource.TestCase{
+ PreCheck: func() { testutils.PreCheck(t) },
+ Providers: testutils.TestAccProviders,
+ CheckDestroy: testAccCheckMaasDeviceDestroy,
+ ErrorCheck: func(err error) error { return err },
+ Steps: []resource.TestStep{
+ {
+ Config: testAccMaasDevice(description, domain, hostname, zone, mac_address),
+ Check: resource.ComposeTestCheckFunc(checks...),
+ },
+ // Test import using ID
+ {
+ ResourceName: "maas_device.test",
+ ImportState: true,
+ ImportStateVerify: true,
+ },
+ // Test import using hostname
+ {
+ ResourceName: "maas_device.test",
+ ImportState: true,
+ ImportStateVerify: true,
+ ImportStateIdFunc: func(s *terraform.State) (string, error) {
+ rs, ok := s.RootModule().Resources["maas_device.test"]
+ if !ok {
+ return "", fmt.Errorf("resource not found: %s", "maas_device.test")
+ }
+
+ if rs.Primary.ID == "" {
+ return "", fmt.Errorf("resource id not set")
+ }
+ return rs.Primary.Attributes["hostname"], nil
+ },
+ },
+ },
+ })
+}
+
+func testAccMaasDeviceCheckExists(rn string, device *entity.Device) resource.TestCheckFunc {
+ return func(s *terraform.State) error {
+ rs, ok := s.RootModule().Resources[rn]
+ if !ok {
+ return fmt.Errorf("resource not found: %s\n %#v", rn, s.RootModule().Resources)
+ }
+
+ if rs.Primary.ID == "" {
+ return fmt.Errorf("resource id not set")
+ }
+
+ conn := testutils.TestAccProvider.Meta().(*client.Client)
+ gotDevice, err := conn.Device.Get(rs.Primary.ID)
+ if err != nil {
+ return fmt.Errorf("error getting device: %s", err)
+ }
+
+ *device = *gotDevice
+
+ return nil
+ }
+}
+
+func testAccMaasDevice(description string, domain string, hostname string, zone string, mac_address string) string {
+ return fmt.Sprintf(`
+resource "maas_dns_domain" "test" {
+ name = "%s"
+ ttl = 3600
+ authoritative = true
+}
+
+resource "maas_device" "test" {
+ description = "%s"
+ domain = maas_dns_domain.test.name
+ hostname = "%s"
+ zone = "%s"
+ network_interfaces {
+ mac_address = "%s"
+ }
+}
+`, domain, description, hostname, zone, mac_address)
+}
+
+func testAccCheckMaasDeviceDestroy(s *terraform.State) error {
+ // retrieve the connection established in Provider configuration
+ conn := testutils.TestAccProvider.Meta().(*client.Client)
+
+ // loop through the resources in state, verifying each maas_device
+ // is destroyed
+ for _, rs := range s.RootModule().Resources {
+ if rs.Type != "maas_device" {
+ continue
+ }
+
+ // Retrieve our maas_device by referencing it's state ID for API lookup
+ response, err := conn.Device.Get(rs.Primary.ID)
+ if err == nil {
+ if response != nil && response.SystemID == rs.Primary.ID {
+ return fmt.Errorf("MAAS Device (%s) still exists.", rs.Primary.ID)
+ }
+
+ return nil
+ }
+
+ // If the error is equivalent to 404 not found, the maas_device is destroyed.
+ // Otherwise return the error
+ if !strings.Contains(err.Error(), "404 Not Found") {
+ return err
+ }
+ }
+
+ return nil
+}
diff --git a/maas/testutils/provider.go b/maas/testutils/provider.go
new file mode 100644
index 00000000..8ca39f6b
--- /dev/null
+++ b/maas/testutils/provider.go
@@ -0,0 +1,30 @@
+package testutils
+
+import (
+ "os"
+ "terraform-provider-maas/maas"
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+)
+
+var (
+ TestAccProviders map[string]*schema.Provider
+ TestAccProvider *schema.Provider
+)
+
+func init() {
+ TestAccProvider = maas.Provider()
+ TestAccProviders = map[string]*schema.Provider{
+ "maas": TestAccProvider,
+ }
+}
+
+func PreCheck(t *testing.T) {
+ if v := os.Getenv("MAAS_API_URL"); v == "" {
+ t.Fatal("MAAS_API_URL must be set for acceptance tests")
+ }
+ if v := os.Getenv("MAAS_API_KEY"); v == "" {
+ t.Fatal("MAAS_API_KEY must be set for acceptance tests")
+ }
+}