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