hetznercloud / hcloud-python Goto Github PK
View Code? Open in Web Editor NEWA Python library for the Hetzner Cloud API
License: MIT License
A Python library for the Hetzner Cloud API
License: MIT License
Hello,
We are developing a new saltstack cloud driver for the Hetzner Public Cloud using hcloud-python. Saltstacks build chain in github required to have the dependencies available in pip
for Python 3.9, but there is no hcloud
available via pip install hcloud==1.6.3
for Python 3.9. Would it be possible to make this available?
Link to saltstack/salt - PR: saltstack/salt#57453
Link to saltstack/salt - specific check: https://jenkinsci.saltstack.com/job/pr-pre-commit/job/PR-57453/7/console
Best regards
Current Behavior
Hi!
We are facing an issue with the update_service method for loadbalancers. We are trying to add/delete certificates within the http-Object of a service. After adding or deleting a certificate inside the http-Object and calling the update_service method, the changes aren't made.
Input Code
Example:
created_cert = hcloud_client.certificates.create(
name=f"{cert_name}_{datetime.strftime(datetime.now(), '%Y%m%d')}",
certificate=cert["fullchain"],
private_key=decrypted_privkey.decode('utf-8'),
)
hcloud_load_balancers = hcloud_client.load_balancers.get_all()
for load_balancer in hcloud_load_balancers:
for service in load_balancer.services:
service.http.certificates.append(created_cert)
update_service_action = load_balancer.update_service(service)
update_service_action.wait_until_finished()
We already debugged the code, and especially looked into the service.http.certificates
-object/list, before calling update_service, to observe, if the certificate is inside the service
-object. Everything seems fine. The update_service_action.status
also contains success
after calling it.
Expected behavior/code
We would think, the above code should add a new certificate to the specified loadbalancers service.
Current Behavior
When running an Ansible script, an error shows up and the script stops:
"Failed to import the required Python library (hcloud-python) on computer's Python /usr/bin/python3. Please read the module documentation and install it in the appropriate location."
Input Code
- name: Create a basic Hetzner hcloud server with ssh key
hcloud_server:
api_token: "{{ hcloud_token }}"
image: "{{ hcloud_image }}"
location: "{{ hcloud_location }}"
name: "{{ item }}"
server_type: "{{ hcloud_type }}"
ssh_keys:
- "{{ hcloud_ssh }}"
state: present
with_inventory_hostnames:
- webservers
register: hcloud_info
Expected behavior/code
Virtual server creation
Environment
I'd like to type check code using this lib with mypy, but it doesn't type check sphinx type directives in docstrings. Stub files could provide type hints without having to change the current code, I'd be willing to submit a PR if that's desirable.
EDIT: Sorry, I looked into the code and it's already annotated. It seems like a hcloud/py.typed
file is needed though, according to the mypy docs. I set up a local clone with a py.typed file and mypy can import hcloud now, though it still doesn't typecheck, the following gives me no warnings for instance:
foo: int = hcloud.Client(self.token).servers.get_by_name(234)
Also, it seems that some types are not set correcly:
hcloud-python/hcloud/certificates/client.py:81: error: Type signature has too few arguments
hcloud-python/hcloud/certificates/client.py:103: error: Type signature has too few arguments
hcloud-python/hcloud/floating_ips/client.py:41: error: Type signature has too few arguments
hcloud-python/hcloud/volumes/client.py:24: error: Type signature has too few arguments
hcloud-python/hcloud/volumes/client.py:40: error: Type signature has too few arguments
hcloud-python/hcloud/volumes/client.py:72: error: Type signature has too few arguments
hcloud-python/hcloud/volumes/client.py:236: error: Type signature has too few arguments
hcloud-python/hcloud/volumes/client.py:266: error: Type signature has too few arguments
hcloud-python/hcloud/images/client.py:51: error: Type signature has too few arguments
hcloud-python/hcloud/load_balancers/client.py:339: error: syntax error in type comment '(...) -> CreateLoadBalancerResponse:'
Found 10 errors in 5 files (checked 1 source file)
Current Behavior
pip install libs differs from source even tho it has same version (1.6.3)
Environment
Additional context/Screenshots
https://i.imgur.com/FFHLVKZ.png
Image of servers/client.py from pip install hcloud
Notice that its missing the networks which will cause a TypeError
TypeError: create() got an unexpected keyword argument 'networks'
Current Behavior
FirewallsClient.create
looks for key action
in the response while the actual key should be actions
(notice the trailing s
).
I wanted to play around with Ansible+hcloud and pretty much copied the example from this tutorial. Executing the playbook gives an error (see below) that hcloud-python is missing even tough it is installed and pip3 show hcloud
confirms it. Unfortunatly I'm not familiar with Python and don't know what the problem might be. Sorry if this is a stupid mistake by me.
Current Behavior
user:~$ ansible-playbook hcloud.yml
ERROR! The Hetzner Cloud dynamic inventory plugin requires hcloud-python.
Environment
pip3 install --user hcloud
)Additional context/Screenshots
Playbook content:
---
# hcloud.yml
- name: Create a Server and a Volume with server
hosts: localhost
connection: local
gather_facts: False
user: root
vars:
hcloud_token: "{{ hcloud_token_testing }}"
tasks:
- name: Create a basic server
hcloud_server:
api_token: "{{ hcloud_token }}"
name: my-server
server_type: cx11
image: ubuntu-18.04
state: present
register: server
- name: Create a volume
hcloud_volume:
api_token: "{{ hcloud_token }}"
name: my-volume
size: 10
server: "{{ server.hcloud_server.name }}"
state: present
ansible.cfg contains this:
[inventory]
enable_plugins = hcloud
# TODO: We should find a better solution for this in the future. As of python 3.3 we could use https://docs.python.org/3/library/ipaddress.html
Is there a way to determine, if cloud-init is finished by using this library.
Remove from Travis CI
Remove all references in our documentation
Is your feature request related to a problem? Please describe.
When I get an APIException
, I would like to see error details in the console traceback
Describe the solution you'd like
add str method to APIException
class
This is more a cry for help rather than a bug report, but this seems to be the only relevant place to post the help request.
Unable to serialise BoundServer to json
Current Behavior
using json.dumps() results in AttributeError
Input Code
response = client.servers.create(....)
print(json.dumps(response.server.__dict__))
TypeError: Object of type ServersClient is not JSON serializable
Expected behavior/code
I don't have an in depth knowledge, so I know I am probably doing something wrong. However I need to write the server results returned from client.servers.create
to mongodb.
Environment
At the moment the only steps i can see should be:
setup.py
This list is not complete.
Current Behavior
Creating a firewall with rules or adding a rule to an existing firewall fails (in different forms). I am not entirely sure if it is my fault, to be honest.
Input Code
I create a rule as follows:
rule_ssh = FirewallRule(
direction = 'in',
protocol = 'TCP',
source_ips = ['0.0.0.0/0', '::/0'],
port = '22',
destination_ips = ['0.0.0.0/0', '::/0'],
)
Then I try to create a firewall:
firewall = client.firewalls.create(
name = 'test',
rules = [rule_ssh]
)
I get the following traceback:
---------------------------------------------------------------------------
APIException Traceback (most recent call last)
<ipython-input-66-c8e589768b69> in <module>
----> 1 firewall = client.firewalls.create(
2 name = 'clusterfirewall',
3 rules = [rule_ssh]
4 )
~/env38/lib/python3.8/site-packages/hcloud/firewalls/client.py in create(self, name, rules, labels)
262 data['rules'].append(rule.to_payload())
263
--> 264 response = self._client.request(url="/firewalls", json=data, method="POST")
265
266 action = None
~/env38/lib/python3.8/site-packages/hcloud/hcloud.py in request(self, method, url, tries, **kwargs)
217 return self.request(method, url, tries, **kwargs)
218 else:
--> 219 self._raise_exception_from_json_content(json_content)
220 else:
221 self._raise_exception_from_response(response)
~/env38/lib/python3.8/site-packages/hcloud/hcloud.py in _raise_exception_from_json_content(self, json_content)
178
179 def _raise_exception_from_json_content(self, json_content):
--> 180 raise APIException(
181 code=json_content['error']['code'],
182 message=json_content['error']['message'],
APIException: invalid input in field 'rules'
Alternatively, I create a firewall without rules and try to add a rule in a second step:
firewall = client.firewalls.create(name = 'test')
client.firewalls.set_rules(firewall = firewall, rules = [rule_ssh])
Now the following exception occurs:
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-71-c2cae1417130> in <module>
----> 1 client.firewalls.set_rules(firewall = firewall, rules = [rule_ssh])
~/env38/lib/python3.8/site-packages/hcloud/firewalls/client.py in set_rules(self, firewall, rules)
321 data['rules'].append(rule.to_payload())
322 response = self._client.request(
--> 323 url="/firewalls/{firewall_id}/actions/set_rules".format(firewall_id=firewall.id),
324 method="POST", json=data)
325 return [BoundAction(self._client.actions, _) for _ in response['actions']]
AttributeError: 'CreateFirewallResponse' object has no attribute 'id'
Expected behavior/code
No errors, but a firewall with rules.
Environment
Current Behavior
'make docs' fails with sphinx 4.0.2 (latest release). app.add_javascript() is removed.
'make docs' outputs a warning that app.add_javascript() is deprecated.
Input Code
Running Sphinx v3.5.4
making output directory... done
/home/tdoczkal/git/hcloud-python/docs/conf.py:166: RemovedInSphinx40Warning: The app.add_javascript() is deprecated. Please use app.add_js_file() instead.
app.add_javascript('js/open_links_in_new_tab.js')
hcloud-python]$ make docs
Expected behavior/code
build docs
Environment
Right now, you specify exact versions of dependencies, like this:
"future==0.17.1",
"python-dateutil==2.7.5",
"requests==2.20.0"
This may be incompatible with existing projects. It would be better to specify ranges of versions that are compatible with the hcloud
package. For example, requests
is a very stable package, and hcloud
will probably work with a wide range of requests
versions, e.g. requests>=2.20,<2.23
Is your feature request related to a problem? Please describe.
The REST documentation and the Go client both support an argument to immediately apply a new firewall to a server on creation.
The Python client should do so as well.
Current Behavior
When running the following ansible-script, i receive the error TypeError: __init__() got an unexpected keyword argument 'dns_ptr'
. (full stack trace in buttom).
I can easily create servers and other ressources
Futhermore i cannot find any documentation saying anything about dns_ptr
in the documentation for creating a loadbalancer, i have looked at the ansible-documentation, and also API-documentation, but did not find anything.
Input Code
Simple example created to illustrate problem;
lberror.yml
- hosts: all
gather_facts: no
vars_prompt:
- name: "hetzner_api_token"
prompt: "Enter api-token from Hetzner"
private: no
tasks:
- name: Create a basic Load Balancer
hetzner.hcloud.hcloud_load_balancer:
api_token: "{{ hetzner_api_token }}"
name: "testlb"
load_balancer_type: "lb11"
location: "fsn1"
state: "present"
It is run with command
ansible-playbook lberror.yml -e "ansible_python_interpreter=/usr/bin/python3" -vvv
Expected behavior/code
This script has run before and i expected it to run again when i ran it yesterday - But it does not. I expected it to create a load-balancer in hetzner.
Environment
3.8.10
1.4.3
and also 1.6.0
2.10.8
Possible Solution
Possible relations
Since my error is dns_ptr on load balancers, it could be related to PR #144
Additional context/Screenshots
The full traceback is:
Traceback (most recent call last):
File "/tmp/ansible_hetzner.hcloud.hcloud_load_balancer_payload_drs_0vnu/ansible_hetzner.hcloud.hcloud_load_balancer_payload.zip/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer.py", line 187, in _get_load_balancer
File "/home/mikkel/.local/lib/python3.8/site-packages/hcloud/load_balancers/client.py", line 337, in get_by_name
return super(LoadBalancersClient, self).get_by_name(name)
File "/home/mikkel/.local/lib/python3.8/site-packages/hcloud/core/client.py", line 75, in get_by_name
response = self.get_list(name=name)
File "/home/mikkel/.local/lib/python3.8/site-packages/hcloud/load_balancers/client.py", line 310, in get_list
ass_load_balancers = [
File "/home/mikkel/.local/lib/python3.8/site-packages/hcloud/load_balancers/client.py", line 311, in <listcomp>
BoundLoadBalancer(self, load_balancer_data) for load_balancer_data in response["load_balancers"]
File "/home/mikkel/.local/lib/python3.8/site-packages/hcloud/load_balancers/client.py", line 29, in __init__
ipv4_address = IPv4Address(**public_net['ipv4'])
TypeError: __init__() got an unexpected keyword argument 'dns_ptr'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/mikkel/.ansible/tmp/ansible-tmp-1632291019.7032492-1208449-116182518945343/AnsiballZ_hcloud_load_balancer.py", line 102, in <module>
_ansiballz_main()
File "/home/mikkel/.ansible/tmp/ansible-tmp-1632291019.7032492-1208449-116182518945343/AnsiballZ_hcloud_load_balancer.py", line 94, in _ansiballz_main
invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
File "/home/mikkel/.ansible/tmp/ansible-tmp-1632291019.7032492-1208449-116182518945343/AnsiballZ_hcloud_load_balancer.py", line 40, in invoke_module
runpy.run_module(mod_name='ansible_collections.hetzner.hcloud.plugins.modules.hcloud_load_balancer', init_globals=None, run_name='__main__', alter_sys=True)
File "/usr/lib/python3.8/runpy.py", line 207, in run_module
return _run_module_code(code, init_globals, run_name, mod_spec)
File "/usr/lib/python3.8/runpy.py", line 97, in _run_module_code
_run_code(code, mod_globals, init_globals,
File "/usr/lib/python3.8/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/tmp/ansible_hetzner.hcloud.hcloud_load_balancer_payload_drs_0vnu/ansible_hetzner.hcloud.hcloud_load_balancer_payload.zip/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer.py", line 324, in <module>
File "/tmp/ansible_hetzner.hcloud.hcloud_load_balancer_payload_drs_0vnu/ansible_hetzner.hcloud.hcloud_load_balancer_payload.zip/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer.py", line 318, in main
File "/tmp/ansible_hetzner.hcloud.hcloud_load_balancer_payload_drs_0vnu/ansible_hetzner.hcloud.hcloud_load_balancer_payload.zip/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer.py", line 269, in present_load_balancer
File "/tmp/ansible_hetzner.hcloud.hcloud_load_balancer_payload_drs_0vnu/ansible_hetzner.hcloud.hcloud_load_balancer_payload.zip/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer.py", line 191, in _get_load_balancer
AttributeError: 'TypeError' object has no attribute 'message'
fatal: [localhost]: FAILED! => {
"changed": false,
"module_stderr": "Traceback (most recent call last):\n File \"/tmp/ansible_hetzner.hcloud.hcloud_load_balancer_payload_drs_0vnu/ansible_hetzner.hcloud.hcloud_load_balancer_payload.zip/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer.py\", line 187, in _get_load_balancer\n File \"/home/mikkel/.local/lib/python3.8/site-packages/hcloud/load_balancers/client.py\", line 337, in get_by_name\n return super(LoadBalancersClient, self).get_by_name(name)\n File \"/home/mikkel/.local/lib/python3.8/site-packages/hcloud/core/client.py\", line 75, in get_by_name\n response = self.get_list(name=name)\n File \"/home/mikkel/.local/lib/python3.8/site-packages/hcloud/load_balancers/client.py\", line 310, in get_list\n ass_load_balancers = [\n File \"/home/mikkel/.local/lib/python3.8/site-packages/hcloud/load_balancers/client.py\", line 311, in <listcomp>\n BoundLoadBalancer(self, load_balancer_data) for load_balancer_data in response[\"load_balancers\"]\n File \"/home/mikkel/.local/lib/python3.8/site-packages/hcloud/load_balancers/client.py\", line 29, in __init__\n ipv4_address = IPv4Address(**public_net['ipv4'])\nTypeError: __init__() got an unexpected keyword argument 'dns_ptr'\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n File \"/home/mikkel/.ansible/tmp/ansible-tmp-1632291019.7032492-1208449-116182518945343/AnsiballZ_hcloud_load_balancer.py\", line 102, in <module>\n _ansiballz_main()\n File \"/home/mikkel/.ansible/tmp/ansible-tmp-1632291019.7032492-1208449-116182518945343/AnsiballZ_hcloud_load_balancer.py\", line 94, in _ansiballz_main\n invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n File \"/home/mikkel/.ansible/tmp/ansible-tmp-1632291019.7032492-1208449-116182518945343/AnsiballZ_hcloud_load_balancer.py\", line 40, in invoke_module\n runpy.run_module(mod_name='ansible_collections.hetzner.hcloud.plugins.modules.hcloud_load_balancer', init_globals=None, run_name='__main__', alter_sys=True)\n File \"/usr/lib/python3.8/runpy.py\", line 207, in run_module\n return _run_module_code(code, init_globals, run_name, mod_spec)\n File \"/usr/lib/python3.8/runpy.py\", line 97, in _run_module_code\n _run_code(code, mod_globals, init_globals,\n File \"/usr/lib/python3.8/runpy.py\", line 87, in _run_code\n exec(code, run_globals)\n File \"/tmp/ansible_hetzner.hcloud.hcloud_load_balancer_payload_drs_0vnu/ansible_hetzner.hcloud.hcloud_load_balancer_payload.zip/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer.py\", line 324, in <module>\n File \"/tmp/ansible_hetzner.hcloud.hcloud_load_balancer_payload_drs_0vnu/ansible_hetzner.hcloud.hcloud_load_balancer_payload.zip/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer.py\", line 318, in main\n File \"/tmp/ansible_hetzner.hcloud.hcloud_load_balancer_payload_drs_0vnu/ansible_hetzner.hcloud.hcloud_load_balancer_payload.zip/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer.py\", line 269, in present_load_balancer\n File \"/tmp/ansible_hetzner.hcloud.hcloud_load_balancer_payload_drs_0vnu/ansible_hetzner.hcloud.hcloud_load_balancer_payload.zip/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer.py\", line 191, in _get_load_balancer\nAttributeError: 'TypeError' object has no attribute 'message'\n",
"module_stdout": "",
"msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
"rc": 1
}
hetznercloud-py has a method wait_until_status_is
for actions and servers which is very convenient.
Are there any plans to implement something like this in hcloud-python
?
In general it would be nice to have a way to synchronize actions, e. g.
Current Behavior
Tried to create a server from image with volume and ssh-keys failed:
sys.path.append('/home/user/hcloud-python/')
from hcloud import HcloudClient
client = HcloudClient(token=token)
volumes = client.volumes.get_by_id(id=vol_id)
ssh_keys = client.ssh_keys.get_all(name='user')
server = client.servers.create(name=vm, server_type=ServerType(name='cx11'), \
image=Image(id=image_id), volumes=volumes, ssh_keys=ssh_keys)
Traceback (most recent call last):
File "bin/hcloud-control.py", line 250, in <module>
main(args)
File "bin/hcloud-control.py", line 230, in main
resume(client, args.vm)
File "bin/hcloud-control.py", line 174, in resume
image=Image(id=image_id), volumes=volumes, ssh_keys=ssh_keys)
File "/home/user/hcloud-python/hcloud/servers/client.py", line 226, in create
response = self._client.request(url="/servers", method="POST", json=data)
File "/home/user/hcloud-python/hcloud/hcloud.py", line 109, in request
self._raise_exception_from_json_content(json_content)
File "/home/user/hcloud-python/hcloud/hcloud.py", line 84, in _raise_exception_from_json_content
details=json_content['error']['details']
hcloud.hcloud.HcloudAPIException
if i put this in try...except block i got:
SSH key 'ssh_key_id not found
Environment
OS: Ubuntu 18.04.2 LTS
Python Version: v3.6.7
Hcloud-Python Version: 95120b9
Current Behavior
ERROR: hcloud 1.6.1 has requirement future==0.17.1, but you'll have future 0.18.0 which is incompatible.
With the following requirements file (reproduce with pip install -r requirements.txt
):
ansible==2.8.5
molecule[hetznercloud]==2.22
pip==19.3
setuptools==41.4.0
Expected behavior/code
Easier bounds so that libraries don't conflict as easily.
Environment
Possible Solution
Use <=
and >=
bounds.
Is your feature request related to a problem? Please describe.
I'm spinning up and delegating workloads to servers in an automated fashion using hcloud-python. Since this is a fully automated setup, I don't want to deal with configuring SSH keys because, if everything goes as planned, I'll only ever connect to a given server once. Hence, I simply wanted to use the root password the API returns in its CreateServerResponse. However, once I connect via SSH I'm forced to reset the password β which I find completely unnecessary and which severely hinders automation because Python libraries like Paramiko, AsyncSSH, Plumbum, Fabric, etc. are not prepared for that.
Describe the solution you'd like
Provide an option for ServersClient.create()
to disable the reset-password policy.
Describe alternatives you've considered
ServersClient.create()
with that key, use server, tear down server, delete SSH key from project. Unfortunately, this adds an additional stack of dependencies just for generating a key which I want to use once.PS: I realize that this request concerns the Cloud API much more than it concerns hcloud-python. However, I didn't know where else to post this and, as outlined above, I also think this is much more of an obstacle for full automation (in Python) than it is for, say, casual users of the Cloud CLI.
Current Behavior
hcloud-python]$ make docs
make -C docs clean
[...]
Running Sphinx v3.5.4
making output directory... done
hcloud-python/docs/conf.py:166: RemovedInSphinx40Warning: The app.add_javascript() is deprecated. Please use app.add_js_file() instead.
app.add_javascript('js/open_links_in_new_tab.js')
building [mo]: targets for 0 po files that are out of date
building [html]: targets for 21 source files that are out of date
updating environment: [new config] 21 added, 0 changed, 0 removed
reading sources... [100%] samples
WARNING: autodoc: failed to import class 'CertificateClient' from module 'hcloud.certificates.client'; the following exception was raised:
Traceback (most recent call last):
File "/app/hcloud-python/lib64/python3.8/site-packages/sphinx/util/inspect.py", line 403, in safe_getattr
return getattr(obj, name, *defargs)
AttributeError: module 'hcloud.certificates.client' has no attribute 'CertificateClient'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/app/hcloud-python/lib64/python3.8/site-packages/sphinx/ext/autodoc/importer.py", line 111, in import_object
obj = attrgetter(obj, mangled_name)
File "/app/hcloud-python/lib64/python3.8/site-packages/sphinx/ext/autodoc/init.py", line 320, in get_attr
return autodoc_attrgetter(self.env.app, obj, name, *defargs)
File "/app/hcloud-python/lib64/python3.8/site-packages/sphinx/ext/autodoc/init.py", line 2604, in autodoc_attrgetter
return safe_getattr(obj, name, *defargs)
File "/app/hcloud-python/lib64/python3.8/site-packages/sphinx/util/inspect.py", line 419, in safe_getattr
raise AttributeError(name) from exc
AttributeError: CertificateClient
hcloud-python/hcloud/certificates/client.py:docstring of hcloud.certificates.client.BoundCertificate.update:7: WARNING: Inline interpreted text or phrase reference start-string without end-string.
WARNING: error while formatting arguments for hcloud.firewalls.client.BoundFirewall.get_actions: Handler <function update_annotations_using_type_comments at 0x7f2220505b80> for event 'autodoc-before-process-signature' threw an exception (exception: list index out of range)
WARNING: error while formatting arguments for hcloud.floating_ips.client.BoundFloatingIP.get_actions: Handler <function update_annotations_using_type_comments at 0x7f2220505b80> for event 'autodoc-before-process-signature' threw an exception (exception: list index out of range)
hcloud-python/hcloud/floating_ips/client.py:docstring of hcloud.floating_ips.client.BoundFloatingIP.get_actions_list:5: WARNING: Definition list ends without a blank line; unexpected unindent.
hcloud-python/hcloud/images/client.py:docstring of hcloud.images.client.ImagesClient.get_by_id:4: WARNING: Inline interpreted text or phrase reference start-string without end-string.
WARNING: error while formatting arguments for hcloud.images.client.BoundImage.update: Handler <function update_annotations_using_type_comments at 0x7f2220505b80> for event 'autodoc-before-process-signature' threw an exception (exception: list index out of range)
hcloud-python/docs/api.clients.load_balancer_types.rst:2: WARNING: Title underline too short.
hcloud-python/hcloud/load_balancers/client.py:docstring of hcloud.load_balancers.client.LoadBalancersClient.get_by_id:4: WARNING: Inline interpreted text or phrase reference start-string without end-string.
WARNING: autodoc: failed to import class 'LoadBalancerHealthCheckHttp' from module 'hcloud.load_balancers.domain'; the following exception was raised:
Traceback (most recent call last):
File "/app/hcloud-python/lib64/python3.8/site-packages/sphinx/util/inspect.py", line 403, in safe_getattr
return getattr(obj, name, *defargs)
AttributeError: module 'hcloud.load_balancers.domain' has no attribute 'LoadBalancerHealthCheckHttp'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/app/hcloud-python/lib64/python3.8/site-packages/sphinx/ext/autodoc/importer.py", line 111, in import_object
obj = attrgetter(obj, mangled_name)
File "/app/hcloud-python/lib64/python3.8/site-packages/sphinx/ext/autodoc/init.py", line 320, in get_attr
return autodoc_attrgetter(self.env.app, obj, name, *defargs)
File "/app/hcloud-python/lib64/python3.8/site-packages/sphinx/ext/autodoc/init.py", line 2604, in autodoc_attrgetter
return safe_getattr(obj, name, *defargs)
File "/app/hcloud-python/lib64/python3.8/site-packages/sphinx/util/inspect.py", line 419, in safe_getattr
raise AttributeError(name) from exc
AttributeError: LoadBalancerHealthCheckHttp
hcloud-python/hcloud/load_balancers/domain.py:docstring of hcloud.load_balancers.domain.LoadBalancerTarget:3: WARNING: Unexpected indentation.
hcloud-python/hcloud/load_balancers/domain.py:docstring of hcloud.load_balancers.domain.LoadBalancerTarget:4: WARNING: Block quote ends without a blank line; unexpected unindent.
hcloud-python/hcloud/load_balancers/domain.py:docstring of hcloud.load_balancers.domain.LoadBalancerTargetLabelSelector:3: WARNING: Unexpected indentation.
hcloud-python/hcloud/load_balancers/domain.py:docstring of hcloud.load_balancers.domain.LoadBalancerTargetIP:3: WARNING: Unexpected indentation.
hcloud-python/hcloud/load_balancers/domain.py:docstring of hcloud.load_balancers.domain.LoadBalancerAlgorithm:3: WARNING: Unexpected indentation.
hcloud-python/hcloud/networks/client.py:docstring of hcloud.networks.client.NetworksClient.get_by_id:4: WARNING: Inline interpreted text or phrase reference start-string without end-string.
hcloud-python/hcloud/ssh_keys/client.py:docstring of hcloud.ssh_keys.client.BoundSSHKey.update:7: WARNING: Inline interpreted text or phrase reference start-string without end-string.
WARNING: error while formatting arguments for hcloud.volumes.client.VolumesClient.get_actions: Handler <function update_annotations_using_type_comments at 0x7f2220505b80> for event 'autodoc-before-process-signature' threw an exception (exception: list index out of range)
WARNING: error while formatting arguments for hcloud.volumes.client.VolumesClient.get_actions_list: Handler <function update_annotations_using_type_comments at 0x7f2220505b80> for event 'autodoc-before-process-signature' threw an exception (exception: list index out of range)
hcloud-python/hcloud/volumes/client.py:docstring of hcloud.volumes.client.VolumesClient.get_actions:6: WARNING: Field list ends without a blank line; unexpected unindent.
hcloud-python/hcloud/volumes/client.py:docstring of hcloud.volumes.client.VolumesClient.get_actions:8: WARNING: Definition list ends without a blank line; unexpected unindent.
WARNING: error while formatting arguments for hcloud.volumes.client.BoundVolume.attach: Handler <function update_annotations_using_type_comments at 0x7f2220505b80> for event 'autodoc-before-process-signature' threw an exception (exception: list index out of range)
WARNING: error while formatting arguments for hcloud.volumes.client.BoundVolume.get_actions: Handler <function update_annotations_using_type_comments at 0x7f2220505b80> for event 'autodoc-before-process-signature' threw an exception (exception: list index out of range)
WARNING: error while formatting arguments for hcloud.volumes.client.BoundVolume.get_actions_list: Handler <function update_annotations_using_type_comments at 0x7f2220505b80> for event 'autodoc-before-process-signature' threw an exception (exception: list index out of range)
hcloud-python/hcloud/volumes/client.py:docstring of hcloud.volumes.client.BoundVolume.get_actions:5: WARNING: Field list ends without a blank line; unexpected unindent.
hcloud-python/hcloud/volumes/client.py:docstring of hcloud.volumes.client.BoundVolume.get_actions:7: WARNING: Definition list ends without a blank line; unexpected unindent.
../CONTRIBUTING.rst:122: WARNING: Literal block expected; none found.
looking for now-outdated files... none found
pickling environment... done
checking consistency... done
preparing documents... done
writing output... [100%] samples
generating indices... genindex done
highlighting module code... [100%] hcloud.volumes.domain
writing additional pages... search done
copying static files... done
copying extra files... done
dumping search index in English (code: en)... done
dumping object inventory... done
build succeeded, 27 warnings.
Expected behavior/code
no build errors for 'make docs'
Environment
Is your feature request related to a problem? Please describe.
I cannot ask your api for the initial used user_data script
Describe the solution you'd like
A user_data attribute on the responded server object would be fine
Describe alternatives you've considered
Just save a own database entity for each created server
Teachability, Documentation, Adoption, Migration Strategy
response = servers_client.get_by_id(...)
response.server.user_data
Is your feature request related to a problem? Please describe.
In one scenario, when I run volume.detach()
, I want to run volume.delete()
afterwards. However, because the detach job is async in the background, my script has to wait for an unknown amount of time before it can successfully call volume.delete()
Describe the solution you'd like
Alternative 1: Make a new function that covers my use case: volume.detach_and_delete()
Alternative 2: Add an option to volume.detach that makes it block until the detach action is actually completed in the backend. It could look like this, for example:
volume.detach(block_until_done=True)
Describe alternatives you've considered
I could write a custom for loop like this in my script, but that's not code I want to have in my script. I would really prefer that the hcloud takes care of this.
def is_volume_detached_from_server(volume, server):
# Implement code that gets the updated volume object or server object
# and checks whether or not the given volume is still attached to the server
return True | False
server = ...
volume.detach()
for i in range(50):
if i == 49:
raise Exception("Timeout")
if is_volume_detached_from_server(volume, server):
break
else:
time.sleep(5)
continue
volume.delete()
Teachability, Documentation, Adoption, Migration Strategy
Migration strategy: None needed, since the requested change(s) would be backwards-compatible
Current Behavior
Not supporting requests 2.23 is causing issues such as ansible-community/molecule-hetznercloud#16.
Line 17 in 053e285
Expected behavior/code
This library supports requests 2.23.
Is your feature request related to a problem? Please describe.
Right after creating a server, I want my Python script to connect to it via SSH. Unfortunately, I then have no other option than to trust the server's SSH fingerprint, resulting in a serious security issue. The same thing applies to the Cloud Console β it doesn't show the SSH fingerprint, either, and I will have to trust the server's fingerprint on first use.
With the Cloud Console the risk is much lower, though, because typically I create a server once, trust its fingerprint once and then use the server for an extended period of time. So the attack window is comparatively small. If however, I spin up and tear down servers using hcloud-python on the daily, the risk of an MITM attack increases tremendously. In fact, I'd go as far as saying that this almost completely defeats the purpose of having an API for automatically spinning up servers, especially if I need to transmit sensitive data (which in my case I do).
Describe the solution you'd like
Always have the Hetzner Cloud API return the server's SSH fingerprint in its CreateServerResponse, so that I don't have to trust the fingerprint when connecting later.
Even better, also provide a way to obtain the SSH fingerprint for existing servers.
Describe alternatives you've considered
A workaround is to set up the SSH daemon's keys using cloud-init. However, this is a) cumbersome and b) more work than should be necessary, given that I don't actually want/need to prescribe the exact fingerprint (which requires me to generate RSA keys from within Python, resulting in yet another dependency). More importantly, though, in light of the above security concerns I'd say the Cloud API should always give me a way to securely obtain a server's SSH fingerprint.
PS: I realize that this request concerns the Cloud API much more than it concerns hcloud-python. However, I didn't know where else to post this and, as outlined above, I also think this is much more of a security issue for automation than it is for, say, casual users of the CLI.
The hcloud.Client
should use a requests Session object for persistent HTTPS connections, avoiding a great deal of HTTPS connection latency/overhead when performing many API requests.
Using a rough time ...
comparison, this change alone seems to reduce the runtime for an Ansible dynamic inventory script making lots of hetzner cloud API requests from ~32s -> ~18s.
Is your feature request related to a problem? Please describe.
Using logging.getLogger("urllib3").setLevel(logging.DEBUG)
to show the individual API requests the library is making, I noticed that requests is establishing a new HTTPS connection for each API request:
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.hetzner.cloud:443
DEBUG:urllib3.connectionpool:https://api.hetzner.cloud:443 "GET /v1/servers?label_selector=...&page=1&per_page=50 HTTP/1.1" 200 None
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.hetzner.cloud:443
DEBUG:urllib3.connectionpool:https://api.hetzner.cloud:443 "GET /v1/networks/... HTTP/1.1" 200 None
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.hetzner.cloud:443
DEBUG:urllib3.connectionpool:https://api.hetzner.cloud:443 "GET /v1/networks/... HTTP/1.1" 200 None
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.hetzner.cloud:443
DEBUG:urllib3.connectionpool:https://api.hetzner.cloud:443 "GET /v1/volumes/... HTTP/1.1" 200 None
Describe the solution you'd like
Changing the Client.request
method to use a requests.Session
avoids the HTTPS connection overhead:
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.hetzner.cloud:443
DEBUG:urllib3.connectionpool:https://api.hetzner.cloud:443 "GET /v1/servers?label_selector=...&page=1&per_page=50 HTTP/1.1" 200 None
DEBUG:urllib3.connectionpool:https://api.hetzner.cloud:443 "GET /v1/networks/... HTTP/1.1" 200 None
DEBUG:urllib3.connectionpool:https://api.hetzner.cloud:443 "GET /v1/networks/... HTTP/1.1" 200 None
DEBUG:urllib3.connectionpool:https://api.hetzner.cloud:443 "GET /v1/volumes/... HTTP/1.1" 200 None
Describe alternatives you've considered
None
Teachability, Documentation, Adoption, Migration Strategy
This should be a completely transparent performance improvement for all users using a hcloud.Client(...)
instance.
Current Behavior
When rebuilding a server from an image, and this server has no ssh key associated, a new root password is generated.
According to the API documentation this new password is returned in key root_password
of the HTTP response. From the Python API, this new root password is not available, making rebuilt servers inaccessible.
Input Code
Something along these lines might reproduce the issue:
client = Client('<token>')
response = client.servers.create('testbox', ServerType(name='cx11'), Image(name='debian-10'))
print('root =', response.root_password)
time.sleep(60)
server = client.servers.get_by_name('testbox')
response = server.rebuild(Image(name='debian-10'))
print('root =', '???') # problem here - response is of type BoundAction not containing the password
Expected behavior/code
In servers/client.py, the root password trashed. It could for example be returned as second return argument, or added to the action's response, or be added to the server object. The wrapper method in line 199 might also need adaption to return the new root password.
Environment
Current Behavior
I get an exeption
File "<snipped>scripts\provision_vms.py", line 31, in create_vm
image=Image(name="ubuntu-18.04"),
File "<snipped>\lib\site-packages\hcloud\servers\client.py", line 449, in create
response = self._client.request(url="/servers", method="POST", json=data)
File "<snipped>\lib\site-packages\hcloud\hcloud.py", line 192, in request
self._raise_exception_from_json_content(json_content)
File "<snipped>\lib\site-packages\hcloud\hcloud.py", line 156, in _raise_exception_from_json_content
details=json_content['error']['details']
hcloud.hcloud.APIException: invalid input in field 'name'
Input Code
https://github.com/hetznercloud/hcloud-python/blob/master/examples/create_server.py#L6
client = Client(token=HETZNER_CLOUD_API_TOKEN)
response = client.servers.create(
name="that_server_12",
server_type=ServerType(name="cx11"),
image=Image(name="ubuntu-18.04"),
)
Expected behavior/code
I expected the server to be created, not get an exception about having an invalid image name.
Environment
Possible Solution
Additional context/Screenshots
Add any other context about the problem here. If applicable, add screenshots to help explain.
Current Behavior
I'm not able to assign my server ressource with this kind of implementation.
Either the documentation does not fit or the implementation or both
Input Code
def apply_to_resources(self, firewall, resources):
# type: (Firewall, List[FirewallResource]) -> List[BoundAction]
"""Applies one Firewall to multiple resources.
:param firewall: :class:`BoundFirewall <hcloud.firewalls.client.BoundFirewall>` or :class:`Firewall <hcloud.firewalls.domain.Firewall>`
:param rules: List[:class:`FirewallResource <hcloud.firewalls.domain.FirewallResource>`]
:return: List[:class:`BoundAction <hcloud.actions.client.BoundAction>`]
"""
data = {
"apply_to": []
}
for resource in resources:
data['apply_to'].append(resource.to_payload())
response = self._client.request(
url="/firewalls/{firewall_id}/actions/apply_to_resources".format(firewall_id=firewall.id),
method="POST", json=data)
return [BoundAction(self._client.actions, _) for _ in response['actions']]
Expected behavior/code
I like to assign the server-ressource to the firewall.
Environment
Possible Solution
We should implement an easy short method to get a specific server (volume, image, location, datacenter, ssh-key) by its name like we have in the hcloud-go https://github.com/hetznercloud/hcloud-go/blob/master/hcloud/server.go#L119
We can also implement a get_by_label(selector=)
method servers, volumes, image, ssh-keys and floating-ips)
This would allow users don't make something like this:
if module.params['id']:
server = client.servers.get_by_id(module.params['id'])
elif module.params['name']:
server = client.servers.get_all(name=module.params['name'])[0]
elif module.params['label_selector']:
server = client.servers.get_all(label_selector=module.params['label_selector'])[0]
Hello,
I was trying to package hcloud-python under gentoo using distutils. The issue resides in the fact that setup.py want to install the 'tests' directory under /usr/lib64/python2.7/site-packages/:
* ERROR: dev-python/hcloud-python-1.2.1::x-portage failed (install phase):
* Package installs 'tests' package which is forbidden and likely a bug in the build system.
# ls -la /tmp/portage/dev-python/hcloud-python-1.2.1/image/_python2.7/usr/lib64/python2.7/site-packages/
total 0
drwxr-xr-x 5 root root 100 apr 26 14:30 .
drwxr-xr-x 3 root root 60 apr 26 14:30 ..
drwxr-xr-x 14 root root 460 apr 26 14:30 hcloud
drwxr-xr-x 2 root root 160 apr 26 14:30 hcloud-1.2.1-py2.7.egg-info
drwxr-xr-x 4 root root 80 apr 26 14:30 tests
For now, I'm dropping the tests directory, but would be great fix the issue upstream. Thanks
We should support the same Client Configuration as the hcloud-go.
So we should also allow the user to customize the endpoint, instead of hardcoding it.
Hello,
Why has the Rules List used for create
and set_rules
a limit from 50 FirewallRule
Objects. How is it possible to add more then 50 Firewall Rules to a Firewall right now I donβt have found a other solution for this than a bulk update with all rules.
Ciao Hetzner,
We use your cloud and storage boxes. We use Apache libcloud to abstract from a specific implementation and found that your storage is not in the library (you can find Amazon, Google, etc).
https://github.com/apache/libcloud
We wrote a driver for libcloud that connects to your storage box via WebDAV. You could add it to Apache libcloud so people could find it and also find you as a cloud provider. I attached the source code below. If you decide to use it I can explain how to add to libcloud, etc and also provide testing code. License is open source.
Cheers
hello i got this error :(
unable to authenticate
Add a possibility to set the User Agent.
We could do it the same way like the hcloud-go does it:
https://github.com/hetznercloud/hcloud-go/blob/master/hcloud/client.go#L107
and
https://github.com/hetznercloud/hcloud-go/blob/master/hcloud/client.go#L228-L237
If statement has duplicate condition inside hcloud/core/client:
https://github.com/hetznercloud/hcloud-python/blob/master/hcloud/core/client.py#L47
BoundServer.request_console()
returns an object containing a websocket url to connect to and a password.
Is there any documentation on how to use that websocket url? Browsers cannot open it directory; I can connect using wscat
or websocat
, but I don't speak fluent websocket, how do I get to a remote console from there?
Thanks in advance!
Cheers,
Kosta
When I create new server via hcloud API and then get all servers information - 'created' date is set one for all. When I then get one server information - date is different
Python 3.6.8 (default, Oct 7 2019, 12:59:55)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
#> from hcloud import Client
#> client = Client(token="sLgM*******N2wMh")
#> s = client.servers.get_all()
#> s[0].created
datetime.datetime(2019, 10, 11, 10, 36, 49, tzinfo=tzutc())
#> s[1].created
datetime.datetime(2019, 10, 11, 10, 36, 49, tzinfo=tzutc())
#> s1 = client.servers.get_by_id(3434180)
#> s1.created
datetime.datetime(2019, 10, 11, 10, 36, 49, tzinfo=tzutc())
#> s2 = client.servers.get_by_id(3434122)
#> s2.created
datetime.datetime(2019, 10, 11, 10, 27, 43, tzinfo=tzutc())
Current Behavior
In my project, I'm getting an error message like this when I install my dependencies:
hcloud 1.4.1 has requirement python-dateutil==2.7.5, but you'll have python-dateutil 2.8.0 which is incompatible.
Input Code
N/A
Expected behavior/code
I expect hcloud
to support more than one version of python-dateutil. Depending on one single version makes it hard to fit hcloud
in a python environment with many other packages.
Environment
Possible Solution
Specify a wider version range for python-dateutil
in setup.py
Additional context/Screenshots
Add any other context about the problem here. If applicable, add screenshots to help explain.
In conda
-based Python deployments (common in science etc.), it would be rather useful to have hcloud
available as a conda / conda-forge package.
Technically, pip
is also available in conda
-based environments and sort of integrates with conda
, but using it can cause non-deterministic behavior down the line. Using pip
should therefore be avoided in this context if possible.
Because hcloud
does not contain non-Python components as far as I can see, the packaging process should be trivial. Guidelines can be found here. If any help is required, I have done this before ;)
Is your feature request related to a problem? Please describe.
I (as a library user) have an issue referring to the "readthedocs" every time I need to understand how I should use a method
I (as a library developer) have a problem with maintaining docs. I would be much easier for me to document my code inside a docstring.
Describe the solution you'd like
I would like to use a docstrings for documenting methods/objects and then run sphinx-apidoc
to create documentation for me
Describe alternatives you've considered
The alternative is what we have right now. We document everything directly in *.rst files
Teachability, Documentation, Adoption, Migration Strategy
I would like to adopt requests
library approach. They have a custom table of content, but they refer to autogenerated code inside documentation.
Example: https://github.com/kennethreitz/requests/blob/master/docs/api.rst
Is it possible to get ssh host key fingerprint if rescue system was enabled and booted? For automated system setup through ssh this would helpful.
Thanks!
Tried to get volume by id failed:
sys.path.append('/home/user/hcloud-python/')
from hcloud import HcloudClient
client = HcloudClient(token=token)
client.volumes.get_by_id(vol_id)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/user/hcloud-python/hcloud/volumes/client.py", line 58, in get_by_id
return BoundVolume(self, response['volume'])
File "/home/user/hcloud-python/hcloud/volumes/client.py", line 17, in __init__
super(BoundVolume, self).__init__(client, data, complete)
File "/home/user/hcloud-python/hcloud/core/client.py", line 69, in __init__
self.data_model = self.model(**data)
TypeError: __init__() got an unexpected keyword argument 'format'
Environment
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.