Browse Source

FD3-576 se agrega ip fija en host

Espinoza Guillermo 7 years ago
parent
commit
6bd2b55c64

+ 6 - 6
composer.lock

@@ -1457,7 +1457,7 @@
             "source": {
                 "type": "git",
                 "url": "ssh://git@200.50.168.30:222/VendorSoftwareFlowdat3/BaseAdmin.git",
-                "reference": "636e3b7997715fe842de5834f1a03cb72b7688e0"
+                "reference": "97587f95769fcfac8f3c43fae36aa02633960f62"
             },
             "type": "library",
             "autoload": {
@@ -1472,7 +1472,7 @@
                 "bootstrap",
                 "sonata"
             ],
-            "time": "2018-07-03T18:07:50+00:00"
+            "time": "2018-07-04T17:03:04+00:00"
         },
         {
             "name": "ik/device-bundle",
@@ -1599,7 +1599,7 @@
             "source": {
                 "type": "git",
                 "url": "ssh://git@200.50.168.30:222/VendorSoftwareFlowdat3/TemplateBundle.git",
-                "reference": "14e7b7c9d0deadf8c779874419cf2f183a02bbf8"
+                "reference": "7e50327475180f03fa24a2fa5ee1dc01dadd2bfa"
             },
             "require": {
                 "ik/base-admin-bundle": "*"
@@ -1617,7 +1617,7 @@
                 "bundle",
                 "template"
             ],
-            "time": "2018-04-24T15:29:11+00:00"
+            "time": "2018-07-04T14:44:27+00:00"
         },
         {
             "name": "ik/webservice-bundle",
@@ -1646,7 +1646,7 @@
             "source": {
                 "type": "git",
                 "url": "ssh://git@200.50.168.30:222/VendorSoftwareFlowdat3/WorkflowBundle.git",
-                "reference": "47ca3a59560cd1e7d8ae5e06ddbea62094fc2996"
+                "reference": "184c2d1c00423b71fd1eae098eead7b938de1882"
             },
             "require": {
                 "php-amqplib/rabbitmq-bundle": "^1.12"
@@ -1676,7 +1676,7 @@
                 "bundle",
                 "workflow"
             ],
-            "time": "2018-06-25T18:50:13+00:00"
+            "time": "2018-07-04T14:51:55+00:00"
         },
         {
             "name": "incenteev/composer-parameter-handler",

+ 25 - 0
src/HostBundle/Entity/Host.php

@@ -78,6 +78,11 @@ class Host implements WorkflowInterface
      * @JMS\Exclude
      */
     protected $currentState = null;
+        
+    /**
+     * @ORM\Column(type="boolean", nullable=true)
+     */
+    protected $fixedIP = false;
 
 
     /**
@@ -175,5 +180,25 @@ class Host implements WorkflowInterface
 
         return $this;
     }
+        
+    /**
+     * @return boolean
+     */
+    public function getFixedIP()
+    {
+        return $this->fixedIP;
+    }
+    
+    /**
+     * @param boolean $fixedIP
+     *
+     * @return Host
+     */
+    public function setFixedIP($fixedIP = null)
+    {
+        $this->fixedIP = $fixedIP;
+        
+        return $this;
+    }
 
 }

+ 1 - 2
src/HostBundle/Entity/HostType.php

@@ -44,11 +44,10 @@ class HostType implements PreRemoveInterface
      */
     protected $shortname;
 
-
     /**
      * @ORM\OneToMany(targetEntity="Host", mappedBy="hostType")
      *
-     * @JMS\MaxDepth(1)
+     * @JMS\Exclude
      */
     protected $hosts;
 

+ 34 - 9
src/HostBundle/EventListener/AdminDHCPOption.php

@@ -2,12 +2,29 @@
 
 namespace HostBundle\EventListener;
 
-use Sonata\AdminBundle\Event\ConfigureEvent;
 use HostBundle\Traits\DHCPOptionTrait;
 use HostBundle\Utils\DHCPOptions;
+use HostBundle\Services\HostService;
+use Sonata\AdminBundle\Event\ConfigureEvent;
+use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
+use Symfony\Component\Form\Extension\Core\Type\TextType;
 
 class AdminDHCPOption
 {
+    
+    /**
+     * @var HostService
+     */
+    private $hostService;
+    
+    
+    /**
+     * @param HostService $hostService
+     */
+    public function __construct(HostService $hostService)
+    {
+        $this->hostService = $hostService;
+    }
 
     /**
      * @param ConfigureEvent $event
@@ -21,14 +38,25 @@ class AdminDHCPOption
                 $mapper->end()->end();
             }
             $options = array(
-                'translation_domain' => 'HostBundle'
+                'translation_domain' => 'HostBundle',
             );
             $mapper->tab('DHCP Option', $options)
                 ->with('DHCP Option', $options);
+            $fieldOptions = [
+                'required' => false,
+            ];
             foreach (DHCPOptions::getConstants() as $opt) {
-                $mapper->add($opt, 'text', array(
-                    'required'=> false,
-                ));
+                
+                if ($opt == 'fixed_address') {
+                    $freeIP = $this->hostService->getFreeFixedIP(false);
+                    $fieldOptions['choices'] = array_combine($freeIP, $freeIP);
+                    $mapper->add($opt, ChoiceType::class, $fieldOptions);
+                    unset($fieldOptions['choices']);
+                    
+                    continue;
+                }
+                
+                $mapper->add($opt, TextType::class, $fieldOptions);
             }
             $mapper->end()->end();
         }
@@ -52,10 +80,7 @@ class AdminDHCPOption
                 ->with('DHCP Option', $options);
             foreach (DHCPOptions::getConstants() as $opt) {
                 if (!$mapper->has($opt)) {
-                    $mapper->add($opt, 'text', array(
-                        'required'=> false,
-                        'mapped' => false,
-                    ));
+                    $mapper->add($opt);
                 }
             }
             $mapper->end()->end();

+ 84 - 0
src/HostBundle/EventListener/AssignHostFixedAddressSubscriber.php

@@ -0,0 +1,84 @@
+<?php
+
+namespace HostBundle\EventListener;
+
+use Doctrine\Common\EventSubscriber;
+use Doctrine\ORM\Event\LifecycleEventArgs;
+use HostBundle\Entity\Host;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+class AssignHostFixedAddressSubscriber implements EventSubscriber
+{
+    
+    /**
+     * @var ContainerInterface
+     */
+    private $serviceContainer;
+    
+    
+    /**
+     * @param ContainerInterface $serviceContainer
+     */
+    public function __construct(ContainerInterface $serviceContainer)
+    {
+        $this->serviceContainer = $serviceContainer;
+    }
+
+    /**
+     * @return array
+     */
+    public function getSubscribedEvents()
+    {
+        return array(
+            'prePersist',
+            'preUpdate',
+        );
+    }
+
+    /**
+     * @param LifecycleEventArgs $args
+     */
+    public function prePersist(LifecycleEventArgs $args)
+    {
+        $this->execute($args);
+    }
+
+    /**
+     * @param LifecycleEventArgs $args
+     */
+    public function preUpdate(LifecycleEventArgs $args)
+    {
+        $this->execute($args, 'preUpdate');
+    }
+
+    /**
+     * @param LifecycleEventArgs $args
+     * @param string $eventName
+     */
+    public function execute(LifecycleEventArgs $args, $eventName = 'prePersist')
+    {
+        $entity = $args->getEntity();
+        if ($entity instanceof Host) {
+            
+            // Se debe asignar una IP fija ya que el host no tiene ninguna
+            if ($entity->getFixedIP() == true && !$entity->getFixedAddress()) {
+                $ip = $this->serviceContainer->get('dhcp.host_service')->getFirstFreeFixedIP();
+                $entity->setFixedAddress($ip);
+            }
+            
+            // Se debe des-asignar una IP fija
+            if ($entity->getFixedIP() == false) {
+                $entity->setFixedAddress(null);
+            }
+            
+            $entity->setOptions(json_encode($entity->getDHCPOption()));
+
+            if ($eventName == 'preUpdate') {
+                $uow = $args->getEntityManager()->getUnitOfWork();
+                $meta = $args->getEntityManager()->getClassMetadata(get_class($entity));
+                $uow->recomputeSingleEntityChangeSet($meta, $entity);
+            }
+        }
+    }
+
+}

+ 3 - 0
src/HostBundle/Form/HostType.php

@@ -18,6 +18,9 @@ class HostType extends AbstractType
             ->add('mac')
             ->add('hostType')
             ->add('state')
+            ->add('fixedIP', null, [
+                'required' => false,
+            ])
             ;
         foreach (DHCPOptions::getConstants() as $opt) {
             $builder->add($opt, 'text', array(

+ 13 - 1
src/HostBundle/Resources/config/services.yml

@@ -6,7 +6,7 @@ services:
         tags:
             - { name: sonata.admin, manager_type: orm, group: Host, label: Host, label_catalogue: HostBundle, label_translator_strategy: sonata.admin.label.strategy.underscore }
         calls:
-            - [setTranslationDomain, [IPv4Bundle]]
+            - [setTranslationDomain, [HostBundle]]
         public: true
 
     sonata.admin.host_type:
@@ -20,6 +20,18 @@ services:
 
     dhcp_option_admin:
        class: HostBundle\EventListener\AdminDHCPOption
+       arguments: [ "@dhcp.host_service" ]
        tags:
            - { name: kernel.event_listener, event: sonata.admin.event.configure.form, method: configureFormFields }
            - { name: kernel.event_listener, event: sonata.admin.event.configure.show, method: configureShowFields }
+           
+    dhcp.host_service:
+        class: HostBundle\Services\HostService
+        arguments: [ "@doctrine.orm.entity_manager", "@pool_ipv4_service" ]
+        
+    dhcp.assign_host_fixed_address.subscriber:
+        class: HostBundle\EventListener\AssignHostFixedAddressSubscriber
+        arguments: [ "@service_container" ]
+        tags:
+            - { name: doctrine.event_subscriber, connection: default }    
+        

+ 2 - 0
src/HostBundle/Resources/translations/HostBundle.es.yml

@@ -42,6 +42,7 @@ form:
     label_log_servers: Log Servers
     label_time_servers: Time Servers
     label_status: Estado
+    label_fixed_address: Fixed Address
 
 list:
     label_mac: Mac
@@ -99,6 +100,7 @@ show:
     label_log_servers: Log Servers
     label_time_servers: Time Servers
     label_status: Estado
+    label_fixed_address: Fixed Address
 
 filter:
     label_mac: Mac

+ 89 - 0
src/HostBundle/Services/HostService.php

@@ -0,0 +1,89 @@
+<?php
+
+namespace HostBundle\Services;
+
+use Doctrine\ORM\EntityManager;
+use Doctrine\ORM\EntityRepository;
+use HostBundle\Entity\Host;
+use IPv4Bundle\Services\PoolService;
+use KeaBundle\Entity\Lease4;
+
+class HostService
+{
+    
+    /**
+     * @var EntityManager
+     */
+    private $em;
+    
+    /**
+     * @var EntityRepository
+     */
+    private $hostRepository;
+    
+    /**
+     * @var EntityRepository
+     */
+    private $lease4Repository;
+    
+    /**
+     * @var PoolService
+     */
+    private $poolService;
+    
+    
+    /**
+     * @param EntityManager $em
+     * @param PoolService $poolService
+     */
+    public function __construct(EntityManager $em, PoolService $poolService)
+    {
+        $this->em = $em;
+        $this->hostRepository = $em->getRepository(Host::class);
+        $this->lease4Repository = $em->getRepository(Lease4::class);
+        $this->poolService = $poolService;
+    }
+    
+    /**
+     * @return string
+     */
+    public function getFirstFreeFixedIP()
+    {
+        $diff = $this->getFreeFixedIP();
+        if (count($diff)) {
+            return current($diff);
+        }
+        
+        return null;
+    }
+    
+    /**
+     * @return array
+     */
+    public function getFreeFixedIP($hostFixed = true)
+    {
+        $range = $this->poolService->getStaticPoolIPRange();
+        $leases = $this->lease4Repository->getAllAddress();
+        $hostsFixedIP = $hostFixed ? $this->getHostsFixedIp() : [];
+        
+        return array_diff($range, $leases, $hostsFixedIP);
+    }
+    
+    /**
+     * @return array
+     */
+    public function getHostsFixedIp()
+    {
+        $hostsFixedIP = [];
+        $hosts = $this->hostRepository->findBy([
+            'fixedIP' => true,
+        ]);
+        foreach ($hosts as $host) {
+            if ($host->getFixedAddress()) {
+                $hostsFixedIP[] = $host->getFixedAddress();
+            }
+        }
+        
+        return $hostsFixedIP;
+    }
+}

+ 10 - 0
src/HostBundle/Traits/DHCPOptionTrait.php

@@ -217,4 +217,14 @@ trait DHCPOptionTrait
         return @$this->json_dhcp_option_config['time_servers'];
     }
 
+    function setFixedAddress($value)
+    {
+        $this->json_dhcp_option_config['fixed_address'] = $value;
+    }
+
+    function getFixedAddress()
+    {
+        return @$this->json_dhcp_option_config['fixed_address'];
+    }
+
 }

+ 1 - 0
src/HostBundle/Utils/DHCPOptions.php

@@ -27,5 +27,6 @@ class DHCPOptions
     const DHCP_OPT122_DHCP_SERVER_SECONDARY = 'option122_dhcp_server_secondary';
     const DHCP_OPT122_PROVISIONING_SERVER = 'option122_provisioning_server';
     const DHCP_OPT122_PROVISIONING_TYPE = 'option122_provisioning_type';
+    const DHCP_FIXED_ADDRESS = 'fixed_address';
 
 }

+ 25 - 1
src/IPv4Bundle/Services/PoolService.php

@@ -6,6 +6,7 @@ use Doctrine\ORM\EntityManager;
 use Doctrine\ORM\EntityRepository;
 use IPv4Bundle\Entity\Pool;
 use KeaBundle\Entity\Lease4;
+use Symfony\Bridge\Doctrine\RegistryInterface;
 
 class PoolService
 {
@@ -23,7 +24,7 @@ class PoolService
     {
         $this->poolRepository = $em->getRepository(Pool::class);
     }
-    
+        
     /**
      * Retorna el primer pool donde se encuentra el lease
      *
@@ -47,4 +48,27 @@ class PoolService
         return null;
     }
     
+    /**
+     * @return array
+     */
+    public function getStaticPoolIPRange()
+    {
+        $range = [];
+        $pools = $this->poolRepository->findBy([
+            'isStatic' => true,
+        ]);
+        foreach ($pools as $pool) {
+            $range[] = $pool->getFirstIp();
+            $firstIp = ip2long($pool->getFirstIp());
+            $lastIp =  ip2long($pool->getLastIp());
+            $currentIP = $firstIp + 1;
+            while ($currentIP <= $lastIp) {
+                $range[] = long2ip($currentIP);
+                $currentIP++;
+            }
+        }
+        
+        return $range;
+    }
+    
 }

+ 1 - 1
src/KeaBundle/Entity/Lease4.php

@@ -6,7 +6,7 @@ use Doctrine\ORM\Mapping as ORM;
 
 /**
  * @ORM\Table(name="kea.lease4")
- * @ORM\Entity
+ * @ORM\Entity(repositoryClass="KeaBundle\Repository\Lease4Repository")
  */
 class Lease4
 {

+ 21 - 0
src/KeaBundle/Repository/Lease4Repository.php

@@ -0,0 +1,21 @@
+<?php
+
+namespace KeaBundle\Repository;
+
+class Lease4Repository extends \Doctrine\ORM\EntityRepository
+{
+
+    /**
+     * @return array
+     */
+    public function getAllAddress()
+    {
+        $qb = $this->createQueryBuilder('Lease4');
+        $leases = $qb->getQuery()->getResult();
+        
+        return array_map(function ($lease) {
+            return $lease->getAddress();
+        }, $leases);
+    }
+
+}