From 820a3f130a97cb7d669ccab27e7d758c5f8821f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Nie=C3=9F?= Date: Sun, 30 Oct 2022 21:01:36 +0100 Subject: [PATCH] feat: Add netbox_dcim_site resource --- .../resources/netbox_dcim_site/resource.tf | 86 +++ netbox/dcim/resource_netbox_dcim_site.go | 495 ++++++++++++++++++ netbox/dcim/resource_netbox_dcim_site_test.go | 179 +++++++ netbox/internal/util/nested.go | 16 + netbox/internal/util/util.go | 25 + netbox/provider.go | 1 + 6 files changed, 802 insertions(+) create mode 100644 examples/resources/netbox_dcim_site/resource.tf create mode 100644 netbox/dcim/resource_netbox_dcim_site.go create mode 100644 netbox/dcim/resource_netbox_dcim_site_test.go diff --git a/examples/resources/netbox_dcim_site/resource.tf b/examples/resources/netbox_dcim_site/resource.tf new file mode 100644 index 000000000..d253d0005 --- /dev/null +++ b/examples/resources/netbox_dcim_site/resource.tf @@ -0,0 +1,86 @@ +resource "netbox_dcim_site" "site_test" { + name = "Test site" + slug = "Test site" + description = "site for testing" + + asns = [ + netbox_ipam_asn.asn_test.id, + ] + + tag { + name = "tag1" + slug = "tag1" + } + + custom_field { + name = "cf_boolean" + type = "boolean" + value = "true" + } + + custom_field { + name = "cf_date" + type = "date" + value = "2020-12-25" + } + + custom_field { + name = "cf_text" + type = "text" + value = "some text" + } + + custom_field { + name = "cf_integer" + type = "integer" + value = "10" + } + + custom_field { + name = "cf_selection" + type = "select" + value = "1" + } + + custom_field { + name = "cf_url" + type = "url" + value = "https://github.com" + } + + custom_field { + name = "cf_multi_selection" + type = "multiselect" + value = jsonencode([ + "0", + "1" + ]) + } + + custom_field { + name = "cf_json" + type = "json" + value = jsonencode({ + stringvalue = "string" + boolvalue = false + dictionary = { + numbervalue = 5 + } + }) + } + + custom_field { + name = "cf_object" + type = "object" + value = 1 + } + + custom_field { + name = "cf_multi_object" + type = "multiobject" + value = jsonencode([ + 1, + 2 + ]) + } +} diff --git a/netbox/dcim/resource_netbox_dcim_site.go b/netbox/dcim/resource_netbox_dcim_site.go new file mode 100644 index 000000000..bf2211e19 --- /dev/null +++ b/netbox/dcim/resource_netbox_dcim_site.go @@ -0,0 +1,495 @@ +package dcim + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + netboxclient "github.com/smutel/go-netbox/v3/netbox/client" + "github.com/smutel/go-netbox/v3/netbox/client/dcim" + "github.com/smutel/go-netbox/v3/netbox/models" + "github.com/smutel/terraform-provider-netbox/v4/netbox/internal/customfield" + "github.com/smutel/terraform-provider-netbox/v4/netbox/internal/requestmodifier" + "github.com/smutel/terraform-provider-netbox/v4/netbox/internal/tag" + "github.com/smutel/terraform-provider-netbox/v4/netbox/internal/util" +) + +func ResourceNetboxDcimSite() *schema.Resource { + return &schema.Resource{ + Description: "Manage a site (dcim module) within Netbox.", + CreateContext: resourceNetboxDcimSiteCreate, + ReadContext: resourceNetboxDcimSiteRead, + UpdateContext: resourceNetboxDcimSiteUpdate, + DeleteContext: resourceNetboxDcimSiteDelete, + Exists: resourceNetboxDcimSiteExists, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Schema: map[string]*schema.Schema{ + "asns": { + Type: schema.TypeSet, + Optional: true, + Description: "ASNs", + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "circuit_count": { + Type: schema.TypeInt, + Computed: true, + Description: "The number of circuits associated to this site (dcim module).", + }, + "comments": { + Type: schema.TypeString, + Optional: true, + StateFunc: util.TrimString, + Description: "Comments for this site (dcim module).", + }, + "content_type": { + Type: schema.TypeString, + Computed: true, + Description: "The content type of this site (dcim module).", + }, + "created": { + Type: schema.TypeString, + Computed: true, + Description: "Date when this site was created.", + }, + "custom_field": &customfield.CustomFieldSchema, + "description": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 100), + Description: "The description of this site (dcim module).", + }, + "device_count": { + Type: schema.TypeInt, + Computed: true, + Description: "The number of devices associated to this site (dcim module).", + }, + "facility": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 50), + Description: "Local facility ID or description.", + }, + "group_id": { + Type: schema.TypeInt, + Optional: true, + Description: "The site group for this site (dcim module).", + }, + "last_updated": { + Type: schema.TypeString, + Computed: true, + Description: "Date when this site was last updated.", + }, + "latitude": { + Type: schema.TypeFloat, + Optional: true, + Description: "GPS coordinate (latitude).", + }, + "longitude": { + Type: schema.TypeFloat, + Optional: true, + Description: "GPS coordinate (longitude)", + }, + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(1, 100), + Description: "The name of this site (dcim module).", + }, + "physical_address": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 200), + StateFunc: util.TrimString, + Description: "The physical address of this site (dcim module).", + }, + "prefix_count": { + Type: schema.TypeInt, + Computed: true, + Description: "The number of prefixes associated to this site (dcim module).", + }, + "rack_count": { + Type: schema.TypeInt, + Computed: true, + Description: "The number of racks associated to this site (dcim module).", + }, + "region_id": { + Type: schema.TypeInt, + Optional: true, + Description: "The description of this site (dcim module).", + }, + "shipping_address": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 200), + StateFunc: util.TrimString, + Description: "The shipping address of this site (dcim module).", + }, + "slug": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(1, 100), + Description: "The slug of this site (dcim module).", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Default: "active", + ValidateFunc: validation.StringInSlice([]string{"planned", "staging", "active", "decommisioning", "retired"}, false), + Description: "The status of this site. Alowed values: \"active\" (default), \"planned\", \"staging\", \"decommisioning\", \"retired\".", + }, + "tag": &tag.TagSchema, + "tenant_id": { + Type: schema.TypeInt, + Optional: true, + Description: "The tenant of this site (dcim module).", + }, + "time_zone": { + Type: schema.TypeString, + Optional: true, + Description: "Timezone this site is in.", + }, + "url": { + Type: schema.TypeString, + Computed: true, + Description: "The link to this site (dcim module).", + }, + "virtualmachine_count": { + Type: schema.TypeInt, + Computed: true, + Description: "The number of virtual machines associated to this site (dcim module).", + }, + "vlan_count": { + Type: schema.TypeInt, + Computed: true, + Description: "The number of vlans associated to this site (dcim module).", + }, + }, + } +} + +var siteRequiredFields = []string{ + "created", + "last_updated", + "asns", + "name", + "slug", + "tags", +} + +func resourceNetboxDcimSiteCreate(ctx context.Context, d *schema.ResourceData, + m interface{}) diag.Diagnostics { + client := m.(*netboxclient.NetBoxAPI) + + asns := d.Get("asns").(*schema.Set).List() + resourceCustomFields := d.Get("custom_field").(*schema.Set).List() + customFields := customfield.ConvertCustomFieldsFromTerraformToAPI(nil, resourceCustomFields) + groupID := int64(d.Get("group_id").(int)) + latitude := d.Get("latitude").(float64) + longitude := d.Get("longitude").(float64) + name := d.Get("name").(string) + regionID := int64(d.Get("region_id").(int)) + slug := d.Get("slug").(string) + tags := d.Get("tag").(*schema.Set).List() + tenantID := int64(d.Get("tenant_id").(int)) + + newResource := &models.WritableSite{ + Asns: util.ToListofInts(asns), + Comments: d.Get("comments").(string), + CustomFields: customFields, + Facility: d.Get("facility").(string), + Description: d.Get("description").(string), + Latitude: &latitude, + Longitude: &longitude, + Name: &name, + PhysicalAddress: d.Get("physical_address").(string), + ShippingAddress: d.Get("shipping_address").(string), + Slug: &slug, + Status: d.Get("status").(string), + Tags: tag.ConvertTagsToNestedTags(tags), + TimeZone: d.Get("time_zone").(string), + } + + if groupID != 0 { + newResource.Group = &groupID + } + if regionID != 0 { + newResource.Region = ®ionID + } + if tenantID != 0 { + newResource.Tenant = &tenantID + } + + resource := dcim.NewDcimSitesCreateParams().WithData(newResource) + + resourceCreated, err := client.Dcim.DcimSitesCreate(resource, nil) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(strconv.FormatInt(resourceCreated.Payload.ID, 10)) + + return resourceNetboxDcimSiteRead(ctx, d, m) +} + +func resourceNetboxDcimSiteRead(ctx context.Context, d *schema.ResourceData, + m interface{}) diag.Diagnostics { + client := m.(*netboxclient.NetBoxAPI) + + resourceID := d.Id() + params := dcim.NewDcimSitesListParams().WithID(&resourceID) + resources, err := client.Dcim.DcimSitesList(params, nil) + if err != nil { + return diag.FromErr(err) + } + + if len(resources.Payload.Results) != 1 { + d.SetId("") + return nil + } + + resource := resources.Payload.Results[0] + if err = d.Set("asns", util.ConvertNestedASNsToASNs(resource.Asns)); err != nil { + return diag.FromErr(err) + } + if err = d.Set("circuit_count", resource.CircuitCount); err != nil { + return diag.FromErr(err) + } + if err = d.Set("comments", resource.Comments); err != nil { + return diag.FromErr(err) + } + if err = d.Set("content_type", util.ConvertURIContentType(resource.URL)); err != nil { + return diag.FromErr(err) + } + if err = d.Set("created", resource.Created.String()); err != nil { + return diag.FromErr(err) + } + + resourceCustomFields := d.Get("custom_field").(*schema.Set).List() + customFields := customfield.UpdateCustomFieldsFromAPI(resourceCustomFields, resource.CustomFields) + + if err = d.Set("custom_field", customFields); err != nil { + return diag.FromErr(err) + } + if err = d.Set("description", resource.Description); err != nil { + return diag.FromErr(err) + } + if err = d.Set("device_count", resource.DeviceCount); err != nil { + return diag.FromErr(err) + } + if err = d.Set("facility", resource.Facility); err != nil { + return diag.FromErr(err) + } + if err = d.Set("group_id", util.GetNestedSiteGroupID(resource.Group)); err != nil { + return diag.FromErr(err) + } + if err = d.Set("last_updated", resource.LastUpdated.String()); err != nil { + return diag.FromErr(err) + } + if err = d.Set("latitude", resource.Latitude); err != nil { + return diag.FromErr(err) + } + if err = d.Set("longitude", resource.Longitude); err != nil { + return diag.FromErr(err) + } + if err = d.Set("name", resource.Name); err != nil { + return diag.FromErr(err) + } + if err = d.Set("physical_address", resource.PhysicalAddress); err != nil { + return diag.FromErr(err) + } + if err = d.Set("prefix_count", resource.PrefixCount); err != nil { + return diag.FromErr(err) + } + if err = d.Set("rack_count", resource.RackCount); err != nil { + return diag.FromErr(err) + } + if err = d.Set("region_id", util.GetNestedRegionID(resource.Region)); err != nil { + return diag.FromErr(err) + } + if err = d.Set("shipping_address", resource.ShippingAddress); err != nil { + return diag.FromErr(err) + } + if err = d.Set("slug", resource.Slug); err != nil { + return diag.FromErr(err) + } + if err = d.Set("status", resource.Status.Value); err != nil { + return diag.FromErr(err) + } + if err = d.Set("tag", tag.ConvertNestedTagsToTags(resource.Tags)); err != nil { + return diag.FromErr(err) + } + if err = d.Set("tenant_id", util.GetNestedTenantID(resource.Tenant)); err != nil { + return diag.FromErr(err) + } + if err = d.Set("time_zone", resource.TimeZone); err != nil { + return diag.FromErr(err) + } + if err = d.Set("url", resource.URL); err != nil { + return diag.FromErr(err) + } + if err = d.Set("virtualmachine_count", resource.VirtualmachineCount); err != nil { + return diag.FromErr(err) + } + if err = d.Set("vlan_count", resource.VlanCount); err != nil { + return diag.FromErr(err) + } + + return nil +} + +func resourceNetboxDcimSiteUpdate(ctx context.Context, d *schema.ResourceData, + m interface{}) diag.Diagnostics { + client := m.(*netboxclient.NetBoxAPI) + + resourceID, err := strconv.ParseInt(d.Id(), 10, 64) + if err != nil { + return diag.Errorf("Unable to convert ID into int64") + } + params := &models.WritableSite{} + + modifiedFields := map[string]interface{}{} + if d.HasChange("asns") { + params.Asns = util.ToListofInts(d.Get("asns").(*schema.Set).List()) + } + if d.HasChange("comments") { + comments := d.Get("comments").(string) + params.Comments = comments + modifiedFields["comments"] = comments + } + if d.HasChange("custom_field") { + stateCustomFields, resourceCustomFields := d.GetChange("custom_field") + customFields := customfield.ConvertCustomFieldsFromTerraformToAPI( + stateCustomFields.(*schema.Set).List(), resourceCustomFields.(*schema.Set).List()) + params.CustomFields = &customFields + } + if d.HasChange("description") { + description := d.Get("description").(string) + params.Description = description + modifiedFields["description"] = description + } + if d.HasChange("facility") { + facility := d.Get("facility").(string) + params.Facility = facility + modifiedFields["facility"] = facility + } + if d.HasChange("group_id") { + groupID := int64(d.Get("group_id").(int)) + params.Group = &groupID + modifiedFields["group"] = groupID + } + if d.HasChange("latitude") { + latitude := d.Get("latitude").(float64) + params.Latitude = &latitude + modifiedFields["latitude"] = latitude + } + if d.HasChange("longitude") { + longitude := d.Get("longitude").(float64) + params.Longitude = &longitude + modifiedFields["longitude"] = longitude + } + if d.HasChange("name") { + name := d.Get("name").(string) + params.Name = &name + } + if d.HasChange("physical_address") { + physicalAddress := d.Get("physical_address").(string) + params.PhysicalAddress = physicalAddress + modifiedFields["physical_address"] = physicalAddress + } + if d.HasChange("region_id") { + regionID := int64(d.Get("region_id").(int)) + params.Region = ®ionID + modifiedFields["region"] = regionID + } + if d.HasChange("status") { + params.Status = d.Get("status").(string) + } + if d.HasChange("slug") { + slug := d.Get("slug").(string) + params.Slug = &slug + } + if d.HasChange("shipping_address") { + shippingAddress := d.Get("shipping_address").(string) + params.ShippingAddress = shippingAddress + modifiedFields["shipping_address"] = shippingAddress + } + if d.HasChange("tenant_id") { + tenantID := int64(d.Get("tenant_id").(int)) + params.Tenant = &tenantID + modifiedFields["tenant"] = tenantID + } + if d.HasChange("tag") { + tags := d.Get("tag").(*schema.Set).List() + params.Tags = tag.ConvertTagsToNestedTags(tags) + } + if d.HasChange("time_zone") { + timeZone := d.Get("time_zone").(string) + params.TimeZone = timeZone + modifiedFields["time_zone"] = timeZone + } + + resource := dcim.NewDcimSitesPartialUpdateParams().WithData(params) + + resource.SetID(resourceID) + + _, err = client.Dcim.DcimSitesPartialUpdate(resource, nil, requestmodifier.NewNetboxRequestModifier(modifiedFields, siteRequiredFields)) + if err != nil { + return diag.FromErr(err) + } + + return resourceNetboxDcimSiteRead(ctx, d, m) +} + +func resourceNetboxDcimSiteDelete(ctx context.Context, d *schema.ResourceData, + m interface{}) diag.Diagnostics { + client := m.(*netboxclient.NetBoxAPI) + + resourceExists, err := resourceNetboxDcimSiteExists(d, m) + if err != nil { + return diag.FromErr(err) + } + + if !resourceExists { + return nil + } + + id, err := strconv.ParseInt(d.Id(), 10, 64) + if err != nil { + return diag.Errorf("Unable to convert ID into int64") + } + + resource := dcim.NewDcimSitesDeleteParams().WithID(id) + if _, err := client.Dcim.DcimSitesDelete(resource, nil); err != nil { + return diag.FromErr(err) + } + + return nil +} + +func resourceNetboxDcimSiteExists(d *schema.ResourceData, + m interface{}) (b bool, e error) { + client := m.(*netboxclient.NetBoxAPI) + resourceExist := false + + resourceID := d.Id() + params := dcim.NewDcimSitesListParams().WithID(&resourceID) + resources, err := client.Dcim.DcimSitesList(params, nil) + if err != nil { + return resourceExist, err + } + + for _, resource := range resources.Payload.Results { + if strconv.FormatInt(resource.ID, 10) == d.Id() { + resourceExist = true + } + } + + return resourceExist, nil +} diff --git a/netbox/dcim/resource_netbox_dcim_site_test.go b/netbox/dcim/resource_netbox_dcim_site_test.go new file mode 100644 index 000000000..50d4ae779 --- /dev/null +++ b/netbox/dcim/resource_netbox_dcim_site_test.go @@ -0,0 +1,179 @@ +package dcim_test + +import ( + "strconv" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/smutel/terraform-provider-netbox/v4/netbox/internal/util" +) + +const resourceNameNetboxDcimSite = "netbox_dcim_site.test" + +func TestAccNetboxDcimSiteMinimal(t *testing.T) { + nameSuffix := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { util.TestAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccCheckNetboxDcimSiteConfig(nameSuffix, false, false, 0), + Check: resource.ComposeTestCheckFunc( + util.TestAccResourceExists(resourceNameNetboxDcimSite), + ), + }, + { + ResourceName: resourceNameNetboxDcimSite, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccNetboxDcimSiteFull(t *testing.T) { + nameSuffix := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum) + asn := int64(acctest.RandIntRange(1, 4294967295)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { util.TestAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccCheckNetboxDcimSiteConfig(nameSuffix, true, true, asn), + Check: resource.ComposeTestCheckFunc( + util.TestAccResourceExists(resourceNameNetboxDcimSite), + ), + }, + { + ResourceName: resourceNameNetboxDcimSite, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccNetboxDcimSiteMinimalFullMinimal(t *testing.T) { + nameSuffix := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum) + asn := int64(acctest.RandIntRange(1, 4294967295)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { util.TestAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccCheckNetboxDcimSiteConfig(nameSuffix, false, false, asn), + Check: resource.ComposeTestCheckFunc( + util.TestAccResourceExists(resourceNameNetboxDcimSite), + ), + }, + { + Config: testAccCheckNetboxDcimSiteConfig(nameSuffix, true, true, asn), + Check: resource.ComposeTestCheckFunc( + util.TestAccResourceExists(resourceNameNetboxDcimSite), + ), + }, + { + Config: testAccCheckNetboxDcimSiteConfig(nameSuffix, false, true, asn), + Check: resource.ComposeTestCheckFunc( + util.TestAccResourceExists(resourceNameNetboxDcimSite), + ), + }, + { + Config: testAccCheckNetboxDcimSiteConfig(nameSuffix, false, false, asn), + Check: resource.ComposeTestCheckFunc( + util.TestAccResourceExists(resourceNameNetboxDcimSite), + ), + }, + }, + }) +} + +func testAccCheckNetboxDcimSiteConfig(nameSuffix string, resourceFull, extraResources bool, asn int64) string { + template := ` + {{ if eq .extraresources "true" }} + #resource "netbox_dcim_site_group" "test" { + # name = "test-{{ .namesuffix }}" + # slug = "test-{{ .namesuffix }}" + #} + + #resource "netbox_dcim_region" "test" { + # name = "test-{{ .namesuffix }}" + # slug = "test-{{ .namesuffix }}" + #} + + resource "netbox_ipam_rir" "test" { + name = "test-{{ .namesuffix }}" + slug = "test-{{ .namesuffix }}" + } + + resource "netbox_tenancy_tenant" "test" { + name = "test-{{ .namesuffix }}" + slug = "test-{{ .namesuffix }}" + } + + resource "netbox_ipam_asn" "test" { + asn = {{ .asn }} + rir_id = netbox_ipam_rir.test.id + } + + #resource "netbox_extras_tag" "test" { + # name = "test-{{ .namesuffix }}" + # slug = "test-{{ .namesuffix }}" + #} + {{ end }} + + resource "netbox_dcim_site" "test" { + name = "test-{{ .namesuffix }}" + slug = "test-{{ .namesuffix }}" + {{ if eq .resourcefull "true" }} + status = "planned" + description = "Test device role" + facility = "TestFaciliy1" + #group_id = netbox_dcim_site_group.test.id + #region_id = netbox_dcim_region.test.id + latitude = 12.54632 + longitude = 41.21632 + tenant_id = netbox_tenancy_tenant.test.id + # Broken in netbox < 3.3.7 + # time_zone = "Europe/Berlin" + + comments = <<-EOT + Comments for Test device role + Multiline + EOT + + physical_address = <<-EOT + multiline + physical + address + EOT + + shipping_address = <<-EOT + multiline + shipping + address + EOT + + asns = [ + netbox_ipam_asn.test.id + ] + + #tag { + # name = netbox_extras_tag.test.name + # slug = netbox_extras_tag.test.slug + #} + {{ end }} + } + ` + data := map[string]string{ + "namesuffix": nameSuffix, + "resourcefull": strconv.FormatBool(resourceFull), + "extraresources": strconv.FormatBool(extraResources), + "asn": strconv.FormatInt(asn, 10), + } + return util.RenderTemplate(template, data) +} diff --git a/netbox/internal/util/nested.go b/netbox/internal/util/nested.go index 34b4ccc49..9e395c58d 100644 --- a/netbox/internal/util/nested.go +++ b/netbox/internal/util/nested.go @@ -28,6 +28,22 @@ func GetNestedPlatformID(nested *models.NestedPlatform) *int64 { return &nested.ID } +func GetNestedRegionID(nested *models.NestedRegion) *int64 { + if nested == nil { + return nil + } + + return &nested.ID +} + +func GetNestedSiteGroupID(nested *models.NestedSiteGroup) *int64 { + if nested == nil { + return nil + } + + return &nested.ID +} + func GetNestedTenantID(nested *models.NestedTenant) *int64 { if nested == nil { return nil diff --git a/netbox/internal/util/util.go b/netbox/internal/util/util.go index 2e5acdc22..691002450 100644 --- a/netbox/internal/util/util.go +++ b/netbox/internal/util/util.go @@ -7,8 +7,21 @@ import ( "strings" "github.com/go-openapi/strfmt" + "github.com/smutel/go-netbox/v3/netbox/models" ) +func ConvertNestedASNsToASNs(asns []*models.NestedASN) []int64 { + var tfASNs []int64 + + for _, t := range asns { + asn := t.ID + + tfASNs = append(tfASNs, asn) + } + + return tfASNs +} + // Convert URL in content_type func ConvertURIContentType(uri strfmt.URI) string { uriSplit := strings.Split(uri.String(), "/") @@ -54,3 +67,15 @@ func GetLocalContextData(data interface{}) (*string, error) { jsonstring := string(localContextDataJSON) return &jsonstring, nil } + +func ToListofInts(in []interface{}) []int64 { + out := make([]int64, len(in)) + for i := range in { + out[i] = int64(in[i].(int)) + } + return out +} + +func TrimString(val interface{}) string { + return strings.TrimSpace(val.(string)) +} diff --git a/netbox/provider.go b/netbox/provider.go index 8a01896e5..fdc188493 100644 --- a/netbox/provider.go +++ b/netbox/provider.go @@ -164,6 +164,7 @@ func Provider() *schema.Provider { "netbox_dcim_manufacturer": dcim.ResourceNetboxDcimManufacturer(), "netbox_dcim_device_role": dcim.ResourceNetboxDcimDeviceRole(), "netbox_dcim_platform": dcim.ResourceNetboxDcimPlatform(), + "netbox_dcim_site": dcim.ResourceNetboxDcimSite(), "netbox_ipam_aggregate": ipam.ResourceNetboxIpamAggregate(), "netbox_ipam_asn": ipam.ResourceNetboxIpamASN(), "netbox_ipam_ip_addresses": ipam.ResourceNetboxIpamIPAddresses(),