Coder Social home page Coder Social logo

linode-python's Introduction

Linode Python Bindings

The bindings consist of three pieces:

  • api.py: Core library that manages authentication and api calls
  • shell.py: A command line interface to api.py that allows you to invoke a specific api command quickly
  • oop.py: An object oriented interface to api.py inspired by django

For definitive documentation on how the api works please visit: https://www.linode.com/api

API Keys

When creating an api object you may specify the key manually, or use the Api.user_getapikey which will return your apikey as well as set the internal key that will be used for subsequent api calls.

Both the shell.py and oop.py have mechanisms to pull the api key from the environment variable LINODE_API_KEY as well.

Batching

Batching should be used with care, once enabled all api calls are cached until Api.batchFlush() is called, however you must remember the order in which calls were made as that's the order of the list returned to you

License

This code is provided under an MIT-style license. Please refer to the LICENSE file in the root of the project for specifics.

linode-python's People

Contributors

cro avatar danslimmon avatar dustinlacewell avatar dustinthughes avatar intheclouddan avatar james-tr avatar jshwright avatar rtucker avatar theckman avatar tjfontaine avatar tylerturk avatar zwerfvogel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

linode-python's Issues

New Decimal handling breaks at least shell --avail_linodeplans

With a github checkout of 2014-05-19, I see the following:

$ ./shell.py --avail_linodeplans
Traceback (most recent call last):
  File "./shell.py", line 130, in <module>
    print(json.dumps(func(**params), indent=2, cls=DecimalEncoder))
  File "/usr/lib/python2.7/json/__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "/usr/lib/python2.7/json/encoder.py", line 203, in encode
    chunks = list(chunks)
  File "/usr/lib/python2.7/json/encoder.py", line 425, in _iterencode
    for chunk in _iterencode_list(o, _current_indent_level):
  File "/usr/lib/python2.7/json/encoder.py", line 326, in _iterencode_list
    for chunk in chunks:
  File "/usr/lib/python2.7/json/encoder.py", line 402, in _iterencode_dict
    for chunk in chunks:
  File "/usr/lib/python2.7/json/encoder.py", line 436, in _iterencode
    o = _default(o)
  File "/usr/lib/python2.7/json/encoder.py", line 178, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: Decimal('20.00') is not JSON serializable

When I change line 270 in api.py back to:

s = json.loads(response)

I get a valid response.

this python project is vulnerable to MITM as it fails to verify the ssl validity of the remote destination

this python project is vulnerable to MITM as it fails to verify the ssl validity of the remote destination.
urllib / urllib2 do not verify ssl at all by default.
from api.py --> where self__request is a urllib request.
req = self.__request(LINODE_API_URL, request, headers)
response = self.__urlopen(req)
response = response.read()

this request can be MITMed leading to the compromise of a users API key.

AttributeError: 'Request' object has no attribute 'prepare'

$ cat test1.py

import os
from linode import api

lin = api.Api(os.environ['LINODE_KEY'])
print lin.avail_linodeplans()

$ python test1.py

Traceback (most recent call last):
  File "test1.py", line 5, in <module>
    print lin.avail_linodeplans()
  File "/PY-ENV/lib/python2.7/site-packages/linode/api.py", line 340, in wrapper
    return self.__send_request(request)
  File "/PY-ENV/lib/python2.7/site-packages/linode/api.py", line 275, in __send_request
    response = self.__urlopen(req)
  File "/PY-ENV/lib/python2.7/site-packages/linode/api.py", line 56, in requests_open
    r = request.prepare()
AttributeError: 'Request' object has no attribute 'prepare'

requests 0.14.1, python 2.7.6. Is there some specific version I should be using for this? Thanks.

fallthrough generic_request doesn't work?

I've been trying to call linode_clone and linode_config_create unsuccessfully. For the latter, I would get errors of this nature:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/storage/development/envs/linode/local/lib/python2.7/site-packages/linode/api.py", line 243, in generic_request
    return self.__send_request(request)
  File "/storage/development/envs/linode/local/lib/python2.7/site-packages/linode/api.py", line 283, in __send_request
    raise ApiError(s['ERRORARRAY'])
linode.api.ApiError: [{u'ERRORCODE': 3, u'ERRORMESSAGE': u'The requested class does not exist'}]

The errors appear to come from upstream in JSON, but they are triggered by this chunk of code which is trying to do some assumptions (and is apparently failing):
https://github.com/tjfontaine/linode-python/blob/master/linode/api.py#L235-L246

For my particular use case, I wrote both function calls into the api explicitly and they worked fine. That's unrelated, besides the fact that the functions do work when written explicitly but not when handed to the fallback.

No more upgrade to support APIv4?

Hi There,

First of all, thank you so much for this awesome library.

We've using your library for years, and everything works fine since Linode still supporting APIv2.

However, we noticed that Linode have start cleaning up their APIv2 documentations and we just get a confirmation from their support team that APIv2 will reaching its end of life soon. We are wondering if developers of this project have plan to upgrade it to support APIv4?

We knew there is an official Python Library for Linode APIv4. However from investigation of that official library, it looks like there are tons of changes from how to iterative the library. It will require our code base to completely rewrite in order to migrate to use the official library. So we would like to give it a try to contact the developers team of this project see if you guys have plan to upgrade the current one again from it's been stopped 3 years ago.

Thanks again,

Regards
Draven Johnson

Edit: I probably misread some of the code here. From reading some issues, looks like this library have already support APIv3?

Thank I guess I mean if there is any plan to support latest APIv4? There are the latest API version that comes with some fancy new features.

Notes: Linode's APIv3 documents are unavailable now: https://www.linode.com/apiv3 (404)

Licensing

Hey there!

Wondering if you could please add an open source license to your project such as BSD or Apache to your project to make it easier for people to use!

Thanks!

Using API Correctly?

I'm trying to use your Linode Python API but I'm getting an error I don't understand. Can you help me? I want to get a list of the disks attached to a particular linode using this code:

from linode import api as linode_api
api = linode_api.Api(<my_api_key>)
linode_id = 1800300
disks = api.linode_disk_list(linode_id)

When I execute the code, I get the following error:

TypeError: wrapper() takes exactly 1 argument (2 given)

I know I'm creating the api instance correctly as I'm using it to successfully call the API's linode_ip_list method. Interestingly, if I don't provide the linode_id argument, I get this error:

linode.api.MissingRequiredArgument: 'LinodeID'

If I call the method with a linode ID, the error says I'm giving it two arguments. But if I don't give it any arguments, it says I'm missing an argument. At this point, I'm not sure if the LinodeID should be an integer or a string but I get the same error in either case. How do I call this method so that I don't get the TypeError argument? Thank you for your help.

Debug logs include sensitive data

If debug logs are turned on api_key, root password, and root ssh key are logged as well. This information should be redacted and not included in debug logs.

Would be great to encode structured parameters as JSON

For example, linode.disk.createfromstackscript takes a parameter StackScriptUDFResponses:

StackScriptUDFResponses - string (required)
JSON encoded name/value pairs, answering this StackScript's User Defined Fields

It's not clear whether it's allowed to pass actual JSON data to this parameter. In fact, it doesn't work, and the following code fails:

env.api.linode_disk_createfromstackscript(
    StackScriptUDFResponses={'hostname': env.target_host}, ...)

If I encode the structured data as a string first, then it works:

env.api.linode_disk_createfromstackscript(
    StackScriptUDFResponses=json.dumps({'hostname': env.target_host}), ...)

But it would be great if linode-python could either warn me that I'm trying to pass a non-string value for a parameter, or automatically encode it as JSON for me. What do you think?

Python 3

There is any plan to port to python 3?

Thank you

Namespaces and Setup.py

More of an enhancement. This API is odd for Python because it doesn't containerize itself inside a namespace or provide a setup.py method which would greatly improve the ease to install as well as allow us to include it in pip requirement files. Right now that process is pretty manual.

Support NodeBalancer API

Hi!

As far as I see, there is no support to NodeBalancer actions. Are you planning to add support for it in the near future or willing to accept patches for it ? =)

Thanks a lot,
Rodrigo

Deploy to PyPI

It would be much easier to install this and more pythonic if it were released onto the PyPI.

There is already a setup.py that has most of the information in there. Some useful extras would be to use find_packages() instead of manually setting this in case the project grows in the future. Another common pattern is to read the readme into the description field.

However the setup.py is good to go as it is and it's a trivial task to put something up on the PyPI.

Examples?

Not even one example in the docs on how to use this?

illegal api_action sent if "Api" tested for not == None

linode_conn = linode.api.Api(p_linode_api_key)
assert not linode_conn == None

just those two lines will send a request to linode with an api_action being equal to "..eq..", which linode reports back
as a thrown exception:
linode.api.ApiError: [{u'ERRORCODE': 3, u'ERRORMESSAGE': u'The requested class does not exist'}]

digging deeper into linode-python the actual response coming in from linode servers via VEpycurl is:
{"ERRORARRAY":[{"ERRORCODE":3,"ERRORMESSAGE":"The requested class does not exist"}],"DATA":{},"ACTION":"..eq.."}

the request that made that response is:
request:{'api_key': 'took-this-out', 'api_responseformat': 'json', 'api_action': '..eq..'}

the "..eq.." form is coming from some function name manipulation, so its original name is "eq"... which is some internal python stuff... ;)

the trick to avoid the problem is just not to do that assertion ;). but I found it curious that it worked like that...
maybe you can call this a feature as well ;)

this seems like

Error when using API's nodebalancer_node_update()

I'm getting an error using linode-python to manipulate Linode's NodeBalancer API.
Even though support is not documented, it works with the list() functions, but throws an ApiError() when trying to use update(). It seems like an error is being sent from the API back-end. I've tried different parameters to no avail.

I don't suppose many people are using the nodebalancer API yet, so this ticket is more of a note to myself. Hopefully I'll get round to finding the cause on the weekend.

Here's a console log, which shows everything is fine until trying nodebalancer_node_update(). I've removed identifying information.

>>> from linode import api
>>> linode = api.Api('my_api_key')
>>> linode.test_echo(HELLO='world') # Test the connection
{u'HELLO': u'world'}

>>> linode.nodebalancer_list() # List my node balancers
[{u'ADDRESS4': u'12.34.56.78,
  u'ADDRESS6': u'ip6-goes-here',
  u'CLIENTCONNTHROTTLE': 0,
  u'HOSTNAME': u'nb-12-34-56-78.fremont.nodebalancer.linode.com',
  u'LABEL': u'nodebalancer_label',
  u'NODEBALANCERID': 123,
  u'STATUS': u'active'}]

>>> linode.nodebalancer_config_list(NODEBALANCERID=123) # Show config for nodebalancer #123
[{u'ALGORITHM': u'roundrobin',
  u'CHECK': u'http_body',
  u'CHECK_ATTEMPTS': 1,
  u'CHECK_BODY': u'OK',
  u'CHECK_INTERVAL': 15,
  u'CHECK_PATH': u'/check/path',
  u'CHECK_TIMEOUT': 5,
  u'CONFIGID': 321,
  u'NODEBALANCERID': 123,
  u'PORT': 80,
  u'PROTOCOL': u'http',
  u'STICKINESS': u'none'}]

>>> linode.nodebalancer_node_list(CONFIGID=321) # Show nodes in my config #321
[{u'ADDRESS': u'192.168.11.11:80',
  u'CONFIGID': 321,
  u'LABEL': u'web1',
  u'MODE': u'accept',
  u'NODEBALANCERID': 123,
  u'NODEID': 1111,
  u'STATUS': u'UP',
  u'WEIGHT': 100},
 {u'ADDRESS': u'192.168.22.22:80',
  u'CONFIGID': 321,
  u'LABEL': u'web2',
  u'MODE': u'accept',
  u'NODEBALANCERID': 123,
  u'NODEID': 2222,
  u'STATUS': u'UP',
  u'WEIGHT': 100}]

>>> linode.nodebalancer_node_update(NODEID=1111, MODE='drain') # Set node #1111 to drain mode
[{u'ERRORCODE': 500, u'ERRORMESSAGE': u"Something wasn't handled well. Logged."}]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.