From c7028d76a0423bbc128e0105105c0aac154f4029 Mon Sep 17 00:00:00 2001 From: Jan Ritter Date: Thu, 12 Apr 2018 18:35:34 +0200 Subject: [PATCH 01/16] feat(#144): added Network entity with relations to Host and Container --- src/AppBundle/Entity/Container.php | 29 +++- src/AppBundle/Entity/Host.php | 32 +++- src/AppBundle/Entity/Network.php | 269 +++++++++++++++++++++++++++++ 3 files changed, 327 insertions(+), 3 deletions(-) create mode 100644 src/AppBundle/Entity/Network.php diff --git a/src/AppBundle/Entity/Container.php b/src/AppBundle/Entity/Container.php index 3b276f8b..57299c32 100644 --- a/src/AppBundle/Entity/Container.php +++ b/src/AppBundle/Entity/Container.php @@ -146,7 +146,7 @@ class Container * @var * @ORM\Column(type="json", nullable=true) * @Assert\Type(type="array") - * @OAS\Property(example="{'limits.cpu': '2'}") + * @OAS\Property(example="{'limits.cpu': '2'}") //TODO Maybe not required with the new Network Entity */ protected $network; @@ -205,12 +205,19 @@ class Container */ protected $image; + /** + * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Network", mappedBy="containers") + * @JMS\Exclude() + */ + protected $networks; + public function __construct() { $this->profiles = new ArrayCollection(); $this->statuses = new ArrayCollection(); $this->backupSchedules = new ArrayCollection(); $this->backups = new ArrayCollection(); + $this->networks = new ArrayCollection(); } /** @@ -635,7 +642,27 @@ public function removeBackup(Backup $backup){ $backup->removeContainer($this); } + /** + * @param Network $network + */ + public function addNetwork(Network $network){ + if ($this->networks->contains($network)) { + return; + } + $this->networks->add($network); + $this->networks->addContainer($this); + } + /** + * @param Network $network + */ + public function removeNetwork(Network $network){ + if (!$this->backups->contains($network)) { + return; + } + $this->networks->removeElement($network); + $network->removeContainer($this); + } /** * @return array diff --git a/src/AppBundle/Entity/Host.php b/src/AppBundle/Entity/Host.php index eed2d68c..fecee706 100644 --- a/src/AppBundle/Entity/Host.php +++ b/src/AppBundle/Entity/Host.php @@ -144,6 +144,12 @@ class Host */ protected $statuses; + /** + * @ORM\OneToMany(targetEntity="AppBundle\Entity\Network", mappedBy="host") + * @JMS\Exclude() + */ + protected $lxdNetworks; + public function __construct() { @@ -151,6 +157,7 @@ public function __construct() $this->profiles = new ArrayCollection(); $this->images = new ArrayCollection(); $this->statuses = new ArrayCollection(); + $this->lxdNetworks = new ArrayCollection(); } @@ -423,9 +430,30 @@ public function removeContainer(Container $container){ } /** - * Adds a Image to the Host. - * @param Image $image + * @param Network $network */ + public function addLXDNetwork(Network $network){ + if ($this->lxdNetworks->contains($network)) { + return; + } + $this->lxdNetworks->add($network); + $network->setHost($this); + } + + /** + * @param Network $network + */ + public function removeLXDNetwork(Network $network){ + if (!$this->lxdNetworks->contains($network)) { + return; + } + $this->lxdNetworks->removeElement($network); + $network->setHost(null); + } + + /** + * @param Image $image + */ public function addImage(Image $image){ if ($this->images->contains($image)) { return; diff --git a/src/AppBundle/Entity/Network.php b/src/AppBundle/Entity/Network.php new file mode 100644 index 00000000..40230fbe --- /dev/null +++ b/src/AppBundle/Entity/Network.php @@ -0,0 +1,269 @@ +containers = new ArrayCollection(); + } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * @return Host | null + */ + public function getHost() : ?Host + { + return $this->host; + } + + /** + * @param Host $host + */ + public function setHost(Host $host) + { + $this->host = $host; + } + + /** + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * @param string $name + */ + public function setName(string $name): void + { + $this->name = $name; + } + + /** + * @return string + */ + public function getDescription(): string + { + return $this->description; + } + + /** + * @param string $description + */ + public function setDescription(string $description): void + { + $this->description = $description; + } + + /** + * @return array + */ + public function getConfig(): array + { + return $this->config; + } + + /** + * @param array $config + */ + public function setConfig(array $config): void + { + $this->config = $config; + } + + /** + * @return string + */ + public function getType(): string + { + return $this->type; + } + + /** + * @param string $type + */ + public function setType(string $type): void + { + $this->type = $type; + } + + /** + * @return bool + */ + public function isManaged(): bool + { + return $this->managed; + } + + /** + * @param bool $managed + */ + public function setManaged(bool $managed): void + { + $this->managed = $managed; + } + + /** + * @return string + */ + public function getStatus(): string + { + return $this->status; + } + + /** + * @param string $status + */ + public function setStatus(string $status): void + { + $this->status = $status; + } + + /** + * @return PersistentCollection + */ + public function getContainers(): PersistentCollection + { + return $this->containers; + } + + /** + * @param PersistentCollection $containers + */ + public function setContainers(PersistentCollection $containers): void + { + $this->containers = $containers; + } + + /** + * @param Container $container + */ + public function addContainer(Container $container) + { + if ($this->containers->contains($container)) { + return; + } + $this->containers->add($container); + $container->addNetwork($this); + } + + /** + * @param Container $container + */ + public function removeContainer(Container $container){ + if (!$this->containers->contains($container)) { + return; + } + $this->containers->removeElement($container); + $container->removeNetwork($this); + } +} \ No newline at end of file From 08f49d517bd831b12fadc4a0d5367a62928972f1 Mon Sep 17 00:00:00 2001 From: Jan Ritter Date: Thu, 12 Apr 2018 18:38:55 +0200 Subject: [PATCH 02/16] fix: fixed relation functions between Host and Image entity --- src/AppBundle/Entity/Host.php | 4 ++-- src/AppBundle/Entity/Image.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/AppBundle/Entity/Host.php b/src/AppBundle/Entity/Host.php index fecee706..3b828b25 100644 --- a/src/AppBundle/Entity/Host.php +++ b/src/AppBundle/Entity/Host.php @@ -459,7 +459,7 @@ public function addImage(Image $image){ return; } $this->images->add($image); - $image->addHost($this); + $image->setHost($this); } /** @@ -471,7 +471,7 @@ public function removeImage(Image $image){ return; } $this->images->removeElement($image); - $image->removeHost($this); + $image->setHost(null); } /** diff --git a/src/AppBundle/Entity/Image.php b/src/AppBundle/Entity/Image.php index 14fba42a..ad803d16 100644 --- a/src/AppBundle/Entity/Image.php +++ b/src/AppBundle/Entity/Image.php @@ -211,7 +211,7 @@ public function getHost() /** * @param Host $host */ - public function setHost(Host $host) + public function setHost($host) { $this->host = $host; } From 03f9618316b0b2c112e69757a3ecb5cd1fbd884b Mon Sep 17 00:00:00 2001 From: Jan Ritter Date: Thu, 12 Apr 2018 18:49:17 +0200 Subject: [PATCH 03/16] feat(#144): added missing orm entity and corrected inversed by value in network entity --- src/AppBundle/Entity/Network.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/AppBundle/Entity/Network.php b/src/AppBundle/Entity/Network.php index 40230fbe..1af7c7ef 100644 --- a/src/AppBundle/Entity/Network.php +++ b/src/AppBundle/Entity/Network.php @@ -11,6 +11,7 @@ /** * Class Network * @package AppBundle\Entity + * @ORM\Entity * @ORM\Table(name="lxdNetwork") */ class Network @@ -78,7 +79,7 @@ class Network protected $status; /** - * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Container", inversedBy=lxdnetworks") + * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Container", inversedBy="networks") * @ORM\JoinTable( * joinColumns={ * @ORM\JoinColumn(name="lxdnetwork_id", referencedColumnName="id") From 984ee7d50cef1af47e34cf9107ad438c3a5c64a8 Mon Sep 17 00:00:00 2001 From: Jan Ritter Date: Sun, 15 Apr 2018 11:54:30 +0200 Subject: [PATCH 04/16] feat: added locations attribute to network entity --- src/AppBundle/Entity/Network.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/AppBundle/Entity/Network.php b/src/AppBundle/Entity/Network.php index 1af7c7ef..71a3cbb6 100644 --- a/src/AppBundle/Entity/Network.php +++ b/src/AppBundle/Entity/Network.php @@ -78,6 +78,14 @@ class Network */ protected $status; + /** + * @ORM\Column(type="array", nullable=true) + * @Assert\Type(type="array") + * + * @var array + */ + protected $locations; + /** * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Container", inversedBy="networks") * @ORM\JoinTable( @@ -245,6 +253,22 @@ public function setContainers(PersistentCollection $containers): void $this->containers = $containers; } + /** + * @return array + */ + public function getLocations(): ?array + { + return $this->locations; + } + + /** + * @param array $locations + */ + public function setLocations($locations): void + { + $this->locations = $locations; + } + /** * @param Container $container */ From 31b6c83443de24d4929dc8a5a6ab524af40ce134 Mon Sep 17 00:00:00 2001 From: Jan Ritter Date: Sun, 15 Apr 2018 12:10:39 +0200 Subject: [PATCH 05/16] docs: added openAPI doc to network entity --- src/AppBundle/Entity/Network.php | 33 ++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/AppBundle/Entity/Network.php b/src/AppBundle/Entity/Network.php index 71a3cbb6..d5be7550 100644 --- a/src/AppBundle/Entity/Network.php +++ b/src/AppBundle/Entity/Network.php @@ -7,12 +7,15 @@ use Symfony\Component\Validator\Constraints as Assert; use JMS\Serializer\Annotation as JMS; use Doctrine\ORM\Mapping as ORM; +use Swagger\Annotations as OAS; /** * Class Network * @package AppBundle\Entity * @ORM\Entity * @ORM\Table(name="lxdNetwork") + * + * @OAS\Schema(schema="network", type="object") */ class Network { @@ -21,6 +24,7 @@ class Network * @ORM\GeneratedValue * @ORM\Column(type="integer") * + * @OAS\Property(example="2") * @var integer */ protected $id; @@ -30,6 +34,7 @@ class Network * @Assert\Type(type="string") * @Assert\NotNull() * + * @OAS\Property(example="lxd-network-1") * @var string */ protected $name; @@ -38,6 +43,7 @@ class Network * @ORM\Column(type="string", nullable=true) * @Assert\Type(type="string") * + * @OAS\Property(example="Some description string") * @var string */ protected $description; @@ -46,9 +52,7 @@ class Network * @ORM\Column(type="json") * @Assert\NotNull() * @Assert\Type(type="array") - * @Assert\Choice({"bridge"}, strict="true") * - * //TODO Add missing choices * @var array */ protected $config; @@ -56,7 +60,9 @@ class Network /** * @ORM\Column(type="string") * @Assert\Type(type="string") + * @Assert\Choice({"bridge"}, strict="true") * + * @OAS\Property(example="bridge") * @var string */ protected $type; @@ -66,6 +72,7 @@ class Network * @Assert\NotNull() * @Assert\Type(type="boolean") * + * @OAS\Property(example=true) * @var boolean */ protected $managed; @@ -74,6 +81,7 @@ class Network * @ORM\Column(type="string", nullable=true) * @Assert\Type(type="string") * + * @OAS\Property(example="Created") * @var string */ protected $status; @@ -82,6 +90,7 @@ class Network * @ORM\Column(type="array", nullable=true) * @Assert\Type(type="array") * + * @OAS\Property(example="Json array with locations") * @var array */ protected $locations; @@ -291,4 +300,24 @@ public function removeContainer(Container $container){ $this->containers->removeElement($container); $container->removeNetwork($this); } + + /** + * @return array + * + * @OAS\Property(property="containerId", example="[1]") + * + * @JMS\VirtualProperty() + */ + public function getContainerId(){ + if($this->containers->isEmpty()){ + return null; + } + + $this->containers->first(); + do{ + $ids[] = $this->containers->current()->getId(); + }while($this->containers->next()); + + return $ids; + } } \ No newline at end of file From 66419515cd2582a8ee9ad65cf6ce09e7f4d3959b Mon Sep 17 00:00:00 2001 From: Jan Ritter Date: Sun, 15 Apr 2018 12:14:01 +0200 Subject: [PATCH 06/16] refactor: removed choices assertions in Network entity --- src/AppBundle/Entity/Network.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/AppBundle/Entity/Network.php b/src/AppBundle/Entity/Network.php index d5be7550..99bcddca 100644 --- a/src/AppBundle/Entity/Network.php +++ b/src/AppBundle/Entity/Network.php @@ -60,7 +60,6 @@ class Network /** * @ORM\Column(type="string") * @Assert\Type(type="string") - * @Assert\Choice({"bridge"}, strict="true") * * @OAS\Property(example="bridge") * @var string From 25ac6003a47770c5e5be3788473a9402fae069a1 Mon Sep 17 00:00:00 2001 From: Jan Ritter Date: Sun, 15 Apr 2018 12:24:20 +0200 Subject: [PATCH 07/16] feat: added getAllNetworks endpoint --- .../Controller/NetworkController.php | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/AppBundle/Controller/NetworkController.php diff --git a/src/AppBundle/Controller/NetworkController.php b/src/AppBundle/Controller/NetworkController.php new file mode 100644 index 00000000..b52c12e0 --- /dev/null +++ b/src/AppBundle/Controller/NetworkController.php @@ -0,0 +1,42 @@ +getDoctrine()->getRepository(Network::class)->findAll(); + + if(!$networks){ + throw new ElementNotFoundException( + 'No Networks found' + ); + } + + $serializer = $this->get('jms_serializer'); + $response = $serializer->serialize($networks, 'json'); + return new Response($response); + } + + public function getSingleNetwork(){ + + } + + public function createNetwork(){ + + } + + public function deleteNetwork(){ + + } +} \ No newline at end of file From 0fe7fa1b4caec9800a3f5a18f2a625d3baa18fe8 Mon Sep 17 00:00:00 2001 From: Jan Ritter Date: Sun, 15 Apr 2018 12:26:28 +0200 Subject: [PATCH 08/16] feat: added getSingleNetwork endpoint --- src/AppBundle/Controller/NetworkController.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/AppBundle/Controller/NetworkController.php b/src/AppBundle/Controller/NetworkController.php index b52c12e0..1ffe02a2 100644 --- a/src/AppBundle/Controller/NetworkController.php +++ b/src/AppBundle/Controller/NetworkController.php @@ -28,8 +28,24 @@ public function getAllNetworks(){ return new Response($response); } - public function getSingleNetwork(){ + /** + * @Route("/networks/{networkID}", name="get_single_networks", methods={"GET"}) + * @param $networkID + * @return Response + * @throws ElementNotFoundException + */ + public function getSingleNetwork($networkID){ + $network = $this->getDoctrine()->getRepository(Network::class)->find($networkID); + if(!$network){ + throw new ElementNotFoundException( + 'No Network for '.$networkID.' found' + ); + } + + $serializer = $this->get('jms_serializer'); + $response = $serializer->serialize($network, 'json'); + return new Response($response); } public function createNetwork(){ From 5169e47ac81799e0a73937f97147ca19ce0874e7 Mon Sep 17 00:00:00 2001 From: Jan Ritter Date: Sun, 15 Apr 2018 12:38:05 +0200 Subject: [PATCH 09/16] refactor: removed type hints from setters to allow validation --- src/AppBundle/Entity/Network.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/AppBundle/Entity/Network.php b/src/AppBundle/Entity/Network.php index 99bcddca..d21aff00 100644 --- a/src/AppBundle/Entity/Network.php +++ b/src/AppBundle/Entity/Network.php @@ -160,7 +160,7 @@ public function getName(): string /** * @param string $name */ - public function setName(string $name): void + public function setName($name): void { $this->name = $name; } @@ -176,7 +176,7 @@ public function getDescription(): string /** * @param string $description */ - public function setDescription(string $description): void + public function setDescription($description): void { $this->description = $description; } @@ -192,7 +192,7 @@ public function getConfig(): array /** * @param array $config */ - public function setConfig(array $config): void + public function setConfig($config): void { $this->config = $config; } @@ -208,7 +208,7 @@ public function getType(): string /** * @param string $type */ - public function setType(string $type): void + public function setType($type): void { $this->type = $type; } @@ -224,7 +224,7 @@ public function isManaged(): bool /** * @param bool $managed */ - public function setManaged(bool $managed): void + public function setManaged($managed): void { $this->managed = $managed; } @@ -240,7 +240,7 @@ public function getStatus(): string /** * @param string $status */ - public function setStatus(string $status): void + public function setStatus($status): void { $this->status = $status; } From 4d83b6576a88f3f614deff159274f95b11b46ee5 Mon Sep 17 00:00:00 2001 From: Jan Ritter Date: Sun, 15 Apr 2018 13:05:38 +0200 Subject: [PATCH 10/16] feat: added networkApi service --- src/AppBundle/Service/LxdApi/NetworkApi.php | 82 +++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 src/AppBundle/Service/LxdApi/NetworkApi.php diff --git a/src/AppBundle/Service/LxdApi/NetworkApi.php b/src/AppBundle/Service/LxdApi/NetworkApi.php new file mode 100644 index 00000000..9d176fba --- /dev/null +++ b/src/AppBundle/Service/LxdApi/NetworkApi.php @@ -0,0 +1,82 @@ +init(); + } + + + /** + * List of all networks on one host + * + * @param Host $host + * @return object + * @throws \Httpful\Exception\ConnectionErrorException + */ + public function list(Host $host) + { + $uri = $this->buildUri($host, $this->getEndpoint()); + return Request::get($uri)->timeoutIn(10)->send(); + } + + /** + * Create a new network an the Host + * + * @param Host $host + * @param Network $network + * @return \Httpful\Response + * @throws \Httpful\Exception\ConnectionErrorException + */ + public function createNetwork(Host $host, Network $network){ + $uri = $this->buildUri($host, $this->getEndpoint()); + + //Build body with provided values + $body = array(); + if($network->getName()) { + $body['name'] = $network->getName(); + } + if($network->getDescription()) { + $body['description'] = $network->getDescription(); + } + if($network->getConfig()) { + $body['config'] = $network->getConfig(); + } + if($network->getType()) { + $body['type'] = $network->getType(); + } + + return Request::post($uri) + -> body(json_encode($body)) + -> timeoutIn(10) + -> send(); + } + + /** + * Get a single network from the Hos (by name) + * + * @param Host $host + * @param $networkName + * @return \Httpful\Response + * @throws \Httpful\Exception\ConnectionErrorException + */ + public function getSingleNetwork(Host $host, $networkName){ + $uri = $this->buildUri($host, $this->getEndpoint()); + return Request::get($uri."/".$networkName)->timeoutIn(10)->send(); + } +} \ No newline at end of file From 8da336e2c697c0d427dfadf64b85d7f37e649b1a Mon Sep 17 00:00:00 2001 From: Jan Ritter Date: Sun, 15 Apr 2018 13:12:08 +0200 Subject: [PATCH 11/16] feat: added createNetwork endpoint --- .../Controller/NetworkController.php | 83 ++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/src/AppBundle/Controller/NetworkController.php b/src/AppBundle/Controller/NetworkController.php index 1ffe02a2..1d701516 100644 --- a/src/AppBundle/Controller/NetworkController.php +++ b/src/AppBundle/Controller/NetworkController.php @@ -2,9 +2,14 @@ namespace AppBundle\Controller; +use AppBundle\Entity\Host; use AppBundle\Entity\Network; use AppBundle\Exception\ElementNotFoundException; +use AppBundle\Exception\WrongInputException; +use AppBundle\Exception\WrongInputExceptionArray; +use AppBundle\Service\LxdApi\NetworkApi; use Symfony\Bundle\FrameworkBundle\Controller\Controller; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; @@ -48,11 +53,87 @@ public function getSingleNetwork($networkID){ return new Response($response); } - public function createNetwork(){ + /** + * @Route("/hosts/{hostID}/networks", name="create_network_on_host", methods={"POST"}) + * + * @param Request $request + * @param $hostID + * @param NetworkApi $networkApi + * @return Response + * @throws ElementNotFoundException + * @throws WrongInputException + * @throws WrongInputExceptionArray + * @throws \Httpful\Exception\ConnectionErrorException + */ + public function createNetwork(Request $request, $hostID, NetworkApi $networkApi){ + $network = new Network(); + + if($request->request->has('name')) { + $network->setName($request->request->get('name')); + } + if($request->request->has('description')) { + $network->setDescription($request->request->get('description')); + } + if($request->request->has('config')) { + $network->setConfig($request->request->get('config')); + } + if($request->request->has('type')) { + $network->setType($request->request->get('type')); + } + + if ($errorArray = $this->validation($network)) { + throw new WrongInputExceptionArray($errorArray); + } + + $host = $this->getDoctrine()->getRepository(Host::class)->find($hostID); + if(!$host){ + throw new ElementNotFoundException( + 'No Host for '.$hostID.' found' + ); + } + + $result = $networkApi->createNetwork($host, $network); + if($result->code != 201){ + throw new WrongInputException("LXD Error - ".$result->body->error); + } + + $result = $networkApi->getSingleNetwork($host, $network->getName()); + if($result->code != 200){ + throw new WrongInputException("LXD Error - ".$result->body->error); + } + + $network->setManaged($result->body->metadata->managed); + $network->setStatus($result->body->metadata->status); + $network->setLocations($result->body->metadata->locations); + + $host->addLXDNetwork($network); + $em = $this->getDoctrine()->getManager(); + $em->persist($host); + $em->persist($network); + $em->flush(); + + $serializer = $this->get('jms_serializer'); + $response = $serializer->serialize($network, 'json'); + return new Response($response, Response::HTTP_CREATED); } public function deleteNetwork(){ } + + private function validation($object) + { + $validator = $this->get('validator'); + $errors = $validator->validate($object); + + if (count($errors) > 0) { + $errorArray = array(); + foreach ($errors as $error) { + $errorArray[$error->getPropertyPath()] = $error->getMessage(); + } + return $errorArray; + } + return false; + } } \ No newline at end of file From 89a0b1b7370e483cfb2195ce619346f6cfb12c21 Mon Sep 17 00:00:00 2001 From: Jan Ritter Date: Sun, 15 Apr 2018 13:27:01 +0200 Subject: [PATCH 12/16] refactor: removed assertion from optional attribute and enabled getter functions to return null --- src/AppBundle/Entity/Network.php | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/AppBundle/Entity/Network.php b/src/AppBundle/Entity/Network.php index d21aff00..20899906 100644 --- a/src/AppBundle/Entity/Network.php +++ b/src/AppBundle/Entity/Network.php @@ -68,8 +68,6 @@ class Network /** * @ORM\Column(type="boolean") - * @Assert\NotNull() - * @Assert\Type(type="boolean") * * @OAS\Property(example=true) * @var boolean @@ -198,9 +196,9 @@ public function setConfig($config): void } /** - * @return string + * @return string | null */ - public function getType(): string + public function getType(): ?string { return $this->type; } @@ -214,9 +212,9 @@ public function setType($type): void } /** - * @return bool + * @return bool | null */ - public function isManaged(): bool + public function isManaged(): ?bool { return $this->managed; } @@ -230,9 +228,9 @@ public function setManaged($managed): void } /** - * @return string + * @return string | null */ - public function getStatus(): string + public function getStatus(): ?string { return $this->status; } From c9a355bb12306fecdab3015dc906f114b280d425 Mon Sep 17 00:00:00 2001 From: Jan Ritter Date: Sun, 15 Apr 2018 13:28:13 +0200 Subject: [PATCH 13/16] feat: set network type based on the response after the creation --- src/AppBundle/Controller/NetworkController.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/AppBundle/Controller/NetworkController.php b/src/AppBundle/Controller/NetworkController.php index 1d701516..77e7f3c7 100644 --- a/src/AppBundle/Controller/NetworkController.php +++ b/src/AppBundle/Controller/NetworkController.php @@ -105,6 +105,7 @@ public function createNetwork(Request $request, $hostID, NetworkApi $networkApi) $network->setManaged($result->body->metadata->managed); $network->setStatus($result->body->metadata->status); $network->setLocations($result->body->metadata->locations); + $network->setType($result->body->metadata->type); $host->addLXDNetwork($network); From edd5fb735d44f85060a83a18366077f0c2bc2ded Mon Sep 17 00:00:00 2001 From: Jan Ritter Date: Sun, 15 Apr 2018 13:58:55 +0200 Subject: [PATCH 14/16] feat: added endpoint to delete a network --- .../Controller/NetworkController.php | 30 +++++++++++++++++-- src/AppBundle/Service/LxdApi/NetworkApi.php | 13 ++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/AppBundle/Controller/NetworkController.php b/src/AppBundle/Controller/NetworkController.php index 77e7f3c7..776e918b 100644 --- a/src/AppBundle/Controller/NetworkController.php +++ b/src/AppBundle/Controller/NetworkController.php @@ -44,7 +44,7 @@ public function getSingleNetwork($networkID){ if(!$network){ throw new ElementNotFoundException( - 'No Network for '.$networkID.' found' + 'No Network for ID '.$networkID.' found' ); } @@ -88,7 +88,7 @@ public function createNetwork(Request $request, $hostID, NetworkApi $networkApi) $host = $this->getDoctrine()->getRepository(Host::class)->find($hostID); if(!$host){ throw new ElementNotFoundException( - 'No Host for '.$hostID.' found' + 'No Host for ID '.$hostID.' found' ); } @@ -119,8 +119,32 @@ public function createNetwork(Request $request, $hostID, NetworkApi $networkApi) return new Response($response, Response::HTTP_CREATED); } - public function deleteNetwork(){ + /** + * @Route("/networks/{networkID}", name="delete_network", methods={"DELETE"}) + * @throws ElementNotFoundException + * @throws WrongInputException + * @throws \Httpful\Exception\ConnectionErrorException + */ + public function deleteNetwork($networkID, NetworkApi $networkApi){ + $network = $this->getDoctrine()->getRepository(Network::class)->find($networkID); + + if(!$network){ + throw new ElementNotFoundException( + 'No Network for ID '.$networkID.' found' + ); + } + + $result = $networkApi->deleteNetwork($network->getHost(), $network->getName()); + + if($result->code != 200 && $result->code != 404){ + throw new WrongInputException("LXD Error - ".$result->body->error); + } + + $em = $this->getDoctrine()->getManager(); + $em->remove($network); + $em->flush(); + return $this->json([], 204); } private function validation($object) diff --git a/src/AppBundle/Service/LxdApi/NetworkApi.php b/src/AppBundle/Service/LxdApi/NetworkApi.php index 9d176fba..52b435bc 100644 --- a/src/AppBundle/Service/LxdApi/NetworkApi.php +++ b/src/AppBundle/Service/LxdApi/NetworkApi.php @@ -79,4 +79,17 @@ public function getSingleNetwork(Host $host, $networkName){ $uri = $this->buildUri($host, $this->getEndpoint()); return Request::get($uri."/".$networkName)->timeoutIn(10)->send(); } + + /** + * Delete single network by name + * + * @param Host $host + * @param $networkName + * @return \Httpful\Response + * @throws \Httpful\Exception\ConnectionErrorException + */ + public function deleteNetwork(Host $host, $networkName){ + $uri = $this->buildUri($host, $this->getEndpoint()); + return Request::delete($uri."/".$networkName)->timeoutIn(10)->send(); + } } \ No newline at end of file From 7d3eeba99ffc6c9d55db654dcf87aed6dad40a4a Mon Sep 17 00:00:00 2001 From: Leon Lenzen Date: Mon, 27 Aug 2018 10:07:03 +0200 Subject: [PATCH 15/16] feat: endpoint for networks from host --- .../Controller/NetworkController.php | 74 +++++++++++++------ 1 file changed, 53 insertions(+), 21 deletions(-) diff --git a/src/AppBundle/Controller/NetworkController.php b/src/AppBundle/Controller/NetworkController.php index 776e918b..657b1722 100644 --- a/src/AppBundle/Controller/NetworkController.php +++ b/src/AppBundle/Controller/NetworkController.php @@ -13,16 +13,42 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; + +/** + * @todo document the api endpoints + */ class NetworkController extends Controller { /** * @Route("/networks", name="get_all_networks", methods={"GET"}) * @throws ElementNotFoundException */ - public function getAllNetworks(){ + public function getAllNetworks() + { $networks = $this->getDoctrine()->getRepository(Network::class)->findAll(); - if(!$networks){ + if (!$networks) { + throw new ElementNotFoundException( + 'No Networks found' + ); + } + + $serializer = $this->get('jms_serializer'); + $response = $serializer->serialize($networks, 'json'); + return new Response($response); + } + + /** + * @Route("/hosts/{hostID}/networks", name="get_all_networks_from_host", methods={"GET"}) + * @throws ElementNotFoundException + * @param int $hostID + * @return Response + */ + public function getAllNetworksFromHost($hostID) + { + $networks = $this->getDoctrine()->getRepository(Network::class)->findBy(['host' => $hostID]); + + if (!$networks) { throw new ElementNotFoundException( 'No Networks found' ); @@ -33,18 +59,22 @@ public function getAllNetworks(){ return new Response($response); } + + + /** * @Route("/networks/{networkID}", name="get_single_networks", methods={"GET"}) * @param $networkID * @return Response * @throws ElementNotFoundException */ - public function getSingleNetwork($networkID){ + public function getSingleNetwork($networkID) + { $network = $this->getDoctrine()->getRepository(Network::class)->find($networkID); - if(!$network){ + if (!$network) { throw new ElementNotFoundException( - 'No Network for ID '.$networkID.' found' + 'No Network for ID ' . $networkID . ' found' ); } @@ -65,19 +95,20 @@ public function getSingleNetwork($networkID){ * @throws WrongInputExceptionArray * @throws \Httpful\Exception\ConnectionErrorException */ - public function createNetwork(Request $request, $hostID, NetworkApi $networkApi){ + public function createNetwork(Request $request, $hostID, NetworkApi $networkApi) + { $network = new Network(); - if($request->request->has('name')) { + if ($request->request->has('name')) { $network->setName($request->request->get('name')); } - if($request->request->has('description')) { + if ($request->request->has('description')) { $network->setDescription($request->request->get('description')); } - if($request->request->has('config')) { + if ($request->request->has('config')) { $network->setConfig($request->request->get('config')); } - if($request->request->has('type')) { + if ($request->request->has('type')) { $network->setType($request->request->get('type')); } @@ -86,20 +117,20 @@ public function createNetwork(Request $request, $hostID, NetworkApi $networkApi) } $host = $this->getDoctrine()->getRepository(Host::class)->find($hostID); - if(!$host){ + if (!$host) { throw new ElementNotFoundException( - 'No Host for ID '.$hostID.' found' + 'No Host for ID ' . $hostID . ' found' ); } $result = $networkApi->createNetwork($host, $network); - if($result->code != 201){ - throw new WrongInputException("LXD Error - ".$result->body->error); + if ($result->code != 201) { + throw new WrongInputException("LXD Error - " . $result->body->error); } $result = $networkApi->getSingleNetwork($host, $network->getName()); - if($result->code != 200){ - throw new WrongInputException("LXD Error - ".$result->body->error); + if ($result->code != 200) { + throw new WrongInputException("LXD Error - " . $result->body->error); } $network->setManaged($result->body->metadata->managed); @@ -125,19 +156,20 @@ public function createNetwork(Request $request, $hostID, NetworkApi $networkApi) * @throws WrongInputException * @throws \Httpful\Exception\ConnectionErrorException */ - public function deleteNetwork($networkID, NetworkApi $networkApi){ + public function deleteNetwork($networkID, NetworkApi $networkApi) + { $network = $this->getDoctrine()->getRepository(Network::class)->find($networkID); - if(!$network){ + if (!$network) { throw new ElementNotFoundException( - 'No Network for ID '.$networkID.' found' + 'No Network for ID ' . $networkID . ' found' ); } $result = $networkApi->deleteNetwork($network->getHost(), $network->getName()); - if($result->code != 200 && $result->code != 404){ - throw new WrongInputException("LXD Error - ".$result->body->error); + if ($result->code != 200 && $result->code != 404) { + throw new WrongInputException("LXD Error - " . $result->body->error); } $em = $this->getDoctrine()->getManager(); From a253a7419ec7a6a7017bc0d99bbe7f9bbdfefab3 Mon Sep 17 00:00:00 2001 From: Leon Lenzen Date: Mon, 27 Aug 2018 10:10:20 +0200 Subject: [PATCH 16/16] refactor: typo --- src/AppBundle/Entity/Container.php | 105 ++++++++++++++++------------- 1 file changed, 58 insertions(+), 47 deletions(-) diff --git a/src/AppBundle/Entity/Container.php b/src/AppBundle/Entity/Container.php index e8ee6c7c..484ed73a 100644 --- a/src/AppBundle/Entity/Container.php +++ b/src/AppBundle/Entity/Container.php @@ -1,4 +1,5 @@ id; } @@ -211,8 +212,9 @@ public function getId() :int /** * @param ContainerStatus $containerStatus */ - public function addStatus(ContainerStatus $containerStatus){ - if(!$this->statuses->contains($containerStatus)){ + public function addStatus(ContainerStatus $containerStatus) + { + if (!$this->statuses->contains($containerStatus)) { $containerStatus->setContainer($this); $this->statuses->add($containerStatus); } @@ -221,8 +223,9 @@ public function addStatus(ContainerStatus $containerStatus){ /** * @param ContainerStatus $containerStatus */ - public function removeStatus(ContainerStatus $containerStatus){ - if(!$this->statuses->contains($containerStatus)){ + public function removeStatus(ContainerStatus $containerStatus) + { + if (!$this->statuses->contains($containerStatus)) { $containerStatus->setContainer(null); $this->statuses->remove($containerStatus); } @@ -317,7 +320,7 @@ public function setState($state) /** * @return string */ - public function getArchitecture(): string + public function getArchitecture() : string { return $this->architecture; } @@ -341,7 +344,7 @@ public function getConfig() /** * @param mixed $config */ - public function setConfig($config): void + public function setConfig($config) : void { $this->config = $config; } @@ -357,7 +360,7 @@ public function getExpandedConfig() /** * @param mixed $expandedConfig */ - public function setExpandedConfig($expandedConfig): void + public function setExpandedConfig($expandedConfig) : void { $this->expandedConfig = $expandedConfig; } @@ -373,7 +376,7 @@ public function getDevices() /** * @param mixed $devices */ - public function setDevices($devices): void + public function setDevices($devices) : void { $this->devices = $devices; } @@ -389,7 +392,7 @@ public function getExpandedDevices() /** * @param mixed $expandedDevices */ - public function setExpandedDevices($expandedDevices): void + public function setExpandedDevices($expandedDevices) : void { $this->expandedDevices = $expandedDevices; } @@ -405,7 +408,7 @@ public function getNetwork() /** * @param mixed $network */ - public function setNetwork($network): void + public function setNetwork($network) : void { $this->network = $network; } @@ -413,7 +416,7 @@ public function setNetwork($network): void /** * @return \DateTime */ - public function getCreatedAt(): \DateTime + public function getCreatedAt() : \DateTime { return $this->createdAt; } @@ -421,7 +424,7 @@ public function getCreatedAt(): \DateTime /** * @param \DateTime $createdAt */ - public function setCreatedAt($createdAt): void + public function setCreatedAt($createdAt) : void { $this->createdAt = $createdAt; } @@ -437,7 +440,7 @@ public function getError() /** * @param mixed $error */ - public function setError($error): void + public function setError($error) : void { $this->error = $error; } @@ -445,7 +448,7 @@ public function setError($error): void /** * @return bool */ - public function isEphemeral(): bool + public function isEphemeral() : bool { return $this->ephemeral; } @@ -453,7 +456,7 @@ public function isEphemeral(): bool /** * @param bool $ephemeral */ - public function setEphemeral($ephemeral): void + public function setEphemeral($ephemeral) : void { $this->ephemeral = $ephemeral; } @@ -463,7 +466,7 @@ public function setEphemeral($ephemeral): void /** * @return Image */ - public function getImage(): Image + public function getImage() : Image { return $this->image; } @@ -471,7 +474,7 @@ public function getImage(): Image /** * @param Image $image */ - public function setImage(Image $image): void + public function setImage(Image $image) : void { $this->image = $image; } @@ -487,7 +490,7 @@ public function getProfiles() /** * @param mixed $profiles */ - public function setProfiles($profiles): void + public function setProfiles($profiles) : void { $this->profiles = $profiles; } @@ -503,13 +506,13 @@ public function getSource() /** * @param mixed $source */ - public function setSource($source): void + public function setSource($source) : void { $this->source = $source; } - public function getBody(): array + public function getBody() : array { $bodyDevices = $this->devices; @@ -520,14 +523,14 @@ public function getBody(): array ]; $body = [ - "name" => $this->getName(), - "architecture" => $this->getArchitecture(), - "profiles" => $this->getProfileNames(), - "ephemeral" => $this->isEphemeral(), - "config" => $this->getConfig(), - "devices" => $bodyDevices, - "source" => $this->getSource() - ]; + "name" => $this->getName(), + "architecture" => $this->getArchitecture(), + "profiles" => $this->getProfileNames(), + "ephemeral" => $this->isEphemeral(), + "config" => $this->getConfig(), + "devices" => $bodyDevices, + "source" => $this->getSource() + ]; return $body; } @@ -538,7 +541,8 @@ public function getBody(): array /** * @param Profile $profile */ - public function addProfile(Profile $profile){ + public function addProfile(Profile $profile) + { if ($this->profiles->contains($profile)) { return; } @@ -549,7 +553,8 @@ public function addProfile(Profile $profile){ /** * @param Profile $profile */ - public function removeProfile(Profile $profile){ + public function removeProfile(Profile $profile) + { if (!$this->profiles->contains($profile)) { return; } @@ -560,7 +565,8 @@ public function removeProfile(Profile $profile){ /** * @param BackupSchedule $backupSchedule */ - public function addBackupSchedule(BackupSchedule $backupSchedule){ + public function addBackupSchedule(BackupSchedule $backupSchedule) + { if ($this->backupSchedules->contains($backupSchedule)) { return; } @@ -571,7 +577,8 @@ public function addBackupSchedule(BackupSchedule $backupSchedule){ /** * @param BackupSchedule $backupSchedule */ - public function removeBackupSchedule(BackupSchedule $backupSchedule){ + public function removeBackupSchedule(BackupSchedule $backupSchedule) + { if (!$this->backupSchedules->contains($backupSchedule)) { return; } @@ -582,7 +589,8 @@ public function removeBackupSchedule(BackupSchedule $backupSchedule){ /** * @param Backup $backup */ - public function addBackup(Backup $backup){ + public function addBackup(Backup $backup) + { if ($this->backups->contains($backup)) { return; } @@ -593,7 +601,8 @@ public function addBackup(Backup $backup){ /** * @param Backup $backup */ - public function removeBackup(Backup $backup){ + public function removeBackup(Backup $backup) + { if (!$this->backups->contains($backup)) { return; } @@ -604,7 +613,8 @@ public function removeBackup(Backup $backup){ /** * @param Network $network */ - public function addNetwork(Network $network){ + public function addNetwork(Network $network) + { if ($this->networks->contains($network)) { return; } @@ -615,7 +625,8 @@ public function addNetwork(Network $network){ /** * @param Network $network */ - public function removeNetwork(Network $network){ + public function removeNetwork(Network $network) + { if (!$this->backups->contains($network)) { return; } @@ -630,15 +641,16 @@ public function removeNetwork(Network $network){ * * @JMS\VirtualProperty() */ - public function getProfileId(){ - if($this->profiles->isEmpty()){ + public function getProfileId() + { + if ($this->profiles->isEmpty()) { return null; } $this->profiles->first(); - do{ + do { $ids[] = $this->profiles->current()->getId(); - }while($this->profiles->next()); + } while ($this->profiles->next()); return $ids; } @@ -647,12 +659,11 @@ public function getProfileNames() { $profileNames = array(); - if($this->profiles->isEmpty()){ + if ($this->profiles->isEmpty()) { return $profileNames; } - foreach ($this->profiles as $profile) - { + foreach ($this->profiles as $profile) { $profileNames[] = $profile->getName(); } @@ -679,7 +690,7 @@ public function getBackups() /** * @return StoragePool */ - public function getStoragePool(): StoragePool + public function getStoragePool() : StoragePool { return $this->storagePool; } @@ -687,7 +698,7 @@ public function getStoragePool(): StoragePool /** * @param StoragePool $storagePool */ - public function setStoragePool(StoragePool $storagePool): void + public function setStoragePool(StoragePool $storagePool) : void { $this->storagePool = $storagePool; }