Squashed 'modules/libjuju/' changes from c50c361..c127833
authorAdam Israel <adam.israel@canonical.com>
Wed, 27 Mar 2019 18:50:11 +0000 (14:50 -0400)
committerAdam Israel <adam.israel@canonical.com>
Wed, 27 Mar 2019 18:50:11 +0000 (14:50 -0400)
c127833 Bump version and changelog for release
6aff679 k8s bundles no longer have application placement (#293)
1de9ad1 Add retry for connection if all endpoints fail (#288)
8cb8d75 Support generation of registration string for model sharing. (#279)
a9e2fd6 Add Twine for dist upload on release (#284)
407a6a6 Update and prepare for 0.11.2 release (#282)
d102620 call related update credential cloud facade methods based on facade version (#281)
2acbdc4 Add test case for redirect during connect (#275)
35fb43e Implement App.get_resources and pinned resources in bundles (#278)
b5ba51a Bump version and changelog for release
7a73a0a Fix bundles with subordinates for Juju <2.5 (#277)
a0f950f Bump version and changelog for release
01125e2 Updates for new Juju version (#274)
87d9388 Fix wrong variable name in revoke_model function (#271)
2b43065 Bump version and changelog for release
98ee524 set include_stats to false to reduce request time (#266)
61e1d69 Update version and changelog for 0.10.1
82f9968 Retry ssh in manual provision test (#265)
d64bfff Clean up lint and add lint coverage to travis config (#263)
c7c5c54 Increase the timeout for charmstore connections (#262)
4a6e398 Fix log level of `Driver connected to juju` message (#258)
514e479 Update version and changelog for 0.10.0
ec2c493 Reorder scp parameters (#259) (#260)
26c86c8 Implement set/get model constraints (#253)
c6b4ab4 Update version and changelog for 0.9.1
e863746 Update websockets to 6.0 (#254)
567bc1a Update version and changelog for 0.9.0
b275ced python3.7 compatibility updates (#251)
bc7336a Handle juju not installed in is_bootstrapped. (#250)
1ce8e0b Add app.reset_config(list). (#249)
c620d4f Implement model.get_action_status (#248)
96ea3c4 Fix `make client` in Python 3.6 (#247)
61969ea Update version and changelog for release
ebf6882 Add support for adding a manual (ssh) machine (#240)
18422f4 Backwards compatibility fixes (#213)
40c0211 Implement model.get_action_output (#242)
c6b8ac5 Fix JSON serialization error for bundle with lxd to unit placement (#243)
5014fc3 Fix reference in docs to connect_current (#239)
ebe0193 Wrap machine agent status workaround in version check (#238)
462989b Convert seconds to nanoseconds for juju.unit.run (#237)
0f413e6 Fix spurious intermittent failure in test_machines.py::test_status (#236)
ce36b60 Define an unused juju-zfs lxd storage pool (#235)
dfc2e8d Add support for Application get_actions (#234)
e7e8c13 Update version and changelog for release
499337b Surface errors from bundle plan (#233)
2d94186 Always send auth-tag even with macaroon auth (#217)
000355c Inline jsonfile credential when sending to controller (#231)
9805123 Bump VERSION and changelog for release
27d723b Always parse tags and spaces constraints to lists (#228)
668945a Doc index improvements (#211)
65e6b5e Add doc req to force newer pymacaroons to fix RTD builds
e2abd47 Fix dependency conflict for building docs
2907a6e Bump VERSION and changelog for 0.7.3 release
37a7500 Full macaroon bakery support (#206)
a06e313 Fix regression with deploying local charm, add test case (#209)
75e9a2b Expose a machines series (#208)
46c98f5 Revert non-functional switch to Py3.6, just specify Py3 instead (#205)
8a99ad1 Cherry-pick VERSION and changelog bump from 0.7.2 release branch
88121d6 Support deploying bundle YAML file directly (rather than just directory) (#202)
57c0dbf Cherry-pick #197 into master (#198)
0973edc Update VERSION and changelog for 0.7.0
f5a4108 Add deprecated placeholder for Controller.get_models
17dffa4 JujuData abstract base class (#194)
76f22cc Make Model and Controller connect methods backwardly compatible (#196)
19b5658 Fix race condition in adding relations (#192)
978f35c refactor connections prior to bakery authentication (#187)
77c0f04 sort all imports; lint tests (#188)
4740935 juju.client.gocookies: new module (#186)
2c4de22 all: use pyrfc3339 instead of dateutil (#185)
7133ffe juju/client: factor out JujuData class (#182)
476b832 Fix race condition in connection monitor test (#183)
e64a5d1 Fix example in README (#178)
97355cc Fix rare hang during Unit.run (#177)
ae0b091 #176: Fix licensing quirks
c0d001b Refactor model handling (#171)
ab807c8 Refactor users handling, add get_users (#170)
5270db5 Upload credential to controller when adding model (#168)
16d8390 Support 'applications' key in bundles (#165)
2de3eed Improve handling of thread error handling for loop.run() (#169)
7807023 Fix encoding when using to_json() (#166)
73effb1 Fix intermittent test failures (#167)
46da148 Update VERSION and changelog for release
3dda1dc Fix test failures (#163)
14392af removing cli command to add ssh keys (#161)
ce68170 Make Application.upgrade_charm upgrade resources (#158)

git-subtree-dir: modules/libjuju
git-subtree-split: c12783304945fdff5c28397b82b535a9cc065ca3

92 files changed:
.gitignore
.travis.yml
Makefile
VERSION
docs/_extensions/automembersummary.py
docs/api/juju.client.rst
docs/api/modules.rst
docs/changelog.rst
docs/index.rst
docs/narrative/controller.rst
docs/narrative/index.rst
docs/narrative/model.rst
docs/readme.rst
docs/requirements.txt
docs/upstream-updates/index.rst
examples/action.py
examples/add_machine.py
examples/add_model.py
examples/allwatcher.py
examples/config.py
examples/connect_current_model.py [new file with mode: 0644]
examples/controller.py
examples/credential.py [new file with mode: 0644]
examples/deploy.py
examples/fullstatus.py
examples/future.py
examples/leadership.py
examples/livemodel.py
examples/localcharm.py
examples/relate.py
examples/unitrun.py
juju/application.py
juju/client/_client.py
juju/client/_client1.py
juju/client/_client2.py
juju/client/_client3.py
juju/client/_client4.py
juju/client/_client5.py
juju/client/_client7.py [new file with mode: 0644]
juju/client/_client8.py [new file with mode: 0644]
juju/client/_client9.py [new file with mode: 0644]
juju/client/_definitions.py
juju/client/client.py
juju/client/connection.py
juju/client/connector.py [new file with mode: 0644]
juju/client/facade.py
juju/client/gocookies.py [new file with mode: 0644]
juju/client/jujudata.py [new file with mode: 0644]
juju/client/overrides.py
juju/client/runner.py
juju/client/schemas-juju-2.5-rc1.json [new file with mode: 0644]
juju/client/schemas-juju-latest.json
juju/constraints.py
juju/controller.py
juju/errors.py
juju/juju.py
juju/loop.py
juju/machine.py
juju/model.py
juju/provisioner.py [new file with mode: 0644]
juju/relation.py
juju/tag.py
juju/unit.py
juju/user.py [new file with mode: 0644]
juju/utils.py
setup.py
tests/base.py
tests/bundle/invalid.yaml [new file with mode: 0644]
tests/bundle/mini-bundle.yaml [new file with mode: 0644]
tests/integration/bundle/bundle-resource-rev.yaml [new file with mode: 0644]
tests/integration/cert.pem [new file with mode: 0644]
tests/integration/key.pem [new file with mode: 0644]
tests/integration/test_application.py
tests/integration/test_client.py
tests/integration/test_connection.py
tests/integration/test_controller.py
tests/integration/test_errors.py
tests/integration/test_macaroon_auth.py [new file with mode: 0644]
tests/integration/test_machine.py
tests/integration/test_model.py
tests/integration/test_unit.py
tests/unit/test_client.py
tests/unit/test_connection.py
tests/unit/test_constraints.py
tests/unit/test_controller.py [new file with mode: 0644]
tests/unit/test_gocookies.py [new file with mode: 0644]
tests/unit/test_loop.py
tests/unit/test_model.py
tests/unit/test_overrides.py
tests/unit/test_placement.py
tests/unit/test_registration_string.py [new file with mode: 0644]
tox.ini

index 866a785..6d00fec 100644 (file)
@@ -10,3 +10,6 @@ __pycache__/
 .\#*
 dist/
 dev/
 .\#*
 dist/
 dev/
+.pytest_cache
+pytestdebug.log
+.vscode/
index 0a57c38..5edfef5 100644 (file)
@@ -1,23 +1,48 @@
-dist: trusty
+dist: xenial
 sudo: required
 language: python
 sudo: required
 language: python
-python:
-  - "3.5"
+cache: pip
 before_install:
 before_install:
-  - sudo add-apt-repository ppa:ubuntu-lxc/lxd-stable -y
+  - if [[ $TRAVIS_PYTHON_VERSION == '3.6' ]]; then sudo add-apt-repository -y ppa:jonathonf/python-3.6; fi
+  - if [[ $TRAVIS_PYTHON_VERSION == '3.7-dev' ]]; then sudo add-apt-repository -y ppa:deadsnakes/ppa; fi
   - sudo apt-get update -q
   - sudo apt-get update -q
-  - sudo apt-get install lxd snapd -y
-  - sudo usermod -a -G lxd $USER
-  - sudo service lxd start || true
-  - sudo lxd init --auto
-install: pip install tox-travis
+  - sudo apt-get remove -qy lxd lxd-client
+  - sudo apt-get install snapd libsodium-dev -y
+install:
+  - sudo snap install lxd || true  # ignore failures so that unit tests will still run, at least
+  - sudo sh -c 'echo PATH=/snap/bin:$PATH >> /etc/environment';
+  - sudo snap install jq || true
+  - sudo snap install juju --classic --$JUJU_CHANNEL || true
+  - sudo snap install juju-wait --classic || true
+  - pip install tox-travis
 env:
 env:
-  - SNAP_CMD="sudo snap install juju --classic --stable"
-  - SNAP_CMD="sudo snap install juju --classic --edge"
+  global: >
+    TEST_AGENTS='{"agents":[{"url":"https://api.staging.jujucharms.com/identity","username":"libjuju-ci@yellow"}],"key":{"private":"88OOCxIHQNguRG7zFg2y2Hx5Ob0SeVKKBRnjyehverc=","public":"fDn20+5FGyN2hYO7z0rFUyoHGUnfrleslUNtoYsjNSs="}}'
+    PATH="/snap/bin:$PATH"
+
+matrix:
+  include:
+  - python: 3.6
+    env: JUJU_CHANNEL=edge
+  - python: 3.6
+    env: JUJU_CHANNEL=stable
+  - python: 3.7-dev
+    env: JUJU_CHANNEL=stable
+  - python: 3.7-dev
+    env: JUJU_CHANNEL=edge
+before_script:
+  # Run lint before performing more expensive operations (fail fast/early)
+  - tox -e lint
+
+  # init lxd for tests
+  - sudo lxd waitready --timeout 30
+  - sudo chmod 666 /var/snap/lxd/common/lxd/unix.socket
+  - lxd init --auto --network-address='[::]' --network-port=8443 --storage-backend=dir
+
+  # Horrible workaround to LP Bug #1738614
+  - sudo mkdir /var/snap/lxd/common/lxd/storage-pools/juju-zfs
+  - lxc storage create juju-zfs dir source=/var/snap/lxd/common/lxd/storage-pools/juju-zfs
+
 script:
 script:
-  - (eval "$SNAP_CMD")
-  - sudo ln -s /snap/bin/juju /usr/bin/juju || true
-  - sudo -E sudo -u $USER -E bash -c "/snap/bin/juju bootstrap localhost test"
-  - tox -e py35,integration
-  - sudo -E sudo -u $USER -E bash -c "/snap/bin/juju destroy-controller --destroy-all-models -y test"
-  - sudo snap remove juju
+  - juju bootstrap localhost test --config 'identity-url=https://api.staging.jujucharms.com/identity' --config 'allow-model-access=true'
+  - tox -e py3,integration,serial
index 2e59306..5938132 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
-BIN := .tox/py35/bin
-PY := $(BIN)/python3.5
+BIN := .tox/py3/bin
+PY := $(BIN)/python
 PIP := $(BIN)/pip
 SCHEMAGEN := $(shell which schemagen)
 VERSION=$(shell cat VERSION)
 PIP := $(BIN)/pip
 SCHEMAGEN := $(shell which schemagen)
 VERSION=$(shell cat VERSION)
@@ -13,7 +13,7 @@ clean:
 .tox:
        tox -r --notest
 
 .tox:
        tox -r --notest
 
-client:
+client: .tox
 ifndef SCHEMAGEN
        $(error "schemagen is not available, please install from https://github.com/juju/schemagen")
 endif
 ifndef SCHEMAGEN
        $(error "schemagen is not available, please install from https://github.com/juju/schemagen")
 endif
@@ -22,6 +22,10 @@ endif
 test:
        tox
 
 test:
        tox
 
+.PHONY: lint
+lint: 
+       tox -e lint --notest
+
 docs: .tox
        $(PIP) install -r docs/requirements.txt
        rm -rf docs/_build/
 docs: .tox
        $(PIP) install -r docs/requirements.txt
        rm -rf docs/_build/
@@ -29,10 +33,12 @@ docs: .tox
        cd docs/_build/ && zip -r docs.zip *
 
 release:
        cd docs/_build/ && zip -r docs.zip *
 
 release:
-       git remote | xargs -L1 git fetch --tags
-       $(PY) setup.py sdist upload
+       git fetch --tags
+       rm dist/*.tar.gz
+       $(PY) setup.py sdist
+       $(BIN)/twine upload --repository-url https://upload.pypi.org/legacy/ dist/*
        git tag ${VERSION}
        git tag ${VERSION}
-       git remote | xargs -L1 git push --tags
+       git push --tags
 
 upload: release
 
 
 upload: release
 
diff --git a/VERSION b/VERSION
index a918a2a..1a96df1 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.6.0
+0.11.3
index 898da62..cfe0b84 100644 (file)
@@ -1,18 +1,16 @@
 # Copyright 2014-2015 Canonical Limited.
 #
 # Copyright 2014-2015 Canonical Limited.
 #
-# This file is part of charm-helpers.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
 #
 #
-# charm-helpers is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License version 3 as
-# published by the Free Software Foundation.
+#  http://www.apache.org/licenses/LICENSE-2.0
 #
 #
-# charm-helpers is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with charm-helpers.  If not, see <http://www.gnu.org/licenses/>.
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
 
 
 import importlib
 
 
 import importlib
index 6a699c0..dad691f 100644 (file)
@@ -1,5 +1,5 @@
-juju\.client package
-====================
+Internal APIs
+=============
 
 These packages are for internal use in communicating with the low-level
 API.  You should use the object oriented API instead.  They are documented
 
 These packages are for internal use in communicating with the low-level
 API.  You should use the object oriented API instead.  They are documented
index bf06f26..9722a6a 100644 (file)
@@ -1,5 +1,5 @@
-juju
-====
+Public APIs
+===========
 
 It is recommended that you start with :doc:`juju.model` or :doc:`juju.controller`.
 If you need helpers to manage the asyncio loop, try :doc:`juju.loop`.
 
 It is recommended that you start with :doc:`juju.model` or :doc:`juju.controller`.
 If you need helpers to manage the asyncio loop, try :doc:`juju.loop`.
index 9da0cdc..039b468 100644 (file)
@@ -1,5 +1,164 @@
-Change Log
-----------
+Changelog
+---------
+
+0.11.3
+^^^^^^
+Wednesday March 13 2019
+
+* k8s bundles no longer have application placement (#293)
+* Add retry for connection if all endpoints fail (#288)
+* Support generation of registration string for model sharing. (#279)
+* Add Twine for dist upload on release (#284)
+
+
+0.11.2
+^^^^^^
+Wednesday January 16 2019
+
+* update facade methods for Juju 2.5-rc2 (#281)
+* Add test case for redirect during connect (#275)
+* Implement App.get_resources and pinned resources in bundles (#278)
+
+
+0.11.1
+^^^^^^
+Thursday December 13 2018
+
+* Fix bundles with subordinates for Juju <2.5 (#277)
+
+
+0.11.0
+^^^^^^
+Tuesday December 11 2018
+
+* Updates for new Juju version (#274)
+* Fix wrong variable name in revoke_model function (#271)
+
+
+0.10.2
+^^^^^^
+Tuesday September 18 2018
+
+* set include_stats to false to reduce request time (#266)
+
+
+0.10.1
+^^^^^^
+Monday September 17 2018
+
+* Retry ssh in manual provision test (#265)
+* Clean up lint and add lint coverage to travis config (#263)
+* Increase the timeout for charmstore connections (#262)
+* Fix log level of `Driver connected to juju` message (#258)
+
+
+0.10.0
+^^^^^^
+Thursday August 16 2018
+
+* Fix error due to scp extra opts order (#260)
+* Implement set/get model constraints (#253)
+
+
+0.9.1
+^^^^^
+Monday July 16 2018
+
+* Update websockets to 6.0 to fix OS X support due to Brew update to Py3.7 (#254)
+
+
+0.9.0
+^^^^^
+Friday June 29 2018
+
+* python3.7 compatibility updates (#251)
+* Handle juju not installed in is_bootstrapped for tests (#250)
+* Add app.reset_config(list). (#249)
+* Implement model.get_action_status (#248)
+* Fix `make client` in Python 3.6 (#247)
+
+
+0.8.0
+^^^^^
+Thursday June 14 2018
+
+* Add support for adding a manual (ssh) machine (#240)
+* Backwards compatibility fixes (#213)
+* Implement model.get_action_output (#242)
+* Fix JSON serialization error for bundle with lxd to unit placement (#243)
+* Fix reference in docs to connect_current (#239)
+* Wrap machine agent status workaround in version check (#238)
+* Convert seconds to nanoseconds for juju.unit.run (#237)
+* Fix spurious intermittent failure in test_machines.py::test_status (#236)
+* Define an unused juju-zfs lxd storage pool for Travis (#235)
+* Add support for Application get_actions (#234)
+
+
+0.7.5
+^^^^^
+Friday May 18 2018
+
+* Surface errors from bundle plan (#233)
+* Always send auth-tag even with macaroon auth (#217)
+* Inline jsonfile credential when sending to controller (#231)
+
+0.7.4
+^^^^^
+Tuesday Apr 24 2018
+
+* Always parse tags and spaces constraints to lists (#228)
+* Doc index improvements (#211)
+* Add doc req to force newer pymacaroons to fix RTD builds
+* Fix dependency conflict for building docs
+
+0.7.3
+^^^^^
+Tuesday Feb 20 2018
+
+* Full macaroon bakery support (#206)
+* Fix regression with deploying local charm, add test case (#209)
+* Expose a machines series (#208)
+* Automated test runner fixes (#205)
+
+0.7.2
+^^^^^
+Friday Feb 9 2018
+
+* Support deploying bundle YAML file directly (rather than just directory) (#202)
+
+0.7.1
+^^^^^
+Monday Dec 18 2017
+
+* Fix missed renames of model_uuids (#197)
+
+0.7.0
+^^^^^
+Fri Dec 15 2017
+
+* Fix race condition in adding relations (#192)
+* Fix race condition in connection monitor test (#183)
+* Fix example in README (#178)
+* Fix rare hang during Unit.run (#177)
+* Fix licensing quirks (#176)
+* Refactor model handling (#171)
+* Refactor users handling, add get_users (#170)
+* Upload credential to controller when adding model (#168)
+* Support 'applications' key in bundles (#165)
+* Improve handling of thread error handling for loop.run() (#169)
+* Fix encoding when using to_json() (#166)
+* Fix intermittent test failures (#167)
+
+0.6.1
+^^^^^
+Fri Sept 29 2017
+
+* Fix failure when controller supports newer facade version (#145)
+* Fix test failures (#163)
+* Fix SSH key handling when adding a new model (#161)
+* Make Application.upgrade_charm upgrade resources (#158)
+* Expand integration tests to use stable/edge versions of juju (#155)
+* Move docs to ReadTheDocs (https://pythonlibjuju.readthedocs.io/en/latest/)
 
 0.6.0
 ^^^^^
 
 0.6.0
 ^^^^^
index b4b075f..2dd55cb 100644 (file)
@@ -11,16 +11,29 @@ Table of Contents
 -----------------
 
 .. toctree::
 -----------------
 
 .. toctree::
+   :caption: Overview
    :glob:
    :maxdepth: 3
 
    narrative/index
    :glob:
    :maxdepth: 3
 
    narrative/index
-   API Docs <api/modules>
-   Internal API Docs <api/juju.client>
-   upstream-updates/index
 
 
 
 
-.. include:: changelog.rst
+.. toctree::
+   :caption: API Documentation
+   :glob:
+   :maxdepth: 3
+
+   api/modules
+   api/juju.client
+
+.. toctree::
+   :caption: Project
+   :glob:
+   :maxdepth: 3
+
+   upstream-updates/index
+   changelog
+
 
 
 Indices and tables
 
 
 Indices and tables
index 2da0e7b..1d86321 100644 (file)
@@ -6,9 +6,9 @@ these endpoints.
 
 Connecting to the controller endpoint is useful if you want to programmatically
 create a new model. If the model you want to use already exists, you can
 
 Connecting to the controller endpoint is useful if you want to programmatically
 create a new model. If the model you want to use already exists, you can
-connect directly to it (see :doc:`model`).
+connect directly to it (see py:doc:`model`).
 
 
-For api docs, see :class:`juju.controller.Controller`.
+For API docs, see py:class:`juju.controller.Controller`.
 
 
 Connecting to the Current Controller
 
 
 Connecting to the Current Controller
@@ -21,7 +21,7 @@ Connect to the currently active Juju controller (the one returned by
   from juju.controller import Controller
 
   controller = Controller()
   from juju.controller import Controller
 
   controller = Controller()
-  await controller.connect_current()
+  await controller.connect()
 
 
 Connecting to a Named Controller
 
 
 Connecting to a Named Controller
@@ -33,68 +33,60 @@ Connect to a controller by name.
   from juju.controller import Controller
 
   controller = Controller()
   from juju.controller import Controller
 
   controller = Controller()
-  await controller.connect_controller('mycontroller')
+  await controller.connect('mycontroller')
 
 
 
 
-Connecting 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.
+Connecting with Authentication
+------------------------------
+You can control what user you are connecting with by specifying either a
+username/password pair, or a macaroon or bakery client that can provide
+a macaroon.
 
 
-.. code:: python
 
 
-  from juju.controller import Controller
+.. code:: python
 
   controller = Controller()
 
   controller = Controller()
+  await controller.connect(username='admin',
+                           password='f53f08cfc32a2e257fe5393271d89d62')
+
+  # or with a macaroon
+  await controller.connect(macaroons=[
+      {
+          "Name": "macaroon-218d87053ad19626bcd5a0eef0bc9ba8bd4fbd80a968f52a5fd430b2aa8660df",
+          "Value": "W3siY2F2ZWF0cyI6 ... jBkZiJ9XQ==",
+          "Domain": "10.130.48.27",
+          "Path": "/auth",
+          "Secure": false,
+          "HostOnly": true,
+          "Expires": "2018-03-07T22:07:23Z",
+      },
+  ])
+
+  # or with a bakery client
+  from macaroonbakery.httpbakery import Client
+  from http.cookiejar import FileCookieJar
+
+  bakery_client=Client()
+  bakery_client.cookies = FileCookieJar('cookies.txt')
+  controller = Controller()
+  await controller.connect(bakery_client=bakery_client)
+  
 
 
-  controller_endpoint = '10.0.4.171:17070'
-  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 controller.connect(
-      controller_endpoint,
-      username,
-      password,
-      cacert,
-  )
-
-
-Connecting with Macaroon Authentication
----------------------------------------
-To connect to a shared controller, you'll need
-to use macaroon authentication. The simplest example is shown below, and uses
-already-discharged macaroons from the local filesystem. This will work if you
-have the Juju CLI installed.
-
-.. note::
 
 
-  The library does not yet contain support for fetching and discharging
-  macaroons. Until it does, if you want to use macaroon auth, you'll need
-  to supply already-discharged macaroons yourself.
+Connecting with an Explicit Endpoint
+------------------------------------
+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
 
 
 .. code:: python
 
-  from juju.client.connection import get_macaroons()
-  from juju.controller import Controller
-
   controller = Controller()
   controller = Controller()
-
-  controller_endpoint = '10.0.4.171:17070'
-  username = None
-  password = None
-  cacert = None
-  macaroons = get_macaroons()
-
   await controller.connect(
   await controller.connect(
-      controller_endpoint,
-      username,
-      password,
-      cacert,
-      macaroons,
+      endpoint='10.0.4.171:17070',
+      username='admin',
+      password='f53f08cfc32a2e257fe5393271d89d62',
+      cacert=None,  # Left out for brevity, but if you have a cert string you
+                    # should pass it in. You can get the cert from the output
+                    # of The `juju show-controller` command.
   )
   )
index eb77e4c..b1684a0 100644 (file)
@@ -1,5 +1,4 @@
-Narrative Docs
-==============
+**Overview**
 
 .. toctree::
    :glob:
 
 .. toctree::
    :glob:
index 57dbc81..42633a1 100644 (file)
@@ -4,7 +4,7 @@ A Juju controller provides websocket endpoints for each of its
 models. In order to do anything useful with a model, the juju lib must
 connect to one of these endpoints. There are several ways to do this.
 
 models. In order to do anything useful with a model, the juju lib must
 connect to one of these endpoints. There are several ways to do this.
 
-For api docs, see :class:`juju.model.Model`.
+For api docs, see py:class:`juju.model.Model`.
 
 
 Connecting to the Current Model
 
 
 Connecting to the Current Model
@@ -14,10 +14,8 @@ Connect to the currently active Juju model (the one returned by
 
 .. code:: python
 
 
 .. code:: python
 
-  from juju.model import Model
-
   model = Model()
   model = Model()
-  await model.connect_current()
+  await model.connect()
 
 
 Connecting to a Named Model
 
 
 Connecting to a Named Model
@@ -28,88 +26,74 @@ This only works if you have the Juju CLI client installed.
 
 .. code:: python
 
 
 .. code:: python
 
-  # $ juju switch
-  # juju-2.0.1:admin/libjuju
-
-  from juju.model import Model
-
   model = Model()
   model = Model()
-  await model.connect_model('juju-2.0.1:admin/libjuju')
+  await model.connect('juju-2.0.1:admin/libjuju')
 
 
 
 
-Connecting 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.
+Connecting with Authentication
+------------------------------
+You can control what user you are connecting with by specifying either a
+username/password pair, or a macaroon or bakery client that can provide
+a macaroon.
 
 
-.. code:: python
 
 
-  from juju.model import Model
+.. code:: python
 
   model = Model()
 
   model = Model()
+  await model.connect(username='admin',
+                      password='f53f08cfc32a2e257fe5393271d89d62')
+
+  # or with a macaroon
+  await model.connect(macaroons=[
+      {
+          "Name": "macaroon-218d87053ad19626bcd5a0eef0bc9ba8bd4fbd80a968f52a5fd430b2aa8660df",
+          "Value": "W3siY2F2ZWF0cyI6 ... jBkZiJ9XQ==",
+          "Domain": "10.130.48.27",
+          "Path": "/auth",
+          "Secure": false,
+          "HostOnly": true,
+          "Expires": "2018-03-07T22:07:23Z",
+      },
+  ])
 
 
-  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,
-  )
-
+  # or with a bakery client
+  from macaroonbakery.httpbakery import Client
+  from http.cookiejar import FileCookieJar
 
 
-Connecting with Macaroon Authentication
----------------------------------------
-To connect to a shared model, or a model an a shared controller, you'll need
-to use macaroon authentication. The simplest example is shown below, and uses
-already-discharged macaroons from the local filesystem. This will work if you
-have the Juju CLI installed.
+  bakery_client=Client()
+  bakery_client.cookies = FileCookieJar('cookies.txt')
+  model = Model()
+  await model.connect(bakery_client=bakery_client)
+  
 
 
-.. note::
 
 
-  The library does not yet contain support for fetching and discharging
-  macaroons. Until it does, if you want to use macaroon auth, you'll need
-  to supply already-discharged macaroons yourself.
+Connecting with an Explicit Endpoint
+------------------------------------
+The most flexible, but also most verbose, way to connect is using the API
+endpoint url, model UUID, and credentials directly. This method does NOT
+require the Juju CLI client to be installed.
 
 .. code:: python
 
 
 .. code:: python
 
-  from juju.client.connection import get_macaroons()
   from juju.model import Model
 
   model = Model()
   from juju.model import Model
 
   model = Model()
-
-  controller_endpoint = '10.0.4.171:17070'
-  model_uuid = 'e8399ac7-078c-4817-8e5e-32316d55b083'
-  username = None
-  password = None
-  cacert = None
-  macaroons = get_macaroons()
-
   await model.connect(
   await model.connect(
-      controller_endpoint,
-      model_uuid,
-      username,
-      password,
-      cacert,
-      macaroons,
+      endpoint='10.0.4.171:17070',
+      uuid='e8399ac7-078c-4817-8e5e-32316d55b083',
+      username='admin',
+      password='f53f08cfc32a2e257fe5393271d89d62',
+      cacert=None,  # Left out for brevity, but if you have a cert string you
+                    # should pass it in. You can get the cert from the output
+                    # of The `juju show-controller` command.
   )
 
 
 Creating and Destroying a Model
 -------------------------------
 Example of creating a new model and then destroying it. See
   )
 
 
 Creating and Destroying a Model
 -------------------------------
 Example of creating a new model and then destroying it. See
-:meth:`juju.controller.Controller.add_model` and
-:meth:`juju.controller.Controller.destroy_model` for more info.
+py:method:`juju.controller.Controller.add_model` and
+py:method:`juju.controller.Controller.destroy_model` for more info.
 
 .. code:: python
 
 
 .. code:: python
 
@@ -134,8 +118,8 @@ Example of creating a new model and then destroying it. See
 Adding Machines and Containers
 ------------------------------
 To add a machine or container, connect to a model and then call its
 Adding Machines and Containers
 ------------------------------
 To add a machine or container, connect to a model and then call its
-:meth:`~juju.model.Model.add_machine` method. A
-:class:`~juju.machine.Machine` instance is returned. The machine id
+py:method:`~juju.model.Model.add_machine` method. A
+py:class:`~juju.machine.Machine` instance is returned. The machine id
 can be used to deploy a charm to a specific machine or container.
 
 .. code:: python
 can be used to deploy a charm to a specific machine or container.
 
 .. code:: python
@@ -192,7 +176,7 @@ Reacting to Changes in a Model
 ------------------------------
 To watch for and respond to changes in a model, register an observer with the
 model. The easiest way to do this is by creating a
 ------------------------------
 To watch for and respond to changes in a model, register an observer with the
 model. The easiest way to do this is by creating a
-:class:`juju.model.ModelObserver` subclass.
+py:class:`juju.model.ModelObserver` subclass.
 
 .. code:: python
 
 
 .. code:: python
 
@@ -283,7 +267,7 @@ to the entity and type of change that you wish to handle.
           # specific handler method is not defined.
 
 
           # specific handler method is not defined.
 
 
-Any :class:`juju.model.ModelEntity` object can be observed directly by
+Any py:class:`juju.model.ModelEntity` object can be observed directly by
 registering callbacks on the object itself.
 
 .. code:: python
 registering callbacks on the object itself.
 
 .. code:: python
index ecfbc5a..87666d0 100644 (file)
@@ -38,18 +38,15 @@ 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
 ----------
 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.
+ubuntu charm, then exits:
 
 
 .. code:: python
 
 
 
 .. code:: python
 
-  #!/usr/bin/python3.5
+  #!/usr/bin/python3
 
 
-  import asyncio
   import logging
   import logging
+  import sys
 
   from juju import loop
   from juju.model import Model
 
   from juju import loop
   from juju.model import Model
@@ -63,26 +60,28 @@ and in the documentation.
       # Connect to the currently active Juju model
       await model.connect_current()
 
       # 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',
-          application_name='ubuntu',
-          series='xenial',
-          channel='stable',
-      )
+      try:
+          # Deploy a single unit of the ubuntu charm, using the latest revision
+          # from the stable channel of the Charm Store.
+          ubuntu_app = await model.deploy(
+            'ubuntu',
+            application_name='ubuntu',
+            series='xenial',
+            channel='stable',
+          )
 
 
-      # Disconnect from the api server and cleanup.
-      model.disconnect()
+          if '--wait' in sys.argv:
+              # optionally block until the application is ready
+              await model.block_until(lambda: ubuntu_app.status == 'active')
+      finally:
+          # Disconnect from the api server and cleanup.
+          await model.disconnect()
 
 
   def main():
 
 
   def main():
-      # Set logging level to debug so we can see verbose output from the
-      # juju library.
-      logging.basicConfig(level=logging.DEBUG)
+      logging.basicConfig(level=logging.INFO)
 
 
-      # Quiet logging from the websocket library. If you want to see
-      # everything sent over the wire, set this to DEBUG.
+      # 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)
 
       ws_logger = logging.getLogger('websockets.protocol')
       ws_logger.setLevel(logging.INFO)
 
@@ -93,3 +92,12 @@ and in the documentation.
 
   if __name__ == '__main__':
       main()
 
   if __name__ == '__main__':
       main()
+
+
+More examples can be found in the docs, as well as in the ``examples/``
+directory of the source tree which can be run using ``tox``.  For
+example, to run ``examples/connect_current_model.py``, use:
+
+.. code:: bash
+
+  tox -e example -- examples/connect_current_model.py
index 06377bf..dabf3a0 100644 (file)
@@ -1,7 +1,5 @@
-websockets
-pyyaml
-theblues
-python-dateutil
-sphinx
+pytz<2018.0,>=2017.2  # conflict between sphinx and macaroonbakery
+pymacaroons>=0.13.0,<1.0  # force new version with pynacl instead of libnacl
+sphinx==1.6.5
 sphinxcontrib-asyncio
 sphinx_rtd_theme
 sphinxcontrib-asyncio
 sphinx_rtd_theme
index 52099e6..41f448a 100644 (file)
@@ -1,5 +1,5 @@
-Upstream Updates
-================
+Syncing Upstream Updates
+========================
 
 Updating the facade and definitions code generated from the schema
 to reflect changes in upstream Juju consists of two steps:
 
 Updating the facade and definitions code generated from the schema
 to reflect changes in upstream Juju consists of two steps:
@@ -48,6 +48,54 @@ as well as one or more of the `juju/client/_clientX.py` files, depending on
 which facades were touched.
 
 
 which facades were touched.
 
 
+Integrating into the Object Layer
+---------------------------------
+
+Once the raw client APIs are synced, you may need to integrate any new or
+changed API calls into the object layer, to provide a clean, Pythonic way
+to interact with the model.  This may be as simple as adding an optional
+parameter to an existing model method, tweaking what manipulations, if any
+the model method does to the data before it is sent to the API, or it may
+require adding an entirely new model method to capture the new functionality.
+
+In general, the approach should be to make the interactions with the model
+layer use the same patterns as when you use the CLI, just with Python idioms
+and OO approaches.
+
+When trying to determine what client calls need to be made and what data to
+be sent for a given Juju CLI action, it is very useful to add
+`--debug --logging-config TRACE` to any Juju CLI command to view the full
+conversation between the CLI client and the API server.  For example:
+
+```
+[johnsca@murdoch:~] $ juju deploy --debug --logging-config TRACE ./builds/test
+11:51:20 INFO  juju.cmd supercommand.go:56 running juju [2.3.5 gc go1.10]
+11:51:20 DEBUG juju.cmd supercommand.go:57   args: []string{"/snap/juju/3884/bin/juju", "deploy", "--debug", "--logging-config", "TRACE", "./builds/test"}
+11:51:20 INFO  juju.juju api.go:67 connecting to API addresses: [35.172.119.191:17070 172.31.94.16:17070 252.94.16.1:17070]
+11:51:20 TRACE juju.api certpool.go:49 cert dir "/etc/juju/certs.d" does not exist
+11:51:20 DEBUG juju.api apiclient.go:843 successfully dialed "wss://35.172.119.191:17070/model/a7317969-6dab-4ba4-844b-af3d661c228d/api"
+11:51:20 INFO  juju.api apiclient.go:597 connection established to "wss://35.172.119.191:17070/model/a7317969-6dab-4ba4-844b-af3d661c228d/api"
+...
+11:51:20 INFO  juju.cmd.juju.application series_selector.go:71 with the configured model default series "xenial"
+11:51:20 DEBUG httpbakery client.go:244 client do POST https://35.172.119.191:17070/model/a7317969-6dab-4ba4-844b-af3d661c228d/charms?revision=0&schema=local&series=xenial {
+11:51:21 DEBUG httpbakery client.go:246 } -> error <nil>
+11:51:21 INFO  cmd deploy.go:1096 Deploying charm "local:xenial/test-0".
+11:51:21 TRACE juju.rpc.jsoncodec codec.go:225 -> {"request-id":3,"type":"Charms","version":2,"request":"CharmInfo","params":{"url":"local:xenial/test-0"}}
+11:51:21 TRACE juju.rpc.jsoncodec codec.go:120 <- {"request-id":3,"response":{"revision":0,"url":"local:xenial/test-0","config":{"test":{"type":"string","default":""}},"meta":{"name":"test","summary":"test","description":"test","subordinate":false,"series":["xenial"],"resources":{"dummy":{"name":"dummy","type":"file","path":"dummy.snap","description":"dummy snap"}},"min-juju-version":"0.0.0"},"actions":{}}}
+11:51:21 TRACE juju.rpc.jsoncodec codec.go:225 -> {"request-id":4,"type":"Charms","version":2,"request":"IsMetered","params":{"url":"local:xenial/test-0"}}
+11:51:21 TRACE juju.rpc.jsoncodec codec.go:120 <- {"request-id":4,"response":{"metered":false}}
+11:51:21 TRACE juju.rpc.jsoncodec codec.go:225 -> {"request-id":5,"type":"Resources","version":1,"request":"AddPendingResources","params":{"tag":"application-test","url":"local:xenial/test-0","channel":"","macaroon":null,"resources":[{"name":"dummy","type":"file","path":"dummy.snap","description":"dummy snap","origin":"store","revision":-1,"fingerprint":"","size":0}]}}
+11:51:21 TRACE juju.rpc.jsoncodec codec.go:120 <- {"request-id":5,"response":{"pending-ids":["c0ffdd92-da23-4fb2-8d41-d82d58423447"]}}
+11:51:21 TRACE juju.rpc.jsoncodec codec.go:225 -> {"request-id":6,"type":"Application","version":5,"request":"Deploy","params":{"applications":[{"application":"test","series":"xenial","charm-url":"local:xenial/test-0","channel":"","num-units":1,"config-yaml":"","constraints":{},"resources":{"dummy":"c0ffdd92-da23-4fb2-8d41-d82d58423447"}}]}}
+11:51:21 TRACE juju.rpc.jsoncodec codec.go:120 <- {"request-id":6,"response":{"results":[{}]}}
+11:51:21 TRACE juju.rpc.jsoncodec codec.go:123 <- error: read tcp 192.168.1.102:52168->35.172.119.191:17070: use of closed network connection (closing true)
+11:51:21 DEBUG juju.api monitor.go:35 RPC connection died
+11:51:21 INFO  cmd supercommand.go:465 command finished
+```
+
+Note that this will contain login information (which has been removed from the above).
+
+
 Overrides
 ---------
 
 Overrides
 ---------
 
index 0f25647..f839f11 100644 (file)
@@ -7,7 +7,6 @@ This example:
 4. Waits for the action results to come back, then exits.
 
 """
 4. Waits for the action results to come back, then exits.
 
 """
-import asyncio
 import logging
 
 from juju import loop
 import logging
 
 from juju import loop
@@ -27,8 +26,8 @@ async def run_action(unit):
 
 async def main():
     model = Model()
 
 async def main():
     model = Model()
-    await model.connect_current()
-    await model.reset(force=True)
+    # connect to current model with current user, per Juju CLI
+    await model.connect()
 
     app = await model.deploy(
         'git',
 
     app = await model.deploy(
         'git',
index 8ae2d40..33d0c34 100755 (executable)
@@ -19,7 +19,7 @@ GB = 1024
 
 async def main():
     model = Model()
 
 async def main():
     model = Model()
-    await model.connect_current()
+    await model.connect()
 
     try:
         # add a new default machine
 
     try:
         # add a new default machine
index 3e46490..88766f1 100644 (file)
@@ -19,7 +19,8 @@ LOG = getLogger(__name__)
 async def main():
     controller = Controller()
     print("Connecting to controller")
 async def main():
     controller = Controller()
     print("Connecting to controller")
-    await controller.connect_current()
+    # connect to current controller with current user, per Juju CLI
+    await controller.connect()
 
     try:
         model_name = "addmodeltest-{}".format(uuid.uuid4())
 
     try:
         model_name = "addmodeltest-{}".format(uuid.uuid4())
index c78d689..884230b 100644 (file)
@@ -16,7 +16,7 @@ from juju import loop
 
 
 async def watch():
 
 
 async def watch():
-    conn = await Connection.connect_current()
+    conn = await Connection.connect()
     allwatcher = client.AllWatcherFacade.from_connection(conn)
     while True:
         change = await allwatcher.Next()
     allwatcher = client.AllWatcherFacade.from_connection(conn)
     while True:
         change = await allwatcher.Next()
index bacc840..c7580f6 100644 (file)
@@ -6,7 +6,6 @@ This example:
 3. Deploys a charm and prints its config and constraints
 
 """
 3. Deploys a charm and prints its config and constraints
 
 """
-import asyncio
 import logging
 
 from juju.model import Model
 import logging
 
 from juju.model import Model
@@ -19,8 +18,8 @@ MB = 1
 
 async def main():
     model = Model()
 
 async def main():
     model = Model()
-    await model.connect_current()
-    await model.reset(force=True)
+    # connect to current model with current user, per Juju CLI
+    await model.connect()
 
     ubuntu_app = await model.deploy(
         'mysql',
 
     ubuntu_app = await model.deploy(
         'mysql',
@@ -47,7 +46,7 @@ async def main():
 
     await model.disconnect()
 
 
     await model.disconnect()
 
-    
+
 if __name__ == '__main__':
     logging.basicConfig(level=logging.DEBUG)
     ws_logger = logging.getLogger('websockets.protocol')
 if __name__ == '__main__':
     logging.basicConfig(level=logging.DEBUG)
     ws_logger = logging.getLogger('websockets.protocol')
diff --git a/examples/connect_current_model.py b/examples/connect_current_model.py
new file mode 100644 (file)
index 0000000..b46a09c
--- /dev/null
@@ -0,0 +1,27 @@
+"""
+This is a very basic example that connects to the currently selected model
+and prints the number of applications deployed to it.
+"""
+import logging
+
+from juju import loop
+from juju.model import Model
+
+log = logging.getLogger(__name__)
+
+
+async def main():
+    model = Model()
+    try:
+        # connect to the current model with the current user, per the Juju CLI
+        await model.connect()
+        print('There are {} applications'.format(len(model.applications)))
+    finally:
+        if model.is_connected():
+            print('Disconnecting from model')
+            await model.disconnect()
+
+
+if __name__ == '__main__':
+    logging.basicConfig(level=logging.INFO)
+    loop.run(main())
index 6002f68..b61a6f6 100644 (file)
@@ -8,7 +8,6 @@ This example:
 5. Destroys the model
 
 """
 5. Destroys the model
 
 """
-import asyncio
 import logging
 
 from juju.controller import Controller
 import logging
 
 from juju.controller import Controller
@@ -17,7 +16,8 @@ from juju import loop
 
 async def main():
     controller = Controller()
 
 async def main():
     controller = Controller()
-    await controller.connect_current()
+    # connect to current controller with current user, per Juju CLI
+    await controller.connect()
     model = await controller.add_model(
         'my-test-model',
         'aws',
     model = await controller.add_model(
         'my-test-model',
         'aws',
diff --git a/examples/credential.py b/examples/credential.py
new file mode 100644 (file)
index 0000000..e653536
--- /dev/null
@@ -0,0 +1,47 @@
+import sys
+from juju import loop
+from juju.controller import Controller
+
+
+async def main(cloud_name, credential_name):
+    controller = Controller()
+    model = None
+    print('Connecting to controller')
+    # connect to current controller with current user, per Juju CLI
+    await controller.connect()
+    try:
+        print('Adding model')
+        model = await controller.add_model(
+            'test',
+            cloud_name=cloud_name,
+            credential_name=credential_name)
+
+        # verify credential
+        print("Verify model's credential: {}".format(
+            model.info.cloud_credential_tag))
+
+        # verify we can deploy
+        print('Deploying ubuntu')
+        app = await model.deploy('ubuntu-10')
+
+        print('Waiting for active')
+        await model.block_until(
+            lambda: app.units and all(unit.workload_status == 'active'
+                                      for unit in app.units))
+
+        print('Removing ubuntu')
+        await app.remove()
+    finally:
+        print('Cleaning up')
+        if model:
+            print('Removing model')
+            model_uuid = model.info.uuid
+            await model.disconnect()
+            await controller.destroy_model(model_uuid)
+        print('Disconnecting')
+        await controller.disconnect()
+
+
+if __name__ == '__main__':
+    assert len(sys.argv) > 2, 'Please provide a cloud and credential name'
+    loop.run(main(sys.argv[1], sys.argv[2]))
index e6c306a..43764d7 100644 (file)
@@ -13,7 +13,8 @@ from juju.model import Model
 async def main():
     model = Model()
     print('Connecting to model')
 async def main():
     model = Model()
     print('Connecting to model')
-    await model.connect_current()
+    # connect to current model with current user, per Juju CLI
+    await model.connect()
 
     try:
         print('Deploying ubuntu')
 
     try:
         print('Deploying ubuntu')
index cdaf51d..5548423 100644 (file)
@@ -5,7 +5,7 @@ from juju.client.client import ClientFacade
 from juju import loop
 
 async def status():
 from juju import loop
 
 async def status():
-    conn = await Connection.connect_current()
+    conn = await Connection.connect()
     client = ClientFacade.from_connection(conn)
 
     patterns = None
     client = ClientFacade.from_connection(conn)
 
     patterns = None
index 0180325..5e974cf 100644 (file)
@@ -2,7 +2,6 @@
 This example doesn't work - it demonstrates features that don't exist yet.
 
 """
 This example doesn't work - it demonstrates features that don't exist yet.
 
 """
-import asyncio
 import logging
 
 from juju.model import Model
 import logging
 
 from juju.model import Model
@@ -11,8 +10,8 @@ from juju import loop
 
 async def main():
     model = Model()
 
 async def main():
     model = Model()
-    await model.connect_current()
-    await model.reset(force=True)
+    # connect to current model with current user, per Juju CLI
+    await model.connect()
 
     goal_state = Model.from_yaml('bundle-like-thing')
     ubuntu_app = await model.deploy(
 
     goal_state = Model.from_yaml('bundle-like-thing')
     ubuntu_app = await model.deploy(
index b231003..dbd1b6e 100644 (file)
@@ -13,7 +13,7 @@ from juju import loop
 
 async def report_leadership():
     model = Model()
 
 async def report_leadership():
     model = Model()
-    await model.connect_current()
+    await model.connect()
 
     print("Leadership: ")
     for app in model.applications.values():
 
     print("Leadership: ")
     for app in model.applications.values():
index 47eb999..1b10ac9 100644 (file)
@@ -6,8 +6,6 @@ This example:
 3. Runs forever (kill with Ctrl-C)
 
 """
 3. Runs forever (kill with Ctrl-C)
 
 """
-import asyncio
-
 from juju.model import Model
 from juju import loop
 
 from juju.model import Model
 from juju import loop
 
@@ -21,7 +19,8 @@ async def on_model_change(delta, old, new, model):
 
 async def watch_model():
     model = Model()
 
 async def watch_model():
     model = Model()
-    await model.connect_current()
+    # connect to current model with current user, per Juju CLI
+    await model.connect()
 
     model.add_observer(on_model_change)
 
 
     model.add_observer(on_model_change)
 
index 978703e..b9481d4 100644 (file)
@@ -15,7 +15,7 @@ from juju import loop
 
 async def main():
     model = Model()
 
 async def main():
     model = Model()
-    await model.connect_current()
+    await model.connect()
 
     # Deploy a local charm using a path to the charm directory
     await model.deploy(
 
     # Deploy a local charm using a path to the charm directory
     await model.deploy(
index 8f1e708..347e021 100644 (file)
@@ -40,59 +40,63 @@ class MyModelObserver(ModelObserver):
 
 async def main():
     model = Model()
 
 async def main():
     model = Model()
-    await model.connect_current()
+    # connect to current model with current user, per Juju CLI
+    await model.connect()
 
 
-    model.add_observer(MyRemoveObserver())
-    await model.reset(force=True)
-    model.add_observer(MyModelObserver())
+    try:
+        model.add_observer(MyRemoveObserver())
+        await model.reset(force=True)
+        model.add_observer(MyModelObserver())
 
 
-    ubuntu_app = await model.deploy(
-        'ubuntu',
-        application_name='ubuntu',
-        series='trusty',
-        channel='stable',
-    )
-    ubuntu_app.on_change(asyncio.coroutine(
-        lambda delta, old_app, new_app, model:
-            print('App changed: {}'.format(new_app.entity_id))
-    ))
-    ubuntu_app.on_remove(asyncio.coroutine(
-        lambda delta, old_app, new_app, model:
-            print('App removed: {}'.format(old_app.entity_id))
-    ))
-    ubuntu_app.on_unit_add(asyncio.coroutine(
-        lambda delta, old_unit, new_unit, model:
-            print('Unit added: {}'.format(new_unit.entity_id))
-    ))
-    ubuntu_app.on_unit_remove(asyncio.coroutine(
-        lambda delta, old_unit, new_unit, model:
-            print('Unit removed: {}'.format(old_unit.entity_id))
-    ))
-    unit_a, unit_b = await ubuntu_app.add_units(count=2)
-    unit_a.on_change(asyncio.coroutine(
-        lambda delta, old_unit, new_unit, model:
-            print('Unit changed: {}'.format(new_unit.entity_id))
-    ))
-    await model.deploy(
-        'nrpe',
-        application_name='nrpe',
-        series='trusty',
-        channel='stable',
-        # subordinates must be deployed without units
-        num_units=0,
-    )
-    my_relation = await model.add_relation(
-        'ubuntu',
-        'nrpe',
-    )
-    my_relation.on_remove(asyncio.coroutine(
-        lambda delta, old_rel, new_rel, model:
-            print('Relation removed: {}'.format(old_rel.endpoints))
-    ))
+        ubuntu_app = await model.deploy(
+            'ubuntu',
+            application_name='ubuntu',
+            series='trusty',
+            channel='stable',
+        )
+        ubuntu_app.on_change(asyncio.coroutine(
+            lambda delta, old_app, new_app, model:
+                print('App changed: {}'.format(new_app.entity_id))
+        ))
+        ubuntu_app.on_remove(asyncio.coroutine(
+            lambda delta, old_app, new_app, model:
+                print('App removed: {}'.format(old_app.entity_id))
+        ))
+        ubuntu_app.on_unit_add(asyncio.coroutine(
+            lambda delta, old_unit, new_unit, model:
+                print('Unit added: {}'.format(new_unit.entity_id))
+        ))
+        ubuntu_app.on_unit_remove(asyncio.coroutine(
+            lambda delta, old_unit, new_unit, model:
+                print('Unit removed: {}'.format(old_unit.entity_id))
+        ))
+        unit_a, unit_b = await ubuntu_app.add_units(count=2)
+        unit_a.on_change(asyncio.coroutine(
+            lambda delta, old_unit, new_unit, model:
+                print('Unit changed: {}'.format(new_unit.entity_id))
+        ))
+        await model.deploy(
+            'nrpe',
+            application_name='nrpe',
+            series='trusty',
+            channel='stable',
+            # subordinates must be deployed without units
+            num_units=0,
+        )
+        my_relation = await model.add_relation(
+            'ubuntu',
+            'nrpe',
+        )
+        my_relation.on_remove(asyncio.coroutine(
+            lambda delta, old_rel, new_rel, model:
+                print('Relation removed: {}'.format(old_rel.endpoints))
+        ))
+    finally:
+        await model.disconnect()
 
 
 if __name__ == '__main__':
 
 
 if __name__ == '__main__':
-    logging.basicConfig(level=logging.DEBUG)
+    logging.basicConfig(level=logging.INFO)
     ws_logger = logging.getLogger('websockets.protocol')
     ws_logger.setLevel(logging.INFO)
     loop.run(main())
     ws_logger = logging.getLogger('websockets.protocol')
     ws_logger.setLevel(logging.INFO)
     loop.run(main())
index 3dfacd6..805f0ae 100644 (file)
@@ -7,7 +7,6 @@ This example:
 4. Waits for the action results to come back, then exits.
 
 """
 4. Waits for the action results to come back, then exits.
 
 """
-import asyncio
 import logging
 
 from juju.model import Model
 import logging
 
 from juju.model import Model
@@ -24,8 +23,8 @@ async def run_command(unit):
 
 async def main():
     model = Model()
 
 async def main():
     model = Model()
-    await model.connect_current()
-    await model.reset(force=True)
+    # connect to current model with current user, per Juju CLI
+    await model.connect()
 
     app = await model.deploy(
         'ubuntu-0',
 
     app = await model.deploy(
         'ubuntu-0',
index 8719a62..3f7f02e 100644 (file)
@@ -1,3 +1,17 @@
+# Copyright 2016 Canonical Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+#     Unless required by applicable law or agreed to in writing, software
+#     distributed under the License is distributed on an "AS IS" BASIS,
+#     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#     See the License for the specific language governing permissions and
+#     limitations under the License.
+
 import asyncio
 import logging
 
 import asyncio
 import logging
 
@@ -38,6 +52,24 @@ class Application(model.ModelEntity):
         ]
 
     @property
         ]
 
     @property
+    def relations(self):
+        return [rel for rel in self.model.relations if rel.matches(self.name)]
+
+    def related_applications(self, endpoint_name=None):
+        apps = {}
+        for rel in self.relations:
+            if rel.is_peer:
+                local_ep, remote_ep = rel.endpoints[0]
+            else:
+                def is_us(ep):
+                    return ep.application.name == self.name
+                local_ep, remote_ep = sorted(rel.endpoints, key=is_us)
+            if endpoint_name is not None and endpoint_name != local_ep.name:
+                continue
+            apps[remote_ep.application.name] = remote_ep.application
+        return apps
+
+    @property
     def status(self):
         """Get the application status, as set by the charm's leader.
 
     def status(self):
         """Get the application status, as set by the charm's leader.
 
@@ -99,6 +131,31 @@ class Application(model.ModelEntity):
 
     add_units = add_unit
 
 
     add_units = add_unit
 
+    async def scale(self, scale=None, scale_change=None):
+        """
+        Set or adjust the scale of this (K8s) application.
+
+        One or the other of scale or scale_change must be provided.
+
+        :param int scale: Scale to which to set this application.
+        :param int scale_change: Amount by which to adjust the scale of this
+            application (can be positive or negative).
+        """
+        app_facade = client.ApplicationFacade.from_connection(self.connection)
+
+        if (scale, scale_change) == (None, None):
+            raise ValueError('Must provide either scale or scale_change')
+
+        log.debug(
+            'Scaling application %s %s %s',
+            self.name, 'to' if scale else 'by', scale or scale_change)
+
+        await app_facade.ScaleApplications([
+            client.ScaleApplicationParam(application_tag=self.tag,
+                                         scale=scale,
+                                         scale_change=scale_change)
+        ])
+
     def allocate(self, budget, value):
         """Allocate budget to this application.
 
     def allocate(self, budget, value):
         """Allocate budget to this application.
 
@@ -196,22 +253,43 @@ class Application(model.ModelEntity):
         result = (await app_facade.Get(self.name)).constraints
         return vars(result) if result else result
 
         result = (await app_facade.Get(self.name)).constraints
         return vars(result) if result else result
 
-    def get_actions(self, schema=False):
+    async def get_actions(self, schema=False):
         """Get actions defined for this application.
 
         :param bool schema: Return the full action schema
         """Get actions defined for this application.
 
         :param bool schema: Return the full action schema
-
+        :return dict: The charms actions, empty dict if none are defined.
         """
         """
-        raise NotImplementedError()
-
-    def get_resources(self, details=False):
+        actions = {}
+        entity = [{"tag": self.tag}]
+        action_facade = client.ActionFacade.from_connection(self.connection)
+        results = (
+            await action_facade.ApplicationsCharmsActions(entity)).results
+        for result in results:
+            if result.application_tag == self.tag and result.actions:
+                actions = result.actions
+                break
+        if not schema:
+            actions = {k: v['description'] for k, v in actions.items()}
+        return actions
+
+    async def get_resources(self):
         """Return resources for this application.
 
         """Return resources for this application.
 
-        :param bool details: Include detailed info about resources used by each
-            unit
-
+        Returns a dict mapping resource name to
+        :class:`~juju._definitions.CharmResource` instances.
         """
         """
-        raise NotImplementedError()
+        facade = client.ResourcesFacade.from_connection(self.connection)
+        response = await facade.ListResources([client.Entity(self.tag)])
+
+        resources = dict()
+        for result in response.results:
+            for resource in result.charm_store_resources or []:
+                resources[resource.name] = resource
+            for resource in result.resources or []:
+                if resource.charmresource:
+                    resource = resource.charmresource
+                    resources[resource.name] = resource
+        return resources
 
     async def run(self, command, timeout=None):
         """Run command on all units for this application.
 
     async def run(self, command, timeout=None):
         """Run command on all units for this application.
@@ -252,12 +330,10 @@ class Application(model.ModelEntity):
         )
         return await self.ann_facade.Set([ann])
 
         )
         return await self.ann_facade.Set([ann])
 
-    async def set_config(self, config, to_default=False):
+    async def set_config(self, config):
         """Set configuration options for this application.
 
         :param config: Dict of configuration to set
         """Set configuration options for this application.
 
         :param config: Dict of configuration to set
-        :param bool to_default: Set application options to default values
-
         """
         app_facade = client.ApplicationFacade.from_connection(self.connection)
 
         """
         app_facade = client.ApplicationFacade.from_connection(self.connection)
 
@@ -266,6 +342,20 @@ class Application(model.ModelEntity):
 
         return await app_facade.Set(self.name, config)
 
 
         return await app_facade.Set(self.name, config)
 
+    async def reset_config(self, to_default):
+        """
+        Restore application config to default values.
+
+        :param list to_default: A list of config options to be reset to their
+        default value.
+        """
+        app_facade = client.ApplicationFacade.from_connection(self.connection)
+
+        log.debug(
+            'Restoring default config for %s: %s', self.name, to_default)
+
+        return await app_facade.Unset(self.name, to_default)
+
     async def set_constraints(self, constraints):
         """Set machine constraints for this application.
 
     async def set_constraints(self, constraints):
         """Set machine constraints for this application.
 
@@ -342,8 +432,13 @@ class Application(model.ModelEntity):
             raise ValueError("switch and revision are mutually exclusive")
 
         client_facade = client.ClientFacade.from_connection(self.connection)
             raise ValueError("switch and revision are mutually exclusive")
 
         client_facade = client.ClientFacade.from_connection(self.connection)
+        resources_facade = client.ResourcesFacade.from_connection(
+            self.connection)
         app_facade = client.ApplicationFacade.from_connection(self.connection)
 
         app_facade = client.ApplicationFacade.from_connection(self.connection)
 
+        charmstore = self.model.charmstore
+        charmstore_entity = None
+
         if switch is not None:
             charm_url = switch
             if not charm_url.startswith('cs:'):
         if switch is not None:
             charm_url = switch
             if not charm_url.startswith('cs:'):
@@ -354,18 +449,65 @@ class Application(model.ModelEntity):
             if revision is not None:
                 charm_url = "%s-%d" % (charm_url, revision)
             else:
             if revision is not None:
                 charm_url = "%s-%d" % (charm_url, revision)
             else:
-                charmstore = self.model.charmstore
-                entity = await charmstore.entity(charm_url, channel=channel)
-                charm_url = entity['Id']
+                charmstore_entity = await charmstore.entity(charm_url,
+                                                            channel=channel)
+                charm_url = charmstore_entity['Id']
 
         if charm_url == self.data['charm-url']:
             raise JujuError('already running charm "%s"' % charm_url)
 
 
         if charm_url == self.data['charm-url']:
             raise JujuError('already running charm "%s"' % charm_url)
 
+        # Update charm
         await client_facade.AddCharm(
             url=charm_url,
             channel=channel
         )
 
         await client_facade.AddCharm(
             url=charm_url,
             channel=channel
         )
 
+        # Update resources
+        if not charmstore_entity:
+            charmstore_entity = await charmstore.entity(charm_url,
+                                                        channel=channel)
+        store_resources = charmstore_entity['Meta']['resources']
+
+        request_data = [client.Entity(self.tag)]
+        response = await resources_facade.ListResources(request_data)
+        existing_resources = {
+            resource.name: resource
+            for resource in response.results[0].resources
+        }
+
+        resources_to_update = [
+            resource for resource in store_resources
+            if resource['Name'] not in existing_resources or
+            existing_resources[resource['Name']].origin != 'upload'
+        ]
+
+        if resources_to_update:
+            request_data = [
+                client.CharmResource(
+                    description=resource.get('Description'),
+                    fingerprint=resource['Fingerprint'],
+                    name=resource['Name'],
+                    path=resource['Path'],
+                    revision=resource['Revision'],
+                    size=resource['Size'],
+                    type_=resource['Type'],
+                    origin='store',
+                ) for resource in resources_to_update
+            ]
+            response = await resources_facade.AddPendingResources(
+                self.tag,
+                charm_url,
+                request_data
+            )
+            pending_ids = response.pending_ids
+            resource_ids = {
+                resource['Name']: id
+                for resource, id in zip(resources_to_update, pending_ids)
+            }
+        else:
+            resource_ids = None
+
+        # Update application
         await app_facade.SetCharm(
             application=self.entity_id,
             channel=channel,
         await app_facade.SetCharm(
             application=self.entity_id,
             channel=channel,
@@ -374,7 +516,7 @@ class Application(model.ModelEntity):
             config_settings_yaml=None,
             force_series=force_series,
             force_units=force_units,
             config_settings_yaml=None,
             force_series=force_series,
             force_units=force_units,
-            resource_ids=None,
+            resource_ids=resource_ids,
             storage_constraints=None
         )
 
             storage_constraints=None
         )
 
index d510e11..c9fdef2 100644 (file)
@@ -3,33 +3,37 @@
 
 from juju.client._definitions import *
 
 
 from juju.client._definitions import *
 
-from juju.client import _client1, _client2, _client3, _client4, _client5
+from juju.client import _client2, _client1, _client3, _client4, _client5, _client8, _client7, _client9
 
 
 CLIENTS = {
 
 
 CLIENTS = {
-    "1": _client1,
     "2": _client2,
     "2": _client2,
+    "1": _client1,
     "3": _client3,
     "4": _client4,
     "3": _client3,
     "4": _client4,
-    "5": _client5
+    "5": _client5,
+    "8": _client8,
+    "7": _client7,
+    "9": _client9
 }
 
 
 
 def lookup_facade(name, version):
 }
 
 
 
 def lookup_facade(name, version):
-        """
-        Given a facade name and version, attempt to pull that facade out
-        of the correct client<version>.py file.
+    """
+    Given a facade name and version, attempt to pull that facade out
+    of the correct client<version>.py file.
 
 
-        """
+    """
+    for _version in range(int(version), 0, -1):
         try:
         try:
-            facade = getattr(CLIENTS[str(version)], name)
-        except KeyError:
-            raise ImportError("No facades found for version {}".format(version))
-        except AttributeError:
-            raise ImportError(
-                "No facade with name '{}' in version {}".format(name, version))
-        return facade
+            facade = getattr(CLIENTS[str(_version)], name)
+            return facade
+        except (KeyError, AttributeError):
+            continue
+    else:
+        raise ImportError("No supported version for facade: "
+                          "{}".format(name))
 
 
 
 
 
 
@@ -44,7 +48,14 @@ class TypeFactory:
         @param connection: initialized Connection object.
 
         """
         @param connection: initialized Connection object.
 
         """
-        version = connection.facades[cls.__name__[:-6]]
+        facade_name = cls.__name__
+        if not facade_name.endswith('Facade'):
+           raise TypeError('Unexpected class name: {}'.format(facade_name))
+        facade_name = facade_name[:-len('Facade')]
+        version = connection.facades.get(facade_name)
+        if version is None:
+            raise Exception('No facade {} in facades {}'.format(facade_name,
+                                                                connection.facades))
 
         c = lookup_facade(cls.__name__, version)
         c = c()
 
         c = lookup_facade(cls.__name__, version)
         c = c()
@@ -57,6 +68,10 @@ class ActionFacade(TypeFactory):
     pass
 
 
     pass
 
 
+class ActionPrunerFacade(TypeFactory):
+    pass
+
+
 class AgentFacade(TypeFactory):
     pass
 
 class AgentFacade(TypeFactory):
     pass
 
@@ -81,6 +96,10 @@ class ApplicationFacade(TypeFactory):
     pass
 
 
     pass
 
 
+class ApplicationOffersFacade(TypeFactory):
+    pass
+
+
 class ApplicationRelationsWatcherFacade(TypeFactory):
     pass
 
 class ApplicationRelationsWatcherFacade(TypeFactory):
     pass
 
@@ -101,6 +120,26 @@ class BundleFacade(TypeFactory):
     pass
 
 
     pass
 
 
+class CAASAgentFacade(TypeFactory):
+    pass
+
+
+class CAASFirewallerFacade(TypeFactory):
+    pass
+
+
+class CAASOperatorFacade(TypeFactory):
+    pass
+
+
+class CAASOperatorProvisionerFacade(TypeFactory):
+    pass
+
+
+class CAASUnitProvisionerFacade(TypeFactory):
+    pass
+
+
 class CharmRevisionUpdaterFacade(TypeFactory):
     pass
 
 class CharmRevisionUpdaterFacade(TypeFactory):
     pass
 
@@ -125,6 +164,22 @@ class ControllerFacade(TypeFactory):
     pass
 
 
     pass
 
 
+class CredentialManagerFacade(TypeFactory):
+    pass
+
+
+class CredentialValidatorFacade(TypeFactory):
+    pass
+
+
+class CrossControllerFacade(TypeFactory):
+    pass
+
+
+class CrossModelRelationsFacade(TypeFactory):
+    pass
+
+
 class DeployerFacade(TypeFactory):
     pass
 
 class DeployerFacade(TypeFactory):
     pass
 
@@ -141,10 +196,22 @@ class EntityWatcherFacade(TypeFactory):
     pass
 
 
     pass
 
 
+class ExternalControllerUpdaterFacade(TypeFactory):
+    pass
+
+
+class FanConfigurerFacade(TypeFactory):
+    pass
+
+
 class FilesystemAttachmentsWatcherFacade(TypeFactory):
     pass
 
 
 class FilesystemAttachmentsWatcherFacade(TypeFactory):
     pass
 
 
+class FirewallRulesFacade(TypeFactory):
+    pass
+
+
 class FirewallerFacade(TypeFactory):
     pass
 
 class FirewallerFacade(TypeFactory):
     pass
 
@@ -253,10 +320,18 @@ class ModelManagerFacade(TypeFactory):
     pass
 
 
     pass
 
 
+class ModelUpgraderFacade(TypeFactory):
+    pass
+
+
 class NotifyWatcherFacade(TypeFactory):
     pass
 
 
 class NotifyWatcherFacade(TypeFactory):
     pass
 
 
+class OfferStatusWatcherFacade(TypeFactory):
+    pass
+
+
 class PayloadsFacade(TypeFactory):
     pass
 
 class PayloadsFacade(TypeFactory):
     pass
 
@@ -281,6 +356,10 @@ class RebootFacade(TypeFactory):
     pass
 
 
     pass
 
 
+class RelationStatusWatcherFacade(TypeFactory):
+    pass
+
+
 class RelationUnitsWatcherFacade(TypeFactory):
     pass
 
 class RelationUnitsWatcherFacade(TypeFactory):
     pass
 
@@ -289,6 +368,10 @@ class RemoteApplicationWatcherFacade(TypeFactory):
     pass
 
 
     pass
 
 
+class RemoteRelationsFacade(TypeFactory):
+    pass
+
+
 class RemoteRelationsWatcherFacade(TypeFactory):
     pass
 
 class RemoteRelationsWatcherFacade(TypeFactory):
     pass
 
@@ -353,6 +436,10 @@ class UniterFacade(TypeFactory):
     pass
 
 
     pass
 
 
+class UpgradeSeriesFacade(TypeFactory):
+    pass
+
+
 class UpgraderFacade(TypeFactory):
     pass
 
 class UpgraderFacade(TypeFactory):
     pass
 
@@ -361,6 +448,10 @@ class UserManagerFacade(TypeFactory):
     pass
 
 
     pass
 
 
+class VolumeAttachmentPlansWatcherFacade(TypeFactory):
+    pass
+
+
 class VolumeAttachmentsWatcherFacade(TypeFactory):
     pass
 
 class VolumeAttachmentsWatcherFacade(TypeFactory):
     pass
 
index 3774056..dd84e78 100644 (file)
@@ -5,6 +5,102 @@ from juju.client.facade import Type, ReturnMapping
 from juju.client._definitions import *
 
 
 from juju.client._definitions import *
 
 
+class ActionPrunerFacade(Type):
+    name = 'ActionPruner'
+    version = 1
+    schema =     {'definitions': {'ActionPruneArgs': {'additionalProperties': False,
+                                         'properties': {'max-history-mb': {'type': 'integer'},
+                                                        'max-history-time': {'type': 'integer'}},
+                                         'required': ['max-history-time',
+                                                      'max-history-mb'],
+                                         'type': 'object'},
+                     'Error': {'additionalProperties': False,
+                               'properties': {'code': {'type': 'string'},
+                                              'info': {'$ref': '#/definitions/ErrorInfo'},
+                                              'message': {'type': 'string'}},
+                               'required': ['message', 'code'],
+                               'type': 'object'},
+                     'ErrorInfo': {'additionalProperties': False,
+                                   'properties': {'macaroon': {'$ref': '#/definitions/Macaroon'},
+                                                  'macaroon-path': {'type': 'string'}},
+                                   'type': 'object'},
+                     'Macaroon': {'additionalProperties': False, 'type': 'object'},
+                     'ModelConfigResult': {'additionalProperties': False,
+                                           'properties': {'config': {'patternProperties': {'.*': {'additionalProperties': True,
+                                                                                                  'type': 'object'}},
+                                                                     'type': 'object'}},
+                                           'required': ['config'],
+                                           'type': 'object'},
+                     'NotifyWatchResult': {'additionalProperties': False,
+                                           'properties': {'NotifyWatcherId': {'type': 'string'},
+                                                          'error': {'$ref': '#/definitions/Error'}},
+                                           'required': ['NotifyWatcherId'],
+                                           'type': 'object'}},
+     'properties': {'ModelConfig': {'properties': {'Result': {'$ref': '#/definitions/ModelConfigResult'}},
+                                    'type': 'object'},
+                    'Prune': {'properties': {'Params': {'$ref': '#/definitions/ActionPruneArgs'}},
+                              'type': 'object'},
+                    'WatchForModelConfigChanges': {'properties': {'Result': {'$ref': '#/definitions/NotifyWatchResult'}},
+                                                   'type': 'object'}},
+     'type': 'object'}
+    
+
+    @ReturnMapping(ModelConfigResult)
+    async def ModelConfig(self):
+        '''
+
+        Returns -> typing.Mapping[str, typing.Any]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='ActionPruner',
+                   request='ModelConfig',
+                   version=1,
+                   params=_params)
+
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(None)
+    async def Prune(self, max_history_mb, max_history_time):
+        '''
+        max_history_mb : int
+        max_history_time : int
+        Returns -> None
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='ActionPruner',
+                   request='Prune',
+                   version=1,
+                   params=_params)
+        _params['max-history-mb'] = max_history_mb
+        _params['max-history-time'] = max_history_time
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(NotifyWatchResult)
+    async def WatchForModelConfigChanges(self):
+        '''
+
+        Returns -> typing.Union[str, _ForwardRef('Error')]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='ActionPruner',
+                   request='WatchForModelConfigChanges',
+                   version=1,
+                   params=_params)
+
+        reply = await self.rpc(msg)
+        return reply
+
+
+
 class AgentToolsFacade(Type):
     name = 'AgentTools'
     version = 1
 class AgentToolsFacade(Type):
     name = 'AgentTools'
     version = 1
@@ -19,7 +115,10 @@ class AgentToolsFacade(Type):
         '''
         # map input types to rpc msg
         _params = dict()
         '''
         # map input types to rpc msg
         _params = dict()
-        msg = dict(type='AgentTools', request='UpdateToolsAvailable', version=1, params=_params)
+        msg = dict(type='AgentTools',
+                   request='UpdateToolsAvailable',
+                   version=1,
+                   params=_params)
 
         reply = await self.rpc(msg)
         return reply
 
         reply = await self.rpc(msg)
         return reply
@@ -50,11 +149,14 @@ class AllWatcherFacade(Type):
     async def Next(self):
         '''
 
     async def Next(self):
         '''
 
-        Returns -> typing.Sequence<+T_co>[~Delta]<~Delta>
+        Returns -> typing.Sequence[~Delta]
         '''
         # map input types to rpc msg
         _params = dict()
         '''
         # map input types to rpc msg
         _params = dict()
-        msg = dict(type='AllWatcher', request='Next', version=1, params=_params)
+        msg = dict(type='AllWatcher',
+                   request='Next',
+                   version=1,
+                   params=_params)
 
         reply = await self.rpc(msg)
         return reply
 
         reply = await self.rpc(msg)
         return reply
@@ -69,7 +171,10 @@ class AllWatcherFacade(Type):
         '''
         # map input types to rpc msg
         _params = dict()
         '''
         # map input types to rpc msg
         _params = dict()
-        msg = dict(type='AllWatcher', request='Stop', version=1, params=_params)
+        msg = dict(type='AllWatcher',
+                   request='Stop',
+                   version=1,
+                   params=_params)
 
         reply = await self.rpc(msg)
         return reply
 
         reply = await self.rpc(msg)
         return reply
@@ -130,7 +235,10 @@ class ApplicationRelationsWatcherFacade(Type):
         '''
         # map input types to rpc msg
         _params = dict()
         '''
         # map input types to rpc msg
         _params = dict()
-        msg = dict(type='ApplicationRelationsWatcher', request='Next', version=1, params=_params)
+        msg = dict(type='ApplicationRelationsWatcher',
+                   request='Next',
+                   version=1,
+                   params=_params)
 
         reply = await self.rpc(msg)
         return reply
 
         reply = await self.rpc(msg)
         return reply
@@ -145,7 +253,10 @@ class ApplicationRelationsWatcherFacade(Type):
         '''
         # map input types to rpc msg
         _params = dict()
         '''
         # map input types to rpc msg
         _params = dict()
-        msg = dict(type='ApplicationRelationsWatcher', request='Stop', version=1, params=_params)
+        msg = dict(type='ApplicationRelationsWatcher',
+                   request='Stop',
+                   version=1,
+                   params=_params)
 
         reply = await self.rpc(msg)
         return reply
 
         reply = await self.rpc(msg)
         return reply
@@ -201,12 +312,15 @@ class ApplicationScalerFacade(Type):
     @ReturnMapping(ErrorResults)
     async def Rescale(self, entities):
         '''
     @ReturnMapping(ErrorResults)
     async def Rescale(self, entities):
         '''
-        entities : typing.Sequence<+T_co>[~Entity]<~Entity>
-        Returns -> typing.Sequence<+T_co>[~ErrorResult]<~ErrorResult>
+        entities : typing.Sequence[~Entity]
+        Returns -> typing.Sequence[~ErrorResult]
         '''
         # map input types to rpc msg
         _params = dict()
         '''
         # map input types to rpc msg
         _params = dict()
-        msg = dict(type='ApplicationScaler', request='Rescale', version=1, params=_params)
+        msg = dict(type='ApplicationScaler',
+                   request='Rescale',
+                   version=1,
+                   params=_params)
         _params['entities'] = entities
         reply = await self.rpc(msg)
         return reply
         _params['entities'] = entities
         reply = await self.rpc(msg)
         return reply
@@ -217,11 +331,14 @@ class ApplicationScalerFacade(Type):
     async def Watch(self):
         '''
 
     async def Watch(self):
         '''
 
-        Returns -> typing.Union[typing.Sequence<+T_co>[str], _ForwardRef('Error')]
+        Returns -> typing.Union[typing.Sequence[str], _ForwardRef('Error'), str]
         '''
         # map input types to rpc msg
         _params = dict()
         '''
         # map input types to rpc msg
         _params = dict()
-        msg = dict(type='ApplicationScaler', request='Watch', version=1, params=_params)
+        msg = dict(type='ApplicationScaler',
+                   request='Watch',
+                   version=1,
+                   params=_params)
 
         reply = await self.rpc(msg)
         return reply
 
         reply = await self.rpc(msg)
         return reply
@@ -327,7 +444,10 @@ class BackupsFacade(Type):
         '''
         # map input types to rpc msg
         _params = dict()
         '''
         # map input types to rpc msg
         _params = dict()
-        msg = dict(type='Backups', request='Create', version=1, params=_params)
+        msg = dict(type='Backups',
+                   request='Create',
+                   version=1,
+                   params=_params)
         _params['notes'] = notes
         reply = await self.rpc(msg)
         return reply
         _params['notes'] = notes
         reply = await self.rpc(msg)
         return reply
@@ -342,7 +462,10 @@ class BackupsFacade(Type):
         '''
         # map input types to rpc msg
         _params = dict()
         '''
         # map input types to rpc msg
         _params = dict()
-        msg = dict(type='Backups', request='FinishRestore', version=1, params=_params)
+        msg = dict(type='Backups',
+                   request='FinishRestore',
+                   version=1,
+                   params=_params)
 
         reply = await self.rpc(msg)
         return reply
 
         reply = await self.rpc(msg)
         return reply
@@ -357,7 +480,10 @@ class BackupsFacade(Type):
         '''
         # map input types to rpc msg
         _params = dict()
         '''
         # map input types to rpc msg
         _params = dict()
-        msg = dict(type='Backups', request='Info', version=1, params=_params)
+        msg = dict(type='Backups',
+                   request='Info',
+                   version=1,
+                   params=_params)
         _params['id'] = id_
         reply = await self.rpc(msg)
         return reply
         _params['id'] = id_
         reply = await self.rpc(msg)
         return reply
@@ -368,11 +494,14 @@ class BackupsFacade(Type):
     async def List(self):
         '''
 
     async def List(self):
         '''
 
-        Returns -> typing.Sequence<+T_co>[~BackupsMetadataResult]<~BackupsMetadataResult>
+        Returns -> typing.Sequence[~BackupsMetadataResult]
         '''
         # map input types to rpc msg
         _params = dict()
         '''
         # map input types to rpc msg
         _params = dict()
-        msg = dict(type='Backups', request='List', version=1, params=_params)
+        msg = dict(type='Backups',
+                   request='List',
+                   version=1,
+                   params=_params)
 
         reply = await self.rpc(msg)
         return reply
 
         reply = await self.rpc(msg)
         return reply
@@ -387,7 +516,10 @@ class BackupsFacade(Type):
         '''
         # map input types to rpc msg
         _params = dict()
         '''
         # map input types to rpc msg
         _params = dict()
-        msg = dict(type='Backups', request='PrepareRestore', version=1, params=_params)
+        msg = dict(type='Backups',
+                   request='PrepareRestore',
+                   version=1,
+                   params=_params)
 
         reply = await self.rpc(msg)
         return reply
 
         reply = await self.rpc(msg)
         return reply
@@ -402,7 +534,10 @@ class BackupsFacade(Type):
         '''
         # map input types to rpc msg
         _params = dict()
         '''
         # map input types to rpc msg
         _params = dict()
-        msg = dict(type='Backups', request='Remove', version=1, params=_params)
+        msg = dict(type='Backups',
+                   request='Remove',
+                   version=1,
+                   params=_params)
         _params['id'] = id_
         reply = await self.rpc(msg)
         return reply
         _params['id'] = id_
         reply = await self.rpc(msg)
         return reply
@@ -417,7 +552,10 @@ class BackupsFacade(Type):
         '''
         # map input types to rpc msg
         _params = dict()
         '''
         # map input types to rpc msg
         _params = dict()
-        msg = dict(type='Backups', request='Restore', version=1, params=_params)
+        msg = dict(type='Backups',
+                   request='Restore',
+                   version=1,
+                   params=_params)
         _params['backup-id'] = backup_id
         reply = await self.rpc(msg)
         return reply
         _params['backup-id'] = backup_id
         reply = await self.rpc(msg)
         return reply
@@ -460,208 +598,193 @@ class BundleFacade(Type):
     async def GetChanges(self, yaml):
         '''
         yaml : str
     async def GetChanges(self, yaml):
         '''
         yaml : str
-        Returns -> typing.Sequence<+T_co>[~BundleChange]<~BundleChange>
+        Returns -> typing.Union[typing.Sequence[~BundleChange], typing.Sequence[str]]
         '''
         # map input types to rpc msg
         _params = dict()
         '''
         # map input types to rpc msg
         _params = dict()
-        msg = dict(type='Bundle', request='GetChanges', version=1, params=_params)
+        msg = dict(type='Bundle',
+                   request='GetChanges',
+                   version=1,
+                   params=_params)
         _params['yaml'] = yaml
         reply = await self.rpc(msg)
         return reply
 
 
 
         _params['yaml'] = yaml
         reply = await self.rpc(msg)
         return reply
 
 
 
-class ClientFacade(Type):
-    name = 'Client'
+class CAASAgentFacade(Type):
+    name = 'CAASAgent'
     version = 1
     version = 1
-    schema =     {'definitions': {'APIHostPortsResult': {'additionalProperties': False,
-                                            'properties': {'servers': {'items': {'items': {'$ref': '#/definitions/HostPort'},
-                                                                                 'type': 'array'},
-                                                                       'type': 'array'}},
-                                            'required': ['servers'],
-                                            'type': 'object'},
-                     'AddCharm': {'additionalProperties': False,
-                                  'properties': {'channel': {'type': 'string'},
-                                                 'url': {'type': 'string'}},
-                                  'required': ['url', 'channel'],
-                                  'type': 'object'},
-                     'AddCharmWithAuthorization': {'additionalProperties': False,
-                                                   'properties': {'channel': {'type': 'string'},
-                                                                  'macaroon': {'$ref': '#/definitions/Macaroon'},
-                                                                  'url': {'type': 'string'}},
-                                                   'required': ['url',
-                                                                'channel',
-                                                                'macaroon'],
-                                                   'type': 'object'},
-                     'AddMachineParams': {'additionalProperties': False,
-                                          'properties': {'addresses': {'items': {'$ref': '#/definitions/Address'},
-                                                                       'type': 'array'},
-                                                         'constraints': {'$ref': '#/definitions/Value'},
-                                                         'container-type': {'type': 'string'},
-                                                         'disks': {'items': {'$ref': '#/definitions/Constraints'},
-                                                                   'type': 'array'},
-                                                         'hardware-characteristics': {'$ref': '#/definitions/HardwareCharacteristics'},
-                                                         'instance-id': {'type': 'string'},
-                                                         'jobs': {'items': {'type': 'string'},
-                                                                  'type': 'array'},
-                                                         'nonce': {'type': 'string'},
-                                                         'parent-id': {'type': 'string'},
-                                                         'placement': {'$ref': '#/definitions/Placement'},
-                                                         'series': {'type': 'string'}},
-                                          'required': ['series',
-                                                       'constraints',
-                                                       'jobs',
-                                                       'parent-id',
-                                                       'container-type',
-                                                       'instance-id',
-                                                       'nonce',
-                                                       'hardware-characteristics',
-                                                       'addresses'],
-                                          'type': 'object'},
-                     'AddMachines': {'additionalProperties': False,
-                                     'properties': {'params': {'items': {'$ref': '#/definitions/AddMachineParams'},
-                                                               'type': 'array'}},
-                                     'required': ['params'],
-                                     'type': 'object'},
-                     'AddMachinesResult': {'additionalProperties': False,
-                                           'properties': {'error': {'$ref': '#/definitions/Error'},
-                                                          'machine': {'type': 'string'}},
-                                           'required': ['machine'],
-                                           'type': 'object'},
-                     'AddMachinesResults': {'additionalProperties': False,
-                                            'properties': {'machines': {'items': {'$ref': '#/definitions/AddMachinesResult'},
-                                                                        'type': 'array'}},
-                                            'required': ['machines'],
-                                            'type': 'object'},
-                     'Address': {'additionalProperties': False,
-                                 'properties': {'scope': {'type': 'string'},
-                                                'space-name': {'type': 'string'},
-                                                'type': {'type': 'string'},
-                                                'value': {'type': 'string'}},
-                                 'required': ['value', 'type', 'scope'],
-                                 'type': 'object'},
-                     'AgentVersionResult': {'additionalProperties': False,
-                                            'properties': {'version': {'$ref': '#/definitions/Number'}},
-                                            'required': ['version'],
-                                            'type': 'object'},
-                     'AllWatcherId': {'additionalProperties': False,
-                                      'properties': {'watcher-id': {'type': 'string'}},
-                                      'required': ['watcher-id'],
-                                      'type': 'object'},
-                     'ApplicationStatus': {'additionalProperties': False,
-                                           'properties': {'can-upgrade-to': {'type': 'string'},
-                                                          'charm': {'type': 'string'},
-                                                          'err': {'additionalProperties': True,
+    schema =     {'definitions': {'CloudCredential': {'additionalProperties': False,
+                                         'properties': {'attrs': {'patternProperties': {'.*': {'type': 'string'}},
                                                                   'type': 'object'},
                                                                   'type': 'object'},
-                                                          'exposed': {'type': 'boolean'},
-                                                          'life': {'type': 'string'},
-                                                          'meter-statuses': {'patternProperties': {'.*': {'$ref': '#/definitions/MeterStatus'}},
-                                                                             'type': 'object'},
-                                                          'relations': {'patternProperties': {'.*': {'items': {'type': 'string'},
-                                                                                                     'type': 'array'}},
-                                                                        'type': 'object'},
-                                                          'series': {'type': 'string'},
-                                                          'status': {'$ref': '#/definitions/DetailedStatus'},
-                                                          'subordinate-to': {'items': {'type': 'string'},
-                                                                             'type': 'array'},
-                                                          'units': {'patternProperties': {'.*': {'$ref': '#/definitions/UnitStatus'}},
-                                                                    'type': 'object'},
-                                                          'workload-version': {'type': 'string'}},
-                                           'required': ['charm',
-                                                        'series',
-                                                        'exposed',
-                                                        'life',
-                                                        'relations',
-                                                        'can-upgrade-to',
-                                                        'subordinate-to',
-                                                        'units',
-                                                        'meter-statuses',
-                                                        'status',
-                                                        'workload-version'],
-                                           'type': 'object'},
-                     'Binary': {'additionalProperties': False,
-                                'properties': {'Arch': {'type': 'string'},
-                                               'Number': {'$ref': '#/definitions/Number'},
-                                               'Series': {'type': 'string'}},
-                                'required': ['Number', 'Series', 'Arch'],
+                                                        'auth-type': {'type': 'string'},
+                                                        'redacted': {'items': {'type': 'string'},
+                                                                     'type': 'array'}},
+                                         'required': ['auth-type'],
+                                         'type': 'object'},
+                     'CloudSpec': {'additionalProperties': False,
+                                   'properties': {'cacertificates': {'items': {'type': 'string'},
+                                                                     'type': 'array'},
+                                                  'credential': {'$ref': '#/definitions/CloudCredential'},
+                                                  'endpoint': {'type': 'string'},
+                                                  'identity-endpoint': {'type': 'string'},
+                                                  'name': {'type': 'string'},
+                                                  'region': {'type': 'string'},
+                                                  'storage-endpoint': {'type': 'string'},
+                                                  'type': {'type': 'string'}},
+                                   'required': ['type', 'name'],
+                                   'type': 'object'},
+                     'CloudSpecResult': {'additionalProperties': False,
+                                         'properties': {'error': {'$ref': '#/definitions/Error'},
+                                                        'result': {'$ref': '#/definitions/CloudSpec'}},
+                                         'type': 'object'},
+                     'CloudSpecResults': {'additionalProperties': False,
+                                          'properties': {'results': {'items': {'$ref': '#/definitions/CloudSpecResult'},
+                                                                     'type': 'array'}},
+                                          'type': 'object'},
+                     'Entities': {'additionalProperties': False,
+                                  'properties': {'entities': {'items': {'$ref': '#/definitions/Entity'},
+                                                              'type': 'array'}},
+                                  'required': ['entities'],
+                                  'type': 'object'},
+                     'Entity': {'additionalProperties': False,
+                                'properties': {'tag': {'type': 'string'}},
+                                'required': ['tag'],
                                 'type': 'object'},
                                 'type': 'object'},
-                     'BundleChange': {'additionalProperties': False,
-                                      'properties': {'args': {'items': {'additionalProperties': True,
-                                                                        'type': 'object'},
-                                                              'type': 'array'},
-                                                     'id': {'type': 'string'},
-                                                     'method': {'type': 'string'},
-                                                     'requires': {'items': {'type': 'string'},
-                                                                  'type': 'array'}},
-                                      'required': ['id',
-                                                   'method',
-                                                   'args',
-                                                   'requires'],
-                                      'type': 'object'},
-                     'BundleChangesParams': {'additionalProperties': False,
-                                             'properties': {'yaml': {'type': 'string'}},
-                                             'required': ['yaml'],
-                                             'type': 'object'},
-                     'BundleChangesResults': {'additionalProperties': False,
-                                              'properties': {'changes': {'items': {'$ref': '#/definitions/BundleChange'},
-                                                                         'type': 'array'},
-                                                             'errors': {'items': {'type': 'string'},
-                                                                        'type': 'array'}},
-                                              'type': 'object'},
-                     'BytesResult': {'additionalProperties': False,
-                                     'properties': {'result': {'items': {'type': 'integer'},
-                                                               'type': 'array'}},
-                                     'required': ['result'],
-                                     'type': 'object'},
-                     'ConfigValue': {'additionalProperties': False,
-                                     'properties': {'source': {'type': 'string'},
-                                                    'value': {'additionalProperties': True,
-                                                              'type': 'object'}},
-                                     'required': ['value', 'source'],
+                     'Error': {'additionalProperties': False,
+                               'properties': {'code': {'type': 'string'},
+                                              'info': {'$ref': '#/definitions/ErrorInfo'},
+                                              'message': {'type': 'string'}},
+                               'required': ['message', 'code'],
+                               'type': 'object'},
+                     'ErrorInfo': {'additionalProperties': False,
+                                   'properties': {'macaroon': {'$ref': '#/definitions/Macaroon'},
+                                                  'macaroon-path': {'type': 'string'}},
+                                   'type': 'object'},
+                     'Macaroon': {'additionalProperties': False, 'type': 'object'},
+                     'ModelConfigResult': {'additionalProperties': False,
+                                           'properties': {'config': {'patternProperties': {'.*': {'additionalProperties': True,
+                                                                                                  'type': 'object'}},
+                                                                     'type': 'object'}},
+                                           'required': ['config'],
+                                           'type': 'object'},
+                     'ModelTag': {'additionalProperties': False, 'type': 'object'},
+                     'NotifyWatchResult': {'additionalProperties': False,
+                                           'properties': {'NotifyWatcherId': {'type': 'string'},
+                                                          'error': {'$ref': '#/definitions/Error'}},
+                                           'required': ['NotifyWatcherId'],
+                                           'type': 'object'}},
+     'properties': {'CloudSpec': {'properties': {'Params': {'$ref': '#/definitions/Entities'},
+                                                 'Result': {'$ref': '#/definitions/CloudSpecResults'}},
+                                  'type': 'object'},
+                    'GetCloudSpec': {'properties': {'Params': {'$ref': '#/definitions/ModelTag'},
+                                                    'Result': {'$ref': '#/definitions/CloudSpecResult'}},
                                      'type': 'object'},
                                      'type': 'object'},
-                     'Constraints': {'additionalProperties': False,
-                                     'properties': {'Count': {'type': 'integer'},
-                                                    'Pool': {'type': 'string'},
-                                                    'Size': {'type': 'integer'}},
-                                     'required': ['Pool', 'Size', 'Count'],
+                    'ModelConfig': {'properties': {'Result': {'$ref': '#/definitions/ModelConfigResult'}},
+                                    'type': 'object'},
+                    'WatchForModelConfigChanges': {'properties': {'Result': {'$ref': '#/definitions/NotifyWatchResult'}},
+                                                   'type': 'object'}},
+     'type': 'object'}
+    
+
+    @ReturnMapping(CloudSpecResults)
+    async def CloudSpec(self, entities):
+        '''
+        entities : typing.Sequence[~Entity]
+        Returns -> typing.Sequence[~CloudSpecResult]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASAgent',
+                   request='CloudSpec',
+                   version=1,
+                   params=_params)
+        _params['entities'] = entities
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(CloudSpecResult)
+    async def GetCloudSpec(self):
+        '''
+
+        Returns -> typing.Union[_ForwardRef('Error'), _ForwardRef('CloudSpec')]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASAgent',
+                   request='GetCloudSpec',
+                   version=1,
+                   params=_params)
+
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(ModelConfigResult)
+    async def ModelConfig(self):
+        '''
+
+        Returns -> typing.Mapping[str, typing.Any]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASAgent',
+                   request='ModelConfig',
+                   version=1,
+                   params=_params)
+
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(NotifyWatchResult)
+    async def WatchForModelConfigChanges(self):
+        '''
+
+        Returns -> typing.Union[str, _ForwardRef('Error')]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASAgent',
+                   request='WatchForModelConfigChanges',
+                   version=1,
+                   params=_params)
+
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+class CAASFirewallerFacade(Type):
+    name = 'CAASFirewaller'
+    version = 1
+    schema =     {'definitions': {'ApplicationGetConfigResults': {'additionalProperties': False,
+                                                     'properties': {'Results': {'items': {'$ref': '#/definitions/ConfigResult'},
+                                                                                'type': 'array'}},
+                                                     'required': ['Results'],
+                                                     'type': 'object'},
+                     'BoolResult': {'additionalProperties': False,
+                                    'properties': {'error': {'$ref': '#/definitions/Error'},
+                                                   'result': {'type': 'boolean'}},
+                                    'required': ['result'],
+                                    'type': 'object'},
+                     'BoolResults': {'additionalProperties': False,
+                                     'properties': {'results': {'items': {'$ref': '#/definitions/BoolResult'},
+                                                                'type': 'array'}},
+                                     'required': ['results'],
                                      'type': 'object'},
                                      'type': 'object'},
-                     'DestroyMachines': {'additionalProperties': False,
-                                         'properties': {'force': {'type': 'boolean'},
-                                                        'machine-names': {'items': {'type': 'string'},
-                                                                          'type': 'array'}},
-                                         'required': ['machine-names', 'force'],
-                                         'type': 'object'},
-                     'DetailedStatus': {'additionalProperties': False,
-                                        'properties': {'data': {'patternProperties': {'.*': {'additionalProperties': True,
+                     'ConfigResult': {'additionalProperties': False,
+                                      'properties': {'config': {'patternProperties': {'.*': {'additionalProperties': True,
                                                                                              'type': 'object'}},
                                                                 'type': 'object'},
                                                                                              'type': 'object'}},
                                                                 'type': 'object'},
-                                                       'err': {'additionalProperties': True,
-                                                               'type': 'object'},
-                                                       'info': {'type': 'string'},
-                                                       'kind': {'type': 'string'},
-                                                       'life': {'type': 'string'},
-                                                       'since': {'format': 'date-time',
-                                                                 'type': 'string'},
-                                                       'status': {'type': 'string'},
-                                                       'version': {'type': 'string'}},
-                                        'required': ['status',
-                                                     'info',
-                                                     'data',
-                                                     'since',
-                                                     'kind',
-                                                     'version',
-                                                     'life'],
-                                        'type': 'object'},
-                     'EndpointStatus': {'additionalProperties': False,
-                                        'properties': {'application': {'type': 'string'},
-                                                       'name': {'type': 'string'},
-                                                       'role': {'type': 'string'},
-                                                       'subordinate': {'type': 'boolean'}},
-                                        'required': ['application',
-                                                     'name',
-                                                     'role',
-                                                     'subordinate'],
-                                        'type': 'object'},
+                                                     'error': {'$ref': '#/definitions/Error'}},
+                                      'required': ['config'],
+                                      'type': 'object'},
                      'Entities': {'additionalProperties': False,
                                   'properties': {'entities': {'items': {'$ref': '#/definitions/Entity'},
                                                               'type': 'array'}},
                      'Entities': {'additionalProperties': False,
                                   'properties': {'entities': {'items': {'$ref': '#/definitions/Entity'},
                                                               'type': 'array'}},
@@ -671,16 +794,6 @@ class ClientFacade(Type):
                                 'properties': {'tag': {'type': 'string'}},
                                 'required': ['tag'],
                                 'type': 'object'},
                                 'properties': {'tag': {'type': 'string'}},
                                 'required': ['tag'],
                                 'type': 'object'},
-                     'EntityStatus': {'additionalProperties': False,
-                                      'properties': {'data': {'patternProperties': {'.*': {'additionalProperties': True,
-                                                                                           'type': 'object'}},
-                                                              'type': 'object'},
-                                                     'info': {'type': 'string'},
-                                                     'since': {'format': 'date-time',
-                                                               'type': 'string'},
-                                                     'status': {'type': 'string'}},
-                                      'required': ['status', 'info', 'since'],
-                                      'type': 'object'},
                      'Error': {'additionalProperties': False,
                                'properties': {'code': {'type': 'string'},
                                               'info': {'$ref': '#/definitions/ErrorInfo'},
                      'Error': {'additionalProperties': False,
                                'properties': {'code': {'type': 'string'},
                                               'info': {'$ref': '#/definitions/ErrorInfo'},
@@ -691,922 +804,3820 @@ class ClientFacade(Type):
                                    'properties': {'macaroon': {'$ref': '#/definitions/Macaroon'},
                                                   'macaroon-path': {'type': 'string'}},
                                    'type': 'object'},
                                    'properties': {'macaroon': {'$ref': '#/definitions/Macaroon'},
                                                   'macaroon-path': {'type': 'string'}},
                                    'type': 'object'},
-                     'ErrorResult': {'additionalProperties': False,
-                                     'properties': {'error': {'$ref': '#/definitions/Error'}},
-                                     'type': 'object'},
-                     'ErrorResults': {'additionalProperties': False,
-                                      'properties': {'results': {'items': {'$ref': '#/definitions/ErrorResult'},
-                                                                 'type': 'array'}},
-                                      'required': ['results'],
-                                      'type': 'object'},
-                     'FindToolsParams': {'additionalProperties': False,
-                                         'properties': {'arch': {'type': 'string'},
-                                                        'major': {'type': 'integer'},
-                                                        'minor': {'type': 'integer'},
-                                                        'number': {'$ref': '#/definitions/Number'},
-                                                        'series': {'type': 'string'}},
-                                         'required': ['number',
-                                                      'major',
-                                                      'minor',
-                                                      'arch',
-                                                      'series'],
-                                         'type': 'object'},
-                     'FindToolsResult': {'additionalProperties': False,
-                                         'properties': {'error': {'$ref': '#/definitions/Error'},
-                                                        'list': {'items': {'$ref': '#/definitions/Tools'},
-                                                                 'type': 'array'}},
-                                         'required': ['list'],
-                                         'type': 'object'},
-                     'FullStatus': {'additionalProperties': False,
-                                    'properties': {'applications': {'patternProperties': {'.*': {'$ref': '#/definitions/ApplicationStatus'}},
-                                                                    'type': 'object'},
-                                                   'machines': {'patternProperties': {'.*': {'$ref': '#/definitions/MachineStatus'}},
-                                                                'type': 'object'},
-                                                   'model': {'$ref': '#/definitions/ModelStatusInfo'},
-                                                   'relations': {'items': {'$ref': '#/definitions/RelationStatus'},
-                                                                 'type': 'array'},
-                                                   'remote-applications': {'patternProperties': {'.*': {'$ref': '#/definitions/RemoteApplicationStatus'}},
-                                                                           'type': 'object'}},
-                                    'required': ['model',
-                                                 'machines',
-                                                 'applications',
-                                                 'remote-applications',
-                                                 'relations'],
+                     'LifeResult': {'additionalProperties': False,
+                                    'properties': {'error': {'$ref': '#/definitions/Error'},
+                                                   'life': {'type': 'string'}},
+                                    'required': ['life'],
                                     'type': 'object'},
                                     'type': 'object'},
-                     'GetConstraintsResults': {'additionalProperties': False,
-                                               'properties': {'constraints': {'$ref': '#/definitions/Value'}},
-                                               'required': ['constraints'],
-                                               'type': 'object'},
-                     'HardwareCharacteristics': {'additionalProperties': False,
-                                                 'properties': {'arch': {'type': 'string'},
-                                                                'availability-zone': {'type': 'string'},
-                                                                'cpu-cores': {'type': 'integer'},
-                                                                'cpu-power': {'type': 'integer'},
-                                                                'mem': {'type': 'integer'},
-                                                                'root-disk': {'type': 'integer'},
-                                                                'tags': {'items': {'type': 'string'},
-                                                                         'type': 'array'}},
-                                                 'type': 'object'},
-                     'History': {'additionalProperties': False,
-                                 'properties': {'error': {'$ref': '#/definitions/Error'},
-                                                'statuses': {'items': {'$ref': '#/definitions/DetailedStatus'},
-                                                             'type': 'array'}},
-                                 'required': ['statuses'],
-                                 'type': 'object'},
-                     'HostPort': {'additionalProperties': False,
-                                  'properties': {'Address': {'$ref': '#/definitions/Address'},
-                                                 'port': {'type': 'integer'}},
-                                  'required': ['Address', 'port'],
-                                  'type': 'object'},
-                     'Macaroon': {'additionalProperties': False, 'type': 'object'},
-                     'MachineHardware': {'additionalProperties': False,
-                                         'properties': {'arch': {'type': 'string'},
-                                                        'availability-zone': {'type': 'string'},
-                                                        'cores': {'type': 'integer'},
-                                                        'cpu-power': {'type': 'integer'},
-                                                        'mem': {'type': 'integer'},
-                                                        'root-disk': {'type': 'integer'},
-                                                        'tags': {'items': {'type': 'string'},
-                                                                 'type': 'array'}},
-                                         'type': 'object'},
-                     'MachineStatus': {'additionalProperties': False,
-                                       'properties': {'agent-status': {'$ref': '#/definitions/DetailedStatus'},
-                                                      'constraints': {'type': 'string'},
-                                                      'containers': {'patternProperties': {'.*': {'$ref': '#/definitions/MachineStatus'}},
-                                                                     'type': 'object'},
-                                                      'dns-name': {'type': 'string'},
-                                                      'hardware': {'type': 'string'},
-                                                      'has-vote': {'type': 'boolean'},
-                                                      'id': {'type': 'string'},
-                                                      'instance-id': {'type': 'string'},
-                                                      'instance-status': {'$ref': '#/definitions/DetailedStatus'},
-                                                      'ip-addresses': {'items': {'type': 'string'},
-                                                                       'type': 'array'},
-                                                      'jobs': {'items': {'type': 'string'},
-                                                               'type': 'array'},
-                                                      'network-interfaces': {'patternProperties': {'.*': {'$ref': '#/definitions/NetworkInterface'}},
-                                                                             'type': 'object'},
-                                                      'series': {'type': 'string'},
-                                                      'wants-vote': {'type': 'boolean'}},
-                                       'required': ['agent-status',
-                                                    'instance-status',
-                                                    'dns-name',
-                                                    'instance-id',
-                                                    'series',
-                                                    'id',
-                                                    'containers',
-                                                    'constraints',
-                                                    'hardware',
-                                                    'jobs',
-                                                    'has-vote',
-                                                    'wants-vote'],
-                                       'type': 'object'},
-                     'MeterStatus': {'additionalProperties': False,
-                                     'properties': {'color': {'type': 'string'},
-                                                    'message': {'type': 'string'}},
-                                     'required': ['color', 'message'],
+                     'LifeResults': {'additionalProperties': False,
+                                     'properties': {'results': {'items': {'$ref': '#/definitions/LifeResult'},
+                                                                'type': 'array'}},
+                                     'required': ['results'],
                                      'type': 'object'},
                                      'type': 'object'},
-                     'ModelConfigResults': {'additionalProperties': False,
-                                            'properties': {'config': {'patternProperties': {'.*': {'$ref': '#/definitions/ConfigValue'}},
-                                                                      'type': 'object'}},
-                                            'required': ['config'],
+                     'Macaroon': {'additionalProperties': False, 'type': 'object'},
+                     'NotifyWatchResult': {'additionalProperties': False,
+                                           'properties': {'NotifyWatcherId': {'type': 'string'},
+                                                          'error': {'$ref': '#/definitions/Error'}},
+                                           'required': ['NotifyWatcherId'],
+                                           'type': 'object'},
+                     'NotifyWatchResults': {'additionalProperties': False,
+                                            'properties': {'results': {'items': {'$ref': '#/definitions/NotifyWatchResult'},
+                                                                       'type': 'array'}},
+                                            'required': ['results'],
                                             'type': 'object'},
                                             'type': 'object'},
-                     'ModelInfo': {'additionalProperties': False,
-                                   'properties': {'agent-version': {'$ref': '#/definitions/Number'},
-                                                  'cloud-credential-tag': {'type': 'string'},
-                                                  'cloud-region': {'type': 'string'},
-                                                  'cloud-tag': {'type': 'string'},
-                                                  'controller-uuid': {'type': 'string'},
-                                                  'default-series': {'type': 'string'},
-                                                  'life': {'type': 'string'},
-                                                  'machines': {'items': {'$ref': '#/definitions/ModelMachineInfo'},
-                                                               'type': 'array'},
-                                                  'migration': {'$ref': '#/definitions/ModelMigrationStatus'},
-                                                  'name': {'type': 'string'},
-                                                  'owner-tag': {'type': 'string'},
-                                                  'provider-type': {'type': 'string'},
-                                                  'sla': {'$ref': '#/definitions/ModelSLAInfo'},
-                                                  'status': {'$ref': '#/definitions/EntityStatus'},
-                                                  'users': {'items': {'$ref': '#/definitions/ModelUserInfo'},
-                                                            'type': 'array'},
-                                                  'uuid': {'type': 'string'}},
-                                   'required': ['name',
-                                                'uuid',
-                                                'controller-uuid',
-                                                'cloud-tag',
-                                                'owner-tag',
-                                                'life',
-                                                'users',
-                                                'machines',
-                                                'sla',
-                                                'agent-version'],
-                                   'type': 'object'},
-                     'ModelMachineInfo': {'additionalProperties': False,
-                                          'properties': {'hardware': {'$ref': '#/definitions/MachineHardware'},
-                                                         'has-vote': {'type': 'boolean'},
-                                                         'id': {'type': 'string'},
-                                                         'instance-id': {'type': 'string'},
-                                                         'status': {'type': 'string'},
-                                                         'wants-vote': {'type': 'boolean'}},
-                                          'required': ['id'],
-                                          'type': 'object'},
-                     'ModelMigrationStatus': {'additionalProperties': False,
-                                              'properties': {'end': {'format': 'date-time',
-                                                                     'type': 'string'},
-                                                             'start': {'format': 'date-time',
-                                                                       'type': 'string'},
-                                                             'status': {'type': 'string'}},
-                                              'required': ['status', 'start'],
-                                              'type': 'object'},
-                     'ModelSLA': {'additionalProperties': False,
-                                  'properties': {'ModelSLAInfo': {'$ref': '#/definitions/ModelSLAInfo'},
-                                                 'creds': {'items': {'type': 'integer'},
-                                                           'type': 'array'}},
-                                  'required': ['ModelSLAInfo', 'creds'],
+                     'StringsWatchResult': {'additionalProperties': False,
+                                            'properties': {'changes': {'items': {'type': 'string'},
+                                                                       'type': 'array'},
+                                                           'error': {'$ref': '#/definitions/Error'},
+                                                           'watcher-id': {'type': 'string'}},
+                                            'required': ['watcher-id'],
+                                            'type': 'object'}},
+     'properties': {'ApplicationsConfig': {'properties': {'Params': {'$ref': '#/definitions/Entities'},
+                                                          'Result': {'$ref': '#/definitions/ApplicationGetConfigResults'}},
+                                           'type': 'object'},
+                    'IsExposed': {'properties': {'Params': {'$ref': '#/definitions/Entities'},
+                                                 'Result': {'$ref': '#/definitions/BoolResults'}},
                                   'type': 'object'},
                                   'type': 'object'},
-                     'ModelSLAInfo': {'additionalProperties': False,
-                                      'properties': {'level': {'type': 'string'},
-                                                     'owner': {'type': 'string'}},
-                                      'required': ['level', 'owner'],
-                                      'type': 'object'},
-                     'ModelSet': {'additionalProperties': False,
-                                  'properties': {'config': {'patternProperties': {'.*': {'additionalProperties': True,
-                                                                                         'type': 'object'}},
-                                                            'type': 'object'}},
-                                  'required': ['config'],
+                    'Life': {'properties': {'Params': {'$ref': '#/definitions/Entities'},
+                                            'Result': {'$ref': '#/definitions/LifeResults'}},
+                             'type': 'object'},
+                    'Watch': {'properties': {'Params': {'$ref': '#/definitions/Entities'},
+                                             'Result': {'$ref': '#/definitions/NotifyWatchResults'}},
+                              'type': 'object'},
+                    'WatchApplications': {'properties': {'Result': {'$ref': '#/definitions/StringsWatchResult'}},
+                                          'type': 'object'}},
+     'type': 'object'}
+    
+
+    @ReturnMapping(ApplicationGetConfigResults)
+    async def ApplicationsConfig(self, entities):
+        '''
+        entities : typing.Sequence[~Entity]
+        Returns -> typing.Sequence[~ConfigResult]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASFirewaller',
+                   request='ApplicationsConfig',
+                   version=1,
+                   params=_params)
+        _params['entities'] = entities
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(BoolResults)
+    async def IsExposed(self, entities):
+        '''
+        entities : typing.Sequence[~Entity]
+        Returns -> typing.Sequence[~BoolResult]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASFirewaller',
+                   request='IsExposed',
+                   version=1,
+                   params=_params)
+        _params['entities'] = entities
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(LifeResults)
+    async def Life(self, entities):
+        '''
+        entities : typing.Sequence[~Entity]
+        Returns -> typing.Sequence[~LifeResult]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASFirewaller',
+                   request='Life',
+                   version=1,
+                   params=_params)
+        _params['entities'] = entities
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(NotifyWatchResults)
+    async def Watch(self, entities):
+        '''
+        entities : typing.Sequence[~Entity]
+        Returns -> typing.Sequence[~NotifyWatchResult]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASFirewaller',
+                   request='Watch',
+                   version=1,
+                   params=_params)
+        _params['entities'] = entities
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(StringsWatchResult)
+    async def WatchApplications(self):
+        '''
+
+        Returns -> typing.Union[typing.Sequence[str], _ForwardRef('Error'), str]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASFirewaller',
+                   request='WatchApplications',
+                   version=1,
+                   params=_params)
+
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+class CAASOperatorFacade(Type):
+    name = 'CAASOperator'
+    version = 1
+    schema =     {'definitions': {'APIHostPortsResult': {'additionalProperties': False,
+                                            'properties': {'servers': {'items': {'items': {'$ref': '#/definitions/HostPort'},
+                                                                                 'type': 'array'},
+                                                                       'type': 'array'}},
+                                            'required': ['servers'],
+                                            'type': 'object'},
+                     'Address': {'additionalProperties': False,
+                                 'properties': {'scope': {'type': 'string'},
+                                                'space-name': {'type': 'string'},
+                                                'type': {'type': 'string'},
+                                                'value': {'type': 'string'}},
+                                 'required': ['value', 'type', 'scope'],
+                                 'type': 'object'},
+                     'ApplicationCharm': {'additionalProperties': False,
+                                          'properties': {'charm-modified-version': {'type': 'integer'},
+                                                         'force-upgrade': {'type': 'boolean'},
+                                                         'sha256': {'type': 'string'},
+                                                         'url': {'type': 'string'}},
+                                          'required': ['url',
+                                                       'sha256',
+                                                       'charm-modified-version'],
+                                          'type': 'object'},
+                     'ApplicationCharmResult': {'additionalProperties': False,
+                                                'properties': {'error': {'$ref': '#/definitions/Error'},
+                                                               'result': {'$ref': '#/definitions/ApplicationCharm'}},
+                                                'type': 'object'},
+                     'ApplicationCharmResults': {'additionalProperties': False,
+                                                 'properties': {'results': {'items': {'$ref': '#/definitions/ApplicationCharmResult'},
+                                                                            'type': 'array'}},
+                                                 'required': ['results'],
+                                                 'type': 'object'},
+                     'Binary': {'additionalProperties': False,
+                                'properties': {'Arch': {'type': 'string'},
+                                               'Number': {'$ref': '#/definitions/Number'},
+                                               'Series': {'type': 'string'}},
+                                'required': ['Number', 'Series', 'Arch'],
+                                'type': 'object'},
+                     'Entities': {'additionalProperties': False,
+                                  'properties': {'entities': {'items': {'$ref': '#/definitions/Entity'},
+                                                              'type': 'array'}},
+                                  'required': ['entities'],
                                   'type': 'object'},
                                   'type': 'object'},
-                     'ModelStatusInfo': {'additionalProperties': False,
-                                         'properties': {'available-version': {'type': 'string'},
-                                                        'cloud-tag': {'type': 'string'},
-                                                        'meter-status': {'$ref': '#/definitions/MeterStatus'},
-                                                        'model-status': {'$ref': '#/definitions/DetailedStatus'},
-                                                        'name': {'type': 'string'},
-                                                        'region': {'type': 'string'},
-                                                        'sla': {'type': 'string'},
-                                                        'version': {'type': 'string'}},
-                                         'required': ['name',
-                                                      'cloud-tag',
-                                                      'version',
-                                                      'available-version',
-                                                      'model-status',
-                                                      'meter-status',
-                                                      'sla'],
+                     'EntitiesVersion': {'additionalProperties': False,
+                                         'properties': {'agent-tools': {'items': {'$ref': '#/definitions/EntityVersion'},
+                                                                        'type': 'array'}},
+                                         'required': ['agent-tools'],
                                          'type': 'object'},
                                          'type': 'object'},
-                     'ModelUnset': {'additionalProperties': False,
-                                    'properties': {'keys': {'items': {'type': 'string'},
-                                                            'type': 'array'}},
-                                    'required': ['keys'],
-                                    'type': 'object'},
-                     'ModelUserInfo': {'additionalProperties': False,
-                                       'properties': {'access': {'type': 'string'},
-                                                      'display-name': {'type': 'string'},
-                                                      'last-connection': {'format': 'date-time',
-                                                                          'type': 'string'},
-                                                      'user': {'type': 'string'}},
-                                       'required': ['user',
-                                                    'display-name',
-                                                    'last-connection',
-                                                    'access'],
-                                       'type': 'object'},
-                     'ModelUserInfoResult': {'additionalProperties': False,
-                                             'properties': {'error': {'$ref': '#/definitions/Error'},
-                                                            'result': {'$ref': '#/definitions/ModelUserInfo'}},
-                                             'type': 'object'},
-                     'ModelUserInfoResults': {'additionalProperties': False,
-                                              'properties': {'results': {'items': {'$ref': '#/definitions/ModelUserInfoResult'},
-                                                                         'type': 'array'}},
-                                              'required': ['results'],
-                                              'type': 'object'},
-                     'NetworkInterface': {'additionalProperties': False,
-                                          'properties': {'dns-nameservers': {'items': {'type': 'string'},
-                                                                             'type': 'array'},
-                                                         'gateway': {'type': 'string'},
-                                                         'ip-addresses': {'items': {'type': 'string'},
-                                                                          'type': 'array'},
-                                                         'is-up': {'type': 'boolean'},
-                                                         'mac-address': {'type': 'string'},
-                                                         'space': {'type': 'string'}},
-                                          'required': ['ip-addresses',
-                                                       'mac-address',
-                                                       'is-up'],
-                                          'type': 'object'},
-                     'Number': {'additionalProperties': False,
-                                'properties': {'Build': {'type': 'integer'},
-                                               'Major': {'type': 'integer'},
-                                               'Minor': {'type': 'integer'},
-                                               'Patch': {'type': 'integer'},
-                                               'Tag': {'type': 'string'}},
-                                'required': ['Major',
-                                             'Minor',
-                                             'Tag',
-                                             'Patch',
-                                             'Build'],
+                     'Entity': {'additionalProperties': False,
+                                'properties': {'tag': {'type': 'string'}},
+                                'required': ['tag'],
                                 'type': 'object'},
                                 'type': 'object'},
-                     'Placement': {'additionalProperties': False,
-                                   'properties': {'directive': {'type': 'string'},
-                                                  'scope': {'type': 'string'}},
-                                   'required': ['scope', 'directive'],
+                     'EntityStatusArgs': {'additionalProperties': False,
+                                          'properties': {'data': {'patternProperties': {'.*': {'additionalProperties': True,
+                                                                                               'type': 'object'}},
+                                                                  'type': 'object'},
+                                                         'info': {'type': 'string'},
+                                                         'status': {'type': 'string'},
+                                                         'tag': {'type': 'string'}},
+                                          'required': ['tag',
+                                                       'status',
+                                                       'info',
+                                                       'data'],
+                                          'type': 'object'},
+                     'EntityString': {'additionalProperties': False,
+                                      'properties': {'tag': {'type': 'string'},
+                                                     'value': {'type': 'string'}},
+                                      'required': ['tag', 'value'],
+                                      'type': 'object'},
+                     'EntityVersion': {'additionalProperties': False,
+                                       'properties': {'tag': {'type': 'string'},
+                                                      'tools': {'$ref': '#/definitions/Version'}},
+                                       'required': ['tag', 'tools'],
+                                       'type': 'object'},
+                     'Error': {'additionalProperties': False,
+                               'properties': {'code': {'type': 'string'},
+                                              'info': {'$ref': '#/definitions/ErrorInfo'},
+                                              'message': {'type': 'string'}},
+                               'required': ['message', 'code'],
+                               'type': 'object'},
+                     'ErrorInfo': {'additionalProperties': False,
+                                   'properties': {'macaroon': {'$ref': '#/definitions/Macaroon'},
+                                                  'macaroon-path': {'type': 'string'}},
                                    'type': 'object'},
                                    'type': 'object'},
-                     'PrivateAddress': {'additionalProperties': False,
+                     'ErrorResult': {'additionalProperties': False,
+                                     'properties': {'error': {'$ref': '#/definitions/Error'}},
+                                     'type': 'object'},
+                     'ErrorResults': {'additionalProperties': False,
+                                      'properties': {'results': {'items': {'$ref': '#/definitions/ErrorResult'},
+                                                                 'type': 'array'}},
+                                      'required': ['results'],
+                                      'type': 'object'},
+                     'HostPort': {'additionalProperties': False,
+                                  'properties': {'Address': {'$ref': '#/definitions/Address'},
+                                                 'port': {'type': 'integer'}},
+                                  'required': ['Address', 'port'],
+                                  'type': 'object'},
+                     'LifeResult': {'additionalProperties': False,
+                                    'properties': {'error': {'$ref': '#/definitions/Error'},
+                                                   'life': {'type': 'string'}},
+                                    'required': ['life'],
+                                    'type': 'object'},
+                     'LifeResults': {'additionalProperties': False,
+                                     'properties': {'results': {'items': {'$ref': '#/definitions/LifeResult'},
+                                                                'type': 'array'}},
+                                     'required': ['results'],
+                                     'type': 'object'},
+                     'Macaroon': {'additionalProperties': False, 'type': 'object'},
+                     'ModelResult': {'additionalProperties': False,
+                                     'properties': {'error': {'$ref': '#/definitions/Error'},
+                                                    'name': {'type': 'string'},
+                                                    'type': {'type': 'string'},
+                                                    'uuid': {'type': 'string'}},
+                                     'required': ['name', 'uuid', 'type'],
+                                     'type': 'object'},
+                     'NotifyWatchResult': {'additionalProperties': False,
+                                           'properties': {'NotifyWatcherId': {'type': 'string'},
+                                                          'error': {'$ref': '#/definitions/Error'}},
+                                           'required': ['NotifyWatcherId'],
+                                           'type': 'object'},
+                     'NotifyWatchResults': {'additionalProperties': False,
+                                            'properties': {'results': {'items': {'$ref': '#/definitions/NotifyWatchResult'},
+                                                                       'type': 'array'}},
+                                            'required': ['results'],
+                                            'type': 'object'},
+                     'Number': {'additionalProperties': False,
+                                'properties': {'Build': {'type': 'integer'},
+                                               'Major': {'type': 'integer'},
+                                               'Minor': {'type': 'integer'},
+                                               'Patch': {'type': 'integer'},
+                                               'Tag': {'type': 'string'}},
+                                'required': ['Major',
+                                             'Minor',
+                                             'Tag',
+                                             'Patch',
+                                             'Build'],
+                                'type': 'object'},
+                     'SetPodSpecParams': {'additionalProperties': False,
+                                          'properties': {'specs': {'items': {'$ref': '#/definitions/EntityString'},
+                                                                   'type': 'array'}},
+                                          'required': ['specs'],
+                                          'type': 'object'},
+                     'SetStatus': {'additionalProperties': False,
+                                   'properties': {'entities': {'items': {'$ref': '#/definitions/EntityStatusArgs'},
+                                                               'type': 'array'}},
+                                   'required': ['entities'],
+                                   'type': 'object'},
+                     'StringResult': {'additionalProperties': False,
+                                      'properties': {'error': {'$ref': '#/definitions/Error'},
+                                                     'result': {'type': 'string'}},
+                                      'required': ['result'],
+                                      'type': 'object'},
+                     'StringsResult': {'additionalProperties': False,
+                                       'properties': {'error': {'$ref': '#/definitions/Error'},
+                                                      'result': {'items': {'type': 'string'},
+                                                                 'type': 'array'}},
+                                       'type': 'object'},
+                     'StringsWatchResult': {'additionalProperties': False,
+                                            'properties': {'changes': {'items': {'type': 'string'},
+                                                                       'type': 'array'},
+                                                           'error': {'$ref': '#/definitions/Error'},
+                                                           'watcher-id': {'type': 'string'}},
+                                            'required': ['watcher-id'],
+                                            'type': 'object'},
+                     'StringsWatchResults': {'additionalProperties': False,
+                                             'properties': {'results': {'items': {'$ref': '#/definitions/StringsWatchResult'},
+                                                                        'type': 'array'}},
+                                             'required': ['results'],
+                                             'type': 'object'},
+                     'Version': {'additionalProperties': False,
+                                 'properties': {'version': {'$ref': '#/definitions/Binary'}},
+                                 'required': ['version'],
+                                 'type': 'object'}},
+     'properties': {'APIAddresses': {'properties': {'Result': {'$ref': '#/definitions/StringsResult'}},
+                                     'type': 'object'},
+                    'APIHostPorts': {'properties': {'Result': {'$ref': '#/definitions/APIHostPortsResult'}},
+                                     'type': 'object'},
+                    'Charm': {'properties': {'Params': {'$ref': '#/definitions/Entities'},
+                                             'Result': {'$ref': '#/definitions/ApplicationCharmResults'}},
+                              'type': 'object'},
+                    'CurrentModel': {'properties': {'Result': {'$ref': '#/definitions/ModelResult'}},
+                                     'type': 'object'},
+                    'Life': {'properties': {'Params': {'$ref': '#/definitions/Entities'},
+                                            'Result': {'$ref': '#/definitions/LifeResults'}},
+                             'type': 'object'},
+                    'ModelUUID': {'properties': {'Result': {'$ref': '#/definitions/StringResult'}},
+                                  'type': 'object'},
+                    'Remove': {'properties': {'Params': {'$ref': '#/definitions/Entities'},
+                                              'Result': {'$ref': '#/definitions/ErrorResults'}},
+                               'type': 'object'},
+                    'SetPodSpec': {'properties': {'Params': {'$ref': '#/definitions/SetPodSpecParams'},
+                                                  'Result': {'$ref': '#/definitions/ErrorResults'}},
+                                   'type': 'object'},
+                    'SetStatus': {'properties': {'Params': {'$ref': '#/definitions/SetStatus'},
+                                                 'Result': {'$ref': '#/definitions/ErrorResults'}},
+                                  'type': 'object'},
+                    'SetTools': {'properties': {'Params': {'$ref': '#/definitions/EntitiesVersion'},
+                                                'Result': {'$ref': '#/definitions/ErrorResults'}},
+                                 'type': 'object'},
+                    'Watch': {'properties': {'Params': {'$ref': '#/definitions/Entities'},
+                                             'Result': {'$ref': '#/definitions/NotifyWatchResults'}},
+                              'type': 'object'},
+                    'WatchAPIHostPorts': {'properties': {'Result': {'$ref': '#/definitions/NotifyWatchResult'}},
+                                          'type': 'object'},
+                    'WatchUnits': {'properties': {'Params': {'$ref': '#/definitions/Entities'},
+                                                  'Result': {'$ref': '#/definitions/StringsWatchResults'}},
+                                   'type': 'object'}},
+     'type': 'object'}
+    
+
+    @ReturnMapping(StringsResult)
+    async def APIAddresses(self):
+        '''
+
+        Returns -> typing.Union[_ForwardRef('Error'), typing.Sequence[str]]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASOperator',
+                   request='APIAddresses',
+                   version=1,
+                   params=_params)
+
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(APIHostPortsResult)
+    async def APIHostPorts(self):
+        '''
+
+        Returns -> typing.Sequence[~HostPort]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASOperator',
+                   request='APIHostPorts',
+                   version=1,
+                   params=_params)
+
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(ApplicationCharmResults)
+    async def Charm(self, entities):
+        '''
+        entities : typing.Sequence[~Entity]
+        Returns -> typing.Sequence[~ApplicationCharmResult]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASOperator',
+                   request='Charm',
+                   version=1,
+                   params=_params)
+        _params['entities'] = entities
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(ModelResult)
+    async def CurrentModel(self):
+        '''
+
+        Returns -> typing.Union[_ForwardRef('Error'), str]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASOperator',
+                   request='CurrentModel',
+                   version=1,
+                   params=_params)
+
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(LifeResults)
+    async def Life(self, entities):
+        '''
+        entities : typing.Sequence[~Entity]
+        Returns -> typing.Sequence[~LifeResult]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASOperator',
+                   request='Life',
+                   version=1,
+                   params=_params)
+        _params['entities'] = entities
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(StringResult)
+    async def ModelUUID(self):
+        '''
+
+        Returns -> typing.Union[_ForwardRef('Error'), str]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASOperator',
+                   request='ModelUUID',
+                   version=1,
+                   params=_params)
+
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(ErrorResults)
+    async def Remove(self, entities):
+        '''
+        entities : typing.Sequence[~Entity]
+        Returns -> typing.Sequence[~ErrorResult]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASOperator',
+                   request='Remove',
+                   version=1,
+                   params=_params)
+        _params['entities'] = entities
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(ErrorResults)
+    async def SetPodSpec(self, specs):
+        '''
+        specs : typing.Sequence[~EntityString]
+        Returns -> typing.Sequence[~ErrorResult]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASOperator',
+                   request='SetPodSpec',
+                   version=1,
+                   params=_params)
+        _params['specs'] = specs
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(ErrorResults)
+    async def SetStatus(self, entities):
+        '''
+        entities : typing.Sequence[~EntityStatusArgs]
+        Returns -> typing.Sequence[~ErrorResult]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASOperator',
+                   request='SetStatus',
+                   version=1,
+                   params=_params)
+        _params['entities'] = entities
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(ErrorResults)
+    async def SetTools(self, agent_tools):
+        '''
+        agent_tools : typing.Sequence[~EntityVersion]
+        Returns -> typing.Sequence[~ErrorResult]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASOperator',
+                   request='SetTools',
+                   version=1,
+                   params=_params)
+        _params['agent-tools'] = agent_tools
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(NotifyWatchResults)
+    async def Watch(self, entities):
+        '''
+        entities : typing.Sequence[~Entity]
+        Returns -> typing.Sequence[~NotifyWatchResult]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASOperator',
+                   request='Watch',
+                   version=1,
+                   params=_params)
+        _params['entities'] = entities
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(NotifyWatchResult)
+    async def WatchAPIHostPorts(self):
+        '''
+
+        Returns -> typing.Union[str, _ForwardRef('Error')]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASOperator',
+                   request='WatchAPIHostPorts',
+                   version=1,
+                   params=_params)
+
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(StringsWatchResults)
+    async def WatchUnits(self, entities):
+        '''
+        entities : typing.Sequence[~Entity]
+        Returns -> typing.Sequence[~StringsWatchResult]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASOperator',
+                   request='WatchUnits',
+                   version=1,
+                   params=_params)
+        _params['entities'] = entities
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+class CAASOperatorProvisionerFacade(Type):
+    name = 'CAASOperatorProvisioner'
+    version = 1
+    schema =     {'definitions': {'APIHostPortsResult': {'additionalProperties': False,
+                                            'properties': {'servers': {'items': {'items': {'$ref': '#/definitions/HostPort'},
+                                                                                 'type': 'array'},
+                                                                       'type': 'array'}},
+                                            'required': ['servers'],
+                                            'type': 'object'},
+                     'Address': {'additionalProperties': False,
+                                 'properties': {'scope': {'type': 'string'},
+                                                'space-name': {'type': 'string'},
+                                                'type': {'type': 'string'},
+                                                'value': {'type': 'string'}},
+                                 'required': ['value', 'type', 'scope'],
+                                 'type': 'object'},
+                     'Entities': {'additionalProperties': False,
+                                  'properties': {'entities': {'items': {'$ref': '#/definitions/Entity'},
+                                                              'type': 'array'}},
+                                  'required': ['entities'],
+                                  'type': 'object'},
+                     'Entity': {'additionalProperties': False,
+                                'properties': {'tag': {'type': 'string'}},
+                                'required': ['tag'],
+                                'type': 'object'},
+                     'EntityPassword': {'additionalProperties': False,
+                                        'properties': {'password': {'type': 'string'},
+                                                       'tag': {'type': 'string'}},
+                                        'required': ['tag', 'password'],
+                                        'type': 'object'},
+                     'EntityPasswords': {'additionalProperties': False,
+                                         'properties': {'changes': {'items': {'$ref': '#/definitions/EntityPassword'},
+                                                                    'type': 'array'}},
+                                         'required': ['changes'],
+                                         'type': 'object'},
+                     'Error': {'additionalProperties': False,
+                               'properties': {'code': {'type': 'string'},
+                                              'info': {'$ref': '#/definitions/ErrorInfo'},
+                                              'message': {'type': 'string'}},
+                               'required': ['message', 'code'],
+                               'type': 'object'},
+                     'ErrorInfo': {'additionalProperties': False,
+                                   'properties': {'macaroon': {'$ref': '#/definitions/Macaroon'},
+                                                  'macaroon-path': {'type': 'string'}},
+                                   'type': 'object'},
+                     'ErrorResult': {'additionalProperties': False,
+                                     'properties': {'error': {'$ref': '#/definitions/Error'}},
+                                     'type': 'object'},
+                     'ErrorResults': {'additionalProperties': False,
+                                      'properties': {'results': {'items': {'$ref': '#/definitions/ErrorResult'},
+                                                                 'type': 'array'}},
+                                      'required': ['results'],
+                                      'type': 'object'},
+                     'HostPort': {'additionalProperties': False,
+                                  'properties': {'Address': {'$ref': '#/definitions/Address'},
+                                                 'port': {'type': 'integer'}},
+                                  'required': ['Address', 'port'],
+                                  'type': 'object'},
+                     'KubernetesFilesystemAttachmentParams': {'additionalProperties': False,
+                                                              'properties': {'mount-point': {'type': 'string'},
+                                                                             'provider': {'type': 'string'},
+                                                                             'read-only': {'type': 'boolean'}},
+                                                              'required': ['provider'],
+                                                              'type': 'object'},
+                     'KubernetesFilesystemParams': {'additionalProperties': False,
+                                                    'properties': {'attachment': {'$ref': '#/definitions/KubernetesFilesystemAttachmentParams'},
+                                                                   'attributes': {'patternProperties': {'.*': {'additionalProperties': True,
+                                                                                                               'type': 'object'}},
+                                                                                  'type': 'object'},
+                                                                   'provider': {'type': 'string'},
+                                                                   'size': {'type': 'integer'},
+                                                                   'storagename': {'type': 'string'},
+                                                                   'tags': {'patternProperties': {'.*': {'type': 'string'}},
+                                                                            'type': 'object'}},
+                                                    'required': ['storagename',
+                                                                 'size',
+                                                                 'provider'],
+                                                    'type': 'object'},
+                     'LifeResult': {'additionalProperties': False,
+                                    'properties': {'error': {'$ref': '#/definitions/Error'},
+                                                   'life': {'type': 'string'}},
+                                    'required': ['life'],
+                                    'type': 'object'},
+                     'LifeResults': {'additionalProperties': False,
+                                     'properties': {'results': {'items': {'$ref': '#/definitions/LifeResult'},
+                                                                'type': 'array'}},
+                                     'required': ['results'],
+                                     'type': 'object'},
+                     'Macaroon': {'additionalProperties': False, 'type': 'object'},
+                     'NotifyWatchResult': {'additionalProperties': False,
+                                           'properties': {'NotifyWatcherId': {'type': 'string'},
+                                                          'error': {'$ref': '#/definitions/Error'}},
+                                           'required': ['NotifyWatcherId'],
+                                           'type': 'object'},
+                     'Number': {'additionalProperties': False,
+                                'properties': {'Build': {'type': 'integer'},
+                                               'Major': {'type': 'integer'},
+                                               'Minor': {'type': 'integer'},
+                                               'Patch': {'type': 'integer'},
+                                               'Tag': {'type': 'string'}},
+                                'required': ['Major',
+                                             'Minor',
+                                             'Tag',
+                                             'Patch',
+                                             'Build'],
+                                'type': 'object'},
+                     'OperatorProvisioningInfo': {'additionalProperties': False,
+                                                  'properties': {'api-addresses': {'items': {'type': 'string'},
+                                                                                   'type': 'array'},
+                                                                 'charm-storage': {'$ref': '#/definitions/KubernetesFilesystemParams'},
+                                                                 'image-path': {'type': 'string'},
+                                                                 'tags': {'patternProperties': {'.*': {'type': 'string'}},
+                                                                          'type': 'object'},
+                                                                 'version': {'$ref': '#/definitions/Number'}},
+                                                  'required': ['image-path',
+                                                               'version',
+                                                               'api-addresses',
+                                                               'charm-storage'],
+                                                  'type': 'object'},
+                     'StringResult': {'additionalProperties': False,
+                                      'properties': {'error': {'$ref': '#/definitions/Error'},
+                                                     'result': {'type': 'string'}},
+                                      'required': ['result'],
+                                      'type': 'object'},
+                     'StringsResult': {'additionalProperties': False,
+                                       'properties': {'error': {'$ref': '#/definitions/Error'},
+                                                      'result': {'items': {'type': 'string'},
+                                                                 'type': 'array'}},
+                                       'type': 'object'},
+                     'StringsWatchResult': {'additionalProperties': False,
+                                            'properties': {'changes': {'items': {'type': 'string'},
+                                                                       'type': 'array'},
+                                                           'error': {'$ref': '#/definitions/Error'},
+                                                           'watcher-id': {'type': 'string'}},
+                                            'required': ['watcher-id'],
+                                            'type': 'object'}},
+     'properties': {'APIAddresses': {'properties': {'Result': {'$ref': '#/definitions/StringsResult'}},
+                                     'type': 'object'},
+                    'APIHostPorts': {'properties': {'Result': {'$ref': '#/definitions/APIHostPortsResult'}},
+                                     'type': 'object'},
+                    'Life': {'properties': {'Params': {'$ref': '#/definitions/Entities'},
+                                            'Result': {'$ref': '#/definitions/LifeResults'}},
+                             'type': 'object'},
+                    'ModelUUID': {'properties': {'Result': {'$ref': '#/definitions/StringResult'}},
+                                  'type': 'object'},
+                    'OperatorProvisioningInfo': {'properties': {'Result': {'$ref': '#/definitions/OperatorProvisioningInfo'}},
+                                                 'type': 'object'},
+                    'SetPasswords': {'properties': {'Params': {'$ref': '#/definitions/EntityPasswords'},
+                                                    'Result': {'$ref': '#/definitions/ErrorResults'}},
+                                     'type': 'object'},
+                    'WatchAPIHostPorts': {'properties': {'Result': {'$ref': '#/definitions/NotifyWatchResult'}},
+                                          'type': 'object'},
+                    'WatchApplications': {'properties': {'Result': {'$ref': '#/definitions/StringsWatchResult'}},
+                                          'type': 'object'}},
+     'type': 'object'}
+    
+
+    @ReturnMapping(StringsResult)
+    async def APIAddresses(self):
+        '''
+
+        Returns -> typing.Union[_ForwardRef('Error'), typing.Sequence[str]]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASOperatorProvisioner',
+                   request='APIAddresses',
+                   version=1,
+                   params=_params)
+
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(APIHostPortsResult)
+    async def APIHostPorts(self):
+        '''
+
+        Returns -> typing.Sequence[~HostPort]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASOperatorProvisioner',
+                   request='APIHostPorts',
+                   version=1,
+                   params=_params)
+
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(LifeResults)
+    async def Life(self, entities):
+        '''
+        entities : typing.Sequence[~Entity]
+        Returns -> typing.Sequence[~LifeResult]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASOperatorProvisioner',
+                   request='Life',
+                   version=1,
+                   params=_params)
+        _params['entities'] = entities
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(StringResult)
+    async def ModelUUID(self):
+        '''
+
+        Returns -> typing.Union[_ForwardRef('Error'), str]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASOperatorProvisioner',
+                   request='ModelUUID',
+                   version=1,
+                   params=_params)
+
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(OperatorProvisioningInfo)
+    async def OperatorProvisioningInfo(self):
+        '''
+
+        Returns -> typing.Union[typing.Sequence[str], _ForwardRef('KubernetesFilesystemParams'), str, typing.Mapping[str, str], _ForwardRef('Number')]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASOperatorProvisioner',
+                   request='OperatorProvisioningInfo',
+                   version=1,
+                   params=_params)
+
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(ErrorResults)
+    async def SetPasswords(self, changes):
+        '''
+        changes : typing.Sequence[~EntityPassword]
+        Returns -> typing.Sequence[~ErrorResult]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASOperatorProvisioner',
+                   request='SetPasswords',
+                   version=1,
+                   params=_params)
+        _params['changes'] = changes
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(NotifyWatchResult)
+    async def WatchAPIHostPorts(self):
+        '''
+
+        Returns -> typing.Union[str, _ForwardRef('Error')]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASOperatorProvisioner',
+                   request='WatchAPIHostPorts',
+                   version=1,
+                   params=_params)
+
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(StringsWatchResult)
+    async def WatchApplications(self):
+        '''
+
+        Returns -> typing.Union[typing.Sequence[str], _ForwardRef('Error'), str]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASOperatorProvisioner',
+                   request='WatchApplications',
+                   version=1,
+                   params=_params)
+
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+class CAASUnitProvisionerFacade(Type):
+    name = 'CAASUnitProvisioner'
+    version = 1
+    schema =     {'definitions': {'Address': {'additionalProperties': False,
+                                 'properties': {'scope': {'type': 'string'},
+                                                'space-name': {'type': 'string'},
+                                                'type': {'type': 'string'},
+                                                'value': {'type': 'string'}},
+                                 'required': ['value', 'type', 'scope'],
+                                 'type': 'object'},
+                     'ApplicationGetConfigResults': {'additionalProperties': False,
+                                                     'properties': {'Results': {'items': {'$ref': '#/definitions/ConfigResult'},
+                                                                                'type': 'array'}},
+                                                     'required': ['Results'],
+                                                     'type': 'object'},
+                     'ApplicationUnitParams': {'additionalProperties': False,
+                                               'properties': {'address': {'type': 'string'},
+                                                              'data': {'patternProperties': {'.*': {'additionalProperties': True,
+                                                                                                    'type': 'object'}},
+                                                                       'type': 'object'},
+                                                              'filesystem-info': {'items': {'$ref': '#/definitions/KubernetesFilesystemInfo'},
+                                                                                  'type': 'array'},
+                                                              'info': {'type': 'string'},
+                                                              'ports': {'items': {'type': 'string'},
+                                                                        'type': 'array'},
+                                                              'provider-id': {'type': 'string'},
+                                                              'status': {'type': 'string'},
+                                                              'unit-tag': {'type': 'string'}},
+                                               'required': ['provider-id',
+                                                            'unit-tag',
+                                                            'address',
+                                                            'ports',
+                                                            'status',
+                                                            'info'],
+                                               'type': 'object'},
+                     'ConfigResult': {'additionalProperties': False,
+                                      'properties': {'config': {'patternProperties': {'.*': {'additionalProperties': True,
+                                                                                             'type': 'object'}},
+                                                                'type': 'object'},
+                                                     'error': {'$ref': '#/definitions/Error'}},
+                                      'required': ['config'],
+                                      'type': 'object'},
+                     'Entities': {'additionalProperties': False,
+                                  'properties': {'entities': {'items': {'$ref': '#/definitions/Entity'},
+                                                              'type': 'array'}},
+                                  'required': ['entities'],
+                                  'type': 'object'},
+                     'Entity': {'additionalProperties': False,
+                                'properties': {'tag': {'type': 'string'}},
+                                'required': ['tag'],
+                                'type': 'object'},
+                     'EntityStatusArgs': {'additionalProperties': False,
+                                          'properties': {'data': {'patternProperties': {'.*': {'additionalProperties': True,
+                                                                                               'type': 'object'}},
+                                                                  'type': 'object'},
+                                                         'info': {'type': 'string'},
+                                                         'status': {'type': 'string'},
+                                                         'tag': {'type': 'string'}},
+                                          'required': ['tag',
+                                                       'status',
+                                                       'info',
+                                                       'data'],
+                                          'type': 'object'},
+                     'Error': {'additionalProperties': False,
+                               'properties': {'code': {'type': 'string'},
+                                              'info': {'$ref': '#/definitions/ErrorInfo'},
+                                              'message': {'type': 'string'}},
+                               'required': ['message', 'code'],
+                               'type': 'object'},
+                     'ErrorInfo': {'additionalProperties': False,
+                                   'properties': {'macaroon': {'$ref': '#/definitions/Macaroon'},
+                                                  'macaroon-path': {'type': 'string'}},
+                                   'type': 'object'},
+                     'ErrorResult': {'additionalProperties': False,
+                                     'properties': {'error': {'$ref': '#/definitions/Error'}},
+                                     'type': 'object'},
+                     'ErrorResults': {'additionalProperties': False,
+                                      'properties': {'results': {'items': {'$ref': '#/definitions/ErrorResult'},
+                                                                 'type': 'array'}},
+                                      'required': ['results'],
+                                      'type': 'object'},
+                     'IntResult': {'additionalProperties': False,
+                                   'properties': {'error': {'$ref': '#/definitions/Error'},
+                                                  'result': {'type': 'integer'}},
+                                   'required': ['result'],
+                                   'type': 'object'},
+                     'IntResults': {'additionalProperties': False,
+                                    'properties': {'results': {'items': {'$ref': '#/definitions/IntResult'},
+                                                               'type': 'array'}},
+                                    'required': ['results'],
+                                    'type': 'object'},
+                     'KubernetesDeviceParams': {'additionalProperties': False,
+                                                'properties': {'Attributes': {'patternProperties': {'.*': {'type': 'string'}},
+                                                                              'type': 'object'},
+                                                               'Count': {'type': 'integer'},
+                                                               'Type': {'type': 'string'}},
+                                                'required': ['Type',
+                                                             'Count',
+                                                             'Attributes'],
+                                                'type': 'object'},
+                     'KubernetesFilesystemAttachmentParams': {'additionalProperties': False,
+                                                              'properties': {'mount-point': {'type': 'string'},
+                                                                             'provider': {'type': 'string'},
+                                                                             'read-only': {'type': 'boolean'}},
+                                                              'required': ['provider'],
+                                                              'type': 'object'},
+                     'KubernetesFilesystemInfo': {'additionalProperties': False,
+                                                  'properties': {'data': {'patternProperties': {'.*': {'additionalProperties': True,
+                                                                                                       'type': 'object'}},
+                                                                          'type': 'object'},
+                                                                 'filesystem-id': {'type': 'string'},
+                                                                 'info': {'type': 'string'},
+                                                                 'mount-point': {'type': 'string'},
+                                                                 'pool': {'type': 'string'},
+                                                                 'read-only': {'type': 'boolean'},
+                                                                 'size': {'type': 'integer'},
+                                                                 'status': {'type': 'string'},
+                                                                 'storagename': {'type': 'string'},
+                                                                 'volume': {'$ref': '#/definitions/KubernetesVolumeInfo'}},
+                                                  'required': ['storagename',
+                                                               'pool',
+                                                               'size',
+                                                               'filesystem-id',
+                                                               'status',
+                                                               'info',
+                                                               'volume'],
+                                                  'type': 'object'},
+                     'KubernetesFilesystemParams': {'additionalProperties': False,
+                                                    'properties': {'attachment': {'$ref': '#/definitions/KubernetesFilesystemAttachmentParams'},
+                                                                   'attributes': {'patternProperties': {'.*': {'additionalProperties': True,
+                                                                                                               'type': 'object'}},
+                                                                                  'type': 'object'},
+                                                                   'provider': {'type': 'string'},
+                                                                   'size': {'type': 'integer'},
+                                                                   'storagename': {'type': 'string'},
+                                                                   'tags': {'patternProperties': {'.*': {'type': 'string'}},
+                                                                            'type': 'object'}},
+                                                    'required': ['storagename',
+                                                                 'size',
+                                                                 'provider'],
+                                                    'type': 'object'},
+                     'KubernetesProvisioningInfo': {'additionalProperties': False,
+                                                    'properties': {'constraints': {'$ref': '#/definitions/Value'},
+                                                                   'devices': {'items': {'$ref': '#/definitions/KubernetesDeviceParams'},
+                                                                               'type': 'array'},
+                                                                   'filesystems': {'items': {'$ref': '#/definitions/KubernetesFilesystemParams'},
+                                                                                   'type': 'array'},
+                                                                   'placement': {'type': 'string'},
+                                                                   'pod-spec': {'type': 'string'},
+                                                                   'tags': {'patternProperties': {'.*': {'type': 'string'}},
+                                                                            'type': 'object'},
+                                                                   'volumes': {'items': {'$ref': '#/definitions/KubernetesVolumeParams'},
+                                                                               'type': 'array'}},
+                                                    'required': ['pod-spec',
+                                                                 'constraints'],
+                                                    'type': 'object'},
+                     'KubernetesProvisioningInfoResult': {'additionalProperties': False,
+                                                          'properties': {'error': {'$ref': '#/definitions/Error'},
+                                                                         'result': {'$ref': '#/definitions/KubernetesProvisioningInfo'}},
+                                                          'required': ['result'],
+                                                          'type': 'object'},
+                     'KubernetesProvisioningInfoResults': {'additionalProperties': False,
+                                                           'properties': {'results': {'items': {'$ref': '#/definitions/KubernetesProvisioningInfoResult'},
+                                                                                      'type': 'array'}},
+                                                           'required': ['results'],
+                                                           'type': 'object'},
+                     'KubernetesVolumeAttachmentParams': {'additionalProperties': False,
+                                                          'properties': {'provider': {'type': 'string'},
+                                                                         'read-only': {'type': 'boolean'}},
+                                                          'required': ['provider'],
+                                                          'type': 'object'},
+                     'KubernetesVolumeInfo': {'additionalProperties': False,
+                                              'properties': {'data': {'patternProperties': {'.*': {'additionalProperties': True,
+                                                                                                   'type': 'object'}},
+                                                                      'type': 'object'},
+                                                             'info': {'type': 'string'},
+                                                             'persistent': {'type': 'boolean'},
+                                                             'pool': {'type': 'string'},
+                                                             'size': {'type': 'integer'},
+                                                             'status': {'type': 'string'},
+                                                             'volume-id': {'type': 'string'}},
+                                              'required': ['volume-id',
+                                                           'size',
+                                                           'persistent',
+                                                           'status',
+                                                           'info'],
+                                              'type': 'object'},
+                     'KubernetesVolumeParams': {'additionalProperties': False,
+                                                'properties': {'attachment': {'$ref': '#/definitions/KubernetesVolumeAttachmentParams'},
+                                                               'attributes': {'patternProperties': {'.*': {'additionalProperties': True,
+                                                                                                           'type': 'object'}},
+                                                                              'type': 'object'},
+                                                               'provider': {'type': 'string'},
+                                                               'size': {'type': 'integer'},
+                                                               'storagename': {'type': 'string'},
+                                                               'tags': {'patternProperties': {'.*': {'type': 'string'}},
+                                                                        'type': 'object'}},
+                                                'required': ['storagename',
+                                                             'size',
+                                                             'provider'],
+                                                'type': 'object'},
+                     'LifeResult': {'additionalProperties': False,
+                                    'properties': {'error': {'$ref': '#/definitions/Error'},
+                                                   'life': {'type': 'string'}},
+                                    'required': ['life'],
+                                    'type': 'object'},
+                     'LifeResults': {'additionalProperties': False,
+                                     'properties': {'results': {'items': {'$ref': '#/definitions/LifeResult'},
+                                                                'type': 'array'}},
+                                     'required': ['results'],
+                                     'type': 'object'},
+                     'Macaroon': {'additionalProperties': False, 'type': 'object'},
+                     'NotifyWatchResult': {'additionalProperties': False,
+                                           'properties': {'NotifyWatcherId': {'type': 'string'},
+                                                          'error': {'$ref': '#/definitions/Error'}},
+                                           'required': ['NotifyWatcherId'],
+                                           'type': 'object'},
+                     'NotifyWatchResults': {'additionalProperties': False,
+                                            'properties': {'results': {'items': {'$ref': '#/definitions/NotifyWatchResult'},
+                                                                       'type': 'array'}},
+                                            'required': ['results'],
+                                            'type': 'object'},
+                     'SetStatus': {'additionalProperties': False,
+                                   'properties': {'entities': {'items': {'$ref': '#/definitions/EntityStatusArgs'},
+                                                               'type': 'array'}},
+                                   'required': ['entities'],
+                                   'type': 'object'},
+                     'StringsWatchResult': {'additionalProperties': False,
+                                            'properties': {'changes': {'items': {'type': 'string'},
+                                                                       'type': 'array'},
+                                                           'error': {'$ref': '#/definitions/Error'},
+                                                           'watcher-id': {'type': 'string'}},
+                                            'required': ['watcher-id'],
+                                            'type': 'object'},
+                     'UpdateApplicationServiceArg': {'additionalProperties': False,
+                                                     'properties': {'addresses': {'items': {'$ref': '#/definitions/Address'},
+                                                                                  'type': 'array'},
+                                                                    'application-tag': {'type': 'string'},
+                                                                    'provider-id': {'type': 'string'}},
+                                                     'required': ['application-tag',
+                                                                  'provider-id',
+                                                                  'addresses'],
+                                                     'type': 'object'},
+                     'UpdateApplicationServiceArgs': {'additionalProperties': False,
+                                                      'properties': {'args': {'items': {'$ref': '#/definitions/UpdateApplicationServiceArg'},
+                                                                              'type': 'array'}},
+                                                      'required': ['args'],
+                                                      'type': 'object'},
+                     'UpdateApplicationUnitArgs': {'additionalProperties': False,
+                                                   'properties': {'args': {'items': {'$ref': '#/definitions/UpdateApplicationUnits'},
+                                                                           'type': 'array'}},
+                                                   'required': ['args'],
+                                                   'type': 'object'},
+                     'UpdateApplicationUnits': {'additionalProperties': False,
+                                                'properties': {'application-tag': {'type': 'string'},
+                                                               'units': {'items': {'$ref': '#/definitions/ApplicationUnitParams'},
+                                                                         'type': 'array'}},
+                                                'required': ['application-tag',
+                                                             'units'],
+                                                'type': 'object'},
+                     'Value': {'additionalProperties': False,
+                               'properties': {'arch': {'type': 'string'},
+                                              'container': {'type': 'string'},
+                                              'cores': {'type': 'integer'},
+                                              'cpu-power': {'type': 'integer'},
+                                              'instance-type': {'type': 'string'},
+                                              'mem': {'type': 'integer'},
+                                              'root-disk': {'type': 'integer'},
+                                              'spaces': {'items': {'type': 'string'},
+                                                         'type': 'array'},
+                                              'tags': {'items': {'type': 'string'},
+                                                       'type': 'array'},
+                                              'virt-type': {'type': 'string'},
+                                              'zones': {'items': {'type': 'string'},
+                                                        'type': 'array'}},
+                               'type': 'object'}},
+     'properties': {'ApplicationsConfig': {'properties': {'Params': {'$ref': '#/definitions/Entities'},
+                                                          'Result': {'$ref': '#/definitions/ApplicationGetConfigResults'}},
+                                           'type': 'object'},
+                    'ApplicationsScale': {'properties': {'Params': {'$ref': '#/definitions/Entities'},
+                                                         'Result': {'$ref': '#/definitions/IntResults'}},
+                                          'type': 'object'},
+                    'Life': {'properties': {'Params': {'$ref': '#/definitions/Entities'},
+                                            'Result': {'$ref': '#/definitions/LifeResults'}},
+                             'type': 'object'},
+                    'ProvisioningInfo': {'properties': {'Params': {'$ref': '#/definitions/Entities'},
+                                                        'Result': {'$ref': '#/definitions/KubernetesProvisioningInfoResults'}},
+                                         'type': 'object'},
+                    'SetOperatorStatus': {'properties': {'Params': {'$ref': '#/definitions/SetStatus'},
+                                                         'Result': {'$ref': '#/definitions/ErrorResults'}},
+                                          'type': 'object'},
+                    'UpdateApplicationsService': {'properties': {'Params': {'$ref': '#/definitions/UpdateApplicationServiceArgs'},
+                                                                 'Result': {'$ref': '#/definitions/ErrorResults'}},
+                                                  'type': 'object'},
+                    'UpdateApplicationsUnits': {'properties': {'Params': {'$ref': '#/definitions/UpdateApplicationUnitArgs'},
+                                                               'Result': {'$ref': '#/definitions/ErrorResults'}},
+                                                'type': 'object'},
+                    'WatchApplications': {'properties': {'Result': {'$ref': '#/definitions/StringsWatchResult'}},
+                                          'type': 'object'},
+                    'WatchApplicationsScale': {'properties': {'Params': {'$ref': '#/definitions/Entities'},
+                                                              'Result': {'$ref': '#/definitions/NotifyWatchResults'}},
+                                               'type': 'object'},
+                    'WatchPodSpec': {'properties': {'Params': {'$ref': '#/definitions/Entities'},
+                                                    'Result': {'$ref': '#/definitions/NotifyWatchResults'}},
+                                     'type': 'object'}},
+     'type': 'object'}
+    
+
+    @ReturnMapping(ApplicationGetConfigResults)
+    async def ApplicationsConfig(self, entities):
+        '''
+        entities : typing.Sequence[~Entity]
+        Returns -> typing.Sequence[~ConfigResult]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASUnitProvisioner',
+                   request='ApplicationsConfig',
+                   version=1,
+                   params=_params)
+        _params['entities'] = entities
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(IntResults)
+    async def ApplicationsScale(self, entities):
+        '''
+        entities : typing.Sequence[~Entity]
+        Returns -> typing.Sequence[~IntResult]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASUnitProvisioner',
+                   request='ApplicationsScale',
+                   version=1,
+                   params=_params)
+        _params['entities'] = entities
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(LifeResults)
+    async def Life(self, entities):
+        '''
+        entities : typing.Sequence[~Entity]
+        Returns -> typing.Sequence[~LifeResult]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASUnitProvisioner',
+                   request='Life',
+                   version=1,
+                   params=_params)
+        _params['entities'] = entities
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(KubernetesProvisioningInfoResults)
+    async def ProvisioningInfo(self, entities):
+        '''
+        entities : typing.Sequence[~Entity]
+        Returns -> typing.Sequence[~KubernetesProvisioningInfoResult]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASUnitProvisioner',
+                   request='ProvisioningInfo',
+                   version=1,
+                   params=_params)
+        _params['entities'] = entities
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(ErrorResults)
+    async def SetOperatorStatus(self, entities):
+        '''
+        entities : typing.Sequence[~EntityStatusArgs]
+        Returns -> typing.Sequence[~ErrorResult]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASUnitProvisioner',
+                   request='SetOperatorStatus',
+                   version=1,
+                   params=_params)
+        _params['entities'] = entities
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(ErrorResults)
+    async def UpdateApplicationsService(self, args):
+        '''
+        args : typing.Sequence[~UpdateApplicationServiceArg]
+        Returns -> typing.Sequence[~ErrorResult]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASUnitProvisioner',
+                   request='UpdateApplicationsService',
+                   version=1,
+                   params=_params)
+        _params['args'] = args
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(ErrorResults)
+    async def UpdateApplicationsUnits(self, args):
+        '''
+        args : typing.Sequence[~UpdateApplicationUnits]
+        Returns -> typing.Sequence[~ErrorResult]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASUnitProvisioner',
+                   request='UpdateApplicationsUnits',
+                   version=1,
+                   params=_params)
+        _params['args'] = args
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(StringsWatchResult)
+    async def WatchApplications(self):
+        '''
+
+        Returns -> typing.Union[typing.Sequence[str], _ForwardRef('Error'), str]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASUnitProvisioner',
+                   request='WatchApplications',
+                   version=1,
+                   params=_params)
+
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(NotifyWatchResults)
+    async def WatchApplicationsScale(self, entities):
+        '''
+        entities : typing.Sequence[~Entity]
+        Returns -> typing.Sequence[~NotifyWatchResult]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASUnitProvisioner',
+                   request='WatchApplicationsScale',
+                   version=1,
+                   params=_params)
+        _params['entities'] = entities
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+    @ReturnMapping(NotifyWatchResults)
+    async def WatchPodSpec(self, entities):
+        '''
+        entities : typing.Sequence[~Entity]
+        Returns -> typing.Sequence[~NotifyWatchResult]
+        '''
+        # map input types to rpc msg
+        _params = dict()
+        msg = dict(type='CAASUnitProvisioner',
+                   request='WatchPodSpec',
+                   version=1,
+                   params=_params)
+        _params['entities'] = entities
+        reply = await self.rpc(msg)
+        return reply
+
+
+
+class ClientFacade(Type):
+    name = 'Client'
+    version = 1
+    schema =     {'definitions': {'APIHostPortsResult': {'additionalProperties': False,
+                                            'properties': {'servers': {'items': {'items': {'$ref': '#/definitions/HostPort'},
+                                                                                 'type': 'array'},
+                                                                       'type': 'array'}},
+                                            'required': ['servers'],
+                                            'type': 'object'},
+                     'AddCharm': {'additionalProperties': False,
+                                  'properties': {'channel': {'type': 'string'},
+                                                 'url': {'type': 'string'}},
+                                  'required': ['url', 'channel'],
+                                  'type': 'object'},
+                     'AddCharmWithAuthorization': {'additionalProperties': False,
+                                                   'properties': {'channel': {'type': 'string'},
+                                                                  'macaroon': {'$ref': '#/definitions/Macaroon'},
+                                                                  'url': {'type': 'string'}},
+                                                   'required': ['url',
+                                                                'channel',
+                                                                'macaroon'],
+                                                   'type': 'object'},
+                     'AddMachineParams': {'additionalProperties': False,
+                                          'properties': {'addresses': {'items': {'$ref': '#/definitions/Address'},
+                                                                       'type': 'array'},
+                                                         'constraints': {'$ref': '#/definitions/Value'},
+                                                         'container-type': {'type': 'string'},
+                                                         'disks': {'items': {'$ref': '#/definitions/Constraints'},
+                                                                   'type': 'array'},
+                                                         'hardware-characteristics': {'$ref': '#/definitions/HardwareCharacteristics'},
+                                                         'instance-id': {'type': 'string'},
+                                                         'jobs': {'items': {'type': 'string'},
+                                                                  'type': 'array'},
+                                                         'nonce': {'type': 'string'},
+                                                         'parent-id': {'type': 'string'},
+                                                         'placement': {'$ref': '#/definitions/Placement'},
+                                                         'series': {'type': 'string'}},
+                                          'required': ['series',
+                                                       'constraints',
+                                                       'jobs',
+                                                       'parent-id',
+                                                       'container-type',
+                                                       'instance-id',
+                                                       'nonce',
+                                                       'hardware-characteristics',
+                                                       'addresses'],
+                                          'type': 'object'},
+                     'AddMachines': {'additionalProperties': False,
+                                     'properties': {'params': {'items': {'$ref': '#/definitions/AddMachineParams'},
+                                                               'type': 'array'}},
+                                     'required': ['params'],
+                                     'type': 'object'},
+                     'AddMachinesResult': {'additionalProperties': False,
+                                           'properties': {'error': {'$ref': '#/definitions/Error'},
+                                                          'machine': {'type': 'string'}},
+                                           'required': ['machine'],
+                                           'type': 'object'},
+                     'AddMachinesResults': {'additionalProperties': False,
+                                            'properties': {'machines': {'items': {'$ref': '#/definitions/AddMachinesResult'},
+                                                                        'type': 'array'}},
+                                            'required': ['machines'],
+                                            'type': 'object'},
+                     'Address': {'additionalProperties': False,
+                                 'properties': {'scope': {'type': 'string'},
+                                                'space-name': {'type': 'string'},
+                                                'type': {'type': 'string'},
+                                                'value': {'type': 'string'}},
+                                 'required': ['value', 'type', 'scope'],
+                                 'type': 'object'},
+                     'AgentVersionResult': {'additionalProperties': False,
+                                            'properties': {'version': {'$ref': '#/definitions/Number'}},
+                                            'required': ['version'],
+                                            'type': 'object'},
+                     'AllWatcherId': {'additionalProperties': False,
+                                      'properties': {'watcher-id': {'type': 'string'}},
+                                      'required': ['watcher-id'],
+                                      'type': 'object'},
+                     'ApplicationStatus': {'additionalProperties': False,
+                                           'properties': {'can-upgrade-to': {'type': 'string'},
+                                                          'charm': {'type': 'string'},
+                                                          'err': {'additionalProperties': True,
+                                                                  'type': 'object'},
+                                                          'exposed': {'type': 'boolean'},
+                                                          'life': {'type': 'string'},
+                                                          'meter-statuses': {'patternProperties': {'.*': {'$ref': '#/definitions/MeterStatus'}},
+                                                                             'type': 'object'},
+                                                          'relations': {'patternProperties': {'.*': {'items': {'type': 'string'},
+                                                                                                     'type': 'array'}},
+                                                                        'type': 'object'},
+                                                          'series': {'type': 'string'},
+                                                          'status': {'$ref': '#/definitions/DetailedStatus'},
+                                                          'subordinate-to': {'items': {'type': 'string'},
+                                                                             'type': 'array'},
+                                                          'units': {'patternProperties': {'.*': {'$ref': '#/definitions/UnitStatus'}},
+                                                                    'type': 'object'},
+                                                          'workload-version': {'type': 'string'}},
+                                           'required': ['charm',
+                                                        'series',
+                                                        'exposed',
+                                                        'life',
+                                                        'relations',
+                                                        'can-upgrade-to',
+                                                        'subordinate-to',
+                                                        'units',
+                                                        'meter-statuses',
+                                                        'status',
+                                                        'workload-version'],
+                                           'type': 'object'},
+                     'Binary': {'additionalProperties': False,
+                                'properties': {'Arch': {'type': 'string'},
+                                               'Number': {'$ref': '#/definitions/Number'},
+                                               'Series': {'type': 'string'}},
+                                'required': ['Number', 'Series', 'Arch'],
+                                'type': 'object'},
+                     'BundleChange': {'additionalProperties': False,
+                                      'properties': {'args': {'items': {'additionalProperties': True,
+                                                                        'type': 'object'},
+                                                              'type': 'array'},
+                                                     'id': {'type': 'string'},
+                                                     'method': {'type': 'string'},
+                                                     'requires': {'items': {'type': 'string'},
+                                                                  'type': 'array'}},
+                                      'required': ['id',
+                                                   'method',
+                                                   'args',
+                                                   'requires'],
+                                      'type': 'object'},
+                     'BundleChangesParams': {'additionalProperties': False,
+                                             'properties': {'yaml': {'type': 'string'}},
+                                             'required': ['yaml'],
+                                             'type': 'object'},
+                     'BundleChangesResults': {'additionalProperties': False,
+                                              'properties': {'changes': {'items': {'$ref': '#/definitions/BundleChange'},
+                                                                         'type': 'array'},
+                                                             'errors': {'items': {'type': 'string'},
+                                                                        'type': 'array'}},
+                                              'type': 'object'},
+                     'BytesResult': {'additionalProperties': False,
+                                     'properties': {'result': {'items': {'type': 'integer'},
+                                                               'type': 'array'}},
+                                     'required': ['result'],
+                                     'type': 'object'},
+                     'ConfigValue': {'additionalProperties': False,
+                                     'properties': {'source': {'type': 'string'},
+                                                    'value': {'additionalProperties': True,
+                                                              'type': 'object'}},
+                                     'required': ['value', 'source'],
+                                     'type': 'object'},
+                     'Constraints': {'additionalProperties': False,
+                                     'properties': {'Count': {'type': 'integer'},
+                                                    'Pool': {'type': 'string'},
+                                                    'Size': {'type': 'integer'}},
+                                     'required': ['Pool', 'Size', 'Count'],
+                                     'type': 'object'},
+                     'DestroyMachines': {'additionalProperties': False,
+                                         'properties': {'force': {'type': 'boolean'},
+                                                        'machine-names': {'items': {'type': 'string'},
+                                                                          'type': 'array'}},
+                                         'required': ['machine-names', 'force'],
+                                         'type': 'object'},
+                     'DetailedStatus': {'additionalProperties': False,
+                                        'properties': {'data': {'patternProperties': {'.*': {'additionalProperties': True,
+                                                                                             'type': 'object'}},
+                                                                'type': 'object'},
+                                                       'err': {'additionalProperties': True,
+                                                               'type': 'object'},
+                                                       'info': {'type': 'string'},
+                                                       'kind': {'type': 'string'},
+                                                       'life': {'type': 'string'},
+                                                       'since': {'format': 'date-time',
+                                                                 'type': 'string'},
+                                                       'status': {'type': 'string'},
+                                                       'version': {'type': 'string'}},
+                                        'required': ['status',
+                                                     'info',
+                                                     'data',
+                                                     'since',
+                                                     'kind',
+                                                     'version',
+                                                     'life'],
+                                        'type': 'object'},
+                     'EndpointStatus': {'additionalProperties': False,
+                                        'properties': {'application': {'type': 'string'},
+                                                       'name': {'type': 'string'},
+                                                       'role': {'type': 'string'},
+                                                       'subordinate': {'type': 'boolean'}},
+                                        'required': ['application',
+                                                 &nbs