11from dataclasses import dataclass , field
2- from typing import List , Optional , Union
2+ from typing import Any , Dict , List , Optional , Union
33
44from linode_api4 .objects import DerivedBase
55from linode_api4 .objects .base import Base , Property
2020 "MonitorServiceToken" ,
2121 "RuleCriteria" ,
2222 "TriggerConditions" ,
23+ "AkamaiObjectStorageLogsDestinationDetails" ,
24+ "CustomHTTPSLogsDestinationDetails" ,
25+ "LogsDestinationDetailsBase" ,
2326 "LogsDestination" ,
24- "LogsDestinationDetails" ,
2527 "LogsDestinationHistory" ,
2628 "LogsDestinationStatus" ,
2729 "LogsDestinationType" ,
@@ -143,10 +145,26 @@ class AlertStatus(StrEnum):
143145
144146class LogsDestinationType (StrEnum ):
145147 """
146- The type of destination for logs data sync. Currently, only ``akamai_object_storage`` is supported.
148+ The type of destination for logs data sync.
147149 """
148150
149151 akamai_object_storage = "akamai_object_storage"
152+ custom_https = "custom_https"
153+
154+
155+ class AuthenticationType (StrEnum ):
156+ none = "none"
157+ basic = "basic"
158+
159+
160+ class DataCompressionType (StrEnum ):
161+ gzip = "gzip"
162+ none = "none"
163+
164+
165+ class ContentType (StrEnum ):
166+ json = "application/json"
167+ json_utf8 = "application/json; charset=utf-8"
150168
151169
152170class LogsDestinationStatus (StrEnum ):
@@ -541,9 +559,97 @@ class AlertChannel(Base):
541559
542560
543561@dataclass
544- class LogsDestinationDetails (JSONObject ):
562+ class BasicAuthenticationDetails (JSONObject ):
563+ """
564+ Includes additional parameters necessary to define basic authentication.
565+ """
566+
567+ basic_authentication_user : Optional [str ] = None
568+ basic_authentication_password : Optional [str ] = None
569+
570+
571+ @dataclass
572+ class DestinationAuthentication (JSONObject ):
573+ """
574+ Authentication details required to access the endpoint_url.
575+ """
576+
577+ type : Optional [AuthenticationType ] = None
578+ details : Optional [BasicAuthenticationDetails ] = None
579+
580+
581+ @dataclass
582+ class CustomHeader (JSONObject ):
583+ """
584+ Pairs of parameters used to optionally include custom headers in the request.
585+ """
586+
587+ name : str = ""
588+ value : str = ""
589+
590+
591+ @dataclass
592+ class ClientCertificateDetails (JSONObject ):
593+ """
594+ Contains TLS client certificate information to additionally secure the connection.
595+ """
596+
597+ client_ca_certificate : Optional [str ] = None
598+ client_certificate : Optional [str ] = None
599+ client_private_key : Optional [str ] = None
600+ tls_hostname : Optional [str ] = None
601+
602+
603+ @dataclass
604+ class LogsDestinationDetailsBase (JSONObject ):
605+ """
606+ Base class for Logs Destination details.
607+ Use the factory method to instantiate the correct subclass based on destination type.
608+ """
609+
610+ @classmethod
611+ def load_by_type (
612+ cls , dest_type : str , json_dict : dict
613+ ) -> Optional ["LogsDestinationDetailsBase" ]:
614+ """
615+ Factory method that instantiates the correct details subclass
616+ based on the destination type string.
617+
618+ :param dest_type: The destination type (e.g. "akamai_object_storage", "custom_https").
619+ :param json_dict: The raw JSON dict for the details block.
620+ :returns: A populated subclass instance, or None if json_dict is empty/None.
621+ """
622+ if not json_dict :
623+ return None
624+
625+ if dest_type == LogsDestinationType .akamai_object_storage :
626+ return AkamaiObjectStorageLogsDestinationDetails .from_json (
627+ json_dict
628+ )
629+ elif dest_type == LogsDestinationType .custom_https :
630+ return CustomHTTPSLogsDestinationDetails .from_json (json_dict )
631+
632+ return None
633+
634+
635+ @dataclass
636+ class CustomHTTPSLogsDestinationDetails (LogsDestinationDetailsBase ):
545637 """
546- Represents the details block for LogsDestination.
638+ Represents the details block for custom_https LogsDestination type.
639+ """
640+
641+ endpoint_url : str = ""
642+ authentication : Optional [DestinationAuthentication ] = None
643+ data_compression : Optional [DataCompressionType ] = None
644+ content_type : Optional [ContentType ] = None
645+ custom_headers : Optional [List [CustomHeader ]] = None
646+ client_certificate_details : Optional [ClientCertificateDetails ] = None
647+
648+
649+ @dataclass
650+ class AkamaiObjectStorageLogsDestinationDetails (LogsDestinationDetailsBase ):
651+ """
652+ Represents the details block for Akamai Object Storage LogsDestination type.
547653 Fields:
548654 - access_key_id: str - The unique identifier assigned to the Object Storage key required for authentication to the bucket.
549655 - bucket_name: str - The name of the Object Storage bucket.
@@ -568,7 +674,7 @@ class LogsDestinationHistory(Base):
568674 properties = {
569675 "created" : Property (is_datetime = True ),
570676 "created_by" : Property (),
571- "details" : Property (json_object = LogsDestinationDetails ),
677+ "details" : Property (),
572678 "id" : Property (identifier = True ),
573679 "label" : Property (),
574680 "status" : Property (),
@@ -578,6 +684,17 @@ class LogsDestinationHistory(Base):
578684 "version" : Property (),
579685 }
580686
687+ def _populate (self , json ):
688+ super ()._populate (json )
689+
690+ if json and "details" in json and "type" in json :
691+ self ._set (
692+ "details" ,
693+ LogsDestinationDetailsBase .load_by_type (
694+ json ["type" ], json ["details" ]
695+ ),
696+ )
697+
581698
582699class LogsDestination (Base ):
583700 """
@@ -591,7 +708,7 @@ class LogsDestination(Base):
591708 properties = {
592709 "created" : Property (is_datetime = True ),
593710 "created_by" : Property (),
594- "details" : Property (mutable = True , json_object = LogsDestinationDetails ),
711+ "details" : Property (mutable = True ),
595712 "id" : Property (identifier = True ),
596713 "label" : Property (mutable = True ),
597714 "status" : Property (),
@@ -601,6 +718,17 @@ class LogsDestination(Base):
601718 "version" : Property (),
602719 }
603720
721+ def _populate (self , json ):
722+ super ()._populate (json )
723+
724+ if json and "details" in json and "type" in json :
725+ self ._set (
726+ "details" ,
727+ LogsDestinationDetailsBase .load_by_type (
728+ json ["type" ], json ["details" ]
729+ ),
730+ )
731+
604732 @property
605733 def history (self ):
606734 """
@@ -636,7 +764,23 @@ class LogsStreamDestination(JSONObject):
636764 id : int = 0
637765 label : str = ""
638766 type : Optional [LogsDestinationType ] = None
639- details : Optional [LogsDestinationDetails ] = None
767+ details : Optional [LogsDestinationDetailsBase ] = None
768+
769+ @classmethod
770+ def from_json (
771+ cls , json : Dict [str , Any ]
772+ ) -> Optional ["LogsStreamDestination" ]:
773+ if json is None :
774+ return None
775+
776+ obj = super ().from_json (json )
777+
778+ if obj and json .get ("type" ):
779+ obj .details = LogsDestinationDetailsBase .load_by_type (
780+ json ["type" ], json .get ("details" )
781+ )
782+
783+ return obj
640784
641785
642786class LogsStreamHistory (Base ):
0 commit comments