]> git.proxmox.com Git - pve-network.git/blame - PVE/Network/SDN/SubnetPlugin.pm
add DNS plugin
[pve-network.git] / PVE / Network / SDN / SubnetPlugin.pm
CommitLineData
c33dd818
AD
1package PVE::Network::SDN::SubnetPlugin;
2
3use strict;
4use warnings;
5
6use PVE::Cluster qw(cfs_read_file cfs_write_file cfs_lock_file);
7use base qw(PVE::SectionConfig);
8use PVE::JSONSchema qw(get_standard_option);
9use PVE::Exception qw(raise raise_param_exc);
10use Net::Subnet qw(subnet_matcher);
11
12PVE::Cluster::cfs_register_file('sdn/subnets.cfg',
13 sub { __PACKAGE__->parse_config(@_); },
14 sub { __PACKAGE__->write_config(@_); });
15
16PVE::JSONSchema::register_standard_option('pve-sdn-subnet-id', {
17 description => "The SDN subnet object identifier.",
18 type => 'string', format => 'pve-sdn-subnet-id',
19 type => 'string'
20});
21
22PVE::JSONSchema::register_format('pve-sdn-subnet-id', \&parse_sdn_subnet_id);
23sub parse_sdn_subnet_id {
24 my ($id, $noerr) = @_;
25
26 my $cidr = $id =~ s/-/\//r;
27
28 if (!(PVE::JSONSchema::pve_verify_cidrv4($cidr, 1) ||
29 PVE::JSONSchema::pve_verify_cidrv6($cidr, 1)))
30 {
31 return undef if $noerr;
32 die "value does not look like a valid CIDR network\n";
33 }
34 return $id;
35}
36
37my $defaultData = {
38
39 propertyList => {
40 subnet => get_standard_option('pve-sdn-subnet-id',
41 { completion => \&PVE::Network::SDN::Subnets::complete_sdn_subnet }),
42 },
43};
44
45sub type {
46 return 'subnet';
47}
48
49sub private {
50 return $defaultData;
51}
52
53sub properties {
54 return {
55 gateway => {
56 type => 'string', format => 'ip',
57 description => "Subnet Gateway: Will be assign on vnet for layer3 zones",
58 },
59 snat => {
60 type => 'boolean',
61 description => "enable masquerade for this subnet if pve-firewall",
62 },
63 #cloudinit, dhcp options
64 routes => {
65 type => 'string',
66 description => "static routes [network=<network>:gateway=<ip>,network=<network>:gateway=<ip>,... ]",
67 },
ee4f339e
AD
68 dns => {
69 type => 'string',
70 description => "dns api server",
c33dd818 71 },
ee4f339e 72 reversedns => {
c33dd818 73 type => 'string',
ee4f339e 74 description => "reverse dns api server",
c33dd818 75 },
ee4f339e
AD
76 dnszone => {
77 type => 'string',
78 description => "dns domain zone ex: mydomain.com",
c33dd818 79 },
ee4f339e 80 reversednszone => {
c33dd818 81 type => 'string',
ee4f339e
AD
82 description => "reverse dns zone ex: 0.168.192.in-addr.arpa",
83 },
84 dnszoneprefix => {
85 type => 'string',
86 description => "dns domain zone prefix ex: 'adm' -> <hostname>.adm.mydomain.com",
c33dd818 87 },
70b03506 88 ipam => {
c33dd818
AD
89 type => 'string',
90 description => "use a specific ipam",
91 },
92 };
93}
94
95sub options {
96 return {
97 gateway => { optional => 1 },
98 routes => { optional => 1 },
c33dd818 99 snat => { optional => 1 },
ee4f339e
AD
100 dns => { optional => 1 },
101 reversedns => { optional => 1 },
102 dnszone => { optional => 1 },
103 reversednszone => { optional => 1 },
104 dnszoneprefix => { optional => 1 },
70b03506 105 ipam => { optional => 1 },
c33dd818
AD
106 };
107}
108
109sub on_update_hook {
110 my ($class, $subnetid, $subnet_cfg) = @_;
111
ee4f339e
AD
112 my $cidr = $subnetid =~ s/-/\//r;
113 my $subnet_matcher = subnet_matcher($cidr);
114
115 my $subnet = $subnet_cfg->{ids}->{$subnetid};
c33dd818 116
ee4f339e
AD
117 my $gateway = $subnet->{gateway};
118 my $dns = $subnet->{dns};
119 my $dnszone = $subnet->{dnszone};
120 my $reversedns = $subnet->{reversedns};
121 my $reversednszone = $subnet->{reversednszone};
122
123 #to: for /32 pointotoping, allow gateway outside the subnet
c33dd818 124 raise_param_exc({ gateway => "$gateway is not in subnet $subnet"}) if $gateway && !$subnet_matcher->($gateway);
70b03506 125
ee4f339e
AD
126 raise_param_exc({ dns => "missing dns provider"}) if $dnszone && !$dns;
127 raise_param_exc({ dnszone => "missing dns zone"}) if $dns && !$dnszone;
128 raise_param_exc({ reversedns => "missing dns provider"}) if $reversednszone && !$reversedns;
129 raise_param_exc({ reversednszone => "missing dns zone"}) if $reversedns && !$reversednszone;
130 raise_param_exc({ reversedns => "missing forward dns zone"}) if $reversednszone && !$dnszone;
131
c33dd818
AD
132}
133
58a7773a
AD
134sub on_delete_hook {
135 my ($class, $subnetid, $subnet_cfg, $vnet_cfg) = @_;
136
137 #verify if vnets have subnet
138 foreach my $vnetid (keys %{$vnet_cfg->{ids}}) {
139 my $vnet = $vnet_cfg->{ids}->{$vnetid};
140 my @subnets = PVE::Tools::split_list($vnet->{subnets}) if $vnet->{subnets};
141 foreach my $subnet (@subnets) {
142 my $id = $subnet =~ s/\//-/r;
143 raise_param_exc({ subnet => "$subnet is attached to vnet $vnetid"}) if $id eq $subnetid;
144 }
145 }
146
147 return;
148}
149
c33dd818 1501;