Skip to content

Commit e05dfb3

Browse files
author
christopher.schmitt
committed
Add Load Balancers
1 parent 2aa8efc commit e05dfb3

31 files changed

+2943
-0
lines changed

.gitlab-ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ stages:
99
tox
1010
variables:
1111
FAKE_API_ENDPOINT: "http://apimock:8080/v1"
12+
API_MOCK_source: "https://docs-internal.staging.hc-k8s.de/hc_public_internal.apib"
1213
tags:
1314
- hc-bladerunner
1415
services:

docs/api.clients.certificates.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
CertificateClient
2+
==================
3+
4+
5+
.. autoclass:: hcloud.certificates.client.CertificateClient
6+
:members:
7+
8+
.. autoclass:: hcloud.certificates.client.BoundCertificate
9+
:members:
10+
11+
.. autoclass:: hcloud.certificates.domain.Certificate
12+
:members:
13+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
LoadBalancerTypesClient
2+
==================
3+
4+
5+
.. autoclass:: hcloud.load_balancer_types.client.LoadBalancerTypesClient
6+
:members:
7+
8+
.. autoclass:: hcloud.load_balancer_types.domain.LoadBalancerType
9+
:members:
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
LoadBalancerClient
2+
==================
3+
4+
5+
.. autoclass:: hcloud.load_balancers.client.LoadBalancerClient
6+
:members:
7+
8+
.. autoclass:: hcloud.load_balancers.client.BoundLoadBalancer
9+
:members:
10+
11+
.. autoclass:: hcloud.load_balancers.domain.LoadBalancer
12+
:members:
13+
14+
.. autoclass:: hcloud.load_balancers.domain.LoadBalancerService
15+
:members:
16+
17+
.. autoclass:: hcloud.load_balancers.domain.LoadBalancerServiceHttp
18+
:members:
19+
20+
.. autoclass:: hcloud.load_balancers.domain.LoadBalancerHealthCheck
21+
:members:
22+
23+
.. autoclass:: hcloud.load_balancers.domain.LoadBalancerHealthCheckHttp
24+
:members:
25+
26+
.. autoclass:: hcloud.load_balancers.domain.LoadBalancerTarget
27+
:members:
28+
29+
.. autoclass:: hcloud.load_balancers.domain.LoadBalancerAlgorithm
30+
:members:

hcloud/certificates/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# -*- coding: utf-8 -*-

hcloud/certificates/client.py

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
# -*- coding: utf-8 -*-
2+
from hcloud.core.client import ClientEntityBase, BoundModelBase, GetEntityByNameMixin
3+
4+
from hcloud.certificates.domain import Certificate
5+
6+
7+
class BoundCertificate(BoundModelBase):
8+
model = Certificate
9+
10+
def update(self, name=None, labels=None):
11+
# type: (Optional[str], Optional[Dict[str, str]]) -> BoundCertificate
12+
"""Updates an certificate. You can update an certificate name and the certificate labels.
13+
14+
:param name: str (optional)
15+
New name to set
16+
:param labels: Dict[str, str] (optional)
17+
User-defined labels (key-value pairs)
18+
:return: :class:`BoundCertificate <hcloud.certificates.client.BoundCertificate>
19+
"""
20+
return self._client.update(self, name, labels)
21+
22+
def delete(self):
23+
# type: () -> bool
24+
"""Deletes a certificate.
25+
:return: boolean
26+
"""
27+
return self._client.delete(self)
28+
29+
30+
class CertificatesClient(ClientEntityBase, GetEntityByNameMixin):
31+
results_list_attribute_name = 'certificates'
32+
33+
def get_by_id(self, id):
34+
# type: (int) -> BoundCertificate
35+
"""Get a specific certificate by its ID.
36+
37+
:param id: int
38+
:return: :class:`BoundCertificate <hcloud.certificates.client.BoundCertificate>`
39+
"""
40+
response = self._client.request(url="/certificates/{certificate_id}".format(certificate_id=id), method="GET")
41+
return BoundCertificate(self, response['certificate'])
42+
43+
def get_list(self,
44+
name=None, # type: Optional[str]
45+
label_selector=None, # type: Optional[str]
46+
page=None, # type: Optional[int]
47+
per_page=None # type: Optional[int]
48+
):
49+
# type: (...) -> PageResults[List[BoundCertificate], Meta]
50+
"""Get a list of certificates
51+
52+
:param name: str (optional)
53+
Can be used to filter certificates by their name.
54+
:param label_selector: str (optional)
55+
Can be used to filter certificates by labels. The response will only contain certificates matching the label selector.
56+
:param page: int (optional)
57+
Specifies the page to fetch
58+
:param per_page: int (optional)
59+
Specifies how many results are returned by page
60+
:return: (List[:class:`BoundCertificate <hcloud.certificates.client.BoundCertificate>`], :class:`Meta <hcloud.core.domain.Meta>`)
61+
"""
62+
params = {}
63+
if name is not None:
64+
params["name"] = name
65+
66+
if label_selector:
67+
params["label_selector"] = label_selector
68+
69+
if page is not None:
70+
params['page'] = page
71+
72+
if per_page is not None:
73+
params['per_page'] = per_page
74+
75+
response = self._client.request(url="/certificates", method="GET", params=params)
76+
77+
certificates = [BoundCertificate(self, certificate_data) for certificate_data in response['certificates']]
78+
79+
return self._add_meta_to_result(certificates, response)
80+
81+
def get_all(self, name=None, label_selector=None):
82+
# type: (Optional[str]) -> List[BoundCertificate]
83+
"""Get all certificates
84+
85+
:param name: str (optional)
86+
Can be used to filter certificates by their name.
87+
:param label_selector: str (optional)
88+
Can be used to filter certificates by labels. The response will only contain certificates matching the label selector.
89+
:return: List[:class:`BoundCertificate <hcloud.certificates.client.BoundCertificate>`]
90+
"""
91+
return super(CertificatesClient, self).get_all(name=name, label_selector=label_selector)
92+
93+
def get_by_name(self, name):
94+
# type: (str) -> BoundCertificate
95+
"""Get certificate by name
96+
97+
:param name: str
98+
Used to get certificate by name.
99+
:return: :class:`BoundCertificate <hcloud.certificates.client.BoundCertificate>`
100+
"""
101+
return super(CertificatesClient, self).get_by_name(name)
102+
103+
def create(self, name, certificate, private_key, labels=None):
104+
# type: (str, str, Optional[Dict[str, str]]) -> BoundCertificate
105+
"""Creates a new Certificate with the given name, certificate and private_key.
106+
107+
:param name: str
108+
:param certificate: str
109+
Certificate and chain in PEM format, in order so that each record directly certifies the one preceding
110+
:param private_key: str
111+
Certificate key in PEM format
112+
:param labels: Dict[str, str] (optional)
113+
User-defined labels (key-value pairs)
114+
:return: :class:`BoundCertificate <hcloud.certificates.client.BoundCertificate>`
115+
"""
116+
data = {
117+
'name': name,
118+
'certificate': certificate,
119+
'private_key': private_key
120+
}
121+
if labels is not None:
122+
data['labels'] = labels
123+
response = self._client.request(url="/certificates", method="POST", json=data)
124+
return BoundCertificate(self, response['certificate'])
125+
126+
def update(self, certificate, name=None, labels=None):
127+
# type: (Certificate, Optional[str], Optional[Dict[str, str]]) -> BoundCertificate
128+
"""Updates a Certificate. You can update a certificate name and labels.
129+
130+
:param certificate: :class:`BoundCertificate <hcloud.certificates.client.BoundCertificate>` or :class:`Certificate <hcloud.certificates.domain.Certificate>`
131+
:param name: str (optional)
132+
New name to set
133+
:param labels: Dict[str, str] (optional)
134+
User-defined labels (key-value pairs)
135+
:return: :class:`BoundCertificate <hcloud.certificates.client.BoundCertificate>`
136+
"""
137+
data = {}
138+
if name is not None:
139+
data['name'] = name
140+
if labels is not None:
141+
data['labels'] = labels
142+
response = self._client.request(url="/certificates/{certificate_id}".format(certificate_id=certificate.id),
143+
method="PUT",
144+
json=data)
145+
return BoundCertificate(self, response['certificate'])
146+
147+
def delete(self, certificate):
148+
# type: (Certificate) -> bool
149+
self._client.request(url="/certificates/{certificate_id}".format(certificate_id=certificate.id),
150+
method="DELETE")
151+
"""Deletes a certificate.
152+
153+
:param certificate: :class:`BoundCertificate <hcloud.certificates.client.BoundCertificate>` or :class:`Certificate <hcloud.certificates.domain.Certificate>`
154+
:return: True
155+
"""
156+
# Return always true, because the API does not return an action for it. When an error occurs a HcloudAPIException will be raised
157+
return True

hcloud/certificates/domain.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# -*- coding: utf-8 -*-
2+
from dateutil.parser import isoparse
3+
4+
from hcloud.core.domain import BaseDomain, DomainIdentityMixin
5+
6+
7+
class Certificate(BaseDomain, DomainIdentityMixin):
8+
"""Certificate Domain
9+
10+
:param id: int ID of Certificate
11+
:param name: str Name of Certificate
12+
:param certificate: str Certificate and chain in PEM format, in order so that each record directly certifies the one preceding
13+
:param not_valid_before: datetime
14+
Point in time when the Certificate becomes valid
15+
:param not_valid_after: datetime
16+
Point in time when the Certificate becomes invalid
17+
:param domain_names: List[str] List of domains and subdomains covered by this certificate
18+
:param fingerprint: str Fingerprint of the Certificate
19+
:param labels: dict
20+
User-defined labels (key-value pairs)
21+
:param created: datetime
22+
Point in time when the certificate was created
23+
"""
24+
__slots__ = (
25+
"id",
26+
"name",
27+
"certificate",
28+
"not_valid_before",
29+
"not_valid_after",
30+
"domain_names",
31+
"fingerprint",
32+
"created",
33+
"labels",
34+
)
35+
36+
def __init__(
37+
self,
38+
id=None,
39+
name=None,
40+
certificate=None,
41+
not_valid_before=None,
42+
not_valid_after=None,
43+
domain_names=None,
44+
fingerprint=None,
45+
created=None,
46+
labels=None,
47+
):
48+
self.id = id
49+
self.name = name
50+
self.certificate = certificate
51+
self.domain_names = domain_names
52+
self.fingerprint = fingerprint
53+
self.not_valid_before = isoparse(not_valid_before) if not_valid_before else None
54+
self.not_valid_after = isoparse(not_valid_after) if not_valid_after else None
55+
self.created = isoparse(created) if created else None
56+
self.labels = labels

hcloud/hcloud.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import requests
66

77
from hcloud.actions.client import ActionsClient
8+
from hcloud.certificates.client import CertificatesClient
89
from hcloud.floating_ips.client import FloatingIPsClient
910
from hcloud.networks.client import NetworksClient
1011
from hcloud.isos.client import IsosClient
@@ -15,6 +16,8 @@
1516
from hcloud.images.client import ImagesClient
1617
from hcloud.locations.client import LocationsClient
1718
from hcloud.datacenters.client import DatacentersClient
19+
from hcloud.load_balancers.client import LoadBalancersClient
20+
from hcloud.load_balancer_types.client import LoadBalancerTypesClient
1821

1922
from .__version__ import VERSION
2023

@@ -112,6 +115,23 @@ def __init__(self, token, api_endpoint="https://api.hetzner.cloud/v1", applicati
112115
113116
:type: :class:`NetworksClient <hcloud.networks.client.NetworksClient>`
114117
"""
118+
self.certificates = CertificatesClient(self)
119+
"""CertificatesClient Instance
120+
121+
:type: :class:`CertificatesClient <hcloud.certificates.client.CertificatesClient>`
122+
"""
123+
124+
self.load_balancers = LoadBalancersClient(self)
125+
"""LoadBalancersClient Instance
126+
127+
:type: :class:`LoadBalancersClient <hcloud.load_balancers.client.LoadBalancersClient>`
128+
"""
129+
130+
self.load_balancer_types = LoadBalancerTypesClient(self)
131+
"""LoadBalancerTypesClient Instance
132+
133+
:type: :class:`LoadBalancerTypesClient <hcloud.load_balancer_types.client.LoadBalancerTypesClient>`
134+
"""
115135

116136
def _get_user_agent(self):
117137
"""Get the user agent of the hcloud-python instance with the user application name (if specified)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# -*- coding: utf-8 -*-
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
from hcloud.core.client import ClientEntityBase, BoundModelBase, GetEntityByNameMixin
2+
from hcloud.load_balancer_types.domain import LoadBalancerType
3+
4+
5+
class BoundLoadBalancerType(BoundModelBase):
6+
model = LoadBalancerType
7+
8+
9+
class LoadBalancerTypesClient(ClientEntityBase, GetEntityByNameMixin):
10+
results_list_attribute_name = 'load_balancer_types'
11+
12+
def get_by_id(self, id):
13+
# type: (int) -> load_balancer_types.client.BoundLoadBalancerType
14+
"""Returns a specific Load Balancer Type.
15+
16+
:param id: int
17+
:return: :class:`BoundLoadBalancerType <hcloud.load_balancer_type.client.BoundLoadBalancerType>`
18+
"""
19+
response = self._client.request(url="/load_balancer_types/{load_balancer_type_id}".format(load_balancer_type_id=id), method="GET")
20+
return BoundLoadBalancerType(self, response['load_balancer_type'])
21+
22+
def get_list(self, name=None, page=None, per_page=None):
23+
# type: (Optional[str], Optional[int], Optional[int]) -> PageResults[List[BoundLoadBalancerType], Meta]
24+
"""Get a list of Load Balancer types
25+
26+
:param name: str (optional)
27+
Can be used to filter Load Balancer type by their name.
28+
:param page: int (optional)
29+
Specifies the page to fetch
30+
:param per_page: int (optional)
31+
Specifies how many results are returned by page
32+
:return: (List[:class:`BoundLoadBalancerType <hcloud.load_balancer_types.client.BoundLoadBalancerType>`], :class:`Meta <hcloud.core.domain.Meta>`)
33+
"""
34+
params = {}
35+
if name is not None:
36+
params['name'] = name
37+
if page is not None:
38+
params['page'] = page
39+
if per_page is not None:
40+
params['per_page'] = per_page
41+
42+
response = self._client.request(url="/load_balancer_types", method="GET", params=params)
43+
load_balancer_types = [BoundLoadBalancerType(self, load_balancer_type_data) for load_balancer_type_data in response['load_balancer_types']]
44+
return self._add_meta_to_result(load_balancer_types, response)
45+
46+
def get_all(self, name=None):
47+
# type: (Optional[str]) -> List[BoundLoadBalancerType]
48+
"""Get all Load Balancer types
49+
50+
:param name: str (optional)
51+
Can be used to filter Load Balancer type by their name.
52+
:return: List[:class:`BoundLoadBalancerType <hcloud.load_balancer_types.client.BoundLoadBalancerType>`]
53+
"""
54+
return super(LoadBalancerTypesClient, self).get_all(name=name)
55+
56+
def get_by_name(self, name):
57+
# type: (str) -> BoundLoadBalancerType
58+
"""Get Load Balancer type by name
59+
60+
:param name: str
61+
Used to get Load Balancer type by name.
62+
:return: :class:`BoundLoadBalancerType <hcloud.load_balancer_types.client.BoundLoadBalancerType>`
63+
"""
64+
return super(LoadBalancerTypesClient, self).get_by_name(name)

0 commit comments

Comments
 (0)