Skip to content

Commit d4fb78e

Browse files
authored
Add firewalls support (#67)
* Add support for Firewalls
1 parent 28ea030 commit d4fb78e

16 files changed

+1069
-1
lines changed

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
* Add support for Firewalls
6+
37
## 2.3.0 (03.02.2021)
8+
49
* Add support for creating Certificates
510
* Add support for creating resources with labels
6-
* Allow setting of "null" `$dnsPtr` value on `changeReverseDNS` of FloatingIP & Server, this resets the DNS PTR to the default value
11+
* Allow setting of "null" `$dnsPtr` value on `changeReverseDNS` of FloatingIP & Server, this resets the DNS PTR to the
12+
default value
713
* Support PHP 8.0
814
* Improve Creating Floating IPs
915

src/HetznerAPIClient.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use LKDev\HetznerCloud\Models\Actions\Actions;
88
use LKDev\HetznerCloud\Models\Certificates\Certificates;
99
use LKDev\HetznerCloud\Models\Datacenters\Datacenters;
10+
use LKDev\HetznerCloud\Models\Firewalls\Firewalls;
1011
use LKDev\HetznerCloud\Models\FloatingIps\FloatingIps;
1112
use LKDev\HetznerCloud\Models\Images\Images;
1213
use LKDev\HetznerCloud\Models\ISOs\ISOs;
@@ -279,6 +280,14 @@ public function certificates()
279280
return new Certificates($this->httpClient);
280281
}
281282

283+
/**
284+
* @return Firewalls
285+
*/
286+
public function firewalls()
287+
{
288+
return new Firewalls($this->httpClient);
289+
}
290+
282291
/**
283292
* @return GuzzleClient
284293
*/

src/Models/Firewalls/Firewall.php

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: lukaskammerling
5+
* Date: 28.01.18
6+
* Time: 20:59.
7+
*/
8+
9+
namespace LKDev\HetznerCloud\Models\Firewalls;
10+
11+
use LKDev\HetznerCloud\APIException;
12+
use LKDev\HetznerCloud\APIResponse;
13+
use LKDev\HetznerCloud\HetznerAPIClient;
14+
use LKDev\HetznerCloud\Models\Actions\Action;
15+
use LKDev\HetznerCloud\Models\Contracts\Resource;
16+
use LKDev\HetznerCloud\Models\Model;
17+
use LKDev\HetznerCloud\Models\Servers\Server;
18+
19+
class Firewall extends Model implements Resource
20+
{
21+
/**
22+
* @var int
23+
*/
24+
public $id;
25+
26+
/**
27+
* @var string
28+
*/
29+
public $name;
30+
31+
/**
32+
* @var string
33+
*/
34+
public $created;
35+
36+
/**
37+
* @var array
38+
*/
39+
public $labels;
40+
41+
/**
42+
* @var FirewallRule[]
43+
*/
44+
public $rules;
45+
46+
/**
47+
* @var FirewallResource[]
48+
*/
49+
public $appliedTo;
50+
51+
/**
52+
* FloatingIp constructor.
53+
*
54+
* @param int $id
55+
* @param string $name
56+
* @param array $rules
57+
* @param array $appliedTo
58+
* @param array $labels
59+
* @param string $created
60+
*/
61+
public function __construct(
62+
int $id,
63+
string $name = '',
64+
array $rules = [],
65+
array $appliedTo = [],
66+
array $labels = [],
67+
string $created = ''
68+
) {
69+
$this->id = $id;
70+
$this->name = $name;
71+
$this->labels = $labels;
72+
$this->created = $created;
73+
$this->name = $name;
74+
$this->rules = $rules;
75+
$this->appliedTo = $appliedTo;
76+
parent::__construct();
77+
}
78+
79+
/**
80+
* Update a Firewall.
81+
*
82+
* @see https://docs.hetzner.cloud/#firewalls-update-a-firewall
83+
* @param array $data
84+
* @return static|null
85+
* @throws \LKDev\HetznerCloud\APIException
86+
*/
87+
public function update(array $data): ?self
88+
{
89+
$response = $this->httpClient->put('firewalls/'.$this->id, [
90+
'json' => $data,
91+
]);
92+
if (! HetznerAPIClient::hasError($response)) {
93+
return self::parse(json_decode((string) $response->getBody())->firewall);
94+
}
95+
96+
return null;
97+
}
98+
99+
/**
100+
* @param $input
101+
* @return \LKDev\HetznerCloud\Models\Firewalls\Firewall|static|null
102+
*/
103+
public static function parse($input): ?self
104+
{
105+
if ($input == null) {
106+
return null;
107+
}
108+
$appliedTo = [];
109+
$rules = [];
110+
111+
foreach ($input->rules as $r) {
112+
$rules[] = new FirewallRule($r->direction, $r->protocol, $r->source_ips, $r->destination_ips, $r->port);
113+
}
114+
115+
foreach ($input->applied_to as $a) {
116+
$appliedTo[] = new FirewallResource($a->type, new Server($a->server->id));
117+
}
118+
119+
return new self($input->id, $input->name, $rules, $appliedTo, get_object_vars($input->labels), $input->created);
120+
}
121+
122+
/**
123+
* Sets the rules of a Firewall.
124+
*
125+
* @see https://docs.hetzner.cloud/#firewall-actions-set-rules
126+
* @param FirewallRule[] $rules
127+
* @return ?APIResponse|null
128+
* @throws APIException
129+
*/
130+
public function setRules(array $rules): ?ApiResponse
131+
{
132+
$response = $this->httpClient->post('firewalls/'.$this->id.'/actions/set_rules', [
133+
'json' => [
134+
'rules' => collect($rules)->map(function ($r) {
135+
return $r->toRequestSchema();
136+
}),
137+
],
138+
]);
139+
if (! HetznerAPIClient::hasError($response)) {
140+
$payload = json_decode((string) $response->getBody());
141+
142+
return APIResponse::create([
143+
'actions' => collect($payload->actions)->map(function ($action) {
144+
return Action::parse($action);
145+
})->toArray(),
146+
], $response->getHeaders());
147+
}
148+
149+
return null;
150+
}
151+
152+
/**
153+
* Deletes a Firewall.
154+
*
155+
* @see https://docs.hetzner.cloud/#firewalls-delete-a-firewall
156+
* @return bool
157+
* @throws \LKDev\HetznerCloud\APIException
158+
*/
159+
public function delete(): bool
160+
{
161+
$response = $this->httpClient->delete('firewalls/'.$this->id);
162+
if (! HetznerAPIClient::hasError($response)) {
163+
return true;
164+
}
165+
166+
return false;
167+
}
168+
169+
/**
170+
* Applies one Firewall to multiple resources.
171+
*
172+
* @see https://docs.hetzner.cloud/#firewall-actions-apply-to-resources
173+
* @param FirewallResource[] $resources
174+
* @return APIResponse|null
175+
* @throws \LKDev\HetznerCloud\APIException
176+
*/
177+
public function applyToResources(array $resources): ?APIResponse
178+
{
179+
$response = $this->httpClient->post('firewalls/'.$this->id.'/actions/apply_to_resources', [
180+
'json' => [
181+
'apply_to' => collect($resources)->map(function ($r) {
182+
return $r->toRequestSchema();
183+
}),
184+
],
185+
]);
186+
if (! HetznerAPIClient::hasError($response)) {
187+
$payload = json_decode((string) $response->getBody());
188+
189+
return APIResponse::create([
190+
'actions' => collect($payload->actions)->map(function ($action) {
191+
return Action::parse($action);
192+
})->toArray(),
193+
], $response->getHeaders());
194+
}
195+
196+
return null;
197+
}
198+
199+
/**
200+
* Removes one Firewall from multiple resources.
201+
*
202+
* @see https://docs.hetzner.cloud/#firewall-actions-remove-from-resources
203+
* @param FirewallResource[] $resources
204+
* @return APIResponse|null
205+
* @throws \LKDev\HetznerCloud\APIException
206+
*/
207+
public function removeFromResources(array $resources): ?APIResponse
208+
{
209+
$response = $this->httpClient->post('firewalls/'.$this->id.'/actions/remove_from_resources', [
210+
'json' => [
211+
'remove_from' => collect($resources)->map(function ($r) {
212+
return $r->toRequestSchema();
213+
}),
214+
],
215+
]);
216+
if (! HetznerAPIClient::hasError($response)) {
217+
$payload = json_decode((string) $response->getBody());
218+
219+
return APIResponse::create([
220+
'actions' => collect($payload->actions)->map(function ($action) {
221+
return Action::parse($action);
222+
})->toArray(),
223+
], $response->getHeaders());
224+
}
225+
226+
return null;
227+
}
228+
229+
/**
230+
* @return mixed
231+
*/
232+
public function reload()
233+
{
234+
return HetznerAPIClient::$instance->firewalls()->get($this->id);
235+
}
236+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace LKDev\HetznerCloud\Models\Firewalls;
4+
5+
use LKDev\HetznerCloud\RequestOpts;
6+
7+
/**
8+
* Class FloatingIPRequestOpts.
9+
*/
10+
class FirewallRequestOpts extends RequestOpts
11+
{
12+
/**
13+
* @var string
14+
*/
15+
public $name;
16+
17+
/**
18+
* RequestOpts constructor.
19+
*
20+
* @param $name
21+
* @param $perPage
22+
* @param $page
23+
* @param $labelSelector
24+
*/
25+
public function __construct(string $name = null, int $perPage = null, int $page = null, string $labelSelector = null)
26+
{
27+
$this->name = $name;
28+
parent::__construct($perPage, $page, $labelSelector);
29+
}
30+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
namespace LKDev\HetznerCloud\Models\Firewalls;
4+
5+
use LKDev\HetznerCloud\Models\Servers\Server;
6+
7+
/**
8+
* Class FirewallResource.
9+
*/
10+
class FirewallResource
11+
{
12+
const TYPE_SERVER = 'server';
13+
14+
/**
15+
* @var string
16+
*/
17+
public $type;
18+
/**
19+
* @var ?Server
20+
*/
21+
public $server;
22+
23+
/**
24+
* FirewallResource constructor.
25+
* @param string $type
26+
* @param Server|null $server
27+
*/
28+
public function __construct(string $type, ?Server $server)
29+
{
30+
$this->type = $type;
31+
$this->server = $server;
32+
}
33+
34+
/**
35+
* @return string[]
36+
*/
37+
public function toRequestSchema(): array
38+
{
39+
$s = ['type' => $this->type];
40+
if ($this->type == self::TYPE_SERVER) {
41+
$s['server'] = ['id' => $this->server->id];
42+
}
43+
44+
return $s;
45+
}
46+
}

0 commit comments

Comments
 (0)