1+ from module .common .logging import get_logger
2+ from module .sources .common .source_base import SourceBase
3+ from module .sources .hetzner .client import HetznerClient
4+ from module .sources .hetzner .config import HetznerConfig
5+ from module .sources .hetzner .network import sync_vm_network
6+ from module .sources .hetzner .disk import sync_vm_disks
7+
8+
9+
10+ from module .netbox .inventory import (
11+ NetBoxInventory ,
12+ NBVM ,
13+ NBSite ,
14+ NBCluster ,
15+ NBClusterType ,
16+ NBVMInterface ,
17+ NBIPAddress ,
18+ NBVirtualDisk ,
19+ )
20+
21+
22+
23+ class HetznerHandler (SourceBase ):
24+
25+ source_type = "hetzner"
26+ source_tag = "hetzner"
27+
28+ settings = HetznerConfig ()
29+
30+
31+
32+ dependent_netbox_objects = [
33+ NBVM ,
34+ NBCluster ,
35+ NBSite ,
36+ NBClusterType ,
37+ NBIPAddress ,
38+ NBVirtualDisk ,
39+ NBVMInterface ,
40+ ]
41+
42+
43+ def __init__ (self , name = None ):
44+
45+ if name is None :
46+ raise ValueError (f"Invalid value for attribute 'name': '{ name } '." )
47+
48+ self .inventory = NetBoxInventory ()
49+ self .name = name
50+ self .log = get_logger ()
51+
52+ settings_handler = HetznerConfig ()
53+ settings_handler .source_name = self .name
54+ self .settings = settings_handler .parse ()
55+
56+ self .set_source_tag ()
57+
58+ if self .settings .enabled is False :
59+ log .info (f"Source '{ name } ' is currently disabled. Skipping" )
60+ return
61+
62+ self .init_successful = True
63+
64+
65+
66+
67+ @classmethod
68+ def implements (cls , source_type ):
69+ return source_type == "hetzner"
70+
71+ def apply (self ):
72+
73+ token = self .settings .api_token
74+
75+ self .log .error (f"TOKEN DEBUG >>> { repr (token )} " )
76+
77+ if not token :
78+ self .log .error ("Hetzner api_token not defined in settings.ini" )
79+ return
80+
81+ self .client = HetznerClient (token = token )
82+
83+ servers = self .client .get_servers ()
84+
85+ self .log .info (f"Connected to Hetzner, found { len (servers )} servers" )
86+
87+
88+
89+ # ---------------------------
90+ # main object
91+ # ---------------------------
92+
93+ site = self .inventory .add_update_object (
94+ NBSite ,
95+ data = {"name" : "cloud" },
96+ source = self ,
97+ )
98+
99+ cluster_type = self .inventory .add_update_object (
100+ NBClusterType ,
101+ data = {"name" : "cloud" },
102+ source = self ,
103+ )
104+
105+ cluster_name = f"Hetzner: { self .name } "
106+
107+ cluster = self .inventory .add_update_object (
108+ NBCluster ,
109+ data = {
110+ "name" : cluster_name ,
111+ "type" : cluster_type ,
112+ "scope_type" : 17 ,
113+ "scope_id" : site ,
114+ },
115+ source = self ,
116+ )
117+
118+ # ---------------------------
119+ # servers loop
120+ # ---------------------------
121+
122+ for server in servers :
123+
124+ # -------- VM --------
125+ vm = self .inventory .add_update_object (
126+ NBVM ,
127+ data = {
128+ "name" : server .name ,
129+ "status" : "active" ,
130+ "cluster" : cluster ,
131+ "site" : site ,
132+ },
133+ source = self ,
134+ )
135+
136+ # -------- interfaces --------
137+ sync_vm_network (self , vm , server )
138+
139+ # -------- disks --------
140+ sync_vm_disks (self , vm , server )
0 commit comments