1
1
import string
2
2
import sys
3
- from dataclasses import dataclass
3
+ from dataclasses import dataclass , field
4
4
from datetime import datetime
5
5
from enum import Enum
6
6
from os import urandom
@@ -291,10 +291,83 @@ def _populate(self, json):
291
291
292
292
@dataclass
293
293
class ConfigInterfaceIPv4 (JSONObject ):
294
+ """
295
+ ConfigInterfaceIPv4 represents the IPv4 configuration of a VPC interface.
296
+ """
297
+
294
298
vpc : str = ""
295
299
nat_1_1 : str = ""
296
300
297
301
302
+ @dataclass
303
+ class ConfigInterfaceIPv6SLAACOptions (JSONObject ):
304
+ """
305
+ ConfigInterfaceIPv6SLAACOptions is used to set a single IPv6 SLAAC configuration of a VPC interface.
306
+ """
307
+
308
+ range : str = ""
309
+
310
+
311
+ @dataclass
312
+ class ConfigInterfaceIPv6RangeOptions (JSONObject ):
313
+ """
314
+ ConfigInterfaceIPv6RangeOptions is used to set a single IPv6 range configuration of a VPC interface.
315
+ """
316
+
317
+ range : str = ""
318
+
319
+
320
+ @dataclass
321
+ class ConfigInterfaceIPv6Options (JSONObject ):
322
+ """
323
+ ConfigInterfaceIPv6Options is used to set the IPv6 configuration of a VPC interface.
324
+ """
325
+
326
+ slaac : List [ConfigInterfaceIPv6SLAACOptions ] = field (
327
+ default_factory = lambda : []
328
+ )
329
+ ranges : List [ConfigInterfaceIPv6RangeOptions ] = field (
330
+ default_factory = lambda : []
331
+ )
332
+ is_public : bool = False
333
+
334
+
335
+ @dataclass
336
+ class ConfigInterfaceIPv6SLAAC (JSONObject ):
337
+ """
338
+ ConfigInterfaceIPv6SLAAC represents a single SLAAC address under a VPC interface's IPv6 configuration.
339
+ """
340
+
341
+ put_class = ConfigInterfaceIPv6SLAACOptions
342
+
343
+ range : str = ""
344
+ address : str = ""
345
+
346
+
347
+ @dataclass
348
+ class ConfigInterfaceIPv6Range (JSONObject ):
349
+ """
350
+ ConfigInterfaceIPv6Range represents a single IPv6 address under a VPC interface's IPv6 configuration.
351
+ """
352
+
353
+ put_class = ConfigInterfaceIPv6RangeOptions
354
+
355
+ range : str = ""
356
+
357
+
358
+ @dataclass
359
+ class ConfigInterfaceIPv6 (JSONObject ):
360
+ """
361
+ ConfigInterfaceIPv6 represents the IPv6 configuration of a VPC interface.
362
+ """
363
+
364
+ put_class = ConfigInterfaceIPv6Options
365
+
366
+ slaac : List [ConfigInterfaceIPv6SLAAC ] = field (default_factory = lambda : [])
367
+ ranges : List [ConfigInterfaceIPv6Range ] = field (default_factory = lambda : [])
368
+ is_public : bool = False
369
+
370
+
298
371
class NetworkInterface (DerivedBase ):
299
372
"""
300
373
This class represents a Configuration Profile's network interface object.
@@ -320,6 +393,7 @@ class NetworkInterface(DerivedBase):
320
393
"vpc_id" : Property (id_relationship = VPC ),
321
394
"subnet_id" : Property (),
322
395
"ipv4" : Property (mutable = True , json_object = ConfigInterfaceIPv4 ),
396
+ "ipv6" : Property (mutable = True , json_object = ConfigInterfaceIPv6 ),
323
397
"ip_ranges" : Property (mutable = True ),
324
398
}
325
399
@@ -391,7 +465,10 @@ class ConfigInterface(JSONObject):
391
465
# VPC-specific
392
466
vpc_id : Optional [int ] = None
393
467
subnet_id : Optional [int ] = None
468
+
394
469
ipv4 : Optional [Union [ConfigInterfaceIPv4 , Dict [str , Any ]]] = None
470
+ ipv6 : Optional [Union [ConfigInterfaceIPv6 , Dict [str , Any ]]] = None
471
+
395
472
ip_ranges : Optional [List [str ]] = None
396
473
397
474
# Computed
@@ -400,7 +477,7 @@ class ConfigInterface(JSONObject):
400
477
def __repr__ (self ):
401
478
return f"Interface: { self .purpose } "
402
479
403
- def _serialize (self ):
480
+ def _serialize (self , is_put : bool = False ):
404
481
purpose_formats = {
405
482
"public" : {"purpose" : "public" , "primary" : self .primary },
406
483
"vlan" : {
@@ -412,11 +489,8 @@ def _serialize(self):
412
489
"purpose" : "vpc" ,
413
490
"primary" : self .primary ,
414
491
"subnet_id" : self .subnet_id ,
415
- "ipv4" : (
416
- self .ipv4 .dict
417
- if isinstance (self .ipv4 , ConfigInterfaceIPv4 )
418
- else self .ipv4
419
- ),
492
+ "ipv4" : self .ipv4 ,
493
+ "ipv6" : self .ipv6 ,
420
494
"ip_ranges" : self .ip_ranges ,
421
495
},
422
496
}
@@ -426,11 +500,14 @@ def _serialize(self):
426
500
f"Unknown interface purpose: { self .purpose } " ,
427
501
)
428
502
429
- return {
430
- k : v
431
- for k , v in purpose_formats [self .purpose ].items ()
432
- if v is not None
433
- }
503
+ return _flatten_request_body_recursive (
504
+ {
505
+ k : v
506
+ for k , v in purpose_formats [self .purpose ].items ()
507
+ if v is not None
508
+ },
509
+ is_put = is_put ,
510
+ )
434
511
435
512
436
513
class Config (DerivedBase ):
@@ -510,16 +587,16 @@ def _populate(self, json):
510
587
511
588
self ._set ("devices" , MappedObject (** devices ))
512
589
513
- def _serialize (self ):
590
+ def _serialize (self , * args , ** kwargs ):
514
591
"""
515
592
Overrides _serialize to transform interfaces into json
516
593
"""
517
- partial = DerivedBase ._serialize (self )
594
+ partial = DerivedBase ._serialize (self , * args , ** kwargs )
518
595
interfaces = []
519
596
520
597
for c in self .interfaces :
521
598
if isinstance (c , ConfigInterface ):
522
- interfaces .append (c ._serialize ())
599
+ interfaces .append (c ._serialize (* args , ** kwargs ))
523
600
else :
524
601
interfaces .append (c )
525
602
@@ -571,6 +648,7 @@ def interface_create_vpc(
571
648
subnet : Union [int , VPCSubnet ],
572
649
primary = False ,
573
650
ipv4 : Union [Dict [str , Any ], ConfigInterfaceIPv4 ] = None ,
651
+ ipv6 : Union [Dict [str , Any ], ConfigInterfaceIPv6Options ] = None ,
574
652
ip_ranges : Optional [List [str ]] = None ,
575
653
) -> NetworkInterface :
576
654
"""
@@ -584,6 +662,8 @@ def interface_create_vpc(
584
662
:type primary: bool
585
663
:param ipv4: The IPv4 configuration of the interface for the associated subnet.
586
664
:type ipv4: Dict or ConfigInterfaceIPv4
665
+ :param ipv6: The IPv6 configuration of the interface for the associated subnet.
666
+ :type ipv6: Dict or ConfigInterfaceIPv6Options
587
667
:param ip_ranges: A list of IPs or IP ranges in the VPC subnet.
588
668
Packets to these CIDRs are routed through the
589
669
VPC network interface.
@@ -594,19 +674,16 @@ def interface_create_vpc(
594
674
"""
595
675
params = {
596
676
"purpose" : "vpc" ,
597
- "subnet_id" : subnet . id if isinstance ( subnet , VPCSubnet ) else subnet ,
677
+ "subnet_id" : subnet ,
598
678
"primary" : primary ,
679
+ "ipv4" : ipv4 ,
680
+ "ipv6" : ipv6 ,
681
+ "ip_ranges" : ip_ranges ,
599
682
}
600
683
601
- if ipv4 is not None :
602
- params ["ipv4" ] = (
603
- ipv4 .dict if isinstance (ipv4 , ConfigInterfaceIPv4 ) else ipv4
604
- )
605
-
606
- if ip_ranges is not None :
607
- params ["ip_ranges" ] = ip_ranges
608
-
609
- return self ._interface_create (params )
684
+ return self ._interface_create (
685
+ drop_null_keys (_flatten_request_body_recursive (params ))
686
+ )
610
687
611
688
def interface_reorder (self , interfaces : List [Union [int , NetworkInterface ]]):
612
689
"""
@@ -1927,8 +2004,8 @@ def _populate(self, json):
1927
2004
ndist = [Image (self ._client , d ) for d in self .images ]
1928
2005
self ._set ("images" , ndist )
1929
2006
1930
- def _serialize (self ):
1931
- dct = Base ._serialize (self )
2007
+ def _serialize (self , * args , ** kwargs ):
2008
+ dct = Base ._serialize (self , * args , ** kwargs )
1932
2009
dct ["images" ] = [d .id for d in self .images ]
1933
2010
return dct
1934
2011
0 commit comments