]>
Commit | Line | Data |
---|---|---|
f5eabba0 AD |
1 | package PVE::Network::SDN::Controllers; |
2 | ||
3 | use strict; | |
4 | use warnings; | |
5 | ||
6 | use Data::Dumper; | |
7 | use JSON; | |
8 | ||
9 | use PVE::Tools qw(extract_param dir_glob_regex run_command); | |
10 | use PVE::Cluster qw(cfs_read_file cfs_write_file cfs_lock_file); | |
11 | ||
12 | use PVE::Network::SDN::Vnets; | |
13 | use PVE::Network::SDN::Zones; | |
14 | ||
fa253735 | 15 | use PVE::Network::SDN::Controllers::EvpnPlugin; |
f23633dc | 16 | use PVE::Network::SDN::Controllers::BgpPlugin; |
f5eabba0 AD |
17 | use PVE::Network::SDN::Controllers::FaucetPlugin; |
18 | use PVE::Network::SDN::Controllers::Plugin; | |
fa253735 | 19 | PVE::Network::SDN::Controllers::EvpnPlugin->register(); |
f23633dc | 20 | PVE::Network::SDN::Controllers::BgpPlugin->register(); |
f5eabba0 AD |
21 | PVE::Network::SDN::Controllers::FaucetPlugin->register(); |
22 | PVE::Network::SDN::Controllers::Plugin->init(); | |
23 | ||
24 | ||
25 | sub sdn_controllers_config { | |
26 | my ($cfg, $id, $noerr) = @_; | |
27 | ||
28 | die "no sdn controller ID specified\n" if !$id; | |
29 | ||
30 | my $scfg = $cfg->{ids}->{$id}; | |
b2d83056 | 31 | die "sdn '$id' does not exist\n" if (!$noerr && !$scfg); |
f5eabba0 AD |
32 | |
33 | return $scfg; | |
34 | } | |
35 | ||
36 | sub config { | |
f703d2ae | 37 | my $config = cfs_read_file("sdn/controllers.cfg"); |
f5eabba0 AD |
38 | $config = cfs_read_file("sdn/controllers.cfg") if !keys %{$config->{ids}}; |
39 | return $config; | |
40 | } | |
41 | ||
42 | sub write_config { | |
43 | my ($cfg) = @_; | |
44 | ||
f703d2ae | 45 | cfs_write_file("sdn/controllers.cfg", $cfg); |
f5eabba0 AD |
46 | } |
47 | ||
48 | sub lock_sdn_controllers_config { | |
49 | my ($code, $errmsg) = @_; | |
50 | ||
f703d2ae | 51 | cfs_lock_file("sdn/controllers.cfg", undef, $code); |
f5eabba0 AD |
52 | if (my $err = $@) { |
53 | $errmsg ? die "$errmsg: $err" : die $err; | |
54 | } | |
55 | } | |
56 | ||
57 | sub sdn_controllers_ids { | |
58 | my ($cfg) = @_; | |
59 | ||
b184ebc3 | 60 | return sort keys %{$cfg->{ids}}; |
f5eabba0 AD |
61 | } |
62 | ||
63 | sub complete_sdn_controller { | |
64 | my ($cmdname, $pname, $cvalue) = @_; | |
65 | ||
d73c7c36 | 66 | my $cfg = PVE::Network::SDN::running_config(); |
f5eabba0 AD |
67 | |
68 | return $cmdname eq 'add' ? [] : [ PVE::Network::SDN::sdn_controllers_ids($cfg) ]; | |
69 | } | |
70 | ||
71 | sub generate_controller_config { | |
72 | ||
d73c7c36 | 73 | my $cfg = PVE::Network::SDN::running_config(); |
5d3e0248 AD |
74 | my $vnet_cfg = $cfg->{vnets}; |
75 | my $zone_cfg = $cfg->{zones}; | |
76 | my $controller_cfg = $cfg->{controllers}; | |
77 | ||
56cdcac9 | 78 | return if !$vnet_cfg && !$zone_cfg && !$controller_cfg; |
f5eabba0 AD |
79 | |
80 | #read main config for physical interfaces | |
81 | my $current_config_file = "/etc/network/interfaces"; | |
82 | my $fh = IO::File->new($current_config_file); | |
83 | my $interfaces_config = PVE::INotify::read_etc_network_interfaces(1,$fh); | |
84 | $fh->close(); | |
85 | ||
86 | #check uplinks | |
87 | my $uplinks = {}; | |
88 | foreach my $id (keys %{$interfaces_config->{ifaces}}) { | |
89 | my $interface = $interfaces_config->{ifaces}->{$id}; | |
90 | if (my $uplink = $interface->{'uplink-id'}) { | |
91 | die "uplink-id $uplink is already defined on $uplinks->{$uplink}" if $uplinks->{$uplink}; | |
92 | $interface->{name} = $id; | |
93 | $uplinks->{$interface->{'uplink-id'}} = $interface; | |
94 | } | |
95 | } | |
96 | ||
97 | #generate configuration | |
98 | my $config = {}; | |
99 | ||
f23633dc | 100 | foreach my $id (sort keys %{$controller_cfg->{ids}}) { |
f5eabba0 AD |
101 | my $plugin_config = $controller_cfg->{ids}->{$id}; |
102 | my $plugin = PVE::Network::SDN::Controllers::Plugin->lookup($plugin_config->{type}); | |
f23633dc | 103 | $plugin->generate_controller_config($plugin_config, $controller_cfg, $id, $uplinks, $config); |
f5eabba0 AD |
104 | } |
105 | ||
f23633dc | 106 | foreach my $id (sort keys %{$zone_cfg->{ids}}) { |
56cdcac9 | 107 | my $plugin_config = $zone_cfg->{ids}->{$id}; |
f5eabba0 AD |
108 | my $controllerid = $plugin_config->{controller}; |
109 | next if !$controllerid; | |
7cb9714d | 110 | my $controller = $controller_cfg->{ids}->{$controllerid}; |
f5eabba0 AD |
111 | if ($controller) { |
112 | my $controller_plugin = PVE::Network::SDN::Controllers::Plugin->lookup($controller->{type}); | |
f23633dc | 113 | $controller_plugin->generate_controller_zone_config($plugin_config, $controller, $controller_cfg, $id, $uplinks, $config); |
f5eabba0 AD |
114 | } |
115 | } | |
116 | ||
f23633dc | 117 | foreach my $id (sort keys %{$vnet_cfg->{ids}}) { |
f5eabba0 | 118 | my $plugin_config = $vnet_cfg->{ids}->{$id}; |
56cdcac9 AD |
119 | my $zoneid = $plugin_config->{zone}; |
120 | next if !$zoneid; | |
121 | my $zone = $zone_cfg->{ids}->{$zoneid}; | |
122 | next if !$zone; | |
123 | my $controllerid = $zone->{controller}; | |
f5eabba0 AD |
124 | next if !$controllerid; |
125 | my $controller = $controller_cfg->{ids}->{$controllerid}; | |
126 | if ($controller) { | |
127 | my $controller_plugin = PVE::Network::SDN::Controllers::Plugin->lookup($controller->{type}); | |
56cdcac9 | 128 | $controller_plugin->generate_controller_vnet_config($plugin_config, $controller, $zoneid, $id, $config); |
f5eabba0 AD |
129 | } |
130 | } | |
131 | ||
132 | return $config; | |
133 | } | |
134 | ||
135 | ||
136 | sub reload_controller { | |
137 | ||
d73c7c36 | 138 | my $cfg = PVE::Network::SDN::running_config(); |
5d3e0248 AD |
139 | my $controller_cfg = $cfg->{controllers}; |
140 | ||
f5eabba0 AD |
141 | return if !$controller_cfg; |
142 | ||
143 | foreach my $id (keys %{$controller_cfg->{ids}}) { | |
144 | my $plugin_config = $controller_cfg->{ids}->{$id}; | |
145 | my $plugin = PVE::Network::SDN::Controllers::Plugin->lookup($plugin_config->{type}); | |
146 | $plugin->reload_controller(); | |
147 | } | |
148 | } | |
149 | ||
9cef13e9 AD |
150 | sub generate_controller_rawconfig { |
151 | my ($config) = @_; | |
152 | ||
d73c7c36 | 153 | my $cfg = PVE::Network::SDN::running_config(); |
9cef13e9 AD |
154 | my $controller_cfg = $cfg->{controllers}; |
155 | return if !$controller_cfg; | |
156 | ||
157 | my $rawconfig = ""; | |
158 | foreach my $id (keys %{$controller_cfg->{ids}}) { | |
159 | my $plugin_config = $controller_cfg->{ids}->{$id}; | |
160 | my $plugin = PVE::Network::SDN::Controllers::Plugin->lookup($plugin_config->{type}); | |
161 | $rawconfig .= $plugin->generate_controller_rawconfig($plugin_config, $config); | |
162 | } | |
163 | return $rawconfig; | |
164 | } | |
165 | ||
f5eabba0 AD |
166 | sub write_controller_config { |
167 | my ($config) = @_; | |
168 | ||
d73c7c36 | 169 | my $cfg = PVE::Network::SDN::running_config(); |
9cef13e9 | 170 | my $controller_cfg = $cfg->{controllers}; |
f5eabba0 AD |
171 | return if !$controller_cfg; |
172 | ||
173 | foreach my $id (keys %{$controller_cfg->{ids}}) { | |
174 | my $plugin_config = $controller_cfg->{ids}->{$id}; | |
175 | my $plugin = PVE::Network::SDN::Controllers::Plugin->lookup($plugin_config->{type}); | |
176 | $plugin->write_controller_config($plugin_config, $config); | |
177 | } | |
178 | } | |
179 | ||
180 | 1; | |
181 |