Skip to content

Conversation

@zliang-akamai
Copy link
Member

📝 Description

Add Linode Interface data source

✔️ How to Test

TF_ACC=1 go test --tags="integration" -v ./linode/linodeinterface -run TestAccDataSourceLinodeInterface_basic

@zliang-akamai zliang-akamai requested a review from a team as a code owner November 4, 2025 07:14
@zliang-akamai zliang-akamai requested review from Copilot, jriddle-linode and lgarber-akamai and removed request for a team November 4, 2025 07:14
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements a new Linode Interface data source that allows users to query information about Linode network interfaces. The data source supports retrieving details about public, VLAN, and VPC interfaces including their IPv4/IPv6 configurations and routing information.

  • Adds comprehensive schema definitions for interface types (public, VLAN, VPC)
  • Implements data models and flattening logic for all interface configurations
  • Includes test coverage with Terraform configuration templates

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
linode/linodeinterface/tmpl/template.go Adds template function for generating basic data source test configuration
linode/linodeinterface/tmpl/datasource_basic.gotf Terraform template for testing data source with instance and interface resources
linode/linodeinterface/framework_datasource_test.go Integration test for the data source with basic functionality checks
linode/linodeinterface/framework_datasource_schema.go Schema definitions for all interface types and their nested attributes
linode/linodeinterface/framework_datasource_models.go Data models and flattening logic for converting API responses to Terraform state
linode/linodeinterface/framework_datasource.go Main data source implementation with read logic and API client interaction
linode/framework_provider.go Registers the new data source with the provider

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +346 to +378
vpcIPv6.IsPublic = types.BoolPointerValue(vpcInterface.IPv6.IsPublic)

// Flatten IPv6 SLAAC
slaac := make([]DataSourceVPCIPv6SLAACModel, len(vpcInterface.IPv6.SLAAC))
for i, s := range vpcInterface.IPv6.SLAAC {
slaac[i] = DataSourceVPCIPv6SLAACModel{
Range: cidrtypes.NewIPv6PrefixValue(s.Range),
Address: iptypes.NewIPv6AddressValue(s.Address),
}
}

slaacSet, slaacDiags := types.SetValueFrom(ctx, dataSourceVPCIPv6SLAACAttribute.Type(), slaac)
diags.Append(slaacDiags...)
if diags.HasError() {
return
}
vpcIPv6.SLAAC = slaacSet

// Flatten IPv6 ranges
ipv6Ranges := make([]DataSourceVPCIPv6RangeModel, len(vpcInterface.IPv6.Ranges))
for i, r := range vpcInterface.IPv6.Ranges {
ipv6Ranges[i] = DataSourceVPCIPv6RangeModel{
Range: cidrtypes.NewIPv6PrefixValue(r.Range),
}
}

ipv6RangesSet, ipv6RangesDiags := types.SetValueFrom(ctx, dataSourceVPCIPv6RangeAttribute.Type(), ipv6Ranges)
diags.Append(ipv6RangesDiags...)
if diags.HasError() {
return
}
vpcIPv6.Ranges = ipv6RangesSet

Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code will panic if vpcInterface.IPv6 is nil. The IPv6 field should be checked for nil before accessing its IsPublic field.

Suggested change
vpcIPv6.IsPublic = types.BoolPointerValue(vpcInterface.IPv6.IsPublic)
// Flatten IPv6 SLAAC
slaac := make([]DataSourceVPCIPv6SLAACModel, len(vpcInterface.IPv6.SLAAC))
for i, s := range vpcInterface.IPv6.SLAAC {
slaac[i] = DataSourceVPCIPv6SLAACModel{
Range: cidrtypes.NewIPv6PrefixValue(s.Range),
Address: iptypes.NewIPv6AddressValue(s.Address),
}
}
slaacSet, slaacDiags := types.SetValueFrom(ctx, dataSourceVPCIPv6SLAACAttribute.Type(), slaac)
diags.Append(slaacDiags...)
if diags.HasError() {
return
}
vpcIPv6.SLAAC = slaacSet
// Flatten IPv6 ranges
ipv6Ranges := make([]DataSourceVPCIPv6RangeModel, len(vpcInterface.IPv6.Ranges))
for i, r := range vpcInterface.IPv6.Ranges {
ipv6Ranges[i] = DataSourceVPCIPv6RangeModel{
Range: cidrtypes.NewIPv6PrefixValue(r.Range),
}
}
ipv6RangesSet, ipv6RangesDiags := types.SetValueFrom(ctx, dataSourceVPCIPv6RangeAttribute.Type(), ipv6Ranges)
diags.Append(ipv6RangesDiags...)
if diags.HasError() {
return
}
vpcIPv6.Ranges = ipv6RangesSet
if vpcInterface.IPv6 != nil {
vpcIPv6.IsPublic = types.BoolPointerValue(vpcInterface.IPv6.IsPublic)
// Flatten IPv6 SLAAC
slaac := make([]DataSourceVPCIPv6SLAACModel, len(vpcInterface.IPv6.SLAAC))
for i, s := range vpcInterface.IPv6.SLAAC {
slaac[i] = DataSourceVPCIPv6SLAACModel{
Range: cidrtypes.NewIPv6PrefixValue(s.Range),
Address: iptypes.NewIPv6AddressValue(s.Address),
}
}
slaacSet, slaacDiags := types.SetValueFrom(ctx, dataSourceVPCIPv6SLAACAttribute.Type(), slaac)
diags.Append(slaacDiags...)
if diags.HasError() {
return
}
vpcIPv6.SLAAC = slaacSet
// Flatten IPv6 ranges
ipv6Ranges := make([]DataSourceVPCIPv6RangeModel, len(vpcInterface.IPv6.Ranges))
for i, r := range vpcInterface.IPv6.Ranges {
ipv6Ranges[i] = DataSourceVPCIPv6RangeModel{
Range: cidrtypes.NewIPv6PrefixValue(r.Range),
}
}
ipv6RangesSet, ipv6RangesDiags := types.SetValueFrom(ctx, dataSourceVPCIPv6RangeAttribute.Type(), ipv6Ranges)
diags.Append(ipv6RangesDiags...)
if diags.HasError() {
return
}
vpcIPv6.Ranges = ipv6RangesSet
} else {
vpcIPv6.IsPublic = types.BoolNull()
vpcIPv6.SLAAC = types.SetNull(dataSourceVPCIPv6SLAACAttribute.Type().(types.SetType).ElemType)
vpcIPv6.Ranges = types.SetNull(dataSourceVPCIPv6RangeAttribute.Type().(types.SetType).ElemType)
}

Copilot uses AI. Check for mistakes.
Comment on lines +307 to +308
addresses := make([]DataSourceVPCIPv4AddressModel, len(vpcInterface.IPv4.Addresses))
for i, addr := range vpcInterface.IPv4.Addresses {
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code will panic if vpcInterface.IPv4 is nil. The IPv4 field should be checked for nil before accessing its Addresses field.

Copilot uses AI. Check for mistakes.
Comment on lines +324 to +325
ranges := make([]DataSourceVPCIPv4RangeModel, len(vpcInterface.IPv4.Ranges))
for i, r := range vpcInterface.IPv4.Ranges {
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code will panic if vpcInterface.IPv4 is nil. The IPv4 field should be checked for nil before accessing its Ranges field.

Copilot uses AI. Check for mistakes.
Comment on lines +346 to +378
vpcIPv6.IsPublic = types.BoolPointerValue(vpcInterface.IPv6.IsPublic)

// Flatten IPv6 SLAAC
slaac := make([]DataSourceVPCIPv6SLAACModel, len(vpcInterface.IPv6.SLAAC))
for i, s := range vpcInterface.IPv6.SLAAC {
slaac[i] = DataSourceVPCIPv6SLAACModel{
Range: cidrtypes.NewIPv6PrefixValue(s.Range),
Address: iptypes.NewIPv6AddressValue(s.Address),
}
}

slaacSet, slaacDiags := types.SetValueFrom(ctx, dataSourceVPCIPv6SLAACAttribute.Type(), slaac)
diags.Append(slaacDiags...)
if diags.HasError() {
return
}
vpcIPv6.SLAAC = slaacSet

// Flatten IPv6 ranges
ipv6Ranges := make([]DataSourceVPCIPv6RangeModel, len(vpcInterface.IPv6.Ranges))
for i, r := range vpcInterface.IPv6.Ranges {
ipv6Ranges[i] = DataSourceVPCIPv6RangeModel{
Range: cidrtypes.NewIPv6PrefixValue(r.Range),
}
}

ipv6RangesSet, ipv6RangesDiags := types.SetValueFrom(ctx, dataSourceVPCIPv6RangeAttribute.Type(), ipv6Ranges)
diags.Append(ipv6RangesDiags...)
if diags.HasError() {
return
}
vpcIPv6.Ranges = ipv6RangesSet

Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code will panic if vpcInterface.IPv6 is nil. The IPv6 field should be checked for nil before accessing its SLAAC field.

Suggested change
vpcIPv6.IsPublic = types.BoolPointerValue(vpcInterface.IPv6.IsPublic)
// Flatten IPv6 SLAAC
slaac := make([]DataSourceVPCIPv6SLAACModel, len(vpcInterface.IPv6.SLAAC))
for i, s := range vpcInterface.IPv6.SLAAC {
slaac[i] = DataSourceVPCIPv6SLAACModel{
Range: cidrtypes.NewIPv6PrefixValue(s.Range),
Address: iptypes.NewIPv6AddressValue(s.Address),
}
}
slaacSet, slaacDiags := types.SetValueFrom(ctx, dataSourceVPCIPv6SLAACAttribute.Type(), slaac)
diags.Append(slaacDiags...)
if diags.HasError() {
return
}
vpcIPv6.SLAAC = slaacSet
// Flatten IPv6 ranges
ipv6Ranges := make([]DataSourceVPCIPv6RangeModel, len(vpcInterface.IPv6.Ranges))
for i, r := range vpcInterface.IPv6.Ranges {
ipv6Ranges[i] = DataSourceVPCIPv6RangeModel{
Range: cidrtypes.NewIPv6PrefixValue(r.Range),
}
}
ipv6RangesSet, ipv6RangesDiags := types.SetValueFrom(ctx, dataSourceVPCIPv6RangeAttribute.Type(), ipv6Ranges)
diags.Append(ipv6RangesDiags...)
if diags.HasError() {
return
}
vpcIPv6.Ranges = ipv6RangesSet
if vpcInterface.IPv6 != nil {
vpcIPv6.IsPublic = types.BoolPointerValue(vpcInterface.IPv6.IsPublic)
// Flatten IPv6 SLAAC
slaac := make([]DataSourceVPCIPv6SLAACModel, len(vpcInterface.IPv6.SLAAC))
for i, s := range vpcInterface.IPv6.SLAAC {
slaac[i] = DataSourceVPCIPv6SLAACModel{
Range: cidrtypes.NewIPv6PrefixValue(s.Range),
Address: iptypes.NewIPv6AddressValue(s.Address),
}
}
slaacSet, slaacDiags := types.SetValueFrom(ctx, dataSourceVPCIPv6SLAACAttribute.Type(), slaac)
diags.Append(slaacDiags...)
if diags.HasError() {
return
}
vpcIPv6.SLAAC = slaacSet
// Flatten IPv6 ranges
ipv6Ranges := make([]DataSourceVPCIPv6RangeModel, len(vpcInterface.IPv6.Ranges))
for i, r := range vpcInterface.IPv6.Ranges {
ipv6Ranges[i] = DataSourceVPCIPv6RangeModel{
Range: cidrtypes.NewIPv6PrefixValue(r.Range),
}
}
ipv6RangesSet, ipv6RangesDiags := types.SetValueFrom(ctx, dataSourceVPCIPv6RangeAttribute.Type(), ipv6Ranges)
diags.Append(ipv6RangesDiags...)
if diags.HasError() {
return
}
vpcIPv6.Ranges = ipv6RangesSet
} else {
vpcIPv6.IsPublic = types.BoolNull()
// Set SLAAC to empty set
slaacSet, slaacDiags := types.SetValueFrom(ctx, dataSourceVPCIPv6SLAACAttribute.Type(), []DataSourceVPCIPv6SLAACModel{})
diags.Append(slaacDiags...)
if diags.HasError() {
return
}
vpcIPv6.SLAAC = slaacSet
// Set Ranges to empty set
ipv6RangesSet, ipv6RangesDiags := types.SetValueFrom(ctx, dataSourceVPCIPv6RangeAttribute.Type(), []DataSourceVPCIPv6RangeModel{})
diags.Append(ipv6RangesDiags...)
if diags.HasError() {
return
}
vpcIPv6.Ranges = ipv6RangesSet
}

Copilot uses AI. Check for mistakes.
Comment on lines +346 to +377
vpcIPv6.IsPublic = types.BoolPointerValue(vpcInterface.IPv6.IsPublic)

// Flatten IPv6 SLAAC
slaac := make([]DataSourceVPCIPv6SLAACModel, len(vpcInterface.IPv6.SLAAC))
for i, s := range vpcInterface.IPv6.SLAAC {
slaac[i] = DataSourceVPCIPv6SLAACModel{
Range: cidrtypes.NewIPv6PrefixValue(s.Range),
Address: iptypes.NewIPv6AddressValue(s.Address),
}
}

slaacSet, slaacDiags := types.SetValueFrom(ctx, dataSourceVPCIPv6SLAACAttribute.Type(), slaac)
diags.Append(slaacDiags...)
if diags.HasError() {
return
}
vpcIPv6.SLAAC = slaacSet

// Flatten IPv6 ranges
ipv6Ranges := make([]DataSourceVPCIPv6RangeModel, len(vpcInterface.IPv6.Ranges))
for i, r := range vpcInterface.IPv6.Ranges {
ipv6Ranges[i] = DataSourceVPCIPv6RangeModel{
Range: cidrtypes.NewIPv6PrefixValue(r.Range),
}
}

ipv6RangesSet, ipv6RangesDiags := types.SetValueFrom(ctx, dataSourceVPCIPv6RangeAttribute.Type(), ipv6Ranges)
diags.Append(ipv6RangesDiags...)
if diags.HasError() {
return
}
vpcIPv6.Ranges = ipv6RangesSet
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code will panic if vpcInterface.IPv6 is nil. The IPv6 field should be checked for nil before accessing its Ranges field.

Suggested change
vpcIPv6.IsPublic = types.BoolPointerValue(vpcInterface.IPv6.IsPublic)
// Flatten IPv6 SLAAC
slaac := make([]DataSourceVPCIPv6SLAACModel, len(vpcInterface.IPv6.SLAAC))
for i, s := range vpcInterface.IPv6.SLAAC {
slaac[i] = DataSourceVPCIPv6SLAACModel{
Range: cidrtypes.NewIPv6PrefixValue(s.Range),
Address: iptypes.NewIPv6AddressValue(s.Address),
}
}
slaacSet, slaacDiags := types.SetValueFrom(ctx, dataSourceVPCIPv6SLAACAttribute.Type(), slaac)
diags.Append(slaacDiags...)
if diags.HasError() {
return
}
vpcIPv6.SLAAC = slaacSet
// Flatten IPv6 ranges
ipv6Ranges := make([]DataSourceVPCIPv6RangeModel, len(vpcInterface.IPv6.Ranges))
for i, r := range vpcInterface.IPv6.Ranges {
ipv6Ranges[i] = DataSourceVPCIPv6RangeModel{
Range: cidrtypes.NewIPv6PrefixValue(r.Range),
}
}
ipv6RangesSet, ipv6RangesDiags := types.SetValueFrom(ctx, dataSourceVPCIPv6RangeAttribute.Type(), ipv6Ranges)
diags.Append(ipv6RangesDiags...)
if diags.HasError() {
return
}
vpcIPv6.Ranges = ipv6RangesSet
if vpcInterface.IPv6 != nil {
vpcIPv6.IsPublic = types.BoolPointerValue(vpcInterface.IPv6.IsPublic)
// Flatten IPv6 SLAAC
slaac := make([]DataSourceVPCIPv6SLAACModel, len(vpcInterface.IPv6.SLAAC))
for i, s := range vpcInterface.IPv6.SLAAC {
slaac[i] = DataSourceVPCIPv6SLAACModel{
Range: cidrtypes.NewIPv6PrefixValue(s.Range),
Address: iptypes.NewIPv6AddressValue(s.Address),
}
}
slaacSet, slaacDiags := types.SetValueFrom(ctx, dataSourceVPCIPv6SLAACAttribute.Type(), slaac)
diags.Append(slaacDiags...)
if diags.HasError() {
return
}
vpcIPv6.SLAAC = slaacSet
// Flatten IPv6 ranges
ipv6Ranges := make([]DataSourceVPCIPv6RangeModel, len(vpcInterface.IPv6.Ranges))
for i, r := range vpcInterface.IPv6.Ranges {
ipv6Ranges[i] = DataSourceVPCIPv6RangeModel{
Range: cidrtypes.NewIPv6PrefixValue(r.Range),
}
}
ipv6RangesSet, ipv6RangesDiags := types.SetValueFrom(ctx, dataSourceVPCIPv6RangeAttribute.Type(), ipv6Ranges)
diags.Append(ipv6RangesDiags...)
if diags.HasError() {
return
}
vpcIPv6.Ranges = ipv6RangesSet
} else {
vpcIPv6.IsPublic = types.BoolPointerValue(nil)
// Set empty sets for SLAAC and Ranges if IPv6 is nil
slaacSet, slaacDiags := types.SetValueFrom(ctx, dataSourceVPCIPv6SLAACAttribute.Type(), []DataSourceVPCIPv6SLAACModel{})
diags.Append(slaacDiags...)
if diags.HasError() {
return
}
vpcIPv6.SLAAC = slaacSet
ipv6RangesSet, ipv6RangesDiags := types.SetValueFrom(ctx, dataSourceVPCIPv6RangeAttribute.Type(), []DataSourceVPCIPv6RangeModel{})
diags.Append(ipv6RangesDiags...)
if diags.HasError() {
return
}
vpcIPv6.Ranges = ipv6RangesSet
}

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant