@@ -54,6 +54,15 @@ func TestParseAliases(t *testing.T) {
5454 ConfigLayer : network .ConfigPlatform ,
5555 }
5656
57+ alias0IPv6 := network.AddressSpecSpec {
58+ Address : netip .MustParsePrefix ("2001:db8::100/64" ),
59+ LinkName : "eth0" ,
60+ Family : nethelpers .FamilyInet6 ,
61+ Scope : nethelpers .ScopeGlobal ,
62+ Flags : nethelpers .AddressFlags (nethelpers .AddressPermanent ),
63+ ConfigLayer : network .ConfigPlatform ,
64+ }
65+
5766 for _ , tc := range []struct {
5867 name string
5968 extra string
@@ -133,6 +142,123 @@ ETH0_ALIAS0_DETACH = ""`,
133142 extra : "" ,
134143 wantAliasAddr : nil ,
135144 },
145+ {
146+ name : "IPv6 alias included" ,
147+ extra : `ETH0_ALIAS0_MAC = "02:00:c0:a8:01:64"
148+ ETH0_ALIAS0_IP6 = "2001:db8::100"
149+ ETH0_ALIAS0_EXTERNAL = "NO"
150+ ETH0_ALIAS0_DETACH = ""` ,
151+ wantAliasAddr : []network.AddressSpecSpec {alias0IPv6 },
152+ },
153+ {
154+ name : "ETH*_ALIAS*_IPV6 legacy alias used when IP6 absent" ,
155+ extra : `ETH0_ALIAS0_MAC = "02:00:c0:a8:01:64"
156+ ETH0_ALIAS0_IPV6 = "2001:db8::100"
157+ ETH0_ALIAS0_EXTERNAL = "NO"
158+ ETH0_ALIAS0_DETACH = ""` ,
159+ wantAliasAddr : []network.AddressSpecSpec {alias0IPv6 },
160+ },
161+ {
162+ name : "IPv6 alias explicit prefix length respected" ,
163+ extra : `ETH0_ALIAS0_MAC = "02:00:c0:a8:01:64"
164+ ETH0_ALIAS0_IP6 = "2001:db8::100"
165+ ETH0_ALIAS0_IP6_PREFIX_LENGTH = "48"
166+ ETH0_ALIAS0_EXTERNAL = "NO"
167+ ETH0_ALIAS0_DETACH = ""` ,
168+ wantAliasAddr : []network.AddressSpecSpec {
169+ {
170+ Address : netip .MustParsePrefix ("2001:db8::100/48" ),
171+ LinkName : "eth0" ,
172+ Family : nethelpers .FamilyInet6 ,
173+ Scope : nethelpers .ScopeGlobal ,
174+ Flags : nethelpers .AddressFlags (nethelpers .AddressPermanent ),
175+ ConfigLayer : network .ConfigPlatform ,
176+ },
177+ },
178+ },
179+ {
180+ name : "EXTERNAL=YES skips IPv6 alias" ,
181+ extra : `ETH0_ALIAS0_MAC = "02:00:c0:a8:01:64"
182+ ETH0_ALIAS0_IP6 = "2001:db8::100"
183+ ETH0_ALIAS0_EXTERNAL = "YES"
184+ ETH0_ALIAS0_DETACH = ""` ,
185+ wantAliasAddr : nil ,
186+ },
187+ {
188+ name : "DETACH non-empty skips IPv6 alias" ,
189+ extra : `ETH0_ALIAS0_MAC = "02:00:c0:a8:01:64"
190+ ETH0_ALIAS0_IP6 = "2001:db8::100"
191+ ETH0_ALIAS0_EXTERNAL = "NO"
192+ ETH0_ALIAS0_DETACH = "yes"` ,
193+ wantAliasAddr : nil ,
194+ },
195+ {
196+ name : "mixed IPv4 and IPv6 aliases both emitted" ,
197+ extra : `ETH0_ALIAS0_MAC = "02:00:c0:a8:01:64"
198+ ETH0_ALIAS0_IP = "192.168.1.100"
199+ ETH0_ALIAS0_MASK = "255.255.255.0"
200+ ETH0_ALIAS0_IP6 = "2001:db8::100"
201+ ETH0_ALIAS0_EXTERNAL = "NO"
202+ ETH0_ALIAS0_DETACH = ""` ,
203+ wantAliasAddr : []network.AddressSpecSpec {alias0IPv4 , alias0IPv6 },
204+ },
205+ {
206+ name : "IPv6 ULA alias emits two IPv6 addresses" ,
207+ extra : `ETH0_ALIAS0_MAC = "02:00:c0:a8:01:64"
208+ ETH0_ALIAS0_IP6 = "2001:db8::100"
209+ ETH0_ALIAS0_IP6_ULA = "fd00::100"
210+ ETH0_ALIAS0_EXTERNAL = "NO"
211+ ETH0_ALIAS0_DETACH = ""` ,
212+ wantAliasAddr : []network.AddressSpecSpec {
213+ alias0IPv6 ,
214+ {
215+ Address : netip .MustParsePrefix ("fd00::100/64" ),
216+ LinkName : "eth0" ,
217+ Family : nethelpers .FamilyInet6 ,
218+ Scope : nethelpers .ScopeGlobal ,
219+ Flags : nethelpers .AddressFlags (nethelpers .AddressPermanent ),
220+ ConfigLayer : network .ConfigPlatform ,
221+ },
222+ },
223+ },
224+ {
225+ name : "EXTERNAL=YES skips IPv6 ULA alias" ,
226+ extra : `ETH0_ALIAS0_MAC = "02:00:c0:a8:01:64"
227+ ETH0_ALIAS0_IP6_ULA = "fd00::100"
228+ ETH0_ALIAS0_EXTERNAL = "YES"
229+ ETH0_ALIAS0_DETACH = ""` ,
230+ wantAliasAddr : nil ,
231+ },
232+ {
233+ name : "DETACH non-empty skips IPv6 ULA alias" ,
234+ extra : `ETH0_ALIAS0_MAC = "02:00:c0:a8:01:64"
235+ ETH0_ALIAS0_IP6_ULA = "fd00::100"
236+ ETH0_ALIAS0_EXTERNAL = "NO"
237+ ETH0_ALIAS0_DETACH = "yes"` ,
238+ wantAliasAddr : nil ,
239+ },
240+ {
241+ name : "mixed IPv4 and IPv6 and ULA alias emits all three addresses" ,
242+ extra : `ETH0_ALIAS0_MAC = "02:00:c0:a8:01:64"
243+ ETH0_ALIAS0_IP = "192.168.1.100"
244+ ETH0_ALIAS0_MASK = "255.255.255.0"
245+ ETH0_ALIAS0_IP6 = "2001:db8::100"
246+ ETH0_ALIAS0_IP6_ULA = "fd00::100"
247+ ETH0_ALIAS0_EXTERNAL = "NO"
248+ ETH0_ALIAS0_DETACH = ""` ,
249+ wantAliasAddr : []network.AddressSpecSpec {
250+ alias0IPv4 ,
251+ alias0IPv6 ,
252+ {
253+ Address : netip .MustParsePrefix ("fd00::100/64" ),
254+ LinkName : "eth0" ,
255+ Family : nethelpers .FamilyInet6 ,
256+ Scope : nethelpers .ScopeGlobal ,
257+ Flags : nethelpers .AddressFlags (nethelpers .AddressPermanent ),
258+ ConfigLayer : network .ConfigPlatform ,
259+ },
260+ },
261+ },
136262 } {
137263 t .Run (tc .name , func (t * testing.T ) {
138264 t .Parallel ()
@@ -151,13 +277,13 @@ ETH0_ALIAS0_DETACH = ""`,
151277 }
152278}
153279
154- func TestParseAliasErrors (t * testing.T ) {
280+ func TestParseErrors (t * testing.T ) {
155281 t .Parallel ()
156282
157283 o := & opennebula.OpenNebula {}
158284 st := state .WrapCore (namespaced .NewState (inmem .Build ))
159285
160- t .Run ("malformed IPv4 returns descriptive error" , func (t * testing.T ) {
286+ t .Run ("malformed alias IPv4 returns descriptive error" , func (t * testing.T ) {
161287 t .Parallel ()
162288
163289 ctx := aliasContext (`ETH0_ALIAS0_MAC = "02:00:c0:a8:01:64"
@@ -170,4 +296,50 @@ ETH0_ALIAS0_DETACH = ""`)
170296 require .ErrorContains (t , err , "ETH0_ALIAS0" )
171297 require .ErrorContains (t , err , "IPv4" )
172298 })
299+
300+ t .Run ("malformed alias IPv6 returns descriptive error" , func (t * testing.T ) {
301+ t .Parallel ()
302+
303+ ctx := aliasContext (`ETH0_ALIAS0_MAC = "02:00:c0:a8:01:64"
304+ ETH0_ALIAS0_IP6 = "notanip"
305+ ETH0_ALIAS0_EXTERNAL = "NO"
306+ ETH0_ALIAS0_DETACH = ""` )
307+
308+ _ , err := o .ParseMetadata (st , ctx )
309+ require .ErrorContains (t , err , "ETH0_ALIAS0" )
310+ require .ErrorContains (t , err , "IPv6" )
311+ })
312+
313+ t .Run ("malformed alias IPv6 ULA returns error containing alias name and ULA" , func (t * testing.T ) {
314+ t .Parallel ()
315+
316+ ctx := aliasContext (`ETH0_ALIAS0_MAC = "02:00:c0:a8:01:64"
317+ ETH0_ALIAS0_IP6_ULA = "notanip"
318+ ETH0_ALIAS0_EXTERNAL = "NO"
319+ ETH0_ALIAS0_DETACH = ""` )
320+
321+ _ , err := o .ParseMetadata (st , ctx )
322+ require .ErrorContains (t , err , "ETH0_ALIAS0" )
323+ require .ErrorContains (t , err , "ULA" )
324+ })
325+
326+ t .Run ("malformed interface IPv6 address returns descriptive error" , func (t * testing.T ) {
327+ t .Parallel ()
328+
329+ ctx := aliasContext ("ETH0_IP6 = \" notanip\" " )
330+
331+ _ , err := o .ParseMetadata (st , ctx )
332+ require .ErrorContains (t , err , "ETH0" )
333+ require .ErrorContains (t , err , "IPv6" )
334+ })
335+
336+ t .Run ("malformed IPv6 gateway returns descriptive error" , func (t * testing.T ) {
337+ t .Parallel ()
338+
339+ ctx := aliasContext ("ETH0_IP6 = \" 2001:db8::1\" \n ETH0_IP6_GATEWAY = \" notanip\" " )
340+
341+ _ , err := o .ParseMetadata (st , ctx )
342+ require .ErrorContains (t , err , "ETH0" )
343+ require .ErrorContains (t , err , "gateway" )
344+ })
173345}
0 commit comments