]> git.proxmox.com Git - pve-network.git/blob - PVE/Network/SDN/Subnets.pm
use statements cleanup
[pve-network.git] / PVE / Network / SDN / Subnets.pm
1 package PVE::Network::SDN::Subnets;
2
3 use strict;
4 use warnings;
5
6 use Net::Subnet qw(subnet_matcher);
7 use Net::IP;
8
9 use PVE::Cluster qw(cfs_read_file cfs_write_file cfs_lock_file);
10 use PVE::Network::SDN::Dns;
11 use PVE::Network::SDN::Ipams;
12
13 use PVE::Network::SDN::SubnetPlugin;
14 PVE::Network::SDN::SubnetPlugin->register();
15 PVE::Network::SDN::SubnetPlugin->init();
16
17 sub sdn_subnets_config {
18 my ($cfg, $id, $noerr) = @_;
19
20 die "no sdn subnet ID specified\n" if !$id;
21
22 my $scfg = $cfg->{ids}->{$id};
23 die "sdn subnet '$id' does not exist\n" if (!$noerr && !$scfg);
24
25 if($scfg) {
26 my ($zone, $network, $mask) = split(/-/, $id);
27 $scfg->{cidr} = "$network/$mask";
28 $scfg->{zone} = $zone;
29 $scfg->{network} = $network;
30 $scfg->{mask} = $mask;
31 }
32
33 return $scfg;
34 }
35
36 sub config {
37 my $config = cfs_read_file("sdn/subnets.cfg");
38 }
39
40 sub write_config {
41 my ($cfg) = @_;
42
43 cfs_write_file("sdn/subnets.cfg", $cfg);
44 }
45
46 sub sdn_subnets_ids {
47 my ($cfg) = @_;
48
49 return sort keys %{$cfg->{ids}};
50 }
51
52 sub complete_sdn_subnet {
53 my ($cmdname, $pname, $cvalue) = @_;
54
55 my $cfg = PVE::Network::SDN::Subnets::config();
56
57 return $cmdname eq 'add' ? [] : [ PVE::Network::SDN::Subnets::sdn_subnets_ids($cfg) ];
58 }
59
60 sub get_subnet {
61 my ($subnetid, $running) = @_;
62
63 my $cfg = {};
64 if($running) {
65 my $cfg = PVE::Network::SDN::config();
66 $cfg = $cfg->{subnets};
67 } else {
68 $cfg = PVE::Network::SDN::Subnets::config();
69 }
70
71 my $subnet = PVE::Network::SDN::Subnets::sdn_subnets_config($cfg, $subnetid, 1);
72 return $subnet;
73 }
74
75 sub find_ip_subnet {
76 my ($ip, $mask, $subnets) = @_;
77
78 my $subnet = undef;
79 my $subnetid = undef;
80
81 foreach my $id (sort keys %{$subnets}) {
82
83 next if $mask ne $subnets->{$id}->{mask};
84 my $cidr = $subnets->{$id}->{cidr};
85 my $subnet_matcher = subnet_matcher($cidr);
86 next if !$subnet_matcher->($ip);
87 $subnet = $subnets->{$id};
88 $subnetid = $id;
89 last;
90 }
91 die "can't find any subnet for ip $ip" if !$subnet;
92
93 return ($subnetid, $subnet);
94 }
95
96 my $verify_dns_zone = sub {
97 my ($zone, $dns) = @_;
98
99 return if !$zone || !$dns;
100
101 my $dns_cfg = PVE::Network::SDN::Dns::config();
102 my $plugin_config = $dns_cfg->{ids}->{$dns};
103 my $plugin = PVE::Network::SDN::Dns::Plugin->lookup($plugin_config->{type});
104 $plugin->verify_zone($plugin_config, $zone);
105 };
106
107 my $get_reversedns_zone = sub {
108 my ($subnetid, $subnet, $dns, $ip) = @_;
109
110 return if !$subnetid || !$dns || !$ip;
111
112 my $dns_cfg = PVE::Network::SDN::Dns::config();
113 my $plugin_config = $dns_cfg->{ids}->{$dns};
114 my $plugin = PVE::Network::SDN::Dns::Plugin->lookup($plugin_config->{type});
115 $plugin->get_reversedns_zone($plugin_config, $subnetid, $subnet, $ip);
116 };
117
118 my $add_dns_record = sub {
119 my ($zone, $dns, $hostname, $ip) = @_;
120 return if !$zone || !$dns || !$hostname || !$ip;
121
122 my $dns_cfg = PVE::Network::SDN::Dns::config();
123 my $plugin_config = $dns_cfg->{ids}->{$dns};
124 my $plugin = PVE::Network::SDN::Dns::Plugin->lookup($plugin_config->{type});
125 $plugin->add_a_record($plugin_config, $zone, $hostname, $ip);
126
127 };
128
129 my $add_dns_ptr_record = sub {
130 my ($reversezone, $zone, $dns, $hostname, $ip) = @_;
131
132 return if !$zone || !$reversezone || !$dns || !$hostname || !$ip;
133
134 $hostname .= ".$zone";
135 my $dns_cfg = PVE::Network::SDN::Dns::config();
136 my $plugin_config = $dns_cfg->{ids}->{$dns};
137 my $plugin = PVE::Network::SDN::Dns::Plugin->lookup($plugin_config->{type});
138 $plugin->add_ptr_record($plugin_config, $reversezone, $hostname, $ip);
139 };
140
141 my $del_dns_record = sub {
142 my ($zone, $dns, $hostname, $ip) = @_;
143
144 return if !$zone || !$dns || !$hostname || !$ip;
145
146 my $dns_cfg = PVE::Network::SDN::Dns::config();
147 my $plugin_config = $dns_cfg->{ids}->{$dns};
148 my $plugin = PVE::Network::SDN::Dns::Plugin->lookup($plugin_config->{type});
149 $plugin->del_a_record($plugin_config, $zone, $hostname, $ip);
150 };
151
152 my $del_dns_ptr_record = sub {
153 my ($reversezone, $dns, $ip) = @_;
154
155 return if !$reversezone || !$dns || !$ip;
156
157 my $dns_cfg = PVE::Network::SDN::Dns::config();
158 my $plugin_config = $dns_cfg->{ids}->{$dns};
159 my $plugin = PVE::Network::SDN::Dns::Plugin->lookup($plugin_config->{type});
160 $plugin->del_ptr_record($plugin_config, $reversezone, $ip);
161 };
162
163 sub next_free_ip {
164 my ($zone, $subnetid, $subnet, $hostname, $description) = @_;
165
166 my $cidr = undef;
167 my $ip = undef;
168 $description = '' if !$description;
169
170 my $ipamid = $zone->{ipam};
171 my $dns = $zone->{dns};
172 my $dnszone = $zone->{dnszone};
173 my $reversedns = $zone->{reversedns};
174 my $dnszoneprefix = $subnet->{dnszoneprefix};
175
176 $hostname .= ".$dnszoneprefix" if $dnszoneprefix;
177
178 #verify dns zones before ipam
179 &$verify_dns_zone($dnszone, $dns);
180
181 if($ipamid) {
182 my $ipam_cfg = PVE::Network::SDN::Ipams::config();
183 my $plugin_config = $ipam_cfg->{ids}->{$ipamid};
184 my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
185 eval {
186 $cidr = $plugin->add_next_freeip($plugin_config, $subnetid, $subnet, $hostname, $description);
187 ($ip, undef) = split(/\//, $cidr);
188 };
189 die $@ if $@;
190 }
191
192 eval {
193 my $reversednszone = &$get_reversedns_zone($subnetid, $subnet, $reversedns, $ip);
194
195 #add dns
196 &$add_dns_record($dnszone, $dns, $hostname, $ip);
197 #add reverse dns
198 &$add_dns_ptr_record($reversednszone, $dnszone, $reversedns, $hostname, $ip);
199 };
200 if ($@) {
201 #rollback
202 my $err = $@;
203 eval {
204 PVE::Network::SDN::Subnets::del_ip($subnetid, $subnet, $ip, $hostname)
205 };
206 die $err;
207 }
208 return $cidr;
209 }
210
211 sub add_ip {
212 my ($zone, $subnetid, $subnet, $ip, $hostname, $description) = @_;
213
214 return if !$subnet || !$ip;
215
216 my $ipamid = $zone->{ipam};
217 my $dns = $zone->{dns};
218 my $dnszone = $zone->{dnszone};
219 my $reversedns = $zone->{reversedns};
220 my $reversednszone = &$get_reversedns_zone($subnetid, $subnet, $reversedns, $ip);
221 my $dnszoneprefix = $subnet->{dnszoneprefix};
222
223 $hostname .= ".$dnszoneprefix" if $dnszoneprefix;
224
225 #verify dns zones before ipam
226 &$verify_dns_zone($dnszone, $dns);
227 &$verify_dns_zone($reversednszone, $reversedns);
228
229 if ($ipamid) {
230 my $ipam_cfg = PVE::Network::SDN::Ipams::config();
231 my $plugin_config = $ipam_cfg->{ids}->{$ipamid};
232 my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
233 eval {
234 $plugin->add_ip($plugin_config, $subnetid, $subnet, $ip, $hostname, $description);
235 };
236 die $@ if $@;
237 }
238
239 eval {
240 #add dns
241 &$add_dns_record($dnszone, $dns, $hostname, $ip);
242 #add reverse dns
243 &$add_dns_ptr_record($reversednszone, $dnszone, $reversedns, $hostname, $ip);
244 };
245 if ($@) {
246 #rollback
247 my $err = $@;
248 eval {
249 PVE::Network::SDN::Subnets::del_ip($subnetid, $subnet, $ip, $hostname)
250 };
251 die $err;
252 }
253 }
254
255 sub del_ip {
256 my ($zone, $subnetid, $subnet, $ip, $hostname) = @_;
257
258 return if !$subnet;
259
260 my $ipamid = $zone->{ipam};
261 my $dns = $zone->{dns};
262 my $dnszone = $zone->{dnszone};
263 my $reversedns = $zone->{reversedns};
264 my $reversednszone = &$get_reversedns_zone($subnetid, $subnet, $reversedns, $ip);
265 my $dnszoneprefix = $subnet->{dnszoneprefix};
266 $hostname .= ".$dnszoneprefix" if $dnszoneprefix;
267
268
269 &$verify_dns_zone($dnszone, $dns);
270 &$verify_dns_zone($reversednszone, $reversedns);
271
272 if ($ipamid) {
273 my $ipam_cfg = PVE::Network::SDN::Ipams::config();
274 my $plugin_config = $ipam_cfg->{ids}->{$ipamid};
275 my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
276 $plugin->del_ip($plugin_config, $subnetid, $subnet, $ip);
277 }
278
279 eval {
280 &$del_dns_record($dnszone, $dns, $hostname, $ip);
281 &$del_dns_ptr_record($reversednszone, $reversedns, $ip);
282 };
283 if ($@) {
284 warn $@;
285 }
286 }
287
288 1;