+++ /dev/null
-package PVE::Network::SDN::Subnets;
-
-use strict;
-use warnings;
-
-use Net::Subnet qw(subnet_matcher);
-use Net::IP;
-use NetAddr::IP qw(:lower);
-
-use PVE::Cluster qw(cfs_read_file cfs_write_file cfs_lock_file);
-use PVE::Network::SDN::Dns;
-use PVE::Network::SDN::Ipams;
-
-use PVE::Network::SDN::SubnetPlugin;
-PVE::Network::SDN::SubnetPlugin->register();
-PVE::Network::SDN::SubnetPlugin->init();
-
-sub sdn_subnets_config {
- my ($cfg, $id, $noerr) = @_;
-
- die "no sdn subnet ID specified\n" if !$id;
-
- my $scfg = $cfg->{ids}->{$id};
- die "sdn subnet '$id' does not exist\n" if (!$noerr && !$scfg);
-
- if($scfg) {
- my ($zone, $network, $mask) = split(/-/, $id);
- $scfg->{cidr} = "$network/$mask";
- $scfg->{zone} = $zone;
- $scfg->{network} = $network;
- $scfg->{mask} = $mask;
- }
-
- return $scfg;
-}
-
-sub config {
- my $config = cfs_read_file("sdn/subnets.cfg");
-}
-
-sub write_config {
- my ($cfg) = @_;
-
- cfs_write_file("sdn/subnets.cfg", $cfg);
-}
-
-sub sdn_subnets_ids {
- my ($cfg) = @_;
-
- return sort keys %{$cfg->{ids}};
-}
-
-sub complete_sdn_subnet {
- my ($cmdname, $pname, $cvalue) = @_;
-
- my $cfg = PVE::Network::SDN::Subnets::config();
-
- return $cmdname eq 'add' ? [] : [ PVE::Network::SDN::Subnets::sdn_subnets_ids($cfg) ];
-}
-
-sub get_subnet {
- my ($subnetid, $running) = @_;
-
- my $cfg = {};
- if($running) {
- my $cfg = PVE::Network::SDN::running_config();
- $cfg = $cfg->{subnets};
- } else {
- $cfg = PVE::Network::SDN::Subnets::config();
- }
-
- my $subnet = PVE::Network::SDN::Subnets::sdn_subnets_config($cfg, $subnetid, 1);
- return $subnet;
-}
-
-sub find_ip_subnet {
- my ($ip, $mask, $subnets) = @_;
-
- my $subnet = undef;
- my $subnetid = undef;
-
- foreach my $id (sort keys %{$subnets}) {
-
- next if $mask ne $subnets->{$id}->{mask};
- my $cidr = $subnets->{$id}->{cidr};
- my $subnet_matcher = subnet_matcher($cidr);
- next if !$subnet_matcher->($ip);
- $subnet = $subnets->{$id};
- $subnetid = $id;
- last;
- }
- die "can't find any subnet for ip $ip" if !$subnet;
-
- return ($subnetid, $subnet);
-}
-
-sub verify_dns_zone {
- my ($zone, $dns) = @_;
-
- return if !$zone || !$dns;
-
- my $dns_cfg = PVE::Network::SDN::Dns::config();
- my $plugin_config = $dns_cfg->{ids}->{$dns};
- my $plugin = PVE::Network::SDN::Dns::Plugin->lookup($plugin_config->{type});
- $plugin->verify_zone($plugin_config, $zone);
-}
-
-sub get_reversedns_zone {
- my ($subnetid, $subnet, $dns, $ip) = @_;
-
- return if !$subnetid || !$dns || !$ip;
-
- my $dns_cfg = PVE::Network::SDN::Dns::config();
- my $plugin_config = $dns_cfg->{ids}->{$dns};
- my $plugin = PVE::Network::SDN::Dns::Plugin->lookup($plugin_config->{type});
- $plugin->get_reversedns_zone($plugin_config, $subnetid, $subnet, $ip);
-}
-
-sub add_dns_record {
- my ($zone, $dns, $hostname, $ip) = @_;
- return if !$zone || !$dns || !$hostname || !$ip;
-
- my $dns_cfg = PVE::Network::SDN::Dns::config();
- my $plugin_config = $dns_cfg->{ids}->{$dns};
- my $plugin = PVE::Network::SDN::Dns::Plugin->lookup($plugin_config->{type});
- $plugin->add_a_record($plugin_config, $zone, $hostname, $ip);
-
-}
-
-sub add_dns_ptr_record {
- my ($reversezone, $zone, $dns, $hostname, $ip) = @_;
-
- return if !$zone || !$reversezone || !$dns || !$hostname || !$ip;
-
- $hostname .= ".$zone";
- my $dns_cfg = PVE::Network::SDN::Dns::config();
- my $plugin_config = $dns_cfg->{ids}->{$dns};
- my $plugin = PVE::Network::SDN::Dns::Plugin->lookup($plugin_config->{type});
- $plugin->add_ptr_record($plugin_config, $reversezone, $hostname, $ip);
-}
-
-sub del_dns_record {
- my ($zone, $dns, $hostname, $ip) = @_;
-
- return if !$zone || !$dns || !$hostname || !$ip;
-
- my $dns_cfg = PVE::Network::SDN::Dns::config();
- my $plugin_config = $dns_cfg->{ids}->{$dns};
- my $plugin = PVE::Network::SDN::Dns::Plugin->lookup($plugin_config->{type});
- $plugin->del_a_record($plugin_config, $zone, $hostname, $ip);
-}
-
-sub del_dns_ptr_record {
- my ($reversezone, $dns, $ip) = @_;
-
- return if !$reversezone || !$dns || !$ip;
-
- my $dns_cfg = PVE::Network::SDN::Dns::config();
- my $plugin_config = $dns_cfg->{ids}->{$dns};
- my $plugin = PVE::Network::SDN::Dns::Plugin->lookup($plugin_config->{type});
- $plugin->del_ptr_record($plugin_config, $reversezone, $ip);
-}
-
-sub add_subnet {
- my ($zone, $subnetid, $subnet) = @_;
-
- my $ipam = $zone->{ipam};
- return if !$ipam;
- my $ipam_cfg = PVE::Network::SDN::Ipams::config();
- my $plugin_config = $ipam_cfg->{ids}->{$ipam};
- my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
- $plugin->add_subnet($plugin_config, $subnetid, $subnet);
-}
-
-sub del_subnet {
- my ($zone, $subnetid, $subnet) = @_;
-
- my $ipam = $zone->{ipam};
- return if !$ipam;
- my $ipam_cfg = PVE::Network::SDN::Ipams::config();
- my $plugin_config = $ipam_cfg->{ids}->{$ipam};
- my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
- $plugin->del_subnet($plugin_config, $subnetid, $subnet);
-}
-
-sub next_free_ip {
- my ($zone, $subnetid, $subnet, $hostname, $mac, $description, $skipdns) = @_;
-
- my $cidr = undef;
- my $ip = undef;
- $description = '' if !$description;
-
- my $ipamid = $zone->{ipam};
- my $dns = $zone->{dns};
- my $dnszone = $zone->{dnszone};
- my $reversedns = $zone->{reversedns};
- my $dnszoneprefix = $subnet->{dnszoneprefix};
-
- $hostname .= ".$dnszoneprefix" if $dnszoneprefix;
-
- #verify dns zones before ipam
- verify_dns_zone($dnszone, $dns) if !$skipdns;
-
- if($ipamid) {
- my $ipam_cfg = PVE::Network::SDN::Ipams::config();
- my $plugin_config = $ipam_cfg->{ids}->{$ipamid};
- my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
- eval {
- $cidr = $plugin->add_next_freeip($plugin_config, $subnetid, $subnet, $hostname, $mac, $description);
- ($ip, undef) = split(/\//, $cidr);
- };
- die $@ if $@;
- }
-
- eval {
- my $reversednszone = get_reversedns_zone($subnetid, $subnet, $reversedns, $ip);
-
- if(!$skipdns) {
- #add dns
- add_dns_record($dnszone, $dns, $hostname, $ip);
- #add reverse dns
- add_dns_ptr_record($reversednszone, $dnszone, $reversedns, $hostname, $ip);
- }
- };
- if ($@) {
- #rollback
- my $err = $@;
- eval {
- PVE::Network::SDN::Subnets::del_ip($zone, $subnetid, $subnet, $ip, $hostname)
- };
- die $err;
- }
- return $cidr;
-}
-
-sub add_ip {
- my ($zone, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway, $skipdns) = @_;
-
- return if !$subnet || !$ip;
-
- my $ipaddr = NetAddr::IP->new($ip);
- $ip = $ipaddr->canon();
-
- my $ipamid = $zone->{ipam};
- my $dns = $zone->{dns};
- my $dnszone = $zone->{dnszone};
- my $reversedns = $zone->{reversedns};
- my $reversednszone = get_reversedns_zone($subnetid, $subnet, $reversedns, $ip);
- my $dnszoneprefix = $subnet->{dnszoneprefix};
-
- $hostname .= ".$dnszoneprefix" if $dnszoneprefix;
-
- #verify dns zones before ipam
- if(!$skipdns) {
- verify_dns_zone($dnszone, $dns);
- verify_dns_zone($reversednszone, $reversedns);
- }
-
- if ($ipamid) {
-
- my $ipam_cfg = PVE::Network::SDN::Ipams::config();
- my $plugin_config = $ipam_cfg->{ids}->{$ipamid};
- my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
-
- eval {
- $plugin->add_ip($plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway);
- };
- die $@ if $@;
- }
-
- eval {
- if(!$skipdns) {
- #add dns
- add_dns_record($dnszone, $dns, $hostname, $ip);
- #add reverse dns
- add_dns_ptr_record($reversednszone, $dnszone, $reversedns, $hostname, $ip);
- }
- };
- if ($@) {
- #rollback
- my $err = $@;
- eval {
- PVE::Network::SDN::Subnets::del_ip($zone, $subnetid, $subnet, $ip, $hostname)
- };
- die $err;
- }
-}
-
-sub update_ip {
- my ($zone, $subnetid, $subnet, $ip, $hostname, $oldhostname, $mac, $description, $skipdns) = @_;
-
- return if !$subnet || !$ip;
-
- my $ipaddr = NetAddr::IP->new($ip);
- $ip = $ipaddr->canon();
-
- my $ipamid = $zone->{ipam};
- my $dns = $zone->{dns};
- my $dnszone = $zone->{dnszone};
- my $reversedns = $zone->{reversedns};
- my $reversednszone = get_reversedns_zone($subnetid, $subnet, $reversedns, $ip);
- my $dnszoneprefix = $subnet->{dnszoneprefix};
-
- $hostname .= ".$dnszoneprefix" if $dnszoneprefix;
-
- #verify dns zones before ipam
- if(!$skipdns) {
- verify_dns_zone($dnszone, $dns);
- verify_dns_zone($reversednszone, $reversedns);
- }
-
- if ($ipamid) {
- my $ipam_cfg = PVE::Network::SDN::Ipams::config();
- my $plugin_config = $ipam_cfg->{ids}->{$ipamid};
- my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
- eval {
- $plugin->update_ip($plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description);
- };
- die $@ if $@;
- }
-
- return if $hostname eq $oldhostname;
-
- eval {
- if(!$skipdns) {
- #add dns
- del_dns_record($dnszone, $dns, $oldhostname, $ip);
- add_dns_record($dnszone, $dns, $hostname, $ip);
- #add reverse dns
- del_dns_ptr_record($reversednszone, $reversedns, $ip);
- add_dns_ptr_record($reversednszone, $dnszone, $reversedns, $hostname, $ip);
- }
- };
-}
-
-sub del_ip {
- my ($zone, $subnetid, $subnet, $ip, $hostname, $skipdns) = @_;
-
- return if !$subnet || !$ip;
-
- my $ipaddr = NetAddr::IP->new($ip);
- $ip = $ipaddr->canon();
-
- my $ipamid = $zone->{ipam};
- my $dns = $zone->{dns};
- my $dnszone = $zone->{dnszone};
- my $reversedns = $zone->{reversedns};
- my $reversednszone = get_reversedns_zone($subnetid, $subnet, $reversedns, $ip);
- my $dnszoneprefix = $subnet->{dnszoneprefix};
- $hostname .= ".$dnszoneprefix" if $dnszoneprefix;
-
- if(!$skipdns) {
- verify_dns_zone($dnszone, $dns);
- verify_dns_zone($reversednszone, $reversedns);
- }
-
- if ($ipamid) {
- my $ipam_cfg = PVE::Network::SDN::Ipams::config();
- my $plugin_config = $ipam_cfg->{ids}->{$ipamid};
- my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
- $plugin->del_ip($plugin_config, $subnetid, $subnet, $ip);
- }
-
- eval {
- if(!$skipdns) {
- del_dns_record($dnszone, $dns, $hostname, $ip);
- del_dns_ptr_record($reversednszone, $reversedns, $ip);
- }
- };
- if ($@) {
- warn $@;
- }
-}
-
-1;