Skip to content

Commit

Permalink
Add session data source
Browse files Browse the repository at this point in the history
  • Loading branch information
mraerino committed Jul 20, 2024
1 parent e3a288f commit eb68ba1
Show file tree
Hide file tree
Showing 4 changed files with 572 additions and 1 deletion.
220 changes: 220 additions & 0 deletions internal/provider/bgpsession_datasource.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
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/diag"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/types"
)

// Ensure provider defined types fully satisfy framework interfaces.
var _ datasource.DataSource = &SessionDataSource{}

func NewSessionDataSource() datasource.DataSource {
return &SessionDataSource{}
}

type SessionDataSource struct {
client *client.Client
}

type SessionDataSourceModel struct {
ID types.Int64 `tfsdk:"id"`
Name types.String `tfsdk:"name"`
Description types.String `tfsdk:"description"`
Comments types.String `tfsdk:"comments"`
Status types.String `tfsdk:"status"`

Site NestedSite `tfsdk:"site"`
Tenant NestedTenant `tfsdk:"tenant"`
Device NestedDevice `tfsdk:"device"`

LocalAddress NestedIPAddress `tfsdk:"local_address"`
RemoteAddress NestedIPAddress `tfsdk:"remote_address"`
LocalAS NestedASN `tfsdk:"local_as"`
RemoteAS NestedASN `tfsdk:"remote_as"`
PeerGroup NestedBGPPeerGroup `tfsdk:"peer_group"`

ImportPolicyIDs types.List `tfsdk:"import_policy_ids"`
ExportPolicyIDs types.List `tfsdk:"export_policy_ids"`

PrefixListIn NestedPrefixList `tfsdk:"prefix_list_in"`
PrefixListOut NestedPrefixList `tfsdk:"prefix_list_out"`

Tags types.List `tfsdk:"tags"`
}

func (m *SessionDataSourceModel) FillFromAPIModel(ctx context.Context, resp *client.BGPSession, diags diag.Diagnostics) {
if resp.Id != nil {
m.ID = types.Int64Value(int64(*resp.Id))
}
if resp.Comments != nil && *resp.Comments != "" {
m.Comments = types.StringPointerValue(resp.Comments)
}
if resp.Description != nil && *resp.Description != "" {
m.Description = types.StringPointerValue(resp.Description)
}
m.Device.FillFromAPI(resp.Device)
if resp.ExportPolicies != nil && len(*resp.ExportPolicies) > 0 {
var ds diag.Diagnostics
m.ExportPolicyIDs, ds = types.ListValueFrom(ctx, types.Int64Type, resp.ExportPolicies)
for _, d := range ds {
diags.Append(diag.WithPath(path.Root("export_policy_ids"), d))
}
}
if resp.ImportPolicies != nil && len(*resp.ImportPolicies) > 0 {
var ds diag.Diagnostics
m.ImportPolicyIDs, ds = types.ListValueFrom(ctx, types.Int64Type, resp.ImportPolicies)
for _, d := range ds {
diags.Append(diag.WithPath(path.Root("import_policy_ids"), d))
}
}
m.LocalAddress.FillFromAPI(&resp.LocalAddress)
m.LocalAS.FillFromAPI(&resp.LocalAs)
if resp.Name != nil {
m.Name = types.StringPointerValue(resp.Name)
}
m.PeerGroup.FillFromAPI(resp.PeerGroup)
m.PrefixListIn.FillFromAPI(resp.PrefixListIn)
m.PrefixListOut.FillFromAPI(resp.PrefixListOut)
m.RemoteAddress.FillFromAPI(&resp.RemoteAddress)
m.RemoteAS.FillFromAPI(&resp.RemoteAs)
m.Site.FillFromAPI(resp.Site)
if resp.Status != nil {
m.Status = types.StringPointerValue((*string)(resp.Status.Value))
}
m.Tenant.FillFromAPI(resp.Tenant)

m.Tags = TagsFromAPI(ctx, resp.Tags, diags)

// todo: custom fields
}

func (d *SessionDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_session"
}

func (d *SessionDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
MarkdownDescription: "BGP Session data source",

Attributes: 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,
},
"status": schema.StringAttribute{
Computed: true,
MarkdownDescription: `One of: "active", "failed", "offline", "planned"`,
},
"site": schema.SingleNestedAttribute{
Computed: true,
Attributes: (*NestedSite)(nil).SchemaAttributes(),
},
"tenant": schema.SingleNestedAttribute{
Computed: true,
Attributes: (*NestedTenant)(nil).SchemaAttributes(),
},
"device": schema.SingleNestedAttribute{
Computed: true,
Attributes: (*NestedDevice)(nil).SchemaAttributes(),
},
"local_address": schema.SingleNestedAttribute{
Computed: true,
Attributes: (*NestedIPAddress)(nil).SchemaAttributes(),
},
"remote_address": schema.SingleNestedAttribute{
Computed: true,
Attributes: (*NestedIPAddress)(nil).SchemaAttributes(),
},
"local_as": schema.SingleNestedAttribute{
Computed: true,
Attributes: (*NestedASN)(nil).SchemaAttributes(),
},
"remote_as": schema.SingleNestedAttribute{
Computed: true,
Attributes: (*NestedASN)(nil).SchemaAttributes(),
},
"peer_group": schema.SingleNestedAttribute{
Computed: true,
Attributes: (*NestedBGPPeerGroup)(nil).SchemaAttributes(),
},
"import_policy_ids": schema.ListAttribute{
ElementType: types.Int64Type,
Computed: true,
},
"export_policy_ids": schema.ListAttribute{
ElementType: types.Int64Type,
Computed: true,
},
"prefix_list_in": schema.SingleNestedAttribute{
Computed: true,
Attributes: (*NestedPrefixList)(nil).SchemaAttributes(),
},
"prefix_list_out": schema.SingleNestedAttribute{
Computed: true,
Attributes: (*NestedPrefixList)(nil).SchemaAttributes(),
},
TagFieldName: TagSchema,
},
}
}

func (d *SessionDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
// Prevent panic if the provider has not been configured.
if req.ProviderData == nil {
return
}

data, ok := req.ProviderData.(*configuredProvider)
if !ok {
resp.Diagnostics.AddError(
"Unexpected Resource Configure Type",
fmt.Sprintf("Expected *configuredProvider, got: %T. Please report this issue to the provider developers.", req.ProviderData),
)
return
}

d.client = data.Client
}

func (d *SessionDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data SessionDataSourceModel

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

httpRes, err := d.client.PluginsBgpBgpsessionRetrieve(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.ParsePluginsBgpSessionRetrieveResponse(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(ctx, res.JSON200, resp.Diagnostics)
if resp.Diagnostics.HasError() {
return
}
}
Loading

0 comments on commit eb68ba1

Please sign in to comment.