]>
Commit | Line | Data |
---|---|---|
70b03506 AD |
1 | package PVE::Network::SDN::Ipams::PhpIpamPlugin; |
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 'phpipam'; | |
13 | } | |
14 | ||
15 | sub properties { | |
16 | return { | |
17 | url => { | |
18 | type => 'string', | |
19 | }, | |
20 | token => { | |
21 | type => 'string', | |
22 | }, | |
23 | section => { | |
24 | type => 'integer', | |
25 | }, | |
26 | }; | |
27 | } | |
28 | ||
29 | sub options { | |
30 | ||
31 | return { | |
32 | url => { optional => 0}, | |
33 | token => { optional => 0 }, | |
34 | section => { optional => 0 }, | |
35 | }; | |
36 | } | |
37 | ||
38 | # Plugin implementation | |
39 | ||
40 | sub add_subnet { | |
04f6db9a | 41 | my ($class, $plugin_config, $subnetid, $subnet, $noerr) = @_; |
70b03506 | 42 | |
e8736dac AD |
43 | my $cidr = $subnet->{cidr}; |
44 | my $network = $subnet->{network}; | |
45 | my $mask = $subnet->{mask}; | |
46 | ||
70b03506 AD |
47 | my $gateway = $subnet->{gateway}; |
48 | my $url = $plugin_config->{url}; | |
49 | my $token = $plugin_config->{token}; | |
50 | my $section = $plugin_config->{section}; | |
51 | my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Token' => $token]; | |
52 | ||
53 | #search subnet | |
3f02d3ec | 54 | my $internalid = get_prefix_id($url, $cidr, $headers); |
70b03506 AD |
55 | |
56 | #create subnet | |
57 | if (!$internalid) { | |
70b03506 AD |
58 | my $params = { subnet => $network, |
59 | mask => $mask, | |
60 | sectionId => $section, | |
61 | }; | |
62 | ||
63 | eval { | |
167dc03f | 64 | PVE::Network::SDN::api_request("POST", "$url/subnets/", $headers, $params); |
70b03506 AD |
65 | }; |
66 | if ($@) { | |
04f6db9a | 67 | die "error add subnet to ipam: $@" if !$noerr; |
70b03506 AD |
68 | } |
69 | } | |
70 | ||
71 | } | |
72 | ||
73 | sub del_subnet { | |
04f6db9a | 74 | my ($class, $plugin_config, $subnetid, $subnet, $noerr) = @_; |
70b03506 | 75 | |
e8736dac | 76 | my $cidr = $subnet->{cidr}; |
70b03506 AD |
77 | my $url = $plugin_config->{url}; |
78 | my $token = $plugin_config->{token}; | |
79 | my $section = $plugin_config->{section}; | |
80 | my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Token' => $token]; | |
81 | ||
3f02d3ec | 82 | my $internalid = get_prefix_id($url, $cidr, $headers); |
70b03506 AD |
83 | return if !$internalid; |
84 | ||
e8736dac | 85 | return; #fixme: check that prefix is empty exluding gateway, before delete |
70b03506 AD |
86 | |
87 | eval { | |
167dc03f | 88 | PVE::Network::SDN::api_request("DELETE", "$url/subnets/$internalid", $headers); |
70b03506 AD |
89 | }; |
90 | if ($@) { | |
04f6db9a | 91 | die "error deleting subnet from ipam: $@" if !$noerr; |
70b03506 AD |
92 | } |
93 | ||
94 | } | |
95 | ||
96 | sub add_ip { | |
04f6db9a | 97 | my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway, $noerr) = @_; |
70b03506 | 98 | |
e8736dac | 99 | my $cidr = $subnet->{cidr}; |
70b03506 AD |
100 | my $url = $plugin_config->{url}; |
101 | my $token = $plugin_config->{token}; | |
102 | my $section = $plugin_config->{section}; | |
103 | my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Token' => $token]; | |
104 | ||
3f02d3ec | 105 | my $internalid = get_prefix_id($url, $cidr, $headers); |
70b03506 AD |
106 | |
107 | my $params = { ip => $ip, | |
108 | subnetId => $internalid, | |
ceb972a9 AD |
109 | hostname => $hostname, |
110 | description => $description, | |
70b03506 | 111 | }; |
34c4c6d7 | 112 | $params->{is_gateway} = 1 if $is_gateway; |
e9365ab0 | 113 | $params->{mac} = $mac if $mac; |
70b03506 AD |
114 | |
115 | eval { | |
167dc03f | 116 | PVE::Network::SDN::api_request("POST", "$url/addresses/", $headers, $params); |
70b03506 AD |
117 | }; |
118 | ||
119 | if ($@) { | |
34c4c6d7 AD |
120 | if($is_gateway) { |
121 | die "error add subnet ip to ipam: ip $ip already exist: $@" if !is_ip_gateway($url, $ip, $headers) && !$noerr; | |
122 | } else { | |
123 | die "error add subnet ip to ipam: ip $ip already exist: $@" if !$noerr; | |
124 | } | |
70b03506 AD |
125 | } |
126 | } | |
127 | ||
dd54b5a3 | 128 | sub update_ip { |
04f6db9a | 129 | my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway, $noerr) = @_; |
dd54b5a3 AD |
130 | |
131 | my $cidr = $subnet->{cidr}; | |
132 | my $url = $plugin_config->{url}; | |
133 | my $token = $plugin_config->{token}; | |
134 | my $section = $plugin_config->{section}; | |
135 | my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Token' => $token]; | |
136 | ||
137 | my $ip_id = get_ip_id($url, $ip, $headers); | |
138 | die "can't find ip addresse in ipam" if !$ip_id; | |
139 | ||
140 | my $params = { | |
dd54b5a3 AD |
141 | hostname => $hostname, |
142 | description => $description, | |
143 | }; | |
34c4c6d7 | 144 | $params->{is_gateway} = 1 if $is_gateway; |
dd54b5a3 AD |
145 | $params->{mac} = $mac if $mac; |
146 | ||
147 | eval { | |
167dc03f | 148 | PVE::Network::SDN::api_request("PATCH", "$url/addresses/$ip_id", $headers, $params); |
dd54b5a3 AD |
149 | }; |
150 | ||
151 | if ($@) { | |
04f6db9a | 152 | die "ipam: error update subnet ip $ip: $@" if !$noerr; |
dd54b5a3 AD |
153 | } |
154 | } | |
155 | ||
70b03506 | 156 | sub add_next_freeip { |
04f6db9a | 157 | my ($class, $plugin_config, $subnetid, $subnet, $hostname, $mac, $description, $noerr) = @_; |
70b03506 | 158 | |
e8736dac AD |
159 | my $cidr = $subnet->{cidr}; |
160 | my $mask = $subnet->{mask}; | |
70b03506 AD |
161 | my $url = $plugin_config->{url}; |
162 | my $token = $plugin_config->{token}; | |
163 | my $section = $plugin_config->{section}; | |
164 | my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Token' => $token]; | |
165 | ||
3f02d3ec | 166 | my $internalid = get_prefix_id($url, $cidr, $headers); |
70b03506 | 167 | |
ceb972a9 AD |
168 | my $params = { hostname => $hostname, |
169 | description => $description, | |
170 | }; | |
70b03506 | 171 | |
e9365ab0 AD |
172 | $params->{mac} = $mac if $mac; |
173 | ||
70b03506 AD |
174 | my $ip = undef; |
175 | eval { | |
167dc03f | 176 | my $result = PVE::Network::SDN::api_request("POST", "$url/addresses/first_free/$internalid/", $headers, $params); |
70b03506 AD |
177 | $ip = $result->{data}; |
178 | }; | |
179 | ||
180 | if ($@) { | |
04f6db9a | 181 | die "can't find free ip in subnet $cidr: $@" if !$noerr; |
70b03506 AD |
182 | } |
183 | ||
04f6db9a | 184 | return "$ip/$mask" if $ip && $mask; |
70b03506 AD |
185 | } |
186 | ||
187 | sub del_ip { | |
04f6db9a | 188 | my ($class, $plugin_config, $subnetid, $subnet, $ip, $noerr) = @_; |
70b03506 AD |
189 | |
190 | return if !$ip; | |
191 | ||
192 | my $url = $plugin_config->{url}; | |
193 | my $token = $plugin_config->{token}; | |
194 | my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Token' => $token]; | |
195 | ||
196 | my $ip_id = get_ip_id($url, $ip, $headers); | |
197 | return if !$ip_id; | |
198 | ||
199 | eval { | |
167dc03f | 200 | PVE::Network::SDN::api_request("DELETE", "$url/addresses/$ip_id", $headers); |
70b03506 AD |
201 | }; |
202 | if ($@) { | |
04f6db9a | 203 | die "error delete ip $ip: $@" if !$noerr; |
70b03506 AD |
204 | } |
205 | } | |
206 | ||
207 | sub verify_api { | |
208 | my ($class, $plugin_config) = @_; | |
209 | ||
210 | my $url = $plugin_config->{url}; | |
211 | my $token = $plugin_config->{token}; | |
212 | my $sectionid = $plugin_config->{section}; | |
213 | my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Token' => $token]; | |
214 | ||
215 | eval { | |
167dc03f | 216 | PVE::Network::SDN::api_request("GET", "$url/sections/$sectionid", $headers); |
70b03506 AD |
217 | }; |
218 | if ($@) { | |
219 | die "Can't connect to phpipam api: $@"; | |
220 | } | |
221 | } | |
222 | ||
223 | sub on_update_hook { | |
224 | my ($class, $plugin_config) = @_; | |
225 | ||
226 | PVE::Network::SDN::Ipams::PhpIpamPlugin::verify_api($class, $plugin_config); | |
227 | } | |
228 | ||
229 | ||
230 | #helpers | |
231 | ||
3f02d3ec | 232 | sub get_prefix_id { |
70b03506 AD |
233 | my ($url, $cidr, $headers) = @_; |
234 | ||
167dc03f | 235 | my $result = PVE::Network::SDN::api_request("GET", "$url/subnets/cidr/$cidr", $headers); |
70b03506 AD |
236 | my $data = @{$result->{data}}[0]; |
237 | my $internalid = $data->{id}; | |
238 | return $internalid; | |
239 | } | |
240 | ||
241 | sub get_ip_id { | |
242 | my ($url, $ip, $headers) = @_; | |
167dc03f | 243 | my $result = PVE::Network::SDN::api_request("GET", "$url/addresses/search/$ip", $headers); |
70b03506 AD |
244 | my $data = @{$result->{data}}[0]; |
245 | my $ip_id = $data->{id}; | |
246 | return $ip_id; | |
247 | } | |
248 | ||
34c4c6d7 AD |
249 | sub is_ip_gateway { |
250 | my ($url, $ip, $headers) = @_; | |
251 | my $result = PVE::Network::SDN::api_request("GET", "$url/addresses/search/$ip", $headers); | |
252 | my $data = @{$result->{data}}[0]; | |
253 | my $is_gateway = $data->{is_gateway}; | |
254 | return $is_gateway; | |
255 | } | |
256 | ||
70b03506 AD |
257 | 1; |
258 | ||
259 |