diff --git a/.env b/.env index 001e100..6a75f75 100644 --- a/.env +++ b/.env @@ -42,3 +42,5 @@ JWT_PASSPHRASE=8b9154df37ffa91ef9186ce095324e39e50ff3b023bb1ed34383abd019ba4515 ###< lexik/jwt-authentication-bundle ### OGBOOT_API_URL=http://localhost:8085 +OGDHCP_API_URL=http://localhost:8085 + diff --git a/config/api_platform/PxeBootFile.yaml b/config/api_platform/PxeBootFile.yaml index 6c5886d..034e707 100644 --- a/config/api_platform/PxeBootFile.yaml +++ b/config/api_platform/PxeBootFile.yaml @@ -9,7 +9,7 @@ resources: groups: ['pxe-boot-file:write'] operations: ApiPlatform\Metadata\GetCollection: - provider: App\State\Provider\PPxeBootFileProvider + provider: App\State\Provider\PxeBootFileProvider filters: - 'api_platform.filter.pxe_boot_file.order' - 'api_platform.filter.pxe_boot_file.search' diff --git a/config/api_platform/Subnet.yaml b/config/api_platform/Subnet.yaml new file mode 100644 index 0000000..7125a1a --- /dev/null +++ b/config/api_platform/Subnet.yaml @@ -0,0 +1,31 @@ +resources: + App\Entity\Subnet: + processor: App\State\Processor\SubnetProcessor + input: App\Dto\Input\SubnetInput + output: App\Dto\Output\SubnetOutput + normalizationContext: + groups: ['default', 'subnet:read'] + denormalizationContext: + groups: ['subnet:write'] + operations: + ApiPlatform\Metadata\GetCollection: + provider: App\State\Provider\SubnetProvider + filters: + - 'api_platform.filter.subnet.order' + - 'api_platform.filter.subnet.search' + + ApiPlatform\Metadata\Get: + provider: App\State\Provider\SubnetProvider + ApiPlatform\Metadata\Put: + provider: App\State\Provider\SubnetProvider + ApiPlatform\Metadata\Patch: + provider: App\State\Provider\SubnetProvider + ApiPlatform\Metadata\Post: ~ + ApiPlatform\Metadata\Delete: ~ + +properties: + App\Entity\Subnet: + id: + identifier: false + uuid: + identifier: true \ No newline at end of file diff --git a/config/services.yaml b/config/services.yaml index e03a116..50cfa8d 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -10,6 +10,7 @@ services: bind: $ogBootApiUrl: '%env(OGBOOT_API_URL)%' + $ogDhcpApiUrl: '%env(OGDHCP_API_URL)%' App\: resource: '../src/' @@ -118,3 +119,8 @@ services: bind: $collectionProvider: '@api_platform.doctrine.orm.state.collection_provider' $itemProvider: '@api_platform.doctrine.orm.state.item_provider' + + App\State\Provider\SubnetProvider: + bind: + $collectionProvider: '@api_platform.doctrine.orm.state.collection_provider' + $itemProvider: '@api_platform.doctrine.orm.state.item_provider' diff --git a/src/Controller/OgDhcp/AbstractOgDhcpController.php b/src/Controller/OgDhcp/AbstractOgDhcpController.php new file mode 100644 index 0000000..8874a9f --- /dev/null +++ b/src/Controller/OgDhcp/AbstractOgDhcpController.php @@ -0,0 +1,20 @@ +request('GET', $this->ogDhcpApiUrl.'/opengnsys3/rest/dhcp/subnets/'.$data->getChecksum(), [ + 'headers' => [ + 'accept' => 'application/json', + ], + ]); + } catch (TransportExceptionInterface $e) { + return new JsonResponse( data: 'An error occurred', status: Response::HTTP_INTERNAL_SERVER_ERROR); + } + + $data = json_decode($response->getContent(), true); + + return new JsonResponse( data: $data, status: Response::HTTP_OK); + } +} \ No newline at end of file diff --git a/src/Controller/OgDhcp/Subnet/GetCollectionAction.php b/src/Controller/OgDhcp/Subnet/GetCollectionAction.php new file mode 100644 index 0000000..d29c5d0 --- /dev/null +++ b/src/Controller/OgDhcp/Subnet/GetCollectionAction.php @@ -0,0 +1,41 @@ +request('GET', $this->ogDhcpApiUrl.'/opengnsys3/rest/subnets', [ + 'headers' => [ + 'accept' => 'application/json', + ], + ]); + } catch (TransportExceptionInterface $e) { + return new JsonResponse( data: 'An error occurred', status: Response::HTTP_INTERNAL_SERVER_ERROR); + } + + $data = json_decode($response->getContent(), true); + + return new JsonResponse( data: $data, status: Response::HTTP_OK); + } +} \ No newline at end of file diff --git a/src/Controller/OgDhcp/Subnet/PostAction.php b/src/Controller/OgDhcp/Subnet/PostAction.php new file mode 100644 index 0000000..c35a461 --- /dev/null +++ b/src/Controller/OgDhcp/Subnet/PostAction.php @@ -0,0 +1,8 @@ +netmask = $subnet->getNetmask(); + $this->ipAddress = $subnet->getIpAddress(); + $this->nextServer = $subnet->getNextServer(); + $this->bootFileName = $subnet->getBootFileName(); + } + + public function createOrUpdateEntity(?Subnet $subnet = null): Subnet + { + if (!$subnet) { + $subnet = new Subnet(); + } + + $subnet->setNetmask($this->netmask); + $subnet->setIpAddress($this->ipAddress); + $subnet->setNextServer($this->nextServer); + $subnet->setBootFileName($this->bootFileName); + + return $subnet; + } +} \ No newline at end of file diff --git a/src/Dto/Output/SubnetOutput.php b/src/Dto/Output/SubnetOutput.php new file mode 100644 index 0000000..567ff2f --- /dev/null +++ b/src/Dto/Output/SubnetOutput.php @@ -0,0 +1,42 @@ +netmask = $subnet->getNetmask(); + $this->ipAddress = $subnet->getIpAddress(); + $this->nextServer = $subnet->getNextServer(); + $this->bootFileName = $subnet->getBootFileName(); + $this->createdAt = $subnet->getCreatedAt(); + $this->createdBy = $subnet->getCreatedBy(); + } +} \ No newline at end of file diff --git a/src/Entity/Subnet.php b/src/Entity/Subnet.php new file mode 100644 index 0000000..29201dd --- /dev/null +++ b/src/Entity/Subnet.php @@ -0,0 +1,70 @@ +netmask; + } + + public function setNetmask(string $netmask): static + { + $this->netmask = $netmask; + + return $this; + } + + public function getIpAddress(): ?string + { + return $this->ipAddress; + } + + public function setIpAddress(string $ipAddress): static + { + $this->ipAddress = $ipAddress; + + return $this; + } + + public function getNextServer(): ?string + { + return $this->nextServer; + } + + public function setNextServer(string $nextServer): static + { + $this->nextServer = $nextServer; + + return $this; + } + + public function getBootFileName(): ?string + { + return $this->bootFileName; + } + + public function setBootFileName(string $bootFileName): static + { + $this->bootFileName = $bootFileName; + + return $this; + } +} diff --git a/src/Factory/SubnetFactory.php b/src/Factory/SubnetFactory.php new file mode 100644 index 0000000..e9e1c66 --- /dev/null +++ b/src/Factory/SubnetFactory.php @@ -0,0 +1,58 @@ + + */ +final class SubnetFactory extends ModelFactory +{ + /** + * @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#factories-as-services + * + * @todo inject services if required + */ + public function __construct() + { + parent::__construct(); + } + + /** + * @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#model-factories + * + * @todo add your default values here + */ + protected function getDefaults(): array + { + return [ + 'bootFileName' => self::faker()->text(255), + 'createdAt' => self::faker()->dateTime(), + 'ipAddress' => self::faker()->text(255), + 'netmask' => self::faker()->text(255), + 'nextServer' => self::faker()->text(255), + 'updatedAt' => self::faker()->dateTime() + ]; + } + + /** + * @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#initialization + */ + protected function initialize(): self + { + return $this + // ->afterInstantiate(function(Subnet $subnet): void {}) + ; + } + + protected static function getClass(): string + { + return Subnet::class; + } +} diff --git a/src/Repository/SubnetRepository.php b/src/Repository/SubnetRepository.php new file mode 100644 index 0000000..988dd99 --- /dev/null +++ b/src/Repository/SubnetRepository.php @@ -0,0 +1,18 @@ + + */ +class SubnetRepository extends AbstractRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Subnet::class); + } +} diff --git a/src/State/Processor/SubnetProcessor.php b/src/State/Processor/SubnetProcessor.php new file mode 100644 index 0000000..0fef5cf --- /dev/null +++ b/src/State/Processor/SubnetProcessor.php @@ -0,0 +1,69 @@ +processCreateOrUpdate($data, $operation, $uriVariables, $context); + case $operation instanceof Delete: + return $this->processDelete($data, $operation, $uriVariables, $context); + } + } + + /** + * @throws \Exception + */ + private function processCreateOrUpdate($data, Operation $operation, array $uriVariables = [], array $context = []): SubnetOutput + { + if (!($data instanceof SubnetInput)) { + throw new \Exception(sprintf('data is not instance of %s', SubnetInput::class)); + } + + $entity = null; + if (isset($uriVariables['uuid'])) { + $entity = $this->subnetRepository->findOneByUuid($uriVariables['uuid']); + } + + $subnet = $data->createOrUpdateEntity($entity); + $this->validator->validate($subnet); + $this->subnetRepository->save($subnet); + + return new SubnetOutput($subnet); + } + + private function processDelete($data, Operation $operation, array $uriVariables = [], array $context = []): null + { + $bootFile = $this->subnetRepository->findOneByUuid($uriVariables['uuid']); + $this->subnetRepository->delete($bootFile); + + return null; + } +} diff --git a/src/State/Provider/SubnetProvider.php b/src/State/Provider/SubnetProvider.php new file mode 100644 index 0000000..919c688 --- /dev/null +++ b/src/State/Provider/SubnetProvider.php @@ -0,0 +1,71 @@ +provideCollection($operation, $uriVariables, $context); + case $operation instanceof Patch: + case $operation instanceof Put: + return $this->provideInput($operation, $uriVariables, $context); + case $operation instanceof Get: + return $this->provideItem($operation, $uriVariables, $context); + } + } + + private function provideCollection(Operation $operation, array $uriVariables = [], array $context = []): object + { + $paginator = $this->collectionProvider->provide($operation, $uriVariables, $context); + + $items = new \ArrayObject(); + foreach ($paginator->getIterator() as $item){ + $items[] = new SubnetOutput($item); + } + + return new TraversablePaginator($items, $paginator->getCurrentPage(), $paginator->getItemsPerPage(), $paginator->getTotalItems()); + } + + public function provideItem(Operation $operation, array $uriVariables = [], array $context = []): object|array|null + { + $item = $this->itemProvider->provide($operation, $uriVariables, $context); + + if (!$item) { + throw new NotFoundHttpException('Subnet not found'); + } + + return new SubnetOutput($item); + } + + public function provideInput(Operation $operation, array $uriVariables = [], array $context = []): object|array|null + { + if (isset($uriVariables['uuid'])) { + $item = $this->itemProvider->provide($operation, $uriVariables, $context); + + return $item !== null ? new SubnetInput($item) : null; + } + + return new SubnetInput(); + } +}