]>
git.proxmox.com Git - pve-network.git/blob - PVE/Network/SDN/Ipams/PVEPlugin.pm
1 package PVE
::Network
::SDN
::Ipams
::PVEPlugin
;
6 use PVE
::Cluster
qw(cfs_read_file cfs_write_file cfs_register_file cfs_lock_file);
9 use NetAddr
::IP
qw(:lower);
14 use base
('PVE::Network::SDN::Ipams::Plugin');
17 my $ipamdb_file = "priv/ipam.db";
19 PVE
::Cluster
::cfs_register_file
($ipamdb_file,
20 sub { PVE
::Network
::SDN
::Ipams
::PVEPlugin-
>parse_config(@_); },
21 sub { PVE
::Network
::SDN
::Ipams
::PVEPlugin-
>write_config(@_); });
33 # Plugin implementation
36 my ($class, $plugin_config, $subnetid, $subnet) = @_;
38 my $cidr = $subnet->{cidr
};
39 my $zone = $subnet->{zone
};
40 my $gateway = $subnet->{gateway
};
43 cfs_lock_file
($ipamdb_file, undef, sub {
47 $db->{zones
}->{$zone} = {} if !$db->{zones
}->{$zone};
48 my $zonedb = $db->{zones
}->{$zone};
50 if(!$zonedb->{subnets
}->{$cidr}) {
52 $zonedb->{subnets
}->{$cidr}->{ips
} = {};
60 my ($class, $plugin_config, $subnetid, $subnet) = @_;
62 my $cidr = $subnet->{cidr
};
63 my $zone = $subnet->{zone
};
65 cfs_lock_file
($ipamdb_file, undef, sub {
69 my $dbzone = $db->{zones
}->{$zone};
70 die "zone '$zone' doesn't exist in IPAM DB\n" if !$dbzone;
71 my $dbsubnet = $dbzone->{subnets
}->{$cidr};
72 die "subnet '$cidr' doesn't exist in IPAM DB\n" if !$dbsubnet;
74 die "cannot delete subnet '$cidr', not empty\n" if keys %{$dbsubnet->{ips
}} > 0;
76 delete $dbzone->{subnets
}->{$cidr};
85 my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway) = @_;
87 my $cidr = $subnet->{cidr
};
88 my $zone = $subnet->{zone
};
90 cfs_lock_file
($ipamdb_file, undef, sub {
93 my $dbzone = $db->{zones
}->{$zone};
94 die "zone '$zone' doesn't exist in IPAM DB\n" if !$dbzone;
95 my $dbsubnet = $dbzone->{subnets
}->{$cidr};
96 die "subnet '$cidr' doesn't exist in IPAM DB\n" if !$dbsubnet;
98 die "IP '$ip' already exist\n" if (!$is_gateway && defined($dbsubnet->{ips
}->{$ip})) || ($is_gateway && defined($dbsubnet->{ips
}->{$ip}) && !defined($dbsubnet->{ips
}->{$ip}->{gateway
}));
99 $dbsubnet->{ips
}->{$ip} = {};
100 $dbsubnet->{ips
}->{$ip} = {gateway
=> 1} if $is_gateway;
108 my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway) = @_;
112 sub add_next_freeip
{
113 my ($class, $plugin_config, $subnetid, $subnet, $hostname, $mac, $description) = @_;
115 my $cidr = $subnet->{cidr
};
116 my $network = $subnet->{network
};
117 my $zone = $subnet->{zone
};
118 my $mask = $subnet->{mask
};
121 cfs_lock_file
($ipamdb_file, undef, sub {
124 my $dbzone = $db->{zones
}->{$zone};
125 die "zone '$zone' doesn't exist in IPAM DB\n" if !$dbzone;
126 my $dbsubnet = $dbzone->{subnets
}->{$cidr};
127 die "subnet '$cidr' doesn't exist in IPAM DB" if !$dbsubnet;
129 if (Net
::IP
::ip_is_ipv4
($network) && $mask == 32) {
130 die "cannot find free IP in subnet '$cidr'\n" if defined($dbsubnet->{ips
}->{$network});
133 my $iplist = NetAddr
::IP-
>new($cidr);
134 my $lastip = $iplist->last()->canon();
135 $iplist++ if Net
::IP
::ip_is_ipv4
($network); #skip network address for ipv4
137 my $ip = $iplist->canon();
138 if (defined($dbsubnet->{ips
}->{$ip})) {
139 last if $ip eq $lastip;
148 die "can't find free ip in subnet '$cidr'\n" if !$freeip;
150 $dbsubnet->{ips
}->{$freeip} = {};
156 return "$freeip/$mask";
160 my ($class, $plugin_config, $subnetid, $subnet, $ip) = @_;
162 my $cidr = $subnet->{cidr
};
163 my $zone = $subnet->{zone
};
165 cfs_lock_file
($ipamdb_file, undef, sub {
168 die "zone $zone don't exist in ipam db" if !$db->{zones
}->{$zone};
169 my $dbzone = $db->{zones
}->{$zone};
170 die "subnet $cidr don't exist in ipam db" if !$dbzone->{subnets
}->{$cidr};
171 my $dbsubnet = $dbzone->{subnets
}->{$cidr};
173 die "IP '$ip' does not exist in IPAM DB\n" if !defined($dbsubnet->{ips
}->{$ip});
174 delete $dbsubnet->{ips
}->{$ip};
184 my $db = cfs_read_file
($ipamdb_file);
191 my $json = to_json
($cfg);
192 cfs_write_file
($ipamdb_file, $json);
196 my ($class, $filename, $cfg) = @_;
202 my ($class, $filename, $raw) = @_;
204 $raw = '{}' if !defined($raw) ||$raw eq '';
205 my $cfg = from_json
($raw);