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