Skip to content

Commit e4bd93a

Browse files
project: VPC Dual Stack (#782)
* project: VPC Dual Stack Implement support for VPC Dual Stack (#706) Add support for /vpcs/ipv6s and /vpcs/{id}/ipv6s (#791) * Remove .DS_Store * Re-run final fixtures * VPC Dual Stack: Add documentation and LA notices (#806) * Add missing VPC Dual Stack docs and LA notices * Fix spacing
1 parent 923cc42 commit e4bd93a

File tree

152 files changed

+32013
-22984
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

152 files changed

+32013
-22984
lines changed

client.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -892,6 +892,18 @@ func copyString(sPtr *string) *string {
892892
return &t
893893
}
894894

895+
// copyValue returns a pointer to a new value copied from the value
896+
// at the given pointer.
897+
func copyValue[T any](ptr *T) *T {
898+
if ptr == nil {
899+
return nil
900+
}
901+
902+
t := *ptr
903+
904+
return &t
905+
}
906+
895907
func copyTime(tPtr *time.Time) *time.Time {
896908
if tPtr == nil {
897909
return nil

helpers_iterator.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package linodego
2+
3+
import (
4+
"iter"
5+
"slices"
6+
)
7+
8+
// mapIter returns a new iterator of the values in the given iterator transformed using the given transform function.
9+
func mapIter[I, O any](values iter.Seq[I], transform func(I) O) iter.Seq[O] {
10+
return func(yield func(O) bool) {
11+
for value := range values {
12+
if !yield(transform(value)) {
13+
return
14+
}
15+
}
16+
}
17+
}
18+
19+
// mapSlice returns a new slice of the values in the given slice transformed using the given transform function.
20+
func mapSlice[I, O any](values []I, transform func(I) O) []O {
21+
return slices.Collect(mapIter(slices.Values(values), transform))
22+
}

instance_config_interfaces.go

Lines changed: 143 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,33 @@ type InstanceConfigInterface struct {
1515
VPCID *int `json:"vpc_id"`
1616
SubnetID *int `json:"subnet_id"`
1717
IPv4 *VPCIPv4 `json:"ipv4"`
18-
IPRanges []string `json:"ip_ranges"`
18+
19+
// NOTE: IPv6 interfaces may not currently be available to all users.
20+
IPv6 *InstanceConfigInterfaceIPv6 `json:"ipv6"`
21+
22+
IPRanges []string `json:"ip_ranges"`
23+
}
24+
25+
// InstanceConfigInterfaceIPv6 represents the IPv6 configuration of a Linode interface.
26+
// NOTE: IPv6 interfaces may not currently be available to all users.
27+
type InstanceConfigInterfaceIPv6 struct {
28+
SLAAC []InstanceConfigInterfaceIPv6SLAAC `json:"slaac"`
29+
Ranges []InstanceConfigInterfaceIPv6Range `json:"ranges"`
30+
IsPublic bool `json:"is_public"`
31+
}
32+
33+
// InstanceConfigInterfaceIPv6SLAAC represents a single IPv6 SLAAC under
34+
// a Linode interface.
35+
// NOTE: IPv6 interfaces may not currently be available to all users.
36+
type InstanceConfigInterfaceIPv6SLAAC struct {
37+
Range string `json:"range"`
38+
Address string `json:"address"`
39+
}
40+
41+
// InstanceConfigInterfaceIPv6Range represents a single IPv6 range under a Linode interface.
42+
// NOTE: IPv6 interfaces may not currently be available to all users.
43+
type InstanceConfigInterfaceIPv6Range struct {
44+
Range string `json:"range"`
1945
}
2046

2147
type VPCIPv4 struct {
@@ -30,15 +56,69 @@ type InstanceConfigInterfaceCreateOptions struct {
3056
Primary bool `json:"primary,omitempty"`
3157
SubnetID *int `json:"subnet_id,omitempty"`
3258
IPv4 *VPCIPv4 `json:"ipv4,omitempty"`
33-
IPRanges []string `json:"ip_ranges,omitempty"`
59+
60+
// NOTE: IPv6 interfaces may not currently be available to all users.
61+
IPv6 *InstanceConfigInterfaceCreateOptionsIPv6 `json:"ipv6,omitempty"`
62+
63+
IPRanges []string `json:"ip_ranges,omitempty"`
64+
}
65+
66+
// InstanceConfigInterfaceCreateOptionsIPv6 represents the IPv6 configuration of a Linode interface
67+
// specified during creation.
68+
// NOTE: IPv6 interfaces may not currently be available to all users.
69+
type InstanceConfigInterfaceCreateOptionsIPv6 struct {
70+
SLAAC []InstanceConfigInterfaceCreateOptionsIPv6SLAAC `json:"slaac,omitempty"`
71+
Ranges []InstanceConfigInterfaceCreateOptionsIPv6Range `json:"ranges,omitempty"`
72+
IsPublic *bool `json:"is_public,omitempty"`
73+
}
74+
75+
// InstanceConfigInterfaceCreateOptionsIPv6SLAAC represents a single IPv6 SLAAC of a Linode interface
76+
// specified during creation.
77+
// NOTE: IPv6 interfaces may not currently be available to all users.
78+
type InstanceConfigInterfaceCreateOptionsIPv6SLAAC struct {
79+
Range string `json:"range"`
80+
}
81+
82+
// InstanceConfigInterfaceCreateOptionsIPv6Range represents a single IPv6 ranges of a Linode interface
83+
// specified during creation.
84+
// NOTE: IPv6 interfaces may not currently be available to all users.
85+
type InstanceConfigInterfaceCreateOptionsIPv6Range struct {
86+
Range *string `json:"range,omitempty"`
3487
}
3588

3689
type InstanceConfigInterfaceUpdateOptions struct {
37-
Primary bool `json:"primary,omitempty"`
38-
IPv4 *VPCIPv4 `json:"ipv4,omitempty"`
90+
Primary bool `json:"primary,omitempty"`
91+
IPv4 *VPCIPv4 `json:"ipv4,omitempty"`
92+
93+
// NOTE: IPv6 interfaces may not currently be available to all users.
94+
IPv6 *InstanceConfigInterfaceUpdateOptionsIPv6 `json:"ipv6,omitempty"`
95+
3996
IPRanges *[]string `json:"ip_ranges,omitempty"`
4097
}
4198

99+
// InstanceConfigInterfaceUpdateOptionsIPv6 represents the IPv6 configuration of a Linode interface
100+
// specified during updates.
101+
// NOTE: IPv6 interfaces may not currently be available to all users.
102+
type InstanceConfigInterfaceUpdateOptionsIPv6 struct {
103+
SLAAC *[]InstanceConfigInterfaceUpdateOptionsIPv6SLAAC `json:"slaac,omitempty"`
104+
Ranges *[]InstanceConfigInterfaceUpdateOptionsIPv6Range `json:"ranges,omitempty"`
105+
IsPublic *bool `json:"is_public,omitempty"`
106+
}
107+
108+
// InstanceConfigInterfaceUpdateOptionsIPv6SLAAC represents a single IPv6 SLAAC of a Linode interface
109+
// specified during updates.
110+
// NOTE: IPv6 interfaces may not currently be available to all users.
111+
type InstanceConfigInterfaceUpdateOptionsIPv6SLAAC struct {
112+
Range *string `json:"range,omitempty"`
113+
}
114+
115+
// InstanceConfigInterfaceUpdateOptionsIPv6Range represents a single IPv6 ranges of a Linode interface
116+
// specified during updates.
117+
// NOTE: IPv6 interfaces may not currently be available to all users.
118+
type InstanceConfigInterfaceUpdateOptionsIPv6Range struct {
119+
Range *string `json:"range,omitempty"`
120+
}
121+
42122
type InstanceConfigInterfacesReorderOptions struct {
43123
IDs []int `json:"ids"`
44124
}
@@ -66,13 +146,37 @@ func (i InstanceConfigInterface) GetCreateOptions() InstanceConfigInterfaceCreat
66146
opts.IPRanges = i.IPRanges
67147
}
68148

69-
if i.Purpose == InterfacePurposeVPC && i.IPv4 != nil {
149+
if i.IPv4 != nil {
70150
opts.IPv4 = &VPCIPv4{
71151
VPC: i.IPv4.VPC,
72152
NAT1To1: i.IPv4.NAT1To1,
73153
}
74154
}
75155

156+
if i.IPv6 != nil {
157+
ipv6 := *i.IPv6
158+
159+
opts.IPv6 = &InstanceConfigInterfaceCreateOptionsIPv6{
160+
SLAAC: mapSlice(
161+
ipv6.SLAAC,
162+
func(i InstanceConfigInterfaceIPv6SLAAC) InstanceConfigInterfaceCreateOptionsIPv6SLAAC {
163+
return InstanceConfigInterfaceCreateOptionsIPv6SLAAC{
164+
Range: i.Range,
165+
}
166+
},
167+
),
168+
Ranges: mapSlice(
169+
ipv6.Ranges,
170+
func(i InstanceConfigInterfaceIPv6Range) InstanceConfigInterfaceCreateOptionsIPv6Range {
171+
return InstanceConfigInterfaceCreateOptionsIPv6Range{
172+
Range: copyValue(&i.Range),
173+
}
174+
},
175+
),
176+
IsPublic: copyValue(&ipv6.IsPublic),
177+
}
178+
}
179+
76180
opts.IPAMAddress = i.IPAMAddress
77181

78182
return opts
@@ -83,10 +187,40 @@ func (i InstanceConfigInterface) GetUpdateOptions() InstanceConfigInterfaceUpdat
83187
Primary: i.Primary,
84188
}
85189

86-
if i.Purpose == InterfacePurposeVPC && i.IPv4 != nil {
87-
opts.IPv4 = &VPCIPv4{
88-
VPC: i.IPv4.VPC,
89-
NAT1To1: i.IPv4.NAT1To1,
190+
if i.Purpose == InterfacePurposeVPC {
191+
if i.IPv4 != nil {
192+
opts.IPv4 = &VPCIPv4{
193+
VPC: i.IPv4.VPC,
194+
NAT1To1: i.IPv4.NAT1To1,
195+
}
196+
}
197+
198+
if i.IPv6 != nil {
199+
ipv6 := *i.IPv6
200+
201+
newSLAAC := mapSlice(
202+
ipv6.SLAAC,
203+
func(i InstanceConfigInterfaceIPv6SLAAC) InstanceConfigInterfaceUpdateOptionsIPv6SLAAC {
204+
return InstanceConfigInterfaceUpdateOptionsIPv6SLAAC{
205+
Range: copyValue(&i.Range),
206+
}
207+
},
208+
)
209+
210+
newRanges := mapSlice(
211+
ipv6.Ranges,
212+
func(i InstanceConfigInterfaceIPv6Range) InstanceConfigInterfaceUpdateOptionsIPv6Range {
213+
return InstanceConfigInterfaceUpdateOptionsIPv6Range{
214+
Range: copyValue(&i.Range),
215+
}
216+
},
217+
)
218+
219+
opts.IPv6 = &InstanceConfigInterfaceUpdateOptionsIPv6{
220+
SLAAC: &newSLAAC,
221+
Ranges: &newRanges,
222+
IsPublic: copyValue(&ipv6.IsPublic),
223+
}
90224
}
91225
}
92226

instance_configs.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,24 +119,27 @@ func (i *InstanceConfig) UnmarshalJSON(b []byte) error {
119119

120120
// GetCreateOptions converts a InstanceConfig to InstanceConfigCreateOptions for use in CreateInstanceConfig
121121
func (i InstanceConfig) GetCreateOptions() InstanceConfigCreateOptions {
122-
initrd := 0
123-
if i.InitRD != nil {
124-
initrd = *i.InitRD
125-
}
126-
127-
return InstanceConfigCreateOptions{
122+
result := InstanceConfigCreateOptions{
128123
Label: i.Label,
129124
Comments: i.Comments,
130-
Devices: *i.Devices,
131125
Helpers: i.Helpers,
132126
Interfaces: getInstanceConfigInterfacesCreateOptionsList(i.Interfaces),
133127
MemoryLimit: i.MemoryLimit,
134128
Kernel: i.Kernel,
135-
InitRD: initrd,
136129
RootDevice: copyString(&i.RootDevice),
137130
RunLevel: i.RunLevel,
138131
VirtMode: i.VirtMode,
139132
}
133+
134+
if i.InitRD != nil {
135+
result.InitRD = *i.InitRD
136+
}
137+
138+
if i.Devices != nil {
139+
result.Devices = *i.Devices
140+
}
141+
142+
return result
140143
}
141144

142145
// GetUpdateOptions converts a InstanceConfig to InstanceConfigUpdateOptions for use in UpdateInstanceConfig

instance_ips.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,21 @@ type VPCIP struct {
5050
SubnetID int `json:"subnet_id"`
5151
InterfaceID int `json:"interface_id"`
5252

53+
// NOTE: IPv6 VPCs may not currently be available to all users.
54+
IPv6Range *string `json:"ipv6_range"`
55+
IPv6IsPublic *bool `json:"ipv6_is_public"`
56+
IPv6Addresses []VPCIPIPv6Address `json:"ipv6_addresses"`
57+
5358
// The type of this field will be made a pointer in the next major release of linodego.
5459
ConfigID int `json:"config_id"`
5560
}
5661

62+
// VPCIPIPv6Address represents a single IPv6 address under a VPCIP.
63+
// NOTE: IPv6 VPCs may not currently be available to all users.
64+
type VPCIPIPv6Address struct {
65+
SLAACAddress string `json:"slaac_address"`
66+
}
67+
5768
// InstanceIPv6Response contains the IPv6 addresses and ranges for an Instance
5869
type InstanceIPv6Response struct {
5970
LinkLocal *InstanceIP `json:"link_local"`

interfaces.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ type VPCInterface struct {
6565
VPCID int `json:"vpc_id"`
6666
SubnetID int `json:"subnet_id"`
6767
IPv4 VPCInterfaceIPv4 `json:"ipv4"`
68+
69+
// NOTE: IPv6 VPC interfaces may not currently be available to all users.
70+
IPv6 VPCInterfaceIPv6 `json:"ipv6"`
6871
}
6972

7073
type VPCInterfaceIPv4 struct {
@@ -82,6 +85,27 @@ type VPCInterfaceIPv4Range struct {
8285
Range string `json:"range"`
8386
}
8487

88+
// VPCInterfaceIPv6 contains the IPv6 configuration for a VPC.
89+
// NOTE: IPv6 VPC interfaces may not currently be available to all users.
90+
type VPCInterfaceIPv6 struct {
91+
SLAAC []VPCInterfaceIPv6SLAAC `json:"slaac"`
92+
Ranges []VPCInterfaceIPv6Range `json:"ranges"`
93+
IsPublic bool `json:"is_public"`
94+
}
95+
96+
// VPCInterfaceIPv6SLAAC contains the information for a single IPv6 SLAAC under a VPC.
97+
// NOTE: IPv6 VPC interfaces may not currently be available to all users.
98+
type VPCInterfaceIPv6SLAAC struct {
99+
Range string `json:"range"`
100+
Address string `json:"address"`
101+
}
102+
103+
// VPCInterfaceIPv6Range contains the information for a single IPv6 range under a VPC.
104+
// NOTE: IPv6 VPC interfaces may not currently be available to all users.
105+
type VPCInterfaceIPv6Range struct {
106+
Range string `json:"range"`
107+
}
108+
85109
type VLANInterface struct {
86110
VLANLabel string `json:"vlan_label"`
87111
IPAMAddress *string `json:"ipam_address,omitempty"`
@@ -127,6 +151,7 @@ type PublicInterfaceIPv6RangeCreateOptions struct {
127151
type VPCInterfaceCreateOptions struct {
128152
SubnetID int `json:"subnet_id"`
129153
IPv4 *VPCInterfaceIPv4CreateOptions `json:"ipv4,omitempty"`
154+
IPv6 *VPCInterfaceIPv6CreateOptions `json:"ipv6,omitempty"`
130155
}
131156

132157
type VPCInterfaceIPv4CreateOptions struct {
@@ -144,6 +169,26 @@ type VPCInterfaceIPv4RangeCreateOptions struct {
144169
Range string `json:"range"`
145170
}
146171

172+
// VPCInterfaceIPv6CreateOptions specifies IPv6 configuration parameters for VPC creation.
173+
// NOTE: IPv6 interfaces may not currently be available to all users.
174+
type VPCInterfaceIPv6CreateOptions struct {
175+
SLAAC []VPCInterfaceIPv6SLAACCreateOptions `json:"slaac,omitempty"`
176+
Ranges []VPCInterfaceIPv6RangeCreateOptions `json:"ranges,omitempty"`
177+
IsPublic bool `json:"is_public"`
178+
}
179+
180+
// VPCInterfaceIPv6SLAACCreateOptions defines the IPv6 SLAAC configuration parameters for VPC creation.
181+
// NOTE: IPv6 interfaces may not currently be available to all users.
182+
type VPCInterfaceIPv6SLAACCreateOptions struct {
183+
Range string `json:"range"`
184+
}
185+
186+
// VPCInterfaceIPv6RangeCreateOptions defines the IPv6 range configuration parameters for VPC creation.
187+
// NOTE: IPv6 interfaces may not currently be available to all users.
188+
type VPCInterfaceIPv6RangeCreateOptions struct {
189+
Range string `json:"range"`
190+
}
191+
147192
type LinodeInterfacesUpgrade struct {
148193
ConfigID int `json:"config_id"`
149194
DryRun bool `json:"dry_run"`

test/integration/fixtures/TestAccountSettings.yaml

Whitespace-only changes.

0 commit comments

Comments
 (0)