From b4dabe4cc86d3492f69fc261288b58ef3f290d69 Mon Sep 17 00:00:00 2001 From: Andrew Starr-Bochicchio Date: Sun, 11 Dec 2016 22:45:54 -0500 Subject: [PATCH] Expand the README. --- README.rst | 32 ++++++++++++++++++-- fabric_digitalocean/decorators.py | 11 ++++++- fabric_digitalocean/tests/test_decorators.py | 15 +++++++-- 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/README.rst b/README.rst index 91d2c54..5880798 100644 --- a/README.rst +++ b/README.rst @@ -10,8 +10,27 @@ fabric-digitalocean is a collection of tools aiming to make it easy to use It was inspired by `fabric-aws`_ -Examples --------- +Installation +------------ + +``` +pip install fabric-digitalocean +``` + +Usage +----- + +With fabric-digitalocean, you can decorate Fabric tasks to run on a set of +DigitalOcean Droplet. The `@droplets` decorator can take a list of Droplet IDs, +a tag, or a region as an argument. If you use a tag or region, it will be +expanded to a list of all Droplets with that tag applied or in that region. +They can also be used together. + +The environmental variable `FABRIC_DIGITALOCEAN_TOKEN` must contain a +DigitalOcean API token. + +See below for an example: + .. code-block:: python from fabric.api import task, run @@ -46,6 +65,15 @@ Examples run('uptime') +Testing +------- + +To run the test suite, use: + +.. code-block:: + nosetests -v --with-coverage --cover-package=fabric_digitalocean + + .. _Fabric: http://www.fabfile.org/ .. _DigitalOcean: https://www.digitalocean.com .. _fabric-aws: https://github.com/EverythingMe/fabric-aws diff --git a/fabric_digitalocean/decorators.py b/fabric_digitalocean/decorators.py index a14d3d4..cd44690 100644 --- a/fabric_digitalocean/decorators.py +++ b/fabric_digitalocean/decorators.py @@ -4,6 +4,10 @@ from fabric.decorators import wraps, _wrap_as_new +class TokenError(Exception): + pass + + def _list_annotating_decorator(attribute, *values): """ From fabric.decorators._list_annotating_decorator @@ -38,7 +42,12 @@ def droplet_generator(region=None, tag=None, ids=[]): :param id: A list of DigitalOcean Droplet IDs :type id: list """ - token = os.getenv('DO_TOKEN') + token = os.getenv('FABRIC_DIGITALOCEAN_TOKEN') + if not token: + raise TokenError('The environmental variable FABRIC_DIGITALOCEAN_TOKEN' + ' is empty. It must contain a valid DigitalOcean API' + ' token.') + client = digitalocean.Manager(token=token) hosts = [] diff --git a/fabric_digitalocean/tests/test_decorators.py b/fabric_digitalocean/tests/test_decorators.py index a53ccfb..978e914 100644 --- a/fabric_digitalocean/tests/test_decorators.py +++ b/fabric_digitalocean/tests/test_decorators.py @@ -3,7 +3,7 @@ import responses from fabric.api import task -from fabric_digitalocean.decorators import droplets +from fabric_digitalocean.decorators import droplets, TokenError class TestDecorators(unittest.TestCase): @@ -11,7 +11,7 @@ class TestDecorators(unittest.TestCase): def setUp(self): super(TestDecorators, self).setUp() - os.environ["DO_TOKEN"] = "afaketokenthatwillworksincewemockthings" + os.environ["FABRIC_DIGITALOCEAN_TOKEN"] = "afaketokenformockingthings" self.base_url = "https://api.digitalocean.com/v2/" def load_from_file(self, json_file): @@ -19,6 +19,17 @@ def load_from_file(self, json_file): with open(os.path.join(cwd, 'fixtures/%s' % json_file), 'r') as f: return f.read() + def test_tokenerror(self): + os.environ["FABRIC_DIGITALOCEAN_TOKEN"] = "" + + with self.assertRaises(TokenError) as context: + @droplets(ids=3164444) + def dummy(): + pass + + self.assertTrue('The environmental variable FABRIC_DIGITALOCEAN_TOKEN' + in str(context.exception)) + @responses.activate def test_droplets_with_id(self): data = self.load_from_file('3164444.json')