BaseKea.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. <?php
  2. namespace KeaBundle\Services;
  3. use HostBundle\Utils\HostStatus;
  4. use KeaBundle\Interfaces\KeaConfigInterface;
  5. class BaseKea implements KeaConfigInterface
  6. {
  7. /**
  8. * @var array
  9. */
  10. private $subnet4 = [];
  11. /**
  12. * @var array
  13. */
  14. private $hooks_libraries = [];
  15. /**
  16. * @var array
  17. */
  18. private $interfaces_config = [];
  19. /**
  20. * @var boolean
  21. */
  22. private $echo_client_id = false;
  23. /**
  24. * @var array
  25. */
  26. private $option_def = [
  27. [
  28. "name" => "subopt1",
  29. "code" => 3,
  30. "space" => "pcc",
  31. "type" => "binary",
  32. "record-types" => "",
  33. "array" => false,
  34. "encapsulate" => "",
  35. ],
  36. [
  37. "name" => "subopt2",
  38. "code" => 6,
  39. "space" => "pcc",
  40. "type" => "binary",
  41. "record-types" => "",
  42. "array" => false,
  43. "encapsulate" => "",
  44. ],
  45. [
  46. "name" =>"clabs",
  47. "code" => 122,
  48. "space" => "dhcp4",
  49. "type" => "empty",
  50. "array" => false,
  51. "record-types" => "",
  52. "encapsulate" => "pcc",
  53. ],
  54. ];
  55. private $client_classes = [];
  56. /**
  57. * @param array $data
  58. * @param boolean $logging
  59. *
  60. * @return string
  61. */
  62. public function getConfig($data = array(), $logging = false)
  63. {
  64. if (isset($data['subnets'])) {
  65. $this->subnetConfig($data['subnets'], $data['reservations']);
  66. }
  67. if (isset($data['library'])) {
  68. $this->hooksLibrariesConfig($data);
  69. }
  70. return json_encode([
  71. array(
  72. 'arguments' => array(
  73. 'Dhcp4' => [
  74. 'echo-client-id' => $this->echo_client_id,
  75. 'option-def' => $this->option_def,
  76. 'control-socket' => $this->controlSocketConfig(),
  77. 'lease-database' => $this->leaseDatabaseConfig($data),
  78. 'hosts-database' => $this->leaseDatabaseConfig($data),
  79. 'client-classes' => $this->client_classes,
  80. 'subnet4' => $this->subnet4,
  81. 'hooks-libraries' => $this->hooks_libraries,
  82. 'interfaces-config' => $this->getInterfacesConfig(),
  83. ],
  84. 'Logging' => $this->loggingConfig(),
  85. ))], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
  86. }
  87. /**
  88. * @param array $subnets
  89. */
  90. private function subnetConfig($subnets, $reservations)
  91. {
  92. foreach ($subnets as $subnet) {
  93. $pools = [];
  94. foreach ($subnet->getIpPool() as $pool) {
  95. $pools[] = [
  96. 'pool' => $pool->getFirstIp() . ' - ' . $pool->getLastIp(),
  97. ];
  98. }
  99. $hostType = $subnet->getAllowedHostType();
  100. $client_class = '';
  101. if ($hostType != 'Cablemodem') {
  102. $client_class = $hostType->getShortname();
  103. }
  104. if ($subnet->getStatus() != HostStatus::STATE_NONE && $subnet->getStatus() != '') {
  105. if ($client_class != '') {
  106. $client_class .= '-';
  107. }
  108. $client_class .= $subnet->getStatus();
  109. }
  110. $subnetConf = [
  111. 'subnet' => $subnet->getAddress(),
  112. 'pools' => $pools,
  113. ];
  114. if(isset($reservations[$subnet->getId()])) {
  115. $subnetConf['reservations'] = $reservations[$subnet->getId()];
  116. }
  117. $nextServer = $subnet->getNextServer();
  118. if ($nextServer != '') {
  119. $subnetConf['next-server'] = $nextServer;
  120. }
  121. $filename = $subnet->getFilename();
  122. if ($filename != '') {
  123. $subnetConf['boot-file-name'] = $filename;
  124. }
  125. if ($client_class != '') {
  126. $subnetConf['client-class'] = $client_class;
  127. $this->client_classes [] = [
  128. 'name' => $client_class,
  129. ];
  130. }
  131. $netgroup = $subnet->getNetGroup();
  132. if ($netgroup && count($netgroup->getRelay())) {
  133. $relay = [];
  134. foreach ($netgroup->getRelay() as $ip) {
  135. $relay[] = $ip;
  136. }
  137. $subnetConf['relay'] = [
  138. 'ip-addresses' => $relay,
  139. ];
  140. }
  141. $this->setOptionData($subnet, $subnetConf);
  142. $this->subnet4[] = $subnetConf;
  143. }
  144. }
  145. /**
  146. * @param array $data
  147. */
  148. private function hooksLibrariesConfig($data)
  149. {
  150. $this->hooks_libraries = [
  151. [
  152. 'library' => '/opt/hooks/mysql/kea-hook-flowdat3-mysql.so',
  153. 'parameters' => [
  154. "host" => $data['db']['host'],
  155. "database" => $data['db']['database'],
  156. "user" => $data['db']['user'],
  157. "password" => $data['db']['password'],
  158. ]
  159. ],
  160. [
  161. "library" => "/opt/hooks/amqp/kea-hook-flowdat3.so",
  162. "parameters" => [
  163. "host" => $data['amqp']['host'],
  164. "user" => $data['amqp']['user'],
  165. "password" => $data['amqp']['password'],
  166. ],
  167. ],
  168. ];
  169. // $dhcp = $data['dhcp'];
  170. // $hosts = $data['hosts'];
  171. //
  172. // $hook = [
  173. // 'library' => $data['library'],
  174. // ];
  175. //
  176. // $dhcpModelParams = $dhcp && $dhcp->getDhcpModel() ? $dhcp->getDhcpModel()->getData('parameters') : null;
  177. //
  178. // $option122 = isset($dhcpModelParams['option122']) ? $dhcpModelParams['option122'] : null;
  179. // $ip = isset($dhcpModelParams['ip']) ? $dhcpModelParams['ip'] : null;
  180. // if ($option122 && $ip) {
  181. // $macs = [];
  182. // foreach ($hosts as $host) {
  183. // if ($host->getMac()) {
  184. // $macs[] = $host->getMac();
  185. // }
  186. // }
  187. //
  188. // $hook['parameters']['option122'] = [
  189. // $ip => $macs
  190. // ];
  191. // }
  192. //
  193. // $remote_id_map = isset($dhcpModelParams['remote-id-map']) ? $dhcpModelParams['remote-id-map'] : null;
  194. // if ($remote_id_map) {
  195. // $hostConfig = [];
  196. // foreach ($hosts as $host) {
  197. // if ($host->getMac()) {
  198. // $mac = $host->getMac();
  199. // $state = $host->getState();
  200. // $shortname = $host->getHostType()->getShortname();
  201. //
  202. // $client_class = $state != HostStatus::STATE_NONE ? $state : $shortname;
  203. //
  204. // $hostConfig[$client_class][] = $mac;
  205. // }
  206. // }
  207. // $hook['parameters']['remote-id-map'] = $hostConfig;
  208. // }
  209. // $this->hooks_libraries[] = $hook;
  210. }
  211. /**
  212. * @return array
  213. */
  214. private function loggingConfig()
  215. {
  216. return array(
  217. 'loggers' => array(
  218. array(
  219. 'debuglevel' => 0,
  220. 'name' => 'kea-dhcp4',
  221. 'output_options' => array(
  222. array(
  223. 'flush' => true,
  224. 'maxsize' => 10240000,
  225. 'maxver' => 1,
  226. 'output' => '/usr/local/var/log/kea-dhcp4.log'
  227. )
  228. ),
  229. 'severity' => 'INFO'
  230. )
  231. )
  232. );
  233. }
  234. /**
  235. * @return array
  236. */
  237. private function controlSocketConfig()
  238. {
  239. /* "control-socket": {"socket-name": "\/tmp\/kea-dhcp4-ctrl.sock","socket-type": "unix"} */
  240. return array(
  241. 'socket-name' => '/tmp/kea-dhcp4-ctrl.sock',
  242. 'socket-type' => 'unix'
  243. );
  244. }
  245. /**
  246. * @return array
  247. */
  248. private function leaseDatabaseConfig($data, $type = 'mysql')
  249. {
  250. if ($type == 'mysql') {
  251. $config = array(
  252. "host" => $data['db']['host'],
  253. "name" => $data['db']['name'],
  254. "user" => $data['db']['user'],
  255. "password" => $data['db']['password'],
  256. "type" => "mysql",
  257. );
  258. } elseif ($type == 'memfile') {
  259. $config = array(
  260. 'lfc-interval' => 3600,
  261. 'type' => 'memfile'
  262. );
  263. }
  264. return $config;
  265. }
  266. /**
  267. * @return array
  268. */
  269. private function getInterfacesConfig()
  270. {
  271. return ['interfaces' => ['*']];
  272. }
  273. /**
  274. * @param Subnet $subnet
  275. *
  276. * @return array
  277. */
  278. private function setOptionData($subnet, &$subnetConf)
  279. {
  280. $option_data = [];
  281. $fields = [
  282. "routers",
  283. "time-servers" => ["always-send" => true],
  284. "log-servers",
  285. "time-offset",
  286. "broadcast-address" => ["always-send" => true],
  287. "domain-name-servers",
  288. ];
  289. foreach ($fields as $key => $options) {
  290. $name = is_array($options) ? $key : $options;
  291. $field = implode('', array_map(function ($piece) {
  292. return ucfirst($piece);
  293. }, explode('-', $name)));
  294. $method = "get{$field}";
  295. $value = $subnet->$method();
  296. if ($value) {
  297. $data = [
  298. 'name' => $name,
  299. 'data' => $subnet->$method(),
  300. ];
  301. if (is_array($options)) {
  302. $data = array_merge($data, $options);
  303. }
  304. $option_data[] = $data;
  305. }
  306. }
  307. $option_122_data = [];
  308. if ($subnet->getOption122ProvisioningServer() && $subnet->getOption122ProvisioningType()) {
  309. $option_122_data = [
  310. [
  311. "name" => "subopt1",
  312. "space" => "pcc",
  313. "code" => 3,
  314. "csv-format" => true,
  315. "data" => bin2hex($subnet->getOption122ProvisioningServer()),
  316. ],
  317. [
  318. "name" => "subopt2",
  319. "space" => "pcc",
  320. "code" => 6,
  321. "csv-format" => true,
  322. "data" => bin2hex($subnet->getOption122ProvisioningType()),
  323. ],
  324. [
  325. "name" => "clabs",
  326. "space" => "dhcp4",
  327. "code" => 122,
  328. "csv-format" => false,
  329. "data" => "",
  330. ],
  331. ];
  332. }
  333. $option_data = array_merge($option_data, $option_122_data);
  334. $subnetConf['option-data'] = $option_data;
  335. return $option_data;
  336. }
  337. }