]> git.proxmox.com Git - pve-network.git/blame - PVE/Network/SDN/Ipams/NetboxPlugin.pm
subnets/ipam : fix is_gateway
[pve-network.git] / PVE / Network / SDN / Ipams / NetboxPlugin.pm
CommitLineData
70b03506
AD
1package PVE::Network::SDN::Ipams::NetboxPlugin;
2
3use strict;
4use warnings;
5use PVE::INotify;
6use PVE::Cluster;
7use PVE::Tools;
8
9use base('PVE::Network::SDN::Ipams::Plugin');
10
11sub type {
12 return 'netbox';
13}
14
15sub properties {
16 return {
17 };
18}
19
20sub options {
21
22 return {
23 url => { optional => 0},
24 token => { optional => 0 },
25 };
26}
27
28# Plugin implementation
29
30sub add_subnet {
04f6db9a 31 my ($class, $plugin_config, $subnetid, $subnet, $noerr) = @_;
70b03506 32
e8736dac 33 my $cidr = $subnet->{cidr};
70b03506
AD
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) {
70b03506
AD
43
44 my $params = { prefix => $cidr };
45
46 eval {
167dc03f 47 my $result = PVE::Network::SDN::api_request("POST", "$url/ipam/prefixes/", $headers, $params);
70b03506
AD
48 };
49 if ($@) {
04f6db9a 50 die "error add subnet to ipam: $@" if !$noerr;
70b03506
AD
51 }
52 }
53
54}
55
56sub del_subnet {
04f6db9a 57 my ($class, $plugin_config, $subnetid, $subnet, $noerr) = @_;
70b03506 58
e8736dac 59 my $cidr = $subnet->{cidr};
70b03506
AD
60 my $url = $plugin_config->{url};
61 my $token = $plugin_config->{token};
62 my $gateway = $subnet->{gateway};
63 my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "token $token"];
64
65 my $internalid = get_prefix_id($url, $cidr, $headers);
66 return if !$internalid;
70b03506 67
e8736dac 68 return; #fixme: check that prefix is empty exluding gateway, before delete
70b03506
AD
69
70 eval {
167dc03f 71 PVE::Network::SDN::api_request("DELETE", "$url/ipam/prefixes/$internalid/", $headers);
70b03506
AD
72 };
73 if ($@) {
04f6db9a 74 die "error deleting subnet from ipam: $@" if !$noerr;
70b03506
AD
75 }
76
77}
78
79sub add_ip {
04f6db9a 80 my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway, $noerr) = @_;
70b03506 81
e8736dac 82 my $mask = $subnet->{mask};
70b03506
AD
83 my $url = $plugin_config->{url};
84 my $token = $plugin_config->{token};
85 my $section = $plugin_config->{section};
86 my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "token $token"];
e9365ab0 87 $description .= " mac:$mac" if $mac && $description;
70b03506 88
ceb972a9 89 my $params = { address => "$ip/$mask", dns_name => $hostname, description => $description };
70b03506
AD
90
91 eval {
167dc03f 92 PVE::Network::SDN::api_request("POST", "$url/ipam/ip-addresses/", $headers, $params);
70b03506
AD
93 };
94
95 if ($@) {
34c4c6d7
AD
96 if($is_gateway) {
97 die "error add subnet ip to ipam: ip $ip already exist: $@" if !is_ip_gateway($url, $ip, $headers) && !$noerr;
98 } else {
99 die "error add subnet ip to ipam: ip already exist: $@" if !$noerr;
100 }
70b03506
AD
101 }
102}
103
dd54b5a3 104sub update_ip {
04f6db9a 105 my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway, $noerr) = @_;
dd54b5a3
AD
106
107 my $mask = $subnet->{mask};
108 my $url = $plugin_config->{url};
109 my $token = $plugin_config->{token};
110 my $section = $plugin_config->{section};
111 my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "token $token"];
112 $description .= " mac:$mac" if $mac && $description;
113
114 my $params = { address => "$ip/$mask", dns_name => $hostname, description => $description };
115
116 my $ip_id = get_ip_id($url, $ip, $headers);
117 die "can't find ip $ip in ipam" if !$ip_id;
118
119 eval {
167dc03f 120 PVE::Network::SDN::api_request("PATCH", "$url/ipam/ip-addresses/$ip_id/", $headers, $params);
dd54b5a3
AD
121 };
122 if ($@) {
04f6db9a 123 die "error update ip $ip : $@" if !$noerr;
dd54b5a3
AD
124 }
125}
126
70b03506 127sub add_next_freeip {
04f6db9a 128 my ($class, $plugin_config, $subnetid, $subnet, $hostname, $mac, $description, $noerr) = @_;
70b03506 129
e8736dac
AD
130 my $cidr = $subnet->{cidr};
131
70b03506
AD
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 $internalid = get_prefix_id($url, $cidr, $headers);
e9365ab0 137 $description .= " mac:$mac" if $mac && $description;
70b03506 138
ceb972a9 139 my $params = { dns_name => $hostname, description => $description };
70b03506
AD
140
141 my $ip = undef;
142 eval {
167dc03f 143 my $result = PVE::Network::SDN::api_request("POST", "$url/ipam/prefixes/$internalid/available-ips/", $headers, $params);
70b03506
AD
144 $ip = $result->{address};
145 };
146
147 if ($@) {
04f6db9a 148 die "can't find free ip in subnet $cidr: $@" if !$noerr;
70b03506
AD
149 }
150
151 return $ip;
152}
153
154sub del_ip {
04f6db9a 155 my ($class, $plugin_config, $subnetid, $subnet, $ip, $noerr) = @_;
70b03506
AD
156
157 return if !$ip;
158
159 my $url = $plugin_config->{url};
160 my $token = $plugin_config->{token};
161 my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "token $token"];
162
163 my $ip_id = get_ip_id($url, $ip, $headers);
164 die "can't find ip $ip in ipam" if !$ip_id;
165
166 eval {
167dc03f 167 PVE::Network::SDN::api_request("DELETE", "$url/ipam/ip-addresses/$ip_id/", $headers);
70b03506
AD
168 };
169 if ($@) {
04f6db9a 170 die "error delete ip $ip : $@" if !$noerr;
70b03506
AD
171 }
172}
173
174sub verify_api {
175 my ($class, $plugin_config) = @_;
176
177 my $url = $plugin_config->{url};
178 my $token = $plugin_config->{token};
179 my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "token $token"];
180
181
182 eval {
167dc03f 183 PVE::Network::SDN::api_request("GET", "$url/ipam/aggregates/", $headers);
70b03506
AD
184 };
185 if ($@) {
186 die "Can't connect to netbox api: $@";
187 }
188}
189
190sub on_update_hook {
191 my ($class, $plugin_config) = @_;
192
193 PVE::Network::SDN::Ipams::NetboxPlugin::verify_api($class, $plugin_config);
194}
195
196#helpers
197
198sub get_prefix_id {
199 my ($url, $cidr, $headers) = @_;
200
167dc03f 201 my $result = PVE::Network::SDN::api_request("GET", "$url/ipam/prefixes/?q=$cidr", $headers);
70b03506
AD
202 my $data = @{$result->{results}}[0];
203 my $internalid = $data->{id};
204 return $internalid;
205}
206
207sub get_ip_id {
208 my ($url, $ip, $headers) = @_;
167dc03f 209 my $result = PVE::Network::SDN::api_request("GET", "$url/ipam/ip-addresses/?q=$ip", $headers);
70b03506
AD
210 my $data = @{$result->{results}}[0];
211 my $ip_id = $data->{id};
212 return $ip_id;
213}
214
34c4c6d7
AD
215sub is_ip_gateway {
216 my ($url, $ip, $headers) = @_;
217 my $result = PVE::Network::SDN::api_request("GET", "$url/addresses/search/$ip", $headers);
218 my $data = @{$result->{data}}[0];
219 my $description = $data->{description};
220 my $is_gateway = 1 if $description eq 'gateway';
221 return $is_gateway;
222}
70b03506
AD
223
2241;
225
226