Browse Source

FD3-805 if the pool ip range change, host reservations are recalculated

Guillermo Espinoza 6 years ago
parent
commit
ff0acbe49d

+ 45 - 0
src/HostBundle/Repository/HostRepository.php

@@ -26,4 +26,49 @@ class HostRepository extends \Doctrine\ORM\EntityRepository
         return $qb->getQuery()->getResult();
     }
 
+    /**
+     * @param string $firstIp
+     * @param string $lastIp
+     * 
+     * @return array
+     */    
+    public function findAllBetweenIp($firstIp, $lastIp)
+    {
+        $qb = $this->createQueryBuilder('Host');
+        $qb->select(array('Host'))
+                ->where(
+                    $qb->expr()->andX(
+                        $qb->expr()->isNotNull('Host.ipv4Address'),
+                        $qb->expr()->between('Host.ipv4Address', ip2long($firstIp), ip2long($lastIp))
+                    )
+                );
+
+        return $qb->getQuery()->getResult();
+    }
+
+    /**
+     * @param string $firstIp
+     * @param string $lastIp
+     * @param string $firstIpNew
+     * @param string $lastIpNew
+     * 
+     * @return array
+     */    
+    public function findAllBetweenIps($firstIp, $lastIp, $firstIpNew, $lastIpNew)
+    {
+        $qb = $this->createQueryBuilder('Host');
+        $qb->select(array('Host'))
+           ->where("Host.ipv4Address IS NOT NULL AND
+           Host.ipv4Address BETWEEN :firstip AND :lastip AND
+           Host.ipv4Address NOT BETWEEN :firstipnew AND :lastipnew")
+           ->setParameters([
+               'firstip' => ip2long($firstIp),
+               'lastip' => ip2long($lastIp),
+               'firstipnew' => ip2long($firstIpNew),
+               'lastipnew' => ip2long($lastIpNew),
+           ]);
+
+        return $qb->getQuery()->getResult();
+    }
+
 }

+ 106 - 0
src/IPv4Bundle/EventListener/PoolIPRangeSubscriber.php

@@ -0,0 +1,106 @@
+<?php
+
+namespace IPv4Bundle\EventListener;
+
+use Doctrine\Common\EventSubscriber;
+use Doctrine\ORM\Event\LifecycleEventArgs;
+use HostBundle\Entity\Host;
+use IPv4Bundle\Entity\Pool;
+use KeaBundle\Services\LeaseService;
+
+class PoolIPRangeSubscriber implements EventSubscriber
+{
+
+    /**
+     * @var ContainerInterface
+     */
+    private $serviceContainer;
+        
+    
+    /**
+     * @param ContainerInterface $serviceContainer
+     */
+    public function __construct($serviceContainer)
+    {
+        $this->serviceContainer = $serviceContainer;
+    }
+
+    /**
+     * @return array
+     */
+    public function getSubscribedEvents()
+    {
+        return array(
+            'postUpdate',
+            'preRemove',
+        );
+    }
+
+    /**
+     * @param LifecycleEventArgs $args
+     */
+    public function postUpdate(LifecycleEventArgs $args)
+    {
+        $this->execute($args);
+    }
+
+    /**
+     * @param LifecycleEventArgs $args
+     */
+    public function preRemove(LifecycleEventArgs $args)
+    {
+        $this->execute($args, true);
+    }
+
+    /**
+     * @param LifecycleEventArgs $args
+     * @param boolean $remove
+     */
+    public function execute(LifecycleEventArgs $args, $remove = false)
+    {
+        $flashbag = $this->serviceContainer->get('session')->getFlashBag();
+        $translator = $this->serviceContainer->get('translator');
+        try {
+            // checking if the entity is a Host and the status has changed
+            $em = $args->getEntityManager();
+            $uow = $em->getUnitOfWork();
+            $uow->computeChangeSets();
+            $entity = $args->getEntity();
+            $changeset = $uow->getEntityChangeSet($entity);
+            if ($entity instanceof Pool && $entity->getIsStatic() == true) {
+                $hosts = [];
+                if ($remove == true) {
+                    $hosts = $em->getRepository(Host::class)->findAllBetweenIp($entity->getFirstIp(), $entity->getLastIp());
+                } else {
+                    $firstIp = $firstIpNew = $entity->getFirstIp();
+                    if (isset($changeset['firstIp'])) {
+                        $firstIp = $changeset['firstIp'][0];
+                        $firstIpNew = $changeset['firstIp'][1];
+                    }
+                    
+                    $lastIp = $lastIpNew = $entity->getLastIp();
+                    if (isset($changeset['lastIp'])) {
+                        $lastIp = $changeset['lastIp'][0];
+                        $lastIpNew = $changeset['lastIp'][1];
+                    }
+                    
+                    $hosts = $em->getRepository(Host::class)->findAllBetweenIps($firstIp, $lastIp, $firstIpNew, $lastIpNew);
+                }
+
+                // setting fixed address to null to all hosts out of range of the pool
+                foreach ($hosts as $host) {
+                    $host->setFixedAddress(null);
+                    $host->setIpv4Address(null);
+                    $host->setFixedIP(false);
+
+                    $em->flush($host);
+                }
+            }
+        } catch (\Exception $ex) {
+            $flashbag->add("error", $ex->getMessage());
+        } catch (\Throwable $ex) {
+            $flashbag->add("error", $ex->getMessage());
+        }
+    }
+
+}

+ 6 - 0
src/IPv4Bundle/Resources/config/services.yml

@@ -38,3 +38,9 @@ services:
         arguments: [ "@service_container" ]
         tags:
             - { name: doctrine.event_subscriber, connection: default }
+
+    ipv4.pool_ip_range.subscriber:
+        class: IPv4Bundle\EventListener\PoolIPRangeSubscriber
+        arguments: [ "@service_container" ]
+        tags:
+            - { name: doctrine.event_subscriber, connection: default }

+ 5 - 5
src/IPv4Bundle/Services/PoolService.php

@@ -84,18 +84,18 @@ class PoolService
         $range = [];
         $pools = $this->poolRepository->findAllStaticByHostTypeAndStatus($hostType, $status);
         foreach ($pools as $pool) {
-            $range[] = $pool->getFirstIp();
             $firstIp = ip2long($pool->getFirstIp());
             $lastIp =  ip2long($pool->getLastIp());
+            $range[] = $firstIp;
             $currentIP = $firstIp + 1;
             while ($currentIP <= $lastIp) {
-                $range[] = long2ip($currentIP);
+                $range[] = $currentIP;
                 $currentIP++;
             }
         }
         sort($range);
         
-        return $range;
+        return array_map('long2ip', $range);
     }
     
     /**
@@ -115,8 +115,8 @@ class PoolService
                 continue;
             }
             $firstIp = ip2long($pool->getFirstIp());
-            $range[] = $firstIp;
             $lastIp =  ip2long($pool->getLastIp());
+            $range[] = $firstIp;
             $currentIP = $firstIp + 1;
             while ($currentIP <= $lastIp) {
                 $range[] = $currentIP;
@@ -127,5 +127,5 @@ class PoolService
         
         return $range;
     }
-    
+        
 }