From 5fb4bf62251df12b61cafc2924ed6d5fbb8181b7 Mon Sep 17 00:00:00 2001 From: Tim Van Steenburgh Date: Tue, 6 Dec 2016 11:56:18 -0500 Subject: [PATCH] Docs --- Makefile | 2 +- docs/index.rst | 115 +++++++++++++++++++++++++--------- docs/narrative/connecting.rst | 66 +++++++++++++++++++ docs/narrative/index.rst | 8 +++ 4 files changed, 161 insertions(+), 30 deletions(-) create mode 100644 docs/narrative/connecting.rst create mode 100644 docs/narrative/index.rst diff --git a/Makefile b/Makefile index 04bc522..4a4ea32 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ test: docs: .tox $(PIP) list | grep Sphinx || $(PIP) install -U sphinx - rm -rf docs/api/* + rm -rf docs/api/* docs/_build/ $(BIN)/sphinx-apidoc -o docs/api/ juju/ $(BIN)/sphinx-build -b html docs/ docs/_build/ diff --git a/docs/index.rst b/docs/index.rst index 67d3fbe..93479ce 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -6,58 +6,115 @@ A Python library for Juju ========================= -Front Matter +NOTE: This is pre-release software. The implementation is usable but +not complete. + +Please report bugs at https://github.com/juju/python-libjuju/issues. + + +Requirements ------------ -NOTE: There is no implementation here yet. It is simply a mocked out -design of what this library might look like. The design itself is not -complete. Comments on the design, good or bad, are welcomed. Use cases -are also appreciated as they will shape the design. +* Python 3.5+ +* Juju 2.0+ + + +Design Notes +------------ -The goal is to end up with a feature-full and officially supported -python library for Juju. +* Asynchronous - uses asyncio and async/await features of python 3.5 +* Websocket-level bindings are programmatically generated (indirectly) from the + Juju golang code, ensuring full api coverage +* Provides an OO layer which encapsulates much of the websocket api and + provides familiar nouns and verbs (e.g. Model.deploy(), Application.add_unit(), + etc.) -The focus right now is on Juju 2+ only. -Design Ideas +Installation ------------ -* Present an object-oriented interface to all the features of the Juju - CLI -* Do as much as possible through the API so that the library can be used - without actually installing Juju + git clone https://github.com/juju/python-libjuju.git + cd python-libjuju + python setup.py install # make sure python is 3.5+ -Example Use Cases ------------------ -Please add more! +Quickstart +---------- +Here's a simple example that shows basic usage of the library. The example +connects to the currently active Juju model, deploys a single unit of the +ubuntu charm, then exits. + +More examples can be found in the `examples/` directory of the source tree, +and in the documentation. -Simple bootstrap/deploy -+++++++++++++++++++++++ .. code:: python - from juju import Juju + #!/usr/bin/python3.5 + + import asyncio + import logging + + from juju.model import Model + + + async def run(): + # Create a Model instance. We need to connect our Model to a Juju api + # server before we can use it. + model = Model() + + # Connect to the currently active Juju model + await model.connect_current() + + # Deploy a single unit of the ubuntu charm, using revision 0 from the + # stable channel of the Charm Store. + ubuntu_app = await model.deploy( + 'ubuntu-0', + service_name='ubuntu', + series='xenial', + channel='stable', + ) + + # Disconnect from the api server and cleanup. + model.disconnect() + + # Stop the asyncio event loop. + model.loop.stop() + + + def main(): + # Set logging level to debug so we can see verbose output from the + # juju library. + logging.basicConfig(level=logging.DEBUG) + + # Quiet logging from the websocket library. If you want to see + # everything sent over the wire, set this to DEBUG. + ws_logger = logging.getLogger('websockets.protocol') + ws_logger.setLevel(logging.INFO) + + # Create the asyncio event loop + loop = asyncio.get_event_loop() + + # Queue up our `run()` coroutine for execution + loop.create_task(run()) - juju = Juju() - lxd = juju.get_cloud('lxd') - controller = lxd.bootstrap('lxd-test') - model = controller.get_model('default') + # Start the event loop + loop.run_forever() - # We might want an async and blocking version of deploy()? - model.deploy('mediawiki-single') - mediawiki = model.get_service('mediawiki') - mediawiki.expose() + if __name__ == '__main__': + main() Table of Contents ----------------- .. toctree:: - :maxdepth: 2 + :glob: + :maxdepth: 3 - api/modules + narrative/index + API Docs diff --git a/docs/narrative/connecting.rst b/docs/narrative/connecting.rst new file mode 100644 index 0000000..1bc52ad --- /dev/null +++ b/docs/narrative/connecting.rst @@ -0,0 +1,66 @@ +Connecting +========== +A Juju controller provides websocket endpoints for itself and each of its +models. In order to do anything useful, the juju lib must connect to one of +these endpoints. There are several ways to do this. + + +To the Current Model +-------------------- +Connect to the currently active Juju model (the one returned by +`juju switch`). This only works if you have the Juju CLI client installed. + +.. code:: python + + from juju.model import Model + + model = Model() + await model.connect_current() + + +To a Named Model +---------------- +Connect to a model by name, using the same format as that returned from the +`juju switch` command. The accepted format is '[controller:][user/]model'. +This only works if you have the Juju CLI client installed. + +.. code:: python + + # $ juju switch + # juju-2.0.1:admin/libjuju + + from juju.model import Model + + model = Model() + await model.connect_model('juju-2.0.1:admin/libjuju') + + +To an API Endpoint with Username/Password Authentication +-------------------------------------------------------- +The most flexible, but also most verbose, way to connect is using the API +endpoint url and credentials directly. This method does NOT require the Juju +CLI client to be installed. + +.. code:: python + + from juju.model import Model + + model = Model() + + controller_endpoint = '10.0.4.171:17070' + model_uuid = 'e8399ac7-078c-4817-8e5e-32316d55b083' + username = 'admin' + password = 'f53f08cfc32a2e257fe5393271d89d62' + + # Left out for brevity, but if you have a cert string you should pass it in. + # You can copy the cert from the output of The `juju show-controller` + # command. + cacert = None + + await model.connect( + controller_endpoint, + model_uuid, + username, + password, + cacert, + ) diff --git a/docs/narrative/index.rst b/docs/narrative/index.rst new file mode 100644 index 0000000..47c2695 --- /dev/null +++ b/docs/narrative/index.rst @@ -0,0 +1,8 @@ +Narrative Docs +============== + +.. toctree:: + :glob: + :maxdepth: 2 + + * -- 2.25.1