Skip to content

Commit

Permalink
Implement peer group datasource
Browse files Browse the repository at this point in the history
  • Loading branch information
mraerino committed Sep 29, 2024
1 parent e189ac7 commit 6bb043e
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 6 deletions.
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (
github.com/oapi-codegen/oapi-codegen/v2 v2.3.0
github.com/oapi-codegen/runtime v1.1.1
github.com/sethvargo/go-envconfig v1.1.0
github.com/stretchr/testify v1.9.0
golang.org/x/tools v0.23.0
)

Expand All @@ -30,6 +31,7 @@ require (
github.com/bgentry/speakeasy v0.1.0 // indirect
github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect
github.com/cloudflare/circl v1.3.7 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.16.0 // indirect
github.com/getkin/kin-openapi v0.124.0 // indirect
github.com/go-openapi/jsonpointer v0.20.2 // indirect
Expand Down Expand Up @@ -71,6 +73,7 @@ require (
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/oklog/run v1.0.0 // indirect
github.com/perimeterx/marshmallow v1.1.5 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/posener/complete v1.2.3 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/spf13/cast v1.5.0 // indirect
Expand Down
6 changes: 0 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -244,17 +244,13 @@ golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/
golang.org/x/exp v0.0.0-20230809150735-7b3493d9a819 h1:EDuYyU/MkFXllv9QF9819VlI9a4tzGuCbhG0ExK9o1U=
golang.org/x/exp v0.0.0-20230809150735-7b3493d9a819/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down Expand Up @@ -291,8 +287,6 @@ golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
113 changes: 113 additions & 0 deletions internal/provider/peergroup_datasource.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package provider

import (
"context"
"fmt"

"github.com/ffddorf/terraform-provider-netbox-bgp/client"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
)

var _ datasource.DataSource = &SessionDataSource{}

func NewPeerGroupDataSource() datasource.DataSource {
return &PeerGroupDataSource{}
}

type PeerGroupDataSource struct {
client *client.Client
}

type PeerGroupDataSourceModel struct {
ID types.Int64 `tfsdk:"id"`
Name types.String `tfsdk:"name"`
Description types.String `tfsdk:"description"`
Comments types.String `tfsdk:"comments"`
ExportPolicyIDs []types.Int64 `tfsdk:"export_policy_ids"`
ImportPolicyIDs []types.Int64 `tfsdk:"import_policy_ids"`
}

func (pgm *PeerGroupDataSourceModel) FillFromAPIModel(resp *client.BGPPeerGroup) {
pgm.ID = maybeInt64Value(resp.Id)
pgm.Name = maybeStringValue(&resp.Name)
pgm.Description = maybeStringValue(&resp.Description)
pgm.Comments = maybeStringValue(resp.Comments)

if resp.ExportPolicies != nil {
for _, id := range *resp.ExportPolicies {
pgm.ExportPolicyIDs = append(pgm.ExportPolicyIDs, types.Int64Value(int64(id)))
}
}
if resp.ImportPolicies != nil && len(*resp.ImportPolicies) > 0 {
for _, id := range *resp.ImportPolicies {
pgm.ImportPolicyIDs = append(pgm.ImportPolicyIDs, types.Int64Value(int64(id)))
}
}
}

func (pgd *PeerGroupDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_peergroup"
}

func (pgd *PeerGroupDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
pgd.client = configureDataSourceClient(req, resp)
}

var peerGroupDataSchema = map[string]schema.Attribute{
"id": schema.Int64Attribute{
MarkdownDescription: "ID of the resource in Netbox to use for lookup",
Required: true,
},
"name": schema.StringAttribute{
Computed: true,
},
"description": schema.StringAttribute{
Computed: true,
},
"comments": schema.StringAttribute{
Computed: true,
},
"import_policy_ids": schema.ListAttribute{
ElementType: types.Int64Type,
Computed: true,
},
"export_policy_ids": schema.ListAttribute{
ElementType: types.Int64Type,
Computed: true,
},
}

func (pgd *PeerGroupDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
MarkdownDescription: "BGP peer group data source",
Attributes: peerGroupDataSchema,
}
}

func (pgd *PeerGroupDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data PeerGroupDataSourceModel

// Read Terraform configuration data into the model
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)

httpRes, err := pgd.client.PluginsBgpBgppeergroupRetrieve(ctx, int(data.ID.ValueInt64()))
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("failed to retrieve session: %s", err))
return
}
res, err := client.ParsePluginsBgpBgppeergroupRetrieveResponse(httpRes)
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("failed to parse session: %s", err))
return
}
if res.JSON200 == nil {
resp.Diagnostics.AddError("Client Error", httpError(httpRes, res.Body))
return
}

data.FillFromAPIModel(res.JSON200)

resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}
55 changes: 55 additions & 0 deletions internal/provider/peergroup_datasource_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package provider

import (
"context"
"fmt"
"strconv"
"testing"

"github.com/ffddorf/terraform-provider-netbox-bgp/client"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/stretchr/testify/require"
)

func TestAccPeerGroupDataSource(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)

c := testClient(t)
comments := "This will be great!"
r, err := c.PluginsBgpBgppeergroupCreate(ctx, client.BGPPeerGroupRequest{
Name: "Example Peer Group",
Description: "For testing",
Comments: &comments,
})
require.NoError(t, err)
pg, err := client.ParsePluginsBgpBgppeergroupCreateResponse(r)
require.NoError(t, err)
require.NotNil(t, pg.JSON201, "bad API response: %d", r.StatusCode)

peerGroupID := *pg.JSON201.Id
t.Cleanup(func() {
_, _ = c.PluginsBgpBgppeergroupDestroy(ctx, peerGroupID)
})

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
ExternalProviders: testExternalProviders,
Steps: []resource.TestStep{
// Read testing
{
Config: fmt.Sprintf(`
data "netboxbgp_peergroup" "test" {
id = %d
}
`, peerGroupID),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.netboxbgp_peergroup.test", "id", strconv.Itoa(peerGroupID)),
resource.TestCheckResourceAttr("data.netboxbgp_peergroup.test", "name", "Example Peer Group"),
resource.TestCheckResourceAttr("data.netboxbgp_peergroup.test", "description", "For testing"),
),
},
},
})
}
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ func (p *NetboxBGPProvider) DataSources(ctx context.Context) []func() datasource
return []func() datasource.DataSource{
NewSessionDataSource,
NewSessionsDataSource,
NewPeerGroupDataSource,
}
}

Expand Down
18 changes: 18 additions & 0 deletions internal/provider/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
package provider

import (
"os"
"testing"

"github.com/ffddorf/terraform-provider-netbox-bgp/client"
"github.com/hashicorp/terraform-plugin-framework/providerserver"
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
"github.com/stretchr/testify/require"
)

// testAccProtoV6ProviderFactories are used to instantiate a provider during
Expand All @@ -23,3 +26,18 @@ func testAccPreCheck(t *testing.T) {
// about the appropriate environment variables being set are common to see in a pre-check
// function.
}

func testClient(t *testing.T) *client.Client {
serverURL, ok := os.LookupEnv("NETBOX_SERVER_URL")
require.True(t, ok, "missing NETBOX_SERVER_URL")
apiToken, ok := os.LookupEnv("NETBOX_API_TOKEN")
require.True(t, ok, "missing NETBOX_API_TOKEN")

opts := []client.ClientOption{
client.WithRequestEditorFn(apiKeyAuth(apiToken)), // auth
}
client, err := client.NewClient(serverURL, opts...)
require.NoError(t, err)

return client
}

0 comments on commit 6bb043e

Please sign in to comment.