]>
Commit | Line | Data |
---|---|---|
70b03506 AD |
1 | package PVE::Network::SDN::Ipams::NetboxPlugin; |
2 | ||
3 | use strict; | |
4 | use warnings; | |
5 | use PVE::INotify; | |
6 | use PVE::Cluster; | |
7 | use PVE::Tools; | |
8 | ||
9 | use base('PVE::Network::SDN::Ipams::Plugin'); | |
10 | ||
11 | sub type { | |
12 | return 'netbox'; | |
13 | } | |
14 | ||
15 | sub properties { | |
16 | return { | |
17 | }; | |
18 | } | |
19 | ||
20 | sub options { | |
21 | ||
22 | return { | |
23 | url => { optional => 0}, | |
24 | token => { optional => 0 }, | |
25 | }; | |
26 | } | |
27 | ||
28 | # Plugin implementation | |
29 | ||
30 | sub add_subnet { | |
31 | my ($class, $plugin_config, $subnetid, $subnet) = @_; | |
32 | ||
33 | my $cidr = $subnetid =~ s/-/\//r; | |
34 | my $gateway = $subnet->{gateway}; | |
35 | my $url = $plugin_config->{url}; | |
36 | my $token = $plugin_config->{token}; | |
37 | my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "token $token"]; | |
38 | ||
39 | my $internalid = get_prefix_id($url, $cidr, $headers); | |
40 | ||
41 | #create subnet | |
42 | if (!$internalid) { | |
43 | my ($network, $mask) = split(/-/, $subnetid); | |
44 | ||
45 | my $params = { prefix => $cidr }; | |
46 | ||
47 | eval { | |
48 | my $result = PVE::Network::SDN::Ipams::Plugin::api_request("POST", "$url/ipam/prefixes/", $headers, $params); | |
49 | $subnet->{ipamid} = $result->{id} if defined($result->{id}); | |
50 | }; | |
51 | if ($@) { | |
52 | die "error add subnet to ipam: $@"; | |
53 | } | |
54 | } | |
55 | ||
56 | } | |
57 | ||
58 | sub del_subnet { | |
59 | my ($class, $plugin_config, $subnetid, $subnet) = @_; | |
60 | ||
61 | my $cidr = $subnetid =~ s/-/\//r; | |
62 | my $url = $plugin_config->{url}; | |
63 | my $token = $plugin_config->{token}; | |
64 | my $gateway = $subnet->{gateway}; | |
65 | my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "token $token"]; | |
66 | ||
67 | my $internalid = get_prefix_id($url, $cidr, $headers); | |
68 | return if !$internalid; | |
69 | #fixme: check that prefix is empty exluding gateway, before delete | |
70 | ||
71 | PVE::Network::SDN::Ipams::NetboxPlugin::del_ip($class, $plugin_config, $subnetid, $gateway) if $gateway; | |
72 | ||
73 | eval { | |
74 | PVE::Network::SDN::Ipams::Plugin::api_request("DELETE", "$url/ipam/prefixes/$internalid/", $headers); | |
75 | }; | |
76 | if ($@) { | |
77 | die "error deleting subnet from ipam: $@"; | |
78 | } | |
79 | ||
80 | } | |
81 | ||
82 | sub add_ip { | |
83 | my ($class, $plugin_config, $subnetid, $ip, $is_gateway) = @_; | |
84 | ||
85 | my ($network, $mask) = split(/-/, $subnetid); | |
86 | my $url = $plugin_config->{url}; | |
87 | my $token = $plugin_config->{token}; | |
88 | my $section = $plugin_config->{section}; | |
89 | my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "token $token"]; | |
90 | ||
91 | my $params = { address => "$ip/$mask" }; | |
92 | ||
93 | eval { | |
94 | PVE::Network::SDN::Ipams::Plugin::api_request("POST", "$url/ipam/ip-addresses/", $headers, $params); | |
95 | }; | |
96 | ||
97 | if ($@) { | |
98 | die "error add subnet ip to ipam: ip already exist: $@"; | |
99 | } | |
100 | } | |
101 | ||
102 | sub add_next_freeip { | |
103 | my ($class, $plugin_config, $subnetid, $subnet) = @_; | |
104 | ||
105 | my $cidr = $subnetid =~ s/-/\//r; | |
106 | my $url = $plugin_config->{url}; | |
107 | my $token = $plugin_config->{token}; | |
108 | my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "token $token"]; | |
109 | ||
110 | my $internalid = get_prefix_id($url, $cidr, $headers); | |
111 | ||
112 | my $params = {}; | |
113 | ||
114 | my $ip = undef; | |
115 | eval { | |
116 | my $result = PVE::Network::SDN::Ipams::Plugin::api_request("POST", "$url/ipam/prefixes/$internalid/available-ips/", $headers, $params); | |
117 | $ip = $result->{address}; | |
118 | }; | |
119 | ||
120 | if ($@) { | |
121 | die "can't find free ip in subnet $cidr: $@"; | |
122 | } | |
123 | ||
124 | return $ip; | |
125 | } | |
126 | ||
127 | sub del_ip { | |
128 | my ($class, $plugin_config, $subnetid, $ip) = @_; | |
129 | ||
130 | return if !$ip; | |
131 | ||
132 | my $url = $plugin_config->{url}; | |
133 | my $token = $plugin_config->{token}; | |
134 | my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "token $token"]; | |
135 | ||
136 | my $ip_id = get_ip_id($url, $ip, $headers); | |
137 | die "can't find ip $ip in ipam" if !$ip_id; | |
138 | ||
139 | eval { | |
140 | PVE::Network::SDN::Ipams::Plugin::api_request("DELETE", "$url/ipam/ip-addresses/$ip_id/", $headers); | |
141 | }; | |
142 | if ($@) { | |
143 | die "error delete ip $ip : $@"; | |
144 | } | |
145 | } | |
146 | ||
147 | sub verify_api { | |
148 | my ($class, $plugin_config) = @_; | |
149 | ||
150 | my $url = $plugin_config->{url}; | |
151 | my $token = $plugin_config->{token}; | |
152 | my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "token $token"]; | |
153 | ||
154 | ||
155 | eval { | |
156 | PVE::Network::SDN::Ipams::Plugin::api_request("GET", "$url/ipam/aggregates/", $headers); | |
157 | }; | |
158 | if ($@) { | |
159 | die "Can't connect to netbox api: $@"; | |
160 | } | |
161 | } | |
162 | ||
163 | sub on_update_hook { | |
164 | my ($class, $plugin_config) = @_; | |
165 | ||
166 | PVE::Network::SDN::Ipams::NetboxPlugin::verify_api($class, $plugin_config); | |
167 | } | |
168 | ||
169 | #helpers | |
170 | ||
171 | sub get_prefix_id { | |
172 | my ($url, $cidr, $headers) = @_; | |
173 | ||
174 | my $result = PVE::Network::SDN::Ipams::Plugin::api_request("GET", "$url/ipam/prefixes/?q=$cidr", $headers); | |
175 | my $data = @{$result->{results}}[0]; | |
176 | my $internalid = $data->{id}; | |
177 | return $internalid; | |
178 | } | |
179 | ||
180 | sub get_ip_id { | |
181 | my ($url, $ip, $headers) = @_; | |
182 | my $result = PVE::Network::SDN::Ipams::Plugin::api_request("GET", "$url/ipam/ip-addresses/?q=$ip", $headers); | |
183 | my $data = @{$result->{results}}[0]; | |
184 | my $ip_id = $data->{id}; | |
185 | return $ip_id; | |
186 | } | |
187 | ||
188 | ||
189 | 1; | |
190 | ||
191 |