From 93e79fb44784f53531556ed14d663c5f5634b6b0 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Tue, 12 Nov 2024 16:44:05 +0900 Subject: [PATCH 01/34] chore: pre-commit and spelling fixes --- .github/ISSUE_TEMPLATE/BugReport.yml | 2 +- .github/ISSUE_TEMPLATE/FeatureRequest.yml | 2 +- .github/pull_request_template.md | 2 +- .github/workflows/static-analysis.yaml | 1 - .github/workflows/test_candidate.yaml | 2 +- .github/workflows/test_edge.yaml | 2 +- .readthedocs.yaml | 2 +- debian/changelog | 2 +- debian/control | 1 - debian/copyright | 1 - docs/_extensions/automembersummary.py | 49 +- docs/changelog.rst | 12 +- docs/conf.py | 169 +- docs/index.rst | 1 - docs/narrative/controller.rst | 2 +- docs/narrative/model.rst | 2 +- docs/requirements.txt | 2 +- examples/action.py | 17 +- examples/add_k8s.py | 27 +- examples/add_machine.py | 36 +- examples/add_model.py | 27 +- examples/add_secrets_backend.py | 15 +- examples/allwatcher.py | 5 +- examples/charmhub_deploy_k8s.py | 18 +- examples/charmhub_deploy_machine.py | 22 +- examples/charmhub_find.py | 5 +- examples/charmhub_info.py | 5 +- examples/charms/ubuntu/config.yaml | 2 +- examples/charms/ubuntu/metadata.yaml | 4 +- examples/cloud.py | 5 +- examples/clouds.py | 5 +- examples/config.py | 31 +- examples/connect_current_model.py | 7 +- examples/controller.py | 19 +- examples/credential.py | 35 +- examples/crossmodel.py | 46 +- examples/crossmodel_bundle.py | 49 +- examples/crossmodel_controller.py | 46 +- examples/crossmodel_relation.py | 66 +- examples/debug-log.py | 13 +- examples/deploy.py | 23 +- examples/deploy_bundle.py | 24 +- examples/deploy_bundle_charmhub.py | 1 + examples/deploy_bundle_with_trust.py | 23 +- examples/deploy_constraints.py | 16 +- examples/deploy_local_big_k8s_bundle.py | 13 +- .../deploy_local_bundle_with_resources.py | 23 +- examples/deploy_local_file_resource.py | 15 +- examples/deploy_local_resource.py | 18 +- examples/deploy_with_revision.py | 22 +- examples/expose-application.py | 71 +- examples/formatted_status.py | 18 +- examples/fullstatus.py | 9 +- examples/future.py | 32 +- examples/get_cloud.py | 5 +- examples/k8s-local-bundle/big-k8s-bundle.yaml | 6 +- examples/leadership.py | 6 +- examples/list_secrets.py | 3 +- examples/livemodel.py | 3 +- examples/local_refresh.py | 11 +- examples/localcharm.py | 11 +- examples/machine_hostname.py | 8 +- examples/model.py | 5 +- examples/modelsummaries.py | 7 +- examples/relate.py | 111 +- examples/run_action.py | 8 +- examples/scp.py | 9 +- examples/status.py | 16 +- examples/unitrun.py | 15 +- examples/upgrade_local_charm_k8s.py | 23 +- juju/action.py | 3 +- juju/annotationhelper.py | 2 +- juju/application.py | 532 +- juju/bundle.py | 545 +- juju/charmhub.py | 83 +- juju/client/_client.py | 42 +- juju/client/_client1.py | 1913 +- juju/client/_client10.py | 2973 ++- juju/client/_client11.py | 1834 +- juju/client/_client12.py | 1774 +- juju/client/_client17.py | 3097 ++- juju/client/_client19.py | 3373 +-- juju/client/_client2.py | 1553 +- juju/client/_client20.py | 3275 ++- juju/client/_client3.py | 2250 +- juju/client/_client4.py | 2263 +- juju/client/_client5.py | 1366 +- juju/client/_client6.py | 4860 ++-- juju/client/_client7.py | 5390 +++-- juju/client/_client8.py | 1297 +- juju/client/_client9.py | 1713 +- juju/client/_definitions.py | 19554 ++++++++++++---- juju/client/client.py | 9 +- juju/client/codegen.py | 1 + juju/client/connection.py | 417 +- juju/client/connector.py | 59 +- juju/client/facade.py | 343 +- juju/client/facade_versions.py | 247 +- juju/client/gocookies.py | 49 +- juju/client/jujudata.py | 80 +- juju/client/overrides.py | 275 +- juju/client/proxy/factory.py | 22 +- juju/client/proxy/kubernetes/proxy.py | 20 +- juju/client/proxy/proxy.py | 2 +- juju/client/runner.py | 1 + juju/client/schemas-juju-3.1.0.json | 2 +- juju/client/schemas-juju-3.1.10.json | 2 +- juju/client/schemas-juju-3.1.5.json | 2 +- juju/client/schemas-juju-3.3.0.json | 2 +- juju/client/schemas-juju-3.3.7.json | 2 +- juju/client/schemas-juju-3.4.6.json | 2 +- juju/client/schemas-juju-3.5.4.json | 2 +- juju/client/schemas-juju-3.6-rc1.json | 2 +- juju/constraints.py | 117 +- juju/controller.py | 380 +- juju/delta.py | 46 +- juju/errors.py | 40 +- juju/exceptions.py | 1 + juju/jasyncio.py | 38 +- juju/juju.py | 9 +- juju/loop.py | 5 +- juju/machine.py | 141 +- juju/model.py | 1286 +- juju/names.py | 24 +- juju/offerendpoints.py | 70 +- juju/origin.py | 37 +- juju/placement.py | 2 +- juju/provisioner.py | 66 +- juju/relation.py | 42 +- juju/remoteapplication.py | 17 +- juju/secrets.py | 15 +- juju/status.py | 145 +- juju/tag.py | 28 +- juju/unit.py | 205 +- juju/url.py | 43 +- juju/user.py | 45 +- juju/utils.py | 164 +- juju/version.py | 2 +- scripts/copyright.sh | 2 +- setup.py | 55 +- tests/base.py | 28 +- tests/bundle/bundle.yaml | 2 +- tests/charm-folder-symlink/metadata.yaml | 2 +- tests/charm-secret/config.yaml | 2 +- tests/charm-secret/metadata.yaml | 4 +- tests/charm-secret/src/charm.py | 4 +- tests/charm-secret/tox.ini | 4 +- .../bundle/bundle-include-base64.yaml | 2 +- tests/integration/bundle/config-base64.yaml | 2 +- .../bundle-with-overlay-multi.yaml | 4 +- .../test-overlays/test-multi-overlay.yaml | 2 +- .../bundle/test-overlays/test-overlay.yaml | 4 +- .../bundle/test-overlays/test-overlay2.yaml | 2 +- .../bundle/test-overlays/test-overlay3.yaml | 2 +- tests/integration/charm-assumes/manifest.yaml | 2 +- tests/integration/charm-assumes/metadata.yaml | 2 +- .../charmcraft.yaml | 2 +- .../integration/file-resource-charm/test.file | 2 +- tests/integration/test_application.py | 232 +- tests/integration/test_charmhub.py | 47 +- tests/integration/test_client.py | 3 +- tests/integration/test_connection.py | 100 +- tests/integration/test_controller.py | 129 +- tests/integration/test_crossmodel.py | 122 +- tests/integration/test_errors.py | 20 +- tests/integration/test_expose.py | 67 +- tests/integration/test_macaroon_auth.py | 41 +- tests/integration/test_machine.py | 32 +- tests/integration/test_model.py | 657 +- tests/integration/test_secrets.py | 50 +- tests/integration/test_unit.py | 211 +- tests/unit/test_application.py | 74 +- tests/unit/test_bundle.py | 969 +- tests/unit/test_client.py | 7 +- tests/unit/test_connection.py | 208 +- tests/unit/test_constraints.py | 92 +- tests/unit/test_controller.py | 178 +- tests/unit/test_definitions.py | 161 +- tests/unit/test_flags.py | 5 +- tests/unit/test_gocookies.py | 113 +- tests/unit/test_loop.py | 7 +- tests/unit/test_machine.py | 14 +- tests/unit/test_model.py | 297 +- tests/unit/test_offerendpoint.py | 147 +- tests/unit/test_origin.py | 5 +- tests/unit/test_overrides.py | 101 +- tests/unit/test_placement.py | 1 - tests/unit/test_proxy.py | 21 +- tests/unit/test_registration_string.py | 11 +- tests/unit/test_relation.py | 30 +- tests/unit/test_secrets.py | 56 +- tests/unit/test_status.py | 14 +- tests/unit/test_unit.py | 144 +- tests/unit/test_url.py | 31 +- tests/unit/test_utils.py | 223 +- tests/utils.py | 8 +- tests/validate/test_facade_versions.py | 10 +- 197 files changed, 44313 insertions(+), 25969 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/BugReport.yml b/.github/ISSUE_TEMPLATE/BugReport.yml index 321fb2230..1956250cb 100644 --- a/.github/ISSUE_TEMPLATE/BugReport.yml +++ b/.github/ISSUE_TEMPLATE/BugReport.yml @@ -53,4 +53,4 @@ body: Please provide a simplified reproducer, and if it's possible please refrain from providing a 'clone this repository and run the integration tests to see the problem' type of a reproducer. Thanks!" render: python validations: - required: true \ No newline at end of file + required: true diff --git a/.github/ISSUE_TEMPLATE/FeatureRequest.yml b/.github/ISSUE_TEMPLATE/FeatureRequest.yml index be196b263..0fd6a0c06 100644 --- a/.github/ISSUE_TEMPLATE/FeatureRequest.yml +++ b/.github/ISSUE_TEMPLATE/FeatureRequest.yml @@ -33,4 +33,4 @@ body: description: "Please provide valid Python code that you'd like to be able to run with this new feature: " render: python validations: - required: true \ No newline at end of file + required: true diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index bd79f6fb1..7ad69550a 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -23,4 +23,4 @@ All CI tests need to pass. #### Notes & Discussion -*\* \ No newline at end of file +*\* diff --git a/.github/workflows/static-analysis.yaml b/.github/workflows/static-analysis.yaml index b4fb30339..aab259729 100644 --- a/.github/workflows/static-analysis.yaml +++ b/.github/workflows/static-analysis.yaml @@ -15,4 +15,3 @@ jobs: steps: - uses: actions/checkout@v4 - uses: wagoid/commitlint-github-action@v6 - diff --git a/.github/workflows/test_candidate.yaml b/.github/workflows/test_candidate.yaml index 078bbe7cc..d0c236d32 100644 --- a/.github/workflows/test_candidate.yaml +++ b/.github/workflows/test_candidate.yaml @@ -42,7 +42,7 @@ jobs: else echo "Candidate $candidate has to be tested" next_test="$candidate" - fi + fi fi echo "next-test=$next_test" >> $GITHUB_ENV echo "$next_test" > ~/juju-last-candidate-version diff --git a/.github/workflows/test_edge.yaml b/.github/workflows/test_edge.yaml index 2e5afaa72..27a949cf3 100644 --- a/.github/workflows/test_edge.yaml +++ b/.github/workflows/test_edge.yaml @@ -42,7 +42,7 @@ jobs: else echo "Edge $edge has to be tested" next_test="$edge" - fi + fi fi echo "next-test=$next_test" >> $GITHUB_ENV echo "$next_test" > ~/juju-last-edge-version diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 8c809a2d8..f861b63a7 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -10,4 +10,4 @@ build: python: "3.10" sphinx: - configuration: docs/conf.py \ No newline at end of file + configuration: docs/conf.py diff --git a/debian/changelog b/debian/changelog index 7dd74b6a7..ebec4fcd8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -17,7 +17,7 @@ Thursday January 9 2020 Tuesday January 7 2020 * Update facade methods for Juju 2.7.0 - * Fix an issue when querying CMR relations (#366) + * Fix an issue when querying CMR relations (#366) * Fix storage support in bundles (#361) * Fix reporting of unit leaders (#374) * AddCloud API support (#370) diff --git a/debian/control b/debian/control index e4a9533df..d00014b2e 100644 --- a/debian/control +++ b/debian/control @@ -130,4 +130,3 @@ Description: . Pylibjuju releases now track the Juju release cadence. New generated schemas will be updated per Juju releases. - diff --git a/debian/copyright b/debian/copyright index 4a504f1b9..1bf7ff177 100644 --- a/debian/copyright +++ b/debian/copyright @@ -212,4 +212,3 @@ License: Apache-2 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. - diff --git a/docs/_extensions/automembersummary.py b/docs/_extensions/automembersummary.py index 486ce3d20..cc29e8342 100644 --- a/docs/_extensions/automembersummary.py +++ b/docs/_extensions/automembersummary.py @@ -33,25 +33,26 @@ def run(self): try: module = importlib.import_module(module_name) except ImportError: - raise SphinxError("Unable to generate reference docs for %s, " - "could not import" % (module_name)) + raise SphinxError( + "Unable to generate reference docs for %s, " + "could not import" % (module_name) + ) - divider = '+{:-<80}+'.format('') - row = '| {:<78} |'.format + divider = "+{:-<80}+".format("") + row = "| {:<78} |".format lines = [] for member_name, member in inspect.getmembers(module): if not self._filter(module_name, member_name, member): continue - summary = textwrap.wrap(self._get_summary(member), 78) or [''] - link = '`{} <#{}>`_'.format(member_name, - '.'.join([module_name, - member_name])) - methods = ['* `{} <#{}>`_'.format(n, - '.'.join([module_name, - member_name, - n])) - for n, m in inspect.getmembers(member) - if not n.startswith('_') and inspect.isfunction(m)] + summary = textwrap.wrap(self._get_summary(member), 78) or [""] + link = "`{} <#{}>`_".format( + member_name, ".".join([module_name, member_name]) + ) + methods = [ + "* `{} <#{}>`_".format(n, ".".join([module_name, member_name, n])) + for n, m in inspect.getmembers(member) + if not n.startswith("_") and inspect.isfunction(m) + ] lines.append(divider) lines.append(row(link)) @@ -59,19 +60,19 @@ def run(self): for line in summary: lines.append(row(line)) if methods: - lines.append(row('')) - lines.append(row('Methods:')) - lines.append(row('')) + lines.append(row("")) + lines.append(row("Methods:")) + lines.append(row("")) for i, method in enumerate(methods): lines.append(row(method)) lines.append(divider) - content = '\n'.join(lines) + content = "\n".join(lines) - result = self._parse(content, '') + result = self._parse(content, "") return result def _get_summary(self, member): - doc = (member.__doc__ or '').splitlines() + doc = (member.__doc__ or "").splitlines() # strip any leading blank lines while doc and not doc[0].strip(): @@ -86,12 +87,12 @@ def _get_summary(self, member): return " ".join(doc).strip() def _filter(self, module_name, member_name, member): - if member_name.startswith('_'): + if member_name.startswith("_"): return False - if hasattr(member, '__module__'): + if hasattr(member, "__module__"): # skip imported classes & functions return member.__module__.startswith(module_name) - elif hasattr(member, '__name__'): + elif hasattr(member, "__name__"): # skip imported modules return member.__name__.startswith(module_name) else: @@ -109,4 +110,4 @@ def _parse(self, rst_text, annotation): def setup(app): - app.add_directive('automembersummary', AutoMemberSummary) + app.add_directive("automembersummary", AutoMemberSummary) diff --git a/docs/changelog.rst b/docs/changelog.rst index b9be9396f..fc7240fd5 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -14,7 +14,7 @@ Thursday 11th July 2024 * feat: conventional commits static analysis by @SimonRichardson in https://github.com/juju/python-libjuju/pull/1068 * fix(series): add noble support by @jack-w-shaw in https://github.com/juju/python-libjuju/pull/1063 * fix zones constraints list parsing by @luissimas in https://github.com/juju/python-libjuju/pull/1054 -* fix(model): fix wrong instanciation of list-secrets facade by @gboutry in https://github.com/juju/python-libjuju/pull/1065 +* fix(model): fix wrong instantiation of list-secrets facade by @gboutry in https://github.com/juju/python-libjuju/pull/1065 * fix(makefile): run .tox before lint in makefile target by @cderici in https://github.com/juju/python-libjuju/pull/1069 3.5.0.0 @@ -99,7 +99,7 @@ Thursday 26th Oct 2023 * Find controller name by endpoint on 3.x track by @cderici in https://github.com/juju/python-libjuju/pull/966 * Optimize & fix unit removal by @cderici in https://github.com/juju/python-libjuju/pull/967 * Allow switch kwarg in refresh to switch to local charms by @jack-w-shaw in https://github.com/juju/python-libjuju/pull/971 -* Parse charm URLs consistantly for local charms by @jack-w-shaw in https://github.com/juju/python-libjuju/pull/974 +* Parse charm URLs consistently for local charms by @jack-w-shaw in https://github.com/juju/python-libjuju/pull/974 * Juju config directory location fix on 3.x by @cderici in https://github.com/juju/python-libjuju/pull/976 * [JUJU-4779] Ensure valid charm origin for local charm switches by @jack-w-shaw in https://github.com/juju/python-libjuju/pull/978 * Application refresh with resources on 3.x by @cderici in https://github.com/juju/python-libjuju/pull/973 @@ -167,7 +167,7 @@ This release works with any Juju 3.x controller. Friday 5th May 2023 -This release has been tested with Juju 3.1.2 and contains the new +This release has been tested with Juju 3.1.2 and contains the new endpoints for secrets backend. This release works with any Juju 3.x controller. @@ -212,7 +212,7 @@ This version is only tested using Juju 3.1.0. Wednesday 26th October -* [JUJU-2027] Local refresh with resoruces by @cderici in https://github.com/juju/python-libjuju/pull/757 +* [JUJU-2027] Local refresh with resources by @cderici in https://github.com/juju/python-libjuju/pull/757 * [JUJU-2026] Improve resolve charm by @cderici in https://github.com/juju/python-libjuju/pull/761 * Add owner and data to license file by @arturo-seijas in https://github.com/juju/python-libjuju/pull/760 @@ -327,7 +327,7 @@ Monday March 21 2022 * [JUJU-573] Fix charm resolution for Juju 2.8.11 by @cderici in https://github.com/juju/python-libjuju/pull/633 * [JUJU-704] Remove non-implemented (stuıb) functions by @cderici in https://github.com/juju/python-libjuju/pull/646 * [JUJU-676] Avoid defaulting to empty string for charm origin by @cderici in https://github.com/juju/python-libjuju/pull/647 -* Charmstore compatability of deploying bundles by @addyess in https://github.com/juju/python-libjuju/pull/650 +* Charmstore compatibility of deploying bundles by @addyess in https://github.com/juju/python-libjuju/pull/650 * [JUJU-731] Subordinate charm num unit by @cderici in https://github.com/juju/python-libjuju/pull/648 * [JUJU-769] Facade schemas for 2.9.27 by @cderici in https://github.com/juju/python-libjuju/pull/652 * [JUJU-771] Auto switch to scale from add_unit on container based models by @cderici in https://github.com/juju/python-libjuju/pull/653 @@ -540,7 +540,7 @@ Thursday January 9 2020 Tuesday January 7 2020 * Update facade methods for Juju 2.7.0 - * Fix an issue when querying CMR relations (#366) + * Fix an issue when querying CMR relations (#366) * Fix storage support in bundles (#361) * Fix reporting of unit leaders (#374) * AddCloud API support (#370) diff --git a/docs/conf.py b/docs/conf.py index 417179595..b64396203 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -26,48 +26,49 @@ # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath('..')) +sys.path.insert(0, os.path.abspath("..")) from juju.version import CLIENT_VERSION + version = CLIENT_VERSION # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +# needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -sys.path.append(os.path.abspath('_extensions/')) +sys.path.append(os.path.abspath("_extensions/")) extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.autosummary', - 'sphinx.ext.intersphinx', - 'sphinx.ext.todo', - 'sphinx.ext.viewcode', - 'sphinxcontrib.asyncio', - 'automembersummary', + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "sphinx.ext.intersphinx", + "sphinx.ext.todo", + "sphinx.ext.viewcode", + "sphinxcontrib.asyncio", + "automembersummary", ] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # source_suffix = ['.rst', '.md'] -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = u'juju' -copyright = u'2016, Canonical Ltd.' -author = u'Canonical' +project = "juju" +copyright = "2016, Canonical Ltd." +author = "Canonical" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -87,38 +88,38 @@ # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' +# today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This patterns also effect to html_static_path and html_extra_path -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] # The reST default role (used for this markup: `text`) to use for all # documents. -#default_role = None +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False +# keep_warnings = False # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = True @@ -128,158 +129,151 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'sphinx_rtd_theme' +html_theme = "sphinx_rtd_theme" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +# html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +# html_theme_path = [] # The name for this set of Sphinx documents. # " v documentation" by default. -#html_title = u'libjuju v0.0.0' +# html_title = u'libjuju v0.0.0' # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None +# html_logo = None # The name of an image file (relative to this directory) to use as a favicon of # the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +# html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = ["_static"] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. -#html_extra_path = [] +# html_extra_path = [] # If not None, a 'Last updated on:' timestamp is inserted at every page # bottom, using the given strftime format. # The empty string is equivalent to '%b %d, %Y'. -#html_last_updated_fmt = None +# html_last_updated_fmt = None # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. -#html_domain_indices = True +# html_domain_indices = True # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +# html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +# html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None +# html_file_suffix = None # Language to be used for generating the HTML full-text search index. # Sphinx supports the following languages: # 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' # 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh' -#html_search_language = 'en' +# html_search_language = 'en' # A dictionary with options for the search language support, empty by default. # 'ja' uses this config value. # 'zh' user can custom change `jieba` dictionary path. -#html_search_options = {'type': 'default'} +# html_search_options = {'type': 'default'} # The name of a javascript file (relative to the configuration directory) that # implements a search results scorer. If empty, the default will be used. -#html_search_scorer = 'scorer.js' +# html_search_scorer = 'scorer.js' # Output file base name for HTML help builder. -htmlhelp_basename = 'libjujudoc' +htmlhelp_basename = "libjujudoc" # -- Options for LaTeX output --------------------------------------------- latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', - -# Latex figure (float) alignment -#'figure_align': 'htbp', + # The paper size ('letterpaper' or 'a4paper'). + #'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + #'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + #'preamble': '', + # Latex figure (float) alignment + #'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, 'libjuju.tex', u'libjuju Documentation', - u'Canonical', 'manual'), + (master_doc, "libjuju.tex", "libjuju Documentation", "Canonical", "manual"), ] # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# latex_domain_indices = True # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'libjuju', u'libjuju Documentation', - [author], 1) -] +man_pages = [(master_doc, "libjuju", "libjuju Documentation", [author], 1)] # If true, show URL addresses after external links. -#man_show_urls = False +# man_show_urls = False # -- Options for Texinfo output ------------------------------------------- @@ -288,22 +282,29 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'libjuju', u'libjuju Documentation', - author, 'libjuju', 'One line description of project.', - 'Miscellaneous'), + ( + master_doc, + "libjuju", + "libjuju Documentation", + author, + "libjuju", + "One line description of project.", + "Miscellaneous", + ), ] # Documents to append as an appendix to all manuals. -#texinfo_appendices = [] +# texinfo_appendices = [] # If false, no module index is generated. -#texinfo_domain_indices = True +# texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' +# texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False +# texinfo_no_detailmenu = False + def setup(app): - app.add_css_file('custom.css') + app.add_css_file("custom.css") diff --git a/docs/index.rst b/docs/index.rst index 2dd55cb82..07eb01c12 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -42,4 +42,3 @@ Indices and tables * :ref:`genindex` * :ref:`modindex` * :ref:`search` - diff --git a/docs/narrative/controller.rst b/docs/narrative/controller.rst index 1696285d2..6fe108069 100644 --- a/docs/narrative/controller.rst +++ b/docs/narrative/controller.rst @@ -70,7 +70,7 @@ a macaroon. bakery_client.cookies = FileCookieJar('cookies.txt') controller = Controller() await controller.connect(bakery_client=bakery_client) - + Connecting with an Explicit Endpoint diff --git a/docs/narrative/model.rst b/docs/narrative/model.rst index 8afe17fa1..c0cb167a9 100644 --- a/docs/narrative/model.rst +++ b/docs/narrative/model.rst @@ -64,7 +64,7 @@ a macaroon. bakery_client.cookies = FileCookieJar('cookies.txt') model = Model() await model.connect(bakery_client=bakery_client) - + Connecting with an Explicit Endpoint diff --git a/docs/requirements.txt b/docs/requirements.txt index cf690bbf3..2ee6d2000 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -13,4 +13,4 @@ macaroonbakery toposort python-dateutil kubernetes -packaging \ No newline at end of file +packaging diff --git a/examples/action.py b/examples/action.py index b0db1b7e8..2da3fdad7 100644 --- a/examples/action.py +++ b/examples/action.py @@ -10,6 +10,7 @@ 4. Waits for the action results to come back, then exits. """ + import logging from juju import jasyncio @@ -17,10 +18,10 @@ async def run_action(unit): - logging.debug('Running action on unit %s', unit.name) + logging.debug("Running action on unit %s", unit.name) # unit.run() returns a juju.action.Action instance - action = await unit.run_action('add-repo', repo='myrepo') + action = await unit.run_action("add-repo", repo="myrepo") # wait for the action to complete action = await action.wait() @@ -33,10 +34,10 @@ async def main(): await model.connect() app = await model.deploy( - 'git', - application_name='git', - series='trusty', - channel='stable', + "git", + application_name="git", + series="trusty", + channel="stable", ) for unit in app.units: @@ -46,8 +47,8 @@ async def main(): await model.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG) - ws_logger = logging.getLogger('websockets.protocol') + ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) jasyncio.run(main()) diff --git a/examples/add_k8s.py b/examples/add_k8s.py index c9c63045e..94121a604 100644 --- a/examples/add_k8s.py +++ b/examples/add_k8s.py @@ -10,6 +10,7 @@ 4. Adds a userpass credential for the cloud. """ + import logging import os import yaml @@ -21,14 +22,14 @@ async def main(): - kubecfg = os.popen('microk8s.config').read() + kubecfg = os.popen("microk8s.config").read() cfg = yaml.safe_load(kubecfg) - ctx = {v['name']: v['context'] for v in cfg['contexts']}[cfg['current-context']] - cluster = {v['name']: v['cluster'] for v in cfg['clusters']}[ctx['cluster']] - user = {v['name']: v['user'] for v in cfg['users']}[ctx['user']] + ctx = {v["name"]: v["context"] for v in cfg["contexts"]}[cfg["current-context"]] + cluster = {v["name"]: v["cluster"] for v in cfg["clusters"]}[ctx["cluster"]] + user = {v["name"]: v["user"] for v in cfg["users"]}[ctx["user"]] - ep = cluster['server'] - caCert = base64.b64decode(cluster['certificate-authority-data']).decode('utf-8') + ep = cluster["server"] + caCert = base64.b64decode(cluster["certificate-authority-data"]).decode("utf-8") controller = Controller() await controller.connect() @@ -39,24 +40,22 @@ async def main(): endpoint=ep, host_cloud_region="microk8s/localhost", regions=[client.CloudRegion(endpoint=ep, name="localhost")], - type_="kubernetes") + type_="kubernetes", + ) cloud = await controller.add_cloud("test", cloud) cred = client.CloudCredential( auth_type="userpass", - attrs={ - "username": user['username'], - "password": user['password'] - } + attrs={"username": user["username"], "password": user["password"]}, ) await controller.add_credential("test", credential=cred, cloud="test") - await controller.remove_cloud('test') + await controller.remove_cloud("test") await controller.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG) - ws_logger = logging.getLogger('websockets.protocol') + ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) jasyncio.run(main()) diff --git a/examples/add_machine.py b/examples/add_machine.py index 47c602d0c..a6202844c 100755 --- a/examples/add_machine.py +++ b/examples/add_machine.py @@ -11,6 +11,7 @@ 3. Deploys charm to the lxd container """ + import logging from juju import jasyncio @@ -30,31 +31,30 @@ async def main(): # add a machine with constraints, disks, and series machine2 = await model.add_machine( constraints={ - 'mem': 256 * MB, + "mem": 256 * MB, }, - disks=[{ - 'size': 10 * GB, - 'count': 1, - }], - series='jammy', + disks=[ + { + "size": 10 * GB, + "count": 1, + } + ], + series="jammy", ) # add a lxd container to machine2 - machine3 = await model.add_machine( - 'lxd:{}'.format(machine2.id), - series='jammy' - ) + machine3 = await model.add_machine("lxd:{}".format(machine2.id), series="jammy") # deploy charm to the lxd container application = await model.deploy( - 'ch:ubuntu', - application_name='ubuntu', - series='jammy', - channel='stable', - to=machine3.id + "ch:ubuntu", + application_name="ubuntu", + series="jammy", + channel="stable", + to=machine3.id, ) - await model.wait_for_idle(status='active') + await model.wait_for_idle(status="active") await application.remove() @@ -65,9 +65,9 @@ async def main(): await model.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG) - ws_logger = logging.getLogger('websockets.protocol') + ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) jasyncio.run(main()) diff --git a/examples/add_model.py b/examples/add_model.py index 06cd18084..837a3f0fe 100644 --- a/examples/add_model.py +++ b/examples/add_model.py @@ -9,6 +9,7 @@ 3. Attempts to ssh into the charm """ + from juju import jasyncio from juju import utils from juju.controller import Controller @@ -30,39 +31,39 @@ async def main(): print("Adding model {}".format(model_name)) model = await controller.add_model(model_name) - print('Deploying ubuntu') + print("Deploying ubuntu") application = await model.deploy( - 'ch:ubuntu', - application_name='ubuntu', - series='jammy', - channel='stable', + "ch:ubuntu", + application_name="ubuntu", + series="jammy", + channel="stable", ) - print('Waiting for active') + print("Waiting for active") await asyncio.sleep(10) - await model.wait_for_idle(status='active') + await model.wait_for_idle(status="active") print("Verifying that we can ssh into the created model") ret = await utils.execute_process( - 'juju', 'ssh', '-m', model_name, 'ubuntu/0', 'ls /', log=LOG) + "juju", "ssh", "-m", model_name, "ubuntu/0", "ls /", log=LOG + ) assert ret - print('Removing ubuntu') + print("Removing ubuntu") await application.remove() print("Destroying model") await controller.destroy_model(model.info.uuid) except Exception: - LOG.exception( - "Test failed! Model {} may not be cleaned up".format(model_name)) + LOG.exception("Test failed! Model {} may not be cleaned up".format(model_name)) finally: - print('Disconnecting from controller') + print("Disconnecting from controller") if model: await model.disconnect() await controller.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": jasyncio.run(main()) diff --git a/examples/add_secrets_backend.py b/examples/add_secrets_backend.py index 10e00d24a..896d0cc88 100644 --- a/examples/add_secrets_backend.py +++ b/examples/add_secrets_backend.py @@ -16,7 +16,7 @@ async def main(): await m.connect() # # deploy postgresql - await m.deploy('postgresql', series="focal") + await m.deploy("postgresql", series="focal") # # deploy vault await m.deploy("vault", series="focal") # # relate/integrate @@ -31,7 +31,7 @@ async def main(): # Deploy this entire thing status = await m.get_status() target = "" - for unit in status.applications['vault'].units.values(): + for unit in status.applications["vault"].units.values(): target = unit.public_address vault_url = "http://%s:8200" % target @@ -44,13 +44,18 @@ async def main(): # Unseal vault vault_client.sys.submit_unseal_keys(keys["keys"]) - target_unit = m.applications['vault'].units[0] + target_unit = m.applications["vault"].units[0] action = await target_unit.run_action("authorize-charm", token=keys["root_token"]) await action.wait() # Add the secret backend c = await m.get_controller() - response = await c.add_secret_backends("1111", "examplevault", "vault", {"endpoint": vault_url, "token": keys["root_token"]}) + response = await c.add_secret_backends( + "1111", + "examplevault", + "vault", + {"endpoint": vault_url, "token": keys["root_token"]}, + ) print("Output from add secret backends") print(response["results"]) @@ -70,5 +75,5 @@ async def main(): await m.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": jasyncio.run(main()) diff --git a/examples/allwatcher.py b/examples/allwatcher.py index b0934e342..fc9687338 100644 --- a/examples/allwatcher.py +++ b/examples/allwatcher.py @@ -10,6 +10,7 @@ 4. Runs forever (kill with Ctrl-C) """ + import logging from juju import jasyncio @@ -28,9 +29,9 @@ async def watch(): print(delta.deltas) -if __name__ == '__main__': +if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG) - ws_logger = logging.getLogger('websockets.protocol') + ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) # Run loop until the process is manually stopped (watch will loop # forever). diff --git a/examples/charmhub_deploy_k8s.py b/examples/charmhub_deploy_k8s.py index c49a74df0..b6676c2d5 100644 --- a/examples/charmhub_deploy_k8s.py +++ b/examples/charmhub_deploy_k8s.py @@ -9,24 +9,25 @@ 3. Destroys the unit and application """ + from juju import jasyncio from juju.model import Model async def main(): model = Model() - print('Connecting to model') + print("Connecting to model") await model.connect() try: - print('Deploying ') + print("Deploying ") application = await model.deploy( - 'ch:juju-qa-test', - application_name='juju-qa-test2', - channel='2.0/edge', + "ch:juju-qa-test", + application_name="juju-qa-test2", + channel="2.0/edge", ) - print('Waiting for active') + print("Waiting for active") await model.wait_for_idle(status="active") # when run on a container based model it should auto-switch to @@ -35,8 +36,9 @@ async def main(): await application.destroy() finally: - print('Disconnecting from model') + print("Disconnecting from model") await model.disconnect() -if __name__ == '__main__': + +if __name__ == "__main__": jasyncio.run(main()) diff --git a/examples/charmhub_deploy_machine.py b/examples/charmhub_deploy_machine.py index 479ec2fe5..09f14963c 100644 --- a/examples/charmhub_deploy_machine.py +++ b/examples/charmhub_deploy_machine.py @@ -9,31 +9,33 @@ 3. Destroys the unit and application """ + from juju import jasyncio from juju.model import Model async def main(): model = Model() - print('Connecting to model') + print("Connecting to model") await model.connect() try: - print('Deploying ') + print("Deploying ") application = await model.deploy( - 'ch:juju-qa-test', - application_name='juju-qa-test', - channel='2.0/edge', + "ch:juju-qa-test", + application_name="juju-qa-test", + channel="2.0/edge", ) - print('Waiting for active') + print("Waiting for active") await model.block_until( - lambda: all(unit.workload_status == 'active' - for unit in application.units)) + lambda: all(unit.workload_status == "active" for unit in application.units) + ) finally: - print('Disconnecting from model') + print("Disconnecting from model") await model.disconnect() -if __name__ == '__main__': + +if __name__ == "__main__": jasyncio.run(main()) diff --git a/examples/charmhub_find.py b/examples/charmhub_find.py index 22526adf8..24af10f6d 100644 --- a/examples/charmhub_find.py +++ b/examples/charmhub_find.py @@ -5,6 +5,7 @@ Example to show how to connect to the current model and search the charm-hub repository for charms. """ + import logging from juju import jasyncio @@ -27,10 +28,10 @@ async def main(): print("{}\t{}".format("N" if resp.type_ == "charm" else "Y", resp.name)) finally: if model.is_connected(): - print('Disconnecting from model') + print("Disconnecting from model") await model.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": logging.basicConfig(level=logging.INFO) jasyncio.run(main()) diff --git a/examples/charmhub_info.py b/examples/charmhub_info.py index 44d6dbfec..01d0a2c22 100644 --- a/examples/charmhub_info.py +++ b/examples/charmhub_info.py @@ -5,6 +5,7 @@ Example to show how to connect to the current model and query the charm-hub repository for information about a given charm. """ + import logging from juju import jasyncio @@ -23,10 +24,10 @@ async def main(): print(charm) finally: if model.is_connected(): - print('Disconnecting from model') + print("Disconnecting from model") await model.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": logging.basicConfig(level=logging.INFO) jasyncio.run(main()) diff --git a/examples/charms/ubuntu/config.yaml b/examples/charms/ubuntu/config.yaml index cac0d8347..4c4680b58 100644 --- a/examples/charms/ubuntu/config.yaml +++ b/examples/charms/ubuntu/config.yaml @@ -3,4 +3,4 @@ # # Learn more about config at: https://juju.is/docs/sdk/config -options: {} \ No newline at end of file +options: {} diff --git a/examples/charms/ubuntu/metadata.yaml b/examples/charms/ubuntu/metadata.yaml index 2a7f9c4f3..2b5d3532b 100644 --- a/examples/charms/ubuntu/metadata.yaml +++ b/examples/charms/ubuntu/metadata.yaml @@ -21,8 +21,8 @@ tags: - misc - application_development subordinate: false -# check: https://juju.is/docs/sdk/assumes for more details +# check: https://juju.is/docs/sdk/assumes for more details assumes: - any_of: - juju >= 2.9 - - k8s-api \ No newline at end of file + - k8s-api diff --git a/examples/cloud.py b/examples/cloud.py index 6dfa5ce92..26e624345 100644 --- a/examples/cloud.py +++ b/examples/cloud.py @@ -9,6 +9,7 @@ 3. Disconnects from the controller """ + import logging from juju import jasyncio @@ -24,8 +25,8 @@ async def main(): await controller.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG) - ws_logger = logging.getLogger('websockets.protocol') + ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) jasyncio.run(main()) diff --git a/examples/clouds.py b/examples/clouds.py index 62750bc9a..ef03d48db 100644 --- a/examples/clouds.py +++ b/examples/clouds.py @@ -9,6 +9,7 @@ 3. Disconnects from the controller """ + import logging from juju import jasyncio @@ -24,8 +25,8 @@ async def main(): await controller.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG) - ws_logger = logging.getLogger('websockets.protocol') + ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) jasyncio.run(main()) diff --git a/examples/config.py b/examples/config.py index 278c9b8bf..cb70abfde 100644 --- a/examples/config.py +++ b/examples/config.py @@ -9,6 +9,7 @@ 3. Deploys a charm and prints its config and constraints """ + import logging from juju.model import Model @@ -25,38 +26,38 @@ async def main(): await model.connect() ubuntu_app = await model.deploy( - 'mysql', - application_name='mysql', - series='jammy', - channel='edge', + "mysql", + application_name="mysql", + series="jammy", + channel="edge", config={ - 'cluster-name': 'foo', + "cluster-name": "foo", }, constraints={ - 'mem': 256 * MB, + "mem": 256 * MB, }, ) - await model.wait_for_idle(status='active') + await model.wait_for_idle(status="active") # update and check app config - await ubuntu_app.set_config({'cluster-name': 'bar'}) + await ubuntu_app.set_config({"cluster-name": "bar"}) config = await ubuntu_app.get_config() - assert (config['cluster-name']['value'] == 'bar') + assert config["cluster-name"]["value"] == "bar" # update and check app constraints - await ubuntu_app.set_constraints({'mem': 512 * MB}) + await ubuntu_app.set_constraints({"mem": 512 * MB}) constraints = await ubuntu_app.get_constraints() - assert (constraints['mem'] == 512 * MB) + assert constraints["mem"] == 512 * MB - print('Removing mysql') + print("Removing mysql") await ubuntu_app.remove() - print('Disconnecting from model') + print("Disconnecting from model") await model.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": # logging.basicConfig(level=logging.DEBUG) - ws_logger = logging.getLogger('websockets.protocol') + ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) jasyncio.run(main()) diff --git a/examples/connect_current_model.py b/examples/connect_current_model.py index 1b7b2749b..7aefa7515 100644 --- a/examples/connect_current_model.py +++ b/examples/connect_current_model.py @@ -5,6 +5,7 @@ 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 jasyncio @@ -18,13 +19,13 @@ async def main(): 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))) + print("There are {} applications".format(len(model.applications))) finally: if model.is_connected(): - print('Disconnecting from model') + print("Disconnecting from model") await model.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": logging.basicConfig(level=logging.INFO) jasyncio.run(main()) diff --git a/examples/controller.py b/examples/controller.py index 173c9e1a7..078ed3615 100644 --- a/examples/controller.py +++ b/examples/controller.py @@ -11,6 +11,7 @@ 5. Destroys the model """ + import logging from juju.controller import Controller @@ -22,23 +23,23 @@ async def main(): # connect to current controller with current user, per Juju CLI await controller.connect() model = await controller.add_model( - 'my-test-model', - 'aws', - 'aws-tim', + "my-test-model", + "aws", + "aws-tim", ) await model.deploy( - 'ubuntu', - application_name='ubuntu', - series='focal', - channel='stable', + "ubuntu", + application_name="ubuntu", + series="focal", + channel="stable", ) await model.disconnect() await controller.destroy_model(model.info.uuid) await controller.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG) - ws_logger = logging.getLogger('websockets.protocol') + ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) jasyncio.run(main()) diff --git a/examples/credential.py b/examples/credential.py index 9c7dfe19e..1ba8b155e 100644 --- a/examples/credential.py +++ b/examples/credential.py @@ -9,42 +9,41 @@ async def main(cloud_name, credential_name): controller = Controller() model = None - print('Connecting to controller') + print("Connecting to controller") # connect to current controller with current user, per Juju CLI await controller.connect() try: - print('Adding model') + print("Adding model") model = await controller.add_model( - 'test', - cloud_name=cloud_name, - credential_name=credential_name) + "test", cloud_name=cloud_name, credential_name=credential_name + ) # verify credential - print("Verify model's credential: {}".format( - model.info.cloud_credential_tag)) + print("Verify model's credential: {}".format(model.info.cloud_credential_tag)) # verify we can deploy - print('Deploying ubuntu') - app = await model.deploy('ch:ubuntu') + print("Deploying ubuntu") + app = await model.deploy("ch:ubuntu") - print('Waiting for active') + print("Waiting for active") await model.block_until( - lambda: app.units and all(unit.workload_status == 'active' - for unit in app.units)) + lambda: app.units + and all(unit.workload_status == "active" for unit in app.units) + ) - print('Removing ubuntu') + print("Removing ubuntu") await app.remove() finally: - print('Cleaning up') + print("Cleaning up") if model: - print('Removing model') + print("Removing model") model_uuid = model.info.uuid await model.disconnect() await controller.destroy_model(model_uuid) - print('Disconnecting') + print("Disconnecting") await controller.disconnect() -if __name__ == '__main__': - assert len(sys.argv) > 2, 'Please provide a cloud and credential name' +if __name__ == "__main__": + assert len(sys.argv) > 2, "Please provide a cloud and credential name" jasyncio.run(main(sys.argv[1], sys.argv[2])) diff --git a/examples/crossmodel.py b/examples/crossmodel.py index a5fdacc4a..f5c5638de 100644 --- a/examples/crossmodel.py +++ b/examples/crossmodel.py @@ -11,6 +11,7 @@ 3. Destroys the unit and application """ + import tempfile from logging import getLogger @@ -26,43 +27,50 @@ async def main(): await controller.connect() try: - print('Creating models') - offering_model = await controller.add_model('test-cmr-1') - consuming_model = await controller.add_model('test-cmr-2') + print("Creating models") + offering_model = await controller.add_model("test-cmr-1") + consuming_model = await controller.add_model("test-cmr-2") - print('Deploying mysql') + print("Deploying mysql") application = await offering_model.deploy( - 'ch:mysql', - application_name='mysql', - series='jammy', - channel='edge', + "ch:mysql", + application_name="mysql", + series="jammy", + channel="edge", ) - print('Waiting for active') + print("Waiting for active") await offering_model.block_until( - lambda: all(unit.workload_status == 'active' - for unit in application.units)) + lambda: all(unit.workload_status == "active" for unit in application.units) + ) - print('Adding offer') + print("Adding offer") await offering_model.create_offer("mysql:db") offers = await offering_model.list_offers() - print('Show offers', ', '.join("%s: %s" % item for offer in offers.results for item in vars(offer).items())) + print( + "Show offers", + ", ".join( + "%s: %s" % item + for offer in offers.results + for item in vars(offer).items() + ), + ) - print('Consuming offer') + print("Consuming offer") await consuming_model.consume("admin/test-cmr-1.mysql") - print('Exporting bundle') + print("Exporting bundle") with tempfile.TemporaryDirectory() as dirpath: await offering_model.export_bundle("{}/bundle.yaml".format(dirpath)) print("Remove SAAS") await consuming_model.remove_saas("mysql") - print('Removing offer') + print("Removing offer") await offering_model.remove_offer("admin/test-cmr-1.mysql", force=True) - print('Destroying models') + print("Destroying models") await controller.destroy_model(offering_model.info.uuid) await controller.destroy_model(consuming_model.info.uuid) @@ -71,9 +79,9 @@ async def main(): raise finally: - print('Disconnecting from controller') + print("Disconnecting from controller") await controller.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": jasyncio.run(main()) diff --git a/examples/crossmodel_bundle.py b/examples/crossmodel_bundle.py index 6a3ae71d6..6841976ea 100644 --- a/examples/crossmodel_bundle.py +++ b/examples/crossmodel_bundle.py @@ -13,6 +13,7 @@ 6. Destroys the units and applications """ + import time from logging import getLogger from pathlib import Path @@ -29,33 +30,39 @@ async def main(): await controller.connect() try: - print('Creating models') - offering_model = await controller.add_model('test-cmr-1') - consuming_model = await controller.add_model('test-cmr-2') + print("Creating models") + offering_model = await controller.add_model("test-cmr-1") + consuming_model = await controller.add_model("test-cmr-2") - print('Deploying mysql') + print("Deploying mysql") await offering_model.deploy( - 'ch:mysql', - application_name='mysql', - series='jammy', - channel='edge', + "ch:mysql", + application_name="mysql", + series="jammy", + channel="edge", ) - print('Waiting for active') - await offering_model.wait_for_idle(status='active') + print("Waiting for active") + await offering_model.wait_for_idle(status="active") - print('Adding offer') + print("Adding offer") await offering_model.create_offer("mysql:db") - print('Deploying bundle') - applications = await consuming_model.deploy(str('local:' / Path(__file__).absolute().parent / "cmr-bundle")) + print("Deploying bundle") + applications = await consuming_model.deploy( + str("local:" / Path(__file__).absolute().parent / "cmr-bundle") + ) - print('Waiting for application to start') + print("Waiting for application to start") await consuming_model.block_until( - lambda: all(unit.agent_status == 'executing' - for application in applications for unit in application.units)) + lambda: all( + unit.agent_status == "executing" + for application in applications + for unit in application.units + ) + ) - print('Exporting bundle') + print("Exporting bundle") bundle = await consuming_model.export_bundle() print(bundle) @@ -64,10 +71,10 @@ async def main(): print("Remove SAAS") await consuming_model.remove_saas("mysql") - print('Removing offer') + print("Removing offer") await offering_model.remove_offer("admin/test-cmr-1.mysql", force=True) - print('Destroying models') + print("Destroying models") await controller.destroy_model(offering_model.info.uuid) await controller.destroy_model(consuming_model.info.uuid) @@ -76,9 +83,9 @@ async def main(): raise finally: - print('Disconnecting from controller') + print("Disconnecting from controller") await controller.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": jasyncio.run(main()) diff --git a/examples/crossmodel_controller.py b/examples/crossmodel_controller.py index 00167d00e..fda5788fe 100644 --- a/examples/crossmodel_controller.py +++ b/examples/crossmodel_controller.py @@ -15,6 +15,7 @@ 9. Removes the offer 10. Destroys models and disconnects """ + import tempfile from logging import getLogger @@ -34,43 +35,50 @@ async def main(): await controller2.connect("test2") try: - print('Creating models') - offering_model = await controller1.add_model('test-cmr-1') - consuming_model = await controller2.add_model('test-cmr-2') + print("Creating models") + offering_model = await controller1.add_model("test-cmr-1") + consuming_model = await controller2.add_model("test-cmr-2") - print('Deploying mysql') + print("Deploying mysql") application = await offering_model.deploy( - 'ch:mysql', - application_name='mysql', - series='trusty', - channel='stable', + "ch:mysql", + application_name="mysql", + series="trusty", + channel="stable", ) - print('Waiting for active') + print("Waiting for active") await offering_model.block_until( - lambda: all(unit.workload_status == 'active' - for unit in application.units)) + lambda: all(unit.workload_status == "active" for unit in application.units) + ) - print('Adding offer') + print("Adding offer") await offering_model.create_offer("mysql:db") offers = await offering_model.list_offers() - print('Show offers', ', '.join("%s: %s" % item for offer in offers.results for item in vars(offer).items())) + print( + "Show offers", + ", ".join( + "%s: %s" % item + for offer in offers.results + for item in vars(offer).items() + ), + ) - print('Consuming offer') + print("Consuming offer") await consuming_model.consume("admin/test-cmr-1.mysql", controller_name="test") - print('Exporting bundle') + print("Exporting bundle") with tempfile.TemporaryDirectory() as dirpath: await offering_model.export_bundle("{}/bundle.yaml".format(dirpath)) print("Remove SAAS") await consuming_model.remove_saas("mysql") - print('Removing offer') + print("Removing offer") await offering_model.remove_offer("admin/test-cmr-1.mysql", force=True) - print('Destroying models') + print("Destroying models") await controller1.destroy_model(offering_model.info.uuid) await controller2.destroy_model(consuming_model.info.uuid) @@ -79,10 +87,10 @@ async def main(): raise finally: - print('Disconnecting from controller') + print("Disconnecting from controller") await controller1.disconnect() await controller2.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": jasyncio.run(main()) diff --git a/examples/crossmodel_relation.py b/examples/crossmodel_relation.py index d878db9a0..42e8b2b50 100644 --- a/examples/crossmodel_relation.py +++ b/examples/crossmodel_relation.py @@ -13,6 +13,7 @@ 6. Destroys the units and applications """ + import tempfile import time from logging import getLogger @@ -29,49 +30,58 @@ async def main(): await controller.connect() try: - print('Creating models') - offering_model = await controller.add_model('test-cmr-1') - consuming_model = await controller.add_model('test-cmr-2') + print("Creating models") + offering_model = await controller.add_model("test-cmr-1") + consuming_model = await controller.add_model("test-cmr-2") - print('Deploying mysql') + print("Deploying mysql") await offering_model.deploy( - 'ch:mysql', - application_name='mysql', - series='jammy', - channel='edge', + "ch:mysql", + application_name="mysql", + series="jammy", + channel="edge", ) - print('Waiting for active') - await offering_model.wait_for_idle(status='active') + print("Waiting for active") + await offering_model.wait_for_idle(status="active") - print('Adding offer') + print("Adding offer") await offering_model.create_offer("mysql:db") offers = await offering_model.list_offers() await offering_model.block_until( - lambda: all(offer.application_name == 'mysql' - for offer in offers.results)) + lambda: all(offer.application_name == "mysql" for offer in offers.results) + ) - print('Show offers', ', '.join("%s: %s" % item for offer in offers.results for item in vars(offer).items())) + print( + "Show offers", + ", ".join( + "%s: %s" % item + for offer in offers.results + for item in vars(offer).items() + ), + ) # TODO (cderici): wordpress charm is somewhat problematic in 3.0, # this example needs to be revisited. - print('Deploying wordpress') + print("Deploying wordpress") application_2 = await consuming_model.deploy( - 'ch:trusty/wordpress', - application_name='wordpress', - series='xenial', - channel='stable', + "ch:trusty/wordpress", + application_name="wordpress", + series="xenial", + channel="stable", ) - print('Waiting for executing') + print("Waiting for executing") await consuming_model.block_until( - lambda: all(unit.agent_status == 'executing' - for unit in application_2.units)) + lambda: all( + unit.agent_status == "executing" for unit in application_2.units + ) + ) - await consuming_model.relate('wordpress', 'admin/test-cmr-1.mysql') + await consuming_model.relate("wordpress", "admin/test-cmr-1.mysql") - print('Exporting bundle') + print("Exporting bundle") with tempfile.TemporaryDirectory() as dirpath: await offering_model.export_bundle("{}/bundle.yaml".format(dirpath)) @@ -80,10 +90,10 @@ async def main(): print("Remove SAAS") await consuming_model.remove_saas("mysql") - print('Removing offer') + print("Removing offer") await offering_model.remove_offer("admin/test-cmr-1.mysql", force=True) - print('Destroying models') + print("Destroying models") await controller.destroy_model(offering_model.info.uuid) await controller.destroy_model(consuming_model.info.uuid) @@ -92,9 +102,9 @@ async def main(): raise finally: - print('Disconnecting from controller') + print("Disconnecting from controller") await controller.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": jasyncio.run(main()) diff --git a/examples/debug-log.py b/examples/debug-log.py index 823c9852f..0200f0c16 100644 --- a/examples/debug-log.py +++ b/examples/debug-log.py @@ -5,6 +5,7 @@ This example demonstrate how debug-log works """ + from juju import jasyncio from juju.model import Model @@ -23,17 +24,17 @@ async def main(): ) application = await model.deploy( - 'ch:ubuntu', - application_name='ubuntu', - series='trusty', - channel='stable', + "ch:ubuntu", + application_name="ubuntu", + series="trusty", + channel="stable", ) - await model.wait_for_idle(status='active') + await model.wait_for_idle(status="active") await application.remove() await model.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": jasyncio.run(main()) diff --git a/examples/deploy.py b/examples/deploy.py index 9d1ea00fc..e1a2ce9e9 100644 --- a/examples/deploy.py +++ b/examples/deploy.py @@ -9,34 +9,35 @@ 3. Destroys the unit and application """ + from juju import jasyncio from juju.model import Model async def main(): model = Model() - print('Connecting to model') + print("Connecting to model") # connect to current model with current user, per Juju CLI await model.connect() try: - print('Deploying ubuntu') + print("Deploying ubuntu") application = await model.deploy( - 'ch:ubuntu', - application_name='ubuntu', - series='trusty', - channel='stable', + "ch:ubuntu", + application_name="ubuntu", + series="trusty", + channel="stable", ) - print('Waiting for active') - await model.wait_for_idle(status='active') + print("Waiting for active") + await model.wait_for_idle(status="active") - print('Removing ubuntu') + print("Removing ubuntu") await application.remove() finally: - print('Disconnecting from model') + print("Disconnecting from model") await model.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": jasyncio.run(main()) diff --git a/examples/deploy_bundle.py b/examples/deploy_bundle.py index eb4ac6374..79a379e55 100644 --- a/examples/deploy_bundle.py +++ b/examples/deploy_bundle.py @@ -9,6 +9,7 @@ 3. Destroys the units and applications """ + from juju.controller import Controller from juju import jasyncio @@ -19,26 +20,26 @@ async def main(): await controller.connect() # Deploy charmhub bundle - await deploy_bundle(controller, 'juju-qa-bundle-test') + await deploy_bundle(controller, "juju-qa-bundle-test") await controller.disconnect() async def deploy_bundle(controller, url, channel=None): models = await controller.list_models() - model = await controller.add_model('model{}'.format(len(models) + 1)) + model = await controller.add_model("model{}".format(len(models) + 1)) try: - print('Deploying bundle') + print("Deploying bundle") applications = await deploy_and_wait_for_bundle(model, url, channel) print("Successfully deployed!") - print('Removing bundle') + print("Removing bundle") for application in applications: await application.remove() finally: - print('Disconnecting from model') + print("Disconnecting from model") await model.disconnect() print("Success") @@ -46,12 +47,17 @@ async def deploy_bundle(controller, url, channel=None): async def deploy_and_wait_for_bundle(model, url, channel=None): applications = await model.deploy(url, channel=channel) - print('Waiting for active') + print("Waiting for active") await model.block_until( - lambda: all(unit.workload_status == 'active' - for application in applications for unit in application.units)) + lambda: all( + unit.workload_status == "active" + for application in applications + for unit in application.units + ) + ) return applications -if __name__ == '__main__': + +if __name__ == "__main__": jasyncio.run(main()) diff --git a/examples/deploy_bundle_charmhub.py b/examples/deploy_bundle_charmhub.py index 9119b6fd8..36a90af27 100644 --- a/examples/deploy_bundle_charmhub.py +++ b/examples/deploy_bundle_charmhub.py @@ -7,6 +7,7 @@ 2. Deploy a bundle from charmhub and waits until it reports itself active 3. Destroys the unit and application """ + from juju import jasyncio from juju.model import Model diff --git a/examples/deploy_bundle_with_trust.py b/examples/deploy_bundle_with_trust.py index 22a3cd442..a3552b48e 100644 --- a/examples/deploy_bundle_with_trust.py +++ b/examples/deploy_bundle_with_trust.py @@ -9,35 +9,40 @@ 3. Destroys the units and applications """ + from juju import jasyncio from juju.model import Model async def main(): model = Model() - print('Connecting to model') + print("Connecting to model") # Connect to current model with current user, per Juju CLI await model.connect() try: - print('Deploying trusted bundle application ubuntu') + print("Deploying trusted bundle application ubuntu") applications = await model.deploy( - 'ch:aws-integrator', + "ch:aws-integrator", trust=True, ) - print('Waiting for active') + print("Waiting for active") await model.block_until( - lambda: all(unit.workload_status == 'active' - for application in applications for unit in application.units)) + lambda: all( + unit.workload_status == "active" + for application in applications + for unit in application.units + ) + ) print("Successfully deployed!") - print('Removing bundle') + print("Removing bundle") for application in applications: await application.remove() finally: - print('Disconnecting from model') + print("Disconnecting from model") await model.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": jasyncio.run(main()) diff --git a/examples/deploy_constraints.py b/examples/deploy_constraints.py index 077e59bc1..c5eeaff68 100644 --- a/examples/deploy_constraints.py +++ b/examples/deploy_constraints.py @@ -9,6 +9,7 @@ 3. Attempts to deploy a charm with constraints """ + from juju import jasyncio from juju.controller import Controller @@ -19,21 +20,20 @@ async def main(): try: model = await controller.add_model("test-model") - application = await model.deploy("ch:ubuntu", - constraints={"arch": "amd64"}) + application = await model.deploy("ch:ubuntu", constraints={"arch": "amd64"}) - print('Waiting for active') + print("Waiting for active") await model.block_until( - lambda: all(unit.workload_status == 'active' - for unit in application.units)) + lambda: all(unit.workload_status == "active" for unit in application.units) + ) print("Successfully deployed!") - print('Removing bundle') + print("Removing bundle") await application.remove() finally: - print('Disconnecting from controller') + print("Disconnecting from controller") await controller.disconnect() print("Success") -if __name__ == '__main__': +if __name__ == "__main__": jasyncio.run(main()) diff --git a/examples/deploy_local_big_k8s_bundle.py b/examples/deploy_local_big_k8s_bundle.py index 76a548f58..686a7b2f5 100644 --- a/examples/deploy_local_big_k8s_bundle.py +++ b/examples/deploy_local_big_k8s_bundle.py @@ -9,28 +9,29 @@ 3. Destroys the units and applications """ + from juju import jasyncio from juju.model import Model async def main(): model = Model() - print('Connecting to model') + print("Connecting to model") # Connect to current model with current user, per Juju CLI await model.connect() try: - print('Deploying bundle') + print("Deploying bundle") await model.deploy( - './examples/k8s-local-bundle/big-k8s-bundle.yaml', - channel='edge', + "./examples/k8s-local-bundle/big-k8s-bundle.yaml", + channel="edge", trust=True, ) finally: - print('Disconnecting from model') + print("Disconnecting from model") await model.disconnect() print("Success") -if __name__ == '__main__': +if __name__ == "__main__": jasyncio.run(main()) diff --git a/examples/deploy_local_bundle_with_resources.py b/examples/deploy_local_bundle_with_resources.py index bb32badc6..eb6c9c1c2 100644 --- a/examples/deploy_local_bundle_with_resources.py +++ b/examples/deploy_local_bundle_with_resources.py @@ -9,35 +9,40 @@ 3. Destroys the units and applications """ + from juju import jasyncio from juju.model import Model async def main(): model = Model() - print('Connecting to model') + print("Connecting to model") # Connect to current model with current user, per Juju CLI await model.connect() try: - print('Deploying bundle') + print("Deploying bundle") applications = await model.deploy( - './examples/k8s-local-bundle/bundle.yaml', + "./examples/k8s-local-bundle/bundle.yaml", ) - print('Waiting for active') + print("Waiting for active") await model.block_until( - lambda: all(unit.workload_status == 'active' - for application in applications for unit in application.units)) + lambda: all( + unit.workload_status == "active" + for application in applications + for unit in application.units + ) + ) print("Successfully deployed!") - print('Removing bundle') + print("Removing bundle") for application in applications: await application.remove() finally: - print('Disconnecting from model') + print("Disconnecting from model") await model.disconnect() print("Success") -if __name__ == '__main__': +if __name__ == "__main__": jasyncio.run(main()) diff --git a/examples/deploy_local_file_resource.py b/examples/deploy_local_file_resource.py index 59da4da6b..6a739e93d 100644 --- a/examples/deploy_local_file_resource.py +++ b/examples/deploy_local_file_resource.py @@ -10,6 +10,7 @@ 3. Destroys the unit and application """ + from juju import jasyncio from juju.model import Model from pathlib import Path @@ -17,25 +18,25 @@ async def main(): model = Model() - print('Connecting to model') + print("Connecting to model") # connect to current model with current user, per Juju CLI await model.connect() application = None try: - print('Deploying local-charm') + print("Deploying local-charm") base_dir = Path(__file__).absolute().parent.parent - charm_path = '{}/tests/integration/file-resource-charm'.format(base_dir) + charm_path = "{}/tests/integration/file-resource-charm".format(base_dir) resources = {"file-res": "test.file"} application = await model.deploy( charm_path, resources=resources, ) - print('Waiting for active') + print("Waiting for active") await model.wait_for_idle() - print('Removing Charm') + print("Removing Charm") await application.remove() except Exception as e: print(e) @@ -43,9 +44,9 @@ async def main(): await application.remove() await model.disconnect() finally: - print('Disconnecting from model') + print("Disconnecting from model") await model.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": jasyncio.run(main()) diff --git a/examples/deploy_local_resource.py b/examples/deploy_local_resource.py index c2a34588e..dc3c3e18f 100644 --- a/examples/deploy_local_resource.py +++ b/examples/deploy_local_resource.py @@ -10,6 +10,7 @@ 3. Destroys the unit and application """ + from juju import jasyncio from juju.model import Model from pathlib import Path @@ -17,33 +18,32 @@ async def main(): model = Model() - print('Connecting to model') + print("Connecting to model") # connect to current model with current user, per Juju CLI await model.connect() try: - print('Deploying local-charm') + print("Deploying local-charm") base_dir = Path(__file__).absolute().parent.parent - charm_path = '{}/tests/integration/oci-image-charm'.format(base_dir) + charm_path = "{}/tests/integration/oci-image-charm".format(base_dir) resources = {"oci-image": "ubuntu/latest"} application = await model.deploy( charm_path, resources=resources, ) - print('Waiting for active') + print("Waiting for active") await model.block_until( - lambda: all(unit.workload_status == 'active' - for unit in application.units), + lambda: all(unit.workload_status == "active" for unit in application.units), timeout=120, ) - print('Removing Charm') + print("Removing Charm") await application.remove() finally: - print('Disconnecting from model') + print("Disconnecting from model") await model.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": jasyncio.run(main()) diff --git a/examples/deploy_with_revision.py b/examples/deploy_with_revision.py index 8ceafc066..f7ce3b11d 100644 --- a/examples/deploy_with_revision.py +++ b/examples/deploy_with_revision.py @@ -6,31 +6,31 @@ async def main(): - charm = 'juju-qa-test' + charm = "juju-qa-test" model = Model() - print('Connecting to model') + print("Connecting to model") # connect to current model with current user, per Juju CLI await model.connect() try: - print(f'Deploying {charm} --channel 2.0/stable --revision 22') + print(f"Deploying {charm} --channel 2.0/stable --revision 22") application = await model.deploy( - 'juju-qa-test', - application_name='test', - channel='2.0/stable', + "juju-qa-test", + application_name="test", + channel="2.0/stable", revision=22, ) - print('Waiting for active') - await model.wait_for_idle(status='active') + print("Waiting for active") + await model.wait_for_idle(status="active") - print(f'Removing {charm}') + print(f"Removing {charm}") await application.remove() finally: - print('Disconnecting from model') + print("Disconnecting from model") await model.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": jasyncio.run(main()) diff --git a/examples/expose-application.py b/examples/expose-application.py index a9dbf1722..bd96f95dc 100644 --- a/examples/expose-application.py +++ b/examples/expose-application.py @@ -11,6 +11,7 @@ NOTE: this test must be run against a 2.9 controller. """ + from juju import jasyncio from juju.model import Model from juju.application import ExposedEndpoint @@ -18,61 +19,67 @@ async def main(): model = Model() - print('Connecting to model') + print("Connecting to model") # connect to current model with current user, per Juju CLI await model.connect() try: - print('Deploying ubuntu') + print("Deploying ubuntu") application = await model.deploy( - 'ch:ubuntu', - application_name='ubuntu', - series='jammy', - channel='stable', + "ch:ubuntu", + application_name="ubuntu", + series="jammy", + channel="stable", ) - print('Waiting for active') + print("Waiting for active") await model.block_until( - lambda: all(unit.workload_status == 'active' - for unit in application.units)) + lambda: all(unit.workload_status == "active" for unit in application.units) + ) - print('Expose all opened port ranges') + print("Expose all opened port ranges") await application.expose() - print('Expose all opened port ranges to the CIDRs that correspond to a list of spaces') - await application.expose(exposed_endpoints={ - "": ExposedEndpoint(to_spaces=["alpha"]) - }) + print( + "Expose all opened port ranges to the CIDRs that correspond to a list of spaces" + ) + await application.expose( + exposed_endpoints={"": ExposedEndpoint(to_spaces=["alpha"])} + ) - print('Expose all opened port ranges to a list of CIDRs') - await application.expose(exposed_endpoints={ - "": ExposedEndpoint(to_cidrs=["10.0.0.0/24"]) - }) + print("Expose all opened port ranges to a list of CIDRs") + await application.expose( + exposed_endpoints={"": ExposedEndpoint(to_cidrs=["10.0.0.0/24"])} + ) - print('Expose all opened port ranges to a list of spaces and CIDRs') - await application.expose(exposed_endpoints={ - "": ExposedEndpoint(to_spaces=["alpha"], to_cidrs=["10.0.0.0/24"]) - }) + print("Expose all opened port ranges to a list of spaces and CIDRs") + await application.expose( + exposed_endpoints={ + "": ExposedEndpoint(to_spaces=["alpha"], to_cidrs=["10.0.0.0/24"]) + } + ) - print('Expose individual endpoints to different space/CIDR combinations') - await application.expose(exposed_endpoints={ - "": ExposedEndpoint(to_spaces=["alpha"], to_cidrs=["10.0.0.0/24"]), - "ubuntu": ExposedEndpoint(to_cidrs=["10.42.42.0/24"]) - }) + print("Expose individual endpoints to different space/CIDR combinations") + await application.expose( + exposed_endpoints={ + "": ExposedEndpoint(to_spaces=["alpha"], to_cidrs=["10.0.0.0/24"]), + "ubuntu": ExposedEndpoint(to_cidrs=["10.42.42.0/24"]), + } + ) # TODO (cderici) : this part needs to be revisited - print('Unexpose individual endpoints (other endpoints remain exposed)') + print("Unexpose individual endpoints (other endpoints remain exposed)") await application.unexpose(exposed_endpoints=["ubuntu"]) - print('Unexpose application') + print("Unexpose application") await application.unexpose() - print('Removing ubuntu') + print("Removing ubuntu") await application.remove() finally: - print('Disconnecting from model') + print("Disconnecting from model") await model.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": jasyncio.run(main()) diff --git a/examples/formatted_status.py b/examples/formatted_status.py index 74932fce6..a0b7cd9fb 100644 --- a/examples/formatted_status.py +++ b/examples/formatted_status.py @@ -6,6 +6,7 @@ description. For a similar solution using the FullStatus object check examples/fullstatus.py """ + from juju import jasyncio import logging import sys @@ -24,25 +25,26 @@ async def main(): await model.connect_current() application = await model.deploy( - 'ch:ubuntu', - application_name='ubuntu', - series='trusty', - channel='stable', + "ch:ubuntu", + application_name="ubuntu", + series="trusty", + channel="stable", ) await jasyncio.sleep(10) tmp = tempfile.NamedTemporaryFile(delete=False) - LOG.info('status dumped to %s', tmp.name) - with open(tmp.name, 'w') as f: + LOG.info("status dumped to %s", tmp.name) + with open(tmp.name, "w") as f: for i in range(10): # Uncomment this line to get the full status # using the standard output. # await formatted_status(model, target=sys.stdout) await formatted_status(model, target=f) - f.write('-----------\n') + f.write("-----------\n") await jasyncio.sleep(1) await application.remove() await model.disconnect() -if __name__ == '__main__': + +if __name__ == "__main__": jasyncio.run(main()) diff --git a/examples/fullstatus.py b/examples/fullstatus.py index 918415218..2cee31210 100644 --- a/examples/fullstatus.py +++ b/examples/fullstatus.py @@ -12,11 +12,12 @@ async def status(): status = await model.get_status() await model.disconnect() - print('Applications:', list(status.applications.keys())) - print('Machines:', list(status.machines.keys())) - print('Relations:', status.relations) + print("Applications:", list(status.applications.keys())) + print("Machines:", list(status.machines.keys())) + print("Relations:", status.relations) return status -if __name__ == '__main__': + +if __name__ == "__main__": jasyncio.run(status()) diff --git a/examples/future.py b/examples/future.py index c9b789909..0054fecb7 100644 --- a/examples/future.py +++ b/examples/future.py @@ -5,6 +5,7 @@ This example doesn't work - it demonstrates features that don't exist yet. """ + import logging from juju.model import Model @@ -16,35 +17,32 @@ async def main(): # connect to current model with current user, per Juju CLI await model.connect() - goal_state = Model.from_yaml('bundle-like-thing') + goal_state = Model.from_yaml("bundle-like-thing") ubuntu_app = await model.deploy( - 'ch:ubuntu', - application_name='ubuntu', - series='trusty', - channel='stable', + "ch:ubuntu", + application_name="ubuntu", + series="trusty", + channel="stable", ) ubuntu_app.on_unit_added(callback=lambda unit: True) await model.deploy( - 'ch:nrpe', - application_name='nrpe', - series='trusty', - channel='stable', + "ch:nrpe", + application_name="nrpe", + series="trusty", + channel="stable", num_units=0, ) await model.relate( - 'ubuntu', - 'nrpe', + "ubuntu", + "nrpe", ) - result, ok = await model.block_until( - lambda: model.matches(goal_state), - timeout=600 - ) + result, ok = await model.block_until(lambda: model.matches(goal_state), timeout=600) -if __name__ == '__main__': +if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG) - ws_logger = logging.getLogger('websockets.protocol') + ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) jasyncio.run(main()) diff --git a/examples/get_cloud.py b/examples/get_cloud.py index be3f80cd4..322998608 100644 --- a/examples/get_cloud.py +++ b/examples/get_cloud.py @@ -9,6 +9,7 @@ 3. Disconnects from the controller """ + import logging from juju import jasyncio @@ -25,8 +26,8 @@ async def main(): await controller.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG) - ws_logger = logging.getLogger('websockets.protocol') + ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) jasyncio.run(main()) diff --git a/examples/k8s-local-bundle/big-k8s-bundle.yaml b/examples/k8s-local-bundle/big-k8s-bundle.yaml index 799433bc4..3c26e585e 100644 --- a/examples/k8s-local-bundle/big-k8s-bundle.yaml +++ b/examples/k8s-local-bundle/big-k8s-bundle.yaml @@ -1,12 +1,12 @@ bundle: kubernetes name: magma-orc8r description: | - Orchestrator is a Magma service that provides a simple and consistent way to - configure and monitor the wireless network securely. The metrics acquired through the platform + Orchestrator is a Magma service that provides a simple and consistent way to + configure and monitor the wireless network securely. The metrics acquired through the platform allows you to see the analytics and traffic flows of the wireless users through the Magma web UI. applications: nms-magmalte: charm: magma-nms-magmalte channel: edge scale: 1 - trust: true \ No newline at end of file + trust: true diff --git a/examples/leadership.py b/examples/leadership.py index d11d7cd5b..d0d36ab28 100644 --- a/examples/leadership.py +++ b/examples/leadership.py @@ -9,6 +9,7 @@ 3. Cleanly disconnects. """ + from juju import jasyncio from juju.model import Model @@ -20,11 +21,10 @@ async def report_leadership(): print("Leadership: ") for app in model.applications.values(): for unit in app.units: - print("{}: {}".format( - unit.name, await unit.is_leader_from_status())) + print("{}: {}".format(unit.name, await unit.is_leader_from_status())) await model.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": jasyncio.run(report_leadership()) diff --git a/examples/list_secrets.py b/examples/list_secrets.py index c7467ba6d..0aabc70d9 100644 --- a/examples/list_secrets.py +++ b/examples/list_secrets.py @@ -6,7 +6,6 @@ async def main(): - m = Model() await m.connect() @@ -15,5 +14,5 @@ async def main(): await m.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": jasyncio.run(main()) diff --git a/examples/livemodel.py b/examples/livemodel.py index a16423e5b..ce7f2999c 100644 --- a/examples/livemodel.py +++ b/examples/livemodel.py @@ -9,6 +9,7 @@ 3. Runs forever (kill with Ctrl-C) """ + from juju.model import Model from juju import jasyncio @@ -28,7 +29,7 @@ async def watch_model(): model.add_observer(on_model_change) -if __name__ == '__main__': +if __name__ == "__main__": # Run loop until the process is manually stopped (watch_model will loop # forever). jasyncio.run(watch_model()) diff --git a/examples/local_refresh.py b/examples/local_refresh.py index 8642d82fb..7ffd70547 100644 --- a/examples/local_refresh.py +++ b/examples/local_refresh.py @@ -8,26 +8,27 @@ 2. Upgrades previously deployed ubuntu charm """ + from juju import jasyncio from juju.model import Model async def main(): model = Model() - print('Connecting to model') + print("Connecting to model") # connect to current model with current user, per Juju CLI await model.connect() try: - print('Get deployed application') + print("Get deployed application") app = model.applications["ubuntu"] - print('Refresh/Upgrade Ubuntu charm with local charm') + print("Refresh/Upgrade Ubuntu charm with local charm") await app.refresh(path="path/to/local/ubuntu.charm") finally: - print('Disconnecting from model') + print("Disconnecting from model") await model.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": jasyncio.run(main()) diff --git a/examples/localcharm.py b/examples/localcharm.py index bf2012a01..93c8e9664 100644 --- a/examples/localcharm.py +++ b/examples/localcharm.py @@ -9,6 +9,7 @@ 3. Deploys the uploaded charm. """ + import logging from juju import jasyncio @@ -21,16 +22,16 @@ async def main(): # Deploy a local charm using a path to the charm directory await model.deploy( - './charms/ubuntu', - application_name='ubuntu', - series='trusty', + "./charms/ubuntu", + application_name="ubuntu", + series="trusty", ) await model.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG) - ws_logger = logging.getLogger('websockets.protocol') + ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) jasyncio.run(main()) diff --git a/examples/machine_hostname.py b/examples/machine_hostname.py index 8ea959b90..5b9ccfb5f 100644 --- a/examples/machine_hostname.py +++ b/examples/machine_hostname.py @@ -14,6 +14,7 @@ NOTE: this example requires a 2.8.10+ controller. """ + import logging from juju import jasyncio @@ -30,8 +31,7 @@ async def main(): try: # Add a machine and wait until the machine agents starts machine1 = await model.add_machine() - await model.block_until( - lambda: machine1.agent_status == 'started') + await model.block_until(lambda: machine1.agent_status == "started") # At this point we can access the reported hostname via the hostname # property of the machine model. @@ -42,9 +42,9 @@ async def main(): await model.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG) - ws_logger = logging.getLogger('websockets.protocol') + ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) jasyncio.run(main()) diff --git a/examples/model.py b/examples/model.py index 06b24b690..5fdc6483f 100755 --- a/examples/model.py +++ b/examples/model.py @@ -9,6 +9,7 @@ 3. Disconnect then reconnect. """ + from juju import jasyncio from juju.model import Model from juju.errors import JujuEntityNotFoundError @@ -21,7 +22,7 @@ async def main(): for i in range(0, retryCount): await model.connect_current() try: - model.applications['foo'].relations + model.applications["foo"].relations except JujuEntityNotFoundError as e: print(e.entity_name) finally: @@ -29,5 +30,5 @@ async def main(): # Everything worked out, continue on wards. -if __name__ == '__main__': +if __name__ == "__main__": jasyncio.run(main()) diff --git a/examples/modelsummaries.py b/examples/modelsummaries.py index ffe3422da..ac1d49569 100644 --- a/examples/modelsummaries.py +++ b/examples/modelsummaries.py @@ -10,6 +10,7 @@ 4. Runs forever (kill with Ctrl-C) """ + import asyncio import logging @@ -34,11 +35,11 @@ def callback(summary): await asyncio.sleep(1) -if __name__ == '__main__': +if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG) - ws_logger = logging.getLogger('websockets.protocol') + ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) - logging.getLogger('juju.client.connection').setLevel(logging.INFO) + logging.getLogger("juju.client.connection").setLevel(logging.INFO) # Run loop until the process is manually stopped (watch will loop # forever). jasyncio.run(watch()) diff --git a/examples/relate.py b/examples/relate.py index 938ca3122..7ab3912cd 100644 --- a/examples/relate.py +++ b/examples/relate.py @@ -10,6 +10,7 @@ 4. Waits for units to be idle, then exits """ + import asyncio import logging @@ -19,15 +20,15 @@ class MyRemoveObserver(ModelObserver): async def on_change(self, delta, old, new, model): - if delta.type == 'remove': - assert (new.latest() == new) - assert (new.next() is None) - assert (new.dead) - assert (new.current) - assert (new.connected) - assert (new.previous().dead) - assert (not new.previous().current) - assert (not new.previous().connected) + if delta.type == "remove": + assert new.latest() == new + assert new.next() is None + assert new.dead + assert new.current + assert new.connected + assert new.previous().dead + assert not new.previous().current + assert not new.previous().connected class MyModelObserver(ModelObserver): @@ -36,7 +37,7 @@ class MyModelObserver(ModelObserver): async def on_change(self, delta, old, new, model): if model.units and model.all_units_idle() and not self._shutting_down: self._shutting_down = True - logging.debug('All units idle, disconnecting') + logging.debug("All units idle, disconnecting") await model.reset(force=True) await model.disconnect() @@ -52,54 +53,72 @@ async def main(): model.add_observer(MyModelObserver()) ubuntu_app = await model.deploy( - 'ch:ubuntu', - application_name='ubuntu', - series='trusty', - channel='stable', + "ch: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) + ) + ) ) - 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)) - )) + unit_a.on_change( + asyncio.coroutine( + lambda delta, old_unit, new_unit, model: print( + "Unit changed: {}".format(new_unit.entity_id) + ) + ) + ) await model.deploy( - 'ch:nrpe', - application_name='nrpe', - series='trusty', - channel='stable', + "ch:nrpe", + application_name="nrpe", + series="trusty", + channel="stable", # subordinates must be deployed without units num_units=0, ) my_relation = await model.relate( - 'ubuntu', - 'nrpe', + "ubuntu", + "nrpe", + ) + my_relation.on_remove( + asyncio.coroutine( + lambda delta, old_rel, new_rel, model: print( + "Relation removed: {}".format(old_rel.endpoints) + ) + ) ) - 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.INFO) - ws_logger = logging.getLogger('websockets.protocol') + ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) jasyncio.run(main()) diff --git a/examples/run_action.py b/examples/run_action.py index 0f8ddfd4c..2f1cf83bc 100644 --- a/examples/run_action.py +++ b/examples/run_action.py @@ -19,15 +19,15 @@ async def _get_password(): model = Model() await model.connect() - await model.deploy('zinc-k8s') + await model.deploy("zinc-k8s") await model.wait_for_idle(status="active") - unit = model.applications['zinc-k8s'].units[0] + unit = model.applications["zinc-k8s"].units[0] action1 = await unit.run_action("get-admin-password") - assert action1.status == 'pending' + assert action1.status == "pending" action2 = await action1.wait() - assert action2.status == 'completed' + assert action2.status == "completed" print(action2.results["admin-password"]) diff --git a/examples/scp.py b/examples/scp.py index 37daa7aa6..11d0c5265 100644 --- a/examples/scp.py +++ b/examples/scp.py @@ -8,6 +8,7 @@ Then attempts to use scp to grab the profile, as a way to show how scp works from a pylibjuju perspective. """ + import logging from juju import jasyncio @@ -21,18 +22,18 @@ async def main(): 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))) + print("There are {} applications".format(len(model.applications))) - machine = model.machines['0'] + machine = model.machines["0"] # This roughly expands to the following: # scp -i ~/.local/share/juju/ssh/juju_id_rsa -o StrictHostKeyChecking=no -q -B ubuntu@10.132.183.88:/home/ubuntu/.profile /tmp/profile await machine.scp_from("/home/ubuntu/.profile", "/tmp/profile") finally: if model.is_connected(): - print('Disconnecting from model') + print("Disconnecting from model") await model.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": logging.basicConfig(level=logging.INFO) jasyncio.run(main()) diff --git a/examples/status.py b/examples/status.py index 0f1e0134f..9ce52d424 100644 --- a/examples/status.py +++ b/examples/status.py @@ -5,6 +5,7 @@ This example demonstrate how status works """ + from juju import jasyncio import logging import sys @@ -21,10 +22,10 @@ async def main(): await model.connect_current() application = await model.deploy( - 'ch:ubuntu', - application_name='ubuntu', - series='jammy', - channel='stable', + "ch:ubuntu", + application_name="ubuntu", + series="jammy", + channel="stable", ) await jasyncio.sleep(10) # Print the status to observe the evolution @@ -41,11 +42,12 @@ async def main(): print(e) await jasyncio.sleep(5) - print('Removing ubuntu') + print("Removing ubuntu") await application.remove() - print('Disconnecting from model') + print("Disconnecting from model") await model.disconnect() -if __name__ == '__main__': + +if __name__ == "__main__": jasyncio.run(main()) diff --git a/examples/unitrun.py b/examples/unitrun.py index eeeb12fad..996461435 100644 --- a/examples/unitrun.py +++ b/examples/unitrun.py @@ -10,6 +10,7 @@ 4. Waits for the action results to come back, then exits. """ + import logging from juju.model import Model @@ -17,10 +18,10 @@ async def run_command(unit): - logging.debug('Running command on unit %s', unit.name) + logging.debug("Running command on unit %s", unit.name) # unit.run() returns a juju.action.Action instance, # it needs to be wait()'ed to get the results - action = await unit.run('unit-get public-address') + action = await unit.run("unit-get public-address") await action.wait() out1 = f"Action status: {action.status}" @@ -40,10 +41,10 @@ async def main(): await model.connect() app = await model.deploy( - 'ch:ubuntu', - application_name='ubuntu', - series='trusty', - channel='stable', + "ch:ubuntu", + application_name="ubuntu", + series="trusty", + channel="stable", ) for unit in app.units: @@ -54,7 +55,7 @@ async def main(): await model.disconnect() -if __name__ == '__main__': +if __name__ == "__main__": # Uncomment below to get logging output # logging.basicConfig(level=logging.DEBUG) diff --git a/examples/upgrade_local_charm_k8s.py b/examples/upgrade_local_charm_k8s.py index 3b6002b36..c005fb1a1 100644 --- a/examples/upgrade_local_charm_k8s.py +++ b/examples/upgrade_local_charm_k8s.py @@ -10,40 +10,41 @@ 4. Destroys the units and applications """ + from juju import jasyncio from juju.model import Model async def main(): model = Model() - print('Connecting to model') + print("Connecting to model") # Connect to current model with current user, per Juju CLI await model.connect() try: - print('Deploying bundle') + print("Deploying bundle") applications = await model.deploy( - './examples/k8s-local-bundle/bundle.yaml', + "./examples/k8s-local-bundle/bundle.yaml", ) - print('Waiting for active') - await model.wait_for_idle(status='active') + print("Waiting for active") + await model.wait_for_idle(status="active") print("Successfully deployed!") - local_path = './examples/charms/onos.charm' - print('Upgrading charm with %s' % local_path) + local_path = "./examples/charms/onos.charm" + print("Upgrading charm with %s" % local_path) await applications[0].upgrade_charm(path=local_path) - await model.wait_for_idle(status='active') + await model.wait_for_idle(status="active") - print('Removing bundle') + print("Removing bundle") for application in applications: await application.remove() finally: - print('Disconnecting from model') + print("Disconnecting from model") await model.disconnect() print("Success") -if __name__ == '__main__': +if __name__ == "__main__": jasyncio.run(main()) diff --git a/juju/action.py b/juju/action.py index 17a8fb90f..7aa729d63 100644 --- a/juju/action.py +++ b/juju/action.py @@ -5,11 +5,10 @@ class Action(model.ModelEntity): - def __init__(self, entity_id, model, history_index=-1, connected=True): super().__init__(entity_id, model, history_index, connected) self.results = {} - self._status = self.data['status'] + self._status = self.data["status"] @property def status(self): diff --git a/juju/annotationhelper.py b/juju/annotationhelper.py index a6be596ff..d8369125b 100644 --- a/juju/annotationhelper.py +++ b/juju/annotationhelper.py @@ -29,7 +29,7 @@ async def _set_annotations(entity_tag, annotations, connection): """ # TODO: ensure annotations is dict with only string keys # and values. - log.debug('Updating annotations on %s', entity_tag) + log.debug("Updating annotations on %s", entity_tag) facade = client.AnnotationsFacade.from_connection(connection) args = client.EntityAnnotations( entity=entity_tag, diff --git a/juju/application.py b/juju/application.py index cf02a1faf..1acddc07b 100644 --- a/juju/application.py +++ b/juju/application.py @@ -36,6 +36,7 @@ class Application(model.ModelEntity): The fields marked deprecated below will be removed in version 4.0 because a different API must be used against Juju 4. """ + @property def name(self) -> str: return self.entity_id @@ -68,13 +69,15 @@ def subordinate(self) -> bool: return self.safe_data["subordinate"] @property - @deprecated("Application.workload_version is deprecated and will be removed in v4, use Unit.workload_version instead.") + @deprecated( + "Application.workload_version is deprecated and will be removed in v4, use Unit.workload_version instead." + ) def workload_version(self) -> str: return self.safe_data["workload-version"] @property def _unit_match_pattern(self): - return r'^{}.*$'.format(self.entity_id) + return r"^{}.*$".format(self.entity_id) def _facade(self): return client.ApplicationFacade.from_connection(self.connection) @@ -87,22 +90,19 @@ def on_unit_add(self, callable_): whenever a unit is added to this application. """ - self.model.add_observer( - callable_, 'unit', 'add', self._unit_match_pattern) + self.model.add_observer(callable_, "unit", "add", self._unit_match_pattern) def on_unit_remove(self, callable_): """Add a "unit removed" observer to this entity, which will be called whenever a unit is removed from this application. """ - self.model.add_observer( - callable_, 'unit', 'remove', self._unit_match_pattern) + self.model.add_observer(callable_, "unit", "remove", self._unit_match_pattern) @property def units(self): return [ - unit for unit in self.model.units.values() - if unit.application == self.name + unit for unit in self.model.units.values() if unit.application == self.name ] @property @@ -120,8 +120,10 @@ def related_applications(self, endpoint_name=None): if rel.is_peer: local_ep, remote_ep = rel.endpoints 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 @@ -135,7 +137,7 @@ def status(self): If the application is unknown it will attempt to derive the unit workload status and highlight the most relevant (severity). """ - status = self.safe_data['status']['current'] + status = self.safe_data["status"]["current"] if status == "unset": known_statuses = [] for unit in self.units: @@ -150,10 +152,8 @@ def status(self): @property def status_message(self): - """Get the application status message, as set by the charm's leader. - - """ - return self.safe_data['status']['message'] + """Get the application status message, as set by the charm's leader.""" + return self.safe_data["status"]["message"] @property def tag(self): @@ -174,8 +174,8 @@ async def relate(self, local_relation, remote_relation): application in the form '[:]' """ - if ':' not in local_relation: - local_relation = '{}:{}'.format(self.name, local_relation) + if ":" not in local_relation: + local_relation = "{}:{}".format(self.name, local_relation) return await self.model.relate(local_relation, remote_relation) @@ -194,15 +194,15 @@ async def add_unit(self, count=1, to=None, attach_storage=[]): """ - if self.model.info.type_ == 'caas': - log.warning('adding units to a container-based model not supported, auto-switching to scale') + if self.model.info.type_ == "caas": + log.warning( + "adding units to a container-based model not supported, auto-switching to scale" + ) return await self.scale(scale_change=count) app_facade = self._facade() - log.debug( - 'Adding %s unit%s to %s', - count, '' if count == 1 else 's', self.name) + log.debug("Adding %s unit%s to %s", count, "" if count == 1 else "s", self.name) result = await app_facade.AddUnits( application=self.name, @@ -212,7 +212,7 @@ async def add_unit(self, count=1, to=None, attach_storage=[]): ) return await jasyncio.gather(*[ - jasyncio.ensure_future(self.model._wait_for_new('unit', unit_id)) + jasyncio.ensure_future(self.model._wait_for_new("unit", unit_id)) for unit_id in result.units ]) @@ -231,19 +231,26 @@ async def scale(self, scale=None, scale_change=None): app_facade = self._facade() if (scale, scale_change) == (None, None): - raise ValueError('Must provide either scale or scale_change') + 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) + "Scaling application %s %s %s", + self.name, + "to" if scale else "by", + scale or scale_change, + ) - await app_facade.ScaleApplications(applications=[ - client.ScaleApplicationParams(application_tag=self.tag, - scale=scale, - scale_change=scale_change) - ]) + await app_facade.ScaleApplications( + applications=[ + client.ScaleApplicationParams( + application_tag=self.tag, scale=scale, scale_change=scale_change + ) + ] + ) - async def destroy_relation(self, local_relation, remote_relation, block_until_done: bool = False): + async def destroy_relation( + self, local_relation, remote_relation, block_until_done: bool = False + ): """Remove a relation to another application. :param str local_relation: Name of relation on this application @@ -252,16 +259,14 @@ async def destroy_relation(self, local_relation, remote_relation, block_until_do :param bool block_until_done: Wait until the relation is completely removed. """ - if ':' not in local_relation: - local_relation = '{}:{}'.format(self.name, local_relation) + if ":" not in local_relation: + local_relation = "{}:{}".format(self.name, local_relation) app_facade = self._facade() - log.debug( - 'Destroying relation %s <-> %s', local_relation, remote_relation) + log.debug("Destroying relation %s <-> %s", local_relation, remote_relation) - await app_facade.DestroyRelation(endpoints=[ - local_relation, remote_relation]) + await app_facade.DestroyRelation(endpoints=[local_relation, remote_relation]) if block_until_done: await block_until( lambda: not any( @@ -273,10 +278,9 @@ async def destroy_relation(self, local_relation, remote_relation, block_until_do remove_relation = destroy_relation async def destroy_unit(self, *unit_names): - """Destroy units by name. - - """ + """Destroy units by name.""" return await self.model.destroy_units(*unit_names) + destroy_units = destroy_unit async def destroy(self, destroy_storage=False, force=False, no_wait=False): @@ -293,46 +297,56 @@ async def destroy(self, destroy_storage=False, force=False, no_wait=False): app_facade = self._facade() - log.debug('Destroying {} with parameters -- destroy-storage : {} -- force : {} -- no-wait : {}'.format( - self.name, destroy_storage, force, no_wait)) + log.debug( + "Destroying {} with parameters -- destroy-storage : {} -- force : {} -- no-wait : {}".format( + self.name, destroy_storage, force, no_wait + ) + ) - res = await app_facade.DestroyApplication(applications=[client.DestroyApplicationParams( - application_tag=self.tag, - destroy_storage=destroy_storage, - force=force, - max_wait=0 if no_wait else None, - )]) + res = await app_facade.DestroyApplication( + applications=[ + client.DestroyApplicationParams( + application_tag=self.tag, + destroy_storage=destroy_storage, + force=force, + max_wait=0 if no_wait else None, + ) + ] + ) return res + remove = destroy def supports_granular_expose_parameters(self): """Returns true if the controller supports granular, per-endpoint - expose parameters.""" + expose parameters.""" return self._facade_version() >= 13 async def expose(self, exposed_endpoints=None): """Make a subset of the application endpoints or the entire application - available over the network. + available over the network. - If the exposed_endpoints argument is not provided, all opened port - ranges for the application will become reachable from 0.0.0.0/0. + If the exposed_endpoints argument is not provided, all opened port + ranges for the application will become reachable from 0.0.0.0/0. - On juju 2.9 and onwards, the exposed_endpoints argument may be used - to specify a list of spaces and or CIDRs that should be able to - reach the port ranges opened for a particular subnet. The - exposed_endpoints parameter is a map where keys are endpoint names - or the empty string ("") which works as a wildcard for all endpoints - and values are ExposedEndpoint instances. + On juju 2.9 and onwards, the exposed_endpoints argument may be used + to specify a list of spaces and or CIDRs that should be able to + reach the port ranges opened for a particular subnet. The + exposed_endpoints parameter is a map where keys are endpoint names + or the empty string ("") which works as a wildcard for all endpoints + and values are ExposedEndpoint instances. - When targeting an older juju controller, the exposed_endpoints param - is not supported and an error will be raised if it is provided. + When targeting an older juju controller, the exposed_endpoints param + is not supported and an error will be raised if it is provided. """ app_facade = self._facade() ctrl_supports_expose_parameters = self.supports_granular_expose_parameters() if exposed_endpoints is not None: if not isinstance(exposed_endpoints, dict): - raise ValueError("endpoints must be a dictionary with ExposedEndpoint values") + raise ValueError( + "endpoints must be a dictionary with ExposedEndpoint values" + ) # The bundle changes code will pass in raw dicts with the exposed # endpoint data. We need to convert those into ExposedEndpoints @@ -347,23 +361,23 @@ async def expose(self, exposed_endpoints=None): len(exposed_endpoints) > 0 and "" not in exposed_endpoints ) has_wildcard_endpoint_with_spaces_or_non_wildcard_cidrs = ( - "" in exposed_endpoints and ( - exposed_endpoints[""].includes_non_wildcard_cidrs() or - exposed_endpoints[""].includes_spaces() + "" in exposed_endpoints + and ( + exposed_endpoints[""].includes_non_wildcard_cidrs() + or exposed_endpoints[""].includes_spaces() ) ) - is_security_risk = ( - not ctrl_supports_expose_parameters and - ( - has_more_than_one_endpoints or - has_non_wildcard_endpoint or - has_wildcard_endpoint_with_spaces_or_non_wildcard_cidrs - ) + is_security_risk = not ctrl_supports_expose_parameters and ( + has_more_than_one_endpoints + or has_non_wildcard_endpoint + or has_wildcard_endpoint_with_spaces_or_non_wildcard_cidrs ) if is_security_risk: - raise JujuError("controller does not support granular expose parameters; applying this change would make all open application ports accessible from 0.0.0.0/0") + raise JujuError( + "controller does not support granular expose parameters; applying this change would make all open application ports accessible from 0.0.0.0/0" + ) for endpoint, expose_details in exposed_endpoints.items(): access_from = "from CIDRs 0.0.0.0/0 and ::/0" @@ -371,36 +385,47 @@ async def expose(self, exposed_endpoints=None): access_from = str(expose_details) if endpoint == "": - log.debug("expose all endpoints of %s and allow access %s", self.name, access_from) + log.debug( + "expose all endpoints of %s and allow access %s", + self.name, + access_from, + ) else: - log.debug("override expose settings for endpoint %s of %s and %s", endpoint, self.name, access_from) + log.debug( + "override expose settings for endpoint %s of %s and %s", + endpoint, + self.name, + access_from, + ) # Map ExposedEndpoint entries to a dict we can pass to the facade. - exposed_endpoints = { - k: v.to_dict() for k, v in exposed_endpoints.items() - } + exposed_endpoints = {k: v.to_dict() for k, v in exposed_endpoints.items()} else: - log.debug("expose all endpoints of %s and allow access from CIDRs 0.0.0.0/0 and ::/0", self.name) + log.debug( + "expose all endpoints of %s and allow access from CIDRs 0.0.0.0/0 and ::/0", + self.name, + ) if not ctrl_supports_expose_parameters: return await app_facade.Expose(application=self.name) - return await app_facade.Expose(application=self.name, - exposed_endpoints=exposed_endpoints) + return await app_facade.Expose( + application=self.name, exposed_endpoints=exposed_endpoints + ) async def unexpose(self, exposed_endpoints=None): """Prevent a subset of the application endpoints or the entire - application from being reached over the network. + application from being reached over the network. - If the exposed_endpoints argument is not provided, the entire - application will be unexposed. + If the exposed_endpoints argument is not provided, the entire + application will be unexposed. - On juju 2.9 and onwards, the exposed_endpoints argument may be used - to specify a list of endpoint names whose port ranges should be - unexposed. + On juju 2.9 and onwards, the exposed_endpoints argument may be used + to specify a list of endpoint names whose port ranges should be + unexposed. - When targeting an older juju controller, the exposed_endpoints param - is not supported and an error will be raised if it is provided. + When targeting an older juju controller, the exposed_endpoints param + is not supported and an error will be raised if it is provided. """ app_facade = self._facade() facade_version = self._facade_version() @@ -408,11 +433,16 @@ async def unexpose(self, exposed_endpoints=None): # Check if an endpoint list is provided if exposed_endpoints is not None and len(exposed_endpoints) > 0: if facade_version < 13: - raise JujuError("controller does not support granular expose parameters; applying this change would unexpose the application") + raise JujuError( + "controller does not support granular expose parameters; applying this change would unexpose the application" + ) - log.debug("Unexposing endpoints %s of %s", ",".join(exposed_endpoints), self.name) - return await app_facade.Unexpose(application=self.name, - exposed_endpoints=exposed_endpoints) + log.debug( + "Unexposing endpoints %s of %s", ",".join(exposed_endpoints), self.name + ) + return await app_facade.Unexpose( + application=self.name, exposed_endpoints=exposed_endpoints + ) # Just expose the entire application log.debug("Unexposing %s", self.name) @@ -425,59 +455,60 @@ async def get_series(self): """ app_facade = self._facade() - log.debug( - 'Getting series for %s', self.name) + log.debug("Getting series for %s", self.name) - appGetResults = (await app_facade.Get(application=self.name)) + appGetResults = await app_facade.Get(application=self.name) if self._facade_version() >= 15: base_channel = appGetResults.base.channel return utils.base_channel_to_series(base_channel) return appGetResults.series async def get_config(self): - """Return the configuration settings dict for this application. - """ + """Return the configuration settings dict for this application.""" app_facade = self._facade() - log.debug( - 'Getting config for %s', self.name) + log.debug("Getting config for %s", self.name) return (await app_facade.Get(application=self.name)).config async def get_trusted(self): - """Return the trusted configuration setting for this application. - - """ - if self.model.info.agent_version < client.Number.from_json('2.4.0'): - raise NotImplementedError("trusted is not supported on model version {}".format(self.model.info.agent_version)) + """Return the trusted configuration setting for this application.""" + if self.model.info.agent_version < client.Number.from_json("2.4.0"): + raise NotImplementedError( + "trusted is not supported on model version {}".format( + self.model.info.agent_version + ) + ) app_facade = self._facade() - log.debug( - 'Getting config for %s', self.name) + log.debug("Getting config for %s", self.name) config = await app_facade.Get(application=self.name) - if 'trust' in config.config: - return config.config['trust']['value'] is True + if "trust" in config.config: + return config.config["trust"]["value"] is True app_config = config.application_config - return app_config['trust']['value'] is True + return app_config["trust"]["value"] is True async def set_trusted(self, trust): """Set the trusted configuration of the application. :param bool trust: Trust the application or not """ - if self.model.info.agent_version < client.Number.from_json('2.4.0'): - raise NotImplementedError("trusted is not supported on model version {}".format(self.model.info.agent_version)) + if self.model.info.agent_version < client.Number.from_json("2.4.0"): + raise NotImplementedError( + "trusted is not supported on model version {}".format( + self.model.info.agent_version + ) + ) # clamp trust to exactly the value juju expects, rather than allowing # anything in the config. app_facade = self._facade() - config = {'trust': json.dumps(True if trust is True else False)} - log.debug( - 'Setting config for %s: %s', self.name, config) + config = {"trust": json.dumps(True if trust is True else False)} + log.debug("Setting config for %s: %s", self.name, config) # Unfortunately we have to do this in a lazy fashion, attempting to use # the method early will cause an error. Attempting to call this @@ -490,19 +521,20 @@ async def set_trusted(self, trust): config_method = app_facade.SetApplicationsConfig else: config_method = app_facade.SetConfigs - return await config_method(args=[{ - "application": self.name, - "config": config, - }]) + return await config_method( + args=[ + { + "application": self.name, + "config": config, + } + ] + ) async def get_constraints(self): - """Return the machine constraints dict for this application. - - """ + """Return the machine constraints dict for this application.""" app_facade = self._facade() - log.debug( - 'Getting constraints for %s', self.name) + log.debug("Getting constraints for %s", self.name) result = (await app_facade.Get(application=self.name)).constraints return vars(result) if result else result @@ -516,7 +548,9 @@ async def get_actions(self, schema=False): actions = {} entity = {"tag": self.tag} action_facade = client.ActionFacade.from_connection(self.connection) - results = (await action_facade.ApplicationsCharmsActions(entities=[entity])).results + results = ( + await action_facade.ApplicationsCharmsActions(entities=[entity]) + ).results for result in results: if result.application_tag == self.tag and result.actions: actions = result.actions @@ -553,25 +587,26 @@ def attach_resource(self, resource_name, file_name, file_obj): conn, headers, path_prefix = self.connection.https_connection() url = "{}/applications/{}/resources/{}".format( - path_prefix, self.name, resource_name) + path_prefix, self.name, resource_name + ) data = file_obj.read() - headers['Content-Type'] = 'application/octet-stream' - headers['Content-Length'] = len(data) - data_bytes = data if isinstance(data, bytes) else bytes(data, 'utf-8') - headers['Content-Sha384'] = hashlib.sha384(data_bytes).hexdigest() + headers["Content-Type"] = "application/octet-stream" + headers["Content-Length"] = len(data) + data_bytes = data if isinstance(data, bytes) else bytes(data, "utf-8") + headers["Content-Sha384"] = hashlib.sha384(data_bytes).hexdigest() file_name = str(file_name) - if not file_name.startswith('./'): - file_name = './' + file_name + if not file_name.startswith("./"): + file_name = "./" + file_name - headers['Content-Disposition'] = "form-data; filename=\"{}\"".format(file_name) - headers['Accept-Encoding'] = 'gzip' - headers['Bakery-Protocol-Version'] = 3 - headers['Connection'] = 'close' + headers["Content-Disposition"] = 'form-data; filename="{}"'.format(file_name) + headers["Accept-Encoding"] = "gzip" + headers["Bakery-Protocol-Version"] = 3 + headers["Connection"] = "close" - conn.request('PUT', url, data, headers) + conn.request("PUT", url, data, headers) response = conn.getresponse() result = response.read().decode() if not response.status == 200: @@ -605,8 +640,7 @@ async def run(self, command, timeout=None): """ action = client.ActionFacade.from_connection(self.connection) - log.debug( - 'Running `%s` on all units of %s', command, self.name) + log.debug("Running `%s` on all units of %s", command, self.name) # TODO this should return a list of Actions return await action.Run( @@ -631,7 +665,7 @@ def charm_url(self): :return str: The charm url """ - return self.safe_data['charm-url'] + return self.safe_data["charm-url"] async def get_annotations(self): """Get annotations on this application. @@ -656,8 +690,7 @@ async def set_config(self, config): """ app_facade = self._facade() - log.debug( - 'Setting config for %s: %s', self.name, config) + log.debug("Setting config for %s: %s", self.name, config) str_config = {} for k, v in config.items(): @@ -665,15 +698,19 @@ async def set_config(self, config): str_config[k] = v elif isinstance(v, dict): # pairs with a value of None are ignored - if v.get('value', False): - str_config[k] = str(v.get('value')) + if v.get("value", False): + str_config[k] = str(v.get("value")) else: raise JujuApplicationConfigError(config, [k, v]) - return await app_facade.SetConfigs(args=[{ - "application": self.name, - "config": str_config, - }]) + return await app_facade.SetConfigs( + args=[ + { + "application": self.name, + "config": str_config, + } + ] + ) async def reset_config(self, to_default): """ @@ -684,13 +721,16 @@ async def reset_config(self, to_default): """ app_facade = self._facade() - log.debug( - 'Restoring default config for %s: %s', self.name, to_default) + log.debug("Restoring default config for %s: %s", self.name, to_default) - return await app_facade.UnsetApplicationsConfig(args=[{ - "application": self.name, - "options": to_default, - }]) + return await app_facade.UnsetApplicationsConfig( + args=[ + { + "application": self.name, + "options": to_default, + } + ] + ) async def set_constraints(self, constraints): """Set machine constraints for this application. @@ -700,21 +740,22 @@ async def set_constraints(self, constraints): """ app_facade = self._facade() - log.debug( - 'Setting constraints for %s: %s', self.name, constraints) + log.debug("Setting constraints for %s: %s", self.name, constraints) - return await app_facade.SetConstraints(application=self.name, constraints=constraints) + return await app_facade.SetConstraints( + application=self.name, constraints=constraints + ) async def refresh( - self, - channel: Optional[str] = None, - force: bool = False, - force_series: bool = False, - force_units: bool = False, - path: Optional[Union[Path, str]] = None, - resources: Optional[Dict[str, str]] = None, - revision: Optional[int] = None, - switch: Optional[str] = None, + self, + channel: Optional[str] = None, + force: bool = False, + force_series: bool = False, + force_units: bool = False, + path: Optional[Union[Path, str]] = None, + resources: Optional[Dict[str, str]] = None, + revision: Optional[int] = None, + switch: Optional[str] = None, ): """Refresh the charm for this application. @@ -744,10 +785,12 @@ async def refresh( # 3 - Finally execute the upgrade # Get the charm URL and charm origin of the given application is running at present. - charm_url_origin_result = await app_facade.GetCharmURLOrigin(application=self.name) + charm_url_origin_result = await app_facade.GetCharmURLOrigin( + application=self.name + ) if charm_url_origin_result.error is not None: err = charm_url_origin_result.error - raise JujuError(f'{err.code} : {err.message}') + raise JujuError(f"{err.code} : {err.message}") current_origin = charm_url_origin_result.charm_origin if path is not None or (switch is not None and is_local_charm(switch)): @@ -772,32 +815,37 @@ async def refresh( charm_name = parsed_url.name if parsed_url.schema is None: - raise JujuError(f'A ch: or cs: schema is required for application refresh, given : {str(parsed_url)}') + raise JujuError( + f"A ch: or cs: schema is required for application refresh, given : {str(parsed_url)}" + ) # Resolve the given charm URLs with an optionally specified preferred channel. # Channel provided via CharmOrigin. resolved_charm_with_channel_results = await charms_facade.ResolveCharms( - resolve=[client.ResolveCharmWithChannel( - charm_origin=origin, - switch_charm=True if switch else False, # rpc expects boolean type - reference=charm_url, - )]) + resolve=[ + client.ResolveCharmWithChannel( + charm_origin=origin, + switch_charm=True if switch else False, # rpc expects boolean type + reference=charm_url, + ) + ] + ) resolved_charm = resolved_charm_with_channel_results.results[0] # Get the destination origin and destination charm_url from the resolved charm if resolved_charm.error is not None: err = resolved_charm.error - raise JujuError(f'{err.code} : {err.message}') + raise JujuError(f"{err.code} : {err.message}") dest_origin = resolved_charm.charm_origin charm_url = resolved_charm.url # Add the charm with the destination url and origin - charm_origin_result = await charms_facade.AddCharm(url=charm_url, - force=force, - charm_origin=dest_origin) + charm_origin_result = await charms_facade.AddCharm( + url=charm_url, force=force, charm_origin=dest_origin + ) if charm_origin_result.error is not None: err = charm_origin_result.error - raise JujuError(f'{err.code} : {err.message}') + raise JujuError(f"{err.code} : {err.message}") # Now take care of the resources: @@ -820,8 +868,7 @@ async def refresh( resources_facade = client.ResourcesFacade.from_connection(self.connection) response = await resources_facade.ListResources(entities=request_data) existing_resources = { - resource.name: resource - for resource in response.results[0].resources + resource.name: resource for resource in response.results[0].resources } charmhub = self.model.charmhub @@ -830,24 +877,30 @@ async def refresh( # Compute the difference btw resources needed and the existing resources resources_to_update = [] for resource in charm_resources: - if utils.should_upgrade_resource(resource, existing_resources, arg_resources): + if utils.should_upgrade_resource( + resource, existing_resources, arg_resources + ): resources_to_update.append(resource) # Update the resources if resources_to_update: request_data = [] for resource in resources_to_update: - res_name = resource.get('Name', resource.get('name')) - request_data.append(client.CharmResource( - description=resource.get('Description', resource.get('description')), - name=res_name, - path=_arg_res_filenames.get(res_name, - resource.get('Path', - resource.get('filename', ''))), - revision=_arg_res_revisions.get(res_name, -1), - type_=resource.get('Type', resource.get('type')), - origin='store', - )) + res_name = resource.get("Name", resource.get("name")) + request_data.append( + client.CharmResource( + description=resource.get( + "Description", resource.get("description") + ), + name=res_name, + path=_arg_res_filenames.get( + res_name, resource.get("Path", resource.get("filename", "")) + ), + revision=_arg_res_revisions.get(res_name, -1), + type_=resource.get("Type", resource.get("type")), + origin="store", + ) + ) response = await resources_facade.AddPendingResources( application_tag=self.tag, @@ -857,44 +910,42 @@ async def refresh( ) pending_ids = response.pending_ids resource_ids = { - resource.get('Name', resource.get('name')): id + resource.get("Name", resource.get("name")): id for resource, id in zip(resources_to_update, pending_ids) } else: resource_ids = None set_charm_args = { - 'application': self.entity_id, - 'charm_url': charm_url, - 'charm_origin': dest_origin, - 'config_settings': None, - 'config_settings_yaml': None, - 'force': force, - 'force_units': force_units, - 'resource_ids': resource_ids, - 'storage_constraints': None, + "application": self.entity_id, + "charm_url": charm_url, + "charm_origin": dest_origin, + "config_settings": None, + "config_settings_yaml": None, + "force": force, + "force_units": force_units, + "resource_ids": resource_ids, + "storage_constraints": None, } if self.connection.is_using_old_client: - set_charm_args['force_series'] = force_series + set_charm_args["force_series"] = force_series # Update the application await app_facade.SetCharm(**set_charm_args) - await self.model.block_until( - lambda: self.data['charm-url'] == charm_url - ) + await self.model.block_until(lambda: self.data["charm-url"] == charm_url) upgrade_charm = refresh async def local_refresh( - self, - *, - charm_origin: _definitions.CharmOrigin, - force: bool, - force_series: bool, - force_units: bool, - path: Union[Path, str], - resources: Optional[Dict[str, str]], + self, + *, + charm_origin: _definitions.CharmOrigin, + force: bool, + force_series: bool, + force_units: bool, + path: Union[Path, str], + resources: Optional[Dict[str, str]], ): """Refresh the charm for this application with a local charm. @@ -917,10 +968,7 @@ async def local_refresh( charm_dir = local_path.expanduser().resolve() model_config = await self.get_config() - series = ( - await self.get_series() or - self.model.info.get('default-series', '') - ) + series = await self.get_series() or self.model.info.get("default-series", "") if not series: metadata = utils.get_local_charm_metadata(charm_dir) await get_charm_series(metadata, self.model) @@ -932,10 +980,9 @@ async def local_refresh( charm_url = await self.model.add_local_charm_dir(charm_dir, series) metadata = utils.get_local_charm_metadata(local_path) if resources is not None: - resources = await self.model.add_local_resources(self.entity_id, - charm_url, - metadata, - resources=resources) + resources = await self.model.add_local_resources( + self.entity_id, charm_url, metadata, resources=resources + ) # We know this charm is a local charm, but this charm origin could be # the charm origin of a charmhub charm. Ensure that we update/remove @@ -949,26 +996,24 @@ async def local_refresh( charm_origin.revision = URL.parse(charm_url).revision set_charm_args = { - 'application': self.entity_id, - 'charm_origin': charm_origin, - 'charm_url': charm_url, - 'config_settings': None, - 'config_settings_yaml': None, - 'force': force, - 'force_units': force_units, - 'resource_ids': resources, - 'storage_constraints': None, + "application": self.entity_id, + "charm_origin": charm_origin, + "charm_url": charm_url, + "config_settings": None, + "config_settings_yaml": None, + "force": force, + "force_units": force_units, + "resource_ids": resources, + "storage_constraints": None, } if self.connection.is_using_old_client: - set_charm_args['force_series'] = force_series + set_charm_args["force_series"] = force_series # Update application await app_facade.SetCharm(**set_charm_args) - await self.model.block_until( - lambda: self.data['charm-url'] == charm_url - ) + await self.model.block_until(lambda: self.data["charm-url"] == charm_url) async def get_metrics(self): """Get metrics for this application's units. @@ -980,9 +1025,9 @@ async def get_metrics(self): def _refresh_origin( - current_origin: client.CharmOrigin, - channel: Optional[str] = None, - revision: Optional[int] = None, + current_origin: client.CharmOrigin, + channel: Optional[str] = None, + revision: Optional[int] = None, ) -> client.CharmOrigin: chan = None if channel is None else Channel.parse(channel).normalize() @@ -992,7 +1037,7 @@ def _refresh_origin( risk=chan.risk if chan else current_origin.risk, revision=revision if revision is not None else current_origin.revision, base=current_origin.base, - architecture=current_origin.get('architecture', DEFAULT_ARCHITECTURE), + architecture=current_origin.get("architecture", DEFAULT_ARCHITECTURE), ) @@ -1015,16 +1060,17 @@ def includes_spaces(self): return self.to_spaces is not None and len(self.to_spaces) > 0 def includes_non_wildcard_cidrs(self): - to_cidrs = (self.to_cidrs or []) - non_wildcard_cidrs = filter(lambda x: x == "0.0.0.0/0" or x == "::/0", - to_cidrs) + to_cidrs = self.to_cidrs or [] + non_wildcard_cidrs = filter(lambda x: x == "0.0.0.0/0" or x == "::/0", to_cidrs) return len(list(non_wildcard_cidrs)) > 0 @classmethod def from_dict(cls, data): - d = (data or {}) + d = data or {} if not isinstance(d, dict): - raise ValueError("expected a dictionary with fields: expose-to-spaces and expose-to-cidrs") + raise ValueError( + "expected a dictionary with fields: expose-to-spaces and expose-to-cidrs" + ) to_spaces = None if "expose-to-spaces" in d and isinstance(d["expose-to-spaces"], list): diff --git a/juju/bundle.py b/juju/bundle.py index 994397441..affc0a35d 100644 --- a/juju/bundle.py +++ b/juju/bundle.py @@ -50,37 +50,37 @@ def __init__(self, model, trusted=False, forced=False): app_units = self._units_by_app.setdefault(unit.application, []) app_units.append(unit_name) - self.bundle_facade = client.BundleFacade.from_connection( - model.connection()) - self.client_facade = client.ClientFacade.from_connection( - model.connection()) - self.app_facade = client.ApplicationFacade.from_connection( - model.connection()) - self.ann_facade = client.AnnotationsFacade.from_connection( - model.connection()) + self.bundle_facade = client.BundleFacade.from_connection(model.connection()) + self.client_facade = client.ClientFacade.from_connection(model.connection()) + self.app_facade = client.ApplicationFacade.from_connection(model.connection()) + self.ann_facade = client.AnnotationsFacade.from_connection(model.connection()) self.machine_manager_facade = client.MachineManagerFacade.from_connection( - model.connection()) + model.connection() + ) # Feature detect if we have the new charms facade, otherwise fallback # to the client facade, when making calls. - best_facade_version = client.CharmsFacade.best_facade_version(model.connection()) + best_facade_version = client.CharmsFacade.best_facade_version( + model.connection() + ) if best_facade_version is not None and best_facade_version > 2: - self.charms_facade = client.CharmsFacade.from_connection( - model.connection()) + self.charms_facade = client.CharmsFacade.from_connection(model.connection()) else: self.charms_facade = None # This describes all the change types that the BundleHandler supports. - change_type_cls = [AddApplicationChange, - AddCharmChange, - AddMachineChange, - AddRelationChange, - AddUnitChange, - CreateOfferChange, - ConsumeOfferChange, - ExposeChange, - ScaleChange, - SetAnnotationsChange] + change_type_cls = [ + AddApplicationChange, + AddCharmChange, + AddMachineChange, + AddRelationChange, + AddUnitChange, + CreateOfferChange, + ConsumeOfferChange, + ExposeChange, + ScaleChange, + SetAnnotationsChange, + ] self.change_types = {} for change_cls in change_type_cls: self.change_types[change_cls.method()] = change_cls @@ -89,10 +89,10 @@ async def _validate_bundle(self, bundle): """Validate the bundle for known issues, raises an error if it encounters a known problem """ - apps_dict = bundle.get('applications', {}) + apps_dict = bundle.get("applications", {}) for app_name in self.applications: app_dict = apps_dict[app_name] - app_trusted = app_dict.get('trust') + app_trusted = app_dict.get("trust") if (not self.trusted and not self.forced) and app_trusted: raise JujuError( "Bundle cannot be deployed without trusting applications with your cloud credentials.\n" @@ -114,23 +114,26 @@ async def _handle_local_charms(self, bundle, bundle_dir): """ apps, args = [], [] - default_series = bundle.get('series') - apps_dict = bundle.get('applications', {}) + default_series = bundle.get("series") + apps_dict = bundle.get("applications", {}) for app_name in self.applications: app_dict = apps_dict[app_name] - charm_dir = app_dict['charm'] + charm_dir = app_dict["charm"] try: charm_path = (bundle_dir / charm_dir).resolve() - if not (charm_path.is_dir() or - (charm_path.is_file() and - charm_path.suffix in ('.charm', '.zip'))): + if not ( + charm_path.is_dir() + or ( + charm_path.is_file() and charm_path.suffix in (".charm", ".zip") + ) + ): continue charm_dir = str(charm_path) except ValueError: pass except FileNotFoundError: continue - series = (app_dict.get('series') or default_series) + series = app_dict.get("series") or default_series if not series: metadata = utils.get_local_charm_metadata(charm_dir) series = await get_charm_series(metadata, self.model) @@ -140,7 +143,8 @@ async def _handle_local_charms(self, bundle, bundle_dir): if not series: raise JujuError( "Couldn't determine series for charm at {}. " - "Add a 'series' key to the bundle.".format(charm_dir)) + "Add a 'series' key to the bundle.".format(charm_dir) + ) # Keep track of what we need to update. We keep a list of apps # that need to be updated, and a corresponding list of args # needed to update those apps. @@ -151,8 +155,7 @@ async def _handle_local_charms(self, bundle, bundle_dir): # If we have apps to update, spawn all the coroutines concurrently # and wait for them to finish. charm_urls = await jasyncio.gather(*[ - self.model.add_local_charm_dir(*params) - for params in args + self.model.add_local_charm_dir(*params) for params in args ]) # Update the 'charm:' entry for each app with the new 'local:' url. @@ -162,15 +165,17 @@ async def _handle_local_charms(self, bundle, bundle_dir): app_name, charm_url, metadata, - resources=bundle.get('applications', {app_name: {}})[app_name].get("resources", {}), + resources=bundle.get("applications", {app_name: {}})[app_name].get( + "resources", {} + ), ) - apps_dict[app_name]['charm'] = charm_url + apps_dict[app_name]["charm"] = charm_url apps_dict[app_name]["resources"] = resources origin = client.CharmOrigin(source="local", risk="stable") if not self.model.connection().is_using_old_client: - origin.base = utils.get_local_charm_base(series, - charm_dir, - client.Base) + origin.base = utils.get_local_charm_base( + series, charm_dir, client.Base + ) self.origins[charm_url] = {str(None): origin} return bundle @@ -183,23 +188,34 @@ def _resolve_include_file_config(self, bundle_dir): relative paths, so backend can't handle them. """ - bundle_apps = [self.bundle.get('applications', {})] - overlay_apps = [overlay.get('applications', {}) for overlay in self.overlays] + bundle_apps = [self.bundle.get("applications", {})] + overlay_apps = [overlay.get("applications", {}) for overlay in self.overlays] for apps in bundle_apps + overlay_apps: for app_name, app in apps.items(): - - if app and 'options' in app: - if 'config' in app['options'] and app['options']['config'].startswith('include-file'): + if app and "options" in app: + if "config" in app["options"] and app["options"][ + "config" + ].startswith("include-file"): # resolve the file if not bundle_dir: - raise NotImplementedError('unable to resolve paths for config:include-file for non-local charms') + raise NotImplementedError( + "unable to resolve paths for config:include-file for non-local charms" + ) try: - config_path = (bundle_dir / Path(app['options']['config'].split('//')[1])).resolve() + config_path = ( + bundle_dir + / Path(app["options"]["config"].split("//")[1]) + ).resolve() except IndexError: - raise JujuError('the path for the included file should start with // and be relative to the bundle') + raise JujuError( + "the path for the included file should start with // and be relative to the bundle" + ) if not config_path.exists(): - raise JujuError('unable to locate config file : %s for : %s' % (config_path, app_name)) + raise JujuError( + "unable to locate config file : %s for : %s" + % (config_path, app_name) + ) # get the contents of the file config_contents = yaml.safe_load(config_path.read_text()) @@ -207,27 +223,38 @@ def _resolve_include_file_config(self, bundle_dir): # inline the configurations for the current app into # the app['options'] for key, val in config_contents[app_name].items(): - app['options'][key] = val + app["options"][key] = val # remove the 'include-file' config - app['options'].pop('config') + app["options"].pop("config") - for option_key, option_val in app['options'].items(): - if isinstance(option_val, str) and option_val.startswith('include-base64'): + for option_key, option_val in app["options"].items(): + if isinstance(option_val, str) and option_val.startswith( + "include-base64" + ): # resolve the file if not bundle_dir: - raise NotImplementedError('unable to resolve paths for config:include-base64 for non-local charms') + raise NotImplementedError( + "unable to resolve paths for config:include-base64 for non-local charms" + ) try: - base64_path = (bundle_dir / Path(option_val.split('//')[1])).resolve() + base64_path = ( + bundle_dir / Path(option_val.split("//")[1]) + ).resolve() except IndexError: - raise JujuError('the path for the included base64 file should start with // and be relative to the bundle') + raise JujuError( + "the path for the included base64 file should start with // and be relative to the bundle" + ) if not base64_path.exists(): - raise JujuError('unable to locate the base64 file : %s for : %s' % (base64_path, app_name)) + raise JujuError( + "unable to locate the base64 file : %s for : %s" + % (base64_path, app_name) + ) # inline the base64 encoded config value base64_contents = base64.b64decode(base64_path.read_text()) - app['options'][option_key] = base64_contents + app["options"][option_key] = base64_contents return self.bundle, self.overlays @@ -264,7 +291,7 @@ async def fetch_plan(self, bundle, origin, overlays=[]): bundle_yaml = await self._download_bundle(bundle, origin) if not bundle_yaml: - raise JujuError('empty bundle, nothing to deploy') + raise JujuError("empty bundle, nothing to deploy") _bundles = [b for b in yaml.safe_load_all(bundle_yaml)] self.overlays = _bundles[1:] @@ -275,13 +302,15 @@ async def fetch_plan(self, bundle, origin, overlays=[]): try: overlay_contents = Path(overlay_yaml_path).read_text() except (OSError, IOError) as e: - raise JujuError('unable to open overlay %s \n %s' % (overlay_yaml_path, e)) + raise JujuError( + "unable to open overlay %s \n %s" % (overlay_yaml_path, e) + ) self.overlays.extend(yaml.safe_load_all(overlay_contents)) # gather the names of the removed charms so model.deploy # wouldn't wait for them to appear in the model for overlay in self.overlays: - overlay_apps = overlay.get('applications', {}) + overlay_apps = overlay.get("applications", {}) for charm_name, val in overlay_apps.items(): if val is None: self.overlay_removed_charms.add(charm_name) @@ -295,42 +324,45 @@ async def fetch_plan(self, bundle, origin, overlays=[]): _yaml_data = [yaml.dump(self.bundle)] for overlay in self.overlays: - _yaml_data.append(yaml.dump(overlay).replace('null', '')) + _yaml_data.append(yaml.dump(overlay).replace("null", "")) yaml_data = "---\n".join(_yaml_data) self.plan = await self.bundle_facade.GetChangesMapArgs( - bundleurl=path, - yaml=yaml_data) + bundleurl=path, yaml=yaml_data + ) if self.plan.errors and any(self.plan.errors): raise JujuError(self.plan.errors) async def _download_bundle(self, charm_url, origin): if self.charms_facade is None: - raise JujuError('unable to download bundle for {} using the new charms facade. Upgrade controller to proceed.'.format(charm_url)) + raise JujuError( + "unable to download bundle for {} using the new charms facade. Upgrade controller to proceed.".format( + charm_url + ) + ) - id = origin.id_ if origin.id_ else '' - hash = origin.hash_ if origin.hash_ else '' + id = origin.id_ if origin.id_ else "" + hash = origin.hash_ if origin.hash_ else "" charm_origin = { - 'source': origin.source, - 'type': origin.type_, - 'id': id, - 'hash': hash, - 'revision': origin.revision, - 'risk': origin.risk, - 'track': origin.track, - 'architecture': origin.architecture, + "source": origin.source, + "type": origin.type_, + "id": id, + "hash": hash, + "revision": origin.revision, + "risk": origin.risk, + "track": origin.track, + "architecture": origin.architecture, } if self.model.connection().is_using_old_client: - charm_origin['os'] = origin.os - charm_origin['series'] = origin.series + charm_origin["os"] = origin.os + charm_origin["series"] = origin.series else: - charm_origin['base'] = origin.base + charm_origin["base"] = origin.base - resp = await self.charms_facade.GetDownloadInfos(entities=[{ - 'charm-url': str(charm_url), - 'charm-origin': charm_origin - }]) + resp = await self.charms_facade.GetDownloadInfos( + entities=[{"charm-url": str(charm_url), "charm-origin": charm_origin}] + ) if len(resp.results) != 1: raise JujuError("expected one result, received {}".format(resp.results)) @@ -341,7 +373,9 @@ async def _download_bundle(self, charm_url, origin): bundle_resp = requests.get(result.url) bundle_resp.raise_for_status() - with closing(bundle_resp), zipfile.ZipFile(io.BytesIO(bundle_resp.content)) as archive: + with closing(bundle_resp), zipfile.ZipFile( + io.BytesIO(bundle_resp.content) + ) as archive: return self._get_bundle_yaml(archive) def _get_bundle_yaml(self, archive): @@ -363,44 +397,52 @@ async def _resolve_charms(self): if app is not None: deployed[name] = name - if is_local_charm(spec['charm']): - spec['charm'] = self.model.applications[name] + if is_local_charm(spec["charm"]): + spec["charm"] = self.model.applications[name] continue - if spec['charm'] == app.charm_url: + if spec["charm"] == app.charm_url: continue cons = await app.get_constraints() - if is_local_charm(spec['charm']): + if is_local_charm(spec["charm"]): continue - charm_url = URL.parse(spec['charm']) + charm_url = URL.parse(spec["charm"]) - channel = Channel.parse(spec['channel']) if 'channel' in spec else Channel('latest', 'stable') + channel = ( + Channel.parse(spec["channel"]) + if "channel" in spec + else Channel("latest", "stable") + ) track, risk = channel.track, channel.risk - series = spec.get('series', self.bundle.get('series', None)) + series = spec.get("series", self.bundle.get("series", None)) base = get_base_from_origin_or_channel(channel, series) if self.charms_facade is not None: - if cons is not None and cons['arch'] != '': - architecture = cons['arch'] + if cons is not None and cons["arch"] != "": + architecture = cons["arch"] else: architecture = await self.model._resolve_architecture(charm_url) - origin = client.CharmOrigin(source=Source.CHARM_HUB.value, - architecture=architecture, - risk=risk, - track=track, - base=base, - ) - charm_url, charm_origin = await self.model._resolve_charm(charm_url, origin) - spec['charm'] = str(charm_url) + origin = client.CharmOrigin( + source=Source.CHARM_HUB.value, + architecture=architecture, + risk=risk, + track=track, + base=base, + ) + charm_url, charm_origin = await self.model._resolve_charm( + charm_url, origin + ) + spec["charm"] = str(charm_url) else: - charm_origin = client.CharmOrigin(source=Source.CHARM_HUB.value, - risk=risk, - track=track, - base=base, - ) + charm_origin = client.CharmOrigin( + source=Source.CHARM_HUB.value, + risk=risk, + track=track, + base=base, + ) if str(channel) not in self.origins: self.origins[str(charm_url)] = {} @@ -420,12 +462,12 @@ async def execute_plan(self): @property def applications(self): - apps_dict = self.bundle.get('applications', {}) + apps_dict = self.bundle.get("applications", {}) return set(apps_dict.keys()) - self.overlay_removed_charms @property def applications_specs(self): - return self.bundle.get('applications', {}) + return self.bundle.get("applications", {}) def resolve_relation(self, reference): parts = reference.split(":", maxsplit=1) @@ -435,7 +477,7 @@ def resolve_relation(self, reference): return "{}:{}".format(application, parts[1]) def resolve(self, reference): - if reference and reference.startswith('$'): + if reference and reference.startswith("$"): ref = self.references[reference[1:]] if ref is not None: reference = ref @@ -443,7 +485,11 @@ def resolve(self, reference): def is_local_charm(charm_url: str): - return charm_url.startswith('.') or charm_url.startswith('local:') or os.path.isabs(charm_url) + return ( + charm_url.startswith(".") + or charm_url.startswith("local:") + or os.path.isabs(charm_url) + ) is_local_bundle = is_local_charm @@ -471,7 +517,7 @@ async def get_charm_series(metadata, model): """ - _series = metadata.get('series') + _series = metadata.get("series") series = _series[0] if _series else None if series is None: @@ -487,7 +533,6 @@ async def get_charm_series(metadata, model): class ChangeSet: - def __init__(self, changes): self.changes = changes @@ -524,7 +569,7 @@ def from_dict(cls, self, data): If a value is missing from the data, then None is assigned to the field instance value. """ - d = (data or {}) + d = data or {} for k, v in cls._toPy.items(): if k in d: setattr(self, v, d[k]) @@ -533,17 +578,19 @@ def from_dict(cls, self, data): class AddApplicationChange(ChangeInfo): - _toPy = {'charm': 'charm', - 'series': 'series', - 'application': 'application', - 'options': 'options', - 'constraints': 'constraints', - 'storage': 'storage', - 'devices': 'devices', - 'endpoint-bindings': 'endpoint_bindings', - 'resources': 'resources', - 'num-units': 'num_units', - 'channel': 'channel'} + _toPy = { + "charm": "charm", + "series": "series", + "application": "application", + "options": "options", + "constraints": "constraints", + "storage": "storage", + "devices": "devices", + "endpoint-bindings": "endpoint_bindings", + "resources": "resources", + "num-units": "num_units", + "channel": "channel", + } """AddApplicationChange holds a change for deploying a Juju application. @@ -572,8 +619,7 @@ class AddApplicationChange(ChangeInfo): @staticmethod def method(): - """method returns an associated ID for the Juju API call. - """ + """method returns an associated ID for the Juju API call.""" return "deploy" async def run(self, context): @@ -587,7 +633,7 @@ async def run(self, context): # bundle change plan, and this short-term workaround may be missing some # aspects of the logic which the CLI client contains to handle edge cases. if self.application in context.model.applications: - log.debug('Skipping %s; already in model', self.application) + log.debug("Skipping %s; already in model", self.application) return self.application # resolve indirect references @@ -596,8 +642,12 @@ async def run(self, context): if self.options is not None: options = self.options if context.trusted: - if context.model.info.agent_version < client.Number.from_json('2.4.0'): - raise NotImplementedError("trusted is not supported on model version {}".format(context.model.info.agent_version)) + if context.model.info.agent_version < client.Number.from_json("2.4.0"): + raise NotImplementedError( + "trusted is not supported on model version {}".format( + context.model.info.agent_version + ) + ) options["trust"] = "true" url = URL.parse(str(charm)) @@ -606,7 +656,7 @@ async def run(self, context): if not self.channel: if Schema.CHARM_HUB.matches(url.schema): self.channel = "latest/stable" - else: # for local charms + else: # for local charms self.channel = "" channel = None @@ -620,15 +670,24 @@ async def run(self, context): context.origins.get(str(url), {}).get(str(non_normalized_channel), None), ) if origin is None: - raise JujuError("expected origin to be valid for application {} and charm {} with channel {}".format(self.application, str(url), str(channel))) + raise JujuError( + "expected origin to be valid for application {} and charm {} with channel {}".format( + self.application, str(url), str(channel) + ) + ) if not self.series: self.series = context.bundle.get("series", None) - resources = context.bundle.get("applications", {}).get(self.application, {}).get("resources", {}) + resources = ( + context.bundle.get("applications", {}) + .get(self.application, {}) + .get("resources", {}) + ) if Schema.CHARM_HUB.matches(url.schema): resources = await context.model._add_charmhub_resources( - self.application, charm, origin, overrides=self.resources) + self.application, charm, origin, overrides=self.resources + ) await context.model._deploy( charm_url=charm, @@ -640,8 +699,7 @@ async def run(self, context): resources=resources, storage={ label: parse_storage_constraint(constraint) - for label, constraint - in (self.storage or {}).items() + for label, constraint in (self.storage or {}).items() }, channel=self.channel, devices=self.devices, @@ -659,20 +717,27 @@ def __str__(self): plural = "" if self.num_units > 1: plural = "s" - units_info = " with {num_units} unit{plural}".format(num_units=self.num_units, - plural=plural) - return "deploy application {application}{units_info}{series} using {charm}".format(application=self.application, - units_info=units_info, - series=series, - charm=self.charm) + units_info = " with {num_units} unit{plural}".format( + num_units=self.num_units, plural=plural + ) + return ( + "deploy application {application}{units_info}{series} using {charm}".format( + application=self.application, + units_info=units_info, + series=series, + charm=self.charm, + ) + ) class AddCharmChange(ChangeInfo): - _toPy = {'charm': 'charm', - 'series': 'series', - 'channel': 'channel', - 'revision': 'revision', - 'architecture': 'architecture'} + _toPy = { + "charm": "charm", + "series": "series", + "channel": "channel", + "revision": "revision", + "architecture": "architecture", + } """AddCharmChange holds a change for adding a charm to the environment. @@ -690,10 +755,10 @@ class AddCharmChange(ChangeInfo): :channel: preferred channel for obtaining the charm. :revision: specified revision of the charm to be added if specified. """ + @staticmethod def method(): - """method returns an associated ID for the Juju API call. - """ + """method returns an associated ID for the Juju API call.""" return "addCharm" async def run(self, context): @@ -713,23 +778,25 @@ async def run(self, context): ch = None identifier = None if Schema.CHARM_HUB.matches(url.schema): - ch = Channel('latest', 'stable') + ch = Channel("latest", "stable") if self.channel: ch = Channel.parse(self.channel).normalize() arch = self.architecture if not arch: arch = await context.model._resolve_architecture(url) base = get_base_from_origin_or_channel(ch, self.series) - origin = client.CharmOrigin(source=Source.CHARM_HUB.value, - architecture=arch, - risk=ch.risk, - track=ch.track, - revision=self.revision, - base=base) + origin = client.CharmOrigin( + source=Source.CHARM_HUB.value, + architecture=arch, + risk=ch.risk, + track=ch.track, + revision=self.revision, + base=base, + ) identifier, origin = await context.model._resolve_charm(url, origin) if identifier is None: - raise JujuError('unknown charm {}'.format(self.charm)) + raise JujuError("unknown charm {}".format(self.charm)) await context.model._add_charm(str(identifier), origin) @@ -746,16 +813,18 @@ def __str__(self): series = " for series {}".format(self.series) if self.channel is not None: channel = " from channel {}".format(self.channel) - return "upload charm {charm}{series}{channel}".format(charm=self.charm, - series=series, - channel=channel) + return "upload charm {charm}{series}{channel}".format( + charm=self.charm, series=series, channel=channel + ) class AddMachineChange(ChangeInfo): - _toPy = {'series': 'series', - 'constraints': 'constraints', - 'container-type': 'container_type', - 'parent-id': 'parent_id'} + _toPy = { + "series": "series", + "constraints": "constraints", + "container-type": "container_type", + "parent-id": "parent_id", + } """AddMachineChange holds a change for adding a machine or container. @@ -773,10 +842,10 @@ class AddMachineChange(ChangeInfo): "lxc" or kvm"). It is not specified for top level machines. :parent_id: id of the parent machine. """ + @staticmethod def method(): - """method returns an associated ID for the Juju API call. - """ + """method returns an associated ID for the Juju API call.""" return "addMachines" async def run(self, context): @@ -789,27 +858,29 @@ async def run(self, context): # Fix up values, as necessary. params = {} if self.parent_id is not None: - if self.parent_id.startswith('$addUnit'): + if self.parent_id.startswith("$addUnit"): unit = context.resolve(self.parent_id)[0] - params['parent_id'] = unit.machine.entity_id + params["parent_id"] = unit.machine.entity_id else: - params['parent_id'] = context.resolve(self.parent_id) + params["parent_id"] = context.resolve(self.parent_id) - params['constraints'] = parse_constraints(self.constraints) - params['jobs'] = params.get('jobs', ['JobHostUnits']) + params["constraints"] = parse_constraints(self.constraints) + params["jobs"] = params.get("jobs", ["JobHostUnits"]) if not context.model.connection().is_using_old_client: - params['base'] = client.Base( - channel=utils.get_series_version(self.series), - name='ubuntu') + params["base"] = client.Base( + channel=utils.get_series_version(self.series), name="ubuntu" + ) else: - params['series'] = self.series - - if self.container_type == 'lxc': - log.warning('Juju 2.0 does not support lxc containers. ' - 'Converting containers to lxd.') - params['container_type'] = 'lxd' + params["series"] = self.series + + if self.container_type == "lxc": + log.warning( + "Juju 2.0 does not support lxc containers. " + "Converting containers to lxd." + ) + params["container_type"] = "lxd" else: - params['container_type'] = self.container_type + params["container_type"] = self.container_type # Submit the request. params = client.AddMachineParams(**params) @@ -818,20 +889,20 @@ async def run(self, context): if error: raise ValueError("Error adding machine: %s" % error.message) machine = results.machines[0].machine - log.debug('Added new machine %s', machine) + log.debug("Added new machine %s", machine) return machine def __str__(self): machine = "new machine" if self.container_type is not None and self.container_type != "": - machine = "{container_type} container on {machine}".format(container_type=self.container_type, - machine=machine) + machine = "{container_type} container on {machine}".format( + container_type=self.container_type, machine=machine + ) return "add {}".format(machine) class AddRelationChange(ChangeInfo): - _toPy = {'endpoint1': 'endpoint1', - 'endpoint2': 'endpoint2'} + _toPy = {"endpoint1": "endpoint1", "endpoint2": "endpoint2"} """AddRelationChange holds a change for adding a relation between two applications. @@ -850,10 +921,10 @@ class AddRelationChange(ChangeInfo): application, and the interface is optional. Examples are "$deploy-42:web", "$deploy-42", "mysql:db". """ + @staticmethod def method(): - """method returns an associated ID for the Juju API call. - """ + """method returns an associated ID for the Juju API call.""" return "addRelation" async def run(self, context): @@ -871,20 +942,20 @@ async def run(self, context): # aspects of the logic which the CLI client contains to handle edge cases. existing = [rel for rel in context.model.relations if rel.matches(ep1, ep2)] if existing: - log.info('Skipping %s <-> %s; already related', ep1, ep2) + log.info("Skipping %s <-> %s; already related", ep1, ep2) return existing[0] - log.info('Relating %s <-> %s', ep1, ep2) + log.info("Relating %s <-> %s", ep1, ep2) return await context.model.relate(ep1, ep2) def __str__(self): - return "add relation {endpoint1} - {endpoint2}".format(endpoint1=self.endpoint1, - endpoint2=self.endpoint2) + return "add relation {endpoint1} - {endpoint2}".format( + endpoint1=self.endpoint1, endpoint2=self.endpoint2 + ) class AddUnitChange(ChangeInfo): - _toPy = {'application': 'application', - 'to': 'to'} + _toPy = {"application": "application", "to": "to"} """AddUnitChange holds a change for adding an application unit. :change_id: id of the change that will be used to identify the current @@ -900,10 +971,10 @@ class AddUnitChange(ChangeInfo): :to: optional location where to add the unit, as a placeholder pointing to another unit change or to a machine change. """ + @staticmethod def method(): - """method returns an associated ID for the Juju API call. - """ + """method returns an associated ID for the Juju API call.""" return "addUnit" async def run(self, context): @@ -921,25 +992,31 @@ async def run(self, context): # NB: this should probably honor placement, but the juju client # doesn't, so we're not bothering, either unit_name = context._units_by_app[application].pop() - log.debug('Reusing unit %s for %s', unit_name, application) + log.debug("Reusing unit %s for %s", unit_name, application) return context.model.units[unit_name] - log.debug('Adding new unit for %s%s', application, - ' to %s' % placement if placement else '') + log.debug( + "Adding new unit for %s%s", + application, + " to %s" % placement if placement else "", + ) return await context.model.applications[application].add_unit( count=1, to=placement, ) def __str__(self): - return "add {application} unit to {to}".format(application=self.application, - to=self.to) + return "add {application} unit to {to}".format( + application=self.application, to=self.to + ) class CreateOfferChange(ChangeInfo): - _toPy = {'application': 'application', - 'endpoints': 'endpoints', - 'offer-name': 'offer_name'} + _toPy = { + "application": "application", + "endpoints": "endpoints", + "offer-name": "offer_name", + } """CreateOfferChange holds a change for creating a new application endpoint offer. @@ -957,10 +1034,10 @@ class CreateOfferChange(ChangeInfo): offer. :offer_name: describes the offer name. """ + @staticmethod def method(): - """method returns an associated ID for the Juju API call. - """ + """method returns an associated ID for the Juju API call.""" return "createOffer" async def run(self, context): @@ -972,20 +1049,23 @@ async def run(self, context): """ application = context.resolve(self.application) for ep in self.endpoints: - await context.model.create_offer(ep, offer_name=self.offer_name, application_name=application) + await context.model.create_offer( + ep, offer_name=self.offer_name, application_name=application + ) def __str__(self): endpoints = "" if self.endpoints is not None: endpoints = ":{}".format(",".join(self.endpoints)) - return "create offer {offer_name} using {application}{endpoints}".format(offer_name=self.offer_name, - application=self.application, - endpoints=endpoints) + return "create offer {offer_name} using {application}{endpoints}".format( + offer_name=self.offer_name, + application=self.application, + endpoints=endpoints, + ) class ConsumeOfferChange(ChangeInfo): - _toPy = {'url': 'url', - 'application-name': 'application_name'} + _toPy = {"url": "url", "application-name": "application_name"} """CreateOfferChange holds a change for consuming a offer. :change_id: id of the change that will be used to identify the current @@ -999,10 +1079,10 @@ class ConsumeOfferChange(ChangeInfo): :url: contains the location of the offer :application_name: describes the application name on offer. """ + @staticmethod def method(): - """method returns an associated ID for the Juju API call. - """ + """method returns an associated ID for the Juju API call.""" return "consumeOffer" async def run(self, context): @@ -1013,18 +1093,21 @@ async def run(self, context): perform a change. """ application = context.resolve(self.application_name) - local_name = await context.model.consume(self.url, application_alias=application) + local_name = await context.model.consume( + self.url, application_alias=application + ) return local_name def __str__(self): - return "consume offer {application_name} at {url}".format(application_name=self.application_name, - url=self.url) + return "consume offer {application_name} at {url}".format( + application_name=self.application_name, url=self.url + ) class ExposeChange(ChangeInfo): _toPy = { - 'application': 'application', - 'exposed-endpoints': 'exposed_endpoints', + "application": "application", + "exposed-endpoints": "exposed_endpoints", } """ExposeChange holds a change for exposing an application. @@ -1043,10 +1126,10 @@ class ExposeChange(ChangeInfo): that should be able to access the port ranges that the application has opened for each endpoint. """ + @staticmethod def method(): - """method returns an associated ID for the Juju API call. - """ + """method returns an associated ID for the Juju API call.""" return "expose" async def run(self, context): @@ -1057,16 +1140,17 @@ async def run(self, context): perform a change. """ application = context.resolve(self.application) - log.info('Exposing %s', application) - return await context.model.applications[application].expose(self.exposed_endpoints) + log.info("Exposing %s", application) + return await context.model.applications[application].expose( + self.exposed_endpoints + ) def __str__(self): return "expose {application}".format(application=self.application) class ScaleChange(ChangeInfo): - _toPy = {'application': 'application', - 'scale': 'scale'} + _toPy = {"application": "application", "scale": "scale"} """ ScaleChange holds a change for scaling an application. @@ -1081,10 +1165,10 @@ class ScaleChange(ChangeInfo): :application: placeholder name of the application to be scaled. :scale: is the new scale value to use. """ + @staticmethod def method(): - """method returns an associated ID for the Juju API call. - """ + """method returns an associated ID for the Juju API call.""" return "scale" async def run(self, context): @@ -1098,14 +1182,13 @@ async def run(self, context): return await context.model.applications[application].scale(scale=self.scale) def __str__(self): - return "scale {application} to {scale} units".format(application=self.application, - scale=self.scale) + return "scale {application} to {scale} units".format( + application=self.application, scale=self.scale + ) class SetAnnotationsChange(ChangeInfo): - _toPy = {'id': 'id', - 'entity-type': 'entity_type', - 'annotations': 'annotations'} + _toPy = {"id": "id", "entity-type": "entity_type", "annotations": "annotations"} """SetAnnotationsChange holds a change for setting application and machine annotations. @@ -1122,10 +1205,10 @@ class SetAnnotationsChange(ChangeInfo): :entity_type: type of the entity, "application" or "machine". :ennotations: annotations as key/value pairs. """ + @staticmethod def method(): - """method returns an associated ID for the Juju API call. - """ + """method returns an associated ID for the Juju API call.""" return "setAnnotations" async def run(self, context): diff --git a/juju/charmhub.py b/juju/charmhub.py index b37654266..99cf408da 100644 --- a/juju/charmhub.py +++ b/juju/charmhub.py @@ -15,7 +15,7 @@ def __init__(self, model): async def _charmhub_url(self): model_conf = await self.model.get_config() - return model_conf['charmhub-url'] + return model_conf["charmhub-url"] async def request_charmhub_with_retry(self, url, retries): for attempt in range(retries): @@ -32,17 +32,19 @@ async def get_charm_id(self, charm_name): url = "{}/v2/charms/info/{}".format(charmhub_url.value, charm_name) _response = await self.request_charmhub_with_retry(url, 5) response = json.loads(_response.text) - return response['id'], response['name'] + return response["id"], response["name"] async def is_subordinate(self, charm_name): conn, headers, path_prefix = self.model.connection().https_connection() charmhub_url = await self._charmhub_url() - url = "{}/v2/charms/info/{}?fields=default-release.revision.subordinate".format(charmhub_url.value, charm_name) + url = "{}/v2/charms/info/{}?fields=default-release.revision.subordinate".format( + charmhub_url.value, charm_name + ) _response = await self.request_charmhub_with_retry(url, 5) response = json.loads(_response.text) - rev_response = response['default-release']['revision'] - return 'subordinate' in rev_response and rev_response['subordinate'] + rev_response = response["default-release"]["revision"] + return "subordinate" in rev_response and rev_response["subordinate"] # TODO (caner) : we should be able to recreate the channel-map through the # api call without needing the CharmHub facade @@ -51,10 +53,12 @@ async def list_resources(self, charm_name): conn, headers, path_prefix = self.model.connection().https_connection() charmhub_url = await self._charmhub_url() - url = "{}/v2/charms/info/{}?fields=default-release.resources".format(charmhub_url.value, charm_name) + url = "{}/v2/charms/info/{}?fields=default-release.resources".format( + charmhub_url.value, charm_name + ) _response = await self.request_charmhub_with_retry(url, 5) response = json.loads(_response.text) - return response['default-release']['resources'] + return response["default-release"]["resources"] async def info(self, name, channel=None): """info displays detailed information about a CharmHub charm. The charm @@ -72,31 +76,31 @@ async def info(self, name, channel=None): if channel is None: channel = "" facade = self._facade() - res = await facade.Info(tag="application-{}".format(name), - channel=channel) + res = await facade.Info(tag="application-{}".format(name), channel=channel) err_code = res.errors.error_list.code if err_code: - raise JujuError(f'charmhub.info - {err_code} :' - f' {res.errors.error_list.message}') + raise JujuError( + f"charmhub.info - {err_code} : {res.errors.error_list.message}" + ) result = res.result result.channel_map = CharmHub._channel_map_to_dict( - result.channel_map, - name, - channel=channel) + result.channel_map, name, channel=channel + ) result = result.serialize() else: charmhub_url = await self._charmhub_url() url = "{}/v2/charms/info/{}?fields=channel-map".format( - charmhub_url.value, name) + charmhub_url.value, name + ) try: _response = await self.request_charmhub_with_retry(url, 5) except JujuError as e: - if '404' in e.message: - raise JujuError(f'{name} not found') from e + if "404" in e.message: + raise JujuError(f"{name} not found") from e result = json.loads(_response.text) - result['channel-map'] = CharmHub._channel_list_to_map(result['channel-map'], - name, - channel=channel) + result["channel-map"] = CharmHub._channel_list_to_map( + result["channel-map"], name, channel=channel + ) return result @staticmethod @@ -128,8 +132,7 @@ def _channel_list_to_map(channel_list_map, name, channel=""): break # After loop is done, check for non-existent channel if channel and channel not in channel_map: - raise JujuError(f'Charmhub.info : channel {channel} not found for' - f' {name}') + raise JujuError(f"Charmhub.info : channel {channel} not found for {name}") return channel_map @staticmethod @@ -145,26 +148,38 @@ def _channel_map_to_dict(channel_map, name, channel=""): # No need to worry about filtering channel # Charmhub facade will take care of that _ch = ch_obj.serialize() - _ch['platforms'] = [p.serialize() for p in _ch['platforms']] + _ch["platforms"] = [p.serialize() for p in _ch["platforms"]] channel_dict[ch_name] = _ch if channel and channel not in channel_dict: - raise JujuError(f'Charmhub.info : channel {channel} not found for' - f' {name}') + raise JujuError(f"Charmhub.info : channel {channel} not found for {name}") return channel_dict - async def find(self, query, category=None, channel=None, - charm_type=None, platforms=None, publisher=None, - relation_requires=None, relation_provides=None): - """find queries the CharmHub store for available charms or bundles. - - """ + async def find( + self, + query, + category=None, + channel=None, + charm_type=None, + platforms=None, + publisher=None, + relation_requires=None, + relation_provides=None, + ): + """find queries the CharmHub store for available charms or bundles.""" if charm_type is not None and charm_type not in ["charm", "bundle"]: raise JujuError("expected either charm or bundle for charm_type") facade = self._facade() - return await facade.Find(query=query, category=category, channel=channel, - type_=charm_type, platforms=platforms, publisher=publisher, - relation_provides=relation_provides, relation_requires=relation_requires) + return await facade.Find( + query=query, + category=category, + channel=channel, + type_=charm_type, + platforms=platforms, + publisher=publisher, + relation_provides=relation_provides, + relation_requires=relation_requires, + ) def _facade(self): return client.CharmHubFacade.from_connection(self.model.connection()) diff --git a/juju/client/_client.py b/juju/client/_client.py index 98173aaa4..0d94ed24a 100644 --- a/juju/client/_client.py +++ b/juju/client/_client.py @@ -4,7 +4,23 @@ from juju.client._definitions import * -from juju.client import _client7, _client3, _client4, _client2, _client17, _client6, _client11, _client1, _client10, _client9, _client5, _client19, _client20, _client8, _client12 +from juju.client import ( + _client7, + _client3, + _client4, + _client2, + _client17, + _client6, + _client11, + _client1, + _client10, + _client9, + _client5, + _client19, + _client20, + _client8, + _client12, +) CLIENTS = { @@ -22,7 +38,7 @@ "19": _client19, "20": _client20, "8": _client8, - "12": _client12 + "12": _client12, } @@ -39,8 +55,7 @@ def lookup_facade(name, version): except (KeyError, AttributeError): continue else: - raise ImportError("No supported version for facade: " - "{}".format(name)) + raise ImportError("No supported version for facade: {}".format(name)) class TypeFactory: @@ -55,13 +70,14 @@ def from_connection(cls, connection): """ facade_name = cls.__name__ - if not facade_name.endswith('Facade'): - raise TypeError('Unexpected class name: {}'.format(facade_name)) - facade_name = facade_name[:-len('Facade')] + 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)) + raise Exception( + "No facade {} in facades {}".format(facade_name, connection.facades) + ) c = lookup_facade(cls.__name__, version) c = c() @@ -78,9 +94,9 @@ def best_facade_version(cls, connection): @param connection: initialized Connection object. """ facade_name = cls.__name__ - if not facade_name.endswith('Facade'): - raise TypeError('Unexpected class name: {}'.format(facade_name)) - facade_name = facade_name[:-len('Facade')] + if not facade_name.endswith("Facade"): + raise TypeError("Unexpected class name: {}".format(facade_name)) + facade_name = facade_name[: -len("Facade")] return connection.facades.get(facade_name) @@ -226,5 +242,3 @@ class SubnetsFacade(TypeFactory): class UserManagerFacade(TypeFactory): pass - - diff --git a/juju/client/_client1.py b/juju/client/_client1.py index 0bd3060f9..687d10338 100644 --- a/juju/client/_client1.py +++ b/juju/client/_client1.py @@ -6,264 +6,395 @@ class CredentialManagerFacade(Type): - name = 'CredentialManager' + name = "CredentialManager" version = 1 - schema = {'definitions': {'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - 'type': 'object'}, - 'ErrorResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}}, - 'type': 'object'}, - 'InvalidateCredentialArg': {'additionalProperties': False, - 'properties': {'reason': {'type': 'string'}}, - 'type': 'object'}}, - 'properties': {'InvalidateModelCredential': {'description': 'InvalidateModelCredential ' - 'marks the cloud ' - 'credential for ' - 'this model as ' - 'invalid.', - 'properties': {'Params': {'$ref': '#/definitions/InvalidateCredentialArg'}, - 'Result': {'$ref': '#/definitions/ErrorResult'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "type": "object", + }, + "ErrorResult": { + "additionalProperties": False, + "properties": {"error": {"$ref": "#/definitions/Error"}}, + "type": "object", + }, + "InvalidateCredentialArg": { + "additionalProperties": False, + "properties": {"reason": {"type": "string"}}, + "type": "object", + }, + }, + "properties": { + "InvalidateModelCredential": { + "description": "InvalidateModelCredential " + "marks the cloud " + "credential for " + "this model as " + "invalid.", + "properties": { + "Params": {"$ref": "#/definitions/InvalidateCredentialArg"}, + "Result": {"$ref": "#/definitions/ErrorResult"}, + }, + "type": "object", + } + }, + "type": "object", + } @ReturnMapping(ErrorResult) async def InvalidateModelCredential(self, reason=None): - ''' + """ InvalidateModelCredential marks the cloud credential for this model as invalid. reason : str Returns -> ErrorResult - ''' + """ if reason is not None and not isinstance(reason, (bytes, str)): - raise Exception("Expected reason to be a str, received: {}".format(type(reason))) + raise Exception( + "Expected reason to be a str, received: {}".format(type(reason)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='CredentialManager', - request='InvalidateModelCredential', - version=1, - params=_params) - _params['reason'] = reason + msg = dict( + type="CredentialManager", + request="InvalidateModelCredential", + version=1, + params=_params, + ) + _params["reason"] = reason reply = await self.rpc(msg) return reply - class FirewallRulesFacade(Type): - name = 'FirewallRules' + name = "FirewallRules" version = 1 - schema = {'definitions': {'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - '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'}, - 'FirewallRule': {'additionalProperties': False, - 'properties': {'known-service': {'type': 'string'}, - 'whitelist-cidrs': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['known-service'], - 'type': 'object'}, - 'FirewallRuleArgs': {'additionalProperties': False, - 'properties': {'args': {'items': {'$ref': '#/definitions/FirewallRule'}, - 'type': 'array'}}, - 'required': ['args'], - 'type': 'object'}, - 'ListFirewallRulesResults': {'additionalProperties': False, - 'properties': {'Rules': {'items': {'$ref': '#/definitions/FirewallRule'}, - 'type': 'array'}}, - 'required': ['Rules'], - 'type': 'object'}}, - 'properties': {'ListFirewallRules': {'description': 'ListFirewallRules ' - 'returns all the firewall ' - 'rules.', - 'properties': {'Result': {'$ref': '#/definitions/ListFirewallRulesResults'}}, - 'type': 'object'}, - 'SetFirewallRules': {'description': 'SetFirewallRules creates ' - 'or updates the specified ' - 'firewall rules.', - 'properties': {'Params': {'$ref': '#/definitions/FirewallRuleArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "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", + }, + "FirewallRule": { + "additionalProperties": False, + "properties": { + "known-service": {"type": "string"}, + "whitelist-cidrs": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["known-service"], + "type": "object", + }, + "FirewallRuleArgs": { + "additionalProperties": False, + "properties": { + "args": { + "items": {"$ref": "#/definitions/FirewallRule"}, + "type": "array", + } + }, + "required": ["args"], + "type": "object", + }, + "ListFirewallRulesResults": { + "additionalProperties": False, + "properties": { + "Rules": { + "items": {"$ref": "#/definitions/FirewallRule"}, + "type": "array", + } + }, + "required": ["Rules"], + "type": "object", + }, + }, + "properties": { + "ListFirewallRules": { + "description": "ListFirewallRules returns all the firewall rules.", + "properties": { + "Result": {"$ref": "#/definitions/ListFirewallRulesResults"} + }, + "type": "object", + }, + "SetFirewallRules": { + "description": "SetFirewallRules creates " + "or updates the specified " + "firewall rules.", + "properties": { + "Params": {"$ref": "#/definitions/FirewallRuleArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(ListFirewallRulesResults) async def ListFirewallRules(self): - ''' + """ ListFirewallRules returns all the firewall rules. Returns -> ListFirewallRulesResults - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='FirewallRules', - request='ListFirewallRules', - version=1, - params=_params) + msg = dict( + type="FirewallRules", request="ListFirewallRules", version=1, params=_params + ) reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def SetFirewallRules(self, args=None): - ''' + """ SetFirewallRules creates or updates the specified firewall rules. args : typing.Sequence[~FirewallRule] Returns -> ErrorResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='FirewallRules', - request='SetFirewallRules', - version=1, - params=_params) - _params['args'] = args + msg = dict( + type="FirewallRules", request="SetFirewallRules", version=1, params=_params + ) + _params["args"] = args reply = await self.rpc(msg) return reply - class ImageMetadataManagerFacade(Type): - name = 'ImageMetadataManager' + name = "ImageMetadataManager" version = 1 - schema = {'definitions': {'CloudImageMetadata': {'additionalProperties': False, - 'properties': {'arch': {'type': 'string'}, - 'image-id': {'type': 'string'}, - 'priority': {'type': 'integer'}, - 'region': {'type': 'string'}, - 'root-storage-size': {'type': 'integer'}, - 'root-storage-type': {'type': 'string'}, - 'source': {'type': 'string'}, - 'stream': {'type': 'string'}, - 'version': {'type': 'string'}, - 'virt-type': {'type': 'string'}}, - 'required': ['image-id', - 'region', - 'version', - 'arch', - 'source', - 'priority'], - 'type': 'object'}, - 'CloudImageMetadataList': {'additionalProperties': False, - 'properties': {'metadata': {'items': {'$ref': '#/definitions/CloudImageMetadata'}, - 'type': 'array'}}, - 'type': 'object'}, - 'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - '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'}, - 'ImageMetadataFilter': {'additionalProperties': False, - 'properties': {'arches': {'items': {'type': 'string'}, - 'type': 'array'}, - 'region': {'type': 'string'}, - 'root-storage-type': {'type': 'string'}, - 'stream': {'type': 'string'}, - 'versions': {'items': {'type': 'string'}, - 'type': 'array'}, - 'virt-type': {'type': 'string'}}, - 'type': 'object'}, - 'ListCloudImageMetadataResult': {'additionalProperties': False, - 'properties': {'result': {'items': {'$ref': '#/definitions/CloudImageMetadata'}, - 'type': 'array'}}, - 'required': ['result'], - 'type': 'object'}, - 'MetadataImageIds': {'additionalProperties': False, - 'properties': {'image-ids': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['image-ids'], - 'type': 'object'}, - 'MetadataSaveParams': {'additionalProperties': False, - 'properties': {'metadata': {'items': {'$ref': '#/definitions/CloudImageMetadataList'}, - 'type': 'array'}}, - 'type': 'object'}}, - 'properties': {'Delete': {'description': 'Delete deletes cloud image metadata ' - 'for given image ids.\n' - 'It supports bulk calls.', - 'properties': {'Params': {'$ref': '#/definitions/MetadataImageIds'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'List': {'description': 'List returns all found cloud image ' - 'metadata that satisfy\n' - 'given filter.\n' - 'Returned list contains metadata ' - 'ordered by priority.', - 'properties': {'Params': {'$ref': '#/definitions/ImageMetadataFilter'}, - 'Result': {'$ref': '#/definitions/ListCloudImageMetadataResult'}}, - 'type': 'object'}, - 'Save': {'description': 'Save stores given cloud image ' - 'metadata.\n' - 'It supports bulk calls.', - 'properties': {'Params': {'$ref': '#/definitions/MetadataSaveParams'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "CloudImageMetadata": { + "additionalProperties": False, + "properties": { + "arch": {"type": "string"}, + "image-id": {"type": "string"}, + "priority": {"type": "integer"}, + "region": {"type": "string"}, + "root-storage-size": {"type": "integer"}, + "root-storage-type": {"type": "string"}, + "source": {"type": "string"}, + "stream": {"type": "string"}, + "version": {"type": "string"}, + "virt-type": {"type": "string"}, + }, + "required": [ + "image-id", + "region", + "version", + "arch", + "source", + "priority", + ], + "type": "object", + }, + "CloudImageMetadataList": { + "additionalProperties": False, + "properties": { + "metadata": { + "items": {"$ref": "#/definitions/CloudImageMetadata"}, + "type": "array", + } + }, + "type": "object", + }, + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "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", + }, + "ImageMetadataFilter": { + "additionalProperties": False, + "properties": { + "arches": {"items": {"type": "string"}, "type": "array"}, + "region": {"type": "string"}, + "root-storage-type": {"type": "string"}, + "stream": {"type": "string"}, + "versions": {"items": {"type": "string"}, "type": "array"}, + "virt-type": {"type": "string"}, + }, + "type": "object", + }, + "ListCloudImageMetadataResult": { + "additionalProperties": False, + "properties": { + "result": { + "items": {"$ref": "#/definitions/CloudImageMetadata"}, + "type": "array", + } + }, + "required": ["result"], + "type": "object", + }, + "MetadataImageIds": { + "additionalProperties": False, + "properties": { + "image-ids": {"items": {"type": "string"}, "type": "array"} + }, + "required": ["image-ids"], + "type": "object", + }, + "MetadataSaveParams": { + "additionalProperties": False, + "properties": { + "metadata": { + "items": {"$ref": "#/definitions/CloudImageMetadataList"}, + "type": "array", + } + }, + "type": "object", + }, + }, + "properties": { + "Delete": { + "description": "Delete deletes cloud image metadata " + "for given image ids.\n" + "It supports bulk calls.", + "properties": { + "Params": {"$ref": "#/definitions/MetadataImageIds"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "List": { + "description": "List returns all found cloud image " + "metadata that satisfy\n" + "given filter.\n" + "Returned list contains metadata " + "ordered by priority.", + "properties": { + "Params": {"$ref": "#/definitions/ImageMetadataFilter"}, + "Result": {"$ref": "#/definitions/ListCloudImageMetadataResult"}, + }, + "type": "object", + }, + "Save": { + "description": "Save stores given cloud image " + "metadata.\n" + "It supports bulk calls.", + "properties": { + "Params": {"$ref": "#/definitions/MetadataSaveParams"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(ErrorResults) async def Delete(self, image_ids=None): - ''' + """ Delete deletes cloud image metadata for given image ids. It supports bulk calls. image_ids : typing.Sequence[str] Returns -> ErrorResults - ''' + """ if image_ids is not None and not isinstance(image_ids, (bytes, str, list)): - raise Exception("Expected image_ids to be a Sequence, received: {}".format(type(image_ids))) + raise Exception( + "Expected image_ids to be a Sequence, received: {}".format( + type(image_ids) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ImageMetadataManager', - request='Delete', - version=1, - params=_params) - _params['image-ids'] = image_ids + msg = dict( + type="ImageMetadataManager", request="Delete", version=1, params=_params + ) + _params["image-ids"] = image_ids reply = await self.rpc(msg) return reply - - @ReturnMapping(ListCloudImageMetadataResult) - async def List(self, arches=None, region=None, root_storage_type=None, stream=None, versions=None, virt_type=None): - ''' + async def List( + self, + arches=None, + region=None, + root_storage_type=None, + stream=None, + versions=None, + virt_type=None, + ): + """ List returns all found cloud image metadata that satisfy given filter. Returned list contains metadata ordered by priority. @@ -275,336 +406,450 @@ async def List(self, arches=None, region=None, root_storage_type=None, stream=No versions : typing.Sequence[str] virt_type : str Returns -> ListCloudImageMetadataResult - ''' + """ if arches is not None and not isinstance(arches, (bytes, str, list)): - raise Exception("Expected arches to be a Sequence, received: {}".format(type(arches))) + raise Exception( + "Expected arches to be a Sequence, received: {}".format(type(arches)) + ) if region is not None and not isinstance(region, (bytes, str)): - raise Exception("Expected region to be a str, received: {}".format(type(region))) - - if root_storage_type is not None and not isinstance(root_storage_type, (bytes, str)): - raise Exception("Expected root_storage_type to be a str, received: {}".format(type(root_storage_type))) + raise Exception( + "Expected region to be a str, received: {}".format(type(region)) + ) + + if root_storage_type is not None and not isinstance( + root_storage_type, (bytes, str) + ): + raise Exception( + "Expected root_storage_type to be a str, received: {}".format( + type(root_storage_type) + ) + ) if stream is not None and not isinstance(stream, (bytes, str)): - raise Exception("Expected stream to be a str, received: {}".format(type(stream))) + raise Exception( + "Expected stream to be a str, received: {}".format(type(stream)) + ) if versions is not None and not isinstance(versions, (bytes, str, list)): - raise Exception("Expected versions to be a Sequence, received: {}".format(type(versions))) + raise Exception( + "Expected versions to be a Sequence, received: {}".format( + type(versions) + ) + ) if virt_type is not None and not isinstance(virt_type, (bytes, str)): - raise Exception("Expected virt_type to be a str, received: {}".format(type(virt_type))) + raise Exception( + "Expected virt_type to be a str, received: {}".format(type(virt_type)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ImageMetadataManager', - request='List', - version=1, - params=_params) - _params['arches'] = arches - _params['region'] = region - _params['root-storage-type'] = root_storage_type - _params['stream'] = stream - _params['versions'] = versions - _params['virt-type'] = virt_type + msg = dict( + type="ImageMetadataManager", request="List", version=1, params=_params + ) + _params["arches"] = arches + _params["region"] = region + _params["root-storage-type"] = root_storage_type + _params["stream"] = stream + _params["versions"] = versions + _params["virt-type"] = virt_type reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def Save(self, metadata=None): - ''' + """ Save stores given cloud image metadata. It supports bulk calls. metadata : typing.Sequence[~CloudImageMetadataList] Returns -> ErrorResults - ''' + """ if metadata is not None and not isinstance(metadata, (bytes, str, list)): - raise Exception("Expected metadata to be a Sequence, received: {}".format(type(metadata))) + raise Exception( + "Expected metadata to be a Sequence, received: {}".format( + type(metadata) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ImageMetadataManager', - request='Save', - version=1, - params=_params) - _params['metadata'] = metadata + msg = dict( + type="ImageMetadataManager", request="Save", version=1, params=_params + ) + _params["metadata"] = metadata reply = await self.rpc(msg) return reply - class KeyManagerFacade(Type): - name = 'KeyManager' + name = "KeyManager" version = 1 - schema = {'definitions': {'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'}, - 'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - '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'}, - 'ListSSHKeys': {'additionalProperties': False, - 'properties': {'entities': {'$ref': '#/definitions/Entities'}, - 'mode': {'type': 'boolean'}}, - 'required': ['entities', 'mode'], - 'type': 'object'}, - 'ModifyUserSSHKeys': {'additionalProperties': False, - 'properties': {'ssh-keys': {'items': {'type': 'string'}, - 'type': 'array'}, - 'user': {'type': 'string'}}, - 'required': ['user', 'ssh-keys'], - 'type': 'object'}, - 'StringsResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'StringsResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/StringsResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}}, - 'properties': {'AddKeys': {'description': 'AddKeys adds new authorised ssh ' - 'keys for the specified user.', - 'properties': {'Params': {'$ref': '#/definitions/ModifyUserSSHKeys'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'DeleteKeys': {'description': 'DeleteKeys deletes the ' - 'authorised ssh keys for the ' - 'specified user.', - 'properties': {'Params': {'$ref': '#/definitions/ModifyUserSSHKeys'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'ImportKeys': {'description': 'ImportKeys imports new ' - 'authorised ssh keys from the ' - 'specified key ids for the ' - 'specified user.', - 'properties': {'Params': {'$ref': '#/definitions/ModifyUserSSHKeys'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'ListKeys': {'description': 'ListKeys returns the authorised ' - 'ssh keys for the specified users.', - 'properties': {'Params': {'$ref': '#/definitions/ListSSHKeys'}, - 'Result': {'$ref': '#/definitions/StringsResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "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", + }, + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "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", + }, + "ListSSHKeys": { + "additionalProperties": False, + "properties": { + "entities": {"$ref": "#/definitions/Entities"}, + "mode": {"type": "boolean"}, + }, + "required": ["entities", "mode"], + "type": "object", + }, + "ModifyUserSSHKeys": { + "additionalProperties": False, + "properties": { + "ssh-keys": {"items": {"type": "string"}, "type": "array"}, + "user": {"type": "string"}, + }, + "required": ["user", "ssh-keys"], + "type": "object", + }, + "StringsResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"items": {"type": "string"}, "type": "array"}, + }, + "type": "object", + }, + "StringsResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/StringsResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + }, + "properties": { + "AddKeys": { + "description": "AddKeys adds new authorised ssh " + "keys for the specified user.", + "properties": { + "Params": {"$ref": "#/definitions/ModifyUserSSHKeys"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "DeleteKeys": { + "description": "DeleteKeys deletes the " + "authorised ssh keys for the " + "specified user.", + "properties": { + "Params": {"$ref": "#/definitions/ModifyUserSSHKeys"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "ImportKeys": { + "description": "ImportKeys imports new " + "authorised ssh keys from the " + "specified key ids for the " + "specified user.", + "properties": { + "Params": {"$ref": "#/definitions/ModifyUserSSHKeys"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "ListKeys": { + "description": "ListKeys returns the authorised " + "ssh keys for the specified users.", + "properties": { + "Params": {"$ref": "#/definitions/ListSSHKeys"}, + "Result": {"$ref": "#/definitions/StringsResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(ErrorResults) async def AddKeys(self, ssh_keys=None, user=None): - ''' + """ AddKeys adds new authorised ssh keys for the specified user. ssh_keys : typing.Sequence[str] user : str Returns -> ErrorResults - ''' + """ if ssh_keys is not None and not isinstance(ssh_keys, (bytes, str, list)): - raise Exception("Expected ssh_keys to be a Sequence, received: {}".format(type(ssh_keys))) + raise Exception( + "Expected ssh_keys to be a Sequence, received: {}".format( + type(ssh_keys) + ) + ) if user is not None and not isinstance(user, (bytes, str)): - raise Exception("Expected user to be a str, received: {}".format(type(user))) + raise Exception( + "Expected user to be a str, received: {}".format(type(user)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='KeyManager', - request='AddKeys', - version=1, - params=_params) - _params['ssh-keys'] = ssh_keys - _params['user'] = user + msg = dict(type="KeyManager", request="AddKeys", version=1, params=_params) + _params["ssh-keys"] = ssh_keys + _params["user"] = user reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def DeleteKeys(self, ssh_keys=None, user=None): - ''' + """ DeleteKeys deletes the authorised ssh keys for the specified user. ssh_keys : typing.Sequence[str] user : str Returns -> ErrorResults - ''' + """ if ssh_keys is not None and not isinstance(ssh_keys, (bytes, str, list)): - raise Exception("Expected ssh_keys to be a Sequence, received: {}".format(type(ssh_keys))) + raise Exception( + "Expected ssh_keys to be a Sequence, received: {}".format( + type(ssh_keys) + ) + ) if user is not None and not isinstance(user, (bytes, str)): - raise Exception("Expected user to be a str, received: {}".format(type(user))) + raise Exception( + "Expected user to be a str, received: {}".format(type(user)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='KeyManager', - request='DeleteKeys', - version=1, - params=_params) - _params['ssh-keys'] = ssh_keys - _params['user'] = user + msg = dict(type="KeyManager", request="DeleteKeys", version=1, params=_params) + _params["ssh-keys"] = ssh_keys + _params["user"] = user reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def ImportKeys(self, ssh_keys=None, user=None): - ''' + """ ImportKeys imports new authorised ssh keys from the specified key ids for the specified user. ssh_keys : typing.Sequence[str] user : str Returns -> ErrorResults - ''' + """ if ssh_keys is not None and not isinstance(ssh_keys, (bytes, str, list)): - raise Exception("Expected ssh_keys to be a Sequence, received: {}".format(type(ssh_keys))) + raise Exception( + "Expected ssh_keys to be a Sequence, received: {}".format( + type(ssh_keys) + ) + ) if user is not None and not isinstance(user, (bytes, str)): - raise Exception("Expected user to be a str, received: {}".format(type(user))) + raise Exception( + "Expected user to be a str, received: {}".format(type(user)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='KeyManager', - request='ImportKeys', - version=1, - params=_params) - _params['ssh-keys'] = ssh_keys - _params['user'] = user + msg = dict(type="KeyManager", request="ImportKeys", version=1, params=_params) + _params["ssh-keys"] = ssh_keys + _params["user"] = user reply = await self.rpc(msg) return reply - - @ReturnMapping(StringsResults) async def ListKeys(self, entities=None, mode=None): - ''' + """ ListKeys returns the authorised ssh keys for the specified users. entities : Entities mode : bool Returns -> StringsResults - ''' + """ if entities is not None and not isinstance(entities, (dict, Entities)): - raise Exception("Expected entities to be a Entities, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Entities, received: {}".format( + type(entities) + ) + ) if mode is not None and not isinstance(mode, bool): - raise Exception("Expected mode to be a bool, received: {}".format(type(mode))) + raise Exception( + "Expected mode to be a bool, received: {}".format(type(mode)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='KeyManager', - request='ListKeys', - version=1, - params=_params) - _params['entities'] = entities - _params['mode'] = mode + msg = dict(type="KeyManager", request="ListKeys", version=1, params=_params) + _params["entities"] = entities + _params["mode"] = mode reply = await self.rpc(msg) return reply - class ModelUpgraderFacade(Type): - name = 'ModelUpgrader' + name = "ModelUpgrader" version = 1 - schema = {'definitions': {'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - 'type': 'object'}, - 'ModelParam': {'additionalProperties': False, - 'properties': {'model-tag': {'type': 'string'}}, - 'required': ['model-tag'], - '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'}, - 'UpgradeModelParams': {'additionalProperties': False, - 'properties': {'agent-stream': {'type': 'string'}, - 'dry-run': {'type': 'boolean'}, - 'ignore-agent-versions': {'type': 'boolean'}, - 'model-tag': {'type': 'string'}, - 'target-version': {'$ref': '#/definitions/Number'}}, - 'required': ['model-tag', - 'target-version'], - 'type': 'object'}, - 'UpgradeModelResult': {'additionalProperties': False, - 'properties': {'chosen-version': {'$ref': '#/definitions/Number'}, - 'error': {'$ref': '#/definitions/Error'}}, - 'required': ['chosen-version'], - 'type': 'object'}}, - 'properties': {'AbortModelUpgrade': {'description': 'AbortModelUpgrade aborts ' - 'and archives the model ' - 'upgrade\n' - 'synchronisation record, ' - 'if any.', - 'properties': {'Params': {'$ref': '#/definitions/ModelParam'}}, - 'type': 'object'}, - 'UpgradeModel': {'description': 'UpgradeModel upgrades a ' - 'model.', - 'properties': {'Params': {'$ref': '#/definitions/UpgradeModelParams'}, - 'Result': {'$ref': '#/definitions/UpgradeModelResult'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "type": "object", + }, + "ModelParam": { + "additionalProperties": False, + "properties": {"model-tag": {"type": "string"}}, + "required": ["model-tag"], + "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", + }, + "UpgradeModelParams": { + "additionalProperties": False, + "properties": { + "agent-stream": {"type": "string"}, + "dry-run": {"type": "boolean"}, + "ignore-agent-versions": {"type": "boolean"}, + "model-tag": {"type": "string"}, + "target-version": {"$ref": "#/definitions/Number"}, + }, + "required": ["model-tag", "target-version"], + "type": "object", + }, + "UpgradeModelResult": { + "additionalProperties": False, + "properties": { + "chosen-version": {"$ref": "#/definitions/Number"}, + "error": {"$ref": "#/definitions/Error"}, + }, + "required": ["chosen-version"], + "type": "object", + }, + }, + "properties": { + "AbortModelUpgrade": { + "description": "AbortModelUpgrade aborts " + "and archives the model " + "upgrade\n" + "synchronisation record, " + "if any.", + "properties": {"Params": {"$ref": "#/definitions/ModelParam"}}, + "type": "object", + }, + "UpgradeModel": { + "description": "UpgradeModel upgrades a model.", + "properties": { + "Params": {"$ref": "#/definitions/UpgradeModelParams"}, + "Result": {"$ref": "#/definitions/UpgradeModelResult"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(None) async def AbortModelUpgrade(self, model_tag=None): - ''' + """ AbortModelUpgrade aborts and archives the model upgrade synchronisation record, if any. model_tag : str Returns -> None - ''' + """ if model_tag is not None and not isinstance(model_tag, (bytes, str)): - raise Exception("Expected model_tag to be a str, received: {}".format(type(model_tag))) + raise Exception( + "Expected model_tag to be a str, received: {}".format(type(model_tag)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelUpgrader', - request='AbortModelUpgrade', - version=1, - params=_params) - _params['model-tag'] = model_tag + msg = dict( + type="ModelUpgrader", request="AbortModelUpgrade", version=1, params=_params + ) + _params["model-tag"] = model_tag reply = await self.rpc(msg) return reply - - @ReturnMapping(UpgradeModelResult) - async def UpgradeModel(self, agent_stream=None, dry_run=None, ignore_agent_versions=None, model_tag=None, target_version=None): - ''' + async def UpgradeModel( + self, + agent_stream=None, + dry_run=None, + ignore_agent_versions=None, + model_tag=None, + target_version=None, + ): + """ UpgradeModel upgrades a model. agent_stream : str @@ -613,481 +858,645 @@ async def UpgradeModel(self, agent_stream=None, dry_run=None, ignore_agent_versi model_tag : str target_version : Number Returns -> UpgradeModelResult - ''' + """ if agent_stream is not None and not isinstance(agent_stream, (bytes, str)): - raise Exception("Expected agent_stream to be a str, received: {}".format(type(agent_stream))) + raise Exception( + "Expected agent_stream to be a str, received: {}".format( + type(agent_stream) + ) + ) if dry_run is not None and not isinstance(dry_run, bool): - raise Exception("Expected dry_run to be a bool, received: {}".format(type(dry_run))) - - if ignore_agent_versions is not None and not isinstance(ignore_agent_versions, bool): - raise Exception("Expected ignore_agent_versions to be a bool, received: {}".format(type(ignore_agent_versions))) + raise Exception( + "Expected dry_run to be a bool, received: {}".format(type(dry_run)) + ) + + if ignore_agent_versions is not None and not isinstance( + ignore_agent_versions, bool + ): + raise Exception( + "Expected ignore_agent_versions to be a bool, received: {}".format( + type(ignore_agent_versions) + ) + ) if model_tag is not None and not isinstance(model_tag, (bytes, str)): - raise Exception("Expected model_tag to be a str, received: {}".format(type(model_tag))) - - if target_version is not None and not isinstance(target_version, (dict, Number)): - raise Exception("Expected target_version to be a Number, received: {}".format(type(target_version))) + raise Exception( + "Expected model_tag to be a str, received: {}".format(type(model_tag)) + ) + + if target_version is not None and not isinstance( + target_version, (dict, Number) + ): + raise Exception( + "Expected target_version to be a Number, received: {}".format( + type(target_version) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelUpgrader', - request='UpgradeModel', - version=1, - params=_params) - _params['agent-stream'] = agent_stream - _params['dry-run'] = dry_run - _params['ignore-agent-versions'] = ignore_agent_versions - _params['model-tag'] = model_tag - _params['target-version'] = target_version + msg = dict( + type="ModelUpgrader", request="UpgradeModel", version=1, params=_params + ) + _params["agent-stream"] = agent_stream + _params["dry-run"] = dry_run + _params["ignore-agent-versions"] = ignore_agent_versions + _params["model-tag"] = model_tag + _params["target-version"] = target_version reply = await self.rpc(msg) return reply - class PayloadsFacade(Type): - name = 'Payloads' + name = "Payloads" version = 1 - schema = {'definitions': {'Payload': {'additionalProperties': False, - 'properties': {'class': {'type': 'string'}, - 'id': {'type': 'string'}, - 'labels': {'items': {'type': 'string'}, - 'type': 'array'}, - 'machine': {'type': 'string'}, - 'status': {'type': 'string'}, - 'type': {'type': 'string'}, - 'unit': {'type': 'string'}}, - 'required': ['class', - 'type', - 'id', - 'status', - 'labels', - 'unit', - 'machine'], - 'type': 'object'}, - 'PayloadListArgs': {'additionalProperties': False, - 'properties': {'patterns': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['patterns'], - 'type': 'object'}, - 'PayloadListResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/Payload'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}}, - 'properties': {'List': {'description': 'List builds the list of payloads ' - 'being tracked for\n' - 'the given unit and IDs. If no IDs are ' - 'provided then all tracked\n' - 'payloads for the unit are returned.', - 'properties': {'Params': {'$ref': '#/definitions/PayloadListArgs'}, - 'Result': {'$ref': '#/definitions/PayloadListResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "Payload": { + "additionalProperties": False, + "properties": { + "class": {"type": "string"}, + "id": {"type": "string"}, + "labels": {"items": {"type": "string"}, "type": "array"}, + "machine": {"type": "string"}, + "status": {"type": "string"}, + "type": {"type": "string"}, + "unit": {"type": "string"}, + }, + "required": [ + "class", + "type", + "id", + "status", + "labels", + "unit", + "machine", + ], + "type": "object", + }, + "PayloadListArgs": { + "additionalProperties": False, + "properties": { + "patterns": {"items": {"type": "string"}, "type": "array"} + }, + "required": ["patterns"], + "type": "object", + }, + "PayloadListResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/Payload"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + }, + "properties": { + "List": { + "description": "List builds the list of payloads " + "being tracked for\n" + "the given unit and IDs. If no IDs are " + "provided then all tracked\n" + "payloads for the unit are returned.", + "properties": { + "Params": {"$ref": "#/definitions/PayloadListArgs"}, + "Result": {"$ref": "#/definitions/PayloadListResults"}, + }, + "type": "object", + } + }, + "type": "object", + } @ReturnMapping(PayloadListResults) async def List(self, patterns=None): - ''' + """ List builds the list of payloads being tracked for the given unit and IDs. If no IDs are provided then all tracked payloads for the unit are returned. patterns : typing.Sequence[str] Returns -> PayloadListResults - ''' + """ if patterns is not None and not isinstance(patterns, (bytes, str, list)): - raise Exception("Expected patterns to be a Sequence, received: {}".format(type(patterns))) + raise Exception( + "Expected patterns to be a Sequence, received: {}".format( + type(patterns) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Payloads', - request='List', - version=1, - params=_params) - _params['patterns'] = patterns + msg = dict(type="Payloads", request="List", version=1, params=_params) + _params["patterns"] = patterns reply = await self.rpc(msg) return reply - class PingerFacade(Type): - name = 'Pinger' + name = "Pinger" version = 1 - schema = {'properties': {'Ping': {'type': 'object'}, 'Stop': {'type': 'object'}}, - 'type': 'object'} - + schema = { + "properties": {"Ping": {"type": "object"}, "Stop": {"type": "object"}}, + "type": "object", + } @ReturnMapping(None) async def Ping(self): - ''' + """ Returns -> None - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Pinger', - request='Ping', - version=1, - params=_params) + msg = dict(type="Pinger", request="Ping", version=1, params=_params) reply = await self.rpc(msg) return reply - - @ReturnMapping(None) async def Stop(self): - ''' + """ Returns -> None - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Pinger', - request='Stop', - version=1, - params=_params) + msg = dict(type="Pinger", request="Stop", version=1, params=_params) reply = await self.rpc(msg) return reply - class SecretBackendsFacade(Type): - name = 'SecretBackends' + name = "SecretBackends" version = 1 - schema = {'definitions': {'AddSecretBackendArg': {'additionalProperties': False, - 'properties': {'SecretBackend': {'$ref': '#/definitions/SecretBackend'}, - 'backend-type': {'type': 'string'}, - 'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'id': {'type': 'string'}, - 'name': {'type': 'string'}, - 'token-rotate-interval': {'type': 'integer'}}, - 'required': ['name', - 'backend-type', - 'config', - 'SecretBackend'], - 'type': 'object'}, - 'AddSecretBackendArgs': {'additionalProperties': False, - 'properties': {'args': {'items': {'$ref': '#/definitions/AddSecretBackendArg'}, - 'type': 'array'}}, - 'required': ['args'], - 'type': 'object'}, - 'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - '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'}, - 'ListSecretBackendsArgs': {'additionalProperties': False, - 'properties': {'names': {'items': {'type': 'string'}, - 'type': 'array'}, - 'reveal': {'type': 'boolean'}}, - 'required': ['names', 'reveal'], - 'type': 'object'}, - 'ListSecretBackendsResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/SecretBackendResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'RemoveSecretBackendArg': {'additionalProperties': False, - 'properties': {'force': {'type': 'boolean'}, - 'name': {'type': 'string'}}, - 'required': ['name'], - 'type': 'object'}, - 'RemoveSecretBackendArgs': {'additionalProperties': False, - 'properties': {'args': {'items': {'$ref': '#/definitions/RemoveSecretBackendArg'}, - 'type': 'array'}}, - 'required': ['args'], - 'type': 'object'}, - 'SecretBackend': {'additionalProperties': False, - 'properties': {'backend-type': {'type': 'string'}, - 'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'name': {'type': 'string'}, - 'token-rotate-interval': {'type': 'integer'}}, - 'required': ['name', - 'backend-type', - 'config'], - 'type': 'object'}, - 'SecretBackendResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'id': {'type': 'string'}, - 'message': {'type': 'string'}, - 'num-secrets': {'type': 'integer'}, - 'result': {'$ref': '#/definitions/SecretBackend'}, - 'status': {'type': 'string'}}, - 'required': ['result', - 'id', - 'num-secrets', - 'status'], - 'type': 'object'}, - 'UpdateSecretBackendArg': {'additionalProperties': False, - 'properties': {'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'force': {'type': 'boolean'}, - 'name': {'type': 'string'}, - 'name-change': {'type': 'string'}, - 'reset': {'items': {'type': 'string'}, - 'type': 'array'}, - 'token-rotate-interval': {'type': 'integer'}}, - 'required': ['name', - 'token-rotate-interval', - 'config', - 'reset'], - 'type': 'object'}, - 'UpdateSecretBackendArgs': {'additionalProperties': False, - 'properties': {'args': {'items': {'$ref': '#/definitions/UpdateSecretBackendArg'}, - 'type': 'array'}}, - 'required': ['args'], - 'type': 'object'}}, - 'properties': {'AddSecretBackends': {'description': 'AddSecretBackends adds ' - 'new secret backends.', - 'properties': {'Params': {'$ref': '#/definitions/AddSecretBackendArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'ListSecretBackends': {'description': 'ListSecretBackends ' - 'lists available secret ' - 'backends.', - 'properties': {'Params': {'$ref': '#/definitions/ListSecretBackendsArgs'}, - 'Result': {'$ref': '#/definitions/ListSecretBackendsResults'}}, - 'type': 'object'}, - 'RemoveSecretBackends': {'description': 'RemoveSecretBackends ' - 'removes secret ' - 'backends.', - 'properties': {'Params': {'$ref': '#/definitions/RemoveSecretBackendArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'UpdateSecretBackends': {'description': 'UpdateSecretBackends ' - 'updates secret ' - 'backends.', - 'properties': {'Params': {'$ref': '#/definitions/UpdateSecretBackendArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "AddSecretBackendArg": { + "additionalProperties": False, + "properties": { + "SecretBackend": {"$ref": "#/definitions/SecretBackend"}, + "backend-type": {"type": "string"}, + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "id": {"type": "string"}, + "name": {"type": "string"}, + "token-rotate-interval": {"type": "integer"}, + }, + "required": ["name", "backend-type", "config", "SecretBackend"], + "type": "object", + }, + "AddSecretBackendArgs": { + "additionalProperties": False, + "properties": { + "args": { + "items": {"$ref": "#/definitions/AddSecretBackendArg"}, + "type": "array", + } + }, + "required": ["args"], + "type": "object", + }, + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "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", + }, + "ListSecretBackendsArgs": { + "additionalProperties": False, + "properties": { + "names": {"items": {"type": "string"}, "type": "array"}, + "reveal": {"type": "boolean"}, + }, + "required": ["names", "reveal"], + "type": "object", + }, + "ListSecretBackendsResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/SecretBackendResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "RemoveSecretBackendArg": { + "additionalProperties": False, + "properties": { + "force": {"type": "boolean"}, + "name": {"type": "string"}, + }, + "required": ["name"], + "type": "object", + }, + "RemoveSecretBackendArgs": { + "additionalProperties": False, + "properties": { + "args": { + "items": {"$ref": "#/definitions/RemoveSecretBackendArg"}, + "type": "array", + } + }, + "required": ["args"], + "type": "object", + }, + "SecretBackend": { + "additionalProperties": False, + "properties": { + "backend-type": {"type": "string"}, + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "name": {"type": "string"}, + "token-rotate-interval": {"type": "integer"}, + }, + "required": ["name", "backend-type", "config"], + "type": "object", + }, + "SecretBackendResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "id": {"type": "string"}, + "message": {"type": "string"}, + "num-secrets": {"type": "integer"}, + "result": {"$ref": "#/definitions/SecretBackend"}, + "status": {"type": "string"}, + }, + "required": ["result", "id", "num-secrets", "status"], + "type": "object", + }, + "UpdateSecretBackendArg": { + "additionalProperties": False, + "properties": { + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "force": {"type": "boolean"}, + "name": {"type": "string"}, + "name-change": {"type": "string"}, + "reset": {"items": {"type": "string"}, "type": "array"}, + "token-rotate-interval": {"type": "integer"}, + }, + "required": ["name", "token-rotate-interval", "config", "reset"], + "type": "object", + }, + "UpdateSecretBackendArgs": { + "additionalProperties": False, + "properties": { + "args": { + "items": {"$ref": "#/definitions/UpdateSecretBackendArg"}, + "type": "array", + } + }, + "required": ["args"], + "type": "object", + }, + }, + "properties": { + "AddSecretBackends": { + "description": "AddSecretBackends adds new secret backends.", + "properties": { + "Params": {"$ref": "#/definitions/AddSecretBackendArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "ListSecretBackends": { + "description": "ListSecretBackends lists available secret backends.", + "properties": { + "Params": {"$ref": "#/definitions/ListSecretBackendsArgs"}, + "Result": {"$ref": "#/definitions/ListSecretBackendsResults"}, + }, + "type": "object", + }, + "RemoveSecretBackends": { + "description": "RemoveSecretBackends removes secret backends.", + "properties": { + "Params": {"$ref": "#/definitions/RemoveSecretBackendArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "UpdateSecretBackends": { + "description": "UpdateSecretBackends updates secret backends.", + "properties": { + "Params": {"$ref": "#/definitions/UpdateSecretBackendArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(ErrorResults) async def AddSecretBackends(self, args=None): - ''' + """ AddSecretBackends adds new secret backends. args : typing.Sequence[~AddSecretBackendArg] Returns -> ErrorResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='SecretBackends', - request='AddSecretBackends', - version=1, - params=_params) - _params['args'] = args + msg = dict( + type="SecretBackends", + request="AddSecretBackends", + version=1, + params=_params, + ) + _params["args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(ListSecretBackendsResults) async def ListSecretBackends(self, names=None, reveal=None): - ''' + """ ListSecretBackends lists available secret backends. names : typing.Sequence[str] reveal : bool Returns -> ListSecretBackendsResults - ''' + """ if names is not None and not isinstance(names, (bytes, str, list)): - raise Exception("Expected names to be a Sequence, received: {}".format(type(names))) + raise Exception( + "Expected names to be a Sequence, received: {}".format(type(names)) + ) if reveal is not None and not isinstance(reveal, bool): - raise Exception("Expected reveal to be a bool, received: {}".format(type(reveal))) + raise Exception( + "Expected reveal to be a bool, received: {}".format(type(reveal)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='SecretBackends', - request='ListSecretBackends', - version=1, - params=_params) - _params['names'] = names - _params['reveal'] = reveal + msg = dict( + type="SecretBackends", + request="ListSecretBackends", + version=1, + params=_params, + ) + _params["names"] = names + _params["reveal"] = reveal reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def RemoveSecretBackends(self, args=None): - ''' + """ RemoveSecretBackends removes secret backends. args : typing.Sequence[~RemoveSecretBackendArg] Returns -> ErrorResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='SecretBackends', - request='RemoveSecretBackends', - version=1, - params=_params) - _params['args'] = args + msg = dict( + type="SecretBackends", + request="RemoveSecretBackends", + version=1, + params=_params, + ) + _params["args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def UpdateSecretBackends(self, args=None): - ''' + """ UpdateSecretBackends updates secret backends. args : typing.Sequence[~UpdateSecretBackendArg] Returns -> ErrorResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='SecretBackends', - request='UpdateSecretBackends', - version=1, - params=_params) - _params['args'] = args + msg = dict( + type="SecretBackends", + request="UpdateSecretBackends", + version=1, + params=_params, + ) + _params["args"] = args reply = await self.rpc(msg) return reply - class SecretsFacade(Type): - name = 'Secrets' + name = "Secrets" version = 1 - schema = {'definitions': {'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - 'type': 'object'}, - 'ListSecretResult': {'additionalProperties': False, - 'properties': {'create-time': {'format': 'date-time', - 'type': 'string'}, - 'description': {'type': 'string'}, - 'label': {'type': 'string'}, - 'latest-expire-time': {'format': 'date-time', - 'type': 'string'}, - 'latest-revision': {'type': 'integer'}, - 'next-rotate-time': {'format': 'date-time', - 'type': 'string'}, - 'owner-tag': {'type': 'string'}, - 'revisions': {'items': {'$ref': '#/definitions/SecretRevision'}, - 'type': 'array'}, - 'rotate-policy': {'type': 'string'}, - 'update-time': {'format': 'date-time', - 'type': 'string'}, - 'uri': {'type': 'string'}, - 'value': {'$ref': '#/definitions/SecretValueResult'}, - 'version': {'type': 'integer'}}, - 'required': ['uri', - 'version', - 'owner-tag', - 'latest-revision', - 'create-time', - 'update-time', - 'revisions'], - 'type': 'object'}, - 'ListSecretResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ListSecretResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'ListSecretsArgs': {'additionalProperties': False, - 'properties': {'filter': {'$ref': '#/definitions/SecretsFilter'}, - 'show-secrets': {'type': 'boolean'}}, - 'required': ['show-secrets', 'filter'], - 'type': 'object'}, - 'SecretRevision': {'additionalProperties': False, - 'properties': {'backend-name': {'type': 'string'}, - 'create-time': {'format': 'date-time', - 'type': 'string'}, - 'expire-time': {'format': 'date-time', - 'type': 'string'}, - 'revision': {'type': 'integer'}, - 'update-time': {'format': 'date-time', - 'type': 'string'}, - 'value-ref': {'$ref': '#/definitions/SecretValueRef'}}, - 'required': ['revision'], - 'type': 'object'}, - 'SecretValueRef': {'additionalProperties': False, - 'properties': {'backend-id': {'type': 'string'}, - 'revision-id': {'type': 'string'}}, - 'required': ['backend-id', 'revision-id'], - 'type': 'object'}, - 'SecretValueResult': {'additionalProperties': False, - 'properties': {'data': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'error': {'$ref': '#/definitions/Error'}}, - 'type': 'object'}, - 'SecretsFilter': {'additionalProperties': False, - 'properties': {'owner-tag': {'type': 'string'}, - 'revision': {'type': 'integer'}, - 'uri': {'type': 'string'}}, - 'type': 'object'}}, - 'properties': {'ListSecrets': {'description': 'ListSecrets lists available ' - 'secrets.', - 'properties': {'Params': {'$ref': '#/definitions/ListSecretsArgs'}, - 'Result': {'$ref': '#/definitions/ListSecretResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "type": "object", + }, + "ListSecretResult": { + "additionalProperties": False, + "properties": { + "create-time": {"format": "date-time", "type": "string"}, + "description": {"type": "string"}, + "label": {"type": "string"}, + "latest-expire-time": {"format": "date-time", "type": "string"}, + "latest-revision": {"type": "integer"}, + "next-rotate-time": {"format": "date-time", "type": "string"}, + "owner-tag": {"type": "string"}, + "revisions": { + "items": {"$ref": "#/definitions/SecretRevision"}, + "type": "array", + }, + "rotate-policy": {"type": "string"}, + "update-time": {"format": "date-time", "type": "string"}, + "uri": {"type": "string"}, + "value": {"$ref": "#/definitions/SecretValueResult"}, + "version": {"type": "integer"}, + }, + "required": [ + "uri", + "version", + "owner-tag", + "latest-revision", + "create-time", + "update-time", + "revisions", + ], + "type": "object", + }, + "ListSecretResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ListSecretResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "ListSecretsArgs": { + "additionalProperties": False, + "properties": { + "filter": {"$ref": "#/definitions/SecretsFilter"}, + "show-secrets": {"type": "boolean"}, + }, + "required": ["show-secrets", "filter"], + "type": "object", + }, + "SecretRevision": { + "additionalProperties": False, + "properties": { + "backend-name": {"type": "string"}, + "create-time": {"format": "date-time", "type": "string"}, + "expire-time": {"format": "date-time", "type": "string"}, + "revision": {"type": "integer"}, + "update-time": {"format": "date-time", "type": "string"}, + "value-ref": {"$ref": "#/definitions/SecretValueRef"}, + }, + "required": ["revision"], + "type": "object", + }, + "SecretValueRef": { + "additionalProperties": False, + "properties": { + "backend-id": {"type": "string"}, + "revision-id": {"type": "string"}, + }, + "required": ["backend-id", "revision-id"], + "type": "object", + }, + "SecretValueResult": { + "additionalProperties": False, + "properties": { + "data": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "error": {"$ref": "#/definitions/Error"}, + }, + "type": "object", + }, + "SecretsFilter": { + "additionalProperties": False, + "properties": { + "owner-tag": {"type": "string"}, + "revision": {"type": "integer"}, + "uri": {"type": "string"}, + }, + "type": "object", + }, + }, + "properties": { + "ListSecrets": { + "description": "ListSecrets lists available secrets.", + "properties": { + "Params": {"$ref": "#/definitions/ListSecretsArgs"}, + "Result": {"$ref": "#/definitions/ListSecretResults"}, + }, + "type": "object", + } + }, + "type": "object", + } @ReturnMapping(ListSecretResults) async def ListSecrets(self, filter_=None, show_secrets=None): - ''' + """ ListSecrets lists available secrets. filter_ : SecretsFilter show_secrets : bool Returns -> ListSecretResults - ''' + """ if filter_ is not None and not isinstance(filter_, (dict, SecretsFilter)): - raise Exception("Expected filter_ to be a SecretsFilter, received: {}".format(type(filter_))) + raise Exception( + "Expected filter_ to be a SecretsFilter, received: {}".format( + type(filter_) + ) + ) if show_secrets is not None and not isinstance(show_secrets, bool): - raise Exception("Expected show_secrets to be a bool, received: {}".format(type(show_secrets))) + raise Exception( + "Expected show_secrets to be a bool, received: {}".format( + type(show_secrets) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Secrets', - request='ListSecrets', - version=1, - params=_params) - _params['filter'] = filter_ - _params['show-secrets'] = show_secrets + msg = dict(type="Secrets", request="ListSecrets", version=1, params=_params) + _params["filter"] = filter_ + _params["show-secrets"] = show_secrets reply = await self.rpc(msg) return reply - - diff --git a/juju/client/_client10.py b/juju/client/_client10.py index 2700cef32..4417a71f8 100644 --- a/juju/client/_client10.py +++ b/juju/client/_client10.py @@ -6,391 +6,615 @@ class MachineManagerFacade(Type): - name = 'MachineManager' + name = "MachineManager" version = 10 - schema = {'definitions': {'AddMachineParams': {'additionalProperties': False, - 'properties': {'addresses': {'items': {'$ref': '#/definitions/Address'}, - 'type': 'array'}, - 'base': {'$ref': '#/definitions/Base'}, - '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'}}, - 'required': ['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': {'cidr': {'type': 'string'}, - 'config-type': {'type': 'string'}, - 'is-secondary': {'type': 'boolean'}, - 'scope': {'type': 'string'}, - 'space-id': {'type': 'string'}, - 'space-name': {'type': 'string'}, - 'type': {'type': 'string'}, - 'value': {'type': 'string'}}, - 'required': ['value', 'type', 'scope'], - 'type': 'object'}, - 'Base': {'additionalProperties': False, - 'properties': {'channel': {'type': 'string'}, - 'name': {'type': 'string'}}, - 'required': ['name', 'channel'], - 'type': 'object'}, - 'Constraints': {'additionalProperties': False, - 'properties': {'Count': {'type': 'integer'}, - 'Pool': {'type': 'string'}, - 'Size': {'type': 'integer'}}, - 'required': ['Pool', 'Size', 'Count'], - 'type': 'object'}, - 'DestroyMachineInfo': {'additionalProperties': False, - 'properties': {'destroyed-containers': {'items': {'$ref': '#/definitions/DestroyMachineResult'}, - 'type': 'array'}, - 'destroyed-storage': {'items': {'$ref': '#/definitions/Entity'}, - 'type': 'array'}, - 'destroyed-units': {'items': {'$ref': '#/definitions/Entity'}, - 'type': 'array'}, - 'detached-storage': {'items': {'$ref': '#/definitions/Entity'}, - 'type': 'array'}, - 'machine-id': {'type': 'string'}}, - 'required': ['machine-id'], - 'type': 'object'}, - 'DestroyMachineResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'info': {'$ref': '#/definitions/DestroyMachineInfo'}}, - 'type': 'object'}, - 'DestroyMachineResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/DestroyMachineResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'DestroyMachinesParams': {'additionalProperties': False, - 'properties': {'dry-run': {'type': 'boolean'}, - 'force': {'type': 'boolean'}, - 'keep': {'type': 'boolean'}, - 'machine-tags': {'items': {'type': 'string'}, - 'type': 'array'}, - 'max-wait': {'type': 'integer'}}, - 'required': ['machine-tags'], - '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'}, - 'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - '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'}, - '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'}, - 'root-disk-source': {'type': 'string'}, - 'tags': {'items': {'type': 'string'}, - 'type': 'array'}, - 'virt-type': {'type': 'string'}}, - 'type': 'object'}, - 'InstanceType': {'additionalProperties': False, - 'properties': {'arches': {'items': {'type': 'string'}, - 'type': 'array'}, - 'cost': {'type': 'integer'}, - 'cpu-cores': {'type': 'integer'}, - 'memory': {'type': 'integer'}, - 'name': {'type': 'string'}, - 'root-disk': {'type': 'integer'}, - 'virt-type': {'type': 'string'}}, - 'required': ['arches', 'cpu-cores', 'memory'], - 'type': 'object'}, - 'InstanceTypesResult': {'additionalProperties': False, - 'properties': {'cost-currency': {'type': 'string'}, - 'cost-divisor': {'type': 'integer'}, - 'cost-unit': {'type': 'string'}, - 'error': {'$ref': '#/definitions/Error'}, - 'instance-types': {'items': {'$ref': '#/definitions/InstanceType'}, - 'type': 'array'}}, - 'type': 'object'}, - 'InstanceTypesResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/InstanceTypesResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'ModelInstanceTypesConstraint': {'additionalProperties': False, - 'properties': {'value': {'$ref': '#/definitions/Value'}}, - 'type': 'object'}, - 'ModelInstanceTypesConstraints': {'additionalProperties': False, - 'properties': {'constraints': {'items': {'$ref': '#/definitions/ModelInstanceTypesConstraint'}, - 'type': 'array'}}, - 'required': ['constraints'], - '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'}, - 'Placement': {'additionalProperties': False, - 'properties': {'directive': {'type': 'string'}, - 'scope': {'type': 'string'}}, - 'required': ['scope', 'directive'], - 'type': 'object'}, - 'ProvisioningScriptParams': {'additionalProperties': False, - 'properties': {'data-dir': {'type': 'string'}, - 'disable-package-commands': {'type': 'boolean'}, - 'machine-id': {'type': 'string'}, - 'nonce': {'type': 'string'}}, - 'required': ['machine-id', - 'nonce', - 'data-dir', - 'disable-package-commands'], - 'type': 'object'}, - 'ProvisioningScriptResult': {'additionalProperties': False, - 'properties': {'script': {'type': 'string'}}, - 'required': ['script'], - 'type': 'object'}, - 'RetryProvisioningArgs': {'additionalProperties': False, - 'properties': {'all': {'type': 'boolean'}, - 'machines': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['all'], - 'type': 'object'}, - 'StringsResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'StringsResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/StringsResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'UpdateChannelArg': {'additionalProperties': False, - 'properties': {'channel': {'type': 'string'}, - 'force': {'type': 'boolean'}, - 'tag': {'$ref': '#/definitions/Entity'}}, - 'required': ['tag', 'force', 'channel'], - 'type': 'object'}, - 'UpdateChannelArgs': {'additionalProperties': False, - 'properties': {'args': {'items': {'$ref': '#/definitions/UpdateChannelArg'}, - 'type': 'array'}}, - 'required': ['args'], - 'type': 'object'}, - 'UpgradeSeriesNotificationParam': {'additionalProperties': False, - 'properties': {'entity': {'$ref': '#/definitions/Entity'}, - 'watcher-id': {'type': 'string'}}, - 'required': ['entity', - 'watcher-id'], - 'type': 'object'}, - 'UpgradeSeriesNotificationParams': {'additionalProperties': False, - 'properties': {'params': {'items': {'$ref': '#/definitions/UpgradeSeriesNotificationParam'}, - 'type': 'array'}}, - 'required': ['params'], - 'type': 'object'}, - 'UpgradeSeriesUnitsResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'unit-names': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['unit-names'], - 'type': 'object'}, - 'UpgradeSeriesUnitsResults': {'additionalProperties': False, - 'properties': {'Results': {'items': {'$ref': '#/definitions/UpgradeSeriesUnitsResult'}, - 'type': 'array'}}, - 'required': ['Results'], - 'type': 'object'}, - 'Value': {'additionalProperties': False, - 'properties': {'allocate-public-ip': {'type': 'boolean'}, - 'arch': {'type': 'string'}, - 'container': {'type': 'string'}, - 'cores': {'type': 'integer'}, - 'cpu-power': {'type': 'integer'}, - 'image-id': {'type': 'string'}, - 'instance-role': {'type': 'string'}, - 'instance-type': {'type': 'string'}, - 'mem': {'type': 'integer'}, - 'root-disk': {'type': 'integer'}, - 'root-disk-source': {'type': 'string'}, - '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': {'AddMachines': {'description': 'AddMachines adds new machines ' - 'with the supplied parameters.\n' - 'The args will contain Base ' - 'info.', - 'properties': {'Params': {'$ref': '#/definitions/AddMachines'}, - 'Result': {'$ref': '#/definitions/AddMachinesResults'}}, - 'type': 'object'}, - 'DestroyMachineWithParams': {'description': 'DestroyMachineWithParams ' - 'removes a set of ' - 'machines from the ' - 'model.', - 'properties': {'Params': {'$ref': '#/definitions/DestroyMachinesParams'}, - 'Result': {'$ref': '#/definitions/DestroyMachineResults'}}, - 'type': 'object'}, - 'GetUpgradeSeriesMessages': {'description': 'GetUpgradeSeriesMessages ' - 'returns all new ' - 'messages ' - 'associated with ' - 'upgrade\n' - 'series events. ' - 'Messages that ' - 'have already been ' - 'retrieved once ' - 'are not\n' - 'returned by this ' - 'method.', - 'properties': {'Params': {'$ref': '#/definitions/UpgradeSeriesNotificationParams'}, - 'Result': {'$ref': '#/definitions/StringsResults'}}, - 'type': 'object'}, - 'InstanceTypes': {'description': 'InstanceTypes returns ' - 'instance type information ' - 'for the cloud and region\n' - 'in which the current model ' - 'is deployed.', - 'properties': {'Params': {'$ref': '#/definitions/ModelInstanceTypesConstraints'}, - 'Result': {'$ref': '#/definitions/InstanceTypesResults'}}, - 'type': 'object'}, - 'ProvisioningScript': {'description': 'ProvisioningScript ' - 'returns a shell script ' - 'that, when run,\n' - 'provisions a machine ' - 'agent on the machine ' - 'executing the script.', - 'properties': {'Params': {'$ref': '#/definitions/ProvisioningScriptParams'}, - 'Result': {'$ref': '#/definitions/ProvisioningScriptResult'}}, - 'type': 'object'}, - 'RetryProvisioning': {'description': 'RetryProvisioning marks ' - 'a provisioning error as ' - 'transient on the ' - 'machines.', - 'properties': {'Params': {'$ref': '#/definitions/RetryProvisioningArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'UpgradeSeriesComplete': {'description': 'UpgradeSeriesComplete ' - 'marks a machine as ' - 'having completed a ' - 'managed series\n' - 'upgrade.', - 'properties': {'Params': {'$ref': '#/definitions/UpdateChannelArg'}, - 'Result': {'$ref': '#/definitions/ErrorResult'}}, - 'type': 'object'}, - 'UpgradeSeriesPrepare': {'description': 'UpgradeSeriesPrepare ' - 'prepares a machine ' - 'for a OS series ' - 'upgrade.', - 'properties': {'Params': {'$ref': '#/definitions/UpdateChannelArg'}, - 'Result': {'$ref': '#/definitions/ErrorResult'}}, - 'type': 'object'}, - 'UpgradeSeriesValidate': {'description': 'UpgradeSeriesValidate ' - 'validates that the ' - 'incoming arguments ' - 'correspond to a\n' - 'valid series upgrade ' - 'for the target ' - 'machine.\n' - 'If they do, a list ' - "of the machine's " - 'current units is ' - 'returned for use in\n' - 'soliciting user ' - 'confirmation of the ' - 'command.', - 'properties': {'Params': {'$ref': '#/definitions/UpdateChannelArgs'}, - 'Result': {'$ref': '#/definitions/UpgradeSeriesUnitsResults'}}, - 'type': 'object'}, - 'WatchUpgradeSeriesNotifications': {'description': 'WatchUpgradeSeriesNotifications ' - 'returns a ' - 'watcher ' - 'that fires ' - 'on ' - 'upgrade\n' - 'series ' - 'events.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/NotifyWatchResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "AddMachineParams": { + "additionalProperties": False, + "properties": { + "addresses": { + "items": {"$ref": "#/definitions/Address"}, + "type": "array", + }, + "base": {"$ref": "#/definitions/Base"}, + "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"}, + }, + "required": [ + "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": { + "cidr": {"type": "string"}, + "config-type": {"type": "string"}, + "is-secondary": {"type": "boolean"}, + "scope": {"type": "string"}, + "space-id": {"type": "string"}, + "space-name": {"type": "string"}, + "type": {"type": "string"}, + "value": {"type": "string"}, + }, + "required": ["value", "type", "scope"], + "type": "object", + }, + "Base": { + "additionalProperties": False, + "properties": { + "channel": {"type": "string"}, + "name": {"type": "string"}, + }, + "required": ["name", "channel"], + "type": "object", + }, + "Constraints": { + "additionalProperties": False, + "properties": { + "Count": {"type": "integer"}, + "Pool": {"type": "string"}, + "Size": {"type": "integer"}, + }, + "required": ["Pool", "Size", "Count"], + "type": "object", + }, + "DestroyMachineInfo": { + "additionalProperties": False, + "properties": { + "destroyed-containers": { + "items": {"$ref": "#/definitions/DestroyMachineResult"}, + "type": "array", + }, + "destroyed-storage": { + "items": {"$ref": "#/definitions/Entity"}, + "type": "array", + }, + "destroyed-units": { + "items": {"$ref": "#/definitions/Entity"}, + "type": "array", + }, + "detached-storage": { + "items": {"$ref": "#/definitions/Entity"}, + "type": "array", + }, + "machine-id": {"type": "string"}, + }, + "required": ["machine-id"], + "type": "object", + }, + "DestroyMachineResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "info": {"$ref": "#/definitions/DestroyMachineInfo"}, + }, + "type": "object", + }, + "DestroyMachineResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/DestroyMachineResult"}, + "type": "array", + } + }, + "type": "object", + }, + "DestroyMachinesParams": { + "additionalProperties": False, + "properties": { + "dry-run": {"type": "boolean"}, + "force": {"type": "boolean"}, + "keep": {"type": "boolean"}, + "machine-tags": {"items": {"type": "string"}, "type": "array"}, + "max-wait": {"type": "integer"}, + }, + "required": ["machine-tags"], + "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", + }, + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "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", + }, + "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"}, + "root-disk-source": {"type": "string"}, + "tags": {"items": {"type": "string"}, "type": "array"}, + "virt-type": {"type": "string"}, + }, + "type": "object", + }, + "InstanceType": { + "additionalProperties": False, + "properties": { + "arches": {"items": {"type": "string"}, "type": "array"}, + "cost": {"type": "integer"}, + "cpu-cores": {"type": "integer"}, + "memory": {"type": "integer"}, + "name": {"type": "string"}, + "root-disk": {"type": "integer"}, + "virt-type": {"type": "string"}, + }, + "required": ["arches", "cpu-cores", "memory"], + "type": "object", + }, + "InstanceTypesResult": { + "additionalProperties": False, + "properties": { + "cost-currency": {"type": "string"}, + "cost-divisor": {"type": "integer"}, + "cost-unit": {"type": "string"}, + "error": {"$ref": "#/definitions/Error"}, + "instance-types": { + "items": {"$ref": "#/definitions/InstanceType"}, + "type": "array", + }, + }, + "type": "object", + }, + "InstanceTypesResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/InstanceTypesResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "ModelInstanceTypesConstraint": { + "additionalProperties": False, + "properties": {"value": {"$ref": "#/definitions/Value"}}, + "type": "object", + }, + "ModelInstanceTypesConstraints": { + "additionalProperties": False, + "properties": { + "constraints": { + "items": {"$ref": "#/definitions/ModelInstanceTypesConstraint"}, + "type": "array", + } + }, + "required": ["constraints"], + "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", + }, + "Placement": { + "additionalProperties": False, + "properties": { + "directive": {"type": "string"}, + "scope": {"type": "string"}, + }, + "required": ["scope", "directive"], + "type": "object", + }, + "ProvisioningScriptParams": { + "additionalProperties": False, + "properties": { + "data-dir": {"type": "string"}, + "disable-package-commands": {"type": "boolean"}, + "machine-id": {"type": "string"}, + "nonce": {"type": "string"}, + }, + "required": [ + "machine-id", + "nonce", + "data-dir", + "disable-package-commands", + ], + "type": "object", + }, + "ProvisioningScriptResult": { + "additionalProperties": False, + "properties": {"script": {"type": "string"}}, + "required": ["script"], + "type": "object", + }, + "RetryProvisioningArgs": { + "additionalProperties": False, + "properties": { + "all": {"type": "boolean"}, + "machines": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["all"], + "type": "object", + }, + "StringsResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"items": {"type": "string"}, "type": "array"}, + }, + "type": "object", + }, + "StringsResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/StringsResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "UpdateChannelArg": { + "additionalProperties": False, + "properties": { + "channel": {"type": "string"}, + "force": {"type": "boolean"}, + "tag": {"$ref": "#/definitions/Entity"}, + }, + "required": ["tag", "force", "channel"], + "type": "object", + }, + "UpdateChannelArgs": { + "additionalProperties": False, + "properties": { + "args": { + "items": {"$ref": "#/definitions/UpdateChannelArg"}, + "type": "array", + } + }, + "required": ["args"], + "type": "object", + }, + "UpgradeSeriesNotificationParam": { + "additionalProperties": False, + "properties": { + "entity": {"$ref": "#/definitions/Entity"}, + "watcher-id": {"type": "string"}, + }, + "required": ["entity", "watcher-id"], + "type": "object", + }, + "UpgradeSeriesNotificationParams": { + "additionalProperties": False, + "properties": { + "params": { + "items": { + "$ref": "#/definitions/UpgradeSeriesNotificationParam" + }, + "type": "array", + } + }, + "required": ["params"], + "type": "object", + }, + "UpgradeSeriesUnitsResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "unit-names": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["unit-names"], + "type": "object", + }, + "UpgradeSeriesUnitsResults": { + "additionalProperties": False, + "properties": { + "Results": { + "items": {"$ref": "#/definitions/UpgradeSeriesUnitsResult"}, + "type": "array", + } + }, + "required": ["Results"], + "type": "object", + }, + "Value": { + "additionalProperties": False, + "properties": { + "allocate-public-ip": {"type": "boolean"}, + "arch": {"type": "string"}, + "container": {"type": "string"}, + "cores": {"type": "integer"}, + "cpu-power": {"type": "integer"}, + "image-id": {"type": "string"}, + "instance-role": {"type": "string"}, + "instance-type": {"type": "string"}, + "mem": {"type": "integer"}, + "root-disk": {"type": "integer"}, + "root-disk-source": {"type": "string"}, + "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": { + "AddMachines": { + "description": "AddMachines adds new machines " + "with the supplied parameters.\n" + "The args will contain Base " + "info.", + "properties": { + "Params": {"$ref": "#/definitions/AddMachines"}, + "Result": {"$ref": "#/definitions/AddMachinesResults"}, + }, + "type": "object", + }, + "DestroyMachineWithParams": { + "description": "DestroyMachineWithParams " + "removes a set of " + "machines from the " + "model.", + "properties": { + "Params": {"$ref": "#/definitions/DestroyMachinesParams"}, + "Result": {"$ref": "#/definitions/DestroyMachineResults"}, + }, + "type": "object", + }, + "GetUpgradeSeriesMessages": { + "description": "GetUpgradeSeriesMessages " + "returns all new " + "messages " + "associated with " + "upgrade\n" + "series events. " + "Messages that " + "have already been " + "retrieved once " + "are not\n" + "returned by this " + "method.", + "properties": { + "Params": {"$ref": "#/definitions/UpgradeSeriesNotificationParams"}, + "Result": {"$ref": "#/definitions/StringsResults"}, + }, + "type": "object", + }, + "InstanceTypes": { + "description": "InstanceTypes returns " + "instance type information " + "for the cloud and region\n" + "in which the current model " + "is deployed.", + "properties": { + "Params": {"$ref": "#/definitions/ModelInstanceTypesConstraints"}, + "Result": {"$ref": "#/definitions/InstanceTypesResults"}, + }, + "type": "object", + }, + "ProvisioningScript": { + "description": "ProvisioningScript " + "returns a shell script " + "that, when run,\n" + "provisions a machine " + "agent on the machine " + "executing the script.", + "properties": { + "Params": {"$ref": "#/definitions/ProvisioningScriptParams"}, + "Result": {"$ref": "#/definitions/ProvisioningScriptResult"}, + }, + "type": "object", + }, + "RetryProvisioning": { + "description": "RetryProvisioning marks " + "a provisioning error as " + "transient on the " + "machines.", + "properties": { + "Params": {"$ref": "#/definitions/RetryProvisioningArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "UpgradeSeriesComplete": { + "description": "UpgradeSeriesComplete " + "marks a machine as " + "having completed a " + "managed series\n" + "upgrade.", + "properties": { + "Params": {"$ref": "#/definitions/UpdateChannelArg"}, + "Result": {"$ref": "#/definitions/ErrorResult"}, + }, + "type": "object", + }, + "UpgradeSeriesPrepare": { + "description": "UpgradeSeriesPrepare " + "prepares a machine " + "for a OS series " + "upgrade.", + "properties": { + "Params": {"$ref": "#/definitions/UpdateChannelArg"}, + "Result": {"$ref": "#/definitions/ErrorResult"}, + }, + "type": "object", + }, + "UpgradeSeriesValidate": { + "description": "UpgradeSeriesValidate " + "validates that the " + "incoming arguments " + "correspond to a\n" + "valid series upgrade " + "for the target " + "machine.\n" + "If they do, a list " + "of the machine's " + "current units is " + "returned for use in\n" + "soliciting user " + "confirmation of the " + "command.", + "properties": { + "Params": {"$ref": "#/definitions/UpdateChannelArgs"}, + "Result": {"$ref": "#/definitions/UpgradeSeriesUnitsResults"}, + }, + "type": "object", + }, + "WatchUpgradeSeriesNotifications": { + "description": "WatchUpgradeSeriesNotifications " + "returns a " + "watcher " + "that fires " + "on " + "upgrade\n" + "series " + "events.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/NotifyWatchResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(AddMachinesResults) async def AddMachines(self, params=None): - ''' + """ AddMachines adds new machines with the supplied parameters. The args will contain Base info. params : typing.Sequence[~AddMachineParams] Returns -> AddMachinesResults - ''' + """ if params is not None and not isinstance(params, (bytes, str, list)): - raise Exception("Expected params to be a Sequence, received: {}".format(type(params))) + raise Exception( + "Expected params to be a Sequence, received: {}".format(type(params)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='MachineManager', - request='AddMachines', - version=10, - params=_params) - _params['params'] = params + msg = dict( + type="MachineManager", request="AddMachines", version=10, params=_params + ) + _params["params"] = params reply = await self.rpc(msg) return reply - - @ReturnMapping(DestroyMachineResults) - async def DestroyMachineWithParams(self, dry_run=None, force=None, keep=None, machine_tags=None, max_wait=None): - ''' + async def DestroyMachineWithParams( + self, dry_run=None, force=None, keep=None, machine_tags=None, max_wait=None + ): + """ DestroyMachineWithParams removes a set of machines from the model. dry_run : bool @@ -399,90 +623,109 @@ async def DestroyMachineWithParams(self, dry_run=None, force=None, keep=None, ma machine_tags : typing.Sequence[str] max_wait : int Returns -> DestroyMachineResults - ''' + """ if dry_run is not None and not isinstance(dry_run, bool): - raise Exception("Expected dry_run to be a bool, received: {}".format(type(dry_run))) + raise Exception( + "Expected dry_run to be a bool, received: {}".format(type(dry_run)) + ) if force is not None and not isinstance(force, bool): - raise Exception("Expected force to be a bool, received: {}".format(type(force))) + raise Exception( + "Expected force to be a bool, received: {}".format(type(force)) + ) if keep is not None and not isinstance(keep, bool): - raise Exception("Expected keep to be a bool, received: {}".format(type(keep))) - - if machine_tags is not None and not isinstance(machine_tags, (bytes, str, list)): - raise Exception("Expected machine_tags to be a Sequence, received: {}".format(type(machine_tags))) + raise Exception( + "Expected keep to be a bool, received: {}".format(type(keep)) + ) + + if machine_tags is not None and not isinstance( + machine_tags, (bytes, str, list) + ): + raise Exception( + "Expected machine_tags to be a Sequence, received: {}".format( + type(machine_tags) + ) + ) if max_wait is not None and not isinstance(max_wait, int): - raise Exception("Expected max_wait to be a int, received: {}".format(type(max_wait))) + raise Exception( + "Expected max_wait to be a int, received: {}".format(type(max_wait)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='MachineManager', - request='DestroyMachineWithParams', - version=10, - params=_params) - _params['dry-run'] = dry_run - _params['force'] = force - _params['keep'] = keep - _params['machine-tags'] = machine_tags - _params['max-wait'] = max_wait + msg = dict( + type="MachineManager", + request="DestroyMachineWithParams", + version=10, + params=_params, + ) + _params["dry-run"] = dry_run + _params["force"] = force + _params["keep"] = keep + _params["machine-tags"] = machine_tags + _params["max-wait"] = max_wait reply = await self.rpc(msg) return reply - - @ReturnMapping(StringsResults) async def GetUpgradeSeriesMessages(self, params=None): - ''' + """ GetUpgradeSeriesMessages returns all new messages associated with upgrade series events. Messages that have already been retrieved once are not returned by this method. params : typing.Sequence[~UpgradeSeriesNotificationParam] Returns -> StringsResults - ''' + """ if params is not None and not isinstance(params, (bytes, str, list)): - raise Exception("Expected params to be a Sequence, received: {}".format(type(params))) + raise Exception( + "Expected params to be a Sequence, received: {}".format(type(params)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='MachineManager', - request='GetUpgradeSeriesMessages', - version=10, - params=_params) - _params['params'] = params + msg = dict( + type="MachineManager", + request="GetUpgradeSeriesMessages", + version=10, + params=_params, + ) + _params["params"] = params reply = await self.rpc(msg) return reply - - @ReturnMapping(InstanceTypesResults) async def InstanceTypes(self, constraints=None): - ''' + """ InstanceTypes returns instance type information for the cloud and region in which the current model is deployed. constraints : typing.Sequence[~ModelInstanceTypesConstraint] Returns -> InstanceTypesResults - ''' + """ if constraints is not None and not isinstance(constraints, (bytes, str, list)): - raise Exception("Expected constraints to be a Sequence, received: {}".format(type(constraints))) + raise Exception( + "Expected constraints to be a Sequence, received: {}".format( + type(constraints) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='MachineManager', - request='InstanceTypes', - version=10, - params=_params) - _params['constraints'] = constraints + msg = dict( + type="MachineManager", request="InstanceTypes", version=10, params=_params + ) + _params["constraints"] = constraints reply = await self.rpc(msg) return reply - - @ReturnMapping(ProvisioningScriptResult) - async def ProvisioningScript(self, data_dir=None, disable_package_commands=None, machine_id=None, nonce=None): - ''' + async def ProvisioningScript( + self, data_dir=None, disable_package_commands=None, machine_id=None, nonce=None + ): + """ ProvisioningScript returns a shell script that, when run, provisions a machine agent on the machine executing the script. @@ -491,65 +734,83 @@ async def ProvisioningScript(self, data_dir=None, disable_package_commands=None, machine_id : str nonce : str Returns -> ProvisioningScriptResult - ''' + """ if data_dir is not None and not isinstance(data_dir, (bytes, str)): - raise Exception("Expected data_dir to be a str, received: {}".format(type(data_dir))) - - if disable_package_commands is not None and not isinstance(disable_package_commands, bool): - raise Exception("Expected disable_package_commands to be a bool, received: {}".format(type(disable_package_commands))) + raise Exception( + "Expected data_dir to be a str, received: {}".format(type(data_dir)) + ) + + if disable_package_commands is not None and not isinstance( + disable_package_commands, bool + ): + raise Exception( + "Expected disable_package_commands to be a bool, received: {}".format( + type(disable_package_commands) + ) + ) if machine_id is not None and not isinstance(machine_id, (bytes, str)): - raise Exception("Expected machine_id to be a str, received: {}".format(type(machine_id))) + raise Exception( + "Expected machine_id to be a str, received: {}".format(type(machine_id)) + ) if nonce is not None and not isinstance(nonce, (bytes, str)): - raise Exception("Expected nonce to be a str, received: {}".format(type(nonce))) + raise Exception( + "Expected nonce to be a str, received: {}".format(type(nonce)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='MachineManager', - request='ProvisioningScript', - version=10, - params=_params) - _params['data-dir'] = data_dir - _params['disable-package-commands'] = disable_package_commands - _params['machine-id'] = machine_id - _params['nonce'] = nonce + msg = dict( + type="MachineManager", + request="ProvisioningScript", + version=10, + params=_params, + ) + _params["data-dir"] = data_dir + _params["disable-package-commands"] = disable_package_commands + _params["machine-id"] = machine_id + _params["nonce"] = nonce reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def RetryProvisioning(self, all_=None, machines=None): - ''' + """ RetryProvisioning marks a provisioning error as transient on the machines. all_ : bool machines : typing.Sequence[str] Returns -> ErrorResults - ''' + """ if all_ is not None and not isinstance(all_, bool): - raise Exception("Expected all_ to be a bool, received: {}".format(type(all_))) + raise Exception( + "Expected all_ to be a bool, received: {}".format(type(all_)) + ) if machines is not None and not isinstance(machines, (bytes, str, list)): - raise Exception("Expected machines to be a Sequence, received: {}".format(type(machines))) + raise Exception( + "Expected machines to be a Sequence, received: {}".format( + type(machines) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='MachineManager', - request='RetryProvisioning', - version=10, - params=_params) - _params['all'] = all_ - _params['machines'] = machines + msg = dict( + type="MachineManager", + request="RetryProvisioning", + version=10, + params=_params, + ) + _params["all"] = all_ + _params["machines"] = machines reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResult) async def UpgradeSeriesComplete(self, channel=None, force=None, tag=None): - ''' + """ UpgradeSeriesComplete marks a machine as having completed a managed series upgrade. @@ -557,66 +818,78 @@ async def UpgradeSeriesComplete(self, channel=None, force=None, tag=None): force : bool tag : Entity Returns -> ErrorResult - ''' + """ if channel is not None and not isinstance(channel, (bytes, str)): - raise Exception("Expected channel to be a str, received: {}".format(type(channel))) + raise Exception( + "Expected channel to be a str, received: {}".format(type(channel)) + ) if force is not None and not isinstance(force, bool): - raise Exception("Expected force to be a bool, received: {}".format(type(force))) + raise Exception( + "Expected force to be a bool, received: {}".format(type(force)) + ) if tag is not None and not isinstance(tag, (dict, Entity)): - raise Exception("Expected tag to be a Entity, received: {}".format(type(tag))) + raise Exception( + "Expected tag to be a Entity, received: {}".format(type(tag)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='MachineManager', - request='UpgradeSeriesComplete', - version=10, - params=_params) - _params['channel'] = channel - _params['force'] = force - _params['tag'] = tag + msg = dict( + type="MachineManager", + request="UpgradeSeriesComplete", + version=10, + params=_params, + ) + _params["channel"] = channel + _params["force"] = force + _params["tag"] = tag reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResult) async def UpgradeSeriesPrepare(self, channel=None, force=None, tag=None): - ''' + """ UpgradeSeriesPrepare prepares a machine for a OS series upgrade. channel : str force : bool tag : Entity Returns -> ErrorResult - ''' + """ if channel is not None and not isinstance(channel, (bytes, str)): - raise Exception("Expected channel to be a str, received: {}".format(type(channel))) + raise Exception( + "Expected channel to be a str, received: {}".format(type(channel)) + ) if force is not None and not isinstance(force, bool): - raise Exception("Expected force to be a bool, received: {}".format(type(force))) + raise Exception( + "Expected force to be a bool, received: {}".format(type(force)) + ) if tag is not None and not isinstance(tag, (dict, Entity)): - raise Exception("Expected tag to be a Entity, received: {}".format(type(tag))) + raise Exception( + "Expected tag to be a Entity, received: {}".format(type(tag)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='MachineManager', - request='UpgradeSeriesPrepare', - version=10, - params=_params) - _params['channel'] = channel - _params['force'] = force - _params['tag'] = tag + msg = dict( + type="MachineManager", + request="UpgradeSeriesPrepare", + version=10, + params=_params, + ) + _params["channel"] = channel + _params["force"] = force + _params["tag"] = tag reply = await self.rpc(msg) return reply - - @ReturnMapping(UpgradeSeriesUnitsResults) async def UpgradeSeriesValidate(self, args=None): - ''' + """ UpgradeSeriesValidate validates that the incoming arguments correspond to a valid series upgrade for the target machine. If they do, a list of the machine's current units is returned for use in @@ -624,621 +897,952 @@ async def UpgradeSeriesValidate(self, args=None): args : typing.Sequence[~UpdateChannelArg] Returns -> UpgradeSeriesUnitsResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='MachineManager', - request='UpgradeSeriesValidate', - version=10, - params=_params) - _params['args'] = args + msg = dict( + type="MachineManager", + request="UpgradeSeriesValidate", + version=10, + params=_params, + ) + _params["args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(NotifyWatchResults) async def WatchUpgradeSeriesNotifications(self, entities=None): - ''' + """ WatchUpgradeSeriesNotifications returns a watcher that fires on upgrade series events. entities : typing.Sequence[~Entity] Returns -> NotifyWatchResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='MachineManager', - request='WatchUpgradeSeriesNotifications', - version=10, - params=_params) - _params['entities'] = entities + msg = dict( + type="MachineManager", + request="WatchUpgradeSeriesNotifications", + version=10, + params=_params, + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - class ModelManagerFacade(Type): - name = 'ModelManager' + name = "ModelManager" version = 10 - schema = {'definitions': {'ChangeModelCredentialParams': {'additionalProperties': False, - 'properties': {'credential-tag': {'type': 'string'}, - 'model-tag': {'type': 'string'}}, - 'required': ['model-tag', - 'credential-tag'], - 'type': 'object'}, - 'ChangeModelCredentialsParams': {'additionalProperties': False, - 'properties': {'model-credentials': {'items': {'$ref': '#/definitions/ChangeModelCredentialParams'}, - 'type': 'array'}}, - 'required': ['model-credentials'], - 'type': 'object'}, - 'DestroyModelParams': {'additionalProperties': False, - 'properties': {'destroy-storage': {'type': 'boolean'}, - 'force': {'type': 'boolean'}, - 'max-wait': {'type': 'integer'}, - 'model-tag': {'type': 'string'}, - 'timeout': {'type': 'integer'}}, - 'required': ['model-tag'], - 'type': 'object'}, - 'DestroyModelsParams': {'additionalProperties': False, - 'properties': {'models': {'items': {'$ref': '#/definitions/DestroyModelParams'}, - 'type': 'array'}}, - 'required': ['models'], - 'type': 'object'}, - 'DumpModelRequest': {'additionalProperties': False, - 'properties': {'entities': {'items': {'$ref': '#/definitions/Entity'}, - 'type': 'array'}, - 'simplified': {'type': 'boolean'}}, - 'required': ['entities', 'simplified'], - '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'}, - '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': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - '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'}, - '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'}, - 'virt-type': {'type': 'string'}}, - 'type': 'object'}, - 'MapResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}}, - 'required': ['result'], - 'type': 'object'}, - 'MapResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/MapResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'Model': {'additionalProperties': False, - 'properties': {'name': {'type': 'string'}, - 'owner-tag': {'type': 'string'}, - 'type': {'type': 'string'}, - 'uuid': {'type': 'string'}}, - 'required': ['name', 'uuid', 'type', 'owner-tag'], - 'type': 'object'}, - 'ModelApplicationInfo': {'additionalProperties': False, - 'properties': {'name': {'type': 'string'}}, - 'required': ['name'], - 'type': 'object'}, - 'ModelCreateArgs': {'additionalProperties': False, - 'properties': {'cloud-tag': {'type': 'string'}, - 'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'credential': {'type': 'string'}, - 'name': {'type': 'string'}, - 'owner-tag': {'type': 'string'}, - 'region': {'type': 'string'}}, - 'required': ['name', 'owner-tag'], - 'type': 'object'}, - 'ModelDefaultValues': {'additionalProperties': False, - 'properties': {'cloud-region': {'type': 'string'}, - 'cloud-tag': {'type': 'string'}, - 'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}}, - 'required': ['config'], - 'type': 'object'}, - 'ModelDefaults': {'additionalProperties': False, - 'properties': {'controller': {'additionalProperties': True, - 'type': 'object'}, - 'default': {'additionalProperties': True, - 'type': 'object'}, - 'regions': {'items': {'$ref': '#/definitions/RegionDefaults'}, - 'type': 'array'}}, - 'type': 'object'}, - 'ModelDefaultsResult': {'additionalProperties': False, - 'properties': {'config': {'patternProperties': {'.*': {'$ref': '#/definitions/ModelDefaults'}}, - 'type': 'object'}, - 'error': {'$ref': '#/definitions/Error'}}, - 'required': ['config'], - 'type': 'object'}, - 'ModelDefaultsResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ModelDefaultsResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'ModelEntityCount': {'additionalProperties': False, - 'properties': {'count': {'type': 'integer'}, - 'entity': {'type': 'string'}}, - 'required': ['entity', 'count'], - 'type': 'object'}, - 'ModelFilesystemInfo': {'additionalProperties': False, - 'properties': {'detachable': {'type': 'boolean'}, - 'id': {'type': 'string'}, - 'message': {'type': 'string'}, - 'provider-id': {'type': 'string'}, - 'status': {'type': 'string'}}, - 'required': ['id'], - 'type': 'object'}, - 'ModelInfo': {'additionalProperties': False, - 'properties': {'agent-version': {'$ref': '#/definitions/Number'}, - 'cloud-credential-tag': {'type': 'string'}, - 'cloud-credential-validity': {'type': 'boolean'}, - 'cloud-region': {'type': 'string'}, - 'cloud-tag': {'type': 'string'}, - 'controller-uuid': {'type': 'string'}, - 'default-base': {'type': 'string'}, - 'default-series': {'type': 'string'}, - 'is-controller': {'type': 'boolean'}, - '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'}, - 'secret-backends': {'items': {'$ref': '#/definitions/SecretBackendResult'}, - 'type': 'array'}, - 'sla': {'$ref': '#/definitions/ModelSLAInfo'}, - 'status': {'$ref': '#/definitions/EntityStatus'}, - 'supported-features': {'items': {'$ref': '#/definitions/SupportedFeature'}, - 'type': 'array'}, - 'type': {'type': 'string'}, - 'users': {'items': {'$ref': '#/definitions/ModelUserInfo'}, - 'type': 'array'}, - 'uuid': {'type': 'string'}}, - 'required': ['name', - 'type', - 'uuid', - 'controller-uuid', - 'is-controller', - 'cloud-tag', - 'owner-tag', - 'life', - 'users', - 'machines', - 'secret-backends', - 'sla', - 'agent-version'], - 'type': 'object'}, - 'ModelInfoResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/ModelInfo'}}, - 'type': 'object'}, - 'ModelInfoResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ModelInfoResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'ModelMachineInfo': {'additionalProperties': False, - 'properties': {'display-name': {'type': 'string'}, - 'ha-primary': {'type': 'boolean'}, - 'hardware': {'$ref': '#/definitions/MachineHardware'}, - 'has-vote': {'type': 'boolean'}, - 'id': {'type': 'string'}, - 'instance-id': {'type': 'string'}, - 'message': {'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'}, - 'ModelSLAInfo': {'additionalProperties': False, - 'properties': {'level': {'type': 'string'}, - 'owner': {'type': 'string'}}, - 'required': ['level', 'owner'], - 'type': 'object'}, - 'ModelStatus': {'additionalProperties': False, - 'properties': {'application-count': {'type': 'integer'}, - 'applications': {'items': {'$ref': '#/definitions/ModelApplicationInfo'}, - 'type': 'array'}, - 'error': {'$ref': '#/definitions/Error'}, - 'filesystems': {'items': {'$ref': '#/definitions/ModelFilesystemInfo'}, - 'type': 'array'}, - 'hosted-machine-count': {'type': 'integer'}, - 'life': {'type': 'string'}, - 'machines': {'items': {'$ref': '#/definitions/ModelMachineInfo'}, - 'type': 'array'}, - 'model-tag': {'type': 'string'}, - 'owner-tag': {'type': 'string'}, - 'type': {'type': 'string'}, - 'unit-count': {'type': 'integer'}, - 'volumes': {'items': {'$ref': '#/definitions/ModelVolumeInfo'}, - 'type': 'array'}}, - 'required': ['model-tag', - 'life', - 'type', - 'hosted-machine-count', - 'application-count', - 'unit-count', - 'owner-tag'], - 'type': 'object'}, - 'ModelStatusResults': {'additionalProperties': False, - 'properties': {'models': {'items': {'$ref': '#/definitions/ModelStatus'}, - 'type': 'array'}}, - 'required': ['models'], - 'type': 'object'}, - 'ModelSummariesRequest': {'additionalProperties': False, - 'properties': {'all': {'type': 'boolean'}, - 'user-tag': {'type': 'string'}}, - 'required': ['user-tag'], - 'type': 'object'}, - 'ModelSummary': {'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'}, - 'counts': {'items': {'$ref': '#/definitions/ModelEntityCount'}, - 'type': 'array'}, - 'default-series': {'type': 'string'}, - 'is-controller': {'type': 'boolean'}, - 'last-connection': {'format': 'date-time', - 'type': 'string'}, - 'life': {'type': 'string'}, - 'migration': {'$ref': '#/definitions/ModelMigrationStatus'}, - 'name': {'type': 'string'}, - 'owner-tag': {'type': 'string'}, - 'provider-type': {'type': 'string'}, - 'sla': {'$ref': '#/definitions/ModelSLAInfo'}, - 'status': {'$ref': '#/definitions/EntityStatus'}, - 'type': {'type': 'string'}, - 'user-access': {'type': 'string'}, - 'uuid': {'type': 'string'}}, - 'required': ['name', - 'uuid', - 'type', - 'controller-uuid', - 'is-controller', - 'cloud-tag', - 'owner-tag', - 'life', - 'user-access', - 'last-connection', - 'counts', - 'sla', - 'agent-version'], - 'type': 'object'}, - 'ModelSummaryResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/ModelSummary'}}, - 'type': 'object'}, - 'ModelSummaryResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ModelSummaryResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'ModelUnsetKeys': {'additionalProperties': False, - 'properties': {'cloud-region': {'type': 'string'}, - 'cloud-tag': {'type': 'string'}, - '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'}, - 'model-tag': {'type': 'string'}, - 'user': {'type': 'string'}}, - 'required': ['model-tag', - 'user', - 'display-name', - 'last-connection', - 'access'], - 'type': 'object'}, - 'ModelVolumeInfo': {'additionalProperties': False, - 'properties': {'detachable': {'type': 'boolean'}, - 'id': {'type': 'string'}, - 'message': {'type': 'string'}, - 'provider-id': {'type': 'string'}, - 'status': {'type': 'string'}}, - 'required': ['id'], - 'type': 'object'}, - 'ModifyModelAccess': {'additionalProperties': False, - 'properties': {'access': {'type': 'string'}, - 'action': {'type': 'string'}, - 'model-tag': {'type': 'string'}, - 'user-tag': {'type': 'string'}}, - 'required': ['user-tag', - 'action', - 'access', - 'model-tag'], - 'type': 'object'}, - 'ModifyModelAccessRequest': {'additionalProperties': False, - 'properties': {'changes': {'items': {'$ref': '#/definitions/ModifyModelAccess'}, - 'type': 'array'}}, - 'required': ['changes'], - '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'}, - 'RegionDefaults': {'additionalProperties': False, - 'properties': {'region-name': {'type': 'string'}, - 'value': {'additionalProperties': True, - 'type': 'object'}}, - 'required': ['region-name', 'value'], - 'type': 'object'}, - 'SecretBackend': {'additionalProperties': False, - 'properties': {'backend-type': {'type': 'string'}, - 'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'name': {'type': 'string'}, - 'token-rotate-interval': {'type': 'integer'}}, - 'required': ['name', - 'backend-type', - 'config'], - 'type': 'object'}, - 'SecretBackendResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'id': {'type': 'string'}, - 'message': {'type': 'string'}, - 'num-secrets': {'type': 'integer'}, - 'result': {'$ref': '#/definitions/SecretBackend'}, - 'status': {'type': 'string'}}, - 'required': ['result', - 'id', - 'num-secrets', - 'status'], - 'type': 'object'}, - 'SetModelDefaults': {'additionalProperties': False, - 'properties': {'config': {'items': {'$ref': '#/definitions/ModelDefaultValues'}, - 'type': 'array'}}, - 'required': ['config'], - 'type': 'object'}, - 'StringResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'type': 'string'}}, - 'required': ['result'], - 'type': 'object'}, - 'StringResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/StringResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'SupportedFeature': {'additionalProperties': False, - 'properties': {'description': {'type': 'string'}, - 'name': {'type': 'string'}, - 'version': {'type': 'string'}}, - 'required': ['name', 'description'], - 'type': 'object'}, - 'UnsetModelDefaults': {'additionalProperties': False, - 'properties': {'keys': {'items': {'$ref': '#/definitions/ModelUnsetKeys'}, - 'type': 'array'}}, - 'required': ['keys'], - 'type': 'object'}, - 'UserModel': {'additionalProperties': False, - 'properties': {'last-connection': {'format': 'date-time', - 'type': 'string'}, - 'model': {'$ref': '#/definitions/Model'}}, - 'required': ['model', 'last-connection'], - 'type': 'object'}, - 'UserModelList': {'additionalProperties': False, - 'properties': {'user-models': {'items': {'$ref': '#/definitions/UserModel'}, - 'type': 'array'}}, - 'required': ['user-models'], - 'type': 'object'}}, - 'properties': {'ChangeModelCredential': {'description': 'ChangeModelCredential ' - 'changes cloud ' - 'credential reference ' - 'for models.\n' - 'These new cloud ' - 'credentials must ' - 'already exist on the ' - 'controller.', - 'properties': {'Params': {'$ref': '#/definitions/ChangeModelCredentialsParams'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'CreateModel': {'description': 'CreateModel creates a new ' - 'model using the account and\n' - 'model config specified in the ' - 'args.', - 'properties': {'Params': {'$ref': '#/definitions/ModelCreateArgs'}, - 'Result': {'$ref': '#/definitions/ModelInfo'}}, - 'type': 'object'}, - 'DestroyModels': {'description': 'DestroyModels will try to ' - 'destroy the specified ' - 'models.\n' - 'If there is a block on ' - 'destruction, this method ' - 'will return an error.\n' - 'From ModelManager v7 ' - 'onwards, DestroyModels gains ' - "'force' and 'max-wait' " - 'parameters.', - 'properties': {'Params': {'$ref': '#/definitions/DestroyModelsParams'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'DumpModels': {'description': 'DumpModels will export the ' - 'models into the database ' - 'agnostic\n' - 'representation. The user needs ' - 'to either be a controller ' - 'admin, or have\n' - 'admin privileges on the model ' - 'itself.', - 'properties': {'Params': {'$ref': '#/definitions/DumpModelRequest'}, - 'Result': {'$ref': '#/definitions/StringResults'}}, - 'type': 'object'}, - 'DumpModelsDB': {'description': 'DumpModelsDB will gather all ' - 'documents from all model ' - 'collections\n' - 'for the specified model. The ' - 'map result contains a map of ' - 'collection\n' - 'names to lists of documents ' - 'represented as maps.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/MapResults'}}, - 'type': 'object'}, - 'ListModelSummaries': {'description': 'ListModelSummaries ' - 'returns models that the ' - 'specified user\n' - 'has access to in the ' - 'current server. ' - 'Controller admins ' - '(superuser)\n' - 'can list models for any ' - 'user. Other users\n' - 'can only ask about ' - 'their own models.', - 'properties': {'Params': {'$ref': '#/definitions/ModelSummariesRequest'}, - 'Result': {'$ref': '#/definitions/ModelSummaryResults'}}, - 'type': 'object'}, - 'ListModels': {'description': 'ListModels returns the models ' - 'that the specified user\n' - 'has access to in the current ' - 'server. Controller admins ' - '(superuser)\n' - 'can list models for any user. ' - 'Other users\n' - 'can only ask about their own ' - 'models.', - 'properties': {'Params': {'$ref': '#/definitions/Entity'}, - 'Result': {'$ref': '#/definitions/UserModelList'}}, - 'type': 'object'}, - 'ModelDefaultsForClouds': {'description': 'ModelDefaultsForClouds ' - 'returns the default ' - 'config values for ' - 'the specified\n' - 'clouds.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ModelDefaultsResults'}}, - 'type': 'object'}, - 'ModelInfo': {'description': 'ModelInfo returns information ' - 'about the specified models.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ModelInfoResults'}}, - 'type': 'object'}, - 'ModelStatus': {'description': 'ModelStatus returns a summary ' - 'of the model.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ModelStatusResults'}}, - 'type': 'object'}, - 'ModifyModelAccess': {'description': 'ModifyModelAccess ' - 'changes the model access ' - 'granted to users.', - 'properties': {'Params': {'$ref': '#/definitions/ModifyModelAccessRequest'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'SetModelDefaults': {'description': 'SetModelDefaults writes ' - 'new values for the ' - 'specified default model ' - 'settings.', - 'properties': {'Params': {'$ref': '#/definitions/SetModelDefaults'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'UnsetModelDefaults': {'description': 'UnsetModelDefaults ' - 'removes the specified ' - 'default model settings.', - 'properties': {'Params': {'$ref': '#/definitions/UnsetModelDefaults'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "ChangeModelCredentialParams": { + "additionalProperties": False, + "properties": { + "credential-tag": {"type": "string"}, + "model-tag": {"type": "string"}, + }, + "required": ["model-tag", "credential-tag"], + "type": "object", + }, + "ChangeModelCredentialsParams": { + "additionalProperties": False, + "properties": { + "model-credentials": { + "items": {"$ref": "#/definitions/ChangeModelCredentialParams"}, + "type": "array", + } + }, + "required": ["model-credentials"], + "type": "object", + }, + "DestroyModelParams": { + "additionalProperties": False, + "properties": { + "destroy-storage": {"type": "boolean"}, + "force": {"type": "boolean"}, + "max-wait": {"type": "integer"}, + "model-tag": {"type": "string"}, + "timeout": {"type": "integer"}, + }, + "required": ["model-tag"], + "type": "object", + }, + "DestroyModelsParams": { + "additionalProperties": False, + "properties": { + "models": { + "items": {"$ref": "#/definitions/DestroyModelParams"}, + "type": "array", + } + }, + "required": ["models"], + "type": "object", + }, + "DumpModelRequest": { + "additionalProperties": False, + "properties": { + "entities": { + "items": {"$ref": "#/definitions/Entity"}, + "type": "array", + }, + "simplified": {"type": "boolean"}, + }, + "required": ["entities", "simplified"], + "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", + }, + "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": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "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", + }, + "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"}, + "virt-type": {"type": "string"}, + }, + "type": "object", + }, + "MapResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + }, + "required": ["result"], + "type": "object", + }, + "MapResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/MapResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "Model": { + "additionalProperties": False, + "properties": { + "name": {"type": "string"}, + "owner-tag": {"type": "string"}, + "type": {"type": "string"}, + "uuid": {"type": "string"}, + }, + "required": ["name", "uuid", "type", "owner-tag"], + "type": "object", + }, + "ModelApplicationInfo": { + "additionalProperties": False, + "properties": {"name": {"type": "string"}}, + "required": ["name"], + "type": "object", + }, + "ModelCreateArgs": { + "additionalProperties": False, + "properties": { + "cloud-tag": {"type": "string"}, + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "credential": {"type": "string"}, + "name": {"type": "string"}, + "owner-tag": {"type": "string"}, + "region": {"type": "string"}, + }, + "required": ["name", "owner-tag"], + "type": "object", + }, + "ModelDefaultValues": { + "additionalProperties": False, + "properties": { + "cloud-region": {"type": "string"}, + "cloud-tag": {"type": "string"}, + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + }, + "required": ["config"], + "type": "object", + }, + "ModelDefaults": { + "additionalProperties": False, + "properties": { + "controller": {"additionalProperties": True, "type": "object"}, + "default": {"additionalProperties": True, "type": "object"}, + "regions": { + "items": {"$ref": "#/definitions/RegionDefaults"}, + "type": "array", + }, + }, + "type": "object", + }, + "ModelDefaultsResult": { + "additionalProperties": False, + "properties": { + "config": { + "patternProperties": { + ".*": {"$ref": "#/definitions/ModelDefaults"} + }, + "type": "object", + }, + "error": {"$ref": "#/definitions/Error"}, + }, + "required": ["config"], + "type": "object", + }, + "ModelDefaultsResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ModelDefaultsResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "ModelEntityCount": { + "additionalProperties": False, + "properties": { + "count": {"type": "integer"}, + "entity": {"type": "string"}, + }, + "required": ["entity", "count"], + "type": "object", + }, + "ModelFilesystemInfo": { + "additionalProperties": False, + "properties": { + "detachable": {"type": "boolean"}, + "id": {"type": "string"}, + "message": {"type": "string"}, + "provider-id": {"type": "string"}, + "status": {"type": "string"}, + }, + "required": ["id"], + "type": "object", + }, + "ModelInfo": { + "additionalProperties": False, + "properties": { + "agent-version": {"$ref": "#/definitions/Number"}, + "cloud-credential-tag": {"type": "string"}, + "cloud-credential-validity": {"type": "boolean"}, + "cloud-region": {"type": "string"}, + "cloud-tag": {"type": "string"}, + "controller-uuid": {"type": "string"}, + "default-base": {"type": "string"}, + "default-series": {"type": "string"}, + "is-controller": {"type": "boolean"}, + "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"}, + "secret-backends": { + "items": {"$ref": "#/definitions/SecretBackendResult"}, + "type": "array", + }, + "sla": {"$ref": "#/definitions/ModelSLAInfo"}, + "status": {"$ref": "#/definitions/EntityStatus"}, + "supported-features": { + "items": {"$ref": "#/definitions/SupportedFeature"}, + "type": "array", + }, + "type": {"type": "string"}, + "users": { + "items": {"$ref": "#/definitions/ModelUserInfo"}, + "type": "array", + }, + "uuid": {"type": "string"}, + }, + "required": [ + "name", + "type", + "uuid", + "controller-uuid", + "is-controller", + "cloud-tag", + "owner-tag", + "life", + "users", + "machines", + "secret-backends", + "sla", + "agent-version", + ], + "type": "object", + }, + "ModelInfoResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/ModelInfo"}, + }, + "type": "object", + }, + "ModelInfoResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ModelInfoResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "ModelMachineInfo": { + "additionalProperties": False, + "properties": { + "display-name": {"type": "string"}, + "ha-primary": {"type": "boolean"}, + "hardware": {"$ref": "#/definitions/MachineHardware"}, + "has-vote": {"type": "boolean"}, + "id": {"type": "string"}, + "instance-id": {"type": "string"}, + "message": {"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", + }, + "ModelSLAInfo": { + "additionalProperties": False, + "properties": { + "level": {"type": "string"}, + "owner": {"type": "string"}, + }, + "required": ["level", "owner"], + "type": "object", + }, + "ModelStatus": { + "additionalProperties": False, + "properties": { + "application-count": {"type": "integer"}, + "applications": { + "items": {"$ref": "#/definitions/ModelApplicationInfo"}, + "type": "array", + }, + "error": {"$ref": "#/definitions/Error"}, + "filesystems": { + "items": {"$ref": "#/definitions/ModelFilesystemInfo"}, + "type": "array", + }, + "hosted-machine-count": {"type": "integer"}, + "life": {"type": "string"}, + "machines": { + "items": {"$ref": "#/definitions/ModelMachineInfo"}, + "type": "array", + }, + "model-tag": {"type": "string"}, + "owner-tag": {"type": "string"}, + "type": {"type": "string"}, + "unit-count": {"type": "integer"}, + "volumes": { + "items": {"$ref": "#/definitions/ModelVolumeInfo"}, + "type": "array", + }, + }, + "required": [ + "model-tag", + "life", + "type", + "hosted-machine-count", + "application-count", + "unit-count", + "owner-tag", + ], + "type": "object", + }, + "ModelStatusResults": { + "additionalProperties": False, + "properties": { + "models": { + "items": {"$ref": "#/definitions/ModelStatus"}, + "type": "array", + } + }, + "required": ["models"], + "type": "object", + }, + "ModelSummariesRequest": { + "additionalProperties": False, + "properties": { + "all": {"type": "boolean"}, + "user-tag": {"type": "string"}, + }, + "required": ["user-tag"], + "type": "object", + }, + "ModelSummary": { + "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"}, + "counts": { + "items": {"$ref": "#/definitions/ModelEntityCount"}, + "type": "array", + }, + "default-series": {"type": "string"}, + "is-controller": {"type": "boolean"}, + "last-connection": {"format": "date-time", "type": "string"}, + "life": {"type": "string"}, + "migration": {"$ref": "#/definitions/ModelMigrationStatus"}, + "name": {"type": "string"}, + "owner-tag": {"type": "string"}, + "provider-type": {"type": "string"}, + "sla": {"$ref": "#/definitions/ModelSLAInfo"}, + "status": {"$ref": "#/definitions/EntityStatus"}, + "type": {"type": "string"}, + "user-access": {"type": "string"}, + "uuid": {"type": "string"}, + }, + "required": [ + "name", + "uuid", + "type", + "controller-uuid", + "is-controller", + "cloud-tag", + "owner-tag", + "life", + "user-access", + "last-connection", + "counts", + "sla", + "agent-version", + ], + "type": "object", + }, + "ModelSummaryResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/ModelSummary"}, + }, + "type": "object", + }, + "ModelSummaryResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ModelSummaryResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "ModelUnsetKeys": { + "additionalProperties": False, + "properties": { + "cloud-region": {"type": "string"}, + "cloud-tag": {"type": "string"}, + "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"}, + "model-tag": {"type": "string"}, + "user": {"type": "string"}, + }, + "required": [ + "model-tag", + "user", + "display-name", + "last-connection", + "access", + ], + "type": "object", + }, + "ModelVolumeInfo": { + "additionalProperties": False, + "properties": { + "detachable": {"type": "boolean"}, + "id": {"type": "string"}, + "message": {"type": "string"}, + "provider-id": {"type": "string"}, + "status": {"type": "string"}, + }, + "required": ["id"], + "type": "object", + }, + "ModifyModelAccess": { + "additionalProperties": False, + "properties": { + "access": {"type": "string"}, + "action": {"type": "string"}, + "model-tag": {"type": "string"}, + "user-tag": {"type": "string"}, + }, + "required": ["user-tag", "action", "access", "model-tag"], + "type": "object", + }, + "ModifyModelAccessRequest": { + "additionalProperties": False, + "properties": { + "changes": { + "items": {"$ref": "#/definitions/ModifyModelAccess"}, + "type": "array", + } + }, + "required": ["changes"], + "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", + }, + "RegionDefaults": { + "additionalProperties": False, + "properties": { + "region-name": {"type": "string"}, + "value": {"additionalProperties": True, "type": "object"}, + }, + "required": ["region-name", "value"], + "type": "object", + }, + "SecretBackend": { + "additionalProperties": False, + "properties": { + "backend-type": {"type": "string"}, + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "name": {"type": "string"}, + "token-rotate-interval": {"type": "integer"}, + }, + "required": ["name", "backend-type", "config"], + "type": "object", + }, + "SecretBackendResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "id": {"type": "string"}, + "message": {"type": "string"}, + "num-secrets": {"type": "integer"}, + "result": {"$ref": "#/definitions/SecretBackend"}, + "status": {"type": "string"}, + }, + "required": ["result", "id", "num-secrets", "status"], + "type": "object", + }, + "SetModelDefaults": { + "additionalProperties": False, + "properties": { + "config": { + "items": {"$ref": "#/definitions/ModelDefaultValues"}, + "type": "array", + } + }, + "required": ["config"], + "type": "object", + }, + "StringResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"type": "string"}, + }, + "required": ["result"], + "type": "object", + }, + "StringResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/StringResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "SupportedFeature": { + "additionalProperties": False, + "properties": { + "description": {"type": "string"}, + "name": {"type": "string"}, + "version": {"type": "string"}, + }, + "required": ["name", "description"], + "type": "object", + }, + "UnsetModelDefaults": { + "additionalProperties": False, + "properties": { + "keys": { + "items": {"$ref": "#/definitions/ModelUnsetKeys"}, + "type": "array", + } + }, + "required": ["keys"], + "type": "object", + }, + "UserModel": { + "additionalProperties": False, + "properties": { + "last-connection": {"format": "date-time", "type": "string"}, + "model": {"$ref": "#/definitions/Model"}, + }, + "required": ["model", "last-connection"], + "type": "object", + }, + "UserModelList": { + "additionalProperties": False, + "properties": { + "user-models": { + "items": {"$ref": "#/definitions/UserModel"}, + "type": "array", + } + }, + "required": ["user-models"], + "type": "object", + }, + }, + "properties": { + "ChangeModelCredential": { + "description": "ChangeModelCredential " + "changes cloud " + "credential reference " + "for models.\n" + "These new cloud " + "credentials must " + "already exist on the " + "controller.", + "properties": { + "Params": {"$ref": "#/definitions/ChangeModelCredentialsParams"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "CreateModel": { + "description": "CreateModel creates a new " + "model using the account and\n" + "model config specified in the " + "args.", + "properties": { + "Params": {"$ref": "#/definitions/ModelCreateArgs"}, + "Result": {"$ref": "#/definitions/ModelInfo"}, + }, + "type": "object", + }, + "DestroyModels": { + "description": "DestroyModels will try to " + "destroy the specified " + "models.\n" + "If there is a block on " + "destruction, this method " + "will return an error.\n" + "From ModelManager v7 " + "onwards, DestroyModels gains " + "'force' and 'max-wait' " + "parameters.", + "properties": { + "Params": {"$ref": "#/definitions/DestroyModelsParams"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "DumpModels": { + "description": "DumpModels will export the " + "models into the database " + "agnostic\n" + "representation. The user needs " + "to either be a controller " + "admin, or have\n" + "admin privileges on the model " + "itself.", + "properties": { + "Params": {"$ref": "#/definitions/DumpModelRequest"}, + "Result": {"$ref": "#/definitions/StringResults"}, + }, + "type": "object", + }, + "DumpModelsDB": { + "description": "DumpModelsDB will gather all " + "documents from all model " + "collections\n" + "for the specified model. The " + "map result contains a map of " + "collection\n" + "names to lists of documents " + "represented as maps.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/MapResults"}, + }, + "type": "object", + }, + "ListModelSummaries": { + "description": "ListModelSummaries " + "returns models that the " + "specified user\n" + "has access to in the " + "current server. " + "Controller admins " + "(superuser)\n" + "can list models for any " + "user. Other users\n" + "can only ask about " + "their own models.", + "properties": { + "Params": {"$ref": "#/definitions/ModelSummariesRequest"}, + "Result": {"$ref": "#/definitions/ModelSummaryResults"}, + }, + "type": "object", + }, + "ListModels": { + "description": "ListModels returns the models " + "that the specified user\n" + "has access to in the current " + "server. Controller admins " + "(superuser)\n" + "can list models for any user. " + "Other users\n" + "can only ask about their own " + "models.", + "properties": { + "Params": {"$ref": "#/definitions/Entity"}, + "Result": {"$ref": "#/definitions/UserModelList"}, + }, + "type": "object", + }, + "ModelDefaultsForClouds": { + "description": "ModelDefaultsForClouds " + "returns the default " + "config values for " + "the specified\n" + "clouds.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/ModelDefaultsResults"}, + }, + "type": "object", + }, + "ModelInfo": { + "description": "ModelInfo returns information " + "about the specified models.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/ModelInfoResults"}, + }, + "type": "object", + }, + "ModelStatus": { + "description": "ModelStatus returns a summary of the model.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/ModelStatusResults"}, + }, + "type": "object", + }, + "ModifyModelAccess": { + "description": "ModifyModelAccess " + "changes the model access " + "granted to users.", + "properties": { + "Params": {"$ref": "#/definitions/ModifyModelAccessRequest"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "SetModelDefaults": { + "description": "SetModelDefaults writes " + "new values for the " + "specified default model " + "settings.", + "properties": { + "Params": {"$ref": "#/definitions/SetModelDefaults"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "UnsetModelDefaults": { + "description": "UnsetModelDefaults " + "removes the specified " + "default model settings.", + "properties": { + "Params": {"$ref": "#/definitions/UnsetModelDefaults"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(ErrorResults) async def ChangeModelCredential(self, model_credentials=None): - ''' + """ ChangeModelCredential changes cloud credential reference for models. These new cloud credentials must already exist on the controller. model_credentials : typing.Sequence[~ChangeModelCredentialParams] Returns -> ErrorResults - ''' - if model_credentials is not None and not isinstance(model_credentials, (bytes, str, list)): - raise Exception("Expected model_credentials to be a Sequence, received: {}".format(type(model_credentials))) + """ + if model_credentials is not None and not isinstance( + model_credentials, (bytes, str, list) + ): + raise Exception( + "Expected model_credentials to be a Sequence, received: {}".format( + type(model_credentials) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='ChangeModelCredential', - version=10, - params=_params) - _params['model-credentials'] = model_credentials + msg = dict( + type="ModelManager", + request="ChangeModelCredential", + version=10, + params=_params, + ) + _params["model-credentials"] = model_credentials reply = await self.rpc(msg) return reply - - @ReturnMapping(ModelInfo) - async def CreateModel(self, cloud_tag=None, config=None, credential=None, name=None, owner_tag=None, region=None): - ''' + async def CreateModel( + self, + cloud_tag=None, + config=None, + credential=None, + name=None, + owner_tag=None, + region=None, + ): + """ CreateModel creates a new model using the account and model config specified in the args. @@ -1249,70 +1853,78 @@ async def CreateModel(self, cloud_tag=None, config=None, credential=None, name=N owner_tag : str region : str Returns -> ModelInfo - ''' + """ if cloud_tag is not None and not isinstance(cloud_tag, (bytes, str)): - raise Exception("Expected cloud_tag to be a str, received: {}".format(type(cloud_tag))) + raise Exception( + "Expected cloud_tag to be a str, received: {}".format(type(cloud_tag)) + ) if config is not None and not isinstance(config, dict): - raise Exception("Expected config to be a Mapping, received: {}".format(type(config))) + raise Exception( + "Expected config to be a Mapping, received: {}".format(type(config)) + ) if credential is not None and not isinstance(credential, (bytes, str)): - raise Exception("Expected credential to be a str, received: {}".format(type(credential))) + raise Exception( + "Expected credential to be a str, received: {}".format(type(credential)) + ) if name is not None and not isinstance(name, (bytes, str)): - raise Exception("Expected name to be a str, received: {}".format(type(name))) + raise Exception( + "Expected name to be a str, received: {}".format(type(name)) + ) if owner_tag is not None and not isinstance(owner_tag, (bytes, str)): - raise Exception("Expected owner_tag to be a str, received: {}".format(type(owner_tag))) + raise Exception( + "Expected owner_tag to be a str, received: {}".format(type(owner_tag)) + ) if region is not None and not isinstance(region, (bytes, str)): - raise Exception("Expected region to be a str, received: {}".format(type(region))) + raise Exception( + "Expected region to be a str, received: {}".format(type(region)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='CreateModel', - version=10, - params=_params) - _params['cloud-tag'] = cloud_tag - _params['config'] = config - _params['credential'] = credential - _params['name'] = name - _params['owner-tag'] = owner_tag - _params['region'] = region + msg = dict( + type="ModelManager", request="CreateModel", version=10, params=_params + ) + _params["cloud-tag"] = cloud_tag + _params["config"] = config + _params["credential"] = credential + _params["name"] = name + _params["owner-tag"] = owner_tag + _params["region"] = region reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def DestroyModels(self, models=None): - ''' + """ DestroyModels will try to destroy the specified models. If there is a block on destruction, this method will return an error. From ModelManager v7 onwards, DestroyModels gains 'force' and 'max-wait' parameters. models : typing.Sequence[~DestroyModelParams] Returns -> ErrorResults - ''' + """ if models is not None and not isinstance(models, (bytes, str, list)): - raise Exception("Expected models to be a Sequence, received: {}".format(type(models))) + raise Exception( + "Expected models to be a Sequence, received: {}".format(type(models)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='DestroyModels', - version=10, - params=_params) - _params['models'] = models + msg = dict( + type="ModelManager", request="DestroyModels", version=10, params=_params + ) + _params["models"] = models reply = await self.rpc(msg) return reply - - @ReturnMapping(StringResults) async def DumpModels(self, entities=None, simplified=None): - ''' + """ DumpModels will export the models into the database agnostic representation. The user needs to either be a controller admin, or have admin privileges on the model itself. @@ -1320,54 +1932,60 @@ async def DumpModels(self, entities=None, simplified=None): entities : typing.Sequence[~Entity] simplified : bool Returns -> StringResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) if simplified is not None and not isinstance(simplified, bool): - raise Exception("Expected simplified to be a bool, received: {}".format(type(simplified))) + raise Exception( + "Expected simplified to be a bool, received: {}".format( + type(simplified) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='DumpModels', - version=10, - params=_params) - _params['entities'] = entities - _params['simplified'] = simplified + msg = dict( + type="ModelManager", request="DumpModels", version=10, params=_params + ) + _params["entities"] = entities + _params["simplified"] = simplified reply = await self.rpc(msg) return reply - - @ReturnMapping(MapResults) async def DumpModelsDB(self, entities=None): - ''' + """ DumpModelsDB will gather all documents from all model collections for the specified model. The map result contains a map of collection names to lists of documents represented as maps. entities : typing.Sequence[~Entity] Returns -> MapResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='DumpModelsDB', - version=10, - params=_params) - _params['entities'] = entities + msg = dict( + type="ModelManager", request="DumpModelsDB", version=10, params=_params + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ModelSummaryResults) async def ListModelSummaries(self, all_=None, user_tag=None): - ''' + """ ListModelSummaries returns models that the specified user has access to in the current server. Controller admins (superuser) can list models for any user. Other users @@ -1376,29 +1994,33 @@ async def ListModelSummaries(self, all_=None, user_tag=None): all_ : bool user_tag : str Returns -> ModelSummaryResults - ''' + """ if all_ is not None and not isinstance(all_, bool): - raise Exception("Expected all_ to be a bool, received: {}".format(type(all_))) + raise Exception( + "Expected all_ to be a bool, received: {}".format(type(all_)) + ) if user_tag is not None and not isinstance(user_tag, (bytes, str)): - raise Exception("Expected user_tag to be a str, received: {}".format(type(user_tag))) + raise Exception( + "Expected user_tag to be a str, received: {}".format(type(user_tag)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='ListModelSummaries', - version=10, - params=_params) - _params['all'] = all_ - _params['user-tag'] = user_tag + msg = dict( + type="ModelManager", + request="ListModelSummaries", + version=10, + params=_params, + ) + _params["all"] = all_ + _params["user-tag"] = user_tag reply = await self.rpc(msg) return reply - - @ReturnMapping(UserModelList) async def ListModels(self, tag=None): - ''' + """ ListModels returns the models that the specified user has access to in the current server. Controller admins (superuser) can list models for any user. Other users @@ -1406,157 +2028,158 @@ async def ListModels(self, tag=None): tag : str Returns -> UserModelList - ''' + """ if tag is not None and not isinstance(tag, (bytes, str)): raise Exception("Expected tag to be a str, received: {}".format(type(tag))) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='ListModels', - version=10, - params=_params) - _params['tag'] = tag + msg = dict( + type="ModelManager", request="ListModels", version=10, params=_params + ) + _params["tag"] = tag reply = await self.rpc(msg) return reply - - @ReturnMapping(ModelDefaultsResults) async def ModelDefaultsForClouds(self, entities=None): - ''' + """ ModelDefaultsForClouds returns the default config values for the specified clouds. entities : typing.Sequence[~Entity] Returns -> ModelDefaultsResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='ModelDefaultsForClouds', - version=10, - params=_params) - _params['entities'] = entities + msg = dict( + type="ModelManager", + request="ModelDefaultsForClouds", + version=10, + params=_params, + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ModelInfoResults) async def ModelInfo(self, entities=None): - ''' + """ ModelInfo returns information about the specified models. entities : typing.Sequence[~Entity] Returns -> ModelInfoResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='ModelInfo', - version=10, - params=_params) - _params['entities'] = entities + msg = dict(type="ModelManager", request="ModelInfo", version=10, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ModelStatusResults) async def ModelStatus(self, entities=None): - ''' + """ ModelStatus returns a summary of the model. entities : typing.Sequence[~Entity] Returns -> ModelStatusResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='ModelStatus', - version=10, - params=_params) - _params['entities'] = entities + msg = dict( + type="ModelManager", request="ModelStatus", version=10, params=_params + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def ModifyModelAccess(self, changes=None): - ''' + """ ModifyModelAccess changes the model access granted to users. changes : typing.Sequence[~ModifyModelAccess] Returns -> ErrorResults - ''' + """ if changes is not None and not isinstance(changes, (bytes, str, list)): - raise Exception("Expected changes to be a Sequence, received: {}".format(type(changes))) + raise Exception( + "Expected changes to be a Sequence, received: {}".format(type(changes)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='ModifyModelAccess', - version=10, - params=_params) - _params['changes'] = changes + msg = dict( + type="ModelManager", request="ModifyModelAccess", version=10, params=_params + ) + _params["changes"] = changes reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def SetModelDefaults(self, config=None): - ''' + """ SetModelDefaults writes new values for the specified default model settings. config : typing.Sequence[~ModelDefaultValues] Returns -> ErrorResults - ''' + """ if config is not None and not isinstance(config, (bytes, str, list)): - raise Exception("Expected config to be a Sequence, received: {}".format(type(config))) + raise Exception( + "Expected config to be a Sequence, received: {}".format(type(config)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='SetModelDefaults', - version=10, - params=_params) - _params['config'] = config + msg = dict( + type="ModelManager", request="SetModelDefaults", version=10, params=_params + ) + _params["config"] = config reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def UnsetModelDefaults(self, keys=None): - ''' + """ UnsetModelDefaults removes the specified default model settings. keys : typing.Sequence[~ModelUnsetKeys] Returns -> ErrorResults - ''' + """ if keys is not None and not isinstance(keys, (bytes, str, list)): - raise Exception("Expected keys to be a Sequence, received: {}".format(type(keys))) + raise Exception( + "Expected keys to be a Sequence, received: {}".format(type(keys)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='UnsetModelDefaults', - version=10, - params=_params) - _params['keys'] = keys + msg = dict( + type="ModelManager", + request="UnsetModelDefaults", + version=10, + params=_params, + ) + _params["keys"] = keys reply = await self.rpc(msg) return reply - - diff --git a/juju/client/_client11.py b/juju/client/_client11.py index a3c7ea0e7..6c96e3b6c 100644 --- a/juju/client/_client11.py +++ b/juju/client/_client11.py @@ -6,685 +6,978 @@ class ControllerFacade(Type): - name = 'Controller' + name = "Controller" version = 11 - schema = {'definitions': {'AllWatcherId': {'additionalProperties': False, - 'properties': {'watcher-id': {'type': 'string'}}, - 'required': ['watcher-id'], - 'type': 'object'}, - 'CloudCredential': {'additionalProperties': False, - 'properties': {'attrs': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - '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'}, - 'is-controller-cloud': {'type': 'boolean'}, - 'name': {'type': 'string'}, - 'region': {'type': 'string'}, - 'skip-tls-verify': {'type': 'boolean'}, - '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'}, - 'ConfigValue': {'additionalProperties': False, - 'properties': {'source': {'type': 'string'}, - 'value': {'additionalProperties': True, - 'type': 'object'}}, - 'required': ['value', 'source'], - 'type': 'object'}, - 'ControllerAPIInfoResult': {'additionalProperties': False, - 'properties': {'addresses': {'items': {'type': 'string'}, - 'type': 'array'}, - 'cacert': {'type': 'string'}, - 'error': {'$ref': '#/definitions/Error'}}, - 'required': ['addresses', - 'cacert'], - 'type': 'object'}, - 'ControllerAPIInfoResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ControllerAPIInfoResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'ControllerConfigResult': {'additionalProperties': False, - 'properties': {'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}}, - 'required': ['config'], - 'type': 'object'}, - 'ControllerConfigSet': {'additionalProperties': False, - 'properties': {'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}}, - 'required': ['config'], - 'type': 'object'}, - 'ControllerVersionResults': {'additionalProperties': False, - 'properties': {'git-commit': {'type': 'string'}, - 'version': {'type': 'string'}}, - 'required': ['version', - 'git-commit'], - 'type': 'object'}, - 'DashboardConnectionInfo': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'proxy-connection': {'$ref': '#/definitions/Proxy'}, - 'ssh-connection': {'$ref': '#/definitions/DashboardConnectionSSHTunnel'}}, - 'required': ['proxy-connection', - 'ssh-connection'], - 'type': 'object'}, - 'DashboardConnectionSSHTunnel': {'additionalProperties': False, - 'properties': {'entity': {'type': 'string'}, - 'host': {'type': 'string'}, - 'model': {'type': 'string'}, - 'port': {'type': 'string'}}, - 'required': ['host', 'port'], - 'type': 'object'}, - 'DestroyControllerArgs': {'additionalProperties': False, - 'properties': {'destroy-models': {'type': 'boolean'}, - 'destroy-storage': {'type': 'boolean'}, - 'force': {'type': 'boolean'}, - 'max-wait': {'type': 'integer'}, - 'model-timeout': {'type': 'integer'}}, - 'required': ['destroy-models'], - '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'}, - 'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - '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'}, - 'HostedModelConfig': {'additionalProperties': False, - 'properties': {'cloud-spec': {'$ref': '#/definitions/CloudSpec'}, - 'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'error': {'$ref': '#/definitions/Error'}, - 'name': {'type': 'string'}, - 'owner': {'type': 'string'}}, - 'required': ['name', 'owner'], - 'type': 'object'}, - 'HostedModelConfigsResults': {'additionalProperties': False, - 'properties': {'models': {'items': {'$ref': '#/definitions/HostedModelConfig'}, - 'type': 'array'}}, - 'required': ['models'], - 'type': 'object'}, - 'InitiateMigrationArgs': {'additionalProperties': False, - 'properties': {'specs': {'items': {'$ref': '#/definitions/MigrationSpec'}, - 'type': 'array'}}, - 'required': ['specs'], - 'type': 'object'}, - 'InitiateMigrationResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'migration-id': {'type': 'string'}, - 'model-tag': {'type': 'string'}}, - 'required': ['model-tag', - 'migration-id'], - 'type': 'object'}, - 'InitiateMigrationResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/InitiateMigrationResult'}, - 'type': 'array'}}, - 'required': ['results'], - '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'}, - 'virt-type': {'type': 'string'}}, - 'type': 'object'}, - 'MigrationSpec': {'additionalProperties': False, - 'properties': {'model-tag': {'type': 'string'}, - 'target-info': {'$ref': '#/definitions/MigrationTargetInfo'}}, - 'required': ['model-tag', 'target-info'], - 'type': 'object'}, - 'MigrationTargetInfo': {'additionalProperties': False, - 'properties': {'addrs': {'items': {'type': 'string'}, - 'type': 'array'}, - 'auth-tag': {'type': 'string'}, - 'ca-cert': {'type': 'string'}, - 'controller-alias': {'type': 'string'}, - 'controller-tag': {'type': 'string'}, - 'macaroons': {'type': 'string'}, - 'password': {'type': 'string'}}, - 'required': ['controller-tag', - 'addrs', - 'ca-cert', - 'auth-tag'], - 'type': 'object'}, - 'Model': {'additionalProperties': False, - 'properties': {'name': {'type': 'string'}, - 'owner-tag': {'type': 'string'}, - 'type': {'type': 'string'}, - 'uuid': {'type': 'string'}}, - 'required': ['name', 'uuid', 'type', 'owner-tag'], - 'type': 'object'}, - 'ModelApplicationInfo': {'additionalProperties': False, - 'properties': {'name': {'type': 'string'}}, - 'required': ['name'], - 'type': 'object'}, - 'ModelBlockInfo': {'additionalProperties': False, - 'properties': {'blocks': {'items': {'type': 'string'}, - 'type': 'array'}, - 'model-uuid': {'type': 'string'}, - 'name': {'type': 'string'}, - 'owner-tag': {'type': 'string'}}, - 'required': ['name', - 'model-uuid', - 'owner-tag', - 'blocks'], - 'type': 'object'}, - 'ModelBlockInfoList': {'additionalProperties': False, - 'properties': {'models': {'items': {'$ref': '#/definitions/ModelBlockInfo'}, - 'type': 'array'}}, - 'type': 'object'}, - 'ModelConfigResults': {'additionalProperties': False, - 'properties': {'config': {'patternProperties': {'.*': {'$ref': '#/definitions/ConfigValue'}}, - 'type': 'object'}}, - 'required': ['config'], - 'type': 'object'}, - 'ModelFilesystemInfo': {'additionalProperties': False, - 'properties': {'detachable': {'type': 'boolean'}, - 'id': {'type': 'string'}, - 'message': {'type': 'string'}, - 'provider-id': {'type': 'string'}, - 'status': {'type': 'string'}}, - 'required': ['id'], - 'type': 'object'}, - 'ModelMachineInfo': {'additionalProperties': False, - 'properties': {'display-name': {'type': 'string'}, - 'ha-primary': {'type': 'boolean'}, - 'hardware': {'$ref': '#/definitions/MachineHardware'}, - 'has-vote': {'type': 'boolean'}, - 'id': {'type': 'string'}, - 'instance-id': {'type': 'string'}, - 'message': {'type': 'string'}, - 'status': {'type': 'string'}, - 'wants-vote': {'type': 'boolean'}}, - 'required': ['id'], - 'type': 'object'}, - 'ModelStatus': {'additionalProperties': False, - 'properties': {'application-count': {'type': 'integer'}, - 'applications': {'items': {'$ref': '#/definitions/ModelApplicationInfo'}, - 'type': 'array'}, - 'error': {'$ref': '#/definitions/Error'}, - 'filesystems': {'items': {'$ref': '#/definitions/ModelFilesystemInfo'}, - 'type': 'array'}, - 'hosted-machine-count': {'type': 'integer'}, - 'life': {'type': 'string'}, - 'machines': {'items': {'$ref': '#/definitions/ModelMachineInfo'}, - 'type': 'array'}, - 'model-tag': {'type': 'string'}, - 'owner-tag': {'type': 'string'}, - 'type': {'type': 'string'}, - 'unit-count': {'type': 'integer'}, - 'volumes': {'items': {'$ref': '#/definitions/ModelVolumeInfo'}, - 'type': 'array'}}, - 'required': ['model-tag', - 'life', - 'type', - 'hosted-machine-count', - 'application-count', - 'unit-count', - 'owner-tag'], - 'type': 'object'}, - 'ModelStatusResults': {'additionalProperties': False, - 'properties': {'models': {'items': {'$ref': '#/definitions/ModelStatus'}, - 'type': 'array'}}, - 'required': ['models'], - 'type': 'object'}, - 'ModelTag': {'additionalProperties': False, 'type': 'object'}, - 'ModelVolumeInfo': {'additionalProperties': False, - 'properties': {'detachable': {'type': 'boolean'}, - 'id': {'type': 'string'}, - 'message': {'type': 'string'}, - 'provider-id': {'type': 'string'}, - 'status': {'type': 'string'}}, - 'required': ['id'], - 'type': 'object'}, - 'ModifyControllerAccess': {'additionalProperties': False, - 'properties': {'access': {'type': 'string'}, - 'action': {'type': 'string'}, - 'user-tag': {'type': 'string'}}, - 'required': ['user-tag', - 'action', - 'access'], - 'type': 'object'}, - 'ModifyControllerAccessRequest': {'additionalProperties': False, - 'properties': {'changes': {'items': {'$ref': '#/definitions/ModifyControllerAccess'}, - 'type': 'array'}}, - 'required': ['changes'], - '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'}, - 'Proxy': {'additionalProperties': False, - 'properties': {'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'type': {'type': 'string'}}, - 'required': ['config', 'type'], - 'type': 'object'}, - 'RemoveBlocksArgs': {'additionalProperties': False, - 'properties': {'all': {'type': 'boolean'}}, - 'required': ['all'], - 'type': 'object'}, - 'StringResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'type': 'string'}}, - 'required': ['result'], - 'type': 'object'}, - 'SummaryWatcherID': {'additionalProperties': False, - 'properties': {'watcher-id': {'type': 'string'}}, - 'required': ['watcher-id'], - 'type': 'object'}, - 'UserAccess': {'additionalProperties': False, - 'properties': {'access': {'type': 'string'}, - 'user-tag': {'type': 'string'}}, - 'required': ['user-tag', 'access'], - 'type': 'object'}, - 'UserAccessResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/UserAccess'}}, - 'type': 'object'}, - 'UserAccessResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/UserAccessResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'UserModel': {'additionalProperties': False, - 'properties': {'last-connection': {'format': 'date-time', - 'type': 'string'}, - 'model': {'$ref': '#/definitions/Model'}}, - 'required': ['model', 'last-connection'], - 'type': 'object'}, - 'UserModelList': {'additionalProperties': False, - 'properties': {'user-models': {'items': {'$ref': '#/definitions/UserModel'}, - 'type': 'array'}}, - 'required': ['user-models'], - 'type': 'object'}}, - 'properties': {'AllModels': {'description': 'AllModels allows controller ' - 'administrators to get the list ' - 'of all the\n' - 'models in the controller.', - 'properties': {'Result': {'$ref': '#/definitions/UserModelList'}}, - 'type': 'object'}, - 'CloudSpec': {'description': "CloudSpec returns the model's " - 'cloud spec.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/CloudSpecResults'}}, - 'type': 'object'}, - 'ConfigSet': {'description': 'ConfigSet changes the value of ' - 'specified controller ' - 'configuration\n' - 'settings. Only some settings can ' - 'be changed after bootstrap.\n' - "Settings that aren't specified " - 'in the params are left ' - 'unchanged.', - 'properties': {'Params': {'$ref': '#/definitions/ControllerConfigSet'}}, - 'type': 'object'}, - 'ControllerAPIInfoForModels': {'description': 'ControllerAPIInfoForModels ' - 'returns the ' - 'controller api ' - 'connection ' - 'details for the ' - 'specified ' - 'models.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ControllerAPIInfoResults'}}, - 'type': 'object'}, - 'ControllerConfig': {'description': 'ControllerConfig returns ' - "the controller's " - 'configuration.', - 'properties': {'Result': {'$ref': '#/definitions/ControllerConfigResult'}}, - 'type': 'object'}, - 'ControllerVersion': {'description': 'ControllerVersion ' - 'returns the version ' - 'information associated ' - 'with this\n' - 'controller binary.\n' - '\n' - 'NOTE: the implementation ' - 'intentionally does not ' - 'check for ' - 'SuperuserAccess\n' - 'as the Version is known ' - 'even to users with login ' - 'access.', - 'properties': {'Result': {'$ref': '#/definitions/ControllerVersionResults'}}, - 'type': 'object'}, - 'DashboardConnectionInfo': {'description': 'DashboardConnectionInfo ' - 'returns the ' - 'connection ' - 'information for a ' - 'client to\n' - 'connect to the ' - 'Juju Dashboard ' - 'including any ' - 'proxying ' - 'information.', - 'properties': {'Result': {'$ref': '#/definitions/DashboardConnectionInfo'}}, - 'type': 'object'}, - 'DestroyController': {'description': 'DestroyController ' - 'destroys the ' - 'controller.\n' - '\n' - 'If the args specify the ' - 'destruction of the ' - 'models, this method ' - 'will\n' - 'attempt to do so. ' - 'Otherwise, if the ' - 'controller has any ' - 'non-empty,\n' - 'non-Dead hosted models, ' - 'then an error with the ' - 'code\n' - 'params.CodeHasHostedModels ' - 'will be transmitted.', - 'properties': {'Params': {'$ref': '#/definitions/DestroyControllerArgs'}}, - 'type': 'object'}, - 'GetCloudSpec': {'description': 'GetCloudSpec constructs the ' - 'CloudSpec for a validated and ' - 'authorized model.', - 'properties': {'Params': {'$ref': '#/definitions/ModelTag'}, - 'Result': {'$ref': '#/definitions/CloudSpecResult'}}, - 'type': 'object'}, - 'GetControllerAccess': {'description': 'GetControllerAccess ' - 'returns the level of ' - 'access the specified ' - 'users\n' - 'have on the ' - 'controller.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/UserAccessResults'}}, - 'type': 'object'}, - 'HostedModelConfigs': {'description': 'HostedModelConfigs ' - 'returns all the ' - 'information that the ' - 'client needs in\n' - 'order to connect ' - 'directly with the host ' - "model's provider and " - 'destroy it\n' - 'directly.', - 'properties': {'Result': {'$ref': '#/definitions/HostedModelConfigsResults'}}, - 'type': 'object'}, - 'IdentityProviderURL': {'description': 'IdentityProviderURL ' - 'returns the URL of the ' - 'configured external ' - 'identity\n' - 'provider for this ' - 'controller or an empty ' - 'string if no external ' - 'identity\n' - 'provider has been ' - 'configured when the ' - 'controller was ' - 'bootstrapped.\n' - '\n' - 'NOTE: the ' - 'implementation ' - 'intentionally does not ' - 'check for ' - 'SuperuserAccess\n' - 'as the URL is known ' - 'even to users with ' - 'login access.', - 'properties': {'Result': {'$ref': '#/definitions/StringResult'}}, - 'type': 'object'}, - 'InitiateMigration': {'description': 'InitiateMigration ' - 'attempts to begin the ' - 'migration of one or\n' - 'more models to other ' - 'controllers.', - 'properties': {'Params': {'$ref': '#/definitions/InitiateMigrationArgs'}, - 'Result': {'$ref': '#/definitions/InitiateMigrationResults'}}, - 'type': 'object'}, - 'ListBlockedModels': {'description': 'ListBlockedModels ' - 'returns a list of all ' - 'models on the ' - 'controller\n' - 'which have a block in ' - 'place. The resulting ' - 'slice is sorted by ' - 'model\n' - 'name, then owner. ' - 'Callers must be ' - 'controller ' - 'administrators to ' - 'retrieve the\n' - 'list.', - 'properties': {'Result': {'$ref': '#/definitions/ModelBlockInfoList'}}, - 'type': 'object'}, - 'ModelConfig': {'description': 'ModelConfig returns the model ' - 'config for the controller\n' - 'model. For information on the ' - 'current model, use\n' - 'client.ModelGet', - 'properties': {'Result': {'$ref': '#/definitions/ModelConfigResults'}}, - 'type': 'object'}, - 'ModelStatus': {'description': 'ModelStatus returns a summary ' - 'of the model.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ModelStatusResults'}}, - 'type': 'object'}, - 'ModifyControllerAccess': {'description': 'ModifyControllerAccess ' - 'changes the model ' - 'access granted to ' - 'users.', - 'properties': {'Params': {'$ref': '#/definitions/ModifyControllerAccessRequest'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'MongoVersion': {'description': 'MongoVersion allows the ' - 'introspection of the mongo ' - 'version per controller', - 'properties': {'Result': {'$ref': '#/definitions/StringResult'}}, - 'type': 'object'}, - 'RemoveBlocks': {'description': 'RemoveBlocks removes all the ' - 'blocks in the controller.', - 'properties': {'Params': {'$ref': '#/definitions/RemoveBlocksArgs'}}, - 'type': 'object'}, - 'WatchAllModelSummaries': {'description': 'WatchAllModelSummaries ' - 'starts watching the ' - 'summary updates ' - 'from the cache.\n' - 'This method is ' - 'superuser access ' - 'only, and watches ' - 'all models in the\n' - 'controller.', - 'properties': {'Result': {'$ref': '#/definitions/SummaryWatcherID'}}, - 'type': 'object'}, - 'WatchAllModels': {'description': 'WatchAllModels starts ' - 'watching events for all ' - 'models in the\n' - 'controller. The returned ' - 'AllWatcherId should be used ' - 'with Next on the\n' - 'AllModelWatcher endpoint to ' - 'receive deltas.', - 'properties': {'Result': {'$ref': '#/definitions/AllWatcherId'}}, - 'type': 'object'}, - 'WatchCloudSpecsChanges': {'description': 'WatchCloudSpecsChanges ' - 'returns a watcher ' - 'for cloud spec ' - 'changes.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/NotifyWatchResults'}}, - 'type': 'object'}, - 'WatchModelSummaries': {'description': 'WatchModelSummaries ' - 'starts watching the ' - 'summary updates from ' - 'the cache.\n' - 'Only models that the ' - 'user has access to are ' - 'returned.', - 'properties': {'Result': {'$ref': '#/definitions/SummaryWatcherID'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "AllWatcherId": { + "additionalProperties": False, + "properties": {"watcher-id": {"type": "string"}}, + "required": ["watcher-id"], + "type": "object", + }, + "CloudCredential": { + "additionalProperties": False, + "properties": { + "attrs": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "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"}, + "is-controller-cloud": {"type": "boolean"}, + "name": {"type": "string"}, + "region": {"type": "string"}, + "skip-tls-verify": {"type": "boolean"}, + "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", + }, + "ConfigValue": { + "additionalProperties": False, + "properties": { + "source": {"type": "string"}, + "value": {"additionalProperties": True, "type": "object"}, + }, + "required": ["value", "source"], + "type": "object", + }, + "ControllerAPIInfoResult": { + "additionalProperties": False, + "properties": { + "addresses": {"items": {"type": "string"}, "type": "array"}, + "cacert": {"type": "string"}, + "error": {"$ref": "#/definitions/Error"}, + }, + "required": ["addresses", "cacert"], + "type": "object", + }, + "ControllerAPIInfoResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ControllerAPIInfoResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "ControllerConfigResult": { + "additionalProperties": False, + "properties": { + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + } + }, + "required": ["config"], + "type": "object", + }, + "ControllerConfigSet": { + "additionalProperties": False, + "properties": { + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + } + }, + "required": ["config"], + "type": "object", + }, + "ControllerVersionResults": { + "additionalProperties": False, + "properties": { + "git-commit": {"type": "string"}, + "version": {"type": "string"}, + }, + "required": ["version", "git-commit"], + "type": "object", + }, + "DashboardConnectionInfo": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "proxy-connection": {"$ref": "#/definitions/Proxy"}, + "ssh-connection": { + "$ref": "#/definitions/DashboardConnectionSSHTunnel" + }, + }, + "required": ["proxy-connection", "ssh-connection"], + "type": "object", + }, + "DashboardConnectionSSHTunnel": { + "additionalProperties": False, + "properties": { + "entity": {"type": "string"}, + "host": {"type": "string"}, + "model": {"type": "string"}, + "port": {"type": "string"}, + }, + "required": ["host", "port"], + "type": "object", + }, + "DestroyControllerArgs": { + "additionalProperties": False, + "properties": { + "destroy-models": {"type": "boolean"}, + "destroy-storage": {"type": "boolean"}, + "force": {"type": "boolean"}, + "max-wait": {"type": "integer"}, + "model-timeout": {"type": "integer"}, + }, + "required": ["destroy-models"], + "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", + }, + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "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", + }, + "HostedModelConfig": { + "additionalProperties": False, + "properties": { + "cloud-spec": {"$ref": "#/definitions/CloudSpec"}, + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "error": {"$ref": "#/definitions/Error"}, + "name": {"type": "string"}, + "owner": {"type": "string"}, + }, + "required": ["name", "owner"], + "type": "object", + }, + "HostedModelConfigsResults": { + "additionalProperties": False, + "properties": { + "models": { + "items": {"$ref": "#/definitions/HostedModelConfig"}, + "type": "array", + } + }, + "required": ["models"], + "type": "object", + }, + "InitiateMigrationArgs": { + "additionalProperties": False, + "properties": { + "specs": { + "items": {"$ref": "#/definitions/MigrationSpec"}, + "type": "array", + } + }, + "required": ["specs"], + "type": "object", + }, + "InitiateMigrationResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "migration-id": {"type": "string"}, + "model-tag": {"type": "string"}, + }, + "required": ["model-tag", "migration-id"], + "type": "object", + }, + "InitiateMigrationResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/InitiateMigrationResult"}, + "type": "array", + } + }, + "required": ["results"], + "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"}, + "virt-type": {"type": "string"}, + }, + "type": "object", + }, + "MigrationSpec": { + "additionalProperties": False, + "properties": { + "model-tag": {"type": "string"}, + "target-info": {"$ref": "#/definitions/MigrationTargetInfo"}, + }, + "required": ["model-tag", "target-info"], + "type": "object", + }, + "MigrationTargetInfo": { + "additionalProperties": False, + "properties": { + "addrs": {"items": {"type": "string"}, "type": "array"}, + "auth-tag": {"type": "string"}, + "ca-cert": {"type": "string"}, + "controller-alias": {"type": "string"}, + "controller-tag": {"type": "string"}, + "macaroons": {"type": "string"}, + "password": {"type": "string"}, + }, + "required": ["controller-tag", "addrs", "ca-cert", "auth-tag"], + "type": "object", + }, + "Model": { + "additionalProperties": False, + "properties": { + "name": {"type": "string"}, + "owner-tag": {"type": "string"}, + "type": {"type": "string"}, + "uuid": {"type": "string"}, + }, + "required": ["name", "uuid", "type", "owner-tag"], + "type": "object", + }, + "ModelApplicationInfo": { + "additionalProperties": False, + "properties": {"name": {"type": "string"}}, + "required": ["name"], + "type": "object", + }, + "ModelBlockInfo": { + "additionalProperties": False, + "properties": { + "blocks": {"items": {"type": "string"}, "type": "array"}, + "model-uuid": {"type": "string"}, + "name": {"type": "string"}, + "owner-tag": {"type": "string"}, + }, + "required": ["name", "model-uuid", "owner-tag", "blocks"], + "type": "object", + }, + "ModelBlockInfoList": { + "additionalProperties": False, + "properties": { + "models": { + "items": {"$ref": "#/definitions/ModelBlockInfo"}, + "type": "array", + } + }, + "type": "object", + }, + "ModelConfigResults": { + "additionalProperties": False, + "properties": { + "config": { + "patternProperties": { + ".*": {"$ref": "#/definitions/ConfigValue"} + }, + "type": "object", + } + }, + "required": ["config"], + "type": "object", + }, + "ModelFilesystemInfo": { + "additionalProperties": False, + "properties": { + "detachable": {"type": "boolean"}, + "id": {"type": "string"}, + "message": {"type": "string"}, + "provider-id": {"type": "string"}, + "status": {"type": "string"}, + }, + "required": ["id"], + "type": "object", + }, + "ModelMachineInfo": { + "additionalProperties": False, + "properties": { + "display-name": {"type": "string"}, + "ha-primary": {"type": "boolean"}, + "hardware": {"$ref": "#/definitions/MachineHardware"}, + "has-vote": {"type": "boolean"}, + "id": {"type": "string"}, + "instance-id": {"type": "string"}, + "message": {"type": "string"}, + "status": {"type": "string"}, + "wants-vote": {"type": "boolean"}, + }, + "required": ["id"], + "type": "object", + }, + "ModelStatus": { + "additionalProperties": False, + "properties": { + "application-count": {"type": "integer"}, + "applications": { + "items": {"$ref": "#/definitions/ModelApplicationInfo"}, + "type": "array", + }, + "error": {"$ref": "#/definitions/Error"}, + "filesystems": { + "items": {"$ref": "#/definitions/ModelFilesystemInfo"}, + "type": "array", + }, + "hosted-machine-count": {"type": "integer"}, + "life": {"type": "string"}, + "machines": { + "items": {"$ref": "#/definitions/ModelMachineInfo"}, + "type": "array", + }, + "model-tag": {"type": "string"}, + "owner-tag": {"type": "string"}, + "type": {"type": "string"}, + "unit-count": {"type": "integer"}, + "volumes": { + "items": {"$ref": "#/definitions/ModelVolumeInfo"}, + "type": "array", + }, + }, + "required": [ + "model-tag", + "life", + "type", + "hosted-machine-count", + "application-count", + "unit-count", + "owner-tag", + ], + "type": "object", + }, + "ModelStatusResults": { + "additionalProperties": False, + "properties": { + "models": { + "items": {"$ref": "#/definitions/ModelStatus"}, + "type": "array", + } + }, + "required": ["models"], + "type": "object", + }, + "ModelTag": {"additionalProperties": False, "type": "object"}, + "ModelVolumeInfo": { + "additionalProperties": False, + "properties": { + "detachable": {"type": "boolean"}, + "id": {"type": "string"}, + "message": {"type": "string"}, + "provider-id": {"type": "string"}, + "status": {"type": "string"}, + }, + "required": ["id"], + "type": "object", + }, + "ModifyControllerAccess": { + "additionalProperties": False, + "properties": { + "access": {"type": "string"}, + "action": {"type": "string"}, + "user-tag": {"type": "string"}, + }, + "required": ["user-tag", "action", "access"], + "type": "object", + }, + "ModifyControllerAccessRequest": { + "additionalProperties": False, + "properties": { + "changes": { + "items": {"$ref": "#/definitions/ModifyControllerAccess"}, + "type": "array", + } + }, + "required": ["changes"], + "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", + }, + "Proxy": { + "additionalProperties": False, + "properties": { + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "type": {"type": "string"}, + }, + "required": ["config", "type"], + "type": "object", + }, + "RemoveBlocksArgs": { + "additionalProperties": False, + "properties": {"all": {"type": "boolean"}}, + "required": ["all"], + "type": "object", + }, + "StringResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"type": "string"}, + }, + "required": ["result"], + "type": "object", + }, + "SummaryWatcherID": { + "additionalProperties": False, + "properties": {"watcher-id": {"type": "string"}}, + "required": ["watcher-id"], + "type": "object", + }, + "UserAccess": { + "additionalProperties": False, + "properties": { + "access": {"type": "string"}, + "user-tag": {"type": "string"}, + }, + "required": ["user-tag", "access"], + "type": "object", + }, + "UserAccessResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/UserAccess"}, + }, + "type": "object", + }, + "UserAccessResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/UserAccessResult"}, + "type": "array", + } + }, + "type": "object", + }, + "UserModel": { + "additionalProperties": False, + "properties": { + "last-connection": {"format": "date-time", "type": "string"}, + "model": {"$ref": "#/definitions/Model"}, + }, + "required": ["model", "last-connection"], + "type": "object", + }, + "UserModelList": { + "additionalProperties": False, + "properties": { + "user-models": { + "items": {"$ref": "#/definitions/UserModel"}, + "type": "array", + } + }, + "required": ["user-models"], + "type": "object", + }, + }, + "properties": { + "AllModels": { + "description": "AllModels allows controller " + "administrators to get the list " + "of all the\n" + "models in the controller.", + "properties": {"Result": {"$ref": "#/definitions/UserModelList"}}, + "type": "object", + }, + "CloudSpec": { + "description": "CloudSpec returns the model's cloud spec.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/CloudSpecResults"}, + }, + "type": "object", + }, + "ConfigSet": { + "description": "ConfigSet changes the value of " + "specified controller " + "configuration\n" + "settings. Only some settings can " + "be changed after bootstrap.\n" + "Settings that aren't specified " + "in the params are left " + "unchanged.", + "properties": {"Params": {"$ref": "#/definitions/ControllerConfigSet"}}, + "type": "object", + }, + "ControllerAPIInfoForModels": { + "description": "ControllerAPIInfoForModels " + "returns the " + "controller api " + "connection " + "details for the " + "specified " + "models.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/ControllerAPIInfoResults"}, + }, + "type": "object", + }, + "ControllerConfig": { + "description": "ControllerConfig returns " + "the controller's " + "configuration.", + "properties": { + "Result": {"$ref": "#/definitions/ControllerConfigResult"} + }, + "type": "object", + }, + "ControllerVersion": { + "description": "ControllerVersion " + "returns the version " + "information associated " + "with this\n" + "controller binary.\n" + "\n" + "NOTE: the implementation " + "intentionally does not " + "check for " + "SuperuserAccess\n" + "as the Version is known " + "even to users with login " + "access.", + "properties": { + "Result": {"$ref": "#/definitions/ControllerVersionResults"} + }, + "type": "object", + }, + "DashboardConnectionInfo": { + "description": "DashboardConnectionInfo " + "returns the " + "connection " + "information for a " + "client to\n" + "connect to the " + "Juju Dashboard " + "including any " + "proxying " + "information.", + "properties": { + "Result": {"$ref": "#/definitions/DashboardConnectionInfo"} + }, + "type": "object", + }, + "DestroyController": { + "description": "DestroyController " + "destroys the " + "controller.\n" + "\n" + "If the args specify the " + "destruction of the " + "models, this method " + "will\n" + "attempt to do so. " + "Otherwise, if the " + "controller has any " + "non-empty,\n" + "non-Dead hosted models, " + "then an error with the " + "code\n" + "params.CodeHasHostedModels " + "will be transmitted.", + "properties": { + "Params": {"$ref": "#/definitions/DestroyControllerArgs"} + }, + "type": "object", + }, + "GetCloudSpec": { + "description": "GetCloudSpec constructs the " + "CloudSpec for a validated and " + "authorized model.", + "properties": { + "Params": {"$ref": "#/definitions/ModelTag"}, + "Result": {"$ref": "#/definitions/CloudSpecResult"}, + }, + "type": "object", + }, + "GetControllerAccess": { + "description": "GetControllerAccess " + "returns the level of " + "access the specified " + "users\n" + "have on the " + "controller.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/UserAccessResults"}, + }, + "type": "object", + }, + "HostedModelConfigs": { + "description": "HostedModelConfigs " + "returns all the " + "information that the " + "client needs in\n" + "order to connect " + "directly with the host " + "model's provider and " + "destroy it\n" + "directly.", + "properties": { + "Result": {"$ref": "#/definitions/HostedModelConfigsResults"} + }, + "type": "object", + }, + "IdentityProviderURL": { + "description": "IdentityProviderURL " + "returns the URL of the " + "configured external " + "identity\n" + "provider for this " + "controller or an empty " + "string if no external " + "identity\n" + "provider has been " + "configured when the " + "controller was " + "bootstrapped.\n" + "\n" + "NOTE: the " + "implementation " + "intentionally does not " + "check for " + "SuperuserAccess\n" + "as the URL is known " + "even to users with " + "login access.", + "properties": {"Result": {"$ref": "#/definitions/StringResult"}}, + "type": "object", + }, + "InitiateMigration": { + "description": "InitiateMigration " + "attempts to begin the " + "migration of one or\n" + "more models to other " + "controllers.", + "properties": { + "Params": {"$ref": "#/definitions/InitiateMigrationArgs"}, + "Result": {"$ref": "#/definitions/InitiateMigrationResults"}, + }, + "type": "object", + }, + "ListBlockedModels": { + "description": "ListBlockedModels " + "returns a list of all " + "models on the " + "controller\n" + "which have a block in " + "place. The resulting " + "slice is sorted by " + "model\n" + "name, then owner. " + "Callers must be " + "controller " + "administrators to " + "retrieve the\n" + "list.", + "properties": {"Result": {"$ref": "#/definitions/ModelBlockInfoList"}}, + "type": "object", + }, + "ModelConfig": { + "description": "ModelConfig returns the model " + "config for the controller\n" + "model. For information on the " + "current model, use\n" + "client.ModelGet", + "properties": {"Result": {"$ref": "#/definitions/ModelConfigResults"}}, + "type": "object", + }, + "ModelStatus": { + "description": "ModelStatus returns a summary of the model.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/ModelStatusResults"}, + }, + "type": "object", + }, + "ModifyControllerAccess": { + "description": "ModifyControllerAccess " + "changes the model " + "access granted to " + "users.", + "properties": { + "Params": {"$ref": "#/definitions/ModifyControllerAccessRequest"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "MongoVersion": { + "description": "MongoVersion allows the " + "introspection of the mongo " + "version per controller", + "properties": {"Result": {"$ref": "#/definitions/StringResult"}}, + "type": "object", + }, + "RemoveBlocks": { + "description": "RemoveBlocks removes all the blocks in the controller.", + "properties": {"Params": {"$ref": "#/definitions/RemoveBlocksArgs"}}, + "type": "object", + }, + "WatchAllModelSummaries": { + "description": "WatchAllModelSummaries " + "starts watching the " + "summary updates " + "from the cache.\n" + "This method is " + "superuser access " + "only, and watches " + "all models in the\n" + "controller.", + "properties": {"Result": {"$ref": "#/definitions/SummaryWatcherID"}}, + "type": "object", + }, + "WatchAllModels": { + "description": "WatchAllModels starts " + "watching events for all " + "models in the\n" + "controller. The returned " + "AllWatcherId should be used " + "with Next on the\n" + "AllModelWatcher endpoint to " + "receive deltas.", + "properties": {"Result": {"$ref": "#/definitions/AllWatcherId"}}, + "type": "object", + }, + "WatchCloudSpecsChanges": { + "description": "WatchCloudSpecsChanges " + "returns a watcher " + "for cloud spec " + "changes.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/NotifyWatchResults"}, + }, + "type": "object", + }, + "WatchModelSummaries": { + "description": "WatchModelSummaries " + "starts watching the " + "summary updates from " + "the cache.\n" + "Only models that the " + "user has access to are " + "returned.", + "properties": {"Result": {"$ref": "#/definitions/SummaryWatcherID"}}, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(UserModelList) async def AllModels(self): - ''' + """ AllModels allows controller administrators to get the list of all the models in the controller. Returns -> UserModelList - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='AllModels', - version=11, - params=_params) + msg = dict(type="Controller", request="AllModels", version=11, params=_params) reply = await self.rpc(msg) return reply - - @ReturnMapping(CloudSpecResults) async def CloudSpec(self, entities=None): - ''' + """ CloudSpec returns the model's cloud spec. entities : typing.Sequence[~Entity] Returns -> CloudSpecResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='CloudSpec', - version=11, - params=_params) - _params['entities'] = entities + msg = dict(type="Controller", request="CloudSpec", version=11, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(None) async def ConfigSet(self, config=None): - ''' + """ ConfigSet changes the value of specified controller configuration settings. Only some settings can be changed after bootstrap. Settings that aren't specified in the params are left unchanged. config : typing.Mapping[str, typing.Any] Returns -> None - ''' + """ if config is not None and not isinstance(config, dict): - raise Exception("Expected config to be a Mapping, received: {}".format(type(config))) + raise Exception( + "Expected config to be a Mapping, received: {}".format(type(config)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='ConfigSet', - version=11, - params=_params) - _params['config'] = config + msg = dict(type="Controller", request="ConfigSet", version=11, params=_params) + _params["config"] = config reply = await self.rpc(msg) return reply - - @ReturnMapping(ControllerAPIInfoResults) async def ControllerAPIInfoForModels(self, entities=None): - ''' + """ ControllerAPIInfoForModels returns the controller api connection details for the specified models. entities : typing.Sequence[~Entity] Returns -> ControllerAPIInfoResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='ControllerAPIInfoForModels', - version=11, - params=_params) - _params['entities'] = entities + msg = dict( + type="Controller", + request="ControllerAPIInfoForModels", + version=11, + params=_params, + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ControllerConfigResult) async def ControllerConfig(self): - ''' + """ ControllerConfig returns the controller's configuration. Returns -> ControllerConfigResult - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='ControllerConfig', - version=11, - params=_params) + msg = dict( + type="Controller", request="ControllerConfig", version=11, params=_params + ) reply = await self.rpc(msg) return reply - - @ReturnMapping(ControllerVersionResults) async def ControllerVersion(self): - ''' + """ ControllerVersion returns the version information associated with this controller binary. @@ -693,45 +986,49 @@ async def ControllerVersion(self): Returns -> ControllerVersionResults - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='ControllerVersion', - version=11, - params=_params) + msg = dict( + type="Controller", request="ControllerVersion", version=11, params=_params + ) reply = await self.rpc(msg) return reply - - @ReturnMapping(DashboardConnectionInfo) async def DashboardConnectionInfo(self): - ''' + """ DashboardConnectionInfo returns the connection information for a client to connect to the Juju Dashboard including any proxying information. Returns -> DashboardConnectionInfo - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='DashboardConnectionInfo', - version=11, - params=_params) + msg = dict( + type="Controller", + request="DashboardConnectionInfo", + version=11, + params=_params, + ) reply = await self.rpc(msg) return reply - - @ReturnMapping(None) - async def DestroyController(self, destroy_models=None, destroy_storage=None, force=None, max_wait=None, model_timeout=None): - ''' + async def DestroyController( + self, + destroy_models=None, + destroy_storage=None, + force=None, + max_wait=None, + model_timeout=None, + ): + """ DestroyController destroys the controller. If the args specify the destruction of the models, this method will @@ -745,109 +1042,117 @@ async def DestroyController(self, destroy_models=None, destroy_storage=None, for max_wait : int model_timeout : int Returns -> None - ''' + """ if destroy_models is not None and not isinstance(destroy_models, bool): - raise Exception("Expected destroy_models to be a bool, received: {}".format(type(destroy_models))) + raise Exception( + "Expected destroy_models to be a bool, received: {}".format( + type(destroy_models) + ) + ) if destroy_storage is not None and not isinstance(destroy_storage, bool): - raise Exception("Expected destroy_storage to be a bool, received: {}".format(type(destroy_storage))) + raise Exception( + "Expected destroy_storage to be a bool, received: {}".format( + type(destroy_storage) + ) + ) if force is not None and not isinstance(force, bool): - raise Exception("Expected force to be a bool, received: {}".format(type(force))) + raise Exception( + "Expected force to be a bool, received: {}".format(type(force)) + ) if max_wait is not None and not isinstance(max_wait, int): - raise Exception("Expected max_wait to be a int, received: {}".format(type(max_wait))) + raise Exception( + "Expected max_wait to be a int, received: {}".format(type(max_wait)) + ) if model_timeout is not None and not isinstance(model_timeout, int): - raise Exception("Expected model_timeout to be a int, received: {}".format(type(model_timeout))) + raise Exception( + "Expected model_timeout to be a int, received: {}".format( + type(model_timeout) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='DestroyController', - version=11, - params=_params) - _params['destroy-models'] = destroy_models - _params['destroy-storage'] = destroy_storage - _params['force'] = force - _params['max-wait'] = max_wait - _params['model-timeout'] = model_timeout + msg = dict( + type="Controller", request="DestroyController", version=11, params=_params + ) + _params["destroy-models"] = destroy_models + _params["destroy-storage"] = destroy_storage + _params["force"] = force + _params["max-wait"] = max_wait + _params["model-timeout"] = model_timeout reply = await self.rpc(msg) return reply - - @ReturnMapping(CloudSpecResult) async def GetCloudSpec(self): - ''' + """ GetCloudSpec constructs the CloudSpec for a validated and authorized model. Returns -> CloudSpecResult - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='GetCloudSpec', - version=11, - params=_params) + msg = dict( + type="Controller", request="GetCloudSpec", version=11, params=_params + ) reply = await self.rpc(msg) return reply - - @ReturnMapping(UserAccessResults) async def GetControllerAccess(self, entities=None): - ''' + """ GetControllerAccess returns the level of access the specified users have on the controller. entities : typing.Sequence[~Entity] Returns -> UserAccessResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='GetControllerAccess', - version=11, - params=_params) - _params['entities'] = entities + msg = dict( + type="Controller", request="GetControllerAccess", version=11, params=_params + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(HostedModelConfigsResults) async def HostedModelConfigs(self): - ''' + """ HostedModelConfigs returns all the information that the client needs in order to connect directly with the host model's provider and destroy it directly. Returns -> HostedModelConfigsResults - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='HostedModelConfigs', - version=11, - params=_params) + msg = dict( + type="Controller", request="HostedModelConfigs", version=11, params=_params + ) reply = await self.rpc(msg) return reply - - @ReturnMapping(StringResult) async def IdentityProviderURL(self): - ''' + """ IdentityProviderURL returns the URL of the configured external identity provider for this controller or an empty string if no external identity provider has been configured when the controller was bootstrapped. @@ -857,47 +1162,43 @@ async def IdentityProviderURL(self): Returns -> StringResult - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='IdentityProviderURL', - version=11, - params=_params) + msg = dict( + type="Controller", request="IdentityProviderURL", version=11, params=_params + ) reply = await self.rpc(msg) return reply - - @ReturnMapping(InitiateMigrationResults) async def InitiateMigration(self, specs=None): - ''' + """ InitiateMigration attempts to begin the migration of one or more models to other controllers. specs : typing.Sequence[~MigrationSpec] Returns -> InitiateMigrationResults - ''' + """ if specs is not None and not isinstance(specs, (bytes, str, list)): - raise Exception("Expected specs to be a Sequence, received: {}".format(type(specs))) + raise Exception( + "Expected specs to be a Sequence, received: {}".format(type(specs)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='InitiateMigration', - version=11, - params=_params) - _params['specs'] = specs + msg = dict( + type="Controller", request="InitiateMigration", version=11, params=_params + ) + _params["specs"] = specs reply = await self.rpc(msg) return reply - - @ReturnMapping(ModelBlockInfoList) async def ListBlockedModels(self): - ''' + """ ListBlockedModels returns a list of all models on the controller which have a block in place. The resulting slice is sorted by model name, then owner. Callers must be controller administrators to retrieve the @@ -905,220 +1206,207 @@ async def ListBlockedModels(self): Returns -> ModelBlockInfoList - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='ListBlockedModels', - version=11, - params=_params) + msg = dict( + type="Controller", request="ListBlockedModels", version=11, params=_params + ) reply = await self.rpc(msg) return reply - - @ReturnMapping(ModelConfigResults) async def ModelConfig(self): - ''' + """ ModelConfig returns the model config for the controller model. For information on the current model, use client.ModelGet Returns -> ModelConfigResults - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='ModelConfig', - version=11, - params=_params) + msg = dict(type="Controller", request="ModelConfig", version=11, params=_params) reply = await self.rpc(msg) return reply - - @ReturnMapping(ModelStatusResults) async def ModelStatus(self, entities=None): - ''' + """ ModelStatus returns a summary of the model. entities : typing.Sequence[~Entity] Returns -> ModelStatusResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='ModelStatus', - version=11, - params=_params) - _params['entities'] = entities + msg = dict(type="Controller", request="ModelStatus", version=11, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def ModifyControllerAccess(self, changes=None): - ''' + """ ModifyControllerAccess changes the model access granted to users. changes : typing.Sequence[~ModifyControllerAccess] Returns -> ErrorResults - ''' + """ if changes is not None and not isinstance(changes, (bytes, str, list)): - raise Exception("Expected changes to be a Sequence, received: {}".format(type(changes))) + raise Exception( + "Expected changes to be a Sequence, received: {}".format(type(changes)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='ModifyControllerAccess', - version=11, - params=_params) - _params['changes'] = changes + msg = dict( + type="Controller", + request="ModifyControllerAccess", + version=11, + params=_params, + ) + _params["changes"] = changes reply = await self.rpc(msg) return reply - - @ReturnMapping(StringResult) async def MongoVersion(self): - ''' + """ MongoVersion allows the introspection of the mongo version per controller Returns -> StringResult - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='MongoVersion', - version=11, - params=_params) + msg = dict( + type="Controller", request="MongoVersion", version=11, params=_params + ) reply = await self.rpc(msg) return reply - - @ReturnMapping(None) async def RemoveBlocks(self, all_=None): - ''' + """ RemoveBlocks removes all the blocks in the controller. all_ : bool Returns -> None - ''' + """ if all_ is not None and not isinstance(all_, bool): - raise Exception("Expected all_ to be a bool, received: {}".format(type(all_))) + raise Exception( + "Expected all_ to be a bool, received: {}".format(type(all_)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='RemoveBlocks', - version=11, - params=_params) - _params['all'] = all_ + msg = dict( + type="Controller", request="RemoveBlocks", version=11, params=_params + ) + _params["all"] = all_ reply = await self.rpc(msg) return reply - - @ReturnMapping(SummaryWatcherID) async def WatchAllModelSummaries(self): - ''' + """ WatchAllModelSummaries starts watching the summary updates from the cache. This method is superuser access only, and watches all models in the controller. Returns -> SummaryWatcherID - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='WatchAllModelSummaries', - version=11, - params=_params) + msg = dict( + type="Controller", + request="WatchAllModelSummaries", + version=11, + params=_params, + ) reply = await self.rpc(msg) return reply - - @ReturnMapping(AllWatcherId) async def WatchAllModels(self): - ''' + """ WatchAllModels starts watching events for all models in the controller. The returned AllWatcherId should be used with Next on the AllModelWatcher endpoint to receive deltas. Returns -> AllWatcherId - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='WatchAllModels', - version=11, - params=_params) + msg = dict( + type="Controller", request="WatchAllModels", version=11, params=_params + ) reply = await self.rpc(msg) return reply - - @ReturnMapping(NotifyWatchResults) async def WatchCloudSpecsChanges(self, entities=None): - ''' + """ WatchCloudSpecsChanges returns a watcher for cloud spec changes. entities : typing.Sequence[~Entity] Returns -> NotifyWatchResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='WatchCloudSpecsChanges', - version=11, - params=_params) - _params['entities'] = entities + msg = dict( + type="Controller", + request="WatchCloudSpecsChanges", + version=11, + params=_params, + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(SummaryWatcherID) async def WatchModelSummaries(self): - ''' + """ WatchModelSummaries starts watching the summary updates from the cache. Only models that the user has access to are returned. Returns -> SummaryWatcherID - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='WatchModelSummaries', - version=11, - params=_params) + msg = dict( + type="Controller", request="WatchModelSummaries", version=11, params=_params + ) reply = await self.rpc(msg) return reply - - diff --git a/juju/client/_client12.py b/juju/client/_client12.py index ede6b5251..a0d3dd1c2 100644 --- a/juju/client/_client12.py +++ b/juju/client/_client12.py @@ -6,667 +6,947 @@ class ControllerFacade(Type): - name = 'Controller' + name = "Controller" version = 12 - schema = {'definitions': {'AllWatcherId': {'additionalProperties': False, - 'properties': {'watcher-id': {'type': 'string'}}, - 'required': ['watcher-id'], - 'type': 'object'}, - 'CloudCredential': {'additionalProperties': False, - 'properties': {'attrs': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - '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'}, - 'is-controller-cloud': {'type': 'boolean'}, - 'name': {'type': 'string'}, - 'region': {'type': 'string'}, - 'skip-tls-verify': {'type': 'boolean'}, - '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'}, - 'ControllerAPIInfoResult': {'additionalProperties': False, - 'properties': {'addresses': {'items': {'type': 'string'}, - 'type': 'array'}, - 'cacert': {'type': 'string'}, - 'error': {'$ref': '#/definitions/Error'}}, - 'required': ['addresses', - 'cacert'], - 'type': 'object'}, - 'ControllerAPIInfoResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ControllerAPIInfoResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'ControllerConfigResult': {'additionalProperties': False, - 'properties': {'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}}, - 'required': ['config'], - 'type': 'object'}, - 'ControllerConfigSet': {'additionalProperties': False, - 'properties': {'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}}, - 'required': ['config'], - 'type': 'object'}, - 'ControllerVersionResults': {'additionalProperties': False, - 'properties': {'git-commit': {'type': 'string'}, - 'version': {'type': 'string'}}, - 'required': ['version', - 'git-commit'], - 'type': 'object'}, - 'DashboardConnectionInfo': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'proxy-connection': {'$ref': '#/definitions/Proxy'}, - 'ssh-connection': {'$ref': '#/definitions/DashboardConnectionSSHTunnel'}}, - 'required': ['proxy-connection', - 'ssh-connection'], - 'type': 'object'}, - 'DashboardConnectionSSHTunnel': {'additionalProperties': False, - 'properties': {'entity': {'type': 'string'}, - 'host': {'type': 'string'}, - 'model': {'type': 'string'}, - 'port': {'type': 'string'}}, - 'required': ['host', 'port'], - 'type': 'object'}, - 'DestroyControllerArgs': {'additionalProperties': False, - 'properties': {'destroy-models': {'type': 'boolean'}, - 'destroy-storage': {'type': 'boolean'}, - 'force': {'type': 'boolean'}, - 'max-wait': {'type': 'integer'}, - 'model-timeout': {'type': 'integer'}}, - 'required': ['destroy-models'], - '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'}, - 'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - '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'}, - 'HostedModelConfig': {'additionalProperties': False, - 'properties': {'cloud-spec': {'$ref': '#/definitions/CloudSpec'}, - 'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'error': {'$ref': '#/definitions/Error'}, - 'name': {'type': 'string'}, - 'owner': {'type': 'string'}}, - 'required': ['name', 'owner'], - 'type': 'object'}, - 'HostedModelConfigsResults': {'additionalProperties': False, - 'properties': {'models': {'items': {'$ref': '#/definitions/HostedModelConfig'}, - 'type': 'array'}}, - 'required': ['models'], - 'type': 'object'}, - 'InitiateMigrationArgs': {'additionalProperties': False, - 'properties': {'specs': {'items': {'$ref': '#/definitions/MigrationSpec'}, - 'type': 'array'}}, - 'required': ['specs'], - 'type': 'object'}, - 'InitiateMigrationResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'migration-id': {'type': 'string'}, - 'model-tag': {'type': 'string'}}, - 'required': ['model-tag', - 'migration-id'], - 'type': 'object'}, - 'InitiateMigrationResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/InitiateMigrationResult'}, - 'type': 'array'}}, - 'required': ['results'], - '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'}, - 'virt-type': {'type': 'string'}}, - 'type': 'object'}, - 'MigrationSpec': {'additionalProperties': False, - 'properties': {'model-tag': {'type': 'string'}, - 'target-info': {'$ref': '#/definitions/MigrationTargetInfo'}}, - 'required': ['model-tag', 'target-info'], - 'type': 'object'}, - 'MigrationTargetInfo': {'additionalProperties': False, - 'properties': {'addrs': {'items': {'type': 'string'}, - 'type': 'array'}, - 'auth-tag': {'type': 'string'}, - 'ca-cert': {'type': 'string'}, - 'controller-alias': {'type': 'string'}, - 'controller-tag': {'type': 'string'}, - 'macaroons': {'type': 'string'}, - 'password': {'type': 'string'}}, - 'required': ['controller-tag', - 'addrs', - 'ca-cert', - 'auth-tag'], - 'type': 'object'}, - 'Model': {'additionalProperties': False, - 'properties': {'name': {'type': 'string'}, - 'owner-tag': {'type': 'string'}, - 'type': {'type': 'string'}, - 'uuid': {'type': 'string'}}, - 'required': ['name', 'uuid', 'type', 'owner-tag'], - 'type': 'object'}, - 'ModelApplicationInfo': {'additionalProperties': False, - 'properties': {'name': {'type': 'string'}}, - 'required': ['name'], - 'type': 'object'}, - 'ModelBlockInfo': {'additionalProperties': False, - 'properties': {'blocks': {'items': {'type': 'string'}, - 'type': 'array'}, - 'model-uuid': {'type': 'string'}, - 'name': {'type': 'string'}, - 'owner-tag': {'type': 'string'}}, - 'required': ['name', - 'model-uuid', - 'owner-tag', - 'blocks'], - 'type': 'object'}, - 'ModelBlockInfoList': {'additionalProperties': False, - 'properties': {'models': {'items': {'$ref': '#/definitions/ModelBlockInfo'}, - 'type': 'array'}}, - 'type': 'object'}, - 'ModelFilesystemInfo': {'additionalProperties': False, - 'properties': {'detachable': {'type': 'boolean'}, - 'id': {'type': 'string'}, - 'message': {'type': 'string'}, - 'provider-id': {'type': 'string'}, - 'status': {'type': 'string'}}, - 'required': ['id'], - 'type': 'object'}, - 'ModelMachineInfo': {'additionalProperties': False, - 'properties': {'display-name': {'type': 'string'}, - 'ha-primary': {'type': 'boolean'}, - 'hardware': {'$ref': '#/definitions/MachineHardware'}, - 'has-vote': {'type': 'boolean'}, - 'id': {'type': 'string'}, - 'instance-id': {'type': 'string'}, - 'message': {'type': 'string'}, - 'status': {'type': 'string'}, - 'wants-vote': {'type': 'boolean'}}, - 'required': ['id'], - 'type': 'object'}, - 'ModelStatus': {'additionalProperties': False, - 'properties': {'application-count': {'type': 'integer'}, - 'applications': {'items': {'$ref': '#/definitions/ModelApplicationInfo'}, - 'type': 'array'}, - 'error': {'$ref': '#/definitions/Error'}, - 'filesystems': {'items': {'$ref': '#/definitions/ModelFilesystemInfo'}, - 'type': 'array'}, - 'hosted-machine-count': {'type': 'integer'}, - 'life': {'type': 'string'}, - 'machines': {'items': {'$ref': '#/definitions/ModelMachineInfo'}, - 'type': 'array'}, - 'model-tag': {'type': 'string'}, - 'owner-tag': {'type': 'string'}, - 'type': {'type': 'string'}, - 'unit-count': {'type': 'integer'}, - 'volumes': {'items': {'$ref': '#/definitions/ModelVolumeInfo'}, - 'type': 'array'}}, - 'required': ['model-tag', - 'life', - 'type', - 'hosted-machine-count', - 'application-count', - 'unit-count', - 'owner-tag'], - 'type': 'object'}, - 'ModelStatusResults': {'additionalProperties': False, - 'properties': {'models': {'items': {'$ref': '#/definitions/ModelStatus'}, - 'type': 'array'}}, - 'required': ['models'], - 'type': 'object'}, - 'ModelTag': {'additionalProperties': False, 'type': 'object'}, - 'ModelVolumeInfo': {'additionalProperties': False, - 'properties': {'detachable': {'type': 'boolean'}, - 'id': {'type': 'string'}, - 'message': {'type': 'string'}, - 'provider-id': {'type': 'string'}, - 'status': {'type': 'string'}}, - 'required': ['id'], - 'type': 'object'}, - 'ModifyControllerAccess': {'additionalProperties': False, - 'properties': {'access': {'type': 'string'}, - 'action': {'type': 'string'}, - 'user-tag': {'type': 'string'}}, - 'required': ['user-tag', - 'action', - 'access'], - 'type': 'object'}, - 'ModifyControllerAccessRequest': {'additionalProperties': False, - 'properties': {'changes': {'items': {'$ref': '#/definitions/ModifyControllerAccess'}, - 'type': 'array'}}, - 'required': ['changes'], - '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'}, - 'Proxy': {'additionalProperties': False, - 'properties': {'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'type': {'type': 'string'}}, - 'required': ['config', 'type'], - 'type': 'object'}, - 'RemoveBlocksArgs': {'additionalProperties': False, - 'properties': {'all': {'type': 'boolean'}}, - 'required': ['all'], - 'type': 'object'}, - 'StringResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'type': 'string'}}, - 'required': ['result'], - 'type': 'object'}, - 'SummaryWatcherID': {'additionalProperties': False, - 'properties': {'watcher-id': {'type': 'string'}}, - 'required': ['watcher-id'], - 'type': 'object'}, - 'UserAccess': {'additionalProperties': False, - 'properties': {'access': {'type': 'string'}, - 'user-tag': {'type': 'string'}}, - 'required': ['user-tag', 'access'], - 'type': 'object'}, - 'UserAccessResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/UserAccess'}}, - 'type': 'object'}, - 'UserAccessResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/UserAccessResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'UserModel': {'additionalProperties': False, - 'properties': {'last-connection': {'format': 'date-time', - 'type': 'string'}, - 'model': {'$ref': '#/definitions/Model'}}, - 'required': ['model', 'last-connection'], - 'type': 'object'}, - 'UserModelList': {'additionalProperties': False, - 'properties': {'user-models': {'items': {'$ref': '#/definitions/UserModel'}, - 'type': 'array'}}, - 'required': ['user-models'], - 'type': 'object'}}, - 'properties': {'AllModels': {'description': 'AllModels allows controller ' - 'administrators to get the list ' - 'of all the\n' - 'models in the controller.', - 'properties': {'Result': {'$ref': '#/definitions/UserModelList'}}, - 'type': 'object'}, - 'CloudSpec': {'description': "CloudSpec returns the model's " - 'cloud spec.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/CloudSpecResults'}}, - 'type': 'object'}, - 'ConfigSet': {'description': 'ConfigSet changes the value of ' - 'specified controller ' - 'configuration\n' - 'settings. Only some settings can ' - 'be changed after bootstrap.\n' - "Settings that aren't specified " - 'in the params are left ' - 'unchanged.', - 'properties': {'Params': {'$ref': '#/definitions/ControllerConfigSet'}}, - 'type': 'object'}, - 'ControllerAPIInfoForModels': {'description': 'ControllerAPIInfoForModels ' - 'returns the ' - 'controller api ' - 'connection ' - 'details for the ' - 'specified ' - 'models.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ControllerAPIInfoResults'}}, - 'type': 'object'}, - 'ControllerConfig': {'description': 'ControllerConfig returns ' - "the controller's " - 'configuration.', - 'properties': {'Result': {'$ref': '#/definitions/ControllerConfigResult'}}, - 'type': 'object'}, - 'ControllerVersion': {'description': 'ControllerVersion ' - 'returns the version ' - 'information associated ' - 'with this\n' - 'controller binary.\n' - '\n' - 'NOTE: the implementation ' - 'intentionally does not ' - 'check for ' - 'SuperuserAccess\n' - 'as the Version is known ' - 'even to users with login ' - 'access.', - 'properties': {'Result': {'$ref': '#/definitions/ControllerVersionResults'}}, - 'type': 'object'}, - 'DashboardConnectionInfo': {'description': 'DashboardConnectionInfo ' - 'returns the ' - 'connection ' - 'information for a ' - 'client to\n' - 'connect to the ' - 'Juju Dashboard ' - 'including any ' - 'proxying ' - 'information.', - 'properties': {'Result': {'$ref': '#/definitions/DashboardConnectionInfo'}}, - 'type': 'object'}, - 'DestroyController': {'description': 'DestroyController ' - 'destroys the ' - 'controller.\n' - '\n' - 'If the args specify the ' - 'destruction of the ' - 'models, this method ' - 'will\n' - 'attempt to do so. ' - 'Otherwise, if the ' - 'controller has any ' - 'non-empty,\n' - 'non-Dead hosted models, ' - 'then an error with the ' - 'code\n' - 'params.CodeHasHostedModels ' - 'will be transmitted.', - 'properties': {'Params': {'$ref': '#/definitions/DestroyControllerArgs'}}, - 'type': 'object'}, - 'GetCloudSpec': {'description': 'GetCloudSpec constructs the ' - 'CloudSpec for a validated and ' - 'authorized model.', - 'properties': {'Params': {'$ref': '#/definitions/ModelTag'}, - 'Result': {'$ref': '#/definitions/CloudSpecResult'}}, - 'type': 'object'}, - 'GetControllerAccess': {'description': 'GetControllerAccess ' - 'returns the level of ' - 'access the specified ' - 'users\n' - 'have on the ' - 'controller.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/UserAccessResults'}}, - 'type': 'object'}, - 'HostedModelConfigs': {'description': 'HostedModelConfigs ' - 'returns all the ' - 'information that the ' - 'client needs in\n' - 'order to connect ' - 'directly with the host ' - "model's provider and " - 'destroy it\n' - 'directly.', - 'properties': {'Result': {'$ref': '#/definitions/HostedModelConfigsResults'}}, - 'type': 'object'}, - 'IdentityProviderURL': {'description': 'IdentityProviderURL ' - 'returns the URL of the ' - 'configured external ' - 'identity\n' - 'provider for this ' - 'controller or an empty ' - 'string if no external ' - 'identity\n' - 'provider has been ' - 'configured when the ' - 'controller was ' - 'bootstrapped.\n' - '\n' - 'NOTE: the ' - 'implementation ' - 'intentionally does not ' - 'check for ' - 'SuperuserAccess\n' - 'as the URL is known ' - 'even to users with ' - 'login access.', - 'properties': {'Result': {'$ref': '#/definitions/StringResult'}}, - 'type': 'object'}, - 'InitiateMigration': {'description': 'InitiateMigration ' - 'attempts to begin the ' - 'migration of one or\n' - 'more models to other ' - 'controllers.', - 'properties': {'Params': {'$ref': '#/definitions/InitiateMigrationArgs'}, - 'Result': {'$ref': '#/definitions/InitiateMigrationResults'}}, - 'type': 'object'}, - 'ListBlockedModels': {'description': 'ListBlockedModels ' - 'returns a list of all ' - 'models on the ' - 'controller\n' - 'which have a block in ' - 'place. The resulting ' - 'slice is sorted by ' - 'model\n' - 'name, then owner. ' - 'Callers must be ' - 'controller ' - 'administrators to ' - 'retrieve the\n' - 'list.', - 'properties': {'Result': {'$ref': '#/definitions/ModelBlockInfoList'}}, - 'type': 'object'}, - 'ModelStatus': {'description': 'ModelStatus returns a summary ' - 'of the model.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ModelStatusResults'}}, - 'type': 'object'}, - 'ModifyControllerAccess': {'description': 'ModifyControllerAccess ' - 'changes the model ' - 'access granted to ' - 'users.', - 'properties': {'Params': {'$ref': '#/definitions/ModifyControllerAccessRequest'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'MongoVersion': {'description': 'MongoVersion allows the ' - 'introspection of the mongo ' - 'version per controller', - 'properties': {'Result': {'$ref': '#/definitions/StringResult'}}, - 'type': 'object'}, - 'RemoveBlocks': {'description': 'RemoveBlocks removes all the ' - 'blocks in the controller.', - 'properties': {'Params': {'$ref': '#/definitions/RemoveBlocksArgs'}}, - 'type': 'object'}, - 'WatchAllModelSummaries': {'description': 'WatchAllModelSummaries ' - 'starts watching the ' - 'summary updates ' - 'from the cache.\n' - 'This method is ' - 'superuser access ' - 'only, and watches ' - 'all models in the\n' - 'controller.', - 'properties': {'Result': {'$ref': '#/definitions/SummaryWatcherID'}}, - 'type': 'object'}, - 'WatchAllModels': {'description': 'WatchAllModels starts ' - 'watching events for all ' - 'models in the\n' - 'controller. The returned ' - 'AllWatcherId should be used ' - 'with Next on the\n' - 'AllModelWatcher endpoint to ' - 'receive deltas.', - 'properties': {'Result': {'$ref': '#/definitions/AllWatcherId'}}, - 'type': 'object'}, - 'WatchCloudSpecsChanges': {'description': 'WatchCloudSpecsChanges ' - 'returns a watcher ' - 'for cloud spec ' - 'changes.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/NotifyWatchResults'}}, - 'type': 'object'}, - 'WatchModelSummaries': {'description': 'WatchModelSummaries ' - 'starts watching the ' - 'summary updates from ' - 'the cache.\n' - 'Only models that the ' - 'user has access to are ' - 'returned.', - 'properties': {'Result': {'$ref': '#/definitions/SummaryWatcherID'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "AllWatcherId": { + "additionalProperties": False, + "properties": {"watcher-id": {"type": "string"}}, + "required": ["watcher-id"], + "type": "object", + }, + "CloudCredential": { + "additionalProperties": False, + "properties": { + "attrs": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "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"}, + "is-controller-cloud": {"type": "boolean"}, + "name": {"type": "string"}, + "region": {"type": "string"}, + "skip-tls-verify": {"type": "boolean"}, + "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", + }, + "ControllerAPIInfoResult": { + "additionalProperties": False, + "properties": { + "addresses": {"items": {"type": "string"}, "type": "array"}, + "cacert": {"type": "string"}, + "error": {"$ref": "#/definitions/Error"}, + }, + "required": ["addresses", "cacert"], + "type": "object", + }, + "ControllerAPIInfoResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ControllerAPIInfoResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "ControllerConfigResult": { + "additionalProperties": False, + "properties": { + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + } + }, + "required": ["config"], + "type": "object", + }, + "ControllerConfigSet": { + "additionalProperties": False, + "properties": { + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + } + }, + "required": ["config"], + "type": "object", + }, + "ControllerVersionResults": { + "additionalProperties": False, + "properties": { + "git-commit": {"type": "string"}, + "version": {"type": "string"}, + }, + "required": ["version", "git-commit"], + "type": "object", + }, + "DashboardConnectionInfo": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "proxy-connection": {"$ref": "#/definitions/Proxy"}, + "ssh-connection": { + "$ref": "#/definitions/DashboardConnectionSSHTunnel" + }, + }, + "required": ["proxy-connection", "ssh-connection"], + "type": "object", + }, + "DashboardConnectionSSHTunnel": { + "additionalProperties": False, + "properties": { + "entity": {"type": "string"}, + "host": {"type": "string"}, + "model": {"type": "string"}, + "port": {"type": "string"}, + }, + "required": ["host", "port"], + "type": "object", + }, + "DestroyControllerArgs": { + "additionalProperties": False, + "properties": { + "destroy-models": {"type": "boolean"}, + "destroy-storage": {"type": "boolean"}, + "force": {"type": "boolean"}, + "max-wait": {"type": "integer"}, + "model-timeout": {"type": "integer"}, + }, + "required": ["destroy-models"], + "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", + }, + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "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", + }, + "HostedModelConfig": { + "additionalProperties": False, + "properties": { + "cloud-spec": {"$ref": "#/definitions/CloudSpec"}, + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "error": {"$ref": "#/definitions/Error"}, + "name": {"type": "string"}, + "owner": {"type": "string"}, + }, + "required": ["name", "owner"], + "type": "object", + }, + "HostedModelConfigsResults": { + "additionalProperties": False, + "properties": { + "models": { + "items": {"$ref": "#/definitions/HostedModelConfig"}, + "type": "array", + } + }, + "required": ["models"], + "type": "object", + }, + "InitiateMigrationArgs": { + "additionalProperties": False, + "properties": { + "specs": { + "items": {"$ref": "#/definitions/MigrationSpec"}, + "type": "array", + } + }, + "required": ["specs"], + "type": "object", + }, + "InitiateMigrationResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "migration-id": {"type": "string"}, + "model-tag": {"type": "string"}, + }, + "required": ["model-tag", "migration-id"], + "type": "object", + }, + "InitiateMigrationResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/InitiateMigrationResult"}, + "type": "array", + } + }, + "required": ["results"], + "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"}, + "virt-type": {"type": "string"}, + }, + "type": "object", + }, + "MigrationSpec": { + "additionalProperties": False, + "properties": { + "model-tag": {"type": "string"}, + "target-info": {"$ref": "#/definitions/MigrationTargetInfo"}, + }, + "required": ["model-tag", "target-info"], + "type": "object", + }, + "MigrationTargetInfo": { + "additionalProperties": False, + "properties": { + "addrs": {"items": {"type": "string"}, "type": "array"}, + "auth-tag": {"type": "string"}, + "ca-cert": {"type": "string"}, + "controller-alias": {"type": "string"}, + "controller-tag": {"type": "string"}, + "macaroons": {"type": "string"}, + "password": {"type": "string"}, + }, + "required": ["controller-tag", "addrs", "ca-cert", "auth-tag"], + "type": "object", + }, + "Model": { + "additionalProperties": False, + "properties": { + "name": {"type": "string"}, + "owner-tag": {"type": "string"}, + "type": {"type": "string"}, + "uuid": {"type": "string"}, + }, + "required": ["name", "uuid", "type", "owner-tag"], + "type": "object", + }, + "ModelApplicationInfo": { + "additionalProperties": False, + "properties": {"name": {"type": "string"}}, + "required": ["name"], + "type": "object", + }, + "ModelBlockInfo": { + "additionalProperties": False, + "properties": { + "blocks": {"items": {"type": "string"}, "type": "array"}, + "model-uuid": {"type": "string"}, + "name": {"type": "string"}, + "owner-tag": {"type": "string"}, + }, + "required": ["name", "model-uuid", "owner-tag", "blocks"], + "type": "object", + }, + "ModelBlockInfoList": { + "additionalProperties": False, + "properties": { + "models": { + "items": {"$ref": "#/definitions/ModelBlockInfo"}, + "type": "array", + } + }, + "type": "object", + }, + "ModelFilesystemInfo": { + "additionalProperties": False, + "properties": { + "detachable": {"type": "boolean"}, + "id": {"type": "string"}, + "message": {"type": "string"}, + "provider-id": {"type": "string"}, + "status": {"type": "string"}, + }, + "required": ["id"], + "type": "object", + }, + "ModelMachineInfo": { + "additionalProperties": False, + "properties": { + "display-name": {"type": "string"}, + "ha-primary": {"type": "boolean"}, + "hardware": {"$ref": "#/definitions/MachineHardware"}, + "has-vote": {"type": "boolean"}, + "id": {"type": "string"}, + "instance-id": {"type": "string"}, + "message": {"type": "string"}, + "status": {"type": "string"}, + "wants-vote": {"type": "boolean"}, + }, + "required": ["id"], + "type": "object", + }, + "ModelStatus": { + "additionalProperties": False, + "properties": { + "application-count": {"type": "integer"}, + "applications": { + "items": {"$ref": "#/definitions/ModelApplicationInfo"}, + "type": "array", + }, + "error": {"$ref": "#/definitions/Error"}, + "filesystems": { + "items": {"$ref": "#/definitions/ModelFilesystemInfo"}, + "type": "array", + }, + "hosted-machine-count": {"type": "integer"}, + "life": {"type": "string"}, + "machines": { + "items": {"$ref": "#/definitions/ModelMachineInfo"}, + "type": "array", + }, + "model-tag": {"type": "string"}, + "owner-tag": {"type": "string"}, + "type": {"type": "string"}, + "unit-count": {"type": "integer"}, + "volumes": { + "items": {"$ref": "#/definitions/ModelVolumeInfo"}, + "type": "array", + }, + }, + "required": [ + "model-tag", + "life", + "type", + "hosted-machine-count", + "application-count", + "unit-count", + "owner-tag", + ], + "type": "object", + }, + "ModelStatusResults": { + "additionalProperties": False, + "properties": { + "models": { + "items": {"$ref": "#/definitions/ModelStatus"}, + "type": "array", + } + }, + "required": ["models"], + "type": "object", + }, + "ModelTag": {"additionalProperties": False, "type": "object"}, + "ModelVolumeInfo": { + "additionalProperties": False, + "properties": { + "detachable": {"type": "boolean"}, + "id": {"type": "string"}, + "message": {"type": "string"}, + "provider-id": {"type": "string"}, + "status": {"type": "string"}, + }, + "required": ["id"], + "type": "object", + }, + "ModifyControllerAccess": { + "additionalProperties": False, + "properties": { + "access": {"type": "string"}, + "action": {"type": "string"}, + "user-tag": {"type": "string"}, + }, + "required": ["user-tag", "action", "access"], + "type": "object", + }, + "ModifyControllerAccessRequest": { + "additionalProperties": False, + "properties": { + "changes": { + "items": {"$ref": "#/definitions/ModifyControllerAccess"}, + "type": "array", + } + }, + "required": ["changes"], + "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", + }, + "Proxy": { + "additionalProperties": False, + "properties": { + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "type": {"type": "string"}, + }, + "required": ["config", "type"], + "type": "object", + }, + "RemoveBlocksArgs": { + "additionalProperties": False, + "properties": {"all": {"type": "boolean"}}, + "required": ["all"], + "type": "object", + }, + "StringResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"type": "string"}, + }, + "required": ["result"], + "type": "object", + }, + "SummaryWatcherID": { + "additionalProperties": False, + "properties": {"watcher-id": {"type": "string"}}, + "required": ["watcher-id"], + "type": "object", + }, + "UserAccess": { + "additionalProperties": False, + "properties": { + "access": {"type": "string"}, + "user-tag": {"type": "string"}, + }, + "required": ["user-tag", "access"], + "type": "object", + }, + "UserAccessResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/UserAccess"}, + }, + "type": "object", + }, + "UserAccessResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/UserAccessResult"}, + "type": "array", + } + }, + "type": "object", + }, + "UserModel": { + "additionalProperties": False, + "properties": { + "last-connection": {"format": "date-time", "type": "string"}, + "model": {"$ref": "#/definitions/Model"}, + }, + "required": ["model", "last-connection"], + "type": "object", + }, + "UserModelList": { + "additionalProperties": False, + "properties": { + "user-models": { + "items": {"$ref": "#/definitions/UserModel"}, + "type": "array", + } + }, + "required": ["user-models"], + "type": "object", + }, + }, + "properties": { + "AllModels": { + "description": "AllModels allows controller " + "administrators to get the list " + "of all the\n" + "models in the controller.", + "properties": {"Result": {"$ref": "#/definitions/UserModelList"}}, + "type": "object", + }, + "CloudSpec": { + "description": "CloudSpec returns the model's cloud spec.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/CloudSpecResults"}, + }, + "type": "object", + }, + "ConfigSet": { + "description": "ConfigSet changes the value of " + "specified controller " + "configuration\n" + "settings. Only some settings can " + "be changed after bootstrap.\n" + "Settings that aren't specified " + "in the params are left " + "unchanged.", + "properties": {"Params": {"$ref": "#/definitions/ControllerConfigSet"}}, + "type": "object", + }, + "ControllerAPIInfoForModels": { + "description": "ControllerAPIInfoForModels " + "returns the " + "controller api " + "connection " + "details for the " + "specified " + "models.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/ControllerAPIInfoResults"}, + }, + "type": "object", + }, + "ControllerConfig": { + "description": "ControllerConfig returns " + "the controller's " + "configuration.", + "properties": { + "Result": {"$ref": "#/definitions/ControllerConfigResult"} + }, + "type": "object", + }, + "ControllerVersion": { + "description": "ControllerVersion " + "returns the version " + "information associated " + "with this\n" + "controller binary.\n" + "\n" + "NOTE: the implementation " + "intentionally does not " + "check for " + "SuperuserAccess\n" + "as the Version is known " + "even to users with login " + "access.", + "properties": { + "Result": {"$ref": "#/definitions/ControllerVersionResults"} + }, + "type": "object", + }, + "DashboardConnectionInfo": { + "description": "DashboardConnectionInfo " + "returns the " + "connection " + "information for a " + "client to\n" + "connect to the " + "Juju Dashboard " + "including any " + "proxying " + "information.", + "properties": { + "Result": {"$ref": "#/definitions/DashboardConnectionInfo"} + }, + "type": "object", + }, + "DestroyController": { + "description": "DestroyController " + "destroys the " + "controller.\n" + "\n" + "If the args specify the " + "destruction of the " + "models, this method " + "will\n" + "attempt to do so. " + "Otherwise, if the " + "controller has any " + "non-empty,\n" + "non-Dead hosted models, " + "then an error with the " + "code\n" + "params.CodeHasHostedModels " + "will be transmitted.", + "properties": { + "Params": {"$ref": "#/definitions/DestroyControllerArgs"} + }, + "type": "object", + }, + "GetCloudSpec": { + "description": "GetCloudSpec constructs the " + "CloudSpec for a validated and " + "authorized model.", + "properties": { + "Params": {"$ref": "#/definitions/ModelTag"}, + "Result": {"$ref": "#/definitions/CloudSpecResult"}, + }, + "type": "object", + }, + "GetControllerAccess": { + "description": "GetControllerAccess " + "returns the level of " + "access the specified " + "users\n" + "have on the " + "controller.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/UserAccessResults"}, + }, + "type": "object", + }, + "HostedModelConfigs": { + "description": "HostedModelConfigs " + "returns all the " + "information that the " + "client needs in\n" + "order to connect " + "directly with the host " + "model's provider and " + "destroy it\n" + "directly.", + "properties": { + "Result": {"$ref": "#/definitions/HostedModelConfigsResults"} + }, + "type": "object", + }, + "IdentityProviderURL": { + "description": "IdentityProviderURL " + "returns the URL of the " + "configured external " + "identity\n" + "provider for this " + "controller or an empty " + "string if no external " + "identity\n" + "provider has been " + "configured when the " + "controller was " + "bootstrapped.\n" + "\n" + "NOTE: the " + "implementation " + "intentionally does not " + "check for " + "SuperuserAccess\n" + "as the URL is known " + "even to users with " + "login access.", + "properties": {"Result": {"$ref": "#/definitions/StringResult"}}, + "type": "object", + }, + "InitiateMigration": { + "description": "InitiateMigration " + "attempts to begin the " + "migration of one or\n" + "more models to other " + "controllers.", + "properties": { + "Params": {"$ref": "#/definitions/InitiateMigrationArgs"}, + "Result": {"$ref": "#/definitions/InitiateMigrationResults"}, + }, + "type": "object", + }, + "ListBlockedModels": { + "description": "ListBlockedModels " + "returns a list of all " + "models on the " + "controller\n" + "which have a block in " + "place. The resulting " + "slice is sorted by " + "model\n" + "name, then owner. " + "Callers must be " + "controller " + "administrators to " + "retrieve the\n" + "list.", + "properties": {"Result": {"$ref": "#/definitions/ModelBlockInfoList"}}, + "type": "object", + }, + "ModelStatus": { + "description": "ModelStatus returns a summary of the model.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/ModelStatusResults"}, + }, + "type": "object", + }, + "ModifyControllerAccess": { + "description": "ModifyControllerAccess " + "changes the model " + "access granted to " + "users.", + "properties": { + "Params": {"$ref": "#/definitions/ModifyControllerAccessRequest"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "MongoVersion": { + "description": "MongoVersion allows the " + "introspection of the mongo " + "version per controller", + "properties": {"Result": {"$ref": "#/definitions/StringResult"}}, + "type": "object", + }, + "RemoveBlocks": { + "description": "RemoveBlocks removes all the blocks in the controller.", + "properties": {"Params": {"$ref": "#/definitions/RemoveBlocksArgs"}}, + "type": "object", + }, + "WatchAllModelSummaries": { + "description": "WatchAllModelSummaries " + "starts watching the " + "summary updates " + "from the cache.\n" + "This method is " + "superuser access " + "only, and watches " + "all models in the\n" + "controller.", + "properties": {"Result": {"$ref": "#/definitions/SummaryWatcherID"}}, + "type": "object", + }, + "WatchAllModels": { + "description": "WatchAllModels starts " + "watching events for all " + "models in the\n" + "controller. The returned " + "AllWatcherId should be used " + "with Next on the\n" + "AllModelWatcher endpoint to " + "receive deltas.", + "properties": {"Result": {"$ref": "#/definitions/AllWatcherId"}}, + "type": "object", + }, + "WatchCloudSpecsChanges": { + "description": "WatchCloudSpecsChanges " + "returns a watcher " + "for cloud spec " + "changes.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/NotifyWatchResults"}, + }, + "type": "object", + }, + "WatchModelSummaries": { + "description": "WatchModelSummaries " + "starts watching the " + "summary updates from " + "the cache.\n" + "Only models that the " + "user has access to are " + "returned.", + "properties": {"Result": {"$ref": "#/definitions/SummaryWatcherID"}}, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(UserModelList) async def AllModels(self): - ''' + """ AllModels allows controller administrators to get the list of all the models in the controller. Returns -> UserModelList - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='AllModels', - version=12, - params=_params) + msg = dict(type="Controller", request="AllModels", version=12, params=_params) reply = await self.rpc(msg) return reply - - @ReturnMapping(CloudSpecResults) async def CloudSpec(self, entities=None): - ''' + """ CloudSpec returns the model's cloud spec. entities : typing.Sequence[~Entity] Returns -> CloudSpecResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='CloudSpec', - version=12, - params=_params) - _params['entities'] = entities + msg = dict(type="Controller", request="CloudSpec", version=12, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(None) async def ConfigSet(self, config=None): - ''' + """ ConfigSet changes the value of specified controller configuration settings. Only some settings can be changed after bootstrap. Settings that aren't specified in the params are left unchanged. config : typing.Mapping[str, typing.Any] Returns -> None - ''' + """ if config is not None and not isinstance(config, dict): - raise Exception("Expected config to be a Mapping, received: {}".format(type(config))) + raise Exception( + "Expected config to be a Mapping, received: {}".format(type(config)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='ConfigSet', - version=12, - params=_params) - _params['config'] = config + msg = dict(type="Controller", request="ConfigSet", version=12, params=_params) + _params["config"] = config reply = await self.rpc(msg) return reply - - @ReturnMapping(ControllerAPIInfoResults) async def ControllerAPIInfoForModels(self, entities=None): - ''' + """ ControllerAPIInfoForModels returns the controller api connection details for the specified models. entities : typing.Sequence[~Entity] Returns -> ControllerAPIInfoResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='ControllerAPIInfoForModels', - version=12, - params=_params) - _params['entities'] = entities + msg = dict( + type="Controller", + request="ControllerAPIInfoForModels", + version=12, + params=_params, + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ControllerConfigResult) async def ControllerConfig(self): - ''' + """ ControllerConfig returns the controller's configuration. Returns -> ControllerConfigResult - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='ControllerConfig', - version=12, - params=_params) + msg = dict( + type="Controller", request="ControllerConfig", version=12, params=_params + ) reply = await self.rpc(msg) return reply - - @ReturnMapping(ControllerVersionResults) async def ControllerVersion(self): - ''' + """ ControllerVersion returns the version information associated with this controller binary. @@ -675,45 +955,49 @@ async def ControllerVersion(self): Returns -> ControllerVersionResults - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='ControllerVersion', - version=12, - params=_params) + msg = dict( + type="Controller", request="ControllerVersion", version=12, params=_params + ) reply = await self.rpc(msg) return reply - - @ReturnMapping(DashboardConnectionInfo) async def DashboardConnectionInfo(self): - ''' + """ DashboardConnectionInfo returns the connection information for a client to connect to the Juju Dashboard including any proxying information. Returns -> DashboardConnectionInfo - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='DashboardConnectionInfo', - version=12, - params=_params) + msg = dict( + type="Controller", + request="DashboardConnectionInfo", + version=12, + params=_params, + ) reply = await self.rpc(msg) return reply - - @ReturnMapping(None) - async def DestroyController(self, destroy_models=None, destroy_storage=None, force=None, max_wait=None, model_timeout=None): - ''' + async def DestroyController( + self, + destroy_models=None, + destroy_storage=None, + force=None, + max_wait=None, + model_timeout=None, + ): + """ DestroyController destroys the controller. If the args specify the destruction of the models, this method will @@ -727,109 +1011,117 @@ async def DestroyController(self, destroy_models=None, destroy_storage=None, for max_wait : int model_timeout : int Returns -> None - ''' + """ if destroy_models is not None and not isinstance(destroy_models, bool): - raise Exception("Expected destroy_models to be a bool, received: {}".format(type(destroy_models))) + raise Exception( + "Expected destroy_models to be a bool, received: {}".format( + type(destroy_models) + ) + ) if destroy_storage is not None and not isinstance(destroy_storage, bool): - raise Exception("Expected destroy_storage to be a bool, received: {}".format(type(destroy_storage))) + raise Exception( + "Expected destroy_storage to be a bool, received: {}".format( + type(destroy_storage) + ) + ) if force is not None and not isinstance(force, bool): - raise Exception("Expected force to be a bool, received: {}".format(type(force))) + raise Exception( + "Expected force to be a bool, received: {}".format(type(force)) + ) if max_wait is not None and not isinstance(max_wait, int): - raise Exception("Expected max_wait to be a int, received: {}".format(type(max_wait))) + raise Exception( + "Expected max_wait to be a int, received: {}".format(type(max_wait)) + ) if model_timeout is not None and not isinstance(model_timeout, int): - raise Exception("Expected model_timeout to be a int, received: {}".format(type(model_timeout))) + raise Exception( + "Expected model_timeout to be a int, received: {}".format( + type(model_timeout) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='DestroyController', - version=12, - params=_params) - _params['destroy-models'] = destroy_models - _params['destroy-storage'] = destroy_storage - _params['force'] = force - _params['max-wait'] = max_wait - _params['model-timeout'] = model_timeout + msg = dict( + type="Controller", request="DestroyController", version=12, params=_params + ) + _params["destroy-models"] = destroy_models + _params["destroy-storage"] = destroy_storage + _params["force"] = force + _params["max-wait"] = max_wait + _params["model-timeout"] = model_timeout reply = await self.rpc(msg) return reply - - @ReturnMapping(CloudSpecResult) async def GetCloudSpec(self): - ''' + """ GetCloudSpec constructs the CloudSpec for a validated and authorized model. Returns -> CloudSpecResult - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='GetCloudSpec', - version=12, - params=_params) + msg = dict( + type="Controller", request="GetCloudSpec", version=12, params=_params + ) reply = await self.rpc(msg) return reply - - @ReturnMapping(UserAccessResults) async def GetControllerAccess(self, entities=None): - ''' + """ GetControllerAccess returns the level of access the specified users have on the controller. entities : typing.Sequence[~Entity] Returns -> UserAccessResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='GetControllerAccess', - version=12, - params=_params) - _params['entities'] = entities + msg = dict( + type="Controller", request="GetControllerAccess", version=12, params=_params + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(HostedModelConfigsResults) async def HostedModelConfigs(self): - ''' + """ HostedModelConfigs returns all the information that the client needs in order to connect directly with the host model's provider and destroy it directly. Returns -> HostedModelConfigsResults - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='HostedModelConfigs', - version=12, - params=_params) + msg = dict( + type="Controller", request="HostedModelConfigs", version=12, params=_params + ) reply = await self.rpc(msg) return reply - - @ReturnMapping(StringResult) async def IdentityProviderURL(self): - ''' + """ IdentityProviderURL returns the URL of the configured external identity provider for this controller or an empty string if no external identity provider has been configured when the controller was bootstrapped. @@ -839,47 +1131,43 @@ async def IdentityProviderURL(self): Returns -> StringResult - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='IdentityProviderURL', - version=12, - params=_params) + msg = dict( + type="Controller", request="IdentityProviderURL", version=12, params=_params + ) reply = await self.rpc(msg) return reply - - @ReturnMapping(InitiateMigrationResults) async def InitiateMigration(self, specs=None): - ''' + """ InitiateMigration attempts to begin the migration of one or more models to other controllers. specs : typing.Sequence[~MigrationSpec] Returns -> InitiateMigrationResults - ''' + """ if specs is not None and not isinstance(specs, (bytes, str, list)): - raise Exception("Expected specs to be a Sequence, received: {}".format(type(specs))) + raise Exception( + "Expected specs to be a Sequence, received: {}".format(type(specs)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='InitiateMigration', - version=12, - params=_params) - _params['specs'] = specs + msg = dict( + type="Controller", request="InitiateMigration", version=12, params=_params + ) + _params["specs"] = specs reply = await self.rpc(msg) return reply - - @ReturnMapping(ModelBlockInfoList) async def ListBlockedModels(self): - ''' + """ ListBlockedModels returns a list of all models on the controller which have a block in place. The resulting slice is sorted by model name, then owner. Callers must be controller administrators to retrieve the @@ -887,197 +1175,189 @@ async def ListBlockedModels(self): Returns -> ModelBlockInfoList - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='ListBlockedModels', - version=12, - params=_params) + msg = dict( + type="Controller", request="ListBlockedModels", version=12, params=_params + ) reply = await self.rpc(msg) return reply - - @ReturnMapping(ModelStatusResults) async def ModelStatus(self, entities=None): - ''' + """ ModelStatus returns a summary of the model. entities : typing.Sequence[~Entity] Returns -> ModelStatusResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='ModelStatus', - version=12, - params=_params) - _params['entities'] = entities + msg = dict(type="Controller", request="ModelStatus", version=12, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def ModifyControllerAccess(self, changes=None): - ''' + """ ModifyControllerAccess changes the model access granted to users. changes : typing.Sequence[~ModifyControllerAccess] Returns -> ErrorResults - ''' + """ if changes is not None and not isinstance(changes, (bytes, str, list)): - raise Exception("Expected changes to be a Sequence, received: {}".format(type(changes))) + raise Exception( + "Expected changes to be a Sequence, received: {}".format(type(changes)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='ModifyControllerAccess', - version=12, - params=_params) - _params['changes'] = changes + msg = dict( + type="Controller", + request="ModifyControllerAccess", + version=12, + params=_params, + ) + _params["changes"] = changes reply = await self.rpc(msg) return reply - - @ReturnMapping(StringResult) async def MongoVersion(self): - ''' + """ MongoVersion allows the introspection of the mongo version per controller Returns -> StringResult - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='MongoVersion', - version=12, - params=_params) + msg = dict( + type="Controller", request="MongoVersion", version=12, params=_params + ) reply = await self.rpc(msg) return reply - - @ReturnMapping(None) async def RemoveBlocks(self, all_=None): - ''' + """ RemoveBlocks removes all the blocks in the controller. all_ : bool Returns -> None - ''' + """ if all_ is not None and not isinstance(all_, bool): - raise Exception("Expected all_ to be a bool, received: {}".format(type(all_))) + raise Exception( + "Expected all_ to be a bool, received: {}".format(type(all_)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='RemoveBlocks', - version=12, - params=_params) - _params['all'] = all_ + msg = dict( + type="Controller", request="RemoveBlocks", version=12, params=_params + ) + _params["all"] = all_ reply = await self.rpc(msg) return reply - - @ReturnMapping(SummaryWatcherID) async def WatchAllModelSummaries(self): - ''' + """ WatchAllModelSummaries starts watching the summary updates from the cache. This method is superuser access only, and watches all models in the controller. Returns -> SummaryWatcherID - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='WatchAllModelSummaries', - version=12, - params=_params) + msg = dict( + type="Controller", + request="WatchAllModelSummaries", + version=12, + params=_params, + ) reply = await self.rpc(msg) return reply - - @ReturnMapping(AllWatcherId) async def WatchAllModels(self): - ''' + """ WatchAllModels starts watching events for all models in the controller. The returned AllWatcherId should be used with Next on the AllModelWatcher endpoint to receive deltas. Returns -> AllWatcherId - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='WatchAllModels', - version=12, - params=_params) + msg = dict( + type="Controller", request="WatchAllModels", version=12, params=_params + ) reply = await self.rpc(msg) return reply - - @ReturnMapping(NotifyWatchResults) async def WatchCloudSpecsChanges(self, entities=None): - ''' + """ WatchCloudSpecsChanges returns a watcher for cloud spec changes. entities : typing.Sequence[~Entity] Returns -> NotifyWatchResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='WatchCloudSpecsChanges', - version=12, - params=_params) - _params['entities'] = entities + msg = dict( + type="Controller", + request="WatchCloudSpecsChanges", + version=12, + params=_params, + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(SummaryWatcherID) async def WatchModelSummaries(self): - ''' + """ WatchModelSummaries starts watching the summary updates from the cache. Only models that the user has access to are returned. Returns -> SummaryWatcherID - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Controller', - request='WatchModelSummaries', - version=12, - params=_params) + msg = dict( + type="Controller", request="WatchModelSummaries", version=12, params=_params + ) reply = await self.rpc(msg) return reply - - diff --git a/juju/client/_client17.py b/juju/client/_client17.py index 68b2985fe..74bf11299 100644 --- a/juju/client/_client17.py +++ b/juju/client/_client17.py @@ -6,895 +6,1448 @@ class ApplicationFacade(Type): - name = 'Application' + name = "Application" version = 17 - schema = {'definitions': {'AddApplicationUnits': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'attach-storage': {'items': {'type': 'string'}, - 'type': 'array'}, - 'num-units': {'type': 'integer'}, - 'placement': {'items': {'$ref': '#/definitions/Placement'}, - 'type': 'array'}, - 'policy': {'type': 'string'}}, - 'required': ['application', - 'num-units', - 'placement'], - 'type': 'object'}, - 'AddApplicationUnitsResults': {'additionalProperties': False, - 'properties': {'units': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['units'], - 'type': 'object'}, - 'AddRelation': {'additionalProperties': False, - 'properties': {'endpoints': {'items': {'type': 'string'}, - 'type': 'array'}, - 'via-cidrs': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['endpoints'], - 'type': 'object'}, - 'AddRelationResults': {'additionalProperties': False, - 'properties': {'endpoints': {'patternProperties': {'.*': {'$ref': '#/definitions/CharmRelation'}}, - 'type': 'object'}}, - 'required': ['endpoints'], - 'type': 'object'}, - 'ApplicationCharmRelations': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}}, - 'required': ['application'], - 'type': 'object'}, - 'ApplicationCharmRelationsResults': {'additionalProperties': False, - 'properties': {'charm-relations': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['charm-relations'], - 'type': 'object'}, - 'ApplicationConfigUnsetArgs': {'additionalProperties': False, - 'properties': {'Args': {'items': {'$ref': '#/definitions/ApplicationUnset'}, - 'type': 'array'}}, - 'required': ['Args'], - 'type': 'object'}, - 'ApplicationConstraint': {'additionalProperties': False, - 'properties': {'constraints': {'$ref': '#/definitions/Value'}, - 'error': {'$ref': '#/definitions/Error'}}, - 'required': ['constraints'], - 'type': 'object'}, - 'ApplicationDeploy': {'additionalProperties': False, - 'properties': {'Force': {'type': 'boolean'}, - 'application': {'type': 'string'}, - 'attach-storage': {'items': {'type': 'string'}, - 'type': 'array'}, - 'channel': {'type': 'string'}, - 'charm-origin': {'$ref': '#/definitions/CharmOrigin'}, - 'charm-url': {'type': 'string'}, - 'config': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'config-yaml': {'type': 'string'}, - 'constraints': {'$ref': '#/definitions/Value'}, - 'devices': {'patternProperties': {'.*': {'$ref': '#/definitions/Constraints'}}, - 'type': 'object'}, - 'endpoint-bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'num-units': {'type': 'integer'}, - 'placement': {'items': {'$ref': '#/definitions/Placement'}, - 'type': 'array'}, - 'policy': {'type': 'string'}, - 'resources': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'storage': {'patternProperties': {'.*': {'$ref': '#/definitions/Constraints'}}, - 'type': 'object'}}, - 'required': ['application', - 'charm-url', - 'channel', - 'num-units', - 'config-yaml', - 'constraints', - 'Force'], - 'type': 'object'}, - 'ApplicationExpose': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'exposed-endpoints': {'patternProperties': {'.*': {'$ref': '#/definitions/ExposedEndpoint'}}, - 'type': 'object'}}, - 'required': ['application'], - 'type': 'object'}, - 'ApplicationGet': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'branch': {'type': 'string'}}, - 'required': ['application', 'branch'], - 'type': 'object'}, - 'ApplicationGetArgs': {'additionalProperties': False, - 'properties': {'args': {'items': {'$ref': '#/definitions/ApplicationGet'}, - 'type': 'array'}}, - 'required': ['args'], - 'type': 'object'}, - 'ApplicationGetConfigResults': {'additionalProperties': False, - 'properties': {'Results': {'items': {'$ref': '#/definitions/ConfigResult'}, - 'type': 'array'}}, - 'required': ['Results'], - 'type': 'object'}, - 'ApplicationGetConstraintsResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ApplicationConstraint'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'ApplicationGetResults': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'application-config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'base': {'$ref': '#/definitions/Base'}, - 'channel': {'type': 'string'}, - 'charm': {'type': 'string'}, - 'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'constraints': {'$ref': '#/definitions/Value'}, - 'endpoint-bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}}, - 'required': ['application', - 'charm', - 'config', - 'constraints', - 'base', - 'channel'], - 'type': 'object'}, - 'ApplicationInfoResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/ApplicationResult'}}, - 'type': 'object'}, - 'ApplicationInfoResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ApplicationInfoResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'ApplicationMergeBindings': {'additionalProperties': False, - 'properties': {'application-tag': {'type': 'string'}, - 'bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'force': {'type': 'boolean'}}, - 'required': ['application-tag', - 'bindings', - 'force'], - 'type': 'object'}, - 'ApplicationMergeBindingsArgs': {'additionalProperties': False, - 'properties': {'args': {'items': {'$ref': '#/definitions/ApplicationMergeBindings'}, - 'type': 'array'}}, - 'required': ['args'], - 'type': 'object'}, - 'ApplicationMetricCredential': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'metrics-credentials': {'items': {'type': 'integer'}, - 'type': 'array'}}, - 'required': ['application', - 'metrics-credentials'], - 'type': 'object'}, - 'ApplicationMetricCredentials': {'additionalProperties': False, - 'properties': {'creds': {'items': {'$ref': '#/definitions/ApplicationMetricCredential'}, - 'type': 'array'}}, - 'required': ['creds'], - 'type': 'object'}, - 'ApplicationOfferDetails': {'additionalProperties': False, - 'properties': {'application-description': {'type': 'string'}, - 'bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'endpoints': {'items': {'$ref': '#/definitions/RemoteEndpoint'}, - 'type': 'array'}, - 'offer-name': {'type': 'string'}, - 'offer-url': {'type': 'string'}, - 'offer-uuid': {'type': 'string'}, - 'source-model-tag': {'type': 'string'}, - 'spaces': {'items': {'$ref': '#/definitions/RemoteSpace'}, - 'type': 'array'}, - 'users': {'items': {'$ref': '#/definitions/OfferUserDetails'}, - 'type': 'array'}}, - 'required': ['source-model-tag', - 'offer-uuid', - 'offer-url', - 'offer-name', - 'application-description'], - 'type': 'object'}, - 'ApplicationResult': {'additionalProperties': False, - 'properties': {'base': {'$ref': '#/definitions/Base'}, - 'channel': {'type': 'string'}, - 'charm': {'type': 'string'}, - 'constraints': {'$ref': '#/definitions/Value'}, - 'endpoint-bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'exposed': {'type': 'boolean'}, - 'exposed-endpoints': {'patternProperties': {'.*': {'$ref': '#/definitions/ExposedEndpoint'}}, - 'type': 'object'}, - 'life': {'type': 'string'}, - 'principal': {'type': 'boolean'}, - 'remote': {'type': 'boolean'}, - 'tag': {'type': 'string'}}, - 'required': ['tag', - 'principal', - 'exposed', - 'remote', - 'life'], - 'type': 'object'}, - 'ApplicationSetCharm': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'channel': {'type': 'string'}, - 'charm-origin': {'$ref': '#/definitions/CharmOrigin'}, - 'charm-url': {'type': 'string'}, - 'config-settings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'config-settings-yaml': {'type': 'string'}, - 'endpoint-bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'force': {'type': 'boolean'}, - 'force-base': {'type': 'boolean'}, - 'force-units': {'type': 'boolean'}, - 'generation': {'type': 'string'}, - 'resource-ids': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'storage-constraints': {'patternProperties': {'.*': {'$ref': '#/definitions/StorageConstraints'}}, - 'type': 'object'}}, - 'required': ['application', - 'generation', - 'charm-url', - 'channel', - 'force', - 'force-units', - 'force-base'], - 'type': 'object'}, - 'ApplicationUnexpose': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'exposed-endpoints': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['application', - 'exposed-endpoints'], - 'type': 'object'}, - 'ApplicationUnset': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'branch': {'type': 'string'}, - 'options': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['application', - 'branch', - 'options'], - 'type': 'object'}, - 'ApplicationsDeploy': {'additionalProperties': False, - 'properties': {'applications': {'items': {'$ref': '#/definitions/ApplicationDeploy'}, - 'type': 'array'}}, - 'required': ['applications'], - 'type': 'object'}, - 'Base': {'additionalProperties': False, - 'properties': {'channel': {'type': 'string'}, - 'name': {'type': 'string'}}, - 'required': ['name', 'channel'], - 'type': 'object'}, - 'CharmOrigin': {'additionalProperties': False, - 'properties': {'architecture': {'type': 'string'}, - 'base': {'$ref': '#/definitions/Base'}, - 'branch': {'type': 'string'}, - 'hash': {'type': 'string'}, - 'id': {'type': 'string'}, - 'instance-key': {'type': 'string'}, - 'revision': {'type': 'integer'}, - 'risk': {'type': 'string'}, - 'source': {'type': 'string'}, - 'track': {'type': 'string'}, - 'type': {'type': 'string'}}, - 'required': ['source', 'type', 'id'], - 'type': 'object'}, - 'CharmRelation': {'additionalProperties': False, - 'properties': {'interface': {'type': 'string'}, - 'limit': {'type': 'integer'}, - 'name': {'type': 'string'}, - 'optional': {'type': 'boolean'}, - 'role': {'type': 'string'}, - 'scope': {'type': 'string'}}, - 'required': ['name', - 'role', - 'interface', - 'optional', - 'limit', - 'scope'], - 'type': 'object'}, - 'CharmURLOriginResult': {'additionalProperties': False, - 'properties': {'charm-origin': {'$ref': '#/definitions/CharmOrigin'}, - 'error': {'$ref': '#/definitions/Error'}, - 'url': {'type': 'string'}}, - 'required': ['url', 'charm-origin'], - 'type': 'object'}, - 'ConfigResult': {'additionalProperties': False, - 'properties': {'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'error': {'$ref': '#/definitions/Error'}}, - 'required': ['config'], - 'type': 'object'}, - 'ConfigSet': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'config': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'config-yaml': {'type': 'string'}, - 'generation': {'type': 'string'}}, - 'required': ['application', - 'generation', - 'config', - 'config-yaml'], - 'type': 'object'}, - 'ConfigSetArgs': {'additionalProperties': False, - 'properties': {'Args': {'items': {'$ref': '#/definitions/ConfigSet'}, - 'type': 'array'}}, - 'required': ['Args'], - 'type': 'object'}, - 'Constraints': {'additionalProperties': False, - 'properties': {'Count': {'type': 'integer'}, - 'Pool': {'type': 'string'}, - 'Size': {'type': 'integer'}}, - 'required': ['Pool', 'Size', 'Count'], - 'type': 'object'}, - 'ConsumeApplicationArg': {'additionalProperties': False, - 'properties': {'ApplicationOfferDetails': {'$ref': '#/definitions/ApplicationOfferDetails'}, - 'application-alias': {'type': 'string'}, - 'application-description': {'type': 'string'}, - 'bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'endpoints': {'items': {'$ref': '#/definitions/RemoteEndpoint'}, - 'type': 'array'}, - 'external-controller': {'$ref': '#/definitions/ExternalControllerInfo'}, - 'macaroon': {'$ref': '#/definitions/Macaroon'}, - 'offer-name': {'type': 'string'}, - 'offer-url': {'type': 'string'}, - 'offer-uuid': {'type': 'string'}, - 'source-model-tag': {'type': 'string'}, - 'spaces': {'items': {'$ref': '#/definitions/RemoteSpace'}, - 'type': 'array'}, - 'users': {'items': {'$ref': '#/definitions/OfferUserDetails'}, - 'type': 'array'}}, - 'required': ['source-model-tag', - 'offer-uuid', - 'offer-url', - 'offer-name', - 'application-description', - 'ApplicationOfferDetails'], - 'type': 'object'}, - 'ConsumeApplicationArgs': {'additionalProperties': False, - 'properties': {'args': {'items': {'$ref': '#/definitions/ConsumeApplicationArg'}, - 'type': 'array'}}, - 'type': 'object'}, - 'DestroyApplicationInfo': {'additionalProperties': False, - 'properties': {'destroyed-storage': {'items': {'$ref': '#/definitions/Entity'}, - 'type': 'array'}, - 'destroyed-units': {'items': {'$ref': '#/definitions/Entity'}, - 'type': 'array'}, - 'detached-storage': {'items': {'$ref': '#/definitions/Entity'}, - 'type': 'array'}}, - 'type': 'object'}, - 'DestroyApplicationParams': {'additionalProperties': False, - 'properties': {'application-tag': {'type': 'string'}, - 'destroy-storage': {'type': 'boolean'}, - 'dry-run': {'type': 'boolean'}, - 'force': {'type': 'boolean'}, - 'max-wait': {'type': 'integer'}}, - 'required': ['application-tag', - 'force'], - 'type': 'object'}, - 'DestroyApplicationResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'info': {'$ref': '#/definitions/DestroyApplicationInfo'}}, - 'type': 'object'}, - 'DestroyApplicationResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/DestroyApplicationResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'DestroyApplicationsParams': {'additionalProperties': False, - 'properties': {'applications': {'items': {'$ref': '#/definitions/DestroyApplicationParams'}, - 'type': 'array'}}, - 'required': ['applications'], - 'type': 'object'}, - 'DestroyConsumedApplicationParams': {'additionalProperties': False, - 'properties': {'application-tag': {'type': 'string'}, - 'force': {'type': 'boolean'}, - 'max-wait': {'type': 'integer'}}, - 'required': ['application-tag'], - 'type': 'object'}, - 'DestroyConsumedApplicationsParams': {'additionalProperties': False, - 'properties': {'applications': {'items': {'$ref': '#/definitions/DestroyConsumedApplicationParams'}, - 'type': 'array'}}, - 'required': ['applications'], - 'type': 'object'}, - 'DestroyRelation': {'additionalProperties': False, - 'properties': {'endpoints': {'items': {'type': 'string'}, - 'type': 'array'}, - 'force': {'type': 'boolean'}, - 'max-wait': {'type': 'integer'}, - 'relation-id': {'type': 'integer'}}, - 'required': ['relation-id'], - 'type': 'object'}, - 'DestroyUnitInfo': {'additionalProperties': False, - 'properties': {'destroyed-storage': {'items': {'$ref': '#/definitions/Entity'}, - 'type': 'array'}, - 'detached-storage': {'items': {'$ref': '#/definitions/Entity'}, - 'type': 'array'}}, - 'type': 'object'}, - 'DestroyUnitParams': {'additionalProperties': False, - 'properties': {'destroy-storage': {'type': 'boolean'}, - 'dry-run': {'type': 'boolean'}, - 'force': {'type': 'boolean'}, - 'max-wait': {'type': 'integer'}, - 'unit-tag': {'type': 'string'}}, - 'required': ['unit-tag'], - 'type': 'object'}, - 'DestroyUnitResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'info': {'$ref': '#/definitions/DestroyUnitInfo'}}, - 'type': 'object'}, - 'DestroyUnitResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/DestroyUnitResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'DestroyUnitsParams': {'additionalProperties': False, - 'properties': {'units': {'items': {'$ref': '#/definitions/DestroyUnitParams'}, - 'type': 'array'}}, - 'required': ['units'], - 'type': 'object'}, - 'EndpointRelationData': {'additionalProperties': False, - 'properties': {'ApplicationData': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'cross-model': {'type': 'boolean'}, - 'endpoint': {'type': 'string'}, - 'related-endpoint': {'type': 'string'}, - 'relation-id': {'type': 'integer'}, - 'unit-relation-data': {'patternProperties': {'.*': {'$ref': '#/definitions/RelationData'}}, - 'type': 'object'}}, - 'required': ['relation-id', - 'endpoint', - 'cross-model', - 'related-endpoint', - 'ApplicationData', - 'unit-relation-data'], - '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'}, - 'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - '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'}, - 'ExposedEndpoint': {'additionalProperties': False, - 'properties': {'expose-to-cidrs': {'items': {'type': 'string'}, - 'type': 'array'}, - 'expose-to-spaces': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'ExternalControllerInfo': {'additionalProperties': False, - 'properties': {'addrs': {'items': {'type': 'string'}, - 'type': 'array'}, - 'ca-cert': {'type': 'string'}, - 'controller-alias': {'type': 'string'}, - 'controller-tag': {'type': 'string'}}, - 'required': ['controller-tag', - 'controller-alias', - 'addrs', - 'ca-cert'], - 'type': 'object'}, - 'Macaroon': {'additionalProperties': False, 'type': 'object'}, - 'OfferUserDetails': {'additionalProperties': False, - 'properties': {'access': {'type': 'string'}, - 'display-name': {'type': 'string'}, - 'user': {'type': 'string'}}, - 'required': ['user', - 'display-name', - 'access'], - 'type': 'object'}, - 'Placement': {'additionalProperties': False, - 'properties': {'directive': {'type': 'string'}, - 'scope': {'type': 'string'}}, - 'required': ['scope', 'directive'], - 'type': 'object'}, - 'RelationData': {'additionalProperties': False, - 'properties': {'InScope': {'type': 'boolean'}, - 'UnitData': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}}, - 'required': ['InScope', 'UnitData'], - 'type': 'object'}, - 'RelationSuspendedArg': {'additionalProperties': False, - 'properties': {'message': {'type': 'string'}, - 'relation-id': {'type': 'integer'}, - 'suspended': {'type': 'boolean'}}, - 'required': ['relation-id', - 'message', - 'suspended'], - 'type': 'object'}, - 'RelationSuspendedArgs': {'additionalProperties': False, - 'properties': {'args': {'items': {'$ref': '#/definitions/RelationSuspendedArg'}, - 'type': 'array'}}, - 'required': ['args'], - 'type': 'object'}, - 'RemoteEndpoint': {'additionalProperties': False, - 'properties': {'interface': {'type': 'string'}, - 'limit': {'type': 'integer'}, - 'name': {'type': 'string'}, - 'role': {'type': 'string'}}, - 'required': ['name', - 'role', - 'interface', - 'limit'], - 'type': 'object'}, - 'RemoteSpace': {'additionalProperties': False, - 'properties': {'cloud-type': {'type': 'string'}, - 'name': {'type': 'string'}, - 'provider-attributes': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'provider-id': {'type': 'string'}, - 'subnets': {'items': {'$ref': '#/definitions/Subnet'}, - 'type': 'array'}}, - 'required': ['cloud-type', - 'name', - 'provider-id', - 'provider-attributes', - 'subnets'], - 'type': 'object'}, - 'ScaleApplicationInfo': {'additionalProperties': False, - 'properties': {'num-units': {'type': 'integer'}}, - 'required': ['num-units'], - 'type': 'object'}, - 'ScaleApplicationParams': {'additionalProperties': False, - 'properties': {'application-tag': {'type': 'string'}, - 'force': {'type': 'boolean'}, - 'scale': {'type': 'integer'}, - 'scale-change': {'type': 'integer'}}, - 'required': ['application-tag', - 'scale', - 'force'], - 'type': 'object'}, - 'ScaleApplicationResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'info': {'$ref': '#/definitions/ScaleApplicationInfo'}}, - 'type': 'object'}, - 'ScaleApplicationResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ScaleApplicationResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'ScaleApplicationsParams': {'additionalProperties': False, - 'properties': {'applications': {'items': {'$ref': '#/definitions/ScaleApplicationParams'}, - 'type': 'array'}}, - 'required': ['applications'], - 'type': 'object'}, - 'SetConstraints': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'constraints': {'$ref': '#/definitions/Value'}}, - 'required': ['application', 'constraints'], - 'type': 'object'}, - 'StorageConstraints': {'additionalProperties': False, - 'properties': {'count': {'type': 'integer'}, - 'pool': {'type': 'string'}, - 'size': {'type': 'integer'}}, - 'type': 'object'}, - 'StringResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'type': 'string'}}, - 'required': ['result'], - 'type': 'object'}, - 'Subnet': {'additionalProperties': False, - 'properties': {'cidr': {'type': 'string'}, - 'life': {'type': 'string'}, - 'provider-id': {'type': 'string'}, - 'provider-network-id': {'type': 'string'}, - 'provider-space-id': {'type': 'string'}, - 'space-tag': {'type': 'string'}, - 'status': {'type': 'string'}, - 'vlan-tag': {'type': 'integer'}, - 'zones': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['cidr', - 'vlan-tag', - 'life', - 'space-tag', - 'zones'], - 'type': 'object'}, - 'UnitInfoResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/UnitResult'}}, - 'type': 'object'}, - 'UnitInfoResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/UnitInfoResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'UnitResult': {'additionalProperties': False, - 'properties': {'address': {'type': 'string'}, - 'charm': {'type': 'string'}, - 'leader': {'type': 'boolean'}, - 'life': {'type': 'string'}, - 'machine': {'type': 'string'}, - 'opened-ports': {'items': {'type': 'string'}, - 'type': 'array'}, - 'provider-id': {'type': 'string'}, - 'public-address': {'type': 'string'}, - 'relation-data': {'items': {'$ref': '#/definitions/EndpointRelationData'}, - 'type': 'array'}, - 'tag': {'type': 'string'}, - 'workload-version': {'type': 'string'}}, - 'required': ['tag', - 'workload-version', - 'opened-ports', - 'charm'], - 'type': 'object'}, - 'UnitsResolved': {'additionalProperties': False, - 'properties': {'all': {'type': 'boolean'}, - 'retry': {'type': 'boolean'}, - 'tags': {'$ref': '#/definitions/Entities'}}, - 'type': 'object'}, - 'UpdateChannelArg': {'additionalProperties': False, - 'properties': {'channel': {'type': 'string'}, - 'force': {'type': 'boolean'}, - 'tag': {'$ref': '#/definitions/Entity'}}, - 'required': ['tag', 'force', 'channel'], - 'type': 'object'}, - 'UpdateChannelArgs': {'additionalProperties': False, - 'properties': {'args': {'items': {'$ref': '#/definitions/UpdateChannelArg'}, - 'type': 'array'}}, - 'required': ['args'], - 'type': 'object'}, - 'Value': {'additionalProperties': False, - 'properties': {'allocate-public-ip': {'type': 'boolean'}, - 'arch': {'type': 'string'}, - 'container': {'type': 'string'}, - 'cores': {'type': 'integer'}, - 'cpu-power': {'type': 'integer'}, - 'instance-role': {'type': 'string'}, - 'instance-type': {'type': 'string'}, - 'mem': {'type': 'integer'}, - 'root-disk': {'type': 'integer'}, - 'root-disk-source': {'type': 'string'}, - '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': {'AddRelation': {'description': 'AddRelation adds a relation ' - 'between the specified ' - 'endpoints and returns the ' - 'relation info.', - 'properties': {'Params': {'$ref': '#/definitions/AddRelation'}, - 'Result': {'$ref': '#/definitions/AddRelationResults'}}, - 'type': 'object'}, - 'AddUnits': {'description': 'AddUnits adds a given number of ' - 'units to an application.', - 'properties': {'Params': {'$ref': '#/definitions/AddApplicationUnits'}, - 'Result': {'$ref': '#/definitions/AddApplicationUnitsResults'}}, - 'type': 'object'}, - 'ApplicationsInfo': {'description': 'ApplicationsInfo returns ' - 'applications information.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ApplicationInfoResults'}}, - 'type': 'object'}, - 'CharmConfig': {'description': 'CharmConfig returns charm ' - 'config for the input list of ' - 'applications and\n' - 'model generations.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationGetArgs'}, - 'Result': {'$ref': '#/definitions/ApplicationGetConfigResults'}}, - 'type': 'object'}, - 'CharmRelations': {'description': 'CharmRelations implements ' - 'the server side of ' - 'Application.CharmRelations.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationCharmRelations'}, - 'Result': {'$ref': '#/definitions/ApplicationCharmRelationsResults'}}, - 'type': 'object'}, - 'Consume': {'description': 'Consume adds remote applications ' - 'to the model without creating any\n' - 'relations.', - 'properties': {'Params': {'$ref': '#/definitions/ConsumeApplicationArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'Deploy': {'description': 'Deploy fetches the charms from the ' - 'charm store and deploys them\n' - 'using the specified placement ' - 'directives.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationsDeploy'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'DestroyApplication': {'description': 'DestroyApplication ' - 'removes a given set of ' - 'applications.', - 'properties': {'Params': {'$ref': '#/definitions/DestroyApplicationsParams'}, - 'Result': {'$ref': '#/definitions/DestroyApplicationResults'}}, - 'type': 'object'}, - 'DestroyConsumedApplications': {'description': 'DestroyConsumedApplications ' - 'removes a ' - 'given set of ' - 'consumed ' - '(remote) ' - 'applications.', - 'properties': {'Params': {'$ref': '#/definitions/DestroyConsumedApplicationsParams'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'DestroyRelation': {'description': 'DestroyRelation removes ' - 'the relation between the\n' - 'specified endpoints or an ' - 'id.', - 'properties': {'Params': {'$ref': '#/definitions/DestroyRelation'}}, - 'type': 'object'}, - 'DestroyUnit': {'description': 'DestroyUnit removes a given ' - 'set of application units.', - 'properties': {'Params': {'$ref': '#/definitions/DestroyUnitsParams'}, - 'Result': {'$ref': '#/definitions/DestroyUnitResults'}}, - 'type': 'object'}, - 'Expose': {'description': 'Expose changes the juju-managed ' - 'firewall to expose any ports that\n' - 'were also explicitly marked by ' - 'units as open.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationExpose'}}, - 'type': 'object'}, - 'Get': {'description': 'Get returns the charm configuration ' - 'for an application.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationGet'}, - 'Result': {'$ref': '#/definitions/ApplicationGetResults'}}, - 'type': 'object'}, - 'GetCharmURLOrigin': {'description': 'GetCharmURLOrigin ' - 'returns the charm URL ' - 'and charm origin the ' - 'given\n' - 'application is running ' - 'at present.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationGet'}, - 'Result': {'$ref': '#/definitions/CharmURLOriginResult'}}, - 'type': 'object'}, - 'GetConfig': {'description': 'GetConfig returns the charm ' - 'config for each of the input ' - 'applications.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ApplicationGetConfigResults'}}, - 'type': 'object'}, - 'GetConstraints': {'description': 'GetConstraints returns the ' - 'constraints for a given ' - 'application.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ApplicationGetConstraintsResults'}}, - 'type': 'object'}, - 'Leader': {'description': 'Leader returns the unit name of the ' - 'leader for the given application.', - 'properties': {'Params': {'$ref': '#/definitions/Entity'}, - 'Result': {'$ref': '#/definitions/StringResult'}}, - 'type': 'object'}, - 'MergeBindings': {'description': 'MergeBindings merges ' - 'operator-defined bindings ' - 'with the current bindings ' - 'for\n' - 'one or more applications.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationMergeBindingsArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'ResolveUnitErrors': {'description': 'ResolveUnitErrors marks ' - 'errors on the specified ' - 'units as resolved.', - 'properties': {'Params': {'$ref': '#/definitions/UnitsResolved'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'ScaleApplications': {'description': 'ScaleApplications scales ' - 'the specified ' - 'application to the ' - 'requested number of ' - 'units.', - 'properties': {'Params': {'$ref': '#/definitions/ScaleApplicationsParams'}, - 'Result': {'$ref': '#/definitions/ScaleApplicationResults'}}, - 'type': 'object'}, - 'SetCharm': {'description': 'SetCharm sets the charm for a ' - 'given for the application.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationSetCharm'}}, - 'type': 'object'}, - 'SetConfigs': {'description': 'SetConfigs implements the ' - 'server side of ' - 'Application.SetConfig. Both\n' - 'application and charm config ' - 'are set. It does not unset ' - 'values in\n' - 'Config map that are set to an ' - 'empty string. Unset should be ' - 'used for that.', - 'properties': {'Params': {'$ref': '#/definitions/ConfigSetArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'SetConstraints': {'description': 'SetConstraints sets the ' - 'constraints for a given ' - 'application.', - 'properties': {'Params': {'$ref': '#/definitions/SetConstraints'}}, - 'type': 'object'}, - 'SetMetricCredentials': {'description': 'SetMetricCredentials ' - 'sets credentials on ' - 'the application.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationMetricCredentials'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'SetRelationsSuspended': {'description': 'SetRelationsSuspended ' - 'sets the suspended ' - 'status of the ' - 'specified relations.', - 'properties': {'Params': {'$ref': '#/definitions/RelationSuspendedArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'Unexpose': {'description': 'Unexpose changes the juju-managed ' - 'firewall to unexpose any ports ' - 'that\n' - 'were also explicitly marked by ' - 'units as open.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationUnexpose'}}, - 'type': 'object'}, - 'UnitsInfo': {'description': 'UnitsInfo returns unit ' - 'information for the given ' - 'entities (units or\n' - 'applications).', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/UnitInfoResults'}}, - 'type': 'object'}, - 'UnsetApplicationsConfig': {'description': 'UnsetApplicationsConfig ' - 'implements the ' - 'server side of ' - 'Application.UnsetApplicationsConfig.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationConfigUnsetArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'UpdateApplicationBase': {'description': 'UpdateApplicationBase ' - 'updates the ' - 'application base.\n' - 'Base for ' - 'subordinates is ' - 'updated too.', - 'properties': {'Params': {'$ref': '#/definitions/UpdateChannelArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "AddApplicationUnits": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "attach-storage": {"items": {"type": "string"}, "type": "array"}, + "num-units": {"type": "integer"}, + "placement": { + "items": {"$ref": "#/definitions/Placement"}, + "type": "array", + }, + "policy": {"type": "string"}, + }, + "required": ["application", "num-units", "placement"], + "type": "object", + }, + "AddApplicationUnitsResults": { + "additionalProperties": False, + "properties": {"units": {"items": {"type": "string"}, "type": "array"}}, + "required": ["units"], + "type": "object", + }, + "AddRelation": { + "additionalProperties": False, + "properties": { + "endpoints": {"items": {"type": "string"}, "type": "array"}, + "via-cidrs": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["endpoints"], + "type": "object", + }, + "AddRelationResults": { + "additionalProperties": False, + "properties": { + "endpoints": { + "patternProperties": { + ".*": {"$ref": "#/definitions/CharmRelation"} + }, + "type": "object", + } + }, + "required": ["endpoints"], + "type": "object", + }, + "ApplicationCharmRelations": { + "additionalProperties": False, + "properties": {"application": {"type": "string"}}, + "required": ["application"], + "type": "object", + }, + "ApplicationCharmRelationsResults": { + "additionalProperties": False, + "properties": { + "charm-relations": {"items": {"type": "string"}, "type": "array"} + }, + "required": ["charm-relations"], + "type": "object", + }, + "ApplicationConfigUnsetArgs": { + "additionalProperties": False, + "properties": { + "Args": { + "items": {"$ref": "#/definitions/ApplicationUnset"}, + "type": "array", + } + }, + "required": ["Args"], + "type": "object", + }, + "ApplicationConstraint": { + "additionalProperties": False, + "properties": { + "constraints": {"$ref": "#/definitions/Value"}, + "error": {"$ref": "#/definitions/Error"}, + }, + "required": ["constraints"], + "type": "object", + }, + "ApplicationDeploy": { + "additionalProperties": False, + "properties": { + "Force": {"type": "boolean"}, + "application": {"type": "string"}, + "attach-storage": {"items": {"type": "string"}, "type": "array"}, + "channel": {"type": "string"}, + "charm-origin": {"$ref": "#/definitions/CharmOrigin"}, + "charm-url": {"type": "string"}, + "config": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "config-yaml": {"type": "string"}, + "constraints": {"$ref": "#/definitions/Value"}, + "devices": { + "patternProperties": { + ".*": {"$ref": "#/definitions/Constraints"} + }, + "type": "object", + }, + "endpoint-bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "num-units": {"type": "integer"}, + "placement": { + "items": {"$ref": "#/definitions/Placement"}, + "type": "array", + }, + "policy": {"type": "string"}, + "resources": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "storage": { + "patternProperties": { + ".*": {"$ref": "#/definitions/Constraints"} + }, + "type": "object", + }, + }, + "required": [ + "application", + "charm-url", + "channel", + "num-units", + "config-yaml", + "constraints", + "Force", + ], + "type": "object", + }, + "ApplicationExpose": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "exposed-endpoints": { + "patternProperties": { + ".*": {"$ref": "#/definitions/ExposedEndpoint"} + }, + "type": "object", + }, + }, + "required": ["application"], + "type": "object", + }, + "ApplicationGet": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "branch": {"type": "string"}, + }, + "required": ["application", "branch"], + "type": "object", + }, + "ApplicationGetArgs": { + "additionalProperties": False, + "properties": { + "args": { + "items": {"$ref": "#/definitions/ApplicationGet"}, + "type": "array", + } + }, + "required": ["args"], + "type": "object", + }, + "ApplicationGetConfigResults": { + "additionalProperties": False, + "properties": { + "Results": { + "items": {"$ref": "#/definitions/ConfigResult"}, + "type": "array", + } + }, + "required": ["Results"], + "type": "object", + }, + "ApplicationGetConstraintsResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ApplicationConstraint"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "ApplicationGetResults": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "application-config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "base": {"$ref": "#/definitions/Base"}, + "channel": {"type": "string"}, + "charm": {"type": "string"}, + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "constraints": {"$ref": "#/definitions/Value"}, + "endpoint-bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + }, + "required": [ + "application", + "charm", + "config", + "constraints", + "base", + "channel", + ], + "type": "object", + }, + "ApplicationInfoResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/ApplicationResult"}, + }, + "type": "object", + }, + "ApplicationInfoResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ApplicationInfoResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "ApplicationMergeBindings": { + "additionalProperties": False, + "properties": { + "application-tag": {"type": "string"}, + "bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "force": {"type": "boolean"}, + }, + "required": ["application-tag", "bindings", "force"], + "type": "object", + }, + "ApplicationMergeBindingsArgs": { + "additionalProperties": False, + "properties": { + "args": { + "items": {"$ref": "#/definitions/ApplicationMergeBindings"}, + "type": "array", + } + }, + "required": ["args"], + "type": "object", + }, + "ApplicationMetricCredential": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "metrics-credentials": { + "items": {"type": "integer"}, + "type": "array", + }, + }, + "required": ["application", "metrics-credentials"], + "type": "object", + }, + "ApplicationMetricCredentials": { + "additionalProperties": False, + "properties": { + "creds": { + "items": {"$ref": "#/definitions/ApplicationMetricCredential"}, + "type": "array", + } + }, + "required": ["creds"], + "type": "object", + }, + "ApplicationOfferDetails": { + "additionalProperties": False, + "properties": { + "application-description": {"type": "string"}, + "bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "endpoints": { + "items": {"$ref": "#/definitions/RemoteEndpoint"}, + "type": "array", + }, + "offer-name": {"type": "string"}, + "offer-url": {"type": "string"}, + "offer-uuid": {"type": "string"}, + "source-model-tag": {"type": "string"}, + "spaces": { + "items": {"$ref": "#/definitions/RemoteSpace"}, + "type": "array", + }, + "users": { + "items": {"$ref": "#/definitions/OfferUserDetails"}, + "type": "array", + }, + }, + "required": [ + "source-model-tag", + "offer-uuid", + "offer-url", + "offer-name", + "application-description", + ], + "type": "object", + }, + "ApplicationResult": { + "additionalProperties": False, + "properties": { + "base": {"$ref": "#/definitions/Base"}, + "channel": {"type": "string"}, + "charm": {"type": "string"}, + "constraints": {"$ref": "#/definitions/Value"}, + "endpoint-bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "exposed": {"type": "boolean"}, + "exposed-endpoints": { + "patternProperties": { + ".*": {"$ref": "#/definitions/ExposedEndpoint"} + }, + "type": "object", + }, + "life": {"type": "string"}, + "principal": {"type": "boolean"}, + "remote": {"type": "boolean"}, + "tag": {"type": "string"}, + }, + "required": ["tag", "principal", "exposed", "remote", "life"], + "type": "object", + }, + "ApplicationSetCharm": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "channel": {"type": "string"}, + "charm-origin": {"$ref": "#/definitions/CharmOrigin"}, + "charm-url": {"type": "string"}, + "config-settings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "config-settings-yaml": {"type": "string"}, + "endpoint-bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "force": {"type": "boolean"}, + "force-base": {"type": "boolean"}, + "force-units": {"type": "boolean"}, + "generation": {"type": "string"}, + "resource-ids": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "storage-constraints": { + "patternProperties": { + ".*": {"$ref": "#/definitions/StorageConstraints"} + }, + "type": "object", + }, + }, + "required": [ + "application", + "generation", + "charm-url", + "channel", + "force", + "force-units", + "force-base", + ], + "type": "object", + }, + "ApplicationUnexpose": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "exposed-endpoints": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["application", "exposed-endpoints"], + "type": "object", + }, + "ApplicationUnset": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "branch": {"type": "string"}, + "options": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["application", "branch", "options"], + "type": "object", + }, + "ApplicationsDeploy": { + "additionalProperties": False, + "properties": { + "applications": { + "items": {"$ref": "#/definitions/ApplicationDeploy"}, + "type": "array", + } + }, + "required": ["applications"], + "type": "object", + }, + "Base": { + "additionalProperties": False, + "properties": { + "channel": {"type": "string"}, + "name": {"type": "string"}, + }, + "required": ["name", "channel"], + "type": "object", + }, + "CharmOrigin": { + "additionalProperties": False, + "properties": { + "architecture": {"type": "string"}, + "base": {"$ref": "#/definitions/Base"}, + "branch": {"type": "string"}, + "hash": {"type": "string"}, + "id": {"type": "string"}, + "instance-key": {"type": "string"}, + "revision": {"type": "integer"}, + "risk": {"type": "string"}, + "source": {"type": "string"}, + "track": {"type": "string"}, + "type": {"type": "string"}, + }, + "required": ["source", "type", "id"], + "type": "object", + }, + "CharmRelation": { + "additionalProperties": False, + "properties": { + "interface": {"type": "string"}, + "limit": {"type": "integer"}, + "name": {"type": "string"}, + "optional": {"type": "boolean"}, + "role": {"type": "string"}, + "scope": {"type": "string"}, + }, + "required": ["name", "role", "interface", "optional", "limit", "scope"], + "type": "object", + }, + "CharmURLOriginResult": { + "additionalProperties": False, + "properties": { + "charm-origin": {"$ref": "#/definitions/CharmOrigin"}, + "error": {"$ref": "#/definitions/Error"}, + "url": {"type": "string"}, + }, + "required": ["url", "charm-origin"], + "type": "object", + }, + "ConfigResult": { + "additionalProperties": False, + "properties": { + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "error": {"$ref": "#/definitions/Error"}, + }, + "required": ["config"], + "type": "object", + }, + "ConfigSet": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "config": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "config-yaml": {"type": "string"}, + "generation": {"type": "string"}, + }, + "required": ["application", "generation", "config", "config-yaml"], + "type": "object", + }, + "ConfigSetArgs": { + "additionalProperties": False, + "properties": { + "Args": { + "items": {"$ref": "#/definitions/ConfigSet"}, + "type": "array", + } + }, + "required": ["Args"], + "type": "object", + }, + "Constraints": { + "additionalProperties": False, + "properties": { + "Count": {"type": "integer"}, + "Pool": {"type": "string"}, + "Size": {"type": "integer"}, + }, + "required": ["Pool", "Size", "Count"], + "type": "object", + }, + "ConsumeApplicationArg": { + "additionalProperties": False, + "properties": { + "ApplicationOfferDetails": { + "$ref": "#/definitions/ApplicationOfferDetails" + }, + "application-alias": {"type": "string"}, + "application-description": {"type": "string"}, + "bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "endpoints": { + "items": {"$ref": "#/definitions/RemoteEndpoint"}, + "type": "array", + }, + "external-controller": { + "$ref": "#/definitions/ExternalControllerInfo" + }, + "macaroon": {"$ref": "#/definitions/Macaroon"}, + "offer-name": {"type": "string"}, + "offer-url": {"type": "string"}, + "offer-uuid": {"type": "string"}, + "source-model-tag": {"type": "string"}, + "spaces": { + "items": {"$ref": "#/definitions/RemoteSpace"}, + "type": "array", + }, + "users": { + "items": {"$ref": "#/definitions/OfferUserDetails"}, + "type": "array", + }, + }, + "required": [ + "source-model-tag", + "offer-uuid", + "offer-url", + "offer-name", + "application-description", + "ApplicationOfferDetails", + ], + "type": "object", + }, + "ConsumeApplicationArgs": { + "additionalProperties": False, + "properties": { + "args": { + "items": {"$ref": "#/definitions/ConsumeApplicationArg"}, + "type": "array", + } + }, + "type": "object", + }, + "DestroyApplicationInfo": { + "additionalProperties": False, + "properties": { + "destroyed-storage": { + "items": {"$ref": "#/definitions/Entity"}, + "type": "array", + }, + "destroyed-units": { + "items": {"$ref": "#/definitions/Entity"}, + "type": "array", + }, + "detached-storage": { + "items": {"$ref": "#/definitions/Entity"}, + "type": "array", + }, + }, + "type": "object", + }, + "DestroyApplicationParams": { + "additionalProperties": False, + "properties": { + "application-tag": {"type": "string"}, + "destroy-storage": {"type": "boolean"}, + "dry-run": {"type": "boolean"}, + "force": {"type": "boolean"}, + "max-wait": {"type": "integer"}, + }, + "required": ["application-tag", "force"], + "type": "object", + }, + "DestroyApplicationResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "info": {"$ref": "#/definitions/DestroyApplicationInfo"}, + }, + "type": "object", + }, + "DestroyApplicationResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/DestroyApplicationResult"}, + "type": "array", + } + }, + "type": "object", + }, + "DestroyApplicationsParams": { + "additionalProperties": False, + "properties": { + "applications": { + "items": {"$ref": "#/definitions/DestroyApplicationParams"}, + "type": "array", + } + }, + "required": ["applications"], + "type": "object", + }, + "DestroyConsumedApplicationParams": { + "additionalProperties": False, + "properties": { + "application-tag": {"type": "string"}, + "force": {"type": "boolean"}, + "max-wait": {"type": "integer"}, + }, + "required": ["application-tag"], + "type": "object", + }, + "DestroyConsumedApplicationsParams": { + "additionalProperties": False, + "properties": { + "applications": { + "items": { + "$ref": "#/definitions/DestroyConsumedApplicationParams" + }, + "type": "array", + } + }, + "required": ["applications"], + "type": "object", + }, + "DestroyRelation": { + "additionalProperties": False, + "properties": { + "endpoints": {"items": {"type": "string"}, "type": "array"}, + "force": {"type": "boolean"}, + "max-wait": {"type": "integer"}, + "relation-id": {"type": "integer"}, + }, + "required": ["relation-id"], + "type": "object", + }, + "DestroyUnitInfo": { + "additionalProperties": False, + "properties": { + "destroyed-storage": { + "items": {"$ref": "#/definitions/Entity"}, + "type": "array", + }, + "detached-storage": { + "items": {"$ref": "#/definitions/Entity"}, + "type": "array", + }, + }, + "type": "object", + }, + "DestroyUnitParams": { + "additionalProperties": False, + "properties": { + "destroy-storage": {"type": "boolean"}, + "dry-run": {"type": "boolean"}, + "force": {"type": "boolean"}, + "max-wait": {"type": "integer"}, + "unit-tag": {"type": "string"}, + }, + "required": ["unit-tag"], + "type": "object", + }, + "DestroyUnitResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "info": {"$ref": "#/definitions/DestroyUnitInfo"}, + }, + "type": "object", + }, + "DestroyUnitResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/DestroyUnitResult"}, + "type": "array", + } + }, + "type": "object", + }, + "DestroyUnitsParams": { + "additionalProperties": False, + "properties": { + "units": { + "items": {"$ref": "#/definitions/DestroyUnitParams"}, + "type": "array", + } + }, + "required": ["units"], + "type": "object", + }, + "EndpointRelationData": { + "additionalProperties": False, + "properties": { + "ApplicationData": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "cross-model": {"type": "boolean"}, + "endpoint": {"type": "string"}, + "related-endpoint": {"type": "string"}, + "relation-id": {"type": "integer"}, + "unit-relation-data": { + "patternProperties": { + ".*": {"$ref": "#/definitions/RelationData"} + }, + "type": "object", + }, + }, + "required": [ + "relation-id", + "endpoint", + "cross-model", + "related-endpoint", + "ApplicationData", + "unit-relation-data", + ], + "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", + }, + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "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", + }, + "ExposedEndpoint": { + "additionalProperties": False, + "properties": { + "expose-to-cidrs": {"items": {"type": "string"}, "type": "array"}, + "expose-to-spaces": {"items": {"type": "string"}, "type": "array"}, + }, + "type": "object", + }, + "ExternalControllerInfo": { + "additionalProperties": False, + "properties": { + "addrs": {"items": {"type": "string"}, "type": "array"}, + "ca-cert": {"type": "string"}, + "controller-alias": {"type": "string"}, + "controller-tag": {"type": "string"}, + }, + "required": ["controller-tag", "controller-alias", "addrs", "ca-cert"], + "type": "object", + }, + "Macaroon": {"additionalProperties": False, "type": "object"}, + "OfferUserDetails": { + "additionalProperties": False, + "properties": { + "access": {"type": "string"}, + "display-name": {"type": "string"}, + "user": {"type": "string"}, + }, + "required": ["user", "display-name", "access"], + "type": "object", + }, + "Placement": { + "additionalProperties": False, + "properties": { + "directive": {"type": "string"}, + "scope": {"type": "string"}, + }, + "required": ["scope", "directive"], + "type": "object", + }, + "RelationData": { + "additionalProperties": False, + "properties": { + "InScope": {"type": "boolean"}, + "UnitData": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + }, + "required": ["InScope", "UnitData"], + "type": "object", + }, + "RelationSuspendedArg": { + "additionalProperties": False, + "properties": { + "message": {"type": "string"}, + "relation-id": {"type": "integer"}, + "suspended": {"type": "boolean"}, + }, + "required": ["relation-id", "message", "suspended"], + "type": "object", + }, + "RelationSuspendedArgs": { + "additionalProperties": False, + "properties": { + "args": { + "items": {"$ref": "#/definitions/RelationSuspendedArg"}, + "type": "array", + } + }, + "required": ["args"], + "type": "object", + }, + "RemoteEndpoint": { + "additionalProperties": False, + "properties": { + "interface": {"type": "string"}, + "limit": {"type": "integer"}, + "name": {"type": "string"}, + "role": {"type": "string"}, + }, + "required": ["name", "role", "interface", "limit"], + "type": "object", + }, + "RemoteSpace": { + "additionalProperties": False, + "properties": { + "cloud-type": {"type": "string"}, + "name": {"type": "string"}, + "provider-attributes": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "provider-id": {"type": "string"}, + "subnets": { + "items": {"$ref": "#/definitions/Subnet"}, + "type": "array", + }, + }, + "required": [ + "cloud-type", + "name", + "provider-id", + "provider-attributes", + "subnets", + ], + "type": "object", + }, + "ScaleApplicationInfo": { + "additionalProperties": False, + "properties": {"num-units": {"type": "integer"}}, + "required": ["num-units"], + "type": "object", + }, + "ScaleApplicationParams": { + "additionalProperties": False, + "properties": { + "application-tag": {"type": "string"}, + "force": {"type": "boolean"}, + "scale": {"type": "integer"}, + "scale-change": {"type": "integer"}, + }, + "required": ["application-tag", "scale", "force"], + "type": "object", + }, + "ScaleApplicationResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "info": {"$ref": "#/definitions/ScaleApplicationInfo"}, + }, + "type": "object", + }, + "ScaleApplicationResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ScaleApplicationResult"}, + "type": "array", + } + }, + "type": "object", + }, + "ScaleApplicationsParams": { + "additionalProperties": False, + "properties": { + "applications": { + "items": {"$ref": "#/definitions/ScaleApplicationParams"}, + "type": "array", + } + }, + "required": ["applications"], + "type": "object", + }, + "SetConstraints": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "constraints": {"$ref": "#/definitions/Value"}, + }, + "required": ["application", "constraints"], + "type": "object", + }, + "StorageConstraints": { + "additionalProperties": False, + "properties": { + "count": {"type": "integer"}, + "pool": {"type": "string"}, + "size": {"type": "integer"}, + }, + "type": "object", + }, + "StringResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"type": "string"}, + }, + "required": ["result"], + "type": "object", + }, + "Subnet": { + "additionalProperties": False, + "properties": { + "cidr": {"type": "string"}, + "life": {"type": "string"}, + "provider-id": {"type": "string"}, + "provider-network-id": {"type": "string"}, + "provider-space-id": {"type": "string"}, + "space-tag": {"type": "string"}, + "status": {"type": "string"}, + "vlan-tag": {"type": "integer"}, + "zones": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["cidr", "vlan-tag", "life", "space-tag", "zones"], + "type": "object", + }, + "UnitInfoResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/UnitResult"}, + }, + "type": "object", + }, + "UnitInfoResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/UnitInfoResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "UnitResult": { + "additionalProperties": False, + "properties": { + "address": {"type": "string"}, + "charm": {"type": "string"}, + "leader": {"type": "boolean"}, + "life": {"type": "string"}, + "machine": {"type": "string"}, + "opened-ports": {"items": {"type": "string"}, "type": "array"}, + "provider-id": {"type": "string"}, + "public-address": {"type": "string"}, + "relation-data": { + "items": {"$ref": "#/definitions/EndpointRelationData"}, + "type": "array", + }, + "tag": {"type": "string"}, + "workload-version": {"type": "string"}, + }, + "required": ["tag", "workload-version", "opened-ports", "charm"], + "type": "object", + }, + "UnitsResolved": { + "additionalProperties": False, + "properties": { + "all": {"type": "boolean"}, + "retry": {"type": "boolean"}, + "tags": {"$ref": "#/definitions/Entities"}, + }, + "type": "object", + }, + "UpdateChannelArg": { + "additionalProperties": False, + "properties": { + "channel": {"type": "string"}, + "force": {"type": "boolean"}, + "tag": {"$ref": "#/definitions/Entity"}, + }, + "required": ["tag", "force", "channel"], + "type": "object", + }, + "UpdateChannelArgs": { + "additionalProperties": False, + "properties": { + "args": { + "items": {"$ref": "#/definitions/UpdateChannelArg"}, + "type": "array", + } + }, + "required": ["args"], + "type": "object", + }, + "Value": { + "additionalProperties": False, + "properties": { + "allocate-public-ip": {"type": "boolean"}, + "arch": {"type": "string"}, + "container": {"type": "string"}, + "cores": {"type": "integer"}, + "cpu-power": {"type": "integer"}, + "instance-role": {"type": "string"}, + "instance-type": {"type": "string"}, + "mem": {"type": "integer"}, + "root-disk": {"type": "integer"}, + "root-disk-source": {"type": "string"}, + "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": { + "AddRelation": { + "description": "AddRelation adds a relation " + "between the specified " + "endpoints and returns the " + "relation info.", + "properties": { + "Params": {"$ref": "#/definitions/AddRelation"}, + "Result": {"$ref": "#/definitions/AddRelationResults"}, + }, + "type": "object", + }, + "AddUnits": { + "description": "AddUnits adds a given number of " + "units to an application.", + "properties": { + "Params": {"$ref": "#/definitions/AddApplicationUnits"}, + "Result": {"$ref": "#/definitions/AddApplicationUnitsResults"}, + }, + "type": "object", + }, + "ApplicationsInfo": { + "description": "ApplicationsInfo returns applications information.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/ApplicationInfoResults"}, + }, + "type": "object", + }, + "CharmConfig": { + "description": "CharmConfig returns charm " + "config for the input list of " + "applications and\n" + "model generations.", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationGetArgs"}, + "Result": {"$ref": "#/definitions/ApplicationGetConfigResults"}, + }, + "type": "object", + }, + "CharmRelations": { + "description": "CharmRelations implements " + "the server side of " + "Application.CharmRelations.", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationCharmRelations"}, + "Result": { + "$ref": "#/definitions/ApplicationCharmRelationsResults" + }, + }, + "type": "object", + }, + "Consume": { + "description": "Consume adds remote applications " + "to the model without creating any\n" + "relations.", + "properties": { + "Params": {"$ref": "#/definitions/ConsumeApplicationArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "Deploy": { + "description": "Deploy fetches the charms from the " + "charm store and deploys them\n" + "using the specified placement " + "directives.", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationsDeploy"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "DestroyApplication": { + "description": "DestroyApplication " + "removes a given set of " + "applications.", + "properties": { + "Params": {"$ref": "#/definitions/DestroyApplicationsParams"}, + "Result": {"$ref": "#/definitions/DestroyApplicationResults"}, + }, + "type": "object", + }, + "DestroyConsumedApplications": { + "description": "DestroyConsumedApplications " + "removes a " + "given set of " + "consumed " + "(remote) " + "applications.", + "properties": { + "Params": { + "$ref": "#/definitions/DestroyConsumedApplicationsParams" + }, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "DestroyRelation": { + "description": "DestroyRelation removes " + "the relation between the\n" + "specified endpoints or an " + "id.", + "properties": {"Params": {"$ref": "#/definitions/DestroyRelation"}}, + "type": "object", + }, + "DestroyUnit": { + "description": "DestroyUnit removes a given set of application units.", + "properties": { + "Params": {"$ref": "#/definitions/DestroyUnitsParams"}, + "Result": {"$ref": "#/definitions/DestroyUnitResults"}, + }, + "type": "object", + }, + "Expose": { + "description": "Expose changes the juju-managed " + "firewall to expose any ports that\n" + "were also explicitly marked by " + "units as open.", + "properties": {"Params": {"$ref": "#/definitions/ApplicationExpose"}}, + "type": "object", + }, + "Get": { + "description": "Get returns the charm configuration " + "for an application.", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationGet"}, + "Result": {"$ref": "#/definitions/ApplicationGetResults"}, + }, + "type": "object", + }, + "GetCharmURLOrigin": { + "description": "GetCharmURLOrigin " + "returns the charm URL " + "and charm origin the " + "given\n" + "application is running " + "at present.", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationGet"}, + "Result": {"$ref": "#/definitions/CharmURLOriginResult"}, + }, + "type": "object", + }, + "GetConfig": { + "description": "GetConfig returns the charm " + "config for each of the input " + "applications.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/ApplicationGetConfigResults"}, + }, + "type": "object", + }, + "GetConstraints": { + "description": "GetConstraints returns the " + "constraints for a given " + "application.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": { + "$ref": "#/definitions/ApplicationGetConstraintsResults" + }, + }, + "type": "object", + }, + "Leader": { + "description": "Leader returns the unit name of the " + "leader for the given application.", + "properties": { + "Params": {"$ref": "#/definitions/Entity"}, + "Result": {"$ref": "#/definitions/StringResult"}, + }, + "type": "object", + }, + "MergeBindings": { + "description": "MergeBindings merges " + "operator-defined bindings " + "with the current bindings " + "for\n" + "one or more applications.", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationMergeBindingsArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "ResolveUnitErrors": { + "description": "ResolveUnitErrors marks " + "errors on the specified " + "units as resolved.", + "properties": { + "Params": {"$ref": "#/definitions/UnitsResolved"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "ScaleApplications": { + "description": "ScaleApplications scales " + "the specified " + "application to the " + "requested number of " + "units.", + "properties": { + "Params": {"$ref": "#/definitions/ScaleApplicationsParams"}, + "Result": {"$ref": "#/definitions/ScaleApplicationResults"}, + }, + "type": "object", + }, + "SetCharm": { + "description": "SetCharm sets the charm for a " + "given for the application.", + "properties": {"Params": {"$ref": "#/definitions/ApplicationSetCharm"}}, + "type": "object", + }, + "SetConfigs": { + "description": "SetConfigs implements the " + "server side of " + "Application.SetConfig. Both\n" + "application and charm config " + "are set. It does not unset " + "values in\n" + "Config map that are set to an " + "empty string. Unset should be " + "used for that.", + "properties": { + "Params": {"$ref": "#/definitions/ConfigSetArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "SetConstraints": { + "description": "SetConstraints sets the " + "constraints for a given " + "application.", + "properties": {"Params": {"$ref": "#/definitions/SetConstraints"}}, + "type": "object", + }, + "SetMetricCredentials": { + "description": "SetMetricCredentials " + "sets credentials on " + "the application.", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationMetricCredentials"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "SetRelationsSuspended": { + "description": "SetRelationsSuspended " + "sets the suspended " + "status of the " + "specified relations.", + "properties": { + "Params": {"$ref": "#/definitions/RelationSuspendedArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "Unexpose": { + "description": "Unexpose changes the juju-managed " + "firewall to unexpose any ports " + "that\n" + "were also explicitly marked by " + "units as open.", + "properties": {"Params": {"$ref": "#/definitions/ApplicationUnexpose"}}, + "type": "object", + }, + "UnitsInfo": { + "description": "UnitsInfo returns unit " + "information for the given " + "entities (units or\n" + "applications).", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/UnitInfoResults"}, + }, + "type": "object", + }, + "UnsetApplicationsConfig": { + "description": "UnsetApplicationsConfig " + "implements the " + "server side of " + "Application.UnsetApplicationsConfig.", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationConfigUnsetArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "UpdateApplicationBase": { + "description": "UpdateApplicationBase " + "updates the " + "application base.\n" + "Base for " + "subordinates is " + "updated too.", + "properties": { + "Params": {"$ref": "#/definitions/UpdateChannelArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(AddRelationResults) async def AddRelation(self, endpoints=None, via_cidrs=None): - ''' + """ AddRelation adds a relation between the specified endpoints and returns the relation info. endpoints : typing.Sequence[str] via_cidrs : typing.Sequence[str] Returns -> AddRelationResults - ''' + """ if endpoints is not None and not isinstance(endpoints, (bytes, str, list)): - raise Exception("Expected endpoints to be a Sequence, received: {}".format(type(endpoints))) + raise Exception( + "Expected endpoints to be a Sequence, received: {}".format( + type(endpoints) + ) + ) if via_cidrs is not None and not isinstance(via_cidrs, (bytes, str, list)): - raise Exception("Expected via_cidrs to be a Sequence, received: {}".format(type(via_cidrs))) + raise Exception( + "Expected via_cidrs to be a Sequence, received: {}".format( + type(via_cidrs) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='AddRelation', - version=17, - params=_params) - _params['endpoints'] = endpoints - _params['via-cidrs'] = via_cidrs + msg = dict( + type="Application", request="AddRelation", version=17, params=_params + ) + _params["endpoints"] = endpoints + _params["via-cidrs"] = via_cidrs reply = await self.rpc(msg) return reply - - @ReturnMapping(AddApplicationUnitsResults) - async def AddUnits(self, application=None, attach_storage=None, num_units=None, placement=None, policy=None): - ''' + async def AddUnits( + self, + application=None, + attach_storage=None, + num_units=None, + placement=None, + policy=None, + ): + """ AddUnits adds a given number of units to an application. application : str @@ -903,205 +1456,228 @@ async def AddUnits(self, application=None, attach_storage=None, num_units=None, placement : typing.Sequence[~Placement] policy : str Returns -> AddApplicationUnitsResults - ''' + """ if application is not None and not isinstance(application, (bytes, str)): - raise Exception("Expected application to be a str, received: {}".format(type(application))) - - if attach_storage is not None and not isinstance(attach_storage, (bytes, str, list)): - raise Exception("Expected attach_storage to be a Sequence, received: {}".format(type(attach_storage))) + raise Exception( + "Expected application to be a str, received: {}".format( + type(application) + ) + ) + + if attach_storage is not None and not isinstance( + attach_storage, (bytes, str, list) + ): + raise Exception( + "Expected attach_storage to be a Sequence, received: {}".format( + type(attach_storage) + ) + ) if num_units is not None and not isinstance(num_units, int): - raise Exception("Expected num_units to be a int, received: {}".format(type(num_units))) + raise Exception( + "Expected num_units to be a int, received: {}".format(type(num_units)) + ) if placement is not None and not isinstance(placement, (bytes, str, list)): - raise Exception("Expected placement to be a Sequence, received: {}".format(type(placement))) + raise Exception( + "Expected placement to be a Sequence, received: {}".format( + type(placement) + ) + ) if policy is not None and not isinstance(policy, (bytes, str)): - raise Exception("Expected policy to be a str, received: {}".format(type(policy))) + raise Exception( + "Expected policy to be a str, received: {}".format(type(policy)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='AddUnits', - version=17, - params=_params) - _params['application'] = application - _params['attach-storage'] = attach_storage - _params['num-units'] = num_units - _params['placement'] = placement - _params['policy'] = policy + msg = dict(type="Application", request="AddUnits", version=17, params=_params) + _params["application"] = application + _params["attach-storage"] = attach_storage + _params["num-units"] = num_units + _params["placement"] = placement + _params["policy"] = policy reply = await self.rpc(msg) return reply - - @ReturnMapping(ApplicationInfoResults) async def ApplicationsInfo(self, entities=None): - ''' + """ ApplicationsInfo returns applications information. entities : typing.Sequence[~Entity] Returns -> ApplicationInfoResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='ApplicationsInfo', - version=17, - params=_params) - _params['entities'] = entities + msg = dict( + type="Application", request="ApplicationsInfo", version=17, params=_params + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ApplicationGetConfigResults) async def CharmConfig(self, args=None): - ''' + """ CharmConfig returns charm config for the input list of applications and model generations. args : typing.Sequence[~ApplicationGet] Returns -> ApplicationGetConfigResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='CharmConfig', - version=17, - params=_params) - _params['args'] = args + msg = dict( + type="Application", request="CharmConfig", version=17, params=_params + ) + _params["args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(ApplicationCharmRelationsResults) async def CharmRelations(self, application=None): - ''' + """ CharmRelations implements the server side of Application.CharmRelations. application : str Returns -> ApplicationCharmRelationsResults - ''' + """ if application is not None and not isinstance(application, (bytes, str)): - raise Exception("Expected application to be a str, received: {}".format(type(application))) + raise Exception( + "Expected application to be a str, received: {}".format( + type(application) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='CharmRelations', - version=17, - params=_params) - _params['application'] = application + msg = dict( + type="Application", request="CharmRelations", version=17, params=_params + ) + _params["application"] = application reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def Consume(self, args=None): - ''' + """ Consume adds remote applications to the model without creating any relations. args : typing.Sequence[~ConsumeApplicationArg] Returns -> ErrorResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='Consume', - version=17, - params=_params) - _params['args'] = args + msg = dict(type="Application", request="Consume", version=17, params=_params) + _params["args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def Deploy(self, applications=None): - ''' + """ Deploy fetches the charms from the charm store and deploys them using the specified placement directives. applications : typing.Sequence[~ApplicationDeploy] Returns -> ErrorResults - ''' - if applications is not None and not isinstance(applications, (bytes, str, list)): - raise Exception("Expected applications to be a Sequence, received: {}".format(type(applications))) + """ + if applications is not None and not isinstance( + applications, (bytes, str, list) + ): + raise Exception( + "Expected applications to be a Sequence, received: {}".format( + type(applications) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='Deploy', - version=17, - params=_params) - _params['applications'] = applications + msg = dict(type="Application", request="Deploy", version=17, params=_params) + _params["applications"] = applications reply = await self.rpc(msg) return reply - - @ReturnMapping(DestroyApplicationResults) async def DestroyApplication(self, applications=None): - ''' + """ DestroyApplication removes a given set of applications. applications : typing.Sequence[~DestroyApplicationParams] Returns -> DestroyApplicationResults - ''' - if applications is not None and not isinstance(applications, (bytes, str, list)): - raise Exception("Expected applications to be a Sequence, received: {}".format(type(applications))) + """ + if applications is not None and not isinstance( + applications, (bytes, str, list) + ): + raise Exception( + "Expected applications to be a Sequence, received: {}".format( + type(applications) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='DestroyApplication', - version=17, - params=_params) - _params['applications'] = applications + msg = dict( + type="Application", request="DestroyApplication", version=17, params=_params + ) + _params["applications"] = applications reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def DestroyConsumedApplications(self, applications=None): - ''' + """ DestroyConsumedApplications removes a given set of consumed (remote) applications. applications : typing.Sequence[~DestroyConsumedApplicationParams] Returns -> ErrorResults - ''' - if applications is not None and not isinstance(applications, (bytes, str, list)): - raise Exception("Expected applications to be a Sequence, received: {}".format(type(applications))) + """ + if applications is not None and not isinstance( + applications, (bytes, str, list) + ): + raise Exception( + "Expected applications to be a Sequence, received: {}".format( + type(applications) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='DestroyConsumedApplications', - version=17, - params=_params) - _params['applications'] = applications + msg = dict( + type="Application", + request="DestroyConsumedApplications", + version=17, + params=_params, + ) + _params["applications"] = applications reply = await self.rpc(msg) return reply - - @ReturnMapping(None) - async def DestroyRelation(self, endpoints=None, force=None, max_wait=None, relation_id=None): - ''' + async def DestroyRelation( + self, endpoints=None, force=None, max_wait=None, relation_id=None + ): + """ DestroyRelation removes the relation between the specified endpoints or an id. @@ -1110,295 +1686,325 @@ async def DestroyRelation(self, endpoints=None, force=None, max_wait=None, relat max_wait : int relation_id : int Returns -> None - ''' + """ if endpoints is not None and not isinstance(endpoints, (bytes, str, list)): - raise Exception("Expected endpoints to be a Sequence, received: {}".format(type(endpoints))) + raise Exception( + "Expected endpoints to be a Sequence, received: {}".format( + type(endpoints) + ) + ) if force is not None and not isinstance(force, bool): - raise Exception("Expected force to be a bool, received: {}".format(type(force))) + raise Exception( + "Expected force to be a bool, received: {}".format(type(force)) + ) if max_wait is not None and not isinstance(max_wait, int): - raise Exception("Expected max_wait to be a int, received: {}".format(type(max_wait))) + raise Exception( + "Expected max_wait to be a int, received: {}".format(type(max_wait)) + ) if relation_id is not None and not isinstance(relation_id, int): - raise Exception("Expected relation_id to be a int, received: {}".format(type(relation_id))) + raise Exception( + "Expected relation_id to be a int, received: {}".format( + type(relation_id) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='DestroyRelation', - version=17, - params=_params) - _params['endpoints'] = endpoints - _params['force'] = force - _params['max-wait'] = max_wait - _params['relation-id'] = relation_id + msg = dict( + type="Application", request="DestroyRelation", version=17, params=_params + ) + _params["endpoints"] = endpoints + _params["force"] = force + _params["max-wait"] = max_wait + _params["relation-id"] = relation_id reply = await self.rpc(msg) return reply - - @ReturnMapping(DestroyUnitResults) async def DestroyUnit(self, units=None): - ''' + """ DestroyUnit removes a given set of application units. units : typing.Sequence[~DestroyUnitParams] Returns -> DestroyUnitResults - ''' + """ if units is not None and not isinstance(units, (bytes, str, list)): - raise Exception("Expected units to be a Sequence, received: {}".format(type(units))) + raise Exception( + "Expected units to be a Sequence, received: {}".format(type(units)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='DestroyUnit', - version=17, - params=_params) - _params['units'] = units + msg = dict( + type="Application", request="DestroyUnit", version=17, params=_params + ) + _params["units"] = units reply = await self.rpc(msg) return reply - - @ReturnMapping(None) async def Expose(self, application=None, exposed_endpoints=None): - ''' + """ Expose changes the juju-managed firewall to expose any ports that were also explicitly marked by units as open. application : str exposed_endpoints : typing.Mapping[str, ~ExposedEndpoint] Returns -> None - ''' + """ if application is not None and not isinstance(application, (bytes, str)): - raise Exception("Expected application to be a str, received: {}".format(type(application))) + raise Exception( + "Expected application to be a str, received: {}".format( + type(application) + ) + ) if exposed_endpoints is not None and not isinstance(exposed_endpoints, dict): - raise Exception("Expected exposed_endpoints to be a Mapping, received: {}".format(type(exposed_endpoints))) + raise Exception( + "Expected exposed_endpoints to be a Mapping, received: {}".format( + type(exposed_endpoints) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='Expose', - version=17, - params=_params) - _params['application'] = application - _params['exposed-endpoints'] = exposed_endpoints + msg = dict(type="Application", request="Expose", version=17, params=_params) + _params["application"] = application + _params["exposed-endpoints"] = exposed_endpoints reply = await self.rpc(msg) return reply - - @ReturnMapping(ApplicationGetResults) async def Get(self, application=None, branch=None): - ''' + """ Get returns the charm configuration for an application. application : str branch : str Returns -> ApplicationGetResults - ''' + """ if application is not None and not isinstance(application, (bytes, str)): - raise Exception("Expected application to be a str, received: {}".format(type(application))) + raise Exception( + "Expected application to be a str, received: {}".format( + type(application) + ) + ) if branch is not None and not isinstance(branch, (bytes, str)): - raise Exception("Expected branch to be a str, received: {}".format(type(branch))) + raise Exception( + "Expected branch to be a str, received: {}".format(type(branch)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='Get', - version=17, - params=_params) - _params['application'] = application - _params['branch'] = branch + msg = dict(type="Application", request="Get", version=17, params=_params) + _params["application"] = application + _params["branch"] = branch reply = await self.rpc(msg) return reply - - @ReturnMapping(CharmURLOriginResult) async def GetCharmURLOrigin(self, application=None, branch=None): - ''' + """ GetCharmURLOrigin returns the charm URL and charm origin the given application is running at present. application : str branch : str Returns -> CharmURLOriginResult - ''' + """ if application is not None and not isinstance(application, (bytes, str)): - raise Exception("Expected application to be a str, received: {}".format(type(application))) + raise Exception( + "Expected application to be a str, received: {}".format( + type(application) + ) + ) if branch is not None and not isinstance(branch, (bytes, str)): - raise Exception("Expected branch to be a str, received: {}".format(type(branch))) + raise Exception( + "Expected branch to be a str, received: {}".format(type(branch)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='GetCharmURLOrigin', - version=17, - params=_params) - _params['application'] = application - _params['branch'] = branch + msg = dict( + type="Application", request="GetCharmURLOrigin", version=17, params=_params + ) + _params["application"] = application + _params["branch"] = branch reply = await self.rpc(msg) return reply - - @ReturnMapping(ApplicationGetConfigResults) async def GetConfig(self, entities=None): - ''' + """ GetConfig returns the charm config for each of the input applications. entities : typing.Sequence[~Entity] Returns -> ApplicationGetConfigResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='GetConfig', - version=17, - params=_params) - _params['entities'] = entities + msg = dict(type="Application", request="GetConfig", version=17, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ApplicationGetConstraintsResults) async def GetConstraints(self, entities=None): - ''' + """ GetConstraints returns the constraints for a given application. entities : typing.Sequence[~Entity] Returns -> ApplicationGetConstraintsResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='GetConstraints', - version=17, - params=_params) - _params['entities'] = entities + msg = dict( + type="Application", request="GetConstraints", version=17, params=_params + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(StringResult) async def Leader(self, tag=None): - ''' + """ Leader returns the unit name of the leader for the given application. tag : str Returns -> StringResult - ''' + """ if tag is not None and not isinstance(tag, (bytes, str)): raise Exception("Expected tag to be a str, received: {}".format(type(tag))) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='Leader', - version=17, - params=_params) - _params['tag'] = tag + msg = dict(type="Application", request="Leader", version=17, params=_params) + _params["tag"] = tag reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def MergeBindings(self, args=None): - ''' + """ MergeBindings merges operator-defined bindings with the current bindings for one or more applications. args : typing.Sequence[~ApplicationMergeBindings] Returns -> ErrorResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='MergeBindings', - version=17, - params=_params) - _params['args'] = args + msg = dict( + type="Application", request="MergeBindings", version=17, params=_params + ) + _params["args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def ResolveUnitErrors(self, all_=None, retry=None, tags=None): - ''' + """ ResolveUnitErrors marks errors on the specified units as resolved. all_ : bool retry : bool tags : Entities Returns -> ErrorResults - ''' + """ if all_ is not None and not isinstance(all_, bool): - raise Exception("Expected all_ to be a bool, received: {}".format(type(all_))) + raise Exception( + "Expected all_ to be a bool, received: {}".format(type(all_)) + ) if retry is not None and not isinstance(retry, bool): - raise Exception("Expected retry to be a bool, received: {}".format(type(retry))) + raise Exception( + "Expected retry to be a bool, received: {}".format(type(retry)) + ) if tags is not None and not isinstance(tags, (dict, Entities)): - raise Exception("Expected tags to be a Entities, received: {}".format(type(tags))) + raise Exception( + "Expected tags to be a Entities, received: {}".format(type(tags)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='ResolveUnitErrors', - version=17, - params=_params) - _params['all'] = all_ - _params['retry'] = retry - _params['tags'] = tags + msg = dict( + type="Application", request="ResolveUnitErrors", version=17, params=_params + ) + _params["all"] = all_ + _params["retry"] = retry + _params["tags"] = tags reply = await self.rpc(msg) return reply - - @ReturnMapping(ScaleApplicationResults) async def ScaleApplications(self, applications=None): - ''' + """ ScaleApplications scales the specified application to the requested number of units. applications : typing.Sequence[~ScaleApplicationParams] Returns -> ScaleApplicationResults - ''' - if applications is not None and not isinstance(applications, (bytes, str, list)): - raise Exception("Expected applications to be a Sequence, received: {}".format(type(applications))) + """ + if applications is not None and not isinstance( + applications, (bytes, str, list) + ): + raise Exception( + "Expected applications to be a Sequence, received: {}".format( + type(applications) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='ScaleApplications', - version=17, - params=_params) - _params['applications'] = applications + msg = dict( + type="Application", request="ScaleApplications", version=17, params=_params + ) + _params["applications"] = applications reply = await self.rpc(msg) return reply - - @ReturnMapping(None) - async def SetCharm(self, application=None, channel=None, charm_origin=None, charm_url=None, config_settings=None, config_settings_yaml=None, endpoint_bindings=None, force=None, force_base=None, force_units=None, generation=None, resource_ids=None, storage_constraints=None): - ''' + async def SetCharm( + self, + application=None, + channel=None, + charm_origin=None, + charm_url=None, + config_settings=None, + config_settings_yaml=None, + endpoint_bindings=None, + force=None, + force_base=None, + force_units=None, + generation=None, + resource_ids=None, + storage_constraints=None, + ): + """ SetCharm sets the charm for a given for the application. application : str @@ -1415,265 +2021,324 @@ async def SetCharm(self, application=None, channel=None, charm_origin=None, char resource_ids : typing.Mapping[str, str] storage_constraints : typing.Mapping[str, ~StorageConstraints] Returns -> None - ''' + """ if application is not None and not isinstance(application, (bytes, str)): - raise Exception("Expected application to be a str, received: {}".format(type(application))) + raise Exception( + "Expected application to be a str, received: {}".format( + type(application) + ) + ) if channel is not None and not isinstance(channel, (bytes, str)): - raise Exception("Expected channel to be a str, received: {}".format(type(channel))) - - if charm_origin is not None and not isinstance(charm_origin, (dict, CharmOrigin)): - raise Exception("Expected charm_origin to be a CharmOrigin, received: {}".format(type(charm_origin))) + raise Exception( + "Expected channel to be a str, received: {}".format(type(channel)) + ) + + if charm_origin is not None and not isinstance( + charm_origin, (dict, CharmOrigin) + ): + raise Exception( + "Expected charm_origin to be a CharmOrigin, received: {}".format( + type(charm_origin) + ) + ) if charm_url is not None and not isinstance(charm_url, (bytes, str)): - raise Exception("Expected charm_url to be a str, received: {}".format(type(charm_url))) + raise Exception( + "Expected charm_url to be a str, received: {}".format(type(charm_url)) + ) if config_settings is not None and not isinstance(config_settings, dict): - raise Exception("Expected config_settings to be a Mapping, received: {}".format(type(config_settings))) - - if config_settings_yaml is not None and not isinstance(config_settings_yaml, (bytes, str)): - raise Exception("Expected config_settings_yaml to be a str, received: {}".format(type(config_settings_yaml))) + raise Exception( + "Expected config_settings to be a Mapping, received: {}".format( + type(config_settings) + ) + ) + + if config_settings_yaml is not None and not isinstance( + config_settings_yaml, (bytes, str) + ): + raise Exception( + "Expected config_settings_yaml to be a str, received: {}".format( + type(config_settings_yaml) + ) + ) if endpoint_bindings is not None and not isinstance(endpoint_bindings, dict): - raise Exception("Expected endpoint_bindings to be a Mapping, received: {}".format(type(endpoint_bindings))) + raise Exception( + "Expected endpoint_bindings to be a Mapping, received: {}".format( + type(endpoint_bindings) + ) + ) if force is not None and not isinstance(force, bool): - raise Exception("Expected force to be a bool, received: {}".format(type(force))) + raise Exception( + "Expected force to be a bool, received: {}".format(type(force)) + ) if force_base is not None and not isinstance(force_base, bool): - raise Exception("Expected force_base to be a bool, received: {}".format(type(force_base))) + raise Exception( + "Expected force_base to be a bool, received: {}".format( + type(force_base) + ) + ) if force_units is not None and not isinstance(force_units, bool): - raise Exception("Expected force_units to be a bool, received: {}".format(type(force_units))) + raise Exception( + "Expected force_units to be a bool, received: {}".format( + type(force_units) + ) + ) if generation is not None and not isinstance(generation, (bytes, str)): - raise Exception("Expected generation to be a str, received: {}".format(type(generation))) + raise Exception( + "Expected generation to be a str, received: {}".format(type(generation)) + ) if resource_ids is not None and not isinstance(resource_ids, dict): - raise Exception("Expected resource_ids to be a Mapping, received: {}".format(type(resource_ids))) - - if storage_constraints is not None and not isinstance(storage_constraints, dict): - raise Exception("Expected storage_constraints to be a Mapping, received: {}".format(type(storage_constraints))) + raise Exception( + "Expected resource_ids to be a Mapping, received: {}".format( + type(resource_ids) + ) + ) + + if storage_constraints is not None and not isinstance( + storage_constraints, dict + ): + raise Exception( + "Expected storage_constraints to be a Mapping, received: {}".format( + type(storage_constraints) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='SetCharm', - version=17, - params=_params) - _params['application'] = application - _params['channel'] = channel - _params['charm-origin'] = charm_origin - _params['charm-url'] = charm_url - _params['config-settings'] = config_settings - _params['config-settings-yaml'] = config_settings_yaml - _params['endpoint-bindings'] = endpoint_bindings - _params['force'] = force - _params['force-base'] = force_base - _params['force-units'] = force_units - _params['generation'] = generation - _params['resource-ids'] = resource_ids - _params['storage-constraints'] = storage_constraints + msg = dict(type="Application", request="SetCharm", version=17, params=_params) + _params["application"] = application + _params["channel"] = channel + _params["charm-origin"] = charm_origin + _params["charm-url"] = charm_url + _params["config-settings"] = config_settings + _params["config-settings-yaml"] = config_settings_yaml + _params["endpoint-bindings"] = endpoint_bindings + _params["force"] = force + _params["force-base"] = force_base + _params["force-units"] = force_units + _params["generation"] = generation + _params["resource-ids"] = resource_ids + _params["storage-constraints"] = storage_constraints reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def SetConfigs(self, args=None): - ''' + """ SetConfigs implements the server side of Application.SetConfig. Both application and charm config are set. It does not unset values in Config map that are set to an empty string. Unset should be used for that. args : typing.Sequence[~ConfigSet] Returns -> ErrorResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='SetConfigs', - version=17, - params=_params) - _params['Args'] = args + msg = dict(type="Application", request="SetConfigs", version=17, params=_params) + _params["Args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(None) async def SetConstraints(self, application=None, constraints=None): - ''' + """ SetConstraints sets the constraints for a given application. application : str constraints : Value Returns -> None - ''' + """ if application is not None and not isinstance(application, (bytes, str)): - raise Exception("Expected application to be a str, received: {}".format(type(application))) + raise Exception( + "Expected application to be a str, received: {}".format( + type(application) + ) + ) if constraints is not None and not isinstance(constraints, (dict, Value)): - raise Exception("Expected constraints to be a Value, received: {}".format(type(constraints))) + raise Exception( + "Expected constraints to be a Value, received: {}".format( + type(constraints) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='SetConstraints', - version=17, - params=_params) - _params['application'] = application - _params['constraints'] = constraints + msg = dict( + type="Application", request="SetConstraints", version=17, params=_params + ) + _params["application"] = application + _params["constraints"] = constraints reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def SetMetricCredentials(self, creds=None): - ''' + """ SetMetricCredentials sets credentials on the application. creds : typing.Sequence[~ApplicationMetricCredential] Returns -> ErrorResults - ''' + """ if creds is not None and not isinstance(creds, (bytes, str, list)): - raise Exception("Expected creds to be a Sequence, received: {}".format(type(creds))) + raise Exception( + "Expected creds to be a Sequence, received: {}".format(type(creds)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='SetMetricCredentials', - version=17, - params=_params) - _params['creds'] = creds + msg = dict( + type="Application", + request="SetMetricCredentials", + version=17, + params=_params, + ) + _params["creds"] = creds reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def SetRelationsSuspended(self, args=None): - ''' + """ SetRelationsSuspended sets the suspended status of the specified relations. args : typing.Sequence[~RelationSuspendedArg] Returns -> ErrorResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='SetRelationsSuspended', - version=17, - params=_params) - _params['args'] = args + msg = dict( + type="Application", + request="SetRelationsSuspended", + version=17, + params=_params, + ) + _params["args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(None) async def Unexpose(self, application=None, exposed_endpoints=None): - ''' + """ Unexpose changes the juju-managed firewall to unexpose any ports that were also explicitly marked by units as open. application : str exposed_endpoints : typing.Sequence[str] Returns -> None - ''' + """ if application is not None and not isinstance(application, (bytes, str)): - raise Exception("Expected application to be a str, received: {}".format(type(application))) - - if exposed_endpoints is not None and not isinstance(exposed_endpoints, (bytes, str, list)): - raise Exception("Expected exposed_endpoints to be a Sequence, received: {}".format(type(exposed_endpoints))) + raise Exception( + "Expected application to be a str, received: {}".format( + type(application) + ) + ) + + if exposed_endpoints is not None and not isinstance( + exposed_endpoints, (bytes, str, list) + ): + raise Exception( + "Expected exposed_endpoints to be a Sequence, received: {}".format( + type(exposed_endpoints) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='Unexpose', - version=17, - params=_params) - _params['application'] = application - _params['exposed-endpoints'] = exposed_endpoints + msg = dict(type="Application", request="Unexpose", version=17, params=_params) + _params["application"] = application + _params["exposed-endpoints"] = exposed_endpoints reply = await self.rpc(msg) return reply - - @ReturnMapping(UnitInfoResults) async def UnitsInfo(self, entities=None): - ''' + """ UnitsInfo returns unit information for the given entities (units or applications). entities : typing.Sequence[~Entity] Returns -> UnitInfoResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='UnitsInfo', - version=17, - params=_params) - _params['entities'] = entities + msg = dict(type="Application", request="UnitsInfo", version=17, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def UnsetApplicationsConfig(self, args=None): - ''' + """ UnsetApplicationsConfig implements the server side of Application.UnsetApplicationsConfig. args : typing.Sequence[~ApplicationUnset] Returns -> ErrorResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='UnsetApplicationsConfig', - version=17, - params=_params) - _params['Args'] = args + msg = dict( + type="Application", + request="UnsetApplicationsConfig", + version=17, + params=_params, + ) + _params["Args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def UpdateApplicationBase(self, args=None): - ''' + """ UpdateApplicationBase updates the application base. Base for subordinates is updated too. args : typing.Sequence[~UpdateChannelArg] Returns -> ErrorResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='UpdateApplicationBase', - version=17, - params=_params) - _params['args'] = args + msg = dict( + type="Application", + request="UpdateApplicationBase", + version=17, + params=_params, + ) + _params["args"] = args reply = await self.rpc(msg) return reply - - diff --git a/juju/client/_client19.py b/juju/client/_client19.py index 897e95da4..f8c7fb849 100644 --- a/juju/client/_client19.py +++ b/juju/client/_client19.py @@ -6,1000 +6,1597 @@ class ApplicationFacade(Type): - name = 'Application' + name = "Application" version = 19 - schema = {'definitions': {'AddApplicationUnits': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'attach-storage': {'items': {'type': 'string'}, - 'type': 'array'}, - 'num-units': {'type': 'integer'}, - 'placement': {'items': {'$ref': '#/definitions/Placement'}, - 'type': 'array'}, - 'policy': {'type': 'string'}}, - 'required': ['application', - 'num-units', - 'placement'], - 'type': 'object'}, - 'AddApplicationUnitsResults': {'additionalProperties': False, - 'properties': {'units': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['units'], - 'type': 'object'}, - 'AddRelation': {'additionalProperties': False, - 'properties': {'endpoints': {'items': {'type': 'string'}, - 'type': 'array'}, - 'via-cidrs': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['endpoints'], - 'type': 'object'}, - 'AddRelationResults': {'additionalProperties': False, - 'properties': {'endpoints': {'patternProperties': {'.*': {'$ref': '#/definitions/CharmRelation'}}, - 'type': 'object'}}, - 'required': ['endpoints'], - 'type': 'object'}, - 'ApplicationCharmRelations': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}}, - 'required': ['application'], - 'type': 'object'}, - 'ApplicationCharmRelationsResults': {'additionalProperties': False, - 'properties': {'charm-relations': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['charm-relations'], - 'type': 'object'}, - 'ApplicationConfigUnsetArgs': {'additionalProperties': False, - 'properties': {'Args': {'items': {'$ref': '#/definitions/ApplicationUnset'}, - 'type': 'array'}}, - 'required': ['Args'], - 'type': 'object'}, - 'ApplicationConstraint': {'additionalProperties': False, - 'properties': {'constraints': {'$ref': '#/definitions/Value'}, - 'error': {'$ref': '#/definitions/Error'}}, - 'required': ['constraints'], - 'type': 'object'}, - 'ApplicationDeploy': {'additionalProperties': False, - 'properties': {'Force': {'type': 'boolean'}, - 'application': {'type': 'string'}, - 'attach-storage': {'items': {'type': 'string'}, - 'type': 'array'}, - 'channel': {'type': 'string'}, - 'charm-origin': {'$ref': '#/definitions/CharmOrigin'}, - 'charm-url': {'type': 'string'}, - 'config': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'config-yaml': {'type': 'string'}, - 'constraints': {'$ref': '#/definitions/Value'}, - 'devices': {'patternProperties': {'.*': {'$ref': '#/definitions/Constraints'}}, - 'type': 'object'}, - 'endpoint-bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'num-units': {'type': 'integer'}, - 'placement': {'items': {'$ref': '#/definitions/Placement'}, - 'type': 'array'}, - 'policy': {'type': 'string'}, - 'resources': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'storage': {'patternProperties': {'.*': {'$ref': '#/definitions/Constraints'}}, - 'type': 'object'}}, - 'required': ['application', - 'charm-url', - 'channel', - 'num-units', - 'config-yaml', - 'constraints', - 'Force'], - 'type': 'object'}, - 'ApplicationExpose': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'exposed-endpoints': {'patternProperties': {'.*': {'$ref': '#/definitions/ExposedEndpoint'}}, - 'type': 'object'}}, - 'required': ['application'], - 'type': 'object'}, - 'ApplicationGet': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'branch': {'type': 'string'}}, - 'required': ['application', 'branch'], - 'type': 'object'}, - 'ApplicationGetArgs': {'additionalProperties': False, - 'properties': {'args': {'items': {'$ref': '#/definitions/ApplicationGet'}, - 'type': 'array'}}, - 'required': ['args'], - 'type': 'object'}, - 'ApplicationGetConfigResults': {'additionalProperties': False, - 'properties': {'Results': {'items': {'$ref': '#/definitions/ConfigResult'}, - 'type': 'array'}}, - 'required': ['Results'], - 'type': 'object'}, - 'ApplicationGetConstraintsResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ApplicationConstraint'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'ApplicationGetResults': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'application-config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'base': {'$ref': '#/definitions/Base'}, - 'channel': {'type': 'string'}, - 'charm': {'type': 'string'}, - 'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'constraints': {'$ref': '#/definitions/Value'}, - 'endpoint-bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}}, - 'required': ['application', - 'charm', - 'config', - 'constraints', - 'base', - 'channel'], - 'type': 'object'}, - 'ApplicationInfoResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/ApplicationResult'}}, - 'type': 'object'}, - 'ApplicationInfoResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ApplicationInfoResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'ApplicationMergeBindings': {'additionalProperties': False, - 'properties': {'application-tag': {'type': 'string'}, - 'bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'force': {'type': 'boolean'}}, - 'required': ['application-tag', - 'bindings', - 'force'], - 'type': 'object'}, - 'ApplicationMergeBindingsArgs': {'additionalProperties': False, - 'properties': {'args': {'items': {'$ref': '#/definitions/ApplicationMergeBindings'}, - 'type': 'array'}}, - 'required': ['args'], - 'type': 'object'}, - 'ApplicationMetricCredential': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'metrics-credentials': {'items': {'type': 'integer'}, - 'type': 'array'}}, - 'required': ['application', - 'metrics-credentials'], - 'type': 'object'}, - 'ApplicationMetricCredentials': {'additionalProperties': False, - 'properties': {'creds': {'items': {'$ref': '#/definitions/ApplicationMetricCredential'}, - 'type': 'array'}}, - 'required': ['creds'], - 'type': 'object'}, - 'ApplicationOfferDetails': {'additionalProperties': False, - 'properties': {'application-description': {'type': 'string'}, - 'bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'endpoints': {'items': {'$ref': '#/definitions/RemoteEndpoint'}, - 'type': 'array'}, - 'offer-name': {'type': 'string'}, - 'offer-url': {'type': 'string'}, - 'offer-uuid': {'type': 'string'}, - 'source-model-tag': {'type': 'string'}, - 'spaces': {'items': {'$ref': '#/definitions/RemoteSpace'}, - 'type': 'array'}, - 'users': {'items': {'$ref': '#/definitions/OfferUserDetails'}, - 'type': 'array'}}, - 'required': ['source-model-tag', - 'offer-uuid', - 'offer-url', - 'offer-name', - 'application-description'], - 'type': 'object'}, - 'ApplicationResult': {'additionalProperties': False, - 'properties': {'base': {'$ref': '#/definitions/Base'}, - 'channel': {'type': 'string'}, - 'charm': {'type': 'string'}, - 'constraints': {'$ref': '#/definitions/Value'}, - 'endpoint-bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'exposed': {'type': 'boolean'}, - 'exposed-endpoints': {'patternProperties': {'.*': {'$ref': '#/definitions/ExposedEndpoint'}}, - 'type': 'object'}, - 'life': {'type': 'string'}, - 'principal': {'type': 'boolean'}, - 'remote': {'type': 'boolean'}, - 'tag': {'type': 'string'}}, - 'required': ['tag', - 'principal', - 'exposed', - 'remote', - 'life'], - 'type': 'object'}, - 'ApplicationSetCharm': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'channel': {'type': 'string'}, - 'charm-origin': {'$ref': '#/definitions/CharmOrigin'}, - 'charm-url': {'type': 'string'}, - 'config-settings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'config-settings-yaml': {'type': 'string'}, - 'endpoint-bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'force': {'type': 'boolean'}, - 'force-base': {'type': 'boolean'}, - 'force-units': {'type': 'boolean'}, - 'generation': {'type': 'string'}, - 'resource-ids': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'storage-constraints': {'patternProperties': {'.*': {'$ref': '#/definitions/StorageConstraints'}}, - 'type': 'object'}}, - 'required': ['application', - 'generation', - 'charm-url', - 'channel', - 'force', - 'force-units', - 'force-base'], - 'type': 'object'}, - 'ApplicationUnexpose': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'exposed-endpoints': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['application', - 'exposed-endpoints'], - 'type': 'object'}, - 'ApplicationUnset': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'branch': {'type': 'string'}, - 'options': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['application', - 'branch', - 'options'], - 'type': 'object'}, - 'ApplicationsDeploy': {'additionalProperties': False, - 'properties': {'applications': {'items': {'$ref': '#/definitions/ApplicationDeploy'}, - 'type': 'array'}}, - 'required': ['applications'], - 'type': 'object'}, - 'Base': {'additionalProperties': False, - 'properties': {'channel': {'type': 'string'}, - 'name': {'type': 'string'}}, - 'required': ['name', 'channel'], - 'type': 'object'}, - 'CharmOrigin': {'additionalProperties': False, - 'properties': {'architecture': {'type': 'string'}, - 'base': {'$ref': '#/definitions/Base'}, - 'branch': {'type': 'string'}, - 'hash': {'type': 'string'}, - 'id': {'type': 'string'}, - 'instance-key': {'type': 'string'}, - 'revision': {'type': 'integer'}, - 'risk': {'type': 'string'}, - 'source': {'type': 'string'}, - 'track': {'type': 'string'}, - 'type': {'type': 'string'}}, - 'required': ['source', 'type', 'id'], - 'type': 'object'}, - 'CharmRelation': {'additionalProperties': False, - 'properties': {'interface': {'type': 'string'}, - 'limit': {'type': 'integer'}, - 'name': {'type': 'string'}, - 'optional': {'type': 'boolean'}, - 'role': {'type': 'string'}, - 'scope': {'type': 'string'}}, - 'required': ['name', - 'role', - 'interface', - 'optional', - 'limit', - 'scope'], - 'type': 'object'}, - 'CharmURLOriginResult': {'additionalProperties': False, - 'properties': {'charm-origin': {'$ref': '#/definitions/CharmOrigin'}, - 'error': {'$ref': '#/definitions/Error'}, - 'url': {'type': 'string'}}, - 'required': ['url', 'charm-origin'], - 'type': 'object'}, - 'ConfigResult': {'additionalProperties': False, - 'properties': {'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'error': {'$ref': '#/definitions/Error'}}, - 'required': ['config'], - 'type': 'object'}, - 'ConfigSet': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'config': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'config-yaml': {'type': 'string'}, - 'generation': {'type': 'string'}}, - 'required': ['application', - 'generation', - 'config', - 'config-yaml'], - 'type': 'object'}, - 'ConfigSetArgs': {'additionalProperties': False, - 'properties': {'Args': {'items': {'$ref': '#/definitions/ConfigSet'}, - 'type': 'array'}}, - 'required': ['Args'], - 'type': 'object'}, - 'Constraints': {'additionalProperties': False, - 'properties': {'Count': {'type': 'integer'}, - 'Pool': {'type': 'string'}, - 'Size': {'type': 'integer'}}, - 'required': ['Pool', 'Size', 'Count'], - 'type': 'object'}, - 'ConsumeApplicationArg': {'additionalProperties': False, - 'properties': {'ApplicationOfferDetails': {'$ref': '#/definitions/ApplicationOfferDetails'}, - 'application-alias': {'type': 'string'}, - 'application-description': {'type': 'string'}, - 'bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'endpoints': {'items': {'$ref': '#/definitions/RemoteEndpoint'}, - 'type': 'array'}, - 'external-controller': {'$ref': '#/definitions/ExternalControllerInfo'}, - 'macaroon': {'$ref': '#/definitions/Macaroon'}, - 'offer-name': {'type': 'string'}, - 'offer-url': {'type': 'string'}, - 'offer-uuid': {'type': 'string'}, - 'source-model-tag': {'type': 'string'}, - 'spaces': {'items': {'$ref': '#/definitions/RemoteSpace'}, - 'type': 'array'}, - 'users': {'items': {'$ref': '#/definitions/OfferUserDetails'}, - 'type': 'array'}}, - 'required': ['source-model-tag', - 'offer-uuid', - 'offer-url', - 'offer-name', - 'application-description', - 'ApplicationOfferDetails'], - 'type': 'object'}, - 'ConsumeApplicationArgs': {'additionalProperties': False, - 'properties': {'args': {'items': {'$ref': '#/definitions/ConsumeApplicationArg'}, - 'type': 'array'}}, - 'type': 'object'}, - 'DeployFromRepositoryArg': {'additionalProperties': False, - 'properties': {'ApplicationName': {'type': 'string'}, - 'AttachStorage': {'items': {'type': 'string'}, - 'type': 'array'}, - 'CharmName': {'type': 'string'}, - 'ConfigYAML': {'type': 'string'}, - 'Cons': {'$ref': '#/definitions/Value'}, - 'Devices': {'patternProperties': {'.*': {'$ref': '#/definitions/Constraints'}}, - 'type': 'object'}, - 'DryRun': {'type': 'boolean'}, - 'Placement': {'items': {'$ref': '#/definitions/Placement'}, - 'type': 'array'}, - 'Storage': {'patternProperties': {'.*': {'$ref': '#/definitions/Constraints'}}, - 'type': 'object'}, - 'Trust': {'type': 'boolean'}, - 'base': {'$ref': '#/definitions/Base'}, - 'channel': {'type': 'string'}, - 'endpoint-bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'force': {'type': 'boolean'}, - 'num-units': {'type': 'integer'}, - 'resources': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'revision': {'type': 'integer'}}, - 'required': ['CharmName', - 'ApplicationName', - 'AttachStorage', - 'ConfigYAML', - 'Cons', - 'Devices', - 'DryRun', - 'Placement', - 'Storage', - 'Trust'], - 'type': 'object'}, - 'DeployFromRepositoryArgs': {'additionalProperties': False, - 'properties': {'Args': {'items': {'$ref': '#/definitions/DeployFromRepositoryArg'}, - 'type': 'array'}}, - 'required': ['Args'], - 'type': 'object'}, - 'DeployFromRepositoryInfo': {'additionalProperties': False, - 'properties': {'architecture': {'type': 'string'}, - 'base': {'$ref': '#/definitions/Base'}, - 'channel': {'type': 'string'}, - 'effective-channel': {'type': 'string'}, - 'name': {'type': 'string'}, - 'revision': {'type': 'integer'}}, - 'required': ['architecture', - 'channel', - 'name', - 'revision'], - 'type': 'object'}, - 'DeployFromRepositoryResult': {'additionalProperties': False, - 'properties': {'Errors': {'items': {'$ref': '#/definitions/Error'}, - 'type': 'array'}, - 'Info': {'$ref': '#/definitions/DeployFromRepositoryInfo'}, - 'PendingResourceUploads': {'items': {'$ref': '#/definitions/PendingResourceUpload'}, - 'type': 'array'}}, - 'required': ['Errors', - 'Info', - 'PendingResourceUploads'], - 'type': 'object'}, - 'DeployFromRepositoryResults': {'additionalProperties': False, - 'properties': {'Results': {'items': {'$ref': '#/definitions/DeployFromRepositoryResult'}, - 'type': 'array'}}, - 'required': ['Results'], - 'type': 'object'}, - 'DestroyApplicationInfo': {'additionalProperties': False, - 'properties': {'destroyed-storage': {'items': {'$ref': '#/definitions/Entity'}, - 'type': 'array'}, - 'destroyed-units': {'items': {'$ref': '#/definitions/Entity'}, - 'type': 'array'}, - 'detached-storage': {'items': {'$ref': '#/definitions/Entity'}, - 'type': 'array'}}, - 'type': 'object'}, - 'DestroyApplicationParams': {'additionalProperties': False, - 'properties': {'application-tag': {'type': 'string'}, - 'destroy-storage': {'type': 'boolean'}, - 'dry-run': {'type': 'boolean'}, - 'force': {'type': 'boolean'}, - 'max-wait': {'type': 'integer'}}, - 'required': ['application-tag', - 'force'], - 'type': 'object'}, - 'DestroyApplicationResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'info': {'$ref': '#/definitions/DestroyApplicationInfo'}}, - 'type': 'object'}, - 'DestroyApplicationResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/DestroyApplicationResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'DestroyApplicationsParams': {'additionalProperties': False, - 'properties': {'applications': {'items': {'$ref': '#/definitions/DestroyApplicationParams'}, - 'type': 'array'}}, - 'required': ['applications'], - 'type': 'object'}, - 'DestroyConsumedApplicationParams': {'additionalProperties': False, - 'properties': {'application-tag': {'type': 'string'}, - 'force': {'type': 'boolean'}, - 'max-wait': {'type': 'integer'}}, - 'required': ['application-tag'], - 'type': 'object'}, - 'DestroyConsumedApplicationsParams': {'additionalProperties': False, - 'properties': {'applications': {'items': {'$ref': '#/definitions/DestroyConsumedApplicationParams'}, - 'type': 'array'}}, - 'required': ['applications'], - 'type': 'object'}, - 'DestroyRelation': {'additionalProperties': False, - 'properties': {'endpoints': {'items': {'type': 'string'}, - 'type': 'array'}, - 'force': {'type': 'boolean'}, - 'max-wait': {'type': 'integer'}, - 'relation-id': {'type': 'integer'}}, - 'required': ['relation-id'], - 'type': 'object'}, - 'DestroyUnitInfo': {'additionalProperties': False, - 'properties': {'destroyed-storage': {'items': {'$ref': '#/definitions/Entity'}, - 'type': 'array'}, - 'detached-storage': {'items': {'$ref': '#/definitions/Entity'}, - 'type': 'array'}}, - 'type': 'object'}, - 'DestroyUnitParams': {'additionalProperties': False, - 'properties': {'destroy-storage': {'type': 'boolean'}, - 'dry-run': {'type': 'boolean'}, - 'force': {'type': 'boolean'}, - 'max-wait': {'type': 'integer'}, - 'unit-tag': {'type': 'string'}}, - 'required': ['unit-tag'], - 'type': 'object'}, - 'DestroyUnitResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'info': {'$ref': '#/definitions/DestroyUnitInfo'}}, - 'type': 'object'}, - 'DestroyUnitResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/DestroyUnitResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'DestroyUnitsParams': {'additionalProperties': False, - 'properties': {'units': {'items': {'$ref': '#/definitions/DestroyUnitParams'}, - 'type': 'array'}}, - 'required': ['units'], - 'type': 'object'}, - 'EndpointRelationData': {'additionalProperties': False, - 'properties': {'ApplicationData': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'cross-model': {'type': 'boolean'}, - 'endpoint': {'type': 'string'}, - 'related-endpoint': {'type': 'string'}, - 'relation-id': {'type': 'integer'}, - 'unit-relation-data': {'patternProperties': {'.*': {'$ref': '#/definitions/RelationData'}}, - 'type': 'object'}}, - 'required': ['relation-id', - 'endpoint', - 'cross-model', - 'related-endpoint', - 'ApplicationData', - 'unit-relation-data'], - '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'}, - 'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - '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'}, - 'ExposedEndpoint': {'additionalProperties': False, - 'properties': {'expose-to-cidrs': {'items': {'type': 'string'}, - 'type': 'array'}, - 'expose-to-spaces': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'ExternalControllerInfo': {'additionalProperties': False, - 'properties': {'addrs': {'items': {'type': 'string'}, - 'type': 'array'}, - 'ca-cert': {'type': 'string'}, - 'controller-alias': {'type': 'string'}, - 'controller-tag': {'type': 'string'}}, - 'required': ['controller-tag', - 'controller-alias', - 'addrs', - 'ca-cert'], - 'type': 'object'}, - 'Macaroon': {'additionalProperties': False, 'type': 'object'}, - 'OfferUserDetails': {'additionalProperties': False, - 'properties': {'access': {'type': 'string'}, - 'display-name': {'type': 'string'}, - 'user': {'type': 'string'}}, - 'required': ['user', - 'display-name', - 'access'], - 'type': 'object'}, - 'PendingResourceUpload': {'additionalProperties': False, - 'properties': {'Filename': {'type': 'string'}, - 'Name': {'type': 'string'}, - 'Type': {'type': 'string'}}, - 'required': ['Name', - 'Filename', - 'Type'], - 'type': 'object'}, - 'Placement': {'additionalProperties': False, - 'properties': {'directive': {'type': 'string'}, - 'scope': {'type': 'string'}}, - 'required': ['scope', 'directive'], - 'type': 'object'}, - 'RelationData': {'additionalProperties': False, - 'properties': {'InScope': {'type': 'boolean'}, - 'UnitData': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}}, - 'required': ['InScope', 'UnitData'], - 'type': 'object'}, - 'RelationSuspendedArg': {'additionalProperties': False, - 'properties': {'message': {'type': 'string'}, - 'relation-id': {'type': 'integer'}, - 'suspended': {'type': 'boolean'}}, - 'required': ['relation-id', - 'message', - 'suspended'], - 'type': 'object'}, - 'RelationSuspendedArgs': {'additionalProperties': False, - 'properties': {'args': {'items': {'$ref': '#/definitions/RelationSuspendedArg'}, - 'type': 'array'}}, - 'required': ['args'], - 'type': 'object'}, - 'RemoteEndpoint': {'additionalProperties': False, - 'properties': {'interface': {'type': 'string'}, - 'limit': {'type': 'integer'}, - 'name': {'type': 'string'}, - 'role': {'type': 'string'}}, - 'required': ['name', - 'role', - 'interface', - 'limit'], - 'type': 'object'}, - 'RemoteSpace': {'additionalProperties': False, - 'properties': {'cloud-type': {'type': 'string'}, - 'name': {'type': 'string'}, - 'provider-attributes': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'provider-id': {'type': 'string'}, - 'subnets': {'items': {'$ref': '#/definitions/Subnet'}, - 'type': 'array'}}, - 'required': ['cloud-type', - 'name', - 'provider-id', - 'provider-attributes', - 'subnets'], - 'type': 'object'}, - 'ScaleApplicationInfo': {'additionalProperties': False, - 'properties': {'num-units': {'type': 'integer'}}, - 'required': ['num-units'], - 'type': 'object'}, - 'ScaleApplicationParams': {'additionalProperties': False, - 'properties': {'application-tag': {'type': 'string'}, - 'force': {'type': 'boolean'}, - 'scale': {'type': 'integer'}, - 'scale-change': {'type': 'integer'}}, - 'required': ['application-tag', - 'scale', - 'force'], - 'type': 'object'}, - 'ScaleApplicationResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'info': {'$ref': '#/definitions/ScaleApplicationInfo'}}, - 'type': 'object'}, - 'ScaleApplicationResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ScaleApplicationResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'ScaleApplicationsParams': {'additionalProperties': False, - 'properties': {'applications': {'items': {'$ref': '#/definitions/ScaleApplicationParams'}, - 'type': 'array'}}, - 'required': ['applications'], - 'type': 'object'}, - 'SetConstraints': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'constraints': {'$ref': '#/definitions/Value'}}, - 'required': ['application', 'constraints'], - 'type': 'object'}, - 'StorageConstraints': {'additionalProperties': False, - 'properties': {'count': {'type': 'integer'}, - 'pool': {'type': 'string'}, - 'size': {'type': 'integer'}}, - 'type': 'object'}, - 'StringResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'type': 'string'}}, - 'required': ['result'], - 'type': 'object'}, - 'Subnet': {'additionalProperties': False, - 'properties': {'cidr': {'type': 'string'}, - 'life': {'type': 'string'}, - 'provider-id': {'type': 'string'}, - 'provider-network-id': {'type': 'string'}, - 'provider-space-id': {'type': 'string'}, - 'space-tag': {'type': 'string'}, - 'status': {'type': 'string'}, - 'vlan-tag': {'type': 'integer'}, - 'zones': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['cidr', - 'vlan-tag', - 'life', - 'space-tag', - 'zones'], - 'type': 'object'}, - 'UnitInfoResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/UnitResult'}}, - 'type': 'object'}, - 'UnitInfoResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/UnitInfoResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'UnitResult': {'additionalProperties': False, - 'properties': {'address': {'type': 'string'}, - 'charm': {'type': 'string'}, - 'leader': {'type': 'boolean'}, - 'life': {'type': 'string'}, - 'machine': {'type': 'string'}, - 'opened-ports': {'items': {'type': 'string'}, - 'type': 'array'}, - 'provider-id': {'type': 'string'}, - 'public-address': {'type': 'string'}, - 'relation-data': {'items': {'$ref': '#/definitions/EndpointRelationData'}, - 'type': 'array'}, - 'tag': {'type': 'string'}, - 'workload-version': {'type': 'string'}}, - 'required': ['tag', - 'workload-version', - 'opened-ports', - 'charm'], - 'type': 'object'}, - 'UnitsResolved': {'additionalProperties': False, - 'properties': {'all': {'type': 'boolean'}, - 'retry': {'type': 'boolean'}, - 'tags': {'$ref': '#/definitions/Entities'}}, - 'type': 'object'}, - 'UpdateChannelArg': {'additionalProperties': False, - 'properties': {'channel': {'type': 'string'}, - 'force': {'type': 'boolean'}, - 'tag': {'$ref': '#/definitions/Entity'}}, - 'required': ['tag', 'force', 'channel'], - 'type': 'object'}, - 'UpdateChannelArgs': {'additionalProperties': False, - 'properties': {'args': {'items': {'$ref': '#/definitions/UpdateChannelArg'}, - 'type': 'array'}}, - 'required': ['args'], - 'type': 'object'}, - 'Value': {'additionalProperties': False, - 'properties': {'allocate-public-ip': {'type': 'boolean'}, - 'arch': {'type': 'string'}, - 'container': {'type': 'string'}, - 'cores': {'type': 'integer'}, - 'cpu-power': {'type': 'integer'}, - 'image-id': {'type': 'string'}, - 'instance-role': {'type': 'string'}, - 'instance-type': {'type': 'string'}, - 'mem': {'type': 'integer'}, - 'root-disk': {'type': 'integer'}, - 'root-disk-source': {'type': 'string'}, - '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': {'AddRelation': {'description': 'AddRelation adds a relation ' - 'between the specified ' - 'endpoints and returns the ' - 'relation info.', - 'properties': {'Params': {'$ref': '#/definitions/AddRelation'}, - 'Result': {'$ref': '#/definitions/AddRelationResults'}}, - 'type': 'object'}, - 'AddUnits': {'description': 'AddUnits adds a given number of ' - 'units to an application.', - 'properties': {'Params': {'$ref': '#/definitions/AddApplicationUnits'}, - 'Result': {'$ref': '#/definitions/AddApplicationUnitsResults'}}, - 'type': 'object'}, - 'ApplicationsInfo': {'description': 'ApplicationsInfo returns ' - 'applications information.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ApplicationInfoResults'}}, - 'type': 'object'}, - 'CharmConfig': {'description': 'CharmConfig returns charm ' - 'config for the input list of ' - 'applications and\n' - 'model generations.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationGetArgs'}, - 'Result': {'$ref': '#/definitions/ApplicationGetConfigResults'}}, - 'type': 'object'}, - 'CharmRelations': {'description': 'CharmRelations implements ' - 'the server side of ' - 'Application.CharmRelations.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationCharmRelations'}, - 'Result': {'$ref': '#/definitions/ApplicationCharmRelationsResults'}}, - 'type': 'object'}, - 'Consume': {'description': 'Consume adds remote applications ' - 'to the model without creating any\n' - 'relations.', - 'properties': {'Params': {'$ref': '#/definitions/ConsumeApplicationArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'Deploy': {'description': 'Deploy fetches the charms from the ' - 'charm store and deploys them\n' - 'using the specified placement ' - 'directives.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationsDeploy'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'DeployFromRepository': {'description': 'DeployFromRepository ' - 'is a one-stop ' - 'deployment method for ' - 'repository\n' - 'charms. Only a charm ' - 'name is required to ' - 'deploy. If argument ' - 'validation\n' - 'fails, a list of all ' - 'errors found in ' - 'validation will be ' - 'returned. If a\n' - 'local resource is ' - 'provided, details ' - 'required for ' - 'uploading the ' - 'validated\n' - 'resource will be ' - 'returned.', - 'properties': {'Params': {'$ref': '#/definitions/DeployFromRepositoryArgs'}, - 'Result': {'$ref': '#/definitions/DeployFromRepositoryResults'}}, - 'type': 'object'}, - 'DestroyApplication': {'description': 'DestroyApplication ' - 'removes a given set of ' - 'applications.', - 'properties': {'Params': {'$ref': '#/definitions/DestroyApplicationsParams'}, - 'Result': {'$ref': '#/definitions/DestroyApplicationResults'}}, - 'type': 'object'}, - 'DestroyConsumedApplications': {'description': 'DestroyConsumedApplications ' - 'removes a ' - 'given set of ' - 'consumed ' - '(remote) ' - 'applications.', - 'properties': {'Params': {'$ref': '#/definitions/DestroyConsumedApplicationsParams'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'DestroyRelation': {'description': 'DestroyRelation removes ' - 'the relation between the\n' - 'specified endpoints or an ' - 'id.', - 'properties': {'Params': {'$ref': '#/definitions/DestroyRelation'}}, - 'type': 'object'}, - 'DestroyUnit': {'description': 'DestroyUnit removes a given ' - 'set of application units.', - 'properties': {'Params': {'$ref': '#/definitions/DestroyUnitsParams'}, - 'Result': {'$ref': '#/definitions/DestroyUnitResults'}}, - 'type': 'object'}, - 'Expose': {'description': 'Expose changes the juju-managed ' - 'firewall to expose any ports that\n' - 'were also explicitly marked by ' - 'units as open.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationExpose'}}, - 'type': 'object'}, - 'Get': {'description': 'Get returns the charm configuration ' - 'for an application.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationGet'}, - 'Result': {'$ref': '#/definitions/ApplicationGetResults'}}, - 'type': 'object'}, - 'GetCharmURLOrigin': {'description': 'GetCharmURLOrigin ' - 'returns the charm URL ' - 'and charm origin the ' - 'given\n' - 'application is running ' - 'at present.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationGet'}, - 'Result': {'$ref': '#/definitions/CharmURLOriginResult'}}, - 'type': 'object'}, - 'GetConfig': {'description': 'GetConfig returns the charm ' - 'config for each of the input ' - 'applications.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ApplicationGetConfigResults'}}, - 'type': 'object'}, - 'GetConstraints': {'description': 'GetConstraints returns the ' - 'constraints for a given ' - 'application.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ApplicationGetConstraintsResults'}}, - 'type': 'object'}, - 'Leader': {'description': 'Leader returns the unit name of the ' - 'leader for the given application.', - 'properties': {'Params': {'$ref': '#/definitions/Entity'}, - 'Result': {'$ref': '#/definitions/StringResult'}}, - 'type': 'object'}, - 'MergeBindings': {'description': 'MergeBindings merges ' - 'operator-defined bindings ' - 'with the current bindings ' - 'for\n' - 'one or more applications.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationMergeBindingsArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'ResolveUnitErrors': {'description': 'ResolveUnitErrors marks ' - 'errors on the specified ' - 'units as resolved.', - 'properties': {'Params': {'$ref': '#/definitions/UnitsResolved'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'ScaleApplications': {'description': 'ScaleApplications scales ' - 'the specified ' - 'application to the ' - 'requested number of ' - 'units.', - 'properties': {'Params': {'$ref': '#/definitions/ScaleApplicationsParams'}, - 'Result': {'$ref': '#/definitions/ScaleApplicationResults'}}, - 'type': 'object'}, - 'SetCharm': {'description': 'SetCharm sets the charm for a ' - 'given for the application.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationSetCharm'}}, - 'type': 'object'}, - 'SetConfigs': {'description': 'SetConfigs implements the ' - 'server side of ' - 'Application.SetConfig. Both\n' - 'application and charm config ' - 'are set. It does not unset ' - 'values in\n' - 'Config map that are set to an ' - 'empty string. Unset should be ' - 'used for that.', - 'properties': {'Params': {'$ref': '#/definitions/ConfigSetArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'SetConstraints': {'description': 'SetConstraints sets the ' - 'constraints for a given ' - 'application.', - 'properties': {'Params': {'$ref': '#/definitions/SetConstraints'}}, - 'type': 'object'}, - 'SetMetricCredentials': {'description': 'SetMetricCredentials ' - 'sets credentials on ' - 'the application.\n' - 'TODO (cderici) only ' - 'used for metered ' - 'charms in cmd ' - 'MeteredDeployAPI,\n' - 'kept for client ' - 'compatibility, remove ' - 'in juju 4.0', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationMetricCredentials'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'SetRelationsSuspended': {'description': 'SetRelationsSuspended ' - 'sets the suspended ' - 'status of the ' - 'specified relations.', - 'properties': {'Params': {'$ref': '#/definitions/RelationSuspendedArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'Unexpose': {'description': 'Unexpose changes the juju-managed ' - 'firewall to unexpose any ports ' - 'that\n' - 'were also explicitly marked by ' - 'units as open.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationUnexpose'}}, - 'type': 'object'}, - 'UnitsInfo': {'description': 'UnitsInfo returns unit ' - 'information for the given ' - 'entities (units or\n' - 'applications).', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/UnitInfoResults'}}, - 'type': 'object'}, - 'UnsetApplicationsConfig': {'description': 'UnsetApplicationsConfig ' - 'implements the ' - 'server side of ' - 'Application.UnsetApplicationsConfig.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationConfigUnsetArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'UpdateApplicationBase': {'description': 'UpdateApplicationBase ' - 'updates the ' - 'application base.\n' - 'Base for ' - 'subordinates is ' - 'updated too.', - 'properties': {'Params': {'$ref': '#/definitions/UpdateChannelArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "AddApplicationUnits": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "attach-storage": {"items": {"type": "string"}, "type": "array"}, + "num-units": {"type": "integer"}, + "placement": { + "items": {"$ref": "#/definitions/Placement"}, + "type": "array", + }, + "policy": {"type": "string"}, + }, + "required": ["application", "num-units", "placement"], + "type": "object", + }, + "AddApplicationUnitsResults": { + "additionalProperties": False, + "properties": {"units": {"items": {"type": "string"}, "type": "array"}}, + "required": ["units"], + "type": "object", + }, + "AddRelation": { + "additionalProperties": False, + "properties": { + "endpoints": {"items": {"type": "string"}, "type": "array"}, + "via-cidrs": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["endpoints"], + "type": "object", + }, + "AddRelationResults": { + "additionalProperties": False, + "properties": { + "endpoints": { + "patternProperties": { + ".*": {"$ref": "#/definitions/CharmRelation"} + }, + "type": "object", + } + }, + "required": ["endpoints"], + "type": "object", + }, + "ApplicationCharmRelations": { + "additionalProperties": False, + "properties": {"application": {"type": "string"}}, + "required": ["application"], + "type": "object", + }, + "ApplicationCharmRelationsResults": { + "additionalProperties": False, + "properties": { + "charm-relations": {"items": {"type": "string"}, "type": "array"} + }, + "required": ["charm-relations"], + "type": "object", + }, + "ApplicationConfigUnsetArgs": { + "additionalProperties": False, + "properties": { + "Args": { + "items": {"$ref": "#/definitions/ApplicationUnset"}, + "type": "array", + } + }, + "required": ["Args"], + "type": "object", + }, + "ApplicationConstraint": { + "additionalProperties": False, + "properties": { + "constraints": {"$ref": "#/definitions/Value"}, + "error": {"$ref": "#/definitions/Error"}, + }, + "required": ["constraints"], + "type": "object", + }, + "ApplicationDeploy": { + "additionalProperties": False, + "properties": { + "Force": {"type": "boolean"}, + "application": {"type": "string"}, + "attach-storage": {"items": {"type": "string"}, "type": "array"}, + "channel": {"type": "string"}, + "charm-origin": {"$ref": "#/definitions/CharmOrigin"}, + "charm-url": {"type": "string"}, + "config": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "config-yaml": {"type": "string"}, + "constraints": {"$ref": "#/definitions/Value"}, + "devices": { + "patternProperties": { + ".*": {"$ref": "#/definitions/Constraints"} + }, + "type": "object", + }, + "endpoint-bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "num-units": {"type": "integer"}, + "placement": { + "items": {"$ref": "#/definitions/Placement"}, + "type": "array", + }, + "policy": {"type": "string"}, + "resources": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "storage": { + "patternProperties": { + ".*": {"$ref": "#/definitions/Constraints"} + }, + "type": "object", + }, + }, + "required": [ + "application", + "charm-url", + "channel", + "num-units", + "config-yaml", + "constraints", + "Force", + ], + "type": "object", + }, + "ApplicationExpose": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "exposed-endpoints": { + "patternProperties": { + ".*": {"$ref": "#/definitions/ExposedEndpoint"} + }, + "type": "object", + }, + }, + "required": ["application"], + "type": "object", + }, + "ApplicationGet": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "branch": {"type": "string"}, + }, + "required": ["application", "branch"], + "type": "object", + }, + "ApplicationGetArgs": { + "additionalProperties": False, + "properties": { + "args": { + "items": {"$ref": "#/definitions/ApplicationGet"}, + "type": "array", + } + }, + "required": ["args"], + "type": "object", + }, + "ApplicationGetConfigResults": { + "additionalProperties": False, + "properties": { + "Results": { + "items": {"$ref": "#/definitions/ConfigResult"}, + "type": "array", + } + }, + "required": ["Results"], + "type": "object", + }, + "ApplicationGetConstraintsResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ApplicationConstraint"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "ApplicationGetResults": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "application-config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "base": {"$ref": "#/definitions/Base"}, + "channel": {"type": "string"}, + "charm": {"type": "string"}, + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "constraints": {"$ref": "#/definitions/Value"}, + "endpoint-bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + }, + "required": [ + "application", + "charm", + "config", + "constraints", + "base", + "channel", + ], + "type": "object", + }, + "ApplicationInfoResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/ApplicationResult"}, + }, + "type": "object", + }, + "ApplicationInfoResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ApplicationInfoResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "ApplicationMergeBindings": { + "additionalProperties": False, + "properties": { + "application-tag": {"type": "string"}, + "bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "force": {"type": "boolean"}, + }, + "required": ["application-tag", "bindings", "force"], + "type": "object", + }, + "ApplicationMergeBindingsArgs": { + "additionalProperties": False, + "properties": { + "args": { + "items": {"$ref": "#/definitions/ApplicationMergeBindings"}, + "type": "array", + } + }, + "required": ["args"], + "type": "object", + }, + "ApplicationMetricCredential": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "metrics-credentials": { + "items": {"type": "integer"}, + "type": "array", + }, + }, + "required": ["application", "metrics-credentials"], + "type": "object", + }, + "ApplicationMetricCredentials": { + "additionalProperties": False, + "properties": { + "creds": { + "items": {"$ref": "#/definitions/ApplicationMetricCredential"}, + "type": "array", + } + }, + "required": ["creds"], + "type": "object", + }, + "ApplicationOfferDetails": { + "additionalProperties": False, + "properties": { + "application-description": {"type": "string"}, + "bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "endpoints": { + "items": {"$ref": "#/definitions/RemoteEndpoint"}, + "type": "array", + }, + "offer-name": {"type": "string"}, + "offer-url": {"type": "string"}, + "offer-uuid": {"type": "string"}, + "source-model-tag": {"type": "string"}, + "spaces": { + "items": {"$ref": "#/definitions/RemoteSpace"}, + "type": "array", + }, + "users": { + "items": {"$ref": "#/definitions/OfferUserDetails"}, + "type": "array", + }, + }, + "required": [ + "source-model-tag", + "offer-uuid", + "offer-url", + "offer-name", + "application-description", + ], + "type": "object", + }, + "ApplicationResult": { + "additionalProperties": False, + "properties": { + "base": {"$ref": "#/definitions/Base"}, + "channel": {"type": "string"}, + "charm": {"type": "string"}, + "constraints": {"$ref": "#/definitions/Value"}, + "endpoint-bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "exposed": {"type": "boolean"}, + "exposed-endpoints": { + "patternProperties": { + ".*": {"$ref": "#/definitions/ExposedEndpoint"} + }, + "type": "object", + }, + "life": {"type": "string"}, + "principal": {"type": "boolean"}, + "remote": {"type": "boolean"}, + "tag": {"type": "string"}, + }, + "required": ["tag", "principal", "exposed", "remote", "life"], + "type": "object", + }, + "ApplicationSetCharm": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "channel": {"type": "string"}, + "charm-origin": {"$ref": "#/definitions/CharmOrigin"}, + "charm-url": {"type": "string"}, + "config-settings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "config-settings-yaml": {"type": "string"}, + "endpoint-bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "force": {"type": "boolean"}, + "force-base": {"type": "boolean"}, + "force-units": {"type": "boolean"}, + "generation": {"type": "string"}, + "resource-ids": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "storage-constraints": { + "patternProperties": { + ".*": {"$ref": "#/definitions/StorageConstraints"} + }, + "type": "object", + }, + }, + "required": [ + "application", + "generation", + "charm-url", + "channel", + "force", + "force-units", + "force-base", + ], + "type": "object", + }, + "ApplicationUnexpose": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "exposed-endpoints": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["application", "exposed-endpoints"], + "type": "object", + }, + "ApplicationUnset": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "branch": {"type": "string"}, + "options": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["application", "branch", "options"], + "type": "object", + }, + "ApplicationsDeploy": { + "additionalProperties": False, + "properties": { + "applications": { + "items": {"$ref": "#/definitions/ApplicationDeploy"}, + "type": "array", + } + }, + "required": ["applications"], + "type": "object", + }, + "Base": { + "additionalProperties": False, + "properties": { + "channel": {"type": "string"}, + "name": {"type": "string"}, + }, + "required": ["name", "channel"], + "type": "object", + }, + "CharmOrigin": { + "additionalProperties": False, + "properties": { + "architecture": {"type": "string"}, + "base": {"$ref": "#/definitions/Base"}, + "branch": {"type": "string"}, + "hash": {"type": "string"}, + "id": {"type": "string"}, + "instance-key": {"type": "string"}, + "revision": {"type": "integer"}, + "risk": {"type": "string"}, + "source": {"type": "string"}, + "track": {"type": "string"}, + "type": {"type": "string"}, + }, + "required": ["source", "type", "id"], + "type": "object", + }, + "CharmRelation": { + "additionalProperties": False, + "properties": { + "interface": {"type": "string"}, + "limit": {"type": "integer"}, + "name": {"type": "string"}, + "optional": {"type": "boolean"}, + "role": {"type": "string"}, + "scope": {"type": "string"}, + }, + "required": ["name", "role", "interface", "optional", "limit", "scope"], + "type": "object", + }, + "CharmURLOriginResult": { + "additionalProperties": False, + "properties": { + "charm-origin": {"$ref": "#/definitions/CharmOrigin"}, + "error": {"$ref": "#/definitions/Error"}, + "url": {"type": "string"}, + }, + "required": ["url", "charm-origin"], + "type": "object", + }, + "ConfigResult": { + "additionalProperties": False, + "properties": { + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "error": {"$ref": "#/definitions/Error"}, + }, + "required": ["config"], + "type": "object", + }, + "ConfigSet": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "config": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "config-yaml": {"type": "string"}, + "generation": {"type": "string"}, + }, + "required": ["application", "generation", "config", "config-yaml"], + "type": "object", + }, + "ConfigSetArgs": { + "additionalProperties": False, + "properties": { + "Args": { + "items": {"$ref": "#/definitions/ConfigSet"}, + "type": "array", + } + }, + "required": ["Args"], + "type": "object", + }, + "Constraints": { + "additionalProperties": False, + "properties": { + "Count": {"type": "integer"}, + "Pool": {"type": "string"}, + "Size": {"type": "integer"}, + }, + "required": ["Pool", "Size", "Count"], + "type": "object", + }, + "ConsumeApplicationArg": { + "additionalProperties": False, + "properties": { + "ApplicationOfferDetails": { + "$ref": "#/definitions/ApplicationOfferDetails" + }, + "application-alias": {"type": "string"}, + "application-description": {"type": "string"}, + "bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "endpoints": { + "items": {"$ref": "#/definitions/RemoteEndpoint"}, + "type": "array", + }, + "external-controller": { + "$ref": "#/definitions/ExternalControllerInfo" + }, + "macaroon": {"$ref": "#/definitions/Macaroon"}, + "offer-name": {"type": "string"}, + "offer-url": {"type": "string"}, + "offer-uuid": {"type": "string"}, + "source-model-tag": {"type": "string"}, + "spaces": { + "items": {"$ref": "#/definitions/RemoteSpace"}, + "type": "array", + }, + "users": { + "items": {"$ref": "#/definitions/OfferUserDetails"}, + "type": "array", + }, + }, + "required": [ + "source-model-tag", + "offer-uuid", + "offer-url", + "offer-name", + "application-description", + "ApplicationOfferDetails", + ], + "type": "object", + }, + "ConsumeApplicationArgs": { + "additionalProperties": False, + "properties": { + "args": { + "items": {"$ref": "#/definitions/ConsumeApplicationArg"}, + "type": "array", + } + }, + "type": "object", + }, + "DeployFromRepositoryArg": { + "additionalProperties": False, + "properties": { + "ApplicationName": {"type": "string"}, + "AttachStorage": {"items": {"type": "string"}, "type": "array"}, + "CharmName": {"type": "string"}, + "ConfigYAML": {"type": "string"}, + "Cons": {"$ref": "#/definitions/Value"}, + "Devices": { + "patternProperties": { + ".*": {"$ref": "#/definitions/Constraints"} + }, + "type": "object", + }, + "DryRun": {"type": "boolean"}, + "Placement": { + "items": {"$ref": "#/definitions/Placement"}, + "type": "array", + }, + "Storage": { + "patternProperties": { + ".*": {"$ref": "#/definitions/Constraints"} + }, + "type": "object", + }, + "Trust": {"type": "boolean"}, + "base": {"$ref": "#/definitions/Base"}, + "channel": {"type": "string"}, + "endpoint-bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "force": {"type": "boolean"}, + "num-units": {"type": "integer"}, + "resources": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "revision": {"type": "integer"}, + }, + "required": [ + "CharmName", + "ApplicationName", + "AttachStorage", + "ConfigYAML", + "Cons", + "Devices", + "DryRun", + "Placement", + "Storage", + "Trust", + ], + "type": "object", + }, + "DeployFromRepositoryArgs": { + "additionalProperties": False, + "properties": { + "Args": { + "items": {"$ref": "#/definitions/DeployFromRepositoryArg"}, + "type": "array", + } + }, + "required": ["Args"], + "type": "object", + }, + "DeployFromRepositoryInfo": { + "additionalProperties": False, + "properties": { + "architecture": {"type": "string"}, + "base": {"$ref": "#/definitions/Base"}, + "channel": {"type": "string"}, + "effective-channel": {"type": "string"}, + "name": {"type": "string"}, + "revision": {"type": "integer"}, + }, + "required": ["architecture", "channel", "name", "revision"], + "type": "object", + }, + "DeployFromRepositoryResult": { + "additionalProperties": False, + "properties": { + "Errors": { + "items": {"$ref": "#/definitions/Error"}, + "type": "array", + }, + "Info": {"$ref": "#/definitions/DeployFromRepositoryInfo"}, + "PendingResourceUploads": { + "items": {"$ref": "#/definitions/PendingResourceUpload"}, + "type": "array", + }, + }, + "required": ["Errors", "Info", "PendingResourceUploads"], + "type": "object", + }, + "DeployFromRepositoryResults": { + "additionalProperties": False, + "properties": { + "Results": { + "items": {"$ref": "#/definitions/DeployFromRepositoryResult"}, + "type": "array", + } + }, + "required": ["Results"], + "type": "object", + }, + "DestroyApplicationInfo": { + "additionalProperties": False, + "properties": { + "destroyed-storage": { + "items": {"$ref": "#/definitions/Entity"}, + "type": "array", + }, + "destroyed-units": { + "items": {"$ref": "#/definitions/Entity"}, + "type": "array", + }, + "detached-storage": { + "items": {"$ref": "#/definitions/Entity"}, + "type": "array", + }, + }, + "type": "object", + }, + "DestroyApplicationParams": { + "additionalProperties": False, + "properties": { + "application-tag": {"type": "string"}, + "destroy-storage": {"type": "boolean"}, + "dry-run": {"type": "boolean"}, + "force": {"type": "boolean"}, + "max-wait": {"type": "integer"}, + }, + "required": ["application-tag", "force"], + "type": "object", + }, + "DestroyApplicationResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "info": {"$ref": "#/definitions/DestroyApplicationInfo"}, + }, + "type": "object", + }, + "DestroyApplicationResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/DestroyApplicationResult"}, + "type": "array", + } + }, + "type": "object", + }, + "DestroyApplicationsParams": { + "additionalProperties": False, + "properties": { + "applications": { + "items": {"$ref": "#/definitions/DestroyApplicationParams"}, + "type": "array", + } + }, + "required": ["applications"], + "type": "object", + }, + "DestroyConsumedApplicationParams": { + "additionalProperties": False, + "properties": { + "application-tag": {"type": "string"}, + "force": {"type": "boolean"}, + "max-wait": {"type": "integer"}, + }, + "required": ["application-tag"], + "type": "object", + }, + "DestroyConsumedApplicationsParams": { + "additionalProperties": False, + "properties": { + "applications": { + "items": { + "$ref": "#/definitions/DestroyConsumedApplicationParams" + }, + "type": "array", + } + }, + "required": ["applications"], + "type": "object", + }, + "DestroyRelation": { + "additionalProperties": False, + "properties": { + "endpoints": {"items": {"type": "string"}, "type": "array"}, + "force": {"type": "boolean"}, + "max-wait": {"type": "integer"}, + "relation-id": {"type": "integer"}, + }, + "required": ["relation-id"], + "type": "object", + }, + "DestroyUnitInfo": { + "additionalProperties": False, + "properties": { + "destroyed-storage": { + "items": {"$ref": "#/definitions/Entity"}, + "type": "array", + }, + "detached-storage": { + "items": {"$ref": "#/definitions/Entity"}, + "type": "array", + }, + }, + "type": "object", + }, + "DestroyUnitParams": { + "additionalProperties": False, + "properties": { + "destroy-storage": {"type": "boolean"}, + "dry-run": {"type": "boolean"}, + "force": {"type": "boolean"}, + "max-wait": {"type": "integer"}, + "unit-tag": {"type": "string"}, + }, + "required": ["unit-tag"], + "type": "object", + }, + "DestroyUnitResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "info": {"$ref": "#/definitions/DestroyUnitInfo"}, + }, + "type": "object", + }, + "DestroyUnitResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/DestroyUnitResult"}, + "type": "array", + } + }, + "type": "object", + }, + "DestroyUnitsParams": { + "additionalProperties": False, + "properties": { + "units": { + "items": {"$ref": "#/definitions/DestroyUnitParams"}, + "type": "array", + } + }, + "required": ["units"], + "type": "object", + }, + "EndpointRelationData": { + "additionalProperties": False, + "properties": { + "ApplicationData": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "cross-model": {"type": "boolean"}, + "endpoint": {"type": "string"}, + "related-endpoint": {"type": "string"}, + "relation-id": {"type": "integer"}, + "unit-relation-data": { + "patternProperties": { + ".*": {"$ref": "#/definitions/RelationData"} + }, + "type": "object", + }, + }, + "required": [ + "relation-id", + "endpoint", + "cross-model", + "related-endpoint", + "ApplicationData", + "unit-relation-data", + ], + "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", + }, + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "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", + }, + "ExposedEndpoint": { + "additionalProperties": False, + "properties": { + "expose-to-cidrs": {"items": {"type": "string"}, "type": "array"}, + "expose-to-spaces": {"items": {"type": "string"}, "type": "array"}, + }, + "type": "object", + }, + "ExternalControllerInfo": { + "additionalProperties": False, + "properties": { + "addrs": {"items": {"type": "string"}, "type": "array"}, + "ca-cert": {"type": "string"}, + "controller-alias": {"type": "string"}, + "controller-tag": {"type": "string"}, + }, + "required": ["controller-tag", "controller-alias", "addrs", "ca-cert"], + "type": "object", + }, + "Macaroon": {"additionalProperties": False, "type": "object"}, + "OfferUserDetails": { + "additionalProperties": False, + "properties": { + "access": {"type": "string"}, + "display-name": {"type": "string"}, + "user": {"type": "string"}, + }, + "required": ["user", "display-name", "access"], + "type": "object", + }, + "PendingResourceUpload": { + "additionalProperties": False, + "properties": { + "Filename": {"type": "string"}, + "Name": {"type": "string"}, + "Type": {"type": "string"}, + }, + "required": ["Name", "Filename", "Type"], + "type": "object", + }, + "Placement": { + "additionalProperties": False, + "properties": { + "directive": {"type": "string"}, + "scope": {"type": "string"}, + }, + "required": ["scope", "directive"], + "type": "object", + }, + "RelationData": { + "additionalProperties": False, + "properties": { + "InScope": {"type": "boolean"}, + "UnitData": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + }, + "required": ["InScope", "UnitData"], + "type": "object", + }, + "RelationSuspendedArg": { + "additionalProperties": False, + "properties": { + "message": {"type": "string"}, + "relation-id": {"type": "integer"}, + "suspended": {"type": "boolean"}, + }, + "required": ["relation-id", "message", "suspended"], + "type": "object", + }, + "RelationSuspendedArgs": { + "additionalProperties": False, + "properties": { + "args": { + "items": {"$ref": "#/definitions/RelationSuspendedArg"}, + "type": "array", + } + }, + "required": ["args"], + "type": "object", + }, + "RemoteEndpoint": { + "additionalProperties": False, + "properties": { + "interface": {"type": "string"}, + "limit": {"type": "integer"}, + "name": {"type": "string"}, + "role": {"type": "string"}, + }, + "required": ["name", "role", "interface", "limit"], + "type": "object", + }, + "RemoteSpace": { + "additionalProperties": False, + "properties": { + "cloud-type": {"type": "string"}, + "name": {"type": "string"}, + "provider-attributes": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "provider-id": {"type": "string"}, + "subnets": { + "items": {"$ref": "#/definitions/Subnet"}, + "type": "array", + }, + }, + "required": [ + "cloud-type", + "name", + "provider-id", + "provider-attributes", + "subnets", + ], + "type": "object", + }, + "ScaleApplicationInfo": { + "additionalProperties": False, + "properties": {"num-units": {"type": "integer"}}, + "required": ["num-units"], + "type": "object", + }, + "ScaleApplicationParams": { + "additionalProperties": False, + "properties": { + "application-tag": {"type": "string"}, + "force": {"type": "boolean"}, + "scale": {"type": "integer"}, + "scale-change": {"type": "integer"}, + }, + "required": ["application-tag", "scale", "force"], + "type": "object", + }, + "ScaleApplicationResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "info": {"$ref": "#/definitions/ScaleApplicationInfo"}, + }, + "type": "object", + }, + "ScaleApplicationResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ScaleApplicationResult"}, + "type": "array", + } + }, + "type": "object", + }, + "ScaleApplicationsParams": { + "additionalProperties": False, + "properties": { + "applications": { + "items": {"$ref": "#/definitions/ScaleApplicationParams"}, + "type": "array", + } + }, + "required": ["applications"], + "type": "object", + }, + "SetConstraints": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "constraints": {"$ref": "#/definitions/Value"}, + }, + "required": ["application", "constraints"], + "type": "object", + }, + "StorageConstraints": { + "additionalProperties": False, + "properties": { + "count": {"type": "integer"}, + "pool": {"type": "string"}, + "size": {"type": "integer"}, + }, + "type": "object", + }, + "StringResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"type": "string"}, + }, + "required": ["result"], + "type": "object", + }, + "Subnet": { + "additionalProperties": False, + "properties": { + "cidr": {"type": "string"}, + "life": {"type": "string"}, + "provider-id": {"type": "string"}, + "provider-network-id": {"type": "string"}, + "provider-space-id": {"type": "string"}, + "space-tag": {"type": "string"}, + "status": {"type": "string"}, + "vlan-tag": {"type": "integer"}, + "zones": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["cidr", "vlan-tag", "life", "space-tag", "zones"], + "type": "object", + }, + "UnitInfoResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/UnitResult"}, + }, + "type": "object", + }, + "UnitInfoResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/UnitInfoResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "UnitResult": { + "additionalProperties": False, + "properties": { + "address": {"type": "string"}, + "charm": {"type": "string"}, + "leader": {"type": "boolean"}, + "life": {"type": "string"}, + "machine": {"type": "string"}, + "opened-ports": {"items": {"type": "string"}, "type": "array"}, + "provider-id": {"type": "string"}, + "public-address": {"type": "string"}, + "relation-data": { + "items": {"$ref": "#/definitions/EndpointRelationData"}, + "type": "array", + }, + "tag": {"type": "string"}, + "workload-version": {"type": "string"}, + }, + "required": ["tag", "workload-version", "opened-ports", "charm"], + "type": "object", + }, + "UnitsResolved": { + "additionalProperties": False, + "properties": { + "all": {"type": "boolean"}, + "retry": {"type": "boolean"}, + "tags": {"$ref": "#/definitions/Entities"}, + }, + "type": "object", + }, + "UpdateChannelArg": { + "additionalProperties": False, + "properties": { + "channel": {"type": "string"}, + "force": {"type": "boolean"}, + "tag": {"$ref": "#/definitions/Entity"}, + }, + "required": ["tag", "force", "channel"], + "type": "object", + }, + "UpdateChannelArgs": { + "additionalProperties": False, + "properties": { + "args": { + "items": {"$ref": "#/definitions/UpdateChannelArg"}, + "type": "array", + } + }, + "required": ["args"], + "type": "object", + }, + "Value": { + "additionalProperties": False, + "properties": { + "allocate-public-ip": {"type": "boolean"}, + "arch": {"type": "string"}, + "container": {"type": "string"}, + "cores": {"type": "integer"}, + "cpu-power": {"type": "integer"}, + "image-id": {"type": "string"}, + "instance-role": {"type": "string"}, + "instance-type": {"type": "string"}, + "mem": {"type": "integer"}, + "root-disk": {"type": "integer"}, + "root-disk-source": {"type": "string"}, + "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": { + "AddRelation": { + "description": "AddRelation adds a relation " + "between the specified " + "endpoints and returns the " + "relation info.", + "properties": { + "Params": {"$ref": "#/definitions/AddRelation"}, + "Result": {"$ref": "#/definitions/AddRelationResults"}, + }, + "type": "object", + }, + "AddUnits": { + "description": "AddUnits adds a given number of " + "units to an application.", + "properties": { + "Params": {"$ref": "#/definitions/AddApplicationUnits"}, + "Result": {"$ref": "#/definitions/AddApplicationUnitsResults"}, + }, + "type": "object", + }, + "ApplicationsInfo": { + "description": "ApplicationsInfo returns applications information.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/ApplicationInfoResults"}, + }, + "type": "object", + }, + "CharmConfig": { + "description": "CharmConfig returns charm " + "config for the input list of " + "applications and\n" + "model generations.", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationGetArgs"}, + "Result": {"$ref": "#/definitions/ApplicationGetConfigResults"}, + }, + "type": "object", + }, + "CharmRelations": { + "description": "CharmRelations implements " + "the server side of " + "Application.CharmRelations.", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationCharmRelations"}, + "Result": { + "$ref": "#/definitions/ApplicationCharmRelationsResults" + }, + }, + "type": "object", + }, + "Consume": { + "description": "Consume adds remote applications " + "to the model without creating any\n" + "relations.", + "properties": { + "Params": {"$ref": "#/definitions/ConsumeApplicationArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "Deploy": { + "description": "Deploy fetches the charms from the " + "charm store and deploys them\n" + "using the specified placement " + "directives.", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationsDeploy"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "DeployFromRepository": { + "description": "DeployFromRepository " + "is a one-stop " + "deployment method for " + "repository\n" + "charms. Only a charm " + "name is required to " + "deploy. If argument " + "validation\n" + "fails, a list of all " + "errors found in " + "validation will be " + "returned. If a\n" + "local resource is " + "provided, details " + "required for " + "uploading the " + "validated\n" + "resource will be " + "returned.", + "properties": { + "Params": {"$ref": "#/definitions/DeployFromRepositoryArgs"}, + "Result": {"$ref": "#/definitions/DeployFromRepositoryResults"}, + }, + "type": "object", + }, + "DestroyApplication": { + "description": "DestroyApplication " + "removes a given set of " + "applications.", + "properties": { + "Params": {"$ref": "#/definitions/DestroyApplicationsParams"}, + "Result": {"$ref": "#/definitions/DestroyApplicationResults"}, + }, + "type": "object", + }, + "DestroyConsumedApplications": { + "description": "DestroyConsumedApplications " + "removes a " + "given set of " + "consumed " + "(remote) " + "applications.", + "properties": { + "Params": { + "$ref": "#/definitions/DestroyConsumedApplicationsParams" + }, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "DestroyRelation": { + "description": "DestroyRelation removes " + "the relation between the\n" + "specified endpoints or an " + "id.", + "properties": {"Params": {"$ref": "#/definitions/DestroyRelation"}}, + "type": "object", + }, + "DestroyUnit": { + "description": "DestroyUnit removes a given set of application units.", + "properties": { + "Params": {"$ref": "#/definitions/DestroyUnitsParams"}, + "Result": {"$ref": "#/definitions/DestroyUnitResults"}, + }, + "type": "object", + }, + "Expose": { + "description": "Expose changes the juju-managed " + "firewall to expose any ports that\n" + "were also explicitly marked by " + "units as open.", + "properties": {"Params": {"$ref": "#/definitions/ApplicationExpose"}}, + "type": "object", + }, + "Get": { + "description": "Get returns the charm configuration " + "for an application.", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationGet"}, + "Result": {"$ref": "#/definitions/ApplicationGetResults"}, + }, + "type": "object", + }, + "GetCharmURLOrigin": { + "description": "GetCharmURLOrigin " + "returns the charm URL " + "and charm origin the " + "given\n" + "application is running " + "at present.", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationGet"}, + "Result": {"$ref": "#/definitions/CharmURLOriginResult"}, + }, + "type": "object", + }, + "GetConfig": { + "description": "GetConfig returns the charm " + "config for each of the input " + "applications.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/ApplicationGetConfigResults"}, + }, + "type": "object", + }, + "GetConstraints": { + "description": "GetConstraints returns the " + "constraints for a given " + "application.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": { + "$ref": "#/definitions/ApplicationGetConstraintsResults" + }, + }, + "type": "object", + }, + "Leader": { + "description": "Leader returns the unit name of the " + "leader for the given application.", + "properties": { + "Params": {"$ref": "#/definitions/Entity"}, + "Result": {"$ref": "#/definitions/StringResult"}, + }, + "type": "object", + }, + "MergeBindings": { + "description": "MergeBindings merges " + "operator-defined bindings " + "with the current bindings " + "for\n" + "one or more applications.", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationMergeBindingsArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "ResolveUnitErrors": { + "description": "ResolveUnitErrors marks " + "errors on the specified " + "units as resolved.", + "properties": { + "Params": {"$ref": "#/definitions/UnitsResolved"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "ScaleApplications": { + "description": "ScaleApplications scales " + "the specified " + "application to the " + "requested number of " + "units.", + "properties": { + "Params": {"$ref": "#/definitions/ScaleApplicationsParams"}, + "Result": {"$ref": "#/definitions/ScaleApplicationResults"}, + }, + "type": "object", + }, + "SetCharm": { + "description": "SetCharm sets the charm for a " + "given for the application.", + "properties": {"Params": {"$ref": "#/definitions/ApplicationSetCharm"}}, + "type": "object", + }, + "SetConfigs": { + "description": "SetConfigs implements the " + "server side of " + "Application.SetConfig. Both\n" + "application and charm config " + "are set. It does not unset " + "values in\n" + "Config map that are set to an " + "empty string. Unset should be " + "used for that.", + "properties": { + "Params": {"$ref": "#/definitions/ConfigSetArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "SetConstraints": { + "description": "SetConstraints sets the " + "constraints for a given " + "application.", + "properties": {"Params": {"$ref": "#/definitions/SetConstraints"}}, + "type": "object", + }, + "SetMetricCredentials": { + "description": "SetMetricCredentials " + "sets credentials on " + "the application.\n" + "TODO (cderici) only " + "used for metered " + "charms in cmd " + "MeteredDeployAPI,\n" + "kept for client " + "compatibility, remove " + "in juju 4.0", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationMetricCredentials"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "SetRelationsSuspended": { + "description": "SetRelationsSuspended " + "sets the suspended " + "status of the " + "specified relations.", + "properties": { + "Params": {"$ref": "#/definitions/RelationSuspendedArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "Unexpose": { + "description": "Unexpose changes the juju-managed " + "firewall to unexpose any ports " + "that\n" + "were also explicitly marked by " + "units as open.", + "properties": {"Params": {"$ref": "#/definitions/ApplicationUnexpose"}}, + "type": "object", + }, + "UnitsInfo": { + "description": "UnitsInfo returns unit " + "information for the given " + "entities (units or\n" + "applications).", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/UnitInfoResults"}, + }, + "type": "object", + }, + "UnsetApplicationsConfig": { + "description": "UnsetApplicationsConfig " + "implements the " + "server side of " + "Application.UnsetApplicationsConfig.", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationConfigUnsetArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "UpdateApplicationBase": { + "description": "UpdateApplicationBase " + "updates the " + "application base.\n" + "Base for " + "subordinates is " + "updated too.", + "properties": { + "Params": {"$ref": "#/definitions/UpdateChannelArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(AddRelationResults) async def AddRelation(self, endpoints=None, via_cidrs=None): - ''' + """ AddRelation adds a relation between the specified endpoints and returns the relation info. endpoints : typing.Sequence[str] via_cidrs : typing.Sequence[str] Returns -> AddRelationResults - ''' + """ if endpoints is not None and not isinstance(endpoints, (bytes, str, list)): - raise Exception("Expected endpoints to be a Sequence, received: {}".format(type(endpoints))) + raise Exception( + "Expected endpoints to be a Sequence, received: {}".format( + type(endpoints) + ) + ) if via_cidrs is not None and not isinstance(via_cidrs, (bytes, str, list)): - raise Exception("Expected via_cidrs to be a Sequence, received: {}".format(type(via_cidrs))) + raise Exception( + "Expected via_cidrs to be a Sequence, received: {}".format( + type(via_cidrs) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='AddRelation', - version=19, - params=_params) - _params['endpoints'] = endpoints - _params['via-cidrs'] = via_cidrs + msg = dict( + type="Application", request="AddRelation", version=19, params=_params + ) + _params["endpoints"] = endpoints + _params["via-cidrs"] = via_cidrs reply = await self.rpc(msg) return reply - - @ReturnMapping(AddApplicationUnitsResults) - async def AddUnits(self, application=None, attach_storage=None, num_units=None, placement=None, policy=None): - ''' + async def AddUnits( + self, + application=None, + attach_storage=None, + num_units=None, + placement=None, + policy=None, + ): + """ AddUnits adds a given number of units to an application. application : str @@ -1008,159 +1605,171 @@ async def AddUnits(self, application=None, attach_storage=None, num_units=None, placement : typing.Sequence[~Placement] policy : str Returns -> AddApplicationUnitsResults - ''' + """ if application is not None and not isinstance(application, (bytes, str)): - raise Exception("Expected application to be a str, received: {}".format(type(application))) - - if attach_storage is not None and not isinstance(attach_storage, (bytes, str, list)): - raise Exception("Expected attach_storage to be a Sequence, received: {}".format(type(attach_storage))) + raise Exception( + "Expected application to be a str, received: {}".format( + type(application) + ) + ) + + if attach_storage is not None and not isinstance( + attach_storage, (bytes, str, list) + ): + raise Exception( + "Expected attach_storage to be a Sequence, received: {}".format( + type(attach_storage) + ) + ) if num_units is not None and not isinstance(num_units, int): - raise Exception("Expected num_units to be a int, received: {}".format(type(num_units))) + raise Exception( + "Expected num_units to be a int, received: {}".format(type(num_units)) + ) if placement is not None and not isinstance(placement, (bytes, str, list)): - raise Exception("Expected placement to be a Sequence, received: {}".format(type(placement))) + raise Exception( + "Expected placement to be a Sequence, received: {}".format( + type(placement) + ) + ) if policy is not None and not isinstance(policy, (bytes, str)): - raise Exception("Expected policy to be a str, received: {}".format(type(policy))) + raise Exception( + "Expected policy to be a str, received: {}".format(type(policy)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='AddUnits', - version=19, - params=_params) - _params['application'] = application - _params['attach-storage'] = attach_storage - _params['num-units'] = num_units - _params['placement'] = placement - _params['policy'] = policy + msg = dict(type="Application", request="AddUnits", version=19, params=_params) + _params["application"] = application + _params["attach-storage"] = attach_storage + _params["num-units"] = num_units + _params["placement"] = placement + _params["policy"] = policy reply = await self.rpc(msg) return reply - - @ReturnMapping(ApplicationInfoResults) async def ApplicationsInfo(self, entities=None): - ''' + """ ApplicationsInfo returns applications information. entities : typing.Sequence[~Entity] Returns -> ApplicationInfoResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='ApplicationsInfo', - version=19, - params=_params) - _params['entities'] = entities + msg = dict( + type="Application", request="ApplicationsInfo", version=19, params=_params + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ApplicationGetConfigResults) async def CharmConfig(self, args=None): - ''' + """ CharmConfig returns charm config for the input list of applications and model generations. args : typing.Sequence[~ApplicationGet] Returns -> ApplicationGetConfigResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='CharmConfig', - version=19, - params=_params) - _params['args'] = args + msg = dict( + type="Application", request="CharmConfig", version=19, params=_params + ) + _params["args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(ApplicationCharmRelationsResults) async def CharmRelations(self, application=None): - ''' + """ CharmRelations implements the server side of Application.CharmRelations. application : str Returns -> ApplicationCharmRelationsResults - ''' + """ if application is not None and not isinstance(application, (bytes, str)): - raise Exception("Expected application to be a str, received: {}".format(type(application))) + raise Exception( + "Expected application to be a str, received: {}".format( + type(application) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='CharmRelations', - version=19, - params=_params) - _params['application'] = application + msg = dict( + type="Application", request="CharmRelations", version=19, params=_params + ) + _params["application"] = application reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def Consume(self, args=None): - ''' + """ Consume adds remote applications to the model without creating any relations. args : typing.Sequence[~ConsumeApplicationArg] Returns -> ErrorResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='Consume', - version=19, - params=_params) - _params['args'] = args + msg = dict(type="Application", request="Consume", version=19, params=_params) + _params["args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def Deploy(self, applications=None): - ''' + """ Deploy fetches the charms from the charm store and deploys them using the specified placement directives. applications : typing.Sequence[~ApplicationDeploy] Returns -> ErrorResults - ''' - if applications is not None and not isinstance(applications, (bytes, str, list)): - raise Exception("Expected applications to be a Sequence, received: {}".format(type(applications))) + """ + if applications is not None and not isinstance( + applications, (bytes, str, list) + ): + raise Exception( + "Expected applications to be a Sequence, received: {}".format( + type(applications) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='Deploy', - version=19, - params=_params) - _params['applications'] = applications + msg = dict(type="Application", request="Deploy", version=19, params=_params) + _params["applications"] = applications reply = await self.rpc(msg) return reply - - @ReturnMapping(DeployFromRepositoryResults) async def DeployFromRepository(self, args=None): - ''' + """ DeployFromRepository is a one-stop deployment method for repository charms. Only a charm name is required to deploy. If argument validation fails, a list of all errors found in validation will be returned. If a @@ -1169,71 +1778,84 @@ async def DeployFromRepository(self, args=None): args : typing.Sequence[~DeployFromRepositoryArg] Returns -> DeployFromRepositoryResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='DeployFromRepository', - version=19, - params=_params) - _params['Args'] = args + msg = dict( + type="Application", + request="DeployFromRepository", + version=19, + params=_params, + ) + _params["Args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(DestroyApplicationResults) async def DestroyApplication(self, applications=None): - ''' + """ DestroyApplication removes a given set of applications. applications : typing.Sequence[~DestroyApplicationParams] Returns -> DestroyApplicationResults - ''' - if applications is not None and not isinstance(applications, (bytes, str, list)): - raise Exception("Expected applications to be a Sequence, received: {}".format(type(applications))) + """ + if applications is not None and not isinstance( + applications, (bytes, str, list) + ): + raise Exception( + "Expected applications to be a Sequence, received: {}".format( + type(applications) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='DestroyApplication', - version=19, - params=_params) - _params['applications'] = applications + msg = dict( + type="Application", request="DestroyApplication", version=19, params=_params + ) + _params["applications"] = applications reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def DestroyConsumedApplications(self, applications=None): - ''' + """ DestroyConsumedApplications removes a given set of consumed (remote) applications. applications : typing.Sequence[~DestroyConsumedApplicationParams] Returns -> ErrorResults - ''' - if applications is not None and not isinstance(applications, (bytes, str, list)): - raise Exception("Expected applications to be a Sequence, received: {}".format(type(applications))) + """ + if applications is not None and not isinstance( + applications, (bytes, str, list) + ): + raise Exception( + "Expected applications to be a Sequence, received: {}".format( + type(applications) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='DestroyConsumedApplications', - version=19, - params=_params) - _params['applications'] = applications + msg = dict( + type="Application", + request="DestroyConsumedApplications", + version=19, + params=_params, + ) + _params["applications"] = applications reply = await self.rpc(msg) return reply - - @ReturnMapping(None) - async def DestroyRelation(self, endpoints=None, force=None, max_wait=None, relation_id=None): - ''' + async def DestroyRelation( + self, endpoints=None, force=None, max_wait=None, relation_id=None + ): + """ DestroyRelation removes the relation between the specified endpoints or an id. @@ -1242,295 +1864,325 @@ async def DestroyRelation(self, endpoints=None, force=None, max_wait=None, relat max_wait : int relation_id : int Returns -> None - ''' + """ if endpoints is not None and not isinstance(endpoints, (bytes, str, list)): - raise Exception("Expected endpoints to be a Sequence, received: {}".format(type(endpoints))) + raise Exception( + "Expected endpoints to be a Sequence, received: {}".format( + type(endpoints) + ) + ) if force is not None and not isinstance(force, bool): - raise Exception("Expected force to be a bool, received: {}".format(type(force))) + raise Exception( + "Expected force to be a bool, received: {}".format(type(force)) + ) if max_wait is not None and not isinstance(max_wait, int): - raise Exception("Expected max_wait to be a int, received: {}".format(type(max_wait))) + raise Exception( + "Expected max_wait to be a int, received: {}".format(type(max_wait)) + ) if relation_id is not None and not isinstance(relation_id, int): - raise Exception("Expected relation_id to be a int, received: {}".format(type(relation_id))) + raise Exception( + "Expected relation_id to be a int, received: {}".format( + type(relation_id) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='DestroyRelation', - version=19, - params=_params) - _params['endpoints'] = endpoints - _params['force'] = force - _params['max-wait'] = max_wait - _params['relation-id'] = relation_id + msg = dict( + type="Application", request="DestroyRelation", version=19, params=_params + ) + _params["endpoints"] = endpoints + _params["force"] = force + _params["max-wait"] = max_wait + _params["relation-id"] = relation_id reply = await self.rpc(msg) return reply - - @ReturnMapping(DestroyUnitResults) async def DestroyUnit(self, units=None): - ''' + """ DestroyUnit removes a given set of application units. units : typing.Sequence[~DestroyUnitParams] Returns -> DestroyUnitResults - ''' + """ if units is not None and not isinstance(units, (bytes, str, list)): - raise Exception("Expected units to be a Sequence, received: {}".format(type(units))) + raise Exception( + "Expected units to be a Sequence, received: {}".format(type(units)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='DestroyUnit', - version=19, - params=_params) - _params['units'] = units + msg = dict( + type="Application", request="DestroyUnit", version=19, params=_params + ) + _params["units"] = units reply = await self.rpc(msg) return reply - - @ReturnMapping(None) async def Expose(self, application=None, exposed_endpoints=None): - ''' + """ Expose changes the juju-managed firewall to expose any ports that were also explicitly marked by units as open. application : str exposed_endpoints : typing.Mapping[str, ~ExposedEndpoint] Returns -> None - ''' + """ if application is not None and not isinstance(application, (bytes, str)): - raise Exception("Expected application to be a str, received: {}".format(type(application))) + raise Exception( + "Expected application to be a str, received: {}".format( + type(application) + ) + ) if exposed_endpoints is not None and not isinstance(exposed_endpoints, dict): - raise Exception("Expected exposed_endpoints to be a Mapping, received: {}".format(type(exposed_endpoints))) + raise Exception( + "Expected exposed_endpoints to be a Mapping, received: {}".format( + type(exposed_endpoints) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='Expose', - version=19, - params=_params) - _params['application'] = application - _params['exposed-endpoints'] = exposed_endpoints + msg = dict(type="Application", request="Expose", version=19, params=_params) + _params["application"] = application + _params["exposed-endpoints"] = exposed_endpoints reply = await self.rpc(msg) return reply - - @ReturnMapping(ApplicationGetResults) async def Get(self, application=None, branch=None): - ''' + """ Get returns the charm configuration for an application. application : str branch : str Returns -> ApplicationGetResults - ''' + """ if application is not None and not isinstance(application, (bytes, str)): - raise Exception("Expected application to be a str, received: {}".format(type(application))) + raise Exception( + "Expected application to be a str, received: {}".format( + type(application) + ) + ) if branch is not None and not isinstance(branch, (bytes, str)): - raise Exception("Expected branch to be a str, received: {}".format(type(branch))) + raise Exception( + "Expected branch to be a str, received: {}".format(type(branch)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='Get', - version=19, - params=_params) - _params['application'] = application - _params['branch'] = branch + msg = dict(type="Application", request="Get", version=19, params=_params) + _params["application"] = application + _params["branch"] = branch reply = await self.rpc(msg) return reply - - @ReturnMapping(CharmURLOriginResult) async def GetCharmURLOrigin(self, application=None, branch=None): - ''' + """ GetCharmURLOrigin returns the charm URL and charm origin the given application is running at present. application : str branch : str Returns -> CharmURLOriginResult - ''' + """ if application is not None and not isinstance(application, (bytes, str)): - raise Exception("Expected application to be a str, received: {}".format(type(application))) + raise Exception( + "Expected application to be a str, received: {}".format( + type(application) + ) + ) if branch is not None and not isinstance(branch, (bytes, str)): - raise Exception("Expected branch to be a str, received: {}".format(type(branch))) + raise Exception( + "Expected branch to be a str, received: {}".format(type(branch)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='GetCharmURLOrigin', - version=19, - params=_params) - _params['application'] = application - _params['branch'] = branch + msg = dict( + type="Application", request="GetCharmURLOrigin", version=19, params=_params + ) + _params["application"] = application + _params["branch"] = branch reply = await self.rpc(msg) return reply - - @ReturnMapping(ApplicationGetConfigResults) async def GetConfig(self, entities=None): - ''' + """ GetConfig returns the charm config for each of the input applications. entities : typing.Sequence[~Entity] Returns -> ApplicationGetConfigResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='GetConfig', - version=19, - params=_params) - _params['entities'] = entities + msg = dict(type="Application", request="GetConfig", version=19, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ApplicationGetConstraintsResults) async def GetConstraints(self, entities=None): - ''' + """ GetConstraints returns the constraints for a given application. entities : typing.Sequence[~Entity] Returns -> ApplicationGetConstraintsResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='GetConstraints', - version=19, - params=_params) - _params['entities'] = entities + msg = dict( + type="Application", request="GetConstraints", version=19, params=_params + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(StringResult) async def Leader(self, tag=None): - ''' + """ Leader returns the unit name of the leader for the given application. tag : str Returns -> StringResult - ''' + """ if tag is not None and not isinstance(tag, (bytes, str)): raise Exception("Expected tag to be a str, received: {}".format(type(tag))) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='Leader', - version=19, - params=_params) - _params['tag'] = tag + msg = dict(type="Application", request="Leader", version=19, params=_params) + _params["tag"] = tag reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def MergeBindings(self, args=None): - ''' + """ MergeBindings merges operator-defined bindings with the current bindings for one or more applications. args : typing.Sequence[~ApplicationMergeBindings] Returns -> ErrorResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='MergeBindings', - version=19, - params=_params) - _params['args'] = args + msg = dict( + type="Application", request="MergeBindings", version=19, params=_params + ) + _params["args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def ResolveUnitErrors(self, all_=None, retry=None, tags=None): - ''' + """ ResolveUnitErrors marks errors on the specified units as resolved. all_ : bool retry : bool tags : Entities Returns -> ErrorResults - ''' + """ if all_ is not None and not isinstance(all_, bool): - raise Exception("Expected all_ to be a bool, received: {}".format(type(all_))) + raise Exception( + "Expected all_ to be a bool, received: {}".format(type(all_)) + ) if retry is not None and not isinstance(retry, bool): - raise Exception("Expected retry to be a bool, received: {}".format(type(retry))) + raise Exception( + "Expected retry to be a bool, received: {}".format(type(retry)) + ) if tags is not None and not isinstance(tags, (dict, Entities)): - raise Exception("Expected tags to be a Entities, received: {}".format(type(tags))) + raise Exception( + "Expected tags to be a Entities, received: {}".format(type(tags)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='ResolveUnitErrors', - version=19, - params=_params) - _params['all'] = all_ - _params['retry'] = retry - _params['tags'] = tags + msg = dict( + type="Application", request="ResolveUnitErrors", version=19, params=_params + ) + _params["all"] = all_ + _params["retry"] = retry + _params["tags"] = tags reply = await self.rpc(msg) return reply - - @ReturnMapping(ScaleApplicationResults) async def ScaleApplications(self, applications=None): - ''' + """ ScaleApplications scales the specified application to the requested number of units. applications : typing.Sequence[~ScaleApplicationParams] Returns -> ScaleApplicationResults - ''' - if applications is not None and not isinstance(applications, (bytes, str, list)): - raise Exception("Expected applications to be a Sequence, received: {}".format(type(applications))) + """ + if applications is not None and not isinstance( + applications, (bytes, str, list) + ): + raise Exception( + "Expected applications to be a Sequence, received: {}".format( + type(applications) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='ScaleApplications', - version=19, - params=_params) - _params['applications'] = applications + msg = dict( + type="Application", request="ScaleApplications", version=19, params=_params + ) + _params["applications"] = applications reply = await self.rpc(msg) return reply - - @ReturnMapping(None) - async def SetCharm(self, application=None, channel=None, charm_origin=None, charm_url=None, config_settings=None, config_settings_yaml=None, endpoint_bindings=None, force=None, force_base=None, force_units=None, generation=None, resource_ids=None, storage_constraints=None): - ''' + async def SetCharm( + self, + application=None, + channel=None, + charm_origin=None, + charm_url=None, + config_settings=None, + config_settings_yaml=None, + endpoint_bindings=None, + force=None, + force_base=None, + force_units=None, + generation=None, + resource_ids=None, + storage_constraints=None, + ): + """ SetCharm sets the charm for a given for the application. application : str @@ -1547,267 +2199,326 @@ async def SetCharm(self, application=None, channel=None, charm_origin=None, char resource_ids : typing.Mapping[str, str] storage_constraints : typing.Mapping[str, ~StorageConstraints] Returns -> None - ''' + """ if application is not None and not isinstance(application, (bytes, str)): - raise Exception("Expected application to be a str, received: {}".format(type(application))) + raise Exception( + "Expected application to be a str, received: {}".format( + type(application) + ) + ) if channel is not None and not isinstance(channel, (bytes, str)): - raise Exception("Expected channel to be a str, received: {}".format(type(channel))) - - if charm_origin is not None and not isinstance(charm_origin, (dict, CharmOrigin)): - raise Exception("Expected charm_origin to be a CharmOrigin, received: {}".format(type(charm_origin))) + raise Exception( + "Expected channel to be a str, received: {}".format(type(channel)) + ) + + if charm_origin is not None and not isinstance( + charm_origin, (dict, CharmOrigin) + ): + raise Exception( + "Expected charm_origin to be a CharmOrigin, received: {}".format( + type(charm_origin) + ) + ) if charm_url is not None and not isinstance(charm_url, (bytes, str)): - raise Exception("Expected charm_url to be a str, received: {}".format(type(charm_url))) + raise Exception( + "Expected charm_url to be a str, received: {}".format(type(charm_url)) + ) if config_settings is not None and not isinstance(config_settings, dict): - raise Exception("Expected config_settings to be a Mapping, received: {}".format(type(config_settings))) - - if config_settings_yaml is not None and not isinstance(config_settings_yaml, (bytes, str)): - raise Exception("Expected config_settings_yaml to be a str, received: {}".format(type(config_settings_yaml))) + raise Exception( + "Expected config_settings to be a Mapping, received: {}".format( + type(config_settings) + ) + ) + + if config_settings_yaml is not None and not isinstance( + config_settings_yaml, (bytes, str) + ): + raise Exception( + "Expected config_settings_yaml to be a str, received: {}".format( + type(config_settings_yaml) + ) + ) if endpoint_bindings is not None and not isinstance(endpoint_bindings, dict): - raise Exception("Expected endpoint_bindings to be a Mapping, received: {}".format(type(endpoint_bindings))) + raise Exception( + "Expected endpoint_bindings to be a Mapping, received: {}".format( + type(endpoint_bindings) + ) + ) if force is not None and not isinstance(force, bool): - raise Exception("Expected force to be a bool, received: {}".format(type(force))) + raise Exception( + "Expected force to be a bool, received: {}".format(type(force)) + ) if force_base is not None and not isinstance(force_base, bool): - raise Exception("Expected force_base to be a bool, received: {}".format(type(force_base))) + raise Exception( + "Expected force_base to be a bool, received: {}".format( + type(force_base) + ) + ) if force_units is not None and not isinstance(force_units, bool): - raise Exception("Expected force_units to be a bool, received: {}".format(type(force_units))) + raise Exception( + "Expected force_units to be a bool, received: {}".format( + type(force_units) + ) + ) if generation is not None and not isinstance(generation, (bytes, str)): - raise Exception("Expected generation to be a str, received: {}".format(type(generation))) + raise Exception( + "Expected generation to be a str, received: {}".format(type(generation)) + ) if resource_ids is not None and not isinstance(resource_ids, dict): - raise Exception("Expected resource_ids to be a Mapping, received: {}".format(type(resource_ids))) - - if storage_constraints is not None and not isinstance(storage_constraints, dict): - raise Exception("Expected storage_constraints to be a Mapping, received: {}".format(type(storage_constraints))) + raise Exception( + "Expected resource_ids to be a Mapping, received: {}".format( + type(resource_ids) + ) + ) + + if storage_constraints is not None and not isinstance( + storage_constraints, dict + ): + raise Exception( + "Expected storage_constraints to be a Mapping, received: {}".format( + type(storage_constraints) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='SetCharm', - version=19, - params=_params) - _params['application'] = application - _params['channel'] = channel - _params['charm-origin'] = charm_origin - _params['charm-url'] = charm_url - _params['config-settings'] = config_settings - _params['config-settings-yaml'] = config_settings_yaml - _params['endpoint-bindings'] = endpoint_bindings - _params['force'] = force - _params['force-base'] = force_base - _params['force-units'] = force_units - _params['generation'] = generation - _params['resource-ids'] = resource_ids - _params['storage-constraints'] = storage_constraints + msg = dict(type="Application", request="SetCharm", version=19, params=_params) + _params["application"] = application + _params["channel"] = channel + _params["charm-origin"] = charm_origin + _params["charm-url"] = charm_url + _params["config-settings"] = config_settings + _params["config-settings-yaml"] = config_settings_yaml + _params["endpoint-bindings"] = endpoint_bindings + _params["force"] = force + _params["force-base"] = force_base + _params["force-units"] = force_units + _params["generation"] = generation + _params["resource-ids"] = resource_ids + _params["storage-constraints"] = storage_constraints reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def SetConfigs(self, args=None): - ''' + """ SetConfigs implements the server side of Application.SetConfig. Both application and charm config are set. It does not unset values in Config map that are set to an empty string. Unset should be used for that. args : typing.Sequence[~ConfigSet] Returns -> ErrorResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='SetConfigs', - version=19, - params=_params) - _params['Args'] = args + msg = dict(type="Application", request="SetConfigs", version=19, params=_params) + _params["Args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(None) async def SetConstraints(self, application=None, constraints=None): - ''' + """ SetConstraints sets the constraints for a given application. application : str constraints : Value Returns -> None - ''' + """ if application is not None and not isinstance(application, (bytes, str)): - raise Exception("Expected application to be a str, received: {}".format(type(application))) + raise Exception( + "Expected application to be a str, received: {}".format( + type(application) + ) + ) if constraints is not None and not isinstance(constraints, (dict, Value)): - raise Exception("Expected constraints to be a Value, received: {}".format(type(constraints))) + raise Exception( + "Expected constraints to be a Value, received: {}".format( + type(constraints) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='SetConstraints', - version=19, - params=_params) - _params['application'] = application - _params['constraints'] = constraints + msg = dict( + type="Application", request="SetConstraints", version=19, params=_params + ) + _params["application"] = application + _params["constraints"] = constraints reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def SetMetricCredentials(self, creds=None): - ''' + """ SetMetricCredentials sets credentials on the application. TODO (cderici) only used for metered charms in cmd MeteredDeployAPI, kept for client compatibility, remove in juju 4.0 creds : typing.Sequence[~ApplicationMetricCredential] Returns -> ErrorResults - ''' + """ if creds is not None and not isinstance(creds, (bytes, str, list)): - raise Exception("Expected creds to be a Sequence, received: {}".format(type(creds))) + raise Exception( + "Expected creds to be a Sequence, received: {}".format(type(creds)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='SetMetricCredentials', - version=19, - params=_params) - _params['creds'] = creds + msg = dict( + type="Application", + request="SetMetricCredentials", + version=19, + params=_params, + ) + _params["creds"] = creds reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def SetRelationsSuspended(self, args=None): - ''' + """ SetRelationsSuspended sets the suspended status of the specified relations. args : typing.Sequence[~RelationSuspendedArg] Returns -> ErrorResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='SetRelationsSuspended', - version=19, - params=_params) - _params['args'] = args + msg = dict( + type="Application", + request="SetRelationsSuspended", + version=19, + params=_params, + ) + _params["args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(None) async def Unexpose(self, application=None, exposed_endpoints=None): - ''' + """ Unexpose changes the juju-managed firewall to unexpose any ports that were also explicitly marked by units as open. application : str exposed_endpoints : typing.Sequence[str] Returns -> None - ''' + """ if application is not None and not isinstance(application, (bytes, str)): - raise Exception("Expected application to be a str, received: {}".format(type(application))) - - if exposed_endpoints is not None and not isinstance(exposed_endpoints, (bytes, str, list)): - raise Exception("Expected exposed_endpoints to be a Sequence, received: {}".format(type(exposed_endpoints))) + raise Exception( + "Expected application to be a str, received: {}".format( + type(application) + ) + ) + + if exposed_endpoints is not None and not isinstance( + exposed_endpoints, (bytes, str, list) + ): + raise Exception( + "Expected exposed_endpoints to be a Sequence, received: {}".format( + type(exposed_endpoints) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='Unexpose', - version=19, - params=_params) - _params['application'] = application - _params['exposed-endpoints'] = exposed_endpoints + msg = dict(type="Application", request="Unexpose", version=19, params=_params) + _params["application"] = application + _params["exposed-endpoints"] = exposed_endpoints reply = await self.rpc(msg) return reply - - @ReturnMapping(UnitInfoResults) async def UnitsInfo(self, entities=None): - ''' + """ UnitsInfo returns unit information for the given entities (units or applications). entities : typing.Sequence[~Entity] Returns -> UnitInfoResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='UnitsInfo', - version=19, - params=_params) - _params['entities'] = entities + msg = dict(type="Application", request="UnitsInfo", version=19, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def UnsetApplicationsConfig(self, args=None): - ''' + """ UnsetApplicationsConfig implements the server side of Application.UnsetApplicationsConfig. args : typing.Sequence[~ApplicationUnset] Returns -> ErrorResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='UnsetApplicationsConfig', - version=19, - params=_params) - _params['Args'] = args + msg = dict( + type="Application", + request="UnsetApplicationsConfig", + version=19, + params=_params, + ) + _params["Args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def UpdateApplicationBase(self, args=None): - ''' + """ UpdateApplicationBase updates the application base. Base for subordinates is updated too. args : typing.Sequence[~UpdateChannelArg] Returns -> ErrorResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='UpdateApplicationBase', - version=19, - params=_params) - _params['args'] = args + msg = dict( + type="Application", + request="UpdateApplicationBase", + version=19, + params=_params, + ) + _params["args"] = args reply = await self.rpc(msg) return reply - - diff --git a/juju/client/_client2.py b/juju/client/_client2.py index d9b6941a1..7101c77d1 100644 --- a/juju/client/_client2.py +++ b/juju/client/_client2.py @@ -6,847 +6,1158 @@ class AnnotationsFacade(Type): - name = 'Annotations' + name = "Annotations" version = 2 - schema = {'definitions': {'AnnotationsGetResult': {'additionalProperties': False, - 'properties': {'annotations': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'entity': {'type': 'string'}, - 'error': {'$ref': '#/definitions/ErrorResult'}}, - 'required': ['entity', 'annotations'], - 'type': 'object'}, - 'AnnotationsGetResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/AnnotationsGetResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'AnnotationsSet': {'additionalProperties': False, - 'properties': {'annotations': {'items': {'$ref': '#/definitions/EntityAnnotations'}, - 'type': 'array'}}, - 'required': ['annotations'], - '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'}, - 'EntityAnnotations': {'additionalProperties': False, - 'properties': {'annotations': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'entity': {'type': 'string'}}, - 'required': ['entity', 'annotations'], - 'type': 'object'}, - 'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - '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'}}, - 'properties': {'Get': {'description': 'Get returns annotations for given ' - 'entities.\n' - 'If annotations cannot be retrieved for ' - 'a given entity, an error is returned.\n' - 'Each entity is treated independently ' - 'and, hence, will fail or succeed ' - 'independently.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/AnnotationsGetResults'}}, - 'type': 'object'}, - 'Set': {'description': 'Set stores annotations for given ' - 'entities', - 'properties': {'Params': {'$ref': '#/definitions/AnnotationsSet'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "AnnotationsGetResult": { + "additionalProperties": False, + "properties": { + "annotations": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "entity": {"type": "string"}, + "error": {"$ref": "#/definitions/ErrorResult"}, + }, + "required": ["entity", "annotations"], + "type": "object", + }, + "AnnotationsGetResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/AnnotationsGetResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "AnnotationsSet": { + "additionalProperties": False, + "properties": { + "annotations": { + "items": {"$ref": "#/definitions/EntityAnnotations"}, + "type": "array", + } + }, + "required": ["annotations"], + "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", + }, + "EntityAnnotations": { + "additionalProperties": False, + "properties": { + "annotations": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "entity": {"type": "string"}, + }, + "required": ["entity", "annotations"], + "type": "object", + }, + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "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", + }, + }, + "properties": { + "Get": { + "description": "Get returns annotations for given " + "entities.\n" + "If annotations cannot be retrieved for " + "a given entity, an error is returned.\n" + "Each entity is treated independently " + "and, hence, will fail or succeed " + "independently.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/AnnotationsGetResults"}, + }, + "type": "object", + }, + "Set": { + "description": "Set stores annotations for given entities", + "properties": { + "Params": {"$ref": "#/definitions/AnnotationsSet"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(AnnotationsGetResults) async def Get(self, entities=None): - ''' + """ Get returns annotations for given entities. If annotations cannot be retrieved for a given entity, an error is returned. Each entity is treated independently and, hence, will fail or succeed independently. entities : typing.Sequence[~Entity] Returns -> AnnotationsGetResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Annotations', - request='Get', - version=2, - params=_params) - _params['entities'] = entities + msg = dict(type="Annotations", request="Get", version=2, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def Set(self, annotations=None): - ''' + """ Set stores annotations for given entities annotations : typing.Sequence[~EntityAnnotations] Returns -> ErrorResults - ''' + """ if annotations is not None and not isinstance(annotations, (bytes, str, list)): - raise Exception("Expected annotations to be a Sequence, received: {}".format(type(annotations))) + raise Exception( + "Expected annotations to be a Sequence, received: {}".format( + type(annotations) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Annotations', - request='Set', - version=2, - params=_params) - _params['annotations'] = annotations + msg = dict(type="Annotations", request="Set", version=2, params=_params) + _params["annotations"] = annotations reply = await self.rpc(msg) return reply - class BlockFacade(Type): - name = 'Block' + name = "Block" version = 2 - schema = {'definitions': {'Block': {'additionalProperties': False, - 'properties': {'id': {'type': 'string'}, - 'message': {'type': 'string'}, - 'tag': {'type': 'string'}, - 'type': {'type': 'string'}}, - 'required': ['id', 'tag', 'type'], - 'type': 'object'}, - 'BlockResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/Block'}}, - 'required': ['result'], - 'type': 'object'}, - 'BlockResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/BlockResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'BlockSwitchParams': {'additionalProperties': False, - 'properties': {'message': {'type': 'string'}, - 'type': {'type': 'string'}}, - 'required': ['type'], - 'type': 'object'}, - 'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - 'type': 'object'}, - 'ErrorResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}}, - 'type': 'object'}}, - 'properties': {'List': {'description': 'List implements Block.List().', - 'properties': {'Result': {'$ref': '#/definitions/BlockResults'}}, - 'type': 'object'}, - 'SwitchBlockOff': {'description': 'SwitchBlockOff implements ' - 'Block.SwitchBlockOff().', - 'properties': {'Params': {'$ref': '#/definitions/BlockSwitchParams'}, - 'Result': {'$ref': '#/definitions/ErrorResult'}}, - 'type': 'object'}, - 'SwitchBlockOn': {'description': 'SwitchBlockOn implements ' - 'Block.SwitchBlockOn().', - 'properties': {'Params': {'$ref': '#/definitions/BlockSwitchParams'}, - 'Result': {'$ref': '#/definitions/ErrorResult'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "Block": { + "additionalProperties": False, + "properties": { + "id": {"type": "string"}, + "message": {"type": "string"}, + "tag": {"type": "string"}, + "type": {"type": "string"}, + }, + "required": ["id", "tag", "type"], + "type": "object", + }, + "BlockResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/Block"}, + }, + "required": ["result"], + "type": "object", + }, + "BlockResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/BlockResult"}, + "type": "array", + } + }, + "type": "object", + }, + "BlockSwitchParams": { + "additionalProperties": False, + "properties": { + "message": {"type": "string"}, + "type": {"type": "string"}, + }, + "required": ["type"], + "type": "object", + }, + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "type": "object", + }, + "ErrorResult": { + "additionalProperties": False, + "properties": {"error": {"$ref": "#/definitions/Error"}}, + "type": "object", + }, + }, + "properties": { + "List": { + "description": "List implements Block.List().", + "properties": {"Result": {"$ref": "#/definitions/BlockResults"}}, + "type": "object", + }, + "SwitchBlockOff": { + "description": "SwitchBlockOff implements Block.SwitchBlockOff().", + "properties": { + "Params": {"$ref": "#/definitions/BlockSwitchParams"}, + "Result": {"$ref": "#/definitions/ErrorResult"}, + }, + "type": "object", + }, + "SwitchBlockOn": { + "description": "SwitchBlockOn implements Block.SwitchBlockOn().", + "properties": { + "Params": {"$ref": "#/definitions/BlockSwitchParams"}, + "Result": {"$ref": "#/definitions/ErrorResult"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(BlockResults) async def List(self): - ''' + """ List implements Block.List(). Returns -> BlockResults - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Block', - request='List', - version=2, - params=_params) + msg = dict(type="Block", request="List", version=2, params=_params) reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResult) async def SwitchBlockOff(self, message=None, type_=None): - ''' + """ SwitchBlockOff implements Block.SwitchBlockOff(). message : str type_ : str Returns -> ErrorResult - ''' + """ if message is not None and not isinstance(message, (bytes, str)): - raise Exception("Expected message to be a str, received: {}".format(type(message))) + raise Exception( + "Expected message to be a str, received: {}".format(type(message)) + ) if type_ is not None and not isinstance(type_, (bytes, str)): - raise Exception("Expected type_ to be a str, received: {}".format(type(type_))) + raise Exception( + "Expected type_ to be a str, received: {}".format(type(type_)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Block', - request='SwitchBlockOff', - version=2, - params=_params) - _params['message'] = message - _params['type'] = type_ + msg = dict(type="Block", request="SwitchBlockOff", version=2, params=_params) + _params["message"] = message + _params["type"] = type_ reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResult) async def SwitchBlockOn(self, message=None, type_=None): - ''' + """ SwitchBlockOn implements Block.SwitchBlockOn(). message : str type_ : str Returns -> ErrorResult - ''' + """ if message is not None and not isinstance(message, (bytes, str)): - raise Exception("Expected message to be a str, received: {}".format(type(message))) + raise Exception( + "Expected message to be a str, received: {}".format(type(message)) + ) if type_ is not None and not isinstance(type_, (bytes, str)): - raise Exception("Expected type_ to be a str, received: {}".format(type(type_))) + raise Exception( + "Expected type_ to be a str, received: {}".format(type(type_)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Block', - request='SwitchBlockOn', - version=2, - params=_params) - _params['message'] = message - _params['type'] = type_ + msg = dict(type="Block", request="SwitchBlockOn", version=2, params=_params) + _params["message"] = message + _params["type"] = type_ reply = await self.rpc(msg) return reply - class HighAvailabilityFacade(Type): - name = 'HighAvailability' + name = "HighAvailability" version = 2 - schema = {'definitions': {'ControllersChangeResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/ControllersChanges'}}, - 'required': ['result'], - 'type': 'object'}, - 'ControllersChangeResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ControllersChangeResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'ControllersChanges': {'additionalProperties': False, - 'properties': {'added': {'items': {'type': 'string'}, - 'type': 'array'}, - 'converted': {'items': {'type': 'string'}, - 'type': 'array'}, - 'maintained': {'items': {'type': 'string'}, - 'type': 'array'}, - 'removed': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'ControllersSpec': {'additionalProperties': False, - 'properties': {'constraints': {'$ref': '#/definitions/Value'}, - 'num-controllers': {'type': 'integer'}, - 'placement': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['num-controllers'], - 'type': 'object'}, - 'ControllersSpecs': {'additionalProperties': False, - 'properties': {'specs': {'items': {'$ref': '#/definitions/ControllersSpec'}, - 'type': 'array'}}, - 'required': ['specs'], - 'type': 'object'}, - 'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - 'type': 'object'}, - 'Value': {'additionalProperties': False, - 'properties': {'allocate-public-ip': {'type': 'boolean'}, - 'arch': {'type': 'string'}, - 'container': {'type': 'string'}, - 'cores': {'type': 'integer'}, - 'cpu-power': {'type': 'integer'}, - 'image-id': {'type': 'string'}, - 'instance-role': {'type': 'string'}, - 'instance-type': {'type': 'string'}, - 'mem': {'type': 'integer'}, - 'root-disk': {'type': 'integer'}, - 'root-disk-source': {'type': 'string'}, - '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': {'EnableHA': {'description': 'EnableHA adds controller machines ' - 'as necessary to ensure the\n' - 'controller has the number of ' - 'machines specified.', - 'properties': {'Params': {'$ref': '#/definitions/ControllersSpecs'}, - 'Result': {'$ref': '#/definitions/ControllersChangeResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "ControllersChangeResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/ControllersChanges"}, + }, + "required": ["result"], + "type": "object", + }, + "ControllersChangeResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ControllersChangeResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "ControllersChanges": { + "additionalProperties": False, + "properties": { + "added": {"items": {"type": "string"}, "type": "array"}, + "converted": {"items": {"type": "string"}, "type": "array"}, + "maintained": {"items": {"type": "string"}, "type": "array"}, + "removed": {"items": {"type": "string"}, "type": "array"}, + }, + "type": "object", + }, + "ControllersSpec": { + "additionalProperties": False, + "properties": { + "constraints": {"$ref": "#/definitions/Value"}, + "num-controllers": {"type": "integer"}, + "placement": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["num-controllers"], + "type": "object", + }, + "ControllersSpecs": { + "additionalProperties": False, + "properties": { + "specs": { + "items": {"$ref": "#/definitions/ControllersSpec"}, + "type": "array", + } + }, + "required": ["specs"], + "type": "object", + }, + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "type": "object", + }, + "Value": { + "additionalProperties": False, + "properties": { + "allocate-public-ip": {"type": "boolean"}, + "arch": {"type": "string"}, + "container": {"type": "string"}, + "cores": {"type": "integer"}, + "cpu-power": {"type": "integer"}, + "image-id": {"type": "string"}, + "instance-role": {"type": "string"}, + "instance-type": {"type": "string"}, + "mem": {"type": "integer"}, + "root-disk": {"type": "integer"}, + "root-disk-source": {"type": "string"}, + "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": { + "EnableHA": { + "description": "EnableHA adds controller machines " + "as necessary to ensure the\n" + "controller has the number of " + "machines specified.", + "properties": { + "Params": {"$ref": "#/definitions/ControllersSpecs"}, + "Result": {"$ref": "#/definitions/ControllersChangeResults"}, + }, + "type": "object", + } + }, + "type": "object", + } @ReturnMapping(ControllersChangeResults) async def EnableHA(self, specs=None): - ''' + """ EnableHA adds controller machines as necessary to ensure the controller has the number of machines specified. specs : typing.Sequence[~ControllersSpec] Returns -> ControllersChangeResults - ''' + """ if specs is not None and not isinstance(specs, (bytes, str, list)): - raise Exception("Expected specs to be a Sequence, received: {}".format(type(specs))) + raise Exception( + "Expected specs to be a Sequence, received: {}".format(type(specs)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='HighAvailability', - request='EnableHA', - version=2, - params=_params) - _params['specs'] = specs + msg = dict( + type="HighAvailability", request="EnableHA", version=2, params=_params + ) + _params["specs"] = specs reply = await self.rpc(msg) return reply - class MetricsDebugFacade(Type): - name = 'MetricsDebug' + name = "MetricsDebug" version = 2 - schema = {'definitions': {'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'}, - 'EntityMetrics': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'metrics': {'items': {'$ref': '#/definitions/MetricResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - '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'}, - 'MeterStatusParam': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'type': 'string'}, - 'tag': {'type': 'string'}}, - 'required': ['tag', 'code'], - 'type': 'object'}, - 'MeterStatusParams': {'additionalProperties': False, - 'properties': {'statues': {'items': {'$ref': '#/definitions/MeterStatusParam'}, - 'type': 'array'}}, - 'required': ['statues'], - 'type': 'object'}, - 'MetricResult': {'additionalProperties': False, - 'properties': {'key': {'type': 'string'}, - 'labels': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'time': {'format': 'date-time', - 'type': 'string'}, - 'unit': {'type': 'string'}, - 'value': {'type': 'string'}}, - 'required': ['time', - 'key', - 'value', - 'unit', - 'labels'], - 'type': 'object'}, - 'MetricResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/EntityMetrics'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}}, - 'properties': {'GetMetrics': {'description': 'GetMetrics returns all metrics ' - 'stored by the state server.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/MetricResults'}}, - 'type': 'object'}, - 'SetMeterStatus': {'description': 'SetMeterStatus sets meter ' - 'statuses for entities.', - 'properties': {'Params': {'$ref': '#/definitions/MeterStatusParams'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "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", + }, + "EntityMetrics": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "metrics": { + "items": {"$ref": "#/definitions/MetricResult"}, + "type": "array", + }, + }, + "type": "object", + }, + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "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", + }, + "MeterStatusParam": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": {"type": "string"}, + "tag": {"type": "string"}, + }, + "required": ["tag", "code"], + "type": "object", + }, + "MeterStatusParams": { + "additionalProperties": False, + "properties": { + "statues": { + "items": {"$ref": "#/definitions/MeterStatusParam"}, + "type": "array", + } + }, + "required": ["statues"], + "type": "object", + }, + "MetricResult": { + "additionalProperties": False, + "properties": { + "key": {"type": "string"}, + "labels": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "time": {"format": "date-time", "type": "string"}, + "unit": {"type": "string"}, + "value": {"type": "string"}, + }, + "required": ["time", "key", "value", "unit", "labels"], + "type": "object", + }, + "MetricResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/EntityMetrics"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + }, + "properties": { + "GetMetrics": { + "description": "GetMetrics returns all metrics " + "stored by the state server.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/MetricResults"}, + }, + "type": "object", + }, + "SetMeterStatus": { + "description": "SetMeterStatus sets meter statuses for entities.", + "properties": { + "Params": {"$ref": "#/definitions/MeterStatusParams"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(MetricResults) async def GetMetrics(self, entities=None): - ''' + """ GetMetrics returns all metrics stored by the state server. entities : typing.Sequence[~Entity] Returns -> MetricResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='MetricsDebug', - request='GetMetrics', - version=2, - params=_params) - _params['entities'] = entities + msg = dict(type="MetricsDebug", request="GetMetrics", version=2, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def SetMeterStatus(self, statues=None): - ''' + """ SetMeterStatus sets meter statuses for entities. statues : typing.Sequence[~MeterStatusParam] Returns -> ErrorResults - ''' + """ if statues is not None and not isinstance(statues, (bytes, str, list)): - raise Exception("Expected statues to be a Sequence, received: {}".format(type(statues))) + raise Exception( + "Expected statues to be a Sequence, received: {}".format(type(statues)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='MetricsDebug', - request='SetMeterStatus', - version=2, - params=_params) - _params['statues'] = statues + msg = dict( + type="MetricsDebug", request="SetMeterStatus", version=2, params=_params + ) + _params["statues"] = statues reply = await self.rpc(msg) return reply - class SecretsFacade(Type): - name = 'Secrets' + name = "Secrets" version = 2 - schema = {'definitions': {'AccessInfo': {'additionalProperties': False, - 'properties': {'role': {'type': 'string'}, - 'scope-tag': {'type': 'string'}, - 'target-tag': {'type': 'string'}}, - 'required': ['target-tag', 'scope-tag', 'role'], - 'type': 'object'}, - 'CreateSecretArg': {'additionalProperties': False, - 'properties': {'UpsertSecretArg': {'$ref': '#/definitions/UpsertSecretArg'}, - 'content': {'$ref': '#/definitions/SecretContentParams'}, - 'description': {'type': 'string'}, - 'expire-time': {'format': 'date-time', - 'type': 'string'}, - 'label': {'type': 'string'}, - 'owner-tag': {'type': 'string'}, - 'params': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'rotate-policy': {'type': 'string'}, - 'uri': {'type': 'string'}}, - 'required': ['UpsertSecretArg', - 'owner-tag'], - 'type': 'object'}, - 'CreateSecretArgs': {'additionalProperties': False, - 'properties': {'args': {'items': {'$ref': '#/definitions/CreateSecretArg'}, - 'type': 'array'}}, - 'required': ['args'], - 'type': 'object'}, - 'DeleteSecretArg': {'additionalProperties': False, - 'properties': {'label': {'type': 'string'}, - 'revisions': {'items': {'type': 'integer'}, - 'type': 'array'}, - 'uri': {'type': 'string'}}, - 'required': ['uri', 'label'], - 'type': 'object'}, - 'DeleteSecretArgs': {'additionalProperties': False, - 'properties': {'args': {'items': {'$ref': '#/definitions/DeleteSecretArg'}, - 'type': 'array'}}, - 'required': ['args'], - 'type': 'object'}, - 'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - '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'}, - 'GrantRevokeUserSecretArg': {'additionalProperties': False, - 'properties': {'applications': {'items': {'type': 'string'}, - 'type': 'array'}, - 'label': {'type': 'string'}, - 'uri': {'type': 'string'}}, - 'required': ['uri', - 'label', - 'applications'], - 'type': 'object'}, - 'ListSecretResult': {'additionalProperties': False, - 'properties': {'access': {'items': {'$ref': '#/definitions/AccessInfo'}, - 'type': 'array'}, - 'create-time': {'format': 'date-time', - 'type': 'string'}, - 'description': {'type': 'string'}, - 'label': {'type': 'string'}, - 'latest-expire-time': {'format': 'date-time', - 'type': 'string'}, - 'latest-revision': {'type': 'integer'}, - 'latest-revision-checksum': {'type': 'string'}, - 'next-rotate-time': {'format': 'date-time', - 'type': 'string'}, - 'owner-tag': {'type': 'string'}, - 'revisions': {'items': {'$ref': '#/definitions/SecretRevision'}, - 'type': 'array'}, - 'rotate-policy': {'type': 'string'}, - 'update-time': {'format': 'date-time', - 'type': 'string'}, - 'uri': {'type': 'string'}, - 'value': {'$ref': '#/definitions/SecretValueResult'}, - 'version': {'type': 'integer'}}, - 'required': ['uri', - 'version', - 'owner-tag', - 'latest-revision', - 'latest-revision-checksum', - 'create-time', - 'update-time', - 'revisions'], - 'type': 'object'}, - 'ListSecretResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ListSecretResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'ListSecretsArgs': {'additionalProperties': False, - 'properties': {'filter': {'$ref': '#/definitions/SecretsFilter'}, - 'show-secrets': {'type': 'boolean'}}, - 'required': ['show-secrets', 'filter'], - 'type': 'object'}, - 'SecretContentParams': {'additionalProperties': False, - 'properties': {'checksum': {'type': 'string'}, - 'data': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'value-ref': {'$ref': '#/definitions/SecretValueRef'}}, - 'type': 'object'}, - 'SecretRevision': {'additionalProperties': False, - 'properties': {'backend-name': {'type': 'string'}, - 'create-time': {'format': 'date-time', - 'type': 'string'}, - 'expire-time': {'format': 'date-time', - 'type': 'string'}, - 'revision': {'type': 'integer'}, - 'update-time': {'format': 'date-time', - 'type': 'string'}, - 'value-ref': {'$ref': '#/definitions/SecretValueRef'}}, - 'required': ['revision'], - 'type': 'object'}, - 'SecretValueRef': {'additionalProperties': False, - 'properties': {'backend-id': {'type': 'string'}, - 'revision-id': {'type': 'string'}}, - 'required': ['backend-id', 'revision-id'], - 'type': 'object'}, - 'SecretValueResult': {'additionalProperties': False, - 'properties': {'data': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'error': {'$ref': '#/definitions/Error'}}, - 'type': 'object'}, - 'SecretsFilter': {'additionalProperties': False, - 'properties': {'label': {'type': 'string'}, - 'owner-tag': {'type': 'string'}, - 'revision': {'type': 'integer'}, - 'uri': {'type': 'string'}}, - 'type': 'object'}, - 'StringResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'type': 'string'}}, - 'required': ['result'], - 'type': 'object'}, - 'StringResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/StringResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'UpdateUserSecretArg': {'additionalProperties': False, - 'properties': {'UpsertSecretArg': {'$ref': '#/definitions/UpsertSecretArg'}, - 'auto-prune': {'type': 'boolean'}, - 'content': {'$ref': '#/definitions/SecretContentParams'}, - 'description': {'type': 'string'}, - 'existing-label': {'type': 'string'}, - 'expire-time': {'format': 'date-time', - 'type': 'string'}, - 'label': {'type': 'string'}, - 'params': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'rotate-policy': {'type': 'string'}, - 'uri': {'type': 'string'}}, - 'required': ['UpsertSecretArg', - 'uri', - 'existing-label'], - 'type': 'object'}, - 'UpdateUserSecretArgs': {'additionalProperties': False, - 'properties': {'args': {'items': {'$ref': '#/definitions/UpdateUserSecretArg'}, - 'type': 'array'}}, - 'required': ['args'], - 'type': 'object'}, - 'UpsertSecretArg': {'additionalProperties': False, - 'properties': {'content': {'$ref': '#/definitions/SecretContentParams'}, - 'description': {'type': 'string'}, - 'expire-time': {'format': 'date-time', - 'type': 'string'}, - 'label': {'type': 'string'}, - 'params': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'rotate-policy': {'type': 'string'}}, - 'type': 'object'}}, - 'properties': {'CreateSecrets': {'description': 'CreateSecrets creates new ' - 'secrets.', - 'properties': {'Params': {'$ref': '#/definitions/CreateSecretArgs'}, - 'Result': {'$ref': '#/definitions/StringResults'}}, - 'type': 'object'}, - 'GrantSecret': {'description': 'GrantSecret grants access to a ' - 'user secret.', - 'properties': {'Params': {'$ref': '#/definitions/GrantRevokeUserSecretArg'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'ListSecrets': {'description': 'ListSecrets lists available ' - 'secrets.', - 'properties': {'Params': {'$ref': '#/definitions/ListSecretsArgs'}, - 'Result': {'$ref': '#/definitions/ListSecretResults'}}, - 'type': 'object'}, - 'RemoveSecrets': {'description': 'RemoveSecrets remove user ' - 'secret.', - 'properties': {'Params': {'$ref': '#/definitions/DeleteSecretArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'RevokeSecret': {'description': 'RevokeSecret revokes access ' - 'to a user secret.', - 'properties': {'Params': {'$ref': '#/definitions/GrantRevokeUserSecretArg'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'UpdateSecrets': {'description': 'UpdateSecrets creates new ' - 'secrets.', - 'properties': {'Params': {'$ref': '#/definitions/UpdateUserSecretArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "AccessInfo": { + "additionalProperties": False, + "properties": { + "role": {"type": "string"}, + "scope-tag": {"type": "string"}, + "target-tag": {"type": "string"}, + }, + "required": ["target-tag", "scope-tag", "role"], + "type": "object", + }, + "CreateSecretArg": { + "additionalProperties": False, + "properties": { + "UpsertSecretArg": {"$ref": "#/definitions/UpsertSecretArg"}, + "content": {"$ref": "#/definitions/SecretContentParams"}, + "description": {"type": "string"}, + "expire-time": {"format": "date-time", "type": "string"}, + "label": {"type": "string"}, + "owner-tag": {"type": "string"}, + "params": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "rotate-policy": {"type": "string"}, + "uri": {"type": "string"}, + }, + "required": ["UpsertSecretArg", "owner-tag"], + "type": "object", + }, + "CreateSecretArgs": { + "additionalProperties": False, + "properties": { + "args": { + "items": {"$ref": "#/definitions/CreateSecretArg"}, + "type": "array", + } + }, + "required": ["args"], + "type": "object", + }, + "DeleteSecretArg": { + "additionalProperties": False, + "properties": { + "label": {"type": "string"}, + "revisions": {"items": {"type": "integer"}, "type": "array"}, + "uri": {"type": "string"}, + }, + "required": ["uri", "label"], + "type": "object", + }, + "DeleteSecretArgs": { + "additionalProperties": False, + "properties": { + "args": { + "items": {"$ref": "#/definitions/DeleteSecretArg"}, + "type": "array", + } + }, + "required": ["args"], + "type": "object", + }, + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "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", + }, + "GrantRevokeUserSecretArg": { + "additionalProperties": False, + "properties": { + "applications": {"items": {"type": "string"}, "type": "array"}, + "label": {"type": "string"}, + "uri": {"type": "string"}, + }, + "required": ["uri", "label", "applications"], + "type": "object", + }, + "ListSecretResult": { + "additionalProperties": False, + "properties": { + "access": { + "items": {"$ref": "#/definitions/AccessInfo"}, + "type": "array", + }, + "create-time": {"format": "date-time", "type": "string"}, + "description": {"type": "string"}, + "label": {"type": "string"}, + "latest-expire-time": {"format": "date-time", "type": "string"}, + "latest-revision": {"type": "integer"}, + "latest-revision-checksum": {"type": "string"}, + "next-rotate-time": {"format": "date-time", "type": "string"}, + "owner-tag": {"type": "string"}, + "revisions": { + "items": {"$ref": "#/definitions/SecretRevision"}, + "type": "array", + }, + "rotate-policy": {"type": "string"}, + "update-time": {"format": "date-time", "type": "string"}, + "uri": {"type": "string"}, + "value": {"$ref": "#/definitions/SecretValueResult"}, + "version": {"type": "integer"}, + }, + "required": [ + "uri", + "version", + "owner-tag", + "latest-revision", + "latest-revision-checksum", + "create-time", + "update-time", + "revisions", + ], + "type": "object", + }, + "ListSecretResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ListSecretResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "ListSecretsArgs": { + "additionalProperties": False, + "properties": { + "filter": {"$ref": "#/definitions/SecretsFilter"}, + "show-secrets": {"type": "boolean"}, + }, + "required": ["show-secrets", "filter"], + "type": "object", + }, + "SecretContentParams": { + "additionalProperties": False, + "properties": { + "checksum": {"type": "string"}, + "data": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "value-ref": {"$ref": "#/definitions/SecretValueRef"}, + }, + "type": "object", + }, + "SecretRevision": { + "additionalProperties": False, + "properties": { + "backend-name": {"type": "string"}, + "create-time": {"format": "date-time", "type": "string"}, + "expire-time": {"format": "date-time", "type": "string"}, + "revision": {"type": "integer"}, + "update-time": {"format": "date-time", "type": "string"}, + "value-ref": {"$ref": "#/definitions/SecretValueRef"}, + }, + "required": ["revision"], + "type": "object", + }, + "SecretValueRef": { + "additionalProperties": False, + "properties": { + "backend-id": {"type": "string"}, + "revision-id": {"type": "string"}, + }, + "required": ["backend-id", "revision-id"], + "type": "object", + }, + "SecretValueResult": { + "additionalProperties": False, + "properties": { + "data": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "error": {"$ref": "#/definitions/Error"}, + }, + "type": "object", + }, + "SecretsFilter": { + "additionalProperties": False, + "properties": { + "label": {"type": "string"}, + "owner-tag": {"type": "string"}, + "revision": {"type": "integer"}, + "uri": {"type": "string"}, + }, + "type": "object", + }, + "StringResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"type": "string"}, + }, + "required": ["result"], + "type": "object", + }, + "StringResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/StringResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "UpdateUserSecretArg": { + "additionalProperties": False, + "properties": { + "UpsertSecretArg": {"$ref": "#/definitions/UpsertSecretArg"}, + "auto-prune": {"type": "boolean"}, + "content": {"$ref": "#/definitions/SecretContentParams"}, + "description": {"type": "string"}, + "existing-label": {"type": "string"}, + "expire-time": {"format": "date-time", "type": "string"}, + "label": {"type": "string"}, + "params": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "rotate-policy": {"type": "string"}, + "uri": {"type": "string"}, + }, + "required": ["UpsertSecretArg", "uri", "existing-label"], + "type": "object", + }, + "UpdateUserSecretArgs": { + "additionalProperties": False, + "properties": { + "args": { + "items": {"$ref": "#/definitions/UpdateUserSecretArg"}, + "type": "array", + } + }, + "required": ["args"], + "type": "object", + }, + "UpsertSecretArg": { + "additionalProperties": False, + "properties": { + "content": {"$ref": "#/definitions/SecretContentParams"}, + "description": {"type": "string"}, + "expire-time": {"format": "date-time", "type": "string"}, + "label": {"type": "string"}, + "params": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "rotate-policy": {"type": "string"}, + }, + "type": "object", + }, + }, + "properties": { + "CreateSecrets": { + "description": "CreateSecrets creates new secrets.", + "properties": { + "Params": {"$ref": "#/definitions/CreateSecretArgs"}, + "Result": {"$ref": "#/definitions/StringResults"}, + }, + "type": "object", + }, + "GrantSecret": { + "description": "GrantSecret grants access to a user secret.", + "properties": { + "Params": {"$ref": "#/definitions/GrantRevokeUserSecretArg"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "ListSecrets": { + "description": "ListSecrets lists available secrets.", + "properties": { + "Params": {"$ref": "#/definitions/ListSecretsArgs"}, + "Result": {"$ref": "#/definitions/ListSecretResults"}, + }, + "type": "object", + }, + "RemoveSecrets": { + "description": "RemoveSecrets remove user secret.", + "properties": { + "Params": {"$ref": "#/definitions/DeleteSecretArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "RevokeSecret": { + "description": "RevokeSecret revokes access to a user secret.", + "properties": { + "Params": {"$ref": "#/definitions/GrantRevokeUserSecretArg"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "UpdateSecrets": { + "description": "UpdateSecrets creates new secrets.", + "properties": { + "Params": {"$ref": "#/definitions/UpdateUserSecretArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(StringResults) async def CreateSecrets(self, args=None): - ''' + """ CreateSecrets creates new secrets. args : typing.Sequence[~CreateSecretArg] Returns -> StringResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Secrets', - request='CreateSecrets', - version=2, - params=_params) - _params['args'] = args + msg = dict(type="Secrets", request="CreateSecrets", version=2, params=_params) + _params["args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def GrantSecret(self, applications=None, label=None, uri=None): - ''' + """ GrantSecret grants access to a user secret. applications : typing.Sequence[str] label : str uri : str Returns -> ErrorResults - ''' - if applications is not None and not isinstance(applications, (bytes, str, list)): - raise Exception("Expected applications to be a Sequence, received: {}".format(type(applications))) + """ + if applications is not None and not isinstance( + applications, (bytes, str, list) + ): + raise Exception( + "Expected applications to be a Sequence, received: {}".format( + type(applications) + ) + ) if label is not None and not isinstance(label, (bytes, str)): - raise Exception("Expected label to be a str, received: {}".format(type(label))) + raise Exception( + "Expected label to be a str, received: {}".format(type(label)) + ) if uri is not None and not isinstance(uri, (bytes, str)): raise Exception("Expected uri to be a str, received: {}".format(type(uri))) # map input types to rpc msg _params = dict() - msg = dict(type='Secrets', - request='GrantSecret', - version=2, - params=_params) - _params['applications'] = applications - _params['label'] = label - _params['uri'] = uri + msg = dict(type="Secrets", request="GrantSecret", version=2, params=_params) + _params["applications"] = applications + _params["label"] = label + _params["uri"] = uri reply = await self.rpc(msg) return reply - - @ReturnMapping(ListSecretResults) async def ListSecrets(self, filter_=None, show_secrets=None): - ''' + """ ListSecrets lists available secrets. filter_ : SecretsFilter show_secrets : bool Returns -> ListSecretResults - ''' + """ if filter_ is not None and not isinstance(filter_, (dict, SecretsFilter)): - raise Exception("Expected filter_ to be a SecretsFilter, received: {}".format(type(filter_))) + raise Exception( + "Expected filter_ to be a SecretsFilter, received: {}".format( + type(filter_) + ) + ) if show_secrets is not None and not isinstance(show_secrets, bool): - raise Exception("Expected show_secrets to be a bool, received: {}".format(type(show_secrets))) + raise Exception( + "Expected show_secrets to be a bool, received: {}".format( + type(show_secrets) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Secrets', - request='ListSecrets', - version=2, - params=_params) - _params['filter'] = filter_ - _params['show-secrets'] = show_secrets + msg = dict(type="Secrets", request="ListSecrets", version=2, params=_params) + _params["filter"] = filter_ + _params["show-secrets"] = show_secrets reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def RemoveSecrets(self, args=None): - ''' + """ RemoveSecrets remove user secret. args : typing.Sequence[~DeleteSecretArg] Returns -> ErrorResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Secrets', - request='RemoveSecrets', - version=2, - params=_params) - _params['args'] = args + msg = dict(type="Secrets", request="RemoveSecrets", version=2, params=_params) + _params["args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def RevokeSecret(self, applications=None, label=None, uri=None): - ''' + """ RevokeSecret revokes access to a user secret. applications : typing.Sequence[str] label : str uri : str Returns -> ErrorResults - ''' - if applications is not None and not isinstance(applications, (bytes, str, list)): - raise Exception("Expected applications to be a Sequence, received: {}".format(type(applications))) + """ + if applications is not None and not isinstance( + applications, (bytes, str, list) + ): + raise Exception( + "Expected applications to be a Sequence, received: {}".format( + type(applications) + ) + ) if label is not None and not isinstance(label, (bytes, str)): - raise Exception("Expected label to be a str, received: {}".format(type(label))) + raise Exception( + "Expected label to be a str, received: {}".format(type(label)) + ) if uri is not None and not isinstance(uri, (bytes, str)): raise Exception("Expected uri to be a str, received: {}".format(type(uri))) # map input types to rpc msg _params = dict() - msg = dict(type='Secrets', - request='RevokeSecret', - version=2, - params=_params) - _params['applications'] = applications - _params['label'] = label - _params['uri'] = uri + msg = dict(type="Secrets", request="RevokeSecret", version=2, params=_params) + _params["applications"] = applications + _params["label"] = label + _params["uri"] = uri reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def UpdateSecrets(self, args=None): - ''' + """ UpdateSecrets creates new secrets. args : typing.Sequence[~UpdateUserSecretArg] Returns -> ErrorResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Secrets', - request='UpdateSecrets', - version=2, - params=_params) - _params['args'] = args + msg = dict(type="Secrets", request="UpdateSecrets", version=2, params=_params) + _params["args"] = args reply = await self.rpc(msg) return reply - - diff --git a/juju/client/_client20.py b/juju/client/_client20.py index 3118b373f..4df353400 100644 --- a/juju/client/_client20.py +++ b/juju/client/_client20.py @@ -6,960 +6,1539 @@ class ApplicationFacade(Type): - name = 'Application' + name = "Application" version = 20 - schema = {'definitions': {'AddApplicationUnits': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'attach-storage': {'items': {'type': 'string'}, - 'type': 'array'}, - 'num-units': {'type': 'integer'}, - 'placement': {'items': {'$ref': '#/definitions/Placement'}, - 'type': 'array'}, - 'policy': {'type': 'string'}}, - 'required': ['application', - 'num-units', - 'placement'], - 'type': 'object'}, - 'AddApplicationUnitsResults': {'additionalProperties': False, - 'properties': {'units': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['units'], - 'type': 'object'}, - 'AddRelation': {'additionalProperties': False, - 'properties': {'endpoints': {'items': {'type': 'string'}, - 'type': 'array'}, - 'via-cidrs': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['endpoints'], - 'type': 'object'}, - 'AddRelationResults': {'additionalProperties': False, - 'properties': {'endpoints': {'patternProperties': {'.*': {'$ref': '#/definitions/CharmRelation'}}, - 'type': 'object'}}, - 'required': ['endpoints'], - 'type': 'object'}, - 'ApplicationCharmRelations': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}}, - 'required': ['application'], - 'type': 'object'}, - 'ApplicationCharmRelationsResults': {'additionalProperties': False, - 'properties': {'charm-relations': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['charm-relations'], - 'type': 'object'}, - 'ApplicationConfigUnsetArgs': {'additionalProperties': False, - 'properties': {'Args': {'items': {'$ref': '#/definitions/ApplicationUnset'}, - 'type': 'array'}}, - 'required': ['Args'], - 'type': 'object'}, - 'ApplicationConstraint': {'additionalProperties': False, - 'properties': {'constraints': {'$ref': '#/definitions/Value'}, - 'error': {'$ref': '#/definitions/Error'}}, - 'required': ['constraints'], - 'type': 'object'}, - 'ApplicationDeploy': {'additionalProperties': False, - 'properties': {'Force': {'type': 'boolean'}, - 'application': {'type': 'string'}, - 'attach-storage': {'items': {'type': 'string'}, - 'type': 'array'}, - 'channel': {'type': 'string'}, - 'charm-origin': {'$ref': '#/definitions/CharmOrigin'}, - 'charm-url': {'type': 'string'}, - 'config': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'config-yaml': {'type': 'string'}, - 'constraints': {'$ref': '#/definitions/Value'}, - 'devices': {'patternProperties': {'.*': {'$ref': '#/definitions/Constraints'}}, - 'type': 'object'}, - 'endpoint-bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'num-units': {'type': 'integer'}, - 'placement': {'items': {'$ref': '#/definitions/Placement'}, - 'type': 'array'}, - 'policy': {'type': 'string'}, - 'resources': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'storage': {'patternProperties': {'.*': {'$ref': '#/definitions/Constraints'}}, - 'type': 'object'}}, - 'required': ['application', - 'charm-url', - 'channel', - 'num-units', - 'config-yaml', - 'constraints', - 'Force'], - 'type': 'object'}, - 'ApplicationExpose': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'exposed-endpoints': {'patternProperties': {'.*': {'$ref': '#/definitions/ExposedEndpoint'}}, - 'type': 'object'}}, - 'required': ['application'], - 'type': 'object'}, - 'ApplicationGet': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'branch': {'type': 'string'}}, - 'required': ['application', 'branch'], - 'type': 'object'}, - 'ApplicationGetArgs': {'additionalProperties': False, - 'properties': {'args': {'items': {'$ref': '#/definitions/ApplicationGet'}, - 'type': 'array'}}, - 'required': ['args'], - 'type': 'object'}, - 'ApplicationGetConfigResults': {'additionalProperties': False, - 'properties': {'Results': {'items': {'$ref': '#/definitions/ConfigResult'}, - 'type': 'array'}}, - 'required': ['Results'], - 'type': 'object'}, - 'ApplicationGetConstraintsResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ApplicationConstraint'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'ApplicationGetResults': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'application-config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'base': {'$ref': '#/definitions/Base'}, - 'channel': {'type': 'string'}, - 'charm': {'type': 'string'}, - 'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'constraints': {'$ref': '#/definitions/Value'}, - 'endpoint-bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}}, - 'required': ['application', - 'charm', - 'config', - 'constraints', - 'base', - 'channel'], - 'type': 'object'}, - 'ApplicationInfoResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/ApplicationResult'}}, - 'type': 'object'}, - 'ApplicationInfoResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ApplicationInfoResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'ApplicationMergeBindings': {'additionalProperties': False, - 'properties': {'application-tag': {'type': 'string'}, - 'bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'force': {'type': 'boolean'}}, - 'required': ['application-tag', - 'bindings', - 'force'], - 'type': 'object'}, - 'ApplicationMergeBindingsArgs': {'additionalProperties': False, - 'properties': {'args': {'items': {'$ref': '#/definitions/ApplicationMergeBindings'}, - 'type': 'array'}}, - 'required': ['args'], - 'type': 'object'}, - 'ApplicationMetricCredential': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'metrics-credentials': {'items': {'type': 'integer'}, - 'type': 'array'}}, - 'required': ['application', - 'metrics-credentials'], - 'type': 'object'}, - 'ApplicationMetricCredentials': {'additionalProperties': False, - 'properties': {'creds': {'items': {'$ref': '#/definitions/ApplicationMetricCredential'}, - 'type': 'array'}}, - 'required': ['creds'], - 'type': 'object'}, - 'ApplicationOfferDetailsV5': {'additionalProperties': False, - 'properties': {'application-description': {'type': 'string'}, - 'endpoints': {'items': {'$ref': '#/definitions/RemoteEndpoint'}, - 'type': 'array'}, - 'offer-name': {'type': 'string'}, - 'offer-url': {'type': 'string'}, - 'offer-uuid': {'type': 'string'}, - 'source-model-tag': {'type': 'string'}, - 'users': {'items': {'$ref': '#/definitions/OfferUserDetails'}, - 'type': 'array'}}, - 'required': ['source-model-tag', - 'offer-uuid', - 'offer-url', - 'offer-name', - 'application-description'], - 'type': 'object'}, - 'ApplicationResult': {'additionalProperties': False, - 'properties': {'base': {'$ref': '#/definitions/Base'}, - 'channel': {'type': 'string'}, - 'charm': {'type': 'string'}, - 'constraints': {'$ref': '#/definitions/Value'}, - 'endpoint-bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'exposed': {'type': 'boolean'}, - 'exposed-endpoints': {'patternProperties': {'.*': {'$ref': '#/definitions/ExposedEndpoint'}}, - 'type': 'object'}, - 'life': {'type': 'string'}, - 'principal': {'type': 'boolean'}, - 'remote': {'type': 'boolean'}, - 'tag': {'type': 'string'}}, - 'required': ['tag', - 'principal', - 'exposed', - 'remote', - 'life'], - 'type': 'object'}, - 'ApplicationSetCharm': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'channel': {'type': 'string'}, - 'charm-origin': {'$ref': '#/definitions/CharmOrigin'}, - 'charm-url': {'type': 'string'}, - 'config-settings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'config-settings-yaml': {'type': 'string'}, - 'endpoint-bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'force': {'type': 'boolean'}, - 'force-base': {'type': 'boolean'}, - 'force-units': {'type': 'boolean'}, - 'generation': {'type': 'string'}, - 'resource-ids': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'storage-constraints': {'patternProperties': {'.*': {'$ref': '#/definitions/StorageConstraints'}}, - 'type': 'object'}}, - 'required': ['application', - 'generation', - 'charm-url', - 'channel', - 'force', - 'force-units', - 'force-base'], - 'type': 'object'}, - 'ApplicationUnexpose': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'exposed-endpoints': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['application', - 'exposed-endpoints'], - 'type': 'object'}, - 'ApplicationUnset': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'branch': {'type': 'string'}, - 'options': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['application', - 'branch', - 'options'], - 'type': 'object'}, - 'ApplicationsDeploy': {'additionalProperties': False, - 'properties': {'applications': {'items': {'$ref': '#/definitions/ApplicationDeploy'}, - 'type': 'array'}}, - 'required': ['applications'], - 'type': 'object'}, - 'Base': {'additionalProperties': False, - 'properties': {'channel': {'type': 'string'}, - 'name': {'type': 'string'}}, - 'required': ['name', 'channel'], - 'type': 'object'}, - 'CharmOrigin': {'additionalProperties': False, - 'properties': {'architecture': {'type': 'string'}, - 'base': {'$ref': '#/definitions/Base'}, - 'branch': {'type': 'string'}, - 'hash': {'type': 'string'}, - 'id': {'type': 'string'}, - 'instance-key': {'type': 'string'}, - 'revision': {'type': 'integer'}, - 'risk': {'type': 'string'}, - 'source': {'type': 'string'}, - 'track': {'type': 'string'}, - 'type': {'type': 'string'}}, - 'required': ['source', 'type', 'id'], - 'type': 'object'}, - 'CharmRelation': {'additionalProperties': False, - 'properties': {'interface': {'type': 'string'}, - 'limit': {'type': 'integer'}, - 'name': {'type': 'string'}, - 'optional': {'type': 'boolean'}, - 'role': {'type': 'string'}, - 'scope': {'type': 'string'}}, - 'required': ['name', - 'role', - 'interface', - 'optional', - 'limit', - 'scope'], - 'type': 'object'}, - 'CharmURLOriginResult': {'additionalProperties': False, - 'properties': {'charm-origin': {'$ref': '#/definitions/CharmOrigin'}, - 'error': {'$ref': '#/definitions/Error'}, - 'url': {'type': 'string'}}, - 'required': ['url', 'charm-origin'], - 'type': 'object'}, - 'ConfigResult': {'additionalProperties': False, - 'properties': {'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'error': {'$ref': '#/definitions/Error'}}, - 'required': ['config'], - 'type': 'object'}, - 'ConfigSet': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'config': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'config-yaml': {'type': 'string'}, - 'generation': {'type': 'string'}}, - 'required': ['application', - 'generation', - 'config', - 'config-yaml'], - 'type': 'object'}, - 'ConfigSetArgs': {'additionalProperties': False, - 'properties': {'Args': {'items': {'$ref': '#/definitions/ConfigSet'}, - 'type': 'array'}}, - 'required': ['Args'], - 'type': 'object'}, - 'Constraints': {'additionalProperties': False, - 'properties': {'Count': {'type': 'integer'}, - 'Pool': {'type': 'string'}, - 'Size': {'type': 'integer'}}, - 'required': ['Pool', 'Size', 'Count'], - 'type': 'object'}, - 'ConsumeApplicationArgV5': {'additionalProperties': False, - 'properties': {'ApplicationOfferDetailsV5': {'$ref': '#/definitions/ApplicationOfferDetailsV5'}, - 'application-alias': {'type': 'string'}, - 'application-description': {'type': 'string'}, - 'endpoints': {'items': {'$ref': '#/definitions/RemoteEndpoint'}, - 'type': 'array'}, - 'external-controller': {'$ref': '#/definitions/ExternalControllerInfo'}, - 'macaroon': {'$ref': '#/definitions/Macaroon'}, - 'offer-name': {'type': 'string'}, - 'offer-url': {'type': 'string'}, - 'offer-uuid': {'type': 'string'}, - 'source-model-tag': {'type': 'string'}, - 'users': {'items': {'$ref': '#/definitions/OfferUserDetails'}, - 'type': 'array'}}, - 'required': ['source-model-tag', - 'offer-uuid', - 'offer-url', - 'offer-name', - 'application-description', - 'ApplicationOfferDetailsV5'], - 'type': 'object'}, - 'ConsumeApplicationArgsV5': {'additionalProperties': False, - 'properties': {'args': {'items': {'$ref': '#/definitions/ConsumeApplicationArgV5'}, - 'type': 'array'}}, - 'type': 'object'}, - 'DeployFromRepositoryArg': {'additionalProperties': False, - 'properties': {'ApplicationName': {'type': 'string'}, - 'AttachStorage': {'items': {'type': 'string'}, - 'type': 'array'}, - 'CharmName': {'type': 'string'}, - 'ConfigYAML': {'type': 'string'}, - 'Cons': {'$ref': '#/definitions/Value'}, - 'Devices': {'patternProperties': {'.*': {'$ref': '#/definitions/Constraints'}}, - 'type': 'object'}, - 'DryRun': {'type': 'boolean'}, - 'Placement': {'items': {'$ref': '#/definitions/Placement'}, - 'type': 'array'}, - 'Storage': {'patternProperties': {'.*': {'$ref': '#/definitions/Constraints'}}, - 'type': 'object'}, - 'Trust': {'type': 'boolean'}, - 'base': {'$ref': '#/definitions/Base'}, - 'channel': {'type': 'string'}, - 'endpoint-bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'force': {'type': 'boolean'}, - 'num-units': {'type': 'integer'}, - 'resources': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'revision': {'type': 'integer'}}, - 'required': ['CharmName', - 'ApplicationName', - 'AttachStorage', - 'ConfigYAML', - 'Cons', - 'Devices', - 'DryRun', - 'Placement', - 'Storage', - 'Trust'], - 'type': 'object'}, - 'DeployFromRepositoryArgs': {'additionalProperties': False, - 'properties': {'Args': {'items': {'$ref': '#/definitions/DeployFromRepositoryArg'}, - 'type': 'array'}}, - 'required': ['Args'], - 'type': 'object'}, - 'DeployFromRepositoryInfo': {'additionalProperties': False, - 'properties': {'architecture': {'type': 'string'}, - 'base': {'$ref': '#/definitions/Base'}, - 'channel': {'type': 'string'}, - 'effective-channel': {'type': 'string'}, - 'name': {'type': 'string'}, - 'revision': {'type': 'integer'}}, - 'required': ['architecture', - 'channel', - 'name', - 'revision'], - 'type': 'object'}, - 'DeployFromRepositoryResult': {'additionalProperties': False, - 'properties': {'Errors': {'items': {'$ref': '#/definitions/Error'}, - 'type': 'array'}, - 'Info': {'$ref': '#/definitions/DeployFromRepositoryInfo'}, - 'PendingResourceUploads': {'items': {'$ref': '#/definitions/PendingResourceUpload'}, - 'type': 'array'}}, - 'required': ['Errors', - 'Info', - 'PendingResourceUploads'], - 'type': 'object'}, - 'DeployFromRepositoryResults': {'additionalProperties': False, - 'properties': {'Results': {'items': {'$ref': '#/definitions/DeployFromRepositoryResult'}, - 'type': 'array'}}, - 'required': ['Results'], - 'type': 'object'}, - 'DestroyApplicationInfo': {'additionalProperties': False, - 'properties': {'destroyed-storage': {'items': {'$ref': '#/definitions/Entity'}, - 'type': 'array'}, - 'destroyed-units': {'items': {'$ref': '#/definitions/Entity'}, - 'type': 'array'}, - 'detached-storage': {'items': {'$ref': '#/definitions/Entity'}, - 'type': 'array'}}, - 'type': 'object'}, - 'DestroyApplicationParams': {'additionalProperties': False, - 'properties': {'application-tag': {'type': 'string'}, - 'destroy-storage': {'type': 'boolean'}, - 'dry-run': {'type': 'boolean'}, - 'force': {'type': 'boolean'}, - 'max-wait': {'type': 'integer'}}, - 'required': ['application-tag', - 'force'], - 'type': 'object'}, - 'DestroyApplicationResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'info': {'$ref': '#/definitions/DestroyApplicationInfo'}}, - 'type': 'object'}, - 'DestroyApplicationResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/DestroyApplicationResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'DestroyApplicationsParams': {'additionalProperties': False, - 'properties': {'applications': {'items': {'$ref': '#/definitions/DestroyApplicationParams'}, - 'type': 'array'}}, - 'required': ['applications'], - 'type': 'object'}, - 'DestroyConsumedApplicationParams': {'additionalProperties': False, - 'properties': {'application-tag': {'type': 'string'}, - 'force': {'type': 'boolean'}, - 'max-wait': {'type': 'integer'}}, - 'required': ['application-tag'], - 'type': 'object'}, - 'DestroyConsumedApplicationsParams': {'additionalProperties': False, - 'properties': {'applications': {'items': {'$ref': '#/definitions/DestroyConsumedApplicationParams'}, - 'type': 'array'}}, - 'required': ['applications'], - 'type': 'object'}, - 'DestroyRelation': {'additionalProperties': False, - 'properties': {'endpoints': {'items': {'type': 'string'}, - 'type': 'array'}, - 'force': {'type': 'boolean'}, - 'max-wait': {'type': 'integer'}, - 'relation-id': {'type': 'integer'}}, - 'required': ['relation-id'], - 'type': 'object'}, - 'DestroyUnitInfo': {'additionalProperties': False, - 'properties': {'destroyed-storage': {'items': {'$ref': '#/definitions/Entity'}, - 'type': 'array'}, - 'detached-storage': {'items': {'$ref': '#/definitions/Entity'}, - 'type': 'array'}}, - 'type': 'object'}, - 'DestroyUnitParams': {'additionalProperties': False, - 'properties': {'destroy-storage': {'type': 'boolean'}, - 'dry-run': {'type': 'boolean'}, - 'force': {'type': 'boolean'}, - 'max-wait': {'type': 'integer'}, - 'unit-tag': {'type': 'string'}}, - 'required': ['unit-tag'], - 'type': 'object'}, - 'DestroyUnitResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'info': {'$ref': '#/definitions/DestroyUnitInfo'}}, - 'type': 'object'}, - 'DestroyUnitResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/DestroyUnitResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'DestroyUnitsParams': {'additionalProperties': False, - 'properties': {'units': {'items': {'$ref': '#/definitions/DestroyUnitParams'}, - 'type': 'array'}}, - 'required': ['units'], - 'type': 'object'}, - 'EndpointRelationData': {'additionalProperties': False, - 'properties': {'ApplicationData': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'cross-model': {'type': 'boolean'}, - 'endpoint': {'type': 'string'}, - 'related-endpoint': {'type': 'string'}, - 'relation-id': {'type': 'integer'}, - 'unit-relation-data': {'patternProperties': {'.*': {'$ref': '#/definitions/RelationData'}}, - 'type': 'object'}}, - 'required': ['relation-id', - 'endpoint', - 'cross-model', - 'related-endpoint', - 'ApplicationData', - 'unit-relation-data'], - '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'}, - 'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - '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'}, - 'ExposedEndpoint': {'additionalProperties': False, - 'properties': {'expose-to-cidrs': {'items': {'type': 'string'}, - 'type': 'array'}, - 'expose-to-spaces': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'ExternalControllerInfo': {'additionalProperties': False, - 'properties': {'addrs': {'items': {'type': 'string'}, - 'type': 'array'}, - 'ca-cert': {'type': 'string'}, - 'controller-alias': {'type': 'string'}, - 'controller-tag': {'type': 'string'}}, - 'required': ['controller-tag', - 'controller-alias', - 'addrs', - 'ca-cert'], - 'type': 'object'}, - 'Macaroon': {'additionalProperties': False, 'type': 'object'}, - 'OfferUserDetails': {'additionalProperties': False, - 'properties': {'access': {'type': 'string'}, - 'display-name': {'type': 'string'}, - 'user': {'type': 'string'}}, - 'required': ['user', - 'display-name', - 'access'], - 'type': 'object'}, - 'PendingResourceUpload': {'additionalProperties': False, - 'properties': {'Filename': {'type': 'string'}, - 'Name': {'type': 'string'}, - 'Type': {'type': 'string'}}, - 'required': ['Name', - 'Filename', - 'Type'], - 'type': 'object'}, - 'Placement': {'additionalProperties': False, - 'properties': {'directive': {'type': 'string'}, - 'scope': {'type': 'string'}}, - 'required': ['scope', 'directive'], - 'type': 'object'}, - 'RelationData': {'additionalProperties': False, - 'properties': {'InScope': {'type': 'boolean'}, - 'UnitData': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}}, - 'required': ['InScope', 'UnitData'], - 'type': 'object'}, - 'RelationSuspendedArg': {'additionalProperties': False, - 'properties': {'message': {'type': 'string'}, - 'relation-id': {'type': 'integer'}, - 'suspended': {'type': 'boolean'}}, - 'required': ['relation-id', - 'message', - 'suspended'], - 'type': 'object'}, - 'RelationSuspendedArgs': {'additionalProperties': False, - 'properties': {'args': {'items': {'$ref': '#/definitions/RelationSuspendedArg'}, - 'type': 'array'}}, - 'required': ['args'], - 'type': 'object'}, - 'RemoteEndpoint': {'additionalProperties': False, - 'properties': {'interface': {'type': 'string'}, - 'limit': {'type': 'integer'}, - 'name': {'type': 'string'}, - 'role': {'type': 'string'}}, - 'required': ['name', - 'role', - 'interface', - 'limit'], - 'type': 'object'}, - 'ScaleApplicationInfo': {'additionalProperties': False, - 'properties': {'num-units': {'type': 'integer'}}, - 'required': ['num-units'], - 'type': 'object'}, - 'ScaleApplicationParams': {'additionalProperties': False, - 'properties': {'application-tag': {'type': 'string'}, - 'force': {'type': 'boolean'}, - 'scale': {'type': 'integer'}, - 'scale-change': {'type': 'integer'}}, - 'required': ['application-tag', - 'scale', - 'force'], - 'type': 'object'}, - 'ScaleApplicationResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'info': {'$ref': '#/definitions/ScaleApplicationInfo'}}, - 'type': 'object'}, - 'ScaleApplicationResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ScaleApplicationResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'ScaleApplicationsParams': {'additionalProperties': False, - 'properties': {'applications': {'items': {'$ref': '#/definitions/ScaleApplicationParams'}, - 'type': 'array'}}, - 'required': ['applications'], - 'type': 'object'}, - 'SetConstraints': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'constraints': {'$ref': '#/definitions/Value'}}, - 'required': ['application', 'constraints'], - 'type': 'object'}, - 'StorageConstraints': {'additionalProperties': False, - 'properties': {'count': {'type': 'integer'}, - 'pool': {'type': 'string'}, - 'size': {'type': 'integer'}}, - 'type': 'object'}, - 'StringResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'type': 'string'}}, - 'required': ['result'], - 'type': 'object'}, - 'UnitInfoResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/UnitResult'}}, - 'type': 'object'}, - 'UnitInfoResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/UnitInfoResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'UnitResult': {'additionalProperties': False, - 'properties': {'address': {'type': 'string'}, - 'charm': {'type': 'string'}, - 'leader': {'type': 'boolean'}, - 'life': {'type': 'string'}, - 'machine': {'type': 'string'}, - 'opened-ports': {'items': {'type': 'string'}, - 'type': 'array'}, - 'provider-id': {'type': 'string'}, - 'public-address': {'type': 'string'}, - 'relation-data': {'items': {'$ref': '#/definitions/EndpointRelationData'}, - 'type': 'array'}, - 'tag': {'type': 'string'}, - 'workload-version': {'type': 'string'}}, - 'required': ['tag', - 'workload-version', - 'opened-ports', - 'charm'], - 'type': 'object'}, - 'UnitsResolved': {'additionalProperties': False, - 'properties': {'all': {'type': 'boolean'}, - 'retry': {'type': 'boolean'}, - 'tags': {'$ref': '#/definitions/Entities'}}, - 'type': 'object'}, - 'UpdateChannelArg': {'additionalProperties': False, - 'properties': {'channel': {'type': 'string'}, - 'force': {'type': 'boolean'}, - 'tag': {'$ref': '#/definitions/Entity'}}, - 'required': ['tag', 'force', 'channel'], - 'type': 'object'}, - 'UpdateChannelArgs': {'additionalProperties': False, - 'properties': {'args': {'items': {'$ref': '#/definitions/UpdateChannelArg'}, - 'type': 'array'}}, - 'required': ['args'], - 'type': 'object'}, - 'Value': {'additionalProperties': False, - 'properties': {'allocate-public-ip': {'type': 'boolean'}, - 'arch': {'type': 'string'}, - 'container': {'type': 'string'}, - 'cores': {'type': 'integer'}, - 'cpu-power': {'type': 'integer'}, - 'image-id': {'type': 'string'}, - 'instance-role': {'type': 'string'}, - 'instance-type': {'type': 'string'}, - 'mem': {'type': 'integer'}, - 'root-disk': {'type': 'integer'}, - 'root-disk-source': {'type': 'string'}, - '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': {'AddRelation': {'description': 'AddRelation adds a relation ' - 'between the specified ' - 'endpoints and returns the ' - 'relation info.', - 'properties': {'Params': {'$ref': '#/definitions/AddRelation'}, - 'Result': {'$ref': '#/definitions/AddRelationResults'}}, - 'type': 'object'}, - 'AddUnits': {'description': 'AddUnits adds a given number of ' - 'units to an application.', - 'properties': {'Params': {'$ref': '#/definitions/AddApplicationUnits'}, - 'Result': {'$ref': '#/definitions/AddApplicationUnitsResults'}}, - 'type': 'object'}, - 'ApplicationsInfo': {'description': 'ApplicationsInfo returns ' - 'applications information.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ApplicationInfoResults'}}, - 'type': 'object'}, - 'CharmConfig': {'description': 'CharmConfig returns charm ' - 'config for the input list of ' - 'applications and\n' - 'model generations.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationGetArgs'}, - 'Result': {'$ref': '#/definitions/ApplicationGetConfigResults'}}, - 'type': 'object'}, - 'CharmRelations': {'description': 'CharmRelations implements ' - 'the server side of ' - 'Application.CharmRelations.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationCharmRelations'}, - 'Result': {'$ref': '#/definitions/ApplicationCharmRelationsResults'}}, - 'type': 'object'}, - 'Consume': {'description': 'Consume adds remote applications ' - 'to the model without creating any\n' - 'relations.', - 'properties': {'Params': {'$ref': '#/definitions/ConsumeApplicationArgsV5'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'Deploy': {'description': 'Deploy fetches the charms from the ' - 'charm store and deploys them\n' - 'using the specified placement ' - 'directives.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationsDeploy'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'DeployFromRepository': {'description': 'DeployFromRepository ' - 'is a one-stop ' - 'deployment method for ' - 'repository\n' - 'charms. Only a charm ' - 'name is required to ' - 'deploy. If argument ' - 'validation\n' - 'fails, a list of all ' - 'errors found in ' - 'validation will be ' - 'returned. If a\n' - 'local resource is ' - 'provided, details ' - 'required for ' - 'uploading the ' - 'validated\n' - 'resource will be ' - 'returned.', - 'properties': {'Params': {'$ref': '#/definitions/DeployFromRepositoryArgs'}, - 'Result': {'$ref': '#/definitions/DeployFromRepositoryResults'}}, - 'type': 'object'}, - 'DestroyApplication': {'description': 'DestroyApplication ' - 'removes a given set of ' - 'applications.', - 'properties': {'Params': {'$ref': '#/definitions/DestroyApplicationsParams'}, - 'Result': {'$ref': '#/definitions/DestroyApplicationResults'}}, - 'type': 'object'}, - 'DestroyConsumedApplications': {'description': 'DestroyConsumedApplications ' - 'removes a ' - 'given set of ' - 'consumed ' - '(remote) ' - 'applications.', - 'properties': {'Params': {'$ref': '#/definitions/DestroyConsumedApplicationsParams'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'DestroyRelation': {'description': 'DestroyRelation removes ' - 'the relation between the\n' - 'specified endpoints or an ' - 'id.', - 'properties': {'Params': {'$ref': '#/definitions/DestroyRelation'}}, - 'type': 'object'}, - 'DestroyUnit': {'description': 'DestroyUnit removes a given ' - 'set of application units.', - 'properties': {'Params': {'$ref': '#/definitions/DestroyUnitsParams'}, - 'Result': {'$ref': '#/definitions/DestroyUnitResults'}}, - 'type': 'object'}, - 'Expose': {'description': 'Expose changes the juju-managed ' - 'firewall to expose any ports that\n' - 'were also explicitly marked by ' - 'units as open.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationExpose'}}, - 'type': 'object'}, - 'Get': {'description': 'Get returns the charm configuration ' - 'for an application.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationGet'}, - 'Result': {'$ref': '#/definitions/ApplicationGetResults'}}, - 'type': 'object'}, - 'GetCharmURLOrigin': {'description': 'GetCharmURLOrigin ' - 'returns the charm URL ' - 'and charm origin the ' - 'given\n' - 'application is running ' - 'at present.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationGet'}, - 'Result': {'$ref': '#/definitions/CharmURLOriginResult'}}, - 'type': 'object'}, - 'GetConfig': {'description': 'GetConfig returns the charm ' - 'config for each of the input ' - 'applications.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ApplicationGetConfigResults'}}, - 'type': 'object'}, - 'GetConstraints': {'description': 'GetConstraints returns the ' - 'constraints for a given ' - 'application.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ApplicationGetConstraintsResults'}}, - 'type': 'object'}, - 'Leader': {'description': 'Leader returns the unit name of the ' - 'leader for the given application.', - 'properties': {'Params': {'$ref': '#/definitions/Entity'}, - 'Result': {'$ref': '#/definitions/StringResult'}}, - 'type': 'object'}, - 'MergeBindings': {'description': 'MergeBindings merges ' - 'operator-defined bindings ' - 'with the current bindings ' - 'for\n' - 'one or more applications.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationMergeBindingsArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'ResolveUnitErrors': {'description': 'ResolveUnitErrors marks ' - 'errors on the specified ' - 'units as resolved.', - 'properties': {'Params': {'$ref': '#/definitions/UnitsResolved'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'ScaleApplications': {'description': 'ScaleApplications scales ' - 'the specified ' - 'application to the ' - 'requested number of ' - 'units.', - 'properties': {'Params': {'$ref': '#/definitions/ScaleApplicationsParams'}, - 'Result': {'$ref': '#/definitions/ScaleApplicationResults'}}, - 'type': 'object'}, - 'SetCharm': {'description': 'SetCharm sets the charm for a ' - 'given for the application.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationSetCharm'}}, - 'type': 'object'}, - 'SetConfigs': {'description': 'SetConfigs implements the ' - 'server side of ' - 'Application.SetConfig. Both\n' - 'application and charm config ' - 'are set. It does not unset ' - 'values in\n' - 'Config map that are set to an ' - 'empty string. Unset should be ' - 'used for that.', - 'properties': {'Params': {'$ref': '#/definitions/ConfigSetArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'SetConstraints': {'description': 'SetConstraints sets the ' - 'constraints for a given ' - 'application.', - 'properties': {'Params': {'$ref': '#/definitions/SetConstraints'}}, - 'type': 'object'}, - 'SetMetricCredentials': {'description': 'SetMetricCredentials ' - 'sets credentials on ' - 'the application.\n' - 'TODO (cderici) only ' - 'used for metered ' - 'charms in cmd ' - 'MeteredDeployAPI,\n' - 'kept for client ' - 'compatibility, remove ' - 'in juju 4.0', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationMetricCredentials'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'SetRelationsSuspended': {'description': 'SetRelationsSuspended ' - 'sets the suspended ' - 'status of the ' - 'specified relations.', - 'properties': {'Params': {'$ref': '#/definitions/RelationSuspendedArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'Unexpose': {'description': 'Unexpose changes the juju-managed ' - 'firewall to unexpose any ports ' - 'that\n' - 'were also explicitly marked by ' - 'units as open.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationUnexpose'}}, - 'type': 'object'}, - 'UnitsInfo': {'description': 'UnitsInfo returns unit ' - 'information for the given ' - 'entities (units or\n' - 'applications).', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/UnitInfoResults'}}, - 'type': 'object'}, - 'UnsetApplicationsConfig': {'description': 'UnsetApplicationsConfig ' - 'implements the ' - 'server side of ' - 'Application.UnsetApplicationsConfig.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationConfigUnsetArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'UpdateApplicationBase': {'description': 'UpdateApplicationBase ' - 'updates the ' - 'application base.\n' - 'Base for ' - 'subordinates is ' - 'updated too.', - 'properties': {'Params': {'$ref': '#/definitions/UpdateChannelArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "AddApplicationUnits": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "attach-storage": {"items": {"type": "string"}, "type": "array"}, + "num-units": {"type": "integer"}, + "placement": { + "items": {"$ref": "#/definitions/Placement"}, + "type": "array", + }, + "policy": {"type": "string"}, + }, + "required": ["application", "num-units", "placement"], + "type": "object", + }, + "AddApplicationUnitsResults": { + "additionalProperties": False, + "properties": {"units": {"items": {"type": "string"}, "type": "array"}}, + "required": ["units"], + "type": "object", + }, + "AddRelation": { + "additionalProperties": False, + "properties": { + "endpoints": {"items": {"type": "string"}, "type": "array"}, + "via-cidrs": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["endpoints"], + "type": "object", + }, + "AddRelationResults": { + "additionalProperties": False, + "properties": { + "endpoints": { + "patternProperties": { + ".*": {"$ref": "#/definitions/CharmRelation"} + }, + "type": "object", + } + }, + "required": ["endpoints"], + "type": "object", + }, + "ApplicationCharmRelations": { + "additionalProperties": False, + "properties": {"application": {"type": "string"}}, + "required": ["application"], + "type": "object", + }, + "ApplicationCharmRelationsResults": { + "additionalProperties": False, + "properties": { + "charm-relations": {"items": {"type": "string"}, "type": "array"} + }, + "required": ["charm-relations"], + "type": "object", + }, + "ApplicationConfigUnsetArgs": { + "additionalProperties": False, + "properties": { + "Args": { + "items": {"$ref": "#/definitions/ApplicationUnset"}, + "type": "array", + } + }, + "required": ["Args"], + "type": "object", + }, + "ApplicationConstraint": { + "additionalProperties": False, + "properties": { + "constraints": {"$ref": "#/definitions/Value"}, + "error": {"$ref": "#/definitions/Error"}, + }, + "required": ["constraints"], + "type": "object", + }, + "ApplicationDeploy": { + "additionalProperties": False, + "properties": { + "Force": {"type": "boolean"}, + "application": {"type": "string"}, + "attach-storage": {"items": {"type": "string"}, "type": "array"}, + "channel": {"type": "string"}, + "charm-origin": {"$ref": "#/definitions/CharmOrigin"}, + "charm-url": {"type": "string"}, + "config": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "config-yaml": {"type": "string"}, + "constraints": {"$ref": "#/definitions/Value"}, + "devices": { + "patternProperties": { + ".*": {"$ref": "#/definitions/Constraints"} + }, + "type": "object", + }, + "endpoint-bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "num-units": {"type": "integer"}, + "placement": { + "items": {"$ref": "#/definitions/Placement"}, + "type": "array", + }, + "policy": {"type": "string"}, + "resources": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "storage": { + "patternProperties": { + ".*": {"$ref": "#/definitions/Constraints"} + }, + "type": "object", + }, + }, + "required": [ + "application", + "charm-url", + "channel", + "num-units", + "config-yaml", + "constraints", + "Force", + ], + "type": "object", + }, + "ApplicationExpose": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "exposed-endpoints": { + "patternProperties": { + ".*": {"$ref": "#/definitions/ExposedEndpoint"} + }, + "type": "object", + }, + }, + "required": ["application"], + "type": "object", + }, + "ApplicationGet": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "branch": {"type": "string"}, + }, + "required": ["application", "branch"], + "type": "object", + }, + "ApplicationGetArgs": { + "additionalProperties": False, + "properties": { + "args": { + "items": {"$ref": "#/definitions/ApplicationGet"}, + "type": "array", + } + }, + "required": ["args"], + "type": "object", + }, + "ApplicationGetConfigResults": { + "additionalProperties": False, + "properties": { + "Results": { + "items": {"$ref": "#/definitions/ConfigResult"}, + "type": "array", + } + }, + "required": ["Results"], + "type": "object", + }, + "ApplicationGetConstraintsResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ApplicationConstraint"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "ApplicationGetResults": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "application-config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "base": {"$ref": "#/definitions/Base"}, + "channel": {"type": "string"}, + "charm": {"type": "string"}, + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "constraints": {"$ref": "#/definitions/Value"}, + "endpoint-bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + }, + "required": [ + "application", + "charm", + "config", + "constraints", + "base", + "channel", + ], + "type": "object", + }, + "ApplicationInfoResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/ApplicationResult"}, + }, + "type": "object", + }, + "ApplicationInfoResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ApplicationInfoResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "ApplicationMergeBindings": { + "additionalProperties": False, + "properties": { + "application-tag": {"type": "string"}, + "bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "force": {"type": "boolean"}, + }, + "required": ["application-tag", "bindings", "force"], + "type": "object", + }, + "ApplicationMergeBindingsArgs": { + "additionalProperties": False, + "properties": { + "args": { + "items": {"$ref": "#/definitions/ApplicationMergeBindings"}, + "type": "array", + } + }, + "required": ["args"], + "type": "object", + }, + "ApplicationMetricCredential": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "metrics-credentials": { + "items": {"type": "integer"}, + "type": "array", + }, + }, + "required": ["application", "metrics-credentials"], + "type": "object", + }, + "ApplicationMetricCredentials": { + "additionalProperties": False, + "properties": { + "creds": { + "items": {"$ref": "#/definitions/ApplicationMetricCredential"}, + "type": "array", + } + }, + "required": ["creds"], + "type": "object", + }, + "ApplicationOfferDetailsV5": { + "additionalProperties": False, + "properties": { + "application-description": {"type": "string"}, + "endpoints": { + "items": {"$ref": "#/definitions/RemoteEndpoint"}, + "type": "array", + }, + "offer-name": {"type": "string"}, + "offer-url": {"type": "string"}, + "offer-uuid": {"type": "string"}, + "source-model-tag": {"type": "string"}, + "users": { + "items": {"$ref": "#/definitions/OfferUserDetails"}, + "type": "array", + }, + }, + "required": [ + "source-model-tag", + "offer-uuid", + "offer-url", + "offer-name", + "application-description", + ], + "type": "object", + }, + "ApplicationResult": { + "additionalProperties": False, + "properties": { + "base": {"$ref": "#/definitions/Base"}, + "channel": {"type": "string"}, + "charm": {"type": "string"}, + "constraints": {"$ref": "#/definitions/Value"}, + "endpoint-bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "exposed": {"type": "boolean"}, + "exposed-endpoints": { + "patternProperties": { + ".*": {"$ref": "#/definitions/ExposedEndpoint"} + }, + "type": "object", + }, + "life": {"type": "string"}, + "principal": {"type": "boolean"}, + "remote": {"type": "boolean"}, + "tag": {"type": "string"}, + }, + "required": ["tag", "principal", "exposed", "remote", "life"], + "type": "object", + }, + "ApplicationSetCharm": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "channel": {"type": "string"}, + "charm-origin": {"$ref": "#/definitions/CharmOrigin"}, + "charm-url": {"type": "string"}, + "config-settings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "config-settings-yaml": {"type": "string"}, + "endpoint-bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "force": {"type": "boolean"}, + "force-base": {"type": "boolean"}, + "force-units": {"type": "boolean"}, + "generation": {"type": "string"}, + "resource-ids": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "storage-constraints": { + "patternProperties": { + ".*": {"$ref": "#/definitions/StorageConstraints"} + }, + "type": "object", + }, + }, + "required": [ + "application", + "generation", + "charm-url", + "channel", + "force", + "force-units", + "force-base", + ], + "type": "object", + }, + "ApplicationUnexpose": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "exposed-endpoints": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["application", "exposed-endpoints"], + "type": "object", + }, + "ApplicationUnset": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "branch": {"type": "string"}, + "options": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["application", "branch", "options"], + "type": "object", + }, + "ApplicationsDeploy": { + "additionalProperties": False, + "properties": { + "applications": { + "items": {"$ref": "#/definitions/ApplicationDeploy"}, + "type": "array", + } + }, + "required": ["applications"], + "type": "object", + }, + "Base": { + "additionalProperties": False, + "properties": { + "channel": {"type": "string"}, + "name": {"type": "string"}, + }, + "required": ["name", "channel"], + "type": "object", + }, + "CharmOrigin": { + "additionalProperties": False, + "properties": { + "architecture": {"type": "string"}, + "base": {"$ref": "#/definitions/Base"}, + "branch": {"type": "string"}, + "hash": {"type": "string"}, + "id": {"type": "string"}, + "instance-key": {"type": "string"}, + "revision": {"type": "integer"}, + "risk": {"type": "string"}, + "source": {"type": "string"}, + "track": {"type": "string"}, + "type": {"type": "string"}, + }, + "required": ["source", "type", "id"], + "type": "object", + }, + "CharmRelation": { + "additionalProperties": False, + "properties": { + "interface": {"type": "string"}, + "limit": {"type": "integer"}, + "name": {"type": "string"}, + "optional": {"type": "boolean"}, + "role": {"type": "string"}, + "scope": {"type": "string"}, + }, + "required": ["name", "role", "interface", "optional", "limit", "scope"], + "type": "object", + }, + "CharmURLOriginResult": { + "additionalProperties": False, + "properties": { + "charm-origin": {"$ref": "#/definitions/CharmOrigin"}, + "error": {"$ref": "#/definitions/Error"}, + "url": {"type": "string"}, + }, + "required": ["url", "charm-origin"], + "type": "object", + }, + "ConfigResult": { + "additionalProperties": False, + "properties": { + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "error": {"$ref": "#/definitions/Error"}, + }, + "required": ["config"], + "type": "object", + }, + "ConfigSet": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "config": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "config-yaml": {"type": "string"}, + "generation": {"type": "string"}, + }, + "required": ["application", "generation", "config", "config-yaml"], + "type": "object", + }, + "ConfigSetArgs": { + "additionalProperties": False, + "properties": { + "Args": { + "items": {"$ref": "#/definitions/ConfigSet"}, + "type": "array", + } + }, + "required": ["Args"], + "type": "object", + }, + "Constraints": { + "additionalProperties": False, + "properties": { + "Count": {"type": "integer"}, + "Pool": {"type": "string"}, + "Size": {"type": "integer"}, + }, + "required": ["Pool", "Size", "Count"], + "type": "object", + }, + "ConsumeApplicationArgV5": { + "additionalProperties": False, + "properties": { + "ApplicationOfferDetailsV5": { + "$ref": "#/definitions/ApplicationOfferDetailsV5" + }, + "application-alias": {"type": "string"}, + "application-description": {"type": "string"}, + "endpoints": { + "items": {"$ref": "#/definitions/RemoteEndpoint"}, + "type": "array", + }, + "external-controller": { + "$ref": "#/definitions/ExternalControllerInfo" + }, + "macaroon": {"$ref": "#/definitions/Macaroon"}, + "offer-name": {"type": "string"}, + "offer-url": {"type": "string"}, + "offer-uuid": {"type": "string"}, + "source-model-tag": {"type": "string"}, + "users": { + "items": {"$ref": "#/definitions/OfferUserDetails"}, + "type": "array", + }, + }, + "required": [ + "source-model-tag", + "offer-uuid", + "offer-url", + "offer-name", + "application-description", + "ApplicationOfferDetailsV5", + ], + "type": "object", + }, + "ConsumeApplicationArgsV5": { + "additionalProperties": False, + "properties": { + "args": { + "items": {"$ref": "#/definitions/ConsumeApplicationArgV5"}, + "type": "array", + } + }, + "type": "object", + }, + "DeployFromRepositoryArg": { + "additionalProperties": False, + "properties": { + "ApplicationName": {"type": "string"}, + "AttachStorage": {"items": {"type": "string"}, "type": "array"}, + "CharmName": {"type": "string"}, + "ConfigYAML": {"type": "string"}, + "Cons": {"$ref": "#/definitions/Value"}, + "Devices": { + "patternProperties": { + ".*": {"$ref": "#/definitions/Constraints"} + }, + "type": "object", + }, + "DryRun": {"type": "boolean"}, + "Placement": { + "items": {"$ref": "#/definitions/Placement"}, + "type": "array", + }, + "Storage": { + "patternProperties": { + ".*": {"$ref": "#/definitions/Constraints"} + }, + "type": "object", + }, + "Trust": {"type": "boolean"}, + "base": {"$ref": "#/definitions/Base"}, + "channel": {"type": "string"}, + "endpoint-bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "force": {"type": "boolean"}, + "num-units": {"type": "integer"}, + "resources": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "revision": {"type": "integer"}, + }, + "required": [ + "CharmName", + "ApplicationName", + "AttachStorage", + "ConfigYAML", + "Cons", + "Devices", + "DryRun", + "Placement", + "Storage", + "Trust", + ], + "type": "object", + }, + "DeployFromRepositoryArgs": { + "additionalProperties": False, + "properties": { + "Args": { + "items": {"$ref": "#/definitions/DeployFromRepositoryArg"}, + "type": "array", + } + }, + "required": ["Args"], + "type": "object", + }, + "DeployFromRepositoryInfo": { + "additionalProperties": False, + "properties": { + "architecture": {"type": "string"}, + "base": {"$ref": "#/definitions/Base"}, + "channel": {"type": "string"}, + "effective-channel": {"type": "string"}, + "name": {"type": "string"}, + "revision": {"type": "integer"}, + }, + "required": ["architecture", "channel", "name", "revision"], + "type": "object", + }, + "DeployFromRepositoryResult": { + "additionalProperties": False, + "properties": { + "Errors": { + "items": {"$ref": "#/definitions/Error"}, + "type": "array", + }, + "Info": {"$ref": "#/definitions/DeployFromRepositoryInfo"}, + "PendingResourceUploads": { + "items": {"$ref": "#/definitions/PendingResourceUpload"}, + "type": "array", + }, + }, + "required": ["Errors", "Info", "PendingResourceUploads"], + "type": "object", + }, + "DeployFromRepositoryResults": { + "additionalProperties": False, + "properties": { + "Results": { + "items": {"$ref": "#/definitions/DeployFromRepositoryResult"}, + "type": "array", + } + }, + "required": ["Results"], + "type": "object", + }, + "DestroyApplicationInfo": { + "additionalProperties": False, + "properties": { + "destroyed-storage": { + "items": {"$ref": "#/definitions/Entity"}, + "type": "array", + }, + "destroyed-units": { + "items": {"$ref": "#/definitions/Entity"}, + "type": "array", + }, + "detached-storage": { + "items": {"$ref": "#/definitions/Entity"}, + "type": "array", + }, + }, + "type": "object", + }, + "DestroyApplicationParams": { + "additionalProperties": False, + "properties": { + "application-tag": {"type": "string"}, + "destroy-storage": {"type": "boolean"}, + "dry-run": {"type": "boolean"}, + "force": {"type": "boolean"}, + "max-wait": {"type": "integer"}, + }, + "required": ["application-tag", "force"], + "type": "object", + }, + "DestroyApplicationResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "info": {"$ref": "#/definitions/DestroyApplicationInfo"}, + }, + "type": "object", + }, + "DestroyApplicationResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/DestroyApplicationResult"}, + "type": "array", + } + }, + "type": "object", + }, + "DestroyApplicationsParams": { + "additionalProperties": False, + "properties": { + "applications": { + "items": {"$ref": "#/definitions/DestroyApplicationParams"}, + "type": "array", + } + }, + "required": ["applications"], + "type": "object", + }, + "DestroyConsumedApplicationParams": { + "additionalProperties": False, + "properties": { + "application-tag": {"type": "string"}, + "force": {"type": "boolean"}, + "max-wait": {"type": "integer"}, + }, + "required": ["application-tag"], + "type": "object", + }, + "DestroyConsumedApplicationsParams": { + "additionalProperties": False, + "properties": { + "applications": { + "items": { + "$ref": "#/definitions/DestroyConsumedApplicationParams" + }, + "type": "array", + } + }, + "required": ["applications"], + "type": "object", + }, + "DestroyRelation": { + "additionalProperties": False, + "properties": { + "endpoints": {"items": {"type": "string"}, "type": "array"}, + "force": {"type": "boolean"}, + "max-wait": {"type": "integer"}, + "relation-id": {"type": "integer"}, + }, + "required": ["relation-id"], + "type": "object", + }, + "DestroyUnitInfo": { + "additionalProperties": False, + "properties": { + "destroyed-storage": { + "items": {"$ref": "#/definitions/Entity"}, + "type": "array", + }, + "detached-storage": { + "items": {"$ref": "#/definitions/Entity"}, + "type": "array", + }, + }, + "type": "object", + }, + "DestroyUnitParams": { + "additionalProperties": False, + "properties": { + "destroy-storage": {"type": "boolean"}, + "dry-run": {"type": "boolean"}, + "force": {"type": "boolean"}, + "max-wait": {"type": "integer"}, + "unit-tag": {"type": "string"}, + }, + "required": ["unit-tag"], + "type": "object", + }, + "DestroyUnitResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "info": {"$ref": "#/definitions/DestroyUnitInfo"}, + }, + "type": "object", + }, + "DestroyUnitResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/DestroyUnitResult"}, + "type": "array", + } + }, + "type": "object", + }, + "DestroyUnitsParams": { + "additionalProperties": False, + "properties": { + "units": { + "items": {"$ref": "#/definitions/DestroyUnitParams"}, + "type": "array", + } + }, + "required": ["units"], + "type": "object", + }, + "EndpointRelationData": { + "additionalProperties": False, + "properties": { + "ApplicationData": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "cross-model": {"type": "boolean"}, + "endpoint": {"type": "string"}, + "related-endpoint": {"type": "string"}, + "relation-id": {"type": "integer"}, + "unit-relation-data": { + "patternProperties": { + ".*": {"$ref": "#/definitions/RelationData"} + }, + "type": "object", + }, + }, + "required": [ + "relation-id", + "endpoint", + "cross-model", + "related-endpoint", + "ApplicationData", + "unit-relation-data", + ], + "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", + }, + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "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", + }, + "ExposedEndpoint": { + "additionalProperties": False, + "properties": { + "expose-to-cidrs": {"items": {"type": "string"}, "type": "array"}, + "expose-to-spaces": {"items": {"type": "string"}, "type": "array"}, + }, + "type": "object", + }, + "ExternalControllerInfo": { + "additionalProperties": False, + "properties": { + "addrs": {"items": {"type": "string"}, "type": "array"}, + "ca-cert": {"type": "string"}, + "controller-alias": {"type": "string"}, + "controller-tag": {"type": "string"}, + }, + "required": ["controller-tag", "controller-alias", "addrs", "ca-cert"], + "type": "object", + }, + "Macaroon": {"additionalProperties": False, "type": "object"}, + "OfferUserDetails": { + "additionalProperties": False, + "properties": { + "access": {"type": "string"}, + "display-name": {"type": "string"}, + "user": {"type": "string"}, + }, + "required": ["user", "display-name", "access"], + "type": "object", + }, + "PendingResourceUpload": { + "additionalProperties": False, + "properties": { + "Filename": {"type": "string"}, + "Name": {"type": "string"}, + "Type": {"type": "string"}, + }, + "required": ["Name", "Filename", "Type"], + "type": "object", + }, + "Placement": { + "additionalProperties": False, + "properties": { + "directive": {"type": "string"}, + "scope": {"type": "string"}, + }, + "required": ["scope", "directive"], + "type": "object", + }, + "RelationData": { + "additionalProperties": False, + "properties": { + "InScope": {"type": "boolean"}, + "UnitData": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + }, + "required": ["InScope", "UnitData"], + "type": "object", + }, + "RelationSuspendedArg": { + "additionalProperties": False, + "properties": { + "message": {"type": "string"}, + "relation-id": {"type": "integer"}, + "suspended": {"type": "boolean"}, + }, + "required": ["relation-id", "message", "suspended"], + "type": "object", + }, + "RelationSuspendedArgs": { + "additionalProperties": False, + "properties": { + "args": { + "items": {"$ref": "#/definitions/RelationSuspendedArg"}, + "type": "array", + } + }, + "required": ["args"], + "type": "object", + }, + "RemoteEndpoint": { + "additionalProperties": False, + "properties": { + "interface": {"type": "string"}, + "limit": {"type": "integer"}, + "name": {"type": "string"}, + "role": {"type": "string"}, + }, + "required": ["name", "role", "interface", "limit"], + "type": "object", + }, + "ScaleApplicationInfo": { + "additionalProperties": False, + "properties": {"num-units": {"type": "integer"}}, + "required": ["num-units"], + "type": "object", + }, + "ScaleApplicationParams": { + "additionalProperties": False, + "properties": { + "application-tag": {"type": "string"}, + "force": {"type": "boolean"}, + "scale": {"type": "integer"}, + "scale-change": {"type": "integer"}, + }, + "required": ["application-tag", "scale", "force"], + "type": "object", + }, + "ScaleApplicationResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "info": {"$ref": "#/definitions/ScaleApplicationInfo"}, + }, + "type": "object", + }, + "ScaleApplicationResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ScaleApplicationResult"}, + "type": "array", + } + }, + "type": "object", + }, + "ScaleApplicationsParams": { + "additionalProperties": False, + "properties": { + "applications": { + "items": {"$ref": "#/definitions/ScaleApplicationParams"}, + "type": "array", + } + }, + "required": ["applications"], + "type": "object", + }, + "SetConstraints": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "constraints": {"$ref": "#/definitions/Value"}, + }, + "required": ["application", "constraints"], + "type": "object", + }, + "StorageConstraints": { + "additionalProperties": False, + "properties": { + "count": {"type": "integer"}, + "pool": {"type": "string"}, + "size": {"type": "integer"}, + }, + "type": "object", + }, + "StringResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"type": "string"}, + }, + "required": ["result"], + "type": "object", + }, + "UnitInfoResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/UnitResult"}, + }, + "type": "object", + }, + "UnitInfoResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/UnitInfoResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "UnitResult": { + "additionalProperties": False, + "properties": { + "address": {"type": "string"}, + "charm": {"type": "string"}, + "leader": {"type": "boolean"}, + "life": {"type": "string"}, + "machine": {"type": "string"}, + "opened-ports": {"items": {"type": "string"}, "type": "array"}, + "provider-id": {"type": "string"}, + "public-address": {"type": "string"}, + "relation-data": { + "items": {"$ref": "#/definitions/EndpointRelationData"}, + "type": "array", + }, + "tag": {"type": "string"}, + "workload-version": {"type": "string"}, + }, + "required": ["tag", "workload-version", "opened-ports", "charm"], + "type": "object", + }, + "UnitsResolved": { + "additionalProperties": False, + "properties": { + "all": {"type": "boolean"}, + "retry": {"type": "boolean"}, + "tags": {"$ref": "#/definitions/Entities"}, + }, + "type": "object", + }, + "UpdateChannelArg": { + "additionalProperties": False, + "properties": { + "channel": {"type": "string"}, + "force": {"type": "boolean"}, + "tag": {"$ref": "#/definitions/Entity"}, + }, + "required": ["tag", "force", "channel"], + "type": "object", + }, + "UpdateChannelArgs": { + "additionalProperties": False, + "properties": { + "args": { + "items": {"$ref": "#/definitions/UpdateChannelArg"}, + "type": "array", + } + }, + "required": ["args"], + "type": "object", + }, + "Value": { + "additionalProperties": False, + "properties": { + "allocate-public-ip": {"type": "boolean"}, + "arch": {"type": "string"}, + "container": {"type": "string"}, + "cores": {"type": "integer"}, + "cpu-power": {"type": "integer"}, + "image-id": {"type": "string"}, + "instance-role": {"type": "string"}, + "instance-type": {"type": "string"}, + "mem": {"type": "integer"}, + "root-disk": {"type": "integer"}, + "root-disk-source": {"type": "string"}, + "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": { + "AddRelation": { + "description": "AddRelation adds a relation " + "between the specified " + "endpoints and returns the " + "relation info.", + "properties": { + "Params": {"$ref": "#/definitions/AddRelation"}, + "Result": {"$ref": "#/definitions/AddRelationResults"}, + }, + "type": "object", + }, + "AddUnits": { + "description": "AddUnits adds a given number of " + "units to an application.", + "properties": { + "Params": {"$ref": "#/definitions/AddApplicationUnits"}, + "Result": {"$ref": "#/definitions/AddApplicationUnitsResults"}, + }, + "type": "object", + }, + "ApplicationsInfo": { + "description": "ApplicationsInfo returns applications information.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/ApplicationInfoResults"}, + }, + "type": "object", + }, + "CharmConfig": { + "description": "CharmConfig returns charm " + "config for the input list of " + "applications and\n" + "model generations.", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationGetArgs"}, + "Result": {"$ref": "#/definitions/ApplicationGetConfigResults"}, + }, + "type": "object", + }, + "CharmRelations": { + "description": "CharmRelations implements " + "the server side of " + "Application.CharmRelations.", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationCharmRelations"}, + "Result": { + "$ref": "#/definitions/ApplicationCharmRelationsResults" + }, + }, + "type": "object", + }, + "Consume": { + "description": "Consume adds remote applications " + "to the model without creating any\n" + "relations.", + "properties": { + "Params": {"$ref": "#/definitions/ConsumeApplicationArgsV5"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "Deploy": { + "description": "Deploy fetches the charms from the " + "charm store and deploys them\n" + "using the specified placement " + "directives.", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationsDeploy"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "DeployFromRepository": { + "description": "DeployFromRepository " + "is a one-stop " + "deployment method for " + "repository\n" + "charms. Only a charm " + "name is required to " + "deploy. If argument " + "validation\n" + "fails, a list of all " + "errors found in " + "validation will be " + "returned. If a\n" + "local resource is " + "provided, details " + "required for " + "uploading the " + "validated\n" + "resource will be " + "returned.", + "properties": { + "Params": {"$ref": "#/definitions/DeployFromRepositoryArgs"}, + "Result": {"$ref": "#/definitions/DeployFromRepositoryResults"}, + }, + "type": "object", + }, + "DestroyApplication": { + "description": "DestroyApplication " + "removes a given set of " + "applications.", + "properties": { + "Params": {"$ref": "#/definitions/DestroyApplicationsParams"}, + "Result": {"$ref": "#/definitions/DestroyApplicationResults"}, + }, + "type": "object", + }, + "DestroyConsumedApplications": { + "description": "DestroyConsumedApplications " + "removes a " + "given set of " + "consumed " + "(remote) " + "applications.", + "properties": { + "Params": { + "$ref": "#/definitions/DestroyConsumedApplicationsParams" + }, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "DestroyRelation": { + "description": "DestroyRelation removes " + "the relation between the\n" + "specified endpoints or an " + "id.", + "properties": {"Params": {"$ref": "#/definitions/DestroyRelation"}}, + "type": "object", + }, + "DestroyUnit": { + "description": "DestroyUnit removes a given set of application units.", + "properties": { + "Params": {"$ref": "#/definitions/DestroyUnitsParams"}, + "Result": {"$ref": "#/definitions/DestroyUnitResults"}, + }, + "type": "object", + }, + "Expose": { + "description": "Expose changes the juju-managed " + "firewall to expose any ports that\n" + "were also explicitly marked by " + "units as open.", + "properties": {"Params": {"$ref": "#/definitions/ApplicationExpose"}}, + "type": "object", + }, + "Get": { + "description": "Get returns the charm configuration " + "for an application.", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationGet"}, + "Result": {"$ref": "#/definitions/ApplicationGetResults"}, + }, + "type": "object", + }, + "GetCharmURLOrigin": { + "description": "GetCharmURLOrigin " + "returns the charm URL " + "and charm origin the " + "given\n" + "application is running " + "at present.", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationGet"}, + "Result": {"$ref": "#/definitions/CharmURLOriginResult"}, + }, + "type": "object", + }, + "GetConfig": { + "description": "GetConfig returns the charm " + "config for each of the input " + "applications.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/ApplicationGetConfigResults"}, + }, + "type": "object", + }, + "GetConstraints": { + "description": "GetConstraints returns the " + "constraints for a given " + "application.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": { + "$ref": "#/definitions/ApplicationGetConstraintsResults" + }, + }, + "type": "object", + }, + "Leader": { + "description": "Leader returns the unit name of the " + "leader for the given application.", + "properties": { + "Params": {"$ref": "#/definitions/Entity"}, + "Result": {"$ref": "#/definitions/StringResult"}, + }, + "type": "object", + }, + "MergeBindings": { + "description": "MergeBindings merges " + "operator-defined bindings " + "with the current bindings " + "for\n" + "one or more applications.", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationMergeBindingsArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "ResolveUnitErrors": { + "description": "ResolveUnitErrors marks " + "errors on the specified " + "units as resolved.", + "properties": { + "Params": {"$ref": "#/definitions/UnitsResolved"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "ScaleApplications": { + "description": "ScaleApplications scales " + "the specified " + "application to the " + "requested number of " + "units.", + "properties": { + "Params": {"$ref": "#/definitions/ScaleApplicationsParams"}, + "Result": {"$ref": "#/definitions/ScaleApplicationResults"}, + }, + "type": "object", + }, + "SetCharm": { + "description": "SetCharm sets the charm for a " + "given for the application.", + "properties": {"Params": {"$ref": "#/definitions/ApplicationSetCharm"}}, + "type": "object", + }, + "SetConfigs": { + "description": "SetConfigs implements the " + "server side of " + "Application.SetConfig. Both\n" + "application and charm config " + "are set. It does not unset " + "values in\n" + "Config map that are set to an " + "empty string. Unset should be " + "used for that.", + "properties": { + "Params": {"$ref": "#/definitions/ConfigSetArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "SetConstraints": { + "description": "SetConstraints sets the " + "constraints for a given " + "application.", + "properties": {"Params": {"$ref": "#/definitions/SetConstraints"}}, + "type": "object", + }, + "SetMetricCredentials": { + "description": "SetMetricCredentials " + "sets credentials on " + "the application.\n" + "TODO (cderici) only " + "used for metered " + "charms in cmd " + "MeteredDeployAPI,\n" + "kept for client " + "compatibility, remove " + "in juju 4.0", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationMetricCredentials"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "SetRelationsSuspended": { + "description": "SetRelationsSuspended " + "sets the suspended " + "status of the " + "specified relations.", + "properties": { + "Params": {"$ref": "#/definitions/RelationSuspendedArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "Unexpose": { + "description": "Unexpose changes the juju-managed " + "firewall to unexpose any ports " + "that\n" + "were also explicitly marked by " + "units as open.", + "properties": {"Params": {"$ref": "#/definitions/ApplicationUnexpose"}}, + "type": "object", + }, + "UnitsInfo": { + "description": "UnitsInfo returns unit " + "information for the given " + "entities (units or\n" + "applications).", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/UnitInfoResults"}, + }, + "type": "object", + }, + "UnsetApplicationsConfig": { + "description": "UnsetApplicationsConfig " + "implements the " + "server side of " + "Application.UnsetApplicationsConfig.", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationConfigUnsetArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "UpdateApplicationBase": { + "description": "UpdateApplicationBase " + "updates the " + "application base.\n" + "Base for " + "subordinates is " + "updated too.", + "properties": { + "Params": {"$ref": "#/definitions/UpdateChannelArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(AddRelationResults) async def AddRelation(self, endpoints=None, via_cidrs=None): - ''' + """ AddRelation adds a relation between the specified endpoints and returns the relation info. endpoints : typing.Sequence[str] via_cidrs : typing.Sequence[str] Returns -> AddRelationResults - ''' + """ if endpoints is not None and not isinstance(endpoints, (bytes, str, list)): - raise Exception("Expected endpoints to be a Sequence, received: {}".format(type(endpoints))) + raise Exception( + "Expected endpoints to be a Sequence, received: {}".format( + type(endpoints) + ) + ) if via_cidrs is not None and not isinstance(via_cidrs, (bytes, str, list)): - raise Exception("Expected via_cidrs to be a Sequence, received: {}".format(type(via_cidrs))) + raise Exception( + "Expected via_cidrs to be a Sequence, received: {}".format( + type(via_cidrs) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='AddRelation', - version=20, - params=_params) - _params['endpoints'] = endpoints - _params['via-cidrs'] = via_cidrs + msg = dict( + type="Application", request="AddRelation", version=20, params=_params + ) + _params["endpoints"] = endpoints + _params["via-cidrs"] = via_cidrs reply = await self.rpc(msg) return reply - - @ReturnMapping(AddApplicationUnitsResults) - async def AddUnits(self, application=None, attach_storage=None, num_units=None, placement=None, policy=None): - ''' + async def AddUnits( + self, + application=None, + attach_storage=None, + num_units=None, + placement=None, + policy=None, + ): + """ AddUnits adds a given number of units to an application. application : str @@ -968,159 +1547,171 @@ async def AddUnits(self, application=None, attach_storage=None, num_units=None, placement : typing.Sequence[~Placement] policy : str Returns -> AddApplicationUnitsResults - ''' + """ if application is not None and not isinstance(application, (bytes, str)): - raise Exception("Expected application to be a str, received: {}".format(type(application))) - - if attach_storage is not None and not isinstance(attach_storage, (bytes, str, list)): - raise Exception("Expected attach_storage to be a Sequence, received: {}".format(type(attach_storage))) + raise Exception( + "Expected application to be a str, received: {}".format( + type(application) + ) + ) + + if attach_storage is not None and not isinstance( + attach_storage, (bytes, str, list) + ): + raise Exception( + "Expected attach_storage to be a Sequence, received: {}".format( + type(attach_storage) + ) + ) if num_units is not None and not isinstance(num_units, int): - raise Exception("Expected num_units to be a int, received: {}".format(type(num_units))) + raise Exception( + "Expected num_units to be a int, received: {}".format(type(num_units)) + ) if placement is not None and not isinstance(placement, (bytes, str, list)): - raise Exception("Expected placement to be a Sequence, received: {}".format(type(placement))) + raise Exception( + "Expected placement to be a Sequence, received: {}".format( + type(placement) + ) + ) if policy is not None and not isinstance(policy, (bytes, str)): - raise Exception("Expected policy to be a str, received: {}".format(type(policy))) + raise Exception( + "Expected policy to be a str, received: {}".format(type(policy)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='AddUnits', - version=20, - params=_params) - _params['application'] = application - _params['attach-storage'] = attach_storage - _params['num-units'] = num_units - _params['placement'] = placement - _params['policy'] = policy + msg = dict(type="Application", request="AddUnits", version=20, params=_params) + _params["application"] = application + _params["attach-storage"] = attach_storage + _params["num-units"] = num_units + _params["placement"] = placement + _params["policy"] = policy reply = await self.rpc(msg) return reply - - @ReturnMapping(ApplicationInfoResults) async def ApplicationsInfo(self, entities=None): - ''' + """ ApplicationsInfo returns applications information. entities : typing.Sequence[~Entity] Returns -> ApplicationInfoResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='ApplicationsInfo', - version=20, - params=_params) - _params['entities'] = entities + msg = dict( + type="Application", request="ApplicationsInfo", version=20, params=_params + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ApplicationGetConfigResults) async def CharmConfig(self, args=None): - ''' + """ CharmConfig returns charm config for the input list of applications and model generations. args : typing.Sequence[~ApplicationGet] Returns -> ApplicationGetConfigResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='CharmConfig', - version=20, - params=_params) - _params['args'] = args + msg = dict( + type="Application", request="CharmConfig", version=20, params=_params + ) + _params["args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(ApplicationCharmRelationsResults) async def CharmRelations(self, application=None): - ''' + """ CharmRelations implements the server side of Application.CharmRelations. application : str Returns -> ApplicationCharmRelationsResults - ''' + """ if application is not None and not isinstance(application, (bytes, str)): - raise Exception("Expected application to be a str, received: {}".format(type(application))) + raise Exception( + "Expected application to be a str, received: {}".format( + type(application) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='CharmRelations', - version=20, - params=_params) - _params['application'] = application + msg = dict( + type="Application", request="CharmRelations", version=20, params=_params + ) + _params["application"] = application reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def Consume(self, args=None): - ''' + """ Consume adds remote applications to the model without creating any relations. args : typing.Sequence[~ConsumeApplicationArgV5] Returns -> ErrorResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='Consume', - version=20, - params=_params) - _params['args'] = args + msg = dict(type="Application", request="Consume", version=20, params=_params) + _params["args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def Deploy(self, applications=None): - ''' + """ Deploy fetches the charms from the charm store and deploys them using the specified placement directives. applications : typing.Sequence[~ApplicationDeploy] Returns -> ErrorResults - ''' - if applications is not None and not isinstance(applications, (bytes, str, list)): - raise Exception("Expected applications to be a Sequence, received: {}".format(type(applications))) + """ + if applications is not None and not isinstance( + applications, (bytes, str, list) + ): + raise Exception( + "Expected applications to be a Sequence, received: {}".format( + type(applications) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='Deploy', - version=20, - params=_params) - _params['applications'] = applications + msg = dict(type="Application", request="Deploy", version=20, params=_params) + _params["applications"] = applications reply = await self.rpc(msg) return reply - - @ReturnMapping(DeployFromRepositoryResults) async def DeployFromRepository(self, args=None): - ''' + """ DeployFromRepository is a one-stop deployment method for repository charms. Only a charm name is required to deploy. If argument validation fails, a list of all errors found in validation will be returned. If a @@ -1129,71 +1720,84 @@ async def DeployFromRepository(self, args=None): args : typing.Sequence[~DeployFromRepositoryArg] Returns -> DeployFromRepositoryResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='DeployFromRepository', - version=20, - params=_params) - _params['Args'] = args + msg = dict( + type="Application", + request="DeployFromRepository", + version=20, + params=_params, + ) + _params["Args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(DestroyApplicationResults) async def DestroyApplication(self, applications=None): - ''' + """ DestroyApplication removes a given set of applications. applications : typing.Sequence[~DestroyApplicationParams] Returns -> DestroyApplicationResults - ''' - if applications is not None and not isinstance(applications, (bytes, str, list)): - raise Exception("Expected applications to be a Sequence, received: {}".format(type(applications))) + """ + if applications is not None and not isinstance( + applications, (bytes, str, list) + ): + raise Exception( + "Expected applications to be a Sequence, received: {}".format( + type(applications) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='DestroyApplication', - version=20, - params=_params) - _params['applications'] = applications + msg = dict( + type="Application", request="DestroyApplication", version=20, params=_params + ) + _params["applications"] = applications reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def DestroyConsumedApplications(self, applications=None): - ''' + """ DestroyConsumedApplications removes a given set of consumed (remote) applications. applications : typing.Sequence[~DestroyConsumedApplicationParams] Returns -> ErrorResults - ''' - if applications is not None and not isinstance(applications, (bytes, str, list)): - raise Exception("Expected applications to be a Sequence, received: {}".format(type(applications))) + """ + if applications is not None and not isinstance( + applications, (bytes, str, list) + ): + raise Exception( + "Expected applications to be a Sequence, received: {}".format( + type(applications) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='DestroyConsumedApplications', - version=20, - params=_params) - _params['applications'] = applications + msg = dict( + type="Application", + request="DestroyConsumedApplications", + version=20, + params=_params, + ) + _params["applications"] = applications reply = await self.rpc(msg) return reply - - @ReturnMapping(None) - async def DestroyRelation(self, endpoints=None, force=None, max_wait=None, relation_id=None): - ''' + async def DestroyRelation( + self, endpoints=None, force=None, max_wait=None, relation_id=None + ): + """ DestroyRelation removes the relation between the specified endpoints or an id. @@ -1202,295 +1806,325 @@ async def DestroyRelation(self, endpoints=None, force=None, max_wait=None, relat max_wait : int relation_id : int Returns -> None - ''' + """ if endpoints is not None and not isinstance(endpoints, (bytes, str, list)): - raise Exception("Expected endpoints to be a Sequence, received: {}".format(type(endpoints))) + raise Exception( + "Expected endpoints to be a Sequence, received: {}".format( + type(endpoints) + ) + ) if force is not None and not isinstance(force, bool): - raise Exception("Expected force to be a bool, received: {}".format(type(force))) + raise Exception( + "Expected force to be a bool, received: {}".format(type(force)) + ) if max_wait is not None and not isinstance(max_wait, int): - raise Exception("Expected max_wait to be a int, received: {}".format(type(max_wait))) + raise Exception( + "Expected max_wait to be a int, received: {}".format(type(max_wait)) + ) if relation_id is not None and not isinstance(relation_id, int): - raise Exception("Expected relation_id to be a int, received: {}".format(type(relation_id))) + raise Exception( + "Expected relation_id to be a int, received: {}".format( + type(relation_id) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='DestroyRelation', - version=20, - params=_params) - _params['endpoints'] = endpoints - _params['force'] = force - _params['max-wait'] = max_wait - _params['relation-id'] = relation_id + msg = dict( + type="Application", request="DestroyRelation", version=20, params=_params + ) + _params["endpoints"] = endpoints + _params["force"] = force + _params["max-wait"] = max_wait + _params["relation-id"] = relation_id reply = await self.rpc(msg) return reply - - @ReturnMapping(DestroyUnitResults) async def DestroyUnit(self, units=None): - ''' + """ DestroyUnit removes a given set of application units. units : typing.Sequence[~DestroyUnitParams] Returns -> DestroyUnitResults - ''' + """ if units is not None and not isinstance(units, (bytes, str, list)): - raise Exception("Expected units to be a Sequence, received: {}".format(type(units))) + raise Exception( + "Expected units to be a Sequence, received: {}".format(type(units)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='DestroyUnit', - version=20, - params=_params) - _params['units'] = units + msg = dict( + type="Application", request="DestroyUnit", version=20, params=_params + ) + _params["units"] = units reply = await self.rpc(msg) return reply - - @ReturnMapping(None) async def Expose(self, application=None, exposed_endpoints=None): - ''' + """ Expose changes the juju-managed firewall to expose any ports that were also explicitly marked by units as open. application : str exposed_endpoints : typing.Mapping[str, ~ExposedEndpoint] Returns -> None - ''' + """ if application is not None and not isinstance(application, (bytes, str)): - raise Exception("Expected application to be a str, received: {}".format(type(application))) + raise Exception( + "Expected application to be a str, received: {}".format( + type(application) + ) + ) if exposed_endpoints is not None and not isinstance(exposed_endpoints, dict): - raise Exception("Expected exposed_endpoints to be a Mapping, received: {}".format(type(exposed_endpoints))) + raise Exception( + "Expected exposed_endpoints to be a Mapping, received: {}".format( + type(exposed_endpoints) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='Expose', - version=20, - params=_params) - _params['application'] = application - _params['exposed-endpoints'] = exposed_endpoints + msg = dict(type="Application", request="Expose", version=20, params=_params) + _params["application"] = application + _params["exposed-endpoints"] = exposed_endpoints reply = await self.rpc(msg) return reply - - @ReturnMapping(ApplicationGetResults) async def Get(self, application=None, branch=None): - ''' + """ Get returns the charm configuration for an application. application : str branch : str Returns -> ApplicationGetResults - ''' + """ if application is not None and not isinstance(application, (bytes, str)): - raise Exception("Expected application to be a str, received: {}".format(type(application))) + raise Exception( + "Expected application to be a str, received: {}".format( + type(application) + ) + ) if branch is not None and not isinstance(branch, (bytes, str)): - raise Exception("Expected branch to be a str, received: {}".format(type(branch))) + raise Exception( + "Expected branch to be a str, received: {}".format(type(branch)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='Get', - version=20, - params=_params) - _params['application'] = application - _params['branch'] = branch + msg = dict(type="Application", request="Get", version=20, params=_params) + _params["application"] = application + _params["branch"] = branch reply = await self.rpc(msg) return reply - - @ReturnMapping(CharmURLOriginResult) async def GetCharmURLOrigin(self, application=None, branch=None): - ''' + """ GetCharmURLOrigin returns the charm URL and charm origin the given application is running at present. application : str branch : str Returns -> CharmURLOriginResult - ''' + """ if application is not None and not isinstance(application, (bytes, str)): - raise Exception("Expected application to be a str, received: {}".format(type(application))) + raise Exception( + "Expected application to be a str, received: {}".format( + type(application) + ) + ) if branch is not None and not isinstance(branch, (bytes, str)): - raise Exception("Expected branch to be a str, received: {}".format(type(branch))) + raise Exception( + "Expected branch to be a str, received: {}".format(type(branch)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='GetCharmURLOrigin', - version=20, - params=_params) - _params['application'] = application - _params['branch'] = branch + msg = dict( + type="Application", request="GetCharmURLOrigin", version=20, params=_params + ) + _params["application"] = application + _params["branch"] = branch reply = await self.rpc(msg) return reply - - @ReturnMapping(ApplicationGetConfigResults) async def GetConfig(self, entities=None): - ''' + """ GetConfig returns the charm config for each of the input applications. entities : typing.Sequence[~Entity] Returns -> ApplicationGetConfigResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='GetConfig', - version=20, - params=_params) - _params['entities'] = entities + msg = dict(type="Application", request="GetConfig", version=20, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ApplicationGetConstraintsResults) async def GetConstraints(self, entities=None): - ''' + """ GetConstraints returns the constraints for a given application. entities : typing.Sequence[~Entity] Returns -> ApplicationGetConstraintsResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='GetConstraints', - version=20, - params=_params) - _params['entities'] = entities + msg = dict( + type="Application", request="GetConstraints", version=20, params=_params + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(StringResult) async def Leader(self, tag=None): - ''' + """ Leader returns the unit name of the leader for the given application. tag : str Returns -> StringResult - ''' + """ if tag is not None and not isinstance(tag, (bytes, str)): raise Exception("Expected tag to be a str, received: {}".format(type(tag))) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='Leader', - version=20, - params=_params) - _params['tag'] = tag + msg = dict(type="Application", request="Leader", version=20, params=_params) + _params["tag"] = tag reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def MergeBindings(self, args=None): - ''' + """ MergeBindings merges operator-defined bindings with the current bindings for one or more applications. args : typing.Sequence[~ApplicationMergeBindings] Returns -> ErrorResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='MergeBindings', - version=20, - params=_params) - _params['args'] = args + msg = dict( + type="Application", request="MergeBindings", version=20, params=_params + ) + _params["args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def ResolveUnitErrors(self, all_=None, retry=None, tags=None): - ''' + """ ResolveUnitErrors marks errors on the specified units as resolved. all_ : bool retry : bool tags : Entities Returns -> ErrorResults - ''' + """ if all_ is not None and not isinstance(all_, bool): - raise Exception("Expected all_ to be a bool, received: {}".format(type(all_))) + raise Exception( + "Expected all_ to be a bool, received: {}".format(type(all_)) + ) if retry is not None and not isinstance(retry, bool): - raise Exception("Expected retry to be a bool, received: {}".format(type(retry))) + raise Exception( + "Expected retry to be a bool, received: {}".format(type(retry)) + ) if tags is not None and not isinstance(tags, (dict, Entities)): - raise Exception("Expected tags to be a Entities, received: {}".format(type(tags))) + raise Exception( + "Expected tags to be a Entities, received: {}".format(type(tags)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='ResolveUnitErrors', - version=20, - params=_params) - _params['all'] = all_ - _params['retry'] = retry - _params['tags'] = tags + msg = dict( + type="Application", request="ResolveUnitErrors", version=20, params=_params + ) + _params["all"] = all_ + _params["retry"] = retry + _params["tags"] = tags reply = await self.rpc(msg) return reply - - @ReturnMapping(ScaleApplicationResults) async def ScaleApplications(self, applications=None): - ''' + """ ScaleApplications scales the specified application to the requested number of units. applications : typing.Sequence[~ScaleApplicationParams] Returns -> ScaleApplicationResults - ''' - if applications is not None and not isinstance(applications, (bytes, str, list)): - raise Exception("Expected applications to be a Sequence, received: {}".format(type(applications))) + """ + if applications is not None and not isinstance( + applications, (bytes, str, list) + ): + raise Exception( + "Expected applications to be a Sequence, received: {}".format( + type(applications) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='ScaleApplications', - version=20, - params=_params) - _params['applications'] = applications + msg = dict( + type="Application", request="ScaleApplications", version=20, params=_params + ) + _params["applications"] = applications reply = await self.rpc(msg) return reply - - @ReturnMapping(None) - async def SetCharm(self, application=None, channel=None, charm_origin=None, charm_url=None, config_settings=None, config_settings_yaml=None, endpoint_bindings=None, force=None, force_base=None, force_units=None, generation=None, resource_ids=None, storage_constraints=None): - ''' + async def SetCharm( + self, + application=None, + channel=None, + charm_origin=None, + charm_url=None, + config_settings=None, + config_settings_yaml=None, + endpoint_bindings=None, + force=None, + force_base=None, + force_units=None, + generation=None, + resource_ids=None, + storage_constraints=None, + ): + """ SetCharm sets the charm for a given for the application. application : str @@ -1507,267 +2141,326 @@ async def SetCharm(self, application=None, channel=None, charm_origin=None, char resource_ids : typing.Mapping[str, str] storage_constraints : typing.Mapping[str, ~StorageConstraints] Returns -> None - ''' + """ if application is not None and not isinstance(application, (bytes, str)): - raise Exception("Expected application to be a str, received: {}".format(type(application))) + raise Exception( + "Expected application to be a str, received: {}".format( + type(application) + ) + ) if channel is not None and not isinstance(channel, (bytes, str)): - raise Exception("Expected channel to be a str, received: {}".format(type(channel))) - - if charm_origin is not None and not isinstance(charm_origin, (dict, CharmOrigin)): - raise Exception("Expected charm_origin to be a CharmOrigin, received: {}".format(type(charm_origin))) + raise Exception( + "Expected channel to be a str, received: {}".format(type(channel)) + ) + + if charm_origin is not None and not isinstance( + charm_origin, (dict, CharmOrigin) + ): + raise Exception( + "Expected charm_origin to be a CharmOrigin, received: {}".format( + type(charm_origin) + ) + ) if charm_url is not None and not isinstance(charm_url, (bytes, str)): - raise Exception("Expected charm_url to be a str, received: {}".format(type(charm_url))) + raise Exception( + "Expected charm_url to be a str, received: {}".format(type(charm_url)) + ) if config_settings is not None and not isinstance(config_settings, dict): - raise Exception("Expected config_settings to be a Mapping, received: {}".format(type(config_settings))) - - if config_settings_yaml is not None and not isinstance(config_settings_yaml, (bytes, str)): - raise Exception("Expected config_settings_yaml to be a str, received: {}".format(type(config_settings_yaml))) + raise Exception( + "Expected config_settings to be a Mapping, received: {}".format( + type(config_settings) + ) + ) + + if config_settings_yaml is not None and not isinstance( + config_settings_yaml, (bytes, str) + ): + raise Exception( + "Expected config_settings_yaml to be a str, received: {}".format( + type(config_settings_yaml) + ) + ) if endpoint_bindings is not None and not isinstance(endpoint_bindings, dict): - raise Exception("Expected endpoint_bindings to be a Mapping, received: {}".format(type(endpoint_bindings))) + raise Exception( + "Expected endpoint_bindings to be a Mapping, received: {}".format( + type(endpoint_bindings) + ) + ) if force is not None and not isinstance(force, bool): - raise Exception("Expected force to be a bool, received: {}".format(type(force))) + raise Exception( + "Expected force to be a bool, received: {}".format(type(force)) + ) if force_base is not None and not isinstance(force_base, bool): - raise Exception("Expected force_base to be a bool, received: {}".format(type(force_base))) + raise Exception( + "Expected force_base to be a bool, received: {}".format( + type(force_base) + ) + ) if force_units is not None and not isinstance(force_units, bool): - raise Exception("Expected force_units to be a bool, received: {}".format(type(force_units))) + raise Exception( + "Expected force_units to be a bool, received: {}".format( + type(force_units) + ) + ) if generation is not None and not isinstance(generation, (bytes, str)): - raise Exception("Expected generation to be a str, received: {}".format(type(generation))) + raise Exception( + "Expected generation to be a str, received: {}".format(type(generation)) + ) if resource_ids is not None and not isinstance(resource_ids, dict): - raise Exception("Expected resource_ids to be a Mapping, received: {}".format(type(resource_ids))) - - if storage_constraints is not None and not isinstance(storage_constraints, dict): - raise Exception("Expected storage_constraints to be a Mapping, received: {}".format(type(storage_constraints))) + raise Exception( + "Expected resource_ids to be a Mapping, received: {}".format( + type(resource_ids) + ) + ) + + if storage_constraints is not None and not isinstance( + storage_constraints, dict + ): + raise Exception( + "Expected storage_constraints to be a Mapping, received: {}".format( + type(storage_constraints) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='SetCharm', - version=20, - params=_params) - _params['application'] = application - _params['channel'] = channel - _params['charm-origin'] = charm_origin - _params['charm-url'] = charm_url - _params['config-settings'] = config_settings - _params['config-settings-yaml'] = config_settings_yaml - _params['endpoint-bindings'] = endpoint_bindings - _params['force'] = force - _params['force-base'] = force_base - _params['force-units'] = force_units - _params['generation'] = generation - _params['resource-ids'] = resource_ids - _params['storage-constraints'] = storage_constraints + msg = dict(type="Application", request="SetCharm", version=20, params=_params) + _params["application"] = application + _params["channel"] = channel + _params["charm-origin"] = charm_origin + _params["charm-url"] = charm_url + _params["config-settings"] = config_settings + _params["config-settings-yaml"] = config_settings_yaml + _params["endpoint-bindings"] = endpoint_bindings + _params["force"] = force + _params["force-base"] = force_base + _params["force-units"] = force_units + _params["generation"] = generation + _params["resource-ids"] = resource_ids + _params["storage-constraints"] = storage_constraints reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def SetConfigs(self, args=None): - ''' + """ SetConfigs implements the server side of Application.SetConfig. Both application and charm config are set. It does not unset values in Config map that are set to an empty string. Unset should be used for that. args : typing.Sequence[~ConfigSet] Returns -> ErrorResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='SetConfigs', - version=20, - params=_params) - _params['Args'] = args + msg = dict(type="Application", request="SetConfigs", version=20, params=_params) + _params["Args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(None) async def SetConstraints(self, application=None, constraints=None): - ''' + """ SetConstraints sets the constraints for a given application. application : str constraints : Value Returns -> None - ''' + """ if application is not None and not isinstance(application, (bytes, str)): - raise Exception("Expected application to be a str, received: {}".format(type(application))) + raise Exception( + "Expected application to be a str, received: {}".format( + type(application) + ) + ) if constraints is not None and not isinstance(constraints, (dict, Value)): - raise Exception("Expected constraints to be a Value, received: {}".format(type(constraints))) + raise Exception( + "Expected constraints to be a Value, received: {}".format( + type(constraints) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='SetConstraints', - version=20, - params=_params) - _params['application'] = application - _params['constraints'] = constraints + msg = dict( + type="Application", request="SetConstraints", version=20, params=_params + ) + _params["application"] = application + _params["constraints"] = constraints reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def SetMetricCredentials(self, creds=None): - ''' + """ SetMetricCredentials sets credentials on the application. TODO (cderici) only used for metered charms in cmd MeteredDeployAPI, kept for client compatibility, remove in juju 4.0 creds : typing.Sequence[~ApplicationMetricCredential] Returns -> ErrorResults - ''' + """ if creds is not None and not isinstance(creds, (bytes, str, list)): - raise Exception("Expected creds to be a Sequence, received: {}".format(type(creds))) + raise Exception( + "Expected creds to be a Sequence, received: {}".format(type(creds)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='SetMetricCredentials', - version=20, - params=_params) - _params['creds'] = creds + msg = dict( + type="Application", + request="SetMetricCredentials", + version=20, + params=_params, + ) + _params["creds"] = creds reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def SetRelationsSuspended(self, args=None): - ''' + """ SetRelationsSuspended sets the suspended status of the specified relations. args : typing.Sequence[~RelationSuspendedArg] Returns -> ErrorResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='SetRelationsSuspended', - version=20, - params=_params) - _params['args'] = args + msg = dict( + type="Application", + request="SetRelationsSuspended", + version=20, + params=_params, + ) + _params["args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(None) async def Unexpose(self, application=None, exposed_endpoints=None): - ''' + """ Unexpose changes the juju-managed firewall to unexpose any ports that were also explicitly marked by units as open. application : str exposed_endpoints : typing.Sequence[str] Returns -> None - ''' + """ if application is not None and not isinstance(application, (bytes, str)): - raise Exception("Expected application to be a str, received: {}".format(type(application))) - - if exposed_endpoints is not None and not isinstance(exposed_endpoints, (bytes, str, list)): - raise Exception("Expected exposed_endpoints to be a Sequence, received: {}".format(type(exposed_endpoints))) + raise Exception( + "Expected application to be a str, received: {}".format( + type(application) + ) + ) + + if exposed_endpoints is not None and not isinstance( + exposed_endpoints, (bytes, str, list) + ): + raise Exception( + "Expected exposed_endpoints to be a Sequence, received: {}".format( + type(exposed_endpoints) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='Unexpose', - version=20, - params=_params) - _params['application'] = application - _params['exposed-endpoints'] = exposed_endpoints + msg = dict(type="Application", request="Unexpose", version=20, params=_params) + _params["application"] = application + _params["exposed-endpoints"] = exposed_endpoints reply = await self.rpc(msg) return reply - - @ReturnMapping(UnitInfoResults) async def UnitsInfo(self, entities=None): - ''' + """ UnitsInfo returns unit information for the given entities (units or applications). entities : typing.Sequence[~Entity] Returns -> UnitInfoResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='UnitsInfo', - version=20, - params=_params) - _params['entities'] = entities + msg = dict(type="Application", request="UnitsInfo", version=20, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def UnsetApplicationsConfig(self, args=None): - ''' + """ UnsetApplicationsConfig implements the server side of Application.UnsetApplicationsConfig. args : typing.Sequence[~ApplicationUnset] Returns -> ErrorResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='UnsetApplicationsConfig', - version=20, - params=_params) - _params['Args'] = args + msg = dict( + type="Application", + request="UnsetApplicationsConfig", + version=20, + params=_params, + ) + _params["Args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def UpdateApplicationBase(self, args=None): - ''' + """ UpdateApplicationBase updates the application base. Base for subordinates is updated too. args : typing.Sequence[~UpdateChannelArg] Returns -> ErrorResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Application', - request='UpdateApplicationBase', - version=20, - params=_params) - _params['args'] = args + msg = dict( + type="Application", + request="UpdateApplicationBase", + version=20, + params=_params, + ) + _params["args"] = args reply = await self.rpc(msg) return reply - - diff --git a/juju/client/_client3.py b/juju/client/_client3.py index 97b22d904..b9c77c523 100644 --- a/juju/client/_client3.py +++ b/juju/client/_client3.py @@ -6,120 +6,182 @@ class AdminFacade(Type): - name = 'Admin' + name = "Admin" version = 3 - schema = {'definitions': {'Address': {'additionalProperties': False, - 'properties': {'cidr': {'type': 'string'}, - 'config-type': {'type': 'string'}, - 'is-secondary': {'type': 'boolean'}, - 'scope': {'type': 'string'}, - 'space-id': {'type': 'string'}, - 'space-name': {'type': 'string'}, - 'type': {'type': 'string'}, - 'value': {'type': 'string'}}, - 'required': ['value', 'type', 'scope'], - 'type': 'object'}, - 'AuthUserInfo': {'additionalProperties': False, - 'properties': {'controller-access': {'type': 'string'}, - 'credentials': {'type': 'string'}, - 'display-name': {'type': 'string'}, - 'identity': {'type': 'string'}, - 'last-connection': {'format': 'date-time', - 'type': 'string'}, - 'model-access': {'type': 'string'}}, - 'required': ['display-name', - 'identity', - 'controller-access', - 'model-access'], - 'type': 'object'}, - 'FacadeVersions': {'additionalProperties': False, - 'properties': {'name': {'type': 'string'}, - 'versions': {'items': {'type': 'integer'}, - 'type': 'array'}}, - 'required': ['name', 'versions'], - 'type': 'object'}, - 'HostPort': {'additionalProperties': False, - 'properties': {'Address': {'$ref': '#/definitions/Address'}, - 'cidr': {'type': 'string'}, - 'config-type': {'type': 'string'}, - 'is-secondary': {'type': 'boolean'}, - 'port': {'type': 'integer'}, - 'scope': {'type': 'string'}, - 'space-id': {'type': 'string'}, - 'space-name': {'type': 'string'}, - 'type': {'type': 'string'}, - 'value': {'type': 'string'}}, - 'required': ['value', - 'type', - 'scope', - 'Address', - 'port'], - 'type': 'object'}, - 'LoginRequest': {'additionalProperties': False, - 'properties': {'auth-tag': {'type': 'string'}, - 'bakery-version': {'type': 'integer'}, - 'cli-args': {'type': 'string'}, - 'client-version': {'type': 'string'}, - 'credentials': {'type': 'string'}, - 'macaroons': {'items': {'items': {'$ref': '#/definitions/Macaroon'}, - 'type': 'array'}, - 'type': 'array'}, - 'nonce': {'type': 'string'}, - 'token': {'type': 'string'}, - 'user-data': {'type': 'string'}}, - 'required': ['auth-tag', - 'credentials', - 'nonce', - 'macaroons', - 'user-data'], - 'type': 'object'}, - 'LoginResult': {'additionalProperties': False, - 'properties': {'bakery-discharge-required': {'$ref': '#/definitions/Macaroon'}, - 'controller-tag': {'type': 'string'}, - 'discharge-required': {'$ref': '#/definitions/Macaroon'}, - 'discharge-required-error': {'type': 'string'}, - 'facades': {'items': {'$ref': '#/definitions/FacadeVersions'}, - 'type': 'array'}, - 'model-tag': {'type': 'string'}, - 'public-dns-name': {'type': 'string'}, - 'server-version': {'type': 'string'}, - 'servers': {'items': {'items': {'$ref': '#/definitions/HostPort'}, - 'type': 'array'}, - 'type': 'array'}, - 'user-info': {'$ref': '#/definitions/AuthUserInfo'}}, - 'type': 'object'}, - 'Macaroon': {'additionalProperties': False, 'type': 'object'}, - 'RedirectInfoResult': {'additionalProperties': False, - 'properties': {'ca-cert': {'type': 'string'}, - 'servers': {'items': {'items': {'$ref': '#/definitions/HostPort'}, - 'type': 'array'}, - 'type': 'array'}}, - 'required': ['servers', 'ca-cert'], - 'type': 'object'}}, - 'properties': {'Login': {'description': 'Login logs in with the provided ' - 'credentials. All subsequent ' - 'requests on the\n' - 'connection will act as the ' - 'authenticated user.', - 'properties': {'Params': {'$ref': '#/definitions/LoginRequest'}, - 'Result': {'$ref': '#/definitions/LoginResult'}}, - 'type': 'object'}, - 'RedirectInfo': {'description': 'RedirectInfo returns ' - 'redirected host information ' - 'for the model.\n' - 'In Juju it always returns an ' - 'error because the Juju ' - 'controller\n' - 'does not multiplex ' - 'controllers.', - 'properties': {'Result': {'$ref': '#/definitions/RedirectInfoResult'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "Address": { + "additionalProperties": False, + "properties": { + "cidr": {"type": "string"}, + "config-type": {"type": "string"}, + "is-secondary": {"type": "boolean"}, + "scope": {"type": "string"}, + "space-id": {"type": "string"}, + "space-name": {"type": "string"}, + "type": {"type": "string"}, + "value": {"type": "string"}, + }, + "required": ["value", "type", "scope"], + "type": "object", + }, + "AuthUserInfo": { + "additionalProperties": False, + "properties": { + "controller-access": {"type": "string"}, + "credentials": {"type": "string"}, + "display-name": {"type": "string"}, + "identity": {"type": "string"}, + "last-connection": {"format": "date-time", "type": "string"}, + "model-access": {"type": "string"}, + }, + "required": [ + "display-name", + "identity", + "controller-access", + "model-access", + ], + "type": "object", + }, + "FacadeVersions": { + "additionalProperties": False, + "properties": { + "name": {"type": "string"}, + "versions": {"items": {"type": "integer"}, "type": "array"}, + }, + "required": ["name", "versions"], + "type": "object", + }, + "HostPort": { + "additionalProperties": False, + "properties": { + "Address": {"$ref": "#/definitions/Address"}, + "cidr": {"type": "string"}, + "config-type": {"type": "string"}, + "is-secondary": {"type": "boolean"}, + "port": {"type": "integer"}, + "scope": {"type": "string"}, + "space-id": {"type": "string"}, + "space-name": {"type": "string"}, + "type": {"type": "string"}, + "value": {"type": "string"}, + }, + "required": ["value", "type", "scope", "Address", "port"], + "type": "object", + }, + "LoginRequest": { + "additionalProperties": False, + "properties": { + "auth-tag": {"type": "string"}, + "bakery-version": {"type": "integer"}, + "cli-args": {"type": "string"}, + "client-version": {"type": "string"}, + "credentials": {"type": "string"}, + "macaroons": { + "items": { + "items": {"$ref": "#/definitions/Macaroon"}, + "type": "array", + }, + "type": "array", + }, + "nonce": {"type": "string"}, + "token": {"type": "string"}, + "user-data": {"type": "string"}, + }, + "required": [ + "auth-tag", + "credentials", + "nonce", + "macaroons", + "user-data", + ], + "type": "object", + }, + "LoginResult": { + "additionalProperties": False, + "properties": { + "bakery-discharge-required": {"$ref": "#/definitions/Macaroon"}, + "controller-tag": {"type": "string"}, + "discharge-required": {"$ref": "#/definitions/Macaroon"}, + "discharge-required-error": {"type": "string"}, + "facades": { + "items": {"$ref": "#/definitions/FacadeVersions"}, + "type": "array", + }, + "model-tag": {"type": "string"}, + "public-dns-name": {"type": "string"}, + "server-version": {"type": "string"}, + "servers": { + "items": { + "items": {"$ref": "#/definitions/HostPort"}, + "type": "array", + }, + "type": "array", + }, + "user-info": {"$ref": "#/definitions/AuthUserInfo"}, + }, + "type": "object", + }, + "Macaroon": {"additionalProperties": False, "type": "object"}, + "RedirectInfoResult": { + "additionalProperties": False, + "properties": { + "ca-cert": {"type": "string"}, + "servers": { + "items": { + "items": {"$ref": "#/definitions/HostPort"}, + "type": "array", + }, + "type": "array", + }, + }, + "required": ["servers", "ca-cert"], + "type": "object", + }, + }, + "properties": { + "Login": { + "description": "Login logs in with the provided " + "credentials. All subsequent " + "requests on the\n" + "connection will act as the " + "authenticated user.", + "properties": { + "Params": {"$ref": "#/definitions/LoginRequest"}, + "Result": {"$ref": "#/definitions/LoginResult"}, + }, + "type": "object", + }, + "RedirectInfo": { + "description": "RedirectInfo returns " + "redirected host information " + "for the model.\n" + "In Juju it always returns an " + "error because the Juju " + "controller\n" + "does not multiplex " + "controllers.", + "properties": {"Result": {"$ref": "#/definitions/RedirectInfoResult"}}, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(LoginResult) - async def Login(self, auth_tag=None, bakery_version=None, cli_args=None, client_version=None, credentials=None, macaroons=None, nonce=None, token=None, user_data=None): - ''' + async def Login( + self, + auth_tag=None, + bakery_version=None, + cli_args=None, + client_version=None, + credentials=None, + macaroons=None, + nonce=None, + token=None, + user_data=None, + ): + """ Login logs in with the provided credentials. All subsequent requests on the connection will act as the authenticated user. @@ -133,553 +195,646 @@ async def Login(self, auth_tag=None, bakery_version=None, cli_args=None, client_ token : str user_data : str Returns -> LoginResult - ''' + """ if auth_tag is not None and not isinstance(auth_tag, (bytes, str)): - raise Exception("Expected auth_tag to be a str, received: {}".format(type(auth_tag))) + raise Exception( + "Expected auth_tag to be a str, received: {}".format(type(auth_tag)) + ) if bakery_version is not None and not isinstance(bakery_version, int): - raise Exception("Expected bakery_version to be a int, received: {}".format(type(bakery_version))) + raise Exception( + "Expected bakery_version to be a int, received: {}".format( + type(bakery_version) + ) + ) if cli_args is not None and not isinstance(cli_args, (bytes, str)): - raise Exception("Expected cli_args to be a str, received: {}".format(type(cli_args))) + raise Exception( + "Expected cli_args to be a str, received: {}".format(type(cli_args)) + ) if client_version is not None and not isinstance(client_version, (bytes, str)): - raise Exception("Expected client_version to be a str, received: {}".format(type(client_version))) + raise Exception( + "Expected client_version to be a str, received: {}".format( + type(client_version) + ) + ) if credentials is not None and not isinstance(credentials, (bytes, str)): - raise Exception("Expected credentials to be a str, received: {}".format(type(credentials))) + raise Exception( + "Expected credentials to be a str, received: {}".format( + type(credentials) + ) + ) if macaroons is not None and not isinstance(macaroons, (bytes, str, list)): - raise Exception("Expected macaroons to be a Sequence, received: {}".format(type(macaroons))) + raise Exception( + "Expected macaroons to be a Sequence, received: {}".format( + type(macaroons) + ) + ) if nonce is not None and not isinstance(nonce, (bytes, str)): - raise Exception("Expected nonce to be a str, received: {}".format(type(nonce))) + raise Exception( + "Expected nonce to be a str, received: {}".format(type(nonce)) + ) if token is not None and not isinstance(token, (bytes, str)): - raise Exception("Expected token to be a str, received: {}".format(type(token))) + raise Exception( + "Expected token to be a str, received: {}".format(type(token)) + ) if user_data is not None and not isinstance(user_data, (bytes, str)): - raise Exception("Expected user_data to be a str, received: {}".format(type(user_data))) + raise Exception( + "Expected user_data to be a str, received: {}".format(type(user_data)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Admin', - request='Login', - version=3, - params=_params) - _params['auth-tag'] = auth_tag - _params['bakery-version'] = bakery_version - _params['cli-args'] = cli_args - _params['client-version'] = client_version - _params['credentials'] = credentials - _params['macaroons'] = macaroons - _params['nonce'] = nonce - _params['token'] = token - _params['user-data'] = user_data + msg = dict(type="Admin", request="Login", version=3, params=_params) + _params["auth-tag"] = auth_tag + _params["bakery-version"] = bakery_version + _params["cli-args"] = cli_args + _params["client-version"] = client_version + _params["credentials"] = credentials + _params["macaroons"] = macaroons + _params["nonce"] = nonce + _params["token"] = token + _params["user-data"] = user_data reply = await self.rpc(msg) return reply - - @ReturnMapping(RedirectInfoResult) async def RedirectInfo(self): - ''' + """ RedirectInfo returns redirected host information for the model. In Juju it always returns an error because the Juju controller does not multiplex controllers. Returns -> RedirectInfoResult - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Admin', - request='RedirectInfo', - version=3, - params=_params) + msg = dict(type="Admin", request="RedirectInfo", version=3, params=_params) reply = await self.rpc(msg) return reply - class AllWatcherFacade(Type): - name = 'AllWatcher' + name = "AllWatcher" version = 3 - schema = {'definitions': {'AllWatcherNextResults': {'additionalProperties': False, - 'properties': {'deltas': {'items': {'$ref': '#/definitions/Delta'}, - 'type': 'array'}}, - 'required': ['deltas'], - 'type': 'object'}, - 'Delta': {'additionalProperties': False, - 'properties': {'entity': {'additionalProperties': True, - 'type': 'object'}, - 'removed': {'type': 'boolean'}}, - 'required': ['removed', 'entity'], - 'type': 'object'}}, - 'properties': {'Next': {'description': 'Next will return the current state of ' - 'everything on the first call\n' - 'and subsequent calls will', - 'properties': {'Result': {'$ref': '#/definitions/AllWatcherNextResults'}}, - 'type': 'object'}, - 'Stop': {'description': 'Stop stops the watcher.', - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "AllWatcherNextResults": { + "additionalProperties": False, + "properties": { + "deltas": { + "items": {"$ref": "#/definitions/Delta"}, + "type": "array", + } + }, + "required": ["deltas"], + "type": "object", + }, + "Delta": { + "additionalProperties": False, + "properties": { + "entity": {"additionalProperties": True, "type": "object"}, + "removed": {"type": "boolean"}, + }, + "required": ["removed", "entity"], + "type": "object", + }, + }, + "properties": { + "Next": { + "description": "Next will return the current state of " + "everything on the first call\n" + "and subsequent calls will", + "properties": { + "Result": {"$ref": "#/definitions/AllWatcherNextResults"} + }, + "type": "object", + }, + "Stop": {"description": "Stop stops the watcher.", "type": "object"}, + }, + "type": "object", + } @ReturnMapping(AllWatcherNextResults) async def Next(self): - ''' + """ Next will return the current state of everything on the first call and subsequent calls will Returns -> AllWatcherNextResults - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='AllWatcher', - request='Next', - version=3, - params=_params) + msg = dict(type="AllWatcher", request="Next", version=3, params=_params) reply = await self.rpc(msg) return reply - - @ReturnMapping(None) async def Stop(self): - ''' + """ Stop stops the watcher. Returns -> None - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='AllWatcher', - request='Stop', - version=3, - params=_params) + msg = dict(type="AllWatcher", request="Stop", version=3, params=_params) reply = await self.rpc(msg) return reply - - async def rpc(self, msg): - ''' + """ Patch rpc method to add Id. - ''' - if not hasattr(self, 'Id'): + """ + if not hasattr(self, "Id"): raise RuntimeError('Missing "Id" field') - msg['Id'] = id + msg["Id"] = id from .facade import TypeEncoder + reply = await self.connection.rpc(msg, encoder=TypeEncoder) return reply - class BackupsFacade(Type): - name = 'Backups' + name = "Backups" version = 3 - schema = {'definitions': {'BackupsCreateArgs': {'additionalProperties': False, - 'properties': {'no-download': {'type': 'boolean'}, - 'notes': {'type': 'string'}}, - 'required': ['notes', 'no-download'], - 'type': 'object'}, - 'BackupsMetadataResult': {'additionalProperties': False, - 'properties': {'base': {'type': 'string'}, - 'checksum': {'type': 'string'}, - 'checksum-format': {'type': 'string'}, - 'controller-machine-id': {'type': 'string'}, - 'controller-machine-inst-id': {'type': 'string'}, - 'controller-uuid': {'type': 'string'}, - 'filename': {'type': 'string'}, - 'finished': {'format': 'date-time', - 'type': 'string'}, - 'format-version': {'type': 'integer'}, - 'ha-nodes': {'type': 'integer'}, - 'hostname': {'type': 'string'}, - 'id': {'type': 'string'}, - 'machine': {'type': 'string'}, - 'model': {'type': 'string'}, - 'notes': {'type': 'string'}, - 'size': {'type': 'integer'}, - 'started': {'format': 'date-time', - 'type': 'string'}, - 'stored': {'format': 'date-time', - 'type': 'string'}, - 'version': {'$ref': '#/definitions/Number'}}, - 'required': ['id', - 'checksum', - 'checksum-format', - 'size', - 'stored', - 'started', - 'finished', - 'notes', - 'model', - 'machine', - 'hostname', - 'version', - 'base', - 'filename', - 'format-version', - 'controller-uuid', - 'controller-machine-id', - 'controller-machine-inst-id', - 'ha-nodes'], - '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'}}, - 'properties': {'Create': {'description': 'Create is the API method that ' - 'requests juju to create a new ' - 'backup\n' - 'of its state.', - 'properties': {'Params': {'$ref': '#/definitions/BackupsCreateArgs'}, - 'Result': {'$ref': '#/definitions/BackupsMetadataResult'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "BackupsCreateArgs": { + "additionalProperties": False, + "properties": { + "no-download": {"type": "boolean"}, + "notes": {"type": "string"}, + }, + "required": ["notes", "no-download"], + "type": "object", + }, + "BackupsMetadataResult": { + "additionalProperties": False, + "properties": { + "base": {"type": "string"}, + "checksum": {"type": "string"}, + "checksum-format": {"type": "string"}, + "controller-machine-id": {"type": "string"}, + "controller-machine-inst-id": {"type": "string"}, + "controller-uuid": {"type": "string"}, + "filename": {"type": "string"}, + "finished": {"format": "date-time", "type": "string"}, + "format-version": {"type": "integer"}, + "ha-nodes": {"type": "integer"}, + "hostname": {"type": "string"}, + "id": {"type": "string"}, + "machine": {"type": "string"}, + "model": {"type": "string"}, + "notes": {"type": "string"}, + "size": {"type": "integer"}, + "started": {"format": "date-time", "type": "string"}, + "stored": {"format": "date-time", "type": "string"}, + "version": {"$ref": "#/definitions/Number"}, + }, + "required": [ + "id", + "checksum", + "checksum-format", + "size", + "stored", + "started", + "finished", + "notes", + "model", + "machine", + "hostname", + "version", + "base", + "filename", + "format-version", + "controller-uuid", + "controller-machine-id", + "controller-machine-inst-id", + "ha-nodes", + ], + "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", + }, + }, + "properties": { + "Create": { + "description": "Create is the API method that " + "requests juju to create a new " + "backup\n" + "of its state.", + "properties": { + "Params": {"$ref": "#/definitions/BackupsCreateArgs"}, + "Result": {"$ref": "#/definitions/BackupsMetadataResult"}, + }, + "type": "object", + } + }, + "type": "object", + } @ReturnMapping(BackupsMetadataResult) async def Create(self, no_download=None, notes=None): - ''' + """ Create is the API method that requests juju to create a new backup of its state. no_download : bool notes : str Returns -> BackupsMetadataResult - ''' + """ if no_download is not None and not isinstance(no_download, bool): - raise Exception("Expected no_download to be a bool, received: {}".format(type(no_download))) + raise Exception( + "Expected no_download to be a bool, received: {}".format( + type(no_download) + ) + ) if notes is not None and not isinstance(notes, (bytes, str)): - raise Exception("Expected notes to be a str, received: {}".format(type(notes))) + raise Exception( + "Expected notes to be a str, received: {}".format(type(notes)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Backups', - request='Create', - version=3, - params=_params) - _params['no-download'] = no_download - _params['notes'] = notes + msg = dict(type="Backups", request="Create", version=3, params=_params) + _params["no-download"] = no_download + _params["notes"] = notes reply = await self.rpc(msg) return reply - class ModelConfigFacade(Type): - name = 'ModelConfig' + name = "ModelConfig" version = 3 - schema = {'definitions': {'ConfigValue': {'additionalProperties': False, - 'properties': {'source': {'type': 'string'}, - 'value': {'additionalProperties': True, - 'type': 'object'}}, - 'required': ['value', 'source'], - 'type': 'object'}, - 'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - 'type': 'object'}, - 'GetConstraintsResults': {'additionalProperties': False, - 'properties': {'constraints': {'$ref': '#/definitions/Value'}}, - 'required': ['constraints'], - 'type': 'object'}, - 'ModelConfigResults': {'additionalProperties': False, - 'properties': {'config': {'patternProperties': {'.*': {'$ref': '#/definitions/ConfigValue'}}, - 'type': 'object'}}, - 'required': ['config'], - 'type': 'object'}, - 'ModelSLA': {'additionalProperties': False, - 'properties': {'ModelSLAInfo': {'$ref': '#/definitions/ModelSLAInfo'}, - 'creds': {'items': {'type': 'integer'}, - 'type': 'array'}, - 'level': {'type': 'string'}, - 'owner': {'type': 'string'}}, - 'required': ['level', - 'owner', - 'ModelSLAInfo', - 'creds'], - 'type': 'object'}, - 'ModelSLAInfo': {'additionalProperties': False, - 'properties': {'level': {'type': 'string'}, - 'owner': {'type': 'string'}}, - 'required': ['level', 'owner'], - 'type': 'object'}, - 'ModelSequencesResult': {'additionalProperties': False, - 'properties': {'sequences': {'patternProperties': {'.*': {'type': 'integer'}}, - 'type': 'object'}}, - 'required': ['sequences'], - 'type': 'object'}, - 'ModelSet': {'additionalProperties': False, - 'properties': {'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}}, - 'required': ['config'], - 'type': 'object'}, - 'ModelUnset': {'additionalProperties': False, - 'properties': {'keys': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['keys'], - 'type': 'object'}, - 'SetConstraints': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'constraints': {'$ref': '#/definitions/Value'}}, - 'required': ['application', 'constraints'], - 'type': 'object'}, - 'StringResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'type': 'string'}}, - 'required': ['result'], - 'type': 'object'}, - 'Value': {'additionalProperties': False, - 'properties': {'allocate-public-ip': {'type': 'boolean'}, - 'arch': {'type': 'string'}, - 'container': {'type': 'string'}, - 'cores': {'type': 'integer'}, - 'cpu-power': {'type': 'integer'}, - 'image-id': {'type': 'string'}, - 'instance-role': {'type': 'string'}, - 'instance-type': {'type': 'string'}, - 'mem': {'type': 'integer'}, - 'root-disk': {'type': 'integer'}, - 'root-disk-source': {'type': 'string'}, - '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': {'GetModelConstraints': {'description': 'GetModelConstraints ' - 'returns the ' - 'constraints for the ' - 'model.', - 'properties': {'Result': {'$ref': '#/definitions/GetConstraintsResults'}}, - 'type': 'object'}, - 'ModelGet': {'description': 'ModelGet implements the ' - 'server-side part of the\n' - 'model-config CLI command.', - 'properties': {'Result': {'$ref': '#/definitions/ModelConfigResults'}}, - 'type': 'object'}, - 'ModelSet': {'description': 'ModelSet implements the ' - 'server-side part of the\n' - 'set-model-config CLI command.', - 'properties': {'Params': {'$ref': '#/definitions/ModelSet'}}, - 'type': 'object'}, - 'ModelUnset': {'description': 'ModelUnset implements the ' - 'server-side part of the\n' - 'set-model-config CLI command.', - 'properties': {'Params': {'$ref': '#/definitions/ModelUnset'}}, - 'type': 'object'}, - 'SLALevel': {'description': 'SLALevel returns the current sla ' - 'level for the model.', - 'properties': {'Result': {'$ref': '#/definitions/StringResult'}}, - 'type': 'object'}, - 'Sequences': {'description': "Sequences returns the model's " - 'sequence names and next values.', - 'properties': {'Result': {'$ref': '#/definitions/ModelSequencesResult'}}, - 'type': 'object'}, - 'SetModelConstraints': {'description': 'SetModelConstraints ' - 'sets the constraints ' - 'for the model.', - 'properties': {'Params': {'$ref': '#/definitions/SetConstraints'}}, - 'type': 'object'}, - 'SetSLALevel': {'description': 'SetSLALevel sets the sla level ' - 'on the model.', - 'properties': {'Params': {'$ref': '#/definitions/ModelSLA'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "ConfigValue": { + "additionalProperties": False, + "properties": { + "source": {"type": "string"}, + "value": {"additionalProperties": True, "type": "object"}, + }, + "required": ["value", "source"], + "type": "object", + }, + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "type": "object", + }, + "GetConstraintsResults": { + "additionalProperties": False, + "properties": {"constraints": {"$ref": "#/definitions/Value"}}, + "required": ["constraints"], + "type": "object", + }, + "ModelConfigResults": { + "additionalProperties": False, + "properties": { + "config": { + "patternProperties": { + ".*": {"$ref": "#/definitions/ConfigValue"} + }, + "type": "object", + } + }, + "required": ["config"], + "type": "object", + }, + "ModelSLA": { + "additionalProperties": False, + "properties": { + "ModelSLAInfo": {"$ref": "#/definitions/ModelSLAInfo"}, + "creds": {"items": {"type": "integer"}, "type": "array"}, + "level": {"type": "string"}, + "owner": {"type": "string"}, + }, + "required": ["level", "owner", "ModelSLAInfo", "creds"], + "type": "object", + }, + "ModelSLAInfo": { + "additionalProperties": False, + "properties": { + "level": {"type": "string"}, + "owner": {"type": "string"}, + }, + "required": ["level", "owner"], + "type": "object", + }, + "ModelSequencesResult": { + "additionalProperties": False, + "properties": { + "sequences": { + "patternProperties": {".*": {"type": "integer"}}, + "type": "object", + } + }, + "required": ["sequences"], + "type": "object", + }, + "ModelSet": { + "additionalProperties": False, + "properties": { + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + } + }, + "required": ["config"], + "type": "object", + }, + "ModelUnset": { + "additionalProperties": False, + "properties": {"keys": {"items": {"type": "string"}, "type": "array"}}, + "required": ["keys"], + "type": "object", + }, + "SetConstraints": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "constraints": {"$ref": "#/definitions/Value"}, + }, + "required": ["application", "constraints"], + "type": "object", + }, + "StringResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"type": "string"}, + }, + "required": ["result"], + "type": "object", + }, + "Value": { + "additionalProperties": False, + "properties": { + "allocate-public-ip": {"type": "boolean"}, + "arch": {"type": "string"}, + "container": {"type": "string"}, + "cores": {"type": "integer"}, + "cpu-power": {"type": "integer"}, + "image-id": {"type": "string"}, + "instance-role": {"type": "string"}, + "instance-type": {"type": "string"}, + "mem": {"type": "integer"}, + "root-disk": {"type": "integer"}, + "root-disk-source": {"type": "string"}, + "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": { + "GetModelConstraints": { + "description": "GetModelConstraints " + "returns the " + "constraints for the " + "model.", + "properties": { + "Result": {"$ref": "#/definitions/GetConstraintsResults"} + }, + "type": "object", + }, + "ModelGet": { + "description": "ModelGet implements the " + "server-side part of the\n" + "model-config CLI command.", + "properties": {"Result": {"$ref": "#/definitions/ModelConfigResults"}}, + "type": "object", + }, + "ModelSet": { + "description": "ModelSet implements the " + "server-side part of the\n" + "set-model-config CLI command.", + "properties": {"Params": {"$ref": "#/definitions/ModelSet"}}, + "type": "object", + }, + "ModelUnset": { + "description": "ModelUnset implements the " + "server-side part of the\n" + "set-model-config CLI command.", + "properties": {"Params": {"$ref": "#/definitions/ModelUnset"}}, + "type": "object", + }, + "SLALevel": { + "description": "SLALevel returns the current sla level for the model.", + "properties": {"Result": {"$ref": "#/definitions/StringResult"}}, + "type": "object", + }, + "Sequences": { + "description": "Sequences returns the model's " + "sequence names and next values.", + "properties": { + "Result": {"$ref": "#/definitions/ModelSequencesResult"} + }, + "type": "object", + }, + "SetModelConstraints": { + "description": "SetModelConstraints " + "sets the constraints " + "for the model.", + "properties": {"Params": {"$ref": "#/definitions/SetConstraints"}}, + "type": "object", + }, + "SetSLALevel": { + "description": "SetSLALevel sets the sla level on the model.", + "properties": {"Params": {"$ref": "#/definitions/ModelSLA"}}, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(GetConstraintsResults) async def GetModelConstraints(self): - ''' + """ GetModelConstraints returns the constraints for the model. Returns -> GetConstraintsResults - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='ModelConfig', - request='GetModelConstraints', - version=3, - params=_params) + msg = dict( + type="ModelConfig", request="GetModelConstraints", version=3, params=_params + ) reply = await self.rpc(msg) return reply - - @ReturnMapping(ModelConfigResults) async def ModelGet(self): - ''' + """ ModelGet implements the server-side part of the model-config CLI command. Returns -> ModelConfigResults - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='ModelConfig', - request='ModelGet', - version=3, - params=_params) + msg = dict(type="ModelConfig", request="ModelGet", version=3, params=_params) reply = await self.rpc(msg) return reply - - @ReturnMapping(None) async def ModelSet(self, config=None): - ''' + """ ModelSet implements the server-side part of the set-model-config CLI command. config : typing.Mapping[str, typing.Any] Returns -> None - ''' + """ if config is not None and not isinstance(config, dict): - raise Exception("Expected config to be a Mapping, received: {}".format(type(config))) + raise Exception( + "Expected config to be a Mapping, received: {}".format(type(config)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelConfig', - request='ModelSet', - version=3, - params=_params) - _params['config'] = config + msg = dict(type="ModelConfig", request="ModelSet", version=3, params=_params) + _params["config"] = config reply = await self.rpc(msg) return reply - - @ReturnMapping(None) async def ModelUnset(self, keys=None): - ''' + """ ModelUnset implements the server-side part of the set-model-config CLI command. keys : typing.Sequence[str] Returns -> None - ''' + """ if keys is not None and not isinstance(keys, (bytes, str, list)): - raise Exception("Expected keys to be a Sequence, received: {}".format(type(keys))) + raise Exception( + "Expected keys to be a Sequence, received: {}".format(type(keys)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelConfig', - request='ModelUnset', - version=3, - params=_params) - _params['keys'] = keys + msg = dict(type="ModelConfig", request="ModelUnset", version=3, params=_params) + _params["keys"] = keys reply = await self.rpc(msg) return reply - - @ReturnMapping(StringResult) async def SLALevel(self): - ''' + """ SLALevel returns the current sla level for the model. Returns -> StringResult - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='ModelConfig', - request='SLALevel', - version=3, - params=_params) + msg = dict(type="ModelConfig", request="SLALevel", version=3, params=_params) reply = await self.rpc(msg) return reply - - @ReturnMapping(ModelSequencesResult) async def Sequences(self): - ''' + """ Sequences returns the model's sequence names and next values. Returns -> ModelSequencesResult - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='ModelConfig', - request='Sequences', - version=3, - params=_params) + msg = dict(type="ModelConfig", request="Sequences", version=3, params=_params) reply = await self.rpc(msg) return reply - - @ReturnMapping(None) async def SetModelConstraints(self, application=None, constraints=None): - ''' + """ SetModelConstraints sets the constraints for the model. application : str constraints : Value Returns -> None - ''' + """ if application is not None and not isinstance(application, (bytes, str)): - raise Exception("Expected application to be a str, received: {}".format(type(application))) + raise Exception( + "Expected application to be a str, received: {}".format( + type(application) + ) + ) if constraints is not None and not isinstance(constraints, (dict, Value)): - raise Exception("Expected constraints to be a Value, received: {}".format(type(constraints))) + raise Exception( + "Expected constraints to be a Value, received: {}".format( + type(constraints) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelConfig', - request='SetModelConstraints', - version=3, - params=_params) - _params['application'] = application - _params['constraints'] = constraints + msg = dict( + type="ModelConfig", request="SetModelConstraints", version=3, params=_params + ) + _params["application"] = application + _params["constraints"] = constraints reply = await self.rpc(msg) return reply - - @ReturnMapping(None) async def SetSLALevel(self, modelslainfo=None, creds=None, level=None, owner=None): - ''' + """ SetSLALevel sets the sla level on the model. modelslainfo : ModelSLAInfo @@ -687,206 +842,302 @@ async def SetSLALevel(self, modelslainfo=None, creds=None, level=None, owner=Non level : str owner : str Returns -> None - ''' - if modelslainfo is not None and not isinstance(modelslainfo, (dict, ModelSLAInfo)): - raise Exception("Expected modelslainfo to be a ModelSLAInfo, received: {}".format(type(modelslainfo))) + """ + if modelslainfo is not None and not isinstance( + modelslainfo, (dict, ModelSLAInfo) + ): + raise Exception( + "Expected modelslainfo to be a ModelSLAInfo, received: {}".format( + type(modelslainfo) + ) + ) if creds is not None and not isinstance(creds, (bytes, str, list)): - raise Exception("Expected creds to be a Sequence, received: {}".format(type(creds))) + raise Exception( + "Expected creds to be a Sequence, received: {}".format(type(creds)) + ) if level is not None and not isinstance(level, (bytes, str)): - raise Exception("Expected level to be a str, received: {}".format(type(level))) + raise Exception( + "Expected level to be a str, received: {}".format(type(level)) + ) if owner is not None and not isinstance(owner, (bytes, str)): - raise Exception("Expected owner to be a str, received: {}".format(type(owner))) + raise Exception( + "Expected owner to be a str, received: {}".format(type(owner)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelConfig', - request='SetSLALevel', - version=3, - params=_params) - _params['ModelSLAInfo'] = modelslainfo - _params['creds'] = creds - _params['level'] = level - _params['owner'] = owner + msg = dict(type="ModelConfig", request="SetSLALevel", version=3, params=_params) + _params["ModelSLAInfo"] = modelslainfo + _params["creds"] = creds + _params["level"] = level + _params["owner"] = owner reply = await self.rpc(msg) return reply - class ResourcesFacade(Type): - name = 'Resources' + name = "Resources" version = 3 - schema = {'definitions': {'AddPendingResourcesArgsV2': {'additionalProperties': False, - 'properties': {'Entity': {'$ref': '#/definitions/Entity'}, - 'charm-origin': {'$ref': '#/definitions/CharmOrigin'}, - 'macaroon': {'$ref': '#/definitions/Macaroon'}, - 'resources': {'items': {'$ref': '#/definitions/CharmResource'}, - 'type': 'array'}, - 'tag': {'type': 'string'}, - 'url': {'type': 'string'}}, - 'required': ['tag', - 'Entity', - 'url', - 'charm-origin', - 'macaroon', - 'resources'], - 'type': 'object'}, - 'AddPendingResourcesResult': {'additionalProperties': False, - 'properties': {'ErrorResult': {'$ref': '#/definitions/ErrorResult'}, - 'error': {'$ref': '#/definitions/Error'}, - 'pending-ids': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['ErrorResult', - 'pending-ids'], - 'type': 'object'}, - 'Base': {'additionalProperties': False, - 'properties': {'channel': {'type': 'string'}, - 'name': {'type': 'string'}}, - 'required': ['name', 'channel'], - 'type': 'object'}, - 'CharmOrigin': {'additionalProperties': False, - 'properties': {'architecture': {'type': 'string'}, - 'base': {'$ref': '#/definitions/Base'}, - 'branch': {'type': 'string'}, - 'hash': {'type': 'string'}, - 'id': {'type': 'string'}, - 'instance-key': {'type': 'string'}, - 'revision': {'type': 'integer'}, - 'risk': {'type': 'string'}, - 'source': {'type': 'string'}, - 'track': {'type': 'string'}, - 'type': {'type': 'string'}}, - 'required': ['source', 'type', 'id'], - 'type': 'object'}, - 'CharmResource': {'additionalProperties': False, - 'properties': {'description': {'type': 'string'}, - 'fingerprint': {'items': {'type': 'integer'}, - 'type': 'array'}, - 'name': {'type': 'string'}, - 'origin': {'type': 'string'}, - 'path': {'type': 'string'}, - 'revision': {'type': 'integer'}, - 'size': {'type': 'integer'}, - 'type': {'type': 'string'}}, - 'required': ['name', - 'type', - 'path', - 'origin', - 'revision', - 'fingerprint', - 'size'], - 'type': 'object'}, - 'Entity': {'additionalProperties': False, - 'properties': {'tag': {'type': 'string'}}, - 'required': ['tag'], - 'type': 'object'}, - 'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - 'type': 'object'}, - 'ErrorResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}}, - 'type': 'object'}, - 'ListResourcesArgs': {'additionalProperties': False, - 'properties': {'entities': {'items': {'$ref': '#/definitions/Entity'}, - 'type': 'array'}}, - 'required': ['entities'], - 'type': 'object'}, - 'Macaroon': {'additionalProperties': False, 'type': 'object'}, - 'Resource': {'additionalProperties': False, - 'properties': {'CharmResource': {'$ref': '#/definitions/CharmResource'}, - 'application': {'type': 'string'}, - 'description': {'type': 'string'}, - 'fingerprint': {'items': {'type': 'integer'}, - 'type': 'array'}, - 'id': {'type': 'string'}, - 'name': {'type': 'string'}, - 'origin': {'type': 'string'}, - 'path': {'type': 'string'}, - 'pending-id': {'type': 'string'}, - 'revision': {'type': 'integer'}, - 'size': {'type': 'integer'}, - 'timestamp': {'format': 'date-time', - 'type': 'string'}, - 'type': {'type': 'string'}, - 'username': {'type': 'string'}}, - 'required': ['name', - 'type', - 'path', - 'origin', - 'revision', - 'fingerprint', - 'size', - 'CharmResource', - 'id', - 'pending-id', - 'application', - 'username', - 'timestamp'], - 'type': 'object'}, - 'ResourcesResult': {'additionalProperties': False, - 'properties': {'ErrorResult': {'$ref': '#/definitions/ErrorResult'}, - 'charm-store-resources': {'items': {'$ref': '#/definitions/CharmResource'}, - 'type': 'array'}, - 'error': {'$ref': '#/definitions/Error'}, - 'resources': {'items': {'$ref': '#/definitions/Resource'}, - 'type': 'array'}, - 'unit-resources': {'items': {'$ref': '#/definitions/UnitResources'}, - 'type': 'array'}}, - 'required': ['ErrorResult', - 'resources', - 'charm-store-resources', - 'unit-resources'], - 'type': 'object'}, - 'ResourcesResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ResourcesResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'UnitResources': {'additionalProperties': False, - 'properties': {'Entity': {'$ref': '#/definitions/Entity'}, - 'download-progress': {'patternProperties': {'.*': {'type': 'integer'}}, - 'type': 'object'}, - 'resources': {'items': {'$ref': '#/definitions/Resource'}, - 'type': 'array'}, - 'tag': {'type': 'string'}}, - 'required': ['tag', - 'Entity', - 'resources', - 'download-progress'], - 'type': 'object'}}, - 'properties': {'AddPendingResources': {'description': 'AddPendingResources ' - 'adds the provided ' - 'resources (info) to ' - 'the Juju\n' - 'model in a pending ' - 'state, meaning they ' - 'are not available ' - 'until\n' - 'resolved. Handles ' - 'CharmHub and Local ' - 'charms.', - 'properties': {'Params': {'$ref': '#/definitions/AddPendingResourcesArgsV2'}, - 'Result': {'$ref': '#/definitions/AddPendingResourcesResult'}}, - 'type': 'object'}, - 'ListResources': {'description': 'ListResources returns the ' - 'list of resources for the ' - 'given application.', - 'properties': {'Params': {'$ref': '#/definitions/ListResourcesArgs'}, - 'Result': {'$ref': '#/definitions/ResourcesResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "AddPendingResourcesArgsV2": { + "additionalProperties": False, + "properties": { + "Entity": {"$ref": "#/definitions/Entity"}, + "charm-origin": {"$ref": "#/definitions/CharmOrigin"}, + "macaroon": {"$ref": "#/definitions/Macaroon"}, + "resources": { + "items": {"$ref": "#/definitions/CharmResource"}, + "type": "array", + }, + "tag": {"type": "string"}, + "url": {"type": "string"}, + }, + "required": [ + "tag", + "Entity", + "url", + "charm-origin", + "macaroon", + "resources", + ], + "type": "object", + }, + "AddPendingResourcesResult": { + "additionalProperties": False, + "properties": { + "ErrorResult": {"$ref": "#/definitions/ErrorResult"}, + "error": {"$ref": "#/definitions/Error"}, + "pending-ids": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["ErrorResult", "pending-ids"], + "type": "object", + }, + "Base": { + "additionalProperties": False, + "properties": { + "channel": {"type": "string"}, + "name": {"type": "string"}, + }, + "required": ["name", "channel"], + "type": "object", + }, + "CharmOrigin": { + "additionalProperties": False, + "properties": { + "architecture": {"type": "string"}, + "base": {"$ref": "#/definitions/Base"}, + "branch": {"type": "string"}, + "hash": {"type": "string"}, + "id": {"type": "string"}, + "instance-key": {"type": "string"}, + "revision": {"type": "integer"}, + "risk": {"type": "string"}, + "source": {"type": "string"}, + "track": {"type": "string"}, + "type": {"type": "string"}, + }, + "required": ["source", "type", "id"], + "type": "object", + }, + "CharmResource": { + "additionalProperties": False, + "properties": { + "description": {"type": "string"}, + "fingerprint": {"items": {"type": "integer"}, "type": "array"}, + "name": {"type": "string"}, + "origin": {"type": "string"}, + "path": {"type": "string"}, + "revision": {"type": "integer"}, + "size": {"type": "integer"}, + "type": {"type": "string"}, + }, + "required": [ + "name", + "type", + "path", + "origin", + "revision", + "fingerprint", + "size", + ], + "type": "object", + }, + "Entity": { + "additionalProperties": False, + "properties": {"tag": {"type": "string"}}, + "required": ["tag"], + "type": "object", + }, + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "type": "object", + }, + "ErrorResult": { + "additionalProperties": False, + "properties": {"error": {"$ref": "#/definitions/Error"}}, + "type": "object", + }, + "ListResourcesArgs": { + "additionalProperties": False, + "properties": { + "entities": { + "items": {"$ref": "#/definitions/Entity"}, + "type": "array", + } + }, + "required": ["entities"], + "type": "object", + }, + "Macaroon": {"additionalProperties": False, "type": "object"}, + "Resource": { + "additionalProperties": False, + "properties": { + "CharmResource": {"$ref": "#/definitions/CharmResource"}, + "application": {"type": "string"}, + "description": {"type": "string"}, + "fingerprint": {"items": {"type": "integer"}, "type": "array"}, + "id": {"type": "string"}, + "name": {"type": "string"}, + "origin": {"type": "string"}, + "path": {"type": "string"}, + "pending-id": {"type": "string"}, + "revision": {"type": "integer"}, + "size": {"type": "integer"}, + "timestamp": {"format": "date-time", "type": "string"}, + "type": {"type": "string"}, + "username": {"type": "string"}, + }, + "required": [ + "name", + "type", + "path", + "origin", + "revision", + "fingerprint", + "size", + "CharmResource", + "id", + "pending-id", + "application", + "username", + "timestamp", + ], + "type": "object", + }, + "ResourcesResult": { + "additionalProperties": False, + "properties": { + "ErrorResult": {"$ref": "#/definitions/ErrorResult"}, + "charm-store-resources": { + "items": {"$ref": "#/definitions/CharmResource"}, + "type": "array", + }, + "error": {"$ref": "#/definitions/Error"}, + "resources": { + "items": {"$ref": "#/definitions/Resource"}, + "type": "array", + }, + "unit-resources": { + "items": {"$ref": "#/definitions/UnitResources"}, + "type": "array", + }, + }, + "required": [ + "ErrorResult", + "resources", + "charm-store-resources", + "unit-resources", + ], + "type": "object", + }, + "ResourcesResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ResourcesResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "UnitResources": { + "additionalProperties": False, + "properties": { + "Entity": {"$ref": "#/definitions/Entity"}, + "download-progress": { + "patternProperties": {".*": {"type": "integer"}}, + "type": "object", + }, + "resources": { + "items": {"$ref": "#/definitions/Resource"}, + "type": "array", + }, + "tag": {"type": "string"}, + }, + "required": ["tag", "Entity", "resources", "download-progress"], + "type": "object", + }, + }, + "properties": { + "AddPendingResources": { + "description": "AddPendingResources " + "adds the provided " + "resources (info) to " + "the Juju\n" + "model in a pending " + "state, meaning they " + "are not available " + "until\n" + "resolved. Handles " + "CharmHub and Local " + "charms.", + "properties": { + "Params": {"$ref": "#/definitions/AddPendingResourcesArgsV2"}, + "Result": {"$ref": "#/definitions/AddPendingResourcesResult"}, + }, + "type": "object", + }, + "ListResources": { + "description": "ListResources returns the " + "list of resources for the " + "given application.", + "properties": { + "Params": {"$ref": "#/definitions/ListResourcesArgs"}, + "Result": {"$ref": "#/definitions/ResourcesResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(AddPendingResourcesResult) - async def AddPendingResources(self, entity=None, charm_origin=None, macaroon=None, resources=None, tag=None, url=None): - ''' + async def AddPendingResources( + self, + entity=None, + charm_origin=None, + macaroon=None, + resources=None, + tag=None, + url=None, + ): + """ AddPendingResources adds the provided resources (info) to the Juju model in a pending state, meaning they are not available until resolved. Handles CharmHub and Local charms. @@ -898,18 +1149,34 @@ async def AddPendingResources(self, entity=None, charm_origin=None, macaroon=Non tag : str url : str Returns -> AddPendingResourcesResult - ''' + """ if entity is not None and not isinstance(entity, (dict, Entity)): - raise Exception("Expected entity to be a Entity, received: {}".format(type(entity))) - - if charm_origin is not None and not isinstance(charm_origin, (dict, CharmOrigin)): - raise Exception("Expected charm_origin to be a CharmOrigin, received: {}".format(type(charm_origin))) + raise Exception( + "Expected entity to be a Entity, received: {}".format(type(entity)) + ) + + if charm_origin is not None and not isinstance( + charm_origin, (dict, CharmOrigin) + ): + raise Exception( + "Expected charm_origin to be a CharmOrigin, received: {}".format( + type(charm_origin) + ) + ) if macaroon is not None and not isinstance(macaroon, (dict, Macaroon)): - raise Exception("Expected macaroon to be a Macaroon, received: {}".format(type(macaroon))) + raise Exception( + "Expected macaroon to be a Macaroon, received: {}".format( + type(macaroon) + ) + ) if resources is not None and not isinstance(resources, (bytes, str, list)): - raise Exception("Expected resources to be a Sequence, received: {}".format(type(resources))) + raise Exception( + "Expected resources to be a Sequence, received: {}".format( + type(resources) + ) + ) if tag is not None and not isinstance(tag, (bytes, str)): raise Exception("Expected tag to be a str, received: {}".format(type(tag))) @@ -919,329 +1186,444 @@ async def AddPendingResources(self, entity=None, charm_origin=None, macaroon=Non # map input types to rpc msg _params = dict() - msg = dict(type='Resources', - request='AddPendingResources', - version=3, - params=_params) - _params['Entity'] = entity - _params['charm-origin'] = charm_origin - _params['macaroon'] = macaroon - _params['resources'] = resources - _params['tag'] = tag - _params['url'] = url + msg = dict( + type="Resources", request="AddPendingResources", version=3, params=_params + ) + _params["Entity"] = entity + _params["charm-origin"] = charm_origin + _params["macaroon"] = macaroon + _params["resources"] = resources + _params["tag"] = tag + _params["url"] = url reply = await self.rpc(msg) return reply - - @ReturnMapping(ResourcesResults) async def ListResources(self, entities=None): - ''' + """ ListResources returns the list of resources for the given application. entities : typing.Sequence[~Entity] Returns -> ResourcesResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Resources', - request='ListResources', - version=3, - params=_params) - _params['entities'] = entities + msg = dict(type="Resources", request="ListResources", version=3, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - class UserManagerFacade(Type): - name = 'UserManager' + name = "UserManager" version = 3 - schema = {'definitions': {'AddUser': {'additionalProperties': False, - 'properties': {'display-name': {'type': 'string'}, - 'password': {'type': 'string'}, - 'username': {'type': 'string'}}, - 'required': ['username', 'display-name'], - 'type': 'object'}, - 'AddUserResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'secret-key': {'items': {'type': 'integer'}, - 'type': 'array'}, - 'tag': {'type': 'string'}}, - 'type': 'object'}, - 'AddUserResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/AddUserResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'AddUsers': {'additionalProperties': False, - 'properties': {'users': {'items': {'$ref': '#/definitions/AddUser'}, - 'type': 'array'}}, - 'required': ['users'], - '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': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - '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'}, - 'ModelUserInfo': {'additionalProperties': False, - 'properties': {'access': {'type': 'string'}, - 'display-name': {'type': 'string'}, - 'last-connection': {'format': 'date-time', - 'type': 'string'}, - 'model-tag': {'type': 'string'}, - 'user': {'type': 'string'}}, - 'required': ['model-tag', - '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'}, - 'UserInfo': {'additionalProperties': False, - 'properties': {'access': {'type': 'string'}, - 'created-by': {'type': 'string'}, - 'date-created': {'format': 'date-time', - 'type': 'string'}, - 'disabled': {'type': 'boolean'}, - 'display-name': {'type': 'string'}, - 'last-connection': {'format': 'date-time', - 'type': 'string'}, - 'username': {'type': 'string'}}, - 'required': ['username', - 'display-name', - 'access', - 'created-by', - 'date-created', - 'disabled'], - 'type': 'object'}, - 'UserInfoRequest': {'additionalProperties': False, - 'properties': {'entities': {'items': {'$ref': '#/definitions/Entity'}, - 'type': 'array'}, - 'include-disabled': {'type': 'boolean'}}, - 'required': ['entities', - 'include-disabled'], - 'type': 'object'}, - 'UserInfoResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/UserInfo'}}, - 'type': 'object'}, - 'UserInfoResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/UserInfoResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}}, - 'properties': {'AddUser': {'description': 'AddUser adds a user with a ' - 'username, and either a password ' - 'or\n' - 'a randomly generated secret key ' - 'which will be returned.', - 'properties': {'Params': {'$ref': '#/definitions/AddUsers'}, - 'Result': {'$ref': '#/definitions/AddUserResults'}}, - 'type': 'object'}, - 'DisableUser': {'description': 'DisableUser disables one or ' - 'more users. If the user is ' - 'already disabled,\n' - 'the action is considered a ' - 'success.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'EnableUser': {'description': 'EnableUser enables one or more ' - 'users. If the user is already ' - 'enabled,\n' - 'the action is considered a ' - 'success.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'ModelUserInfo': {'description': 'ModelUserInfo returns ' - 'information on all users in ' - 'the model.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ModelUserInfoResults'}}, - 'type': 'object'}, - 'RemoveUser': {'description': 'RemoveUser permanently removes ' - 'a user from the current ' - 'controller for each\n' - 'entity provided. While the user ' - 'is permanently removed we keep ' - "it's\n" - 'information around for auditing ' - 'purposes.\n' - 'TODO(redir): Add information ' - 'about getting deleted user ' - 'information when we\n' - 'add that capability.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'ResetPassword': {'description': 'ResetPassword resets ' - 'password for supplied users ' - 'by\n' - 'invalidating current ' - 'passwords (if any) and ' - 'generating\n' - 'new random secret keys which ' - 'will be returned.\n' - 'Users cannot reset their own ' - 'password.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/AddUserResults'}}, - 'type': 'object'}, - 'SetPassword': {'description': 'SetPassword changes the stored ' - 'password for the specified ' - 'users.', - 'properties': {'Params': {'$ref': '#/definitions/EntityPasswords'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'UserInfo': {'description': 'UserInfo returns information on a ' - 'user.', - 'properties': {'Params': {'$ref': '#/definitions/UserInfoRequest'}, - 'Result': {'$ref': '#/definitions/UserInfoResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "AddUser": { + "additionalProperties": False, + "properties": { + "display-name": {"type": "string"}, + "password": {"type": "string"}, + "username": {"type": "string"}, + }, + "required": ["username", "display-name"], + "type": "object", + }, + "AddUserResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "secret-key": {"items": {"type": "integer"}, "type": "array"}, + "tag": {"type": "string"}, + }, + "type": "object", + }, + "AddUserResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/AddUserResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "AddUsers": { + "additionalProperties": False, + "properties": { + "users": { + "items": {"$ref": "#/definitions/AddUser"}, + "type": "array", + } + }, + "required": ["users"], + "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": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "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", + }, + "ModelUserInfo": { + "additionalProperties": False, + "properties": { + "access": {"type": "string"}, + "display-name": {"type": "string"}, + "last-connection": {"format": "date-time", "type": "string"}, + "model-tag": {"type": "string"}, + "user": {"type": "string"}, + }, + "required": [ + "model-tag", + "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", + }, + "UserInfo": { + "additionalProperties": False, + "properties": { + "access": {"type": "string"}, + "created-by": {"type": "string"}, + "date-created": {"format": "date-time", "type": "string"}, + "disabled": {"type": "boolean"}, + "display-name": {"type": "string"}, + "last-connection": {"format": "date-time", "type": "string"}, + "username": {"type": "string"}, + }, + "required": [ + "username", + "display-name", + "access", + "created-by", + "date-created", + "disabled", + ], + "type": "object", + }, + "UserInfoRequest": { + "additionalProperties": False, + "properties": { + "entities": { + "items": {"$ref": "#/definitions/Entity"}, + "type": "array", + }, + "include-disabled": {"type": "boolean"}, + }, + "required": ["entities", "include-disabled"], + "type": "object", + }, + "UserInfoResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/UserInfo"}, + }, + "type": "object", + }, + "UserInfoResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/UserInfoResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + }, + "properties": { + "AddUser": { + "description": "AddUser adds a user with a " + "username, and either a password " + "or\n" + "a randomly generated secret key " + "which will be returned.", + "properties": { + "Params": {"$ref": "#/definitions/AddUsers"}, + "Result": {"$ref": "#/definitions/AddUserResults"}, + }, + "type": "object", + }, + "DisableUser": { + "description": "DisableUser disables one or " + "more users. If the user is " + "already disabled,\n" + "the action is considered a " + "success.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "EnableUser": { + "description": "EnableUser enables one or more " + "users. If the user is already " + "enabled,\n" + "the action is considered a " + "success.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "ModelUserInfo": { + "description": "ModelUserInfo returns " + "information on all users in " + "the model.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/ModelUserInfoResults"}, + }, + "type": "object", + }, + "RemoveUser": { + "description": "RemoveUser permanently removes " + "a user from the current " + "controller for each\n" + "entity provided. While the user " + "is permanently removed we keep " + "it's\n" + "information around for auditing " + "purposes.\n" + "TODO(redir): Add information " + "about getting deleted user " + "information when we\n" + "add that capability.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "ResetPassword": { + "description": "ResetPassword resets " + "password for supplied users " + "by\n" + "invalidating current " + "passwords (if any) and " + "generating\n" + "new random secret keys which " + "will be returned.\n" + "Users cannot reset their own " + "password.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/AddUserResults"}, + }, + "type": "object", + }, + "SetPassword": { + "description": "SetPassword changes the stored " + "password for the specified " + "users.", + "properties": { + "Params": {"$ref": "#/definitions/EntityPasswords"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "UserInfo": { + "description": "UserInfo returns information on a user.", + "properties": { + "Params": {"$ref": "#/definitions/UserInfoRequest"}, + "Result": {"$ref": "#/definitions/UserInfoResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(AddUserResults) async def AddUser(self, users=None): - ''' + """ AddUser adds a user with a username, and either a password or a randomly generated secret key which will be returned. users : typing.Sequence[~AddUser] Returns -> AddUserResults - ''' + """ if users is not None and not isinstance(users, (bytes, str, list)): - raise Exception("Expected users to be a Sequence, received: {}".format(type(users))) + raise Exception( + "Expected users to be a Sequence, received: {}".format(type(users)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='UserManager', - request='AddUser', - version=3, - params=_params) - _params['users'] = users + msg = dict(type="UserManager", request="AddUser", version=3, params=_params) + _params["users"] = users reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def DisableUser(self, entities=None): - ''' + """ DisableUser disables one or more users. If the user is already disabled, the action is considered a success. entities : typing.Sequence[~Entity] Returns -> ErrorResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='UserManager', - request='DisableUser', - version=3, - params=_params) - _params['entities'] = entities + msg = dict(type="UserManager", request="DisableUser", version=3, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def EnableUser(self, entities=None): - ''' + """ EnableUser enables one or more users. If the user is already enabled, the action is considered a success. entities : typing.Sequence[~Entity] Returns -> ErrorResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='UserManager', - request='EnableUser', - version=3, - params=_params) - _params['entities'] = entities + msg = dict(type="UserManager", request="EnableUser", version=3, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ModelUserInfoResults) async def ModelUserInfo(self, entities=None): - ''' + """ ModelUserInfo returns information on all users in the model. entities : typing.Sequence[~Entity] Returns -> ModelUserInfoResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='UserManager', - request='ModelUserInfo', - version=3, - params=_params) - _params['entities'] = entities + msg = dict( + type="UserManager", request="ModelUserInfo", version=3, params=_params + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def RemoveUser(self, entities=None): - ''' + """ RemoveUser permanently removes a user from the current controller for each entity provided. While the user is permanently removed we keep it's information around for auditing purposes. @@ -1250,25 +1632,24 @@ async def RemoveUser(self, entities=None): entities : typing.Sequence[~Entity] Returns -> ErrorResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='UserManager', - request='RemoveUser', - version=3, - params=_params) - _params['entities'] = entities + msg = dict(type="UserManager", request="RemoveUser", version=3, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(AddUserResults) async def ResetPassword(self, entities=None): - ''' + """ ResetPassword resets password for supplied users by invalidating current passwords (if any) and generating new random secret keys which will be returned. @@ -1276,69 +1657,70 @@ async def ResetPassword(self, entities=None): entities : typing.Sequence[~Entity] Returns -> AddUserResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='UserManager', - request='ResetPassword', - version=3, - params=_params) - _params['entities'] = entities + msg = dict( + type="UserManager", request="ResetPassword", version=3, params=_params + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def SetPassword(self, changes=None): - ''' + """ SetPassword changes the stored password for the specified users. changes : typing.Sequence[~EntityPassword] Returns -> ErrorResults - ''' + """ if changes is not None and not isinstance(changes, (bytes, str, list)): - raise Exception("Expected changes to be a Sequence, received: {}".format(type(changes))) + raise Exception( + "Expected changes to be a Sequence, received: {}".format(type(changes)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='UserManager', - request='SetPassword', - version=3, - params=_params) - _params['changes'] = changes + msg = dict(type="UserManager", request="SetPassword", version=3, params=_params) + _params["changes"] = changes reply = await self.rpc(msg) return reply - - @ReturnMapping(UserInfoResults) async def UserInfo(self, entities=None, include_disabled=None): - ''' + """ UserInfo returns information on a user. entities : typing.Sequence[~Entity] include_disabled : bool Returns -> UserInfoResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) if include_disabled is not None and not isinstance(include_disabled, bool): - raise Exception("Expected include_disabled to be a bool, received: {}".format(type(include_disabled))) + raise Exception( + "Expected include_disabled to be a bool, received: {}".format( + type(include_disabled) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='UserManager', - request='UserInfo', - version=3, - params=_params) - _params['entities'] = entities - _params['include-disabled'] = include_disabled + msg = dict(type="UserManager", request="UserInfo", version=3, params=_params) + _params["entities"] = entities + _params["include-disabled"] = include_disabled reply = await self.rpc(msg) return reply - - diff --git a/juju/client/_client4.py b/juju/client/_client4.py index 090bbf042..4c6d8e413 100644 --- a/juju/client/_client4.py +++ b/juju/client/_client4.py @@ -6,881 +6,1211 @@ class AllModelWatcherFacade(Type): - name = 'AllModelWatcher' + name = "AllModelWatcher" version = 4 - schema = {'definitions': {'AllWatcherNextResults': {'additionalProperties': False, - 'properties': {'deltas': {'items': {'$ref': '#/definitions/Delta'}, - 'type': 'array'}}, - 'required': ['deltas'], - 'type': 'object'}, - 'Delta': {'additionalProperties': False, - 'properties': {'entity': {'additionalProperties': True, - 'type': 'object'}, - 'removed': {'type': 'boolean'}}, - 'required': ['removed', 'entity'], - 'type': 'object'}}, - 'properties': {'Next': {'description': 'Next will return the current state of ' - 'everything on the first call\n' - 'and subsequent calls will', - 'properties': {'Result': {'$ref': '#/definitions/AllWatcherNextResults'}}, - 'type': 'object'}, - 'Stop': {'description': 'Stop stops the watcher.', - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "AllWatcherNextResults": { + "additionalProperties": False, + "properties": { + "deltas": { + "items": {"$ref": "#/definitions/Delta"}, + "type": "array", + } + }, + "required": ["deltas"], + "type": "object", + }, + "Delta": { + "additionalProperties": False, + "properties": { + "entity": {"additionalProperties": True, "type": "object"}, + "removed": {"type": "boolean"}, + }, + "required": ["removed", "entity"], + "type": "object", + }, + }, + "properties": { + "Next": { + "description": "Next will return the current state of " + "everything on the first call\n" + "and subsequent calls will", + "properties": { + "Result": {"$ref": "#/definitions/AllWatcherNextResults"} + }, + "type": "object", + }, + "Stop": {"description": "Stop stops the watcher.", "type": "object"}, + }, + "type": "object", + } @ReturnMapping(AllWatcherNextResults) async def Next(self): - ''' + """ Next will return the current state of everything on the first call and subsequent calls will Returns -> AllWatcherNextResults - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='AllModelWatcher', - request='Next', - version=4, - params=_params) + msg = dict(type="AllModelWatcher", request="Next", version=4, params=_params) reply = await self.rpc(msg) return reply - - @ReturnMapping(None) async def Stop(self): - ''' + """ Stop stops the watcher. Returns -> None - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='AllModelWatcher', - request='Stop', - version=4, - params=_params) + msg = dict(type="AllModelWatcher", request="Stop", version=4, params=_params) reply = await self.rpc(msg) return reply - - async def rpc(self, msg): - ''' + """ Patch rpc method to add Id. - ''' - if not hasattr(self, 'Id'): + """ + if not hasattr(self, "Id"): raise RuntimeError('Missing "Id" field') - msg['Id'] = id + msg["Id"] = id from .facade import TypeEncoder + reply = await self.connection.rpc(msg, encoder=TypeEncoder) return reply - class ApplicationOffersFacade(Type): - name = 'ApplicationOffers' + name = "ApplicationOffers" version = 4 - schema = {'definitions': {'AddApplicationOffer': {'additionalProperties': False, - 'properties': {'application-description': {'type': 'string'}, - 'application-name': {'type': 'string'}, - 'endpoints': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'model-tag': {'type': 'string'}, - 'offer-name': {'type': 'string'}, - 'owner-tag': {'type': 'string'}}, - 'required': ['model-tag', - 'offer-name', - 'application-name', - 'application-description', - 'endpoints'], - 'type': 'object'}, - 'AddApplicationOffers': {'additionalProperties': False, - 'properties': {'Offers': {'items': {'$ref': '#/definitions/AddApplicationOffer'}, - 'type': 'array'}}, - 'required': ['Offers'], - 'type': 'object'}, - 'ApplicationOfferAdminDetails': {'additionalProperties': False, - 'properties': {'ApplicationOfferDetails': {'$ref': '#/definitions/ApplicationOfferDetails'}, - 'application-description': {'type': 'string'}, - 'application-name': {'type': 'string'}, - 'bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'charm-url': {'type': 'string'}, - 'connections': {'items': {'$ref': '#/definitions/OfferConnection'}, - 'type': 'array'}, - 'endpoints': {'items': {'$ref': '#/definitions/RemoteEndpoint'}, - 'type': 'array'}, - 'offer-name': {'type': 'string'}, - 'offer-url': {'type': 'string'}, - 'offer-uuid': {'type': 'string'}, - 'source-model-tag': {'type': 'string'}, - 'spaces': {'items': {'$ref': '#/definitions/RemoteSpace'}, - 'type': 'array'}, - 'users': {'items': {'$ref': '#/definitions/OfferUserDetails'}, - 'type': 'array'}}, - 'required': ['source-model-tag', - 'offer-uuid', - 'offer-url', - 'offer-name', - 'application-description', - 'ApplicationOfferDetails', - 'application-name', - 'charm-url'], - 'type': 'object'}, - 'ApplicationOfferDetails': {'additionalProperties': False, - 'properties': {'application-description': {'type': 'string'}, - 'bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'endpoints': {'items': {'$ref': '#/definitions/RemoteEndpoint'}, - 'type': 'array'}, - 'offer-name': {'type': 'string'}, - 'offer-url': {'type': 'string'}, - 'offer-uuid': {'type': 'string'}, - 'source-model-tag': {'type': 'string'}, - 'spaces': {'items': {'$ref': '#/definitions/RemoteSpace'}, - 'type': 'array'}, - 'users': {'items': {'$ref': '#/definitions/OfferUserDetails'}, - 'type': 'array'}}, - 'required': ['source-model-tag', - 'offer-uuid', - 'offer-url', - 'offer-name', - 'application-description'], - 'type': 'object'}, - 'ApplicationOfferResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/ApplicationOfferAdminDetails'}}, - 'type': 'object'}, - 'ApplicationOffersResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ApplicationOfferResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'ConsumeOfferDetails': {'additionalProperties': False, - 'properties': {'external-controller': {'$ref': '#/definitions/ExternalControllerInfo'}, - 'macaroon': {'$ref': '#/definitions/Macaroon'}, - 'offer': {'$ref': '#/definitions/ApplicationOfferDetails'}}, - 'type': 'object'}, - 'ConsumeOfferDetailsArg': {'additionalProperties': False, - 'properties': {'offer-urls': {'$ref': '#/definitions/OfferURLs'}, - 'user-tag': {'type': 'string'}}, - 'required': ['offer-urls'], - 'type': 'object'}, - 'ConsumeOfferDetailsResult': {'additionalProperties': False, - 'properties': {'ConsumeOfferDetails': {'$ref': '#/definitions/ConsumeOfferDetails'}, - 'error': {'$ref': '#/definitions/Error'}, - 'external-controller': {'$ref': '#/definitions/ExternalControllerInfo'}, - 'macaroon': {'$ref': '#/definitions/Macaroon'}, - 'offer': {'$ref': '#/definitions/ApplicationOfferDetails'}}, - 'required': ['ConsumeOfferDetails'], - 'type': 'object'}, - 'ConsumeOfferDetailsResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ConsumeOfferDetailsResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'DestroyApplicationOffers': {'additionalProperties': False, - 'properties': {'force': {'type': 'boolean'}, - 'offer-urls': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['offer-urls'], - 'type': 'object'}, - 'EndpointFilterAttributes': {'additionalProperties': False, - 'properties': {'interface': {'type': 'string'}, - 'name': {'type': 'string'}, - 'role': {'type': 'string'}}, - 'required': ['role', - 'interface', - 'name'], - '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': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - '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'}, - 'ExternalControllerInfo': {'additionalProperties': False, - 'properties': {'addrs': {'items': {'type': 'string'}, - 'type': 'array'}, - 'ca-cert': {'type': 'string'}, - 'controller-alias': {'type': 'string'}, - 'controller-tag': {'type': 'string'}}, - 'required': ['controller-tag', - 'controller-alias', - 'addrs', - 'ca-cert'], - 'type': 'object'}, - 'Macaroon': {'additionalProperties': False, 'type': 'object'}, - 'ModifyOfferAccess': {'additionalProperties': False, - 'properties': {'access': {'type': 'string'}, - 'action': {'type': 'string'}, - 'offer-url': {'type': 'string'}, - 'user-tag': {'type': 'string'}}, - 'required': ['user-tag', - 'action', - 'access', - 'offer-url'], - 'type': 'object'}, - 'ModifyOfferAccessRequest': {'additionalProperties': False, - 'properties': {'changes': {'items': {'$ref': '#/definitions/ModifyOfferAccess'}, - 'type': 'array'}}, - 'required': ['changes'], - 'type': 'object'}, - 'OfferConnection': {'additionalProperties': False, - 'properties': {'endpoint': {'type': 'string'}, - 'ingress-subnets': {'items': {'type': 'string'}, - 'type': 'array'}, - 'relation-id': {'type': 'integer'}, - 'source-model-tag': {'type': 'string'}, - 'status': {'$ref': '#/definitions/EntityStatus'}, - 'username': {'type': 'string'}}, - 'required': ['source-model-tag', - 'relation-id', - 'username', - 'endpoint', - 'status', - 'ingress-subnets'], - 'type': 'object'}, - 'OfferFilter': {'additionalProperties': False, - 'properties': {'allowed-users': {'items': {'type': 'string'}, - 'type': 'array'}, - 'application-description': {'type': 'string'}, - 'application-name': {'type': 'string'}, - 'application-user': {'type': 'string'}, - 'connected-users': {'items': {'type': 'string'}, - 'type': 'array'}, - 'endpoints': {'items': {'$ref': '#/definitions/EndpointFilterAttributes'}, - 'type': 'array'}, - 'model-name': {'type': 'string'}, - 'offer-name': {'type': 'string'}, - 'owner-name': {'type': 'string'}}, - 'required': ['owner-name', - 'model-name', - 'offer-name', - 'application-name', - 'application-description', - 'application-user', - 'endpoints', - 'connected-users', - 'allowed-users'], - 'type': 'object'}, - 'OfferFilters': {'additionalProperties': False, - 'properties': {'Filters': {'items': {'$ref': '#/definitions/OfferFilter'}, - 'type': 'array'}}, - 'required': ['Filters'], - 'type': 'object'}, - 'OfferURLs': {'additionalProperties': False, - 'properties': {'bakery-version': {'type': 'integer'}, - 'offer-urls': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'OfferUserDetails': {'additionalProperties': False, - 'properties': {'access': {'type': 'string'}, - 'display-name': {'type': 'string'}, - 'user': {'type': 'string'}}, - 'required': ['user', - 'display-name', - 'access'], - 'type': 'object'}, - 'QueryApplicationOffersResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ApplicationOfferAdminDetails'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'RemoteApplicationInfo': {'additionalProperties': False, - 'properties': {'description': {'type': 'string'}, - 'endpoints': {'items': {'$ref': '#/definitions/RemoteEndpoint'}, - 'type': 'array'}, - 'icon-url-path': {'type': 'string'}, - 'model-tag': {'type': 'string'}, - 'name': {'type': 'string'}, - 'offer-url': {'type': 'string'}, - 'source-model-label': {'type': 'string'}}, - 'required': ['model-tag', - 'name', - 'description', - 'offer-url', - 'endpoints', - 'icon-url-path'], - 'type': 'object'}, - 'RemoteApplicationInfoResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/RemoteApplicationInfo'}}, - 'type': 'object'}, - 'RemoteApplicationInfoResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/RemoteApplicationInfoResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'RemoteEndpoint': {'additionalProperties': False, - 'properties': {'interface': {'type': 'string'}, - 'limit': {'type': 'integer'}, - 'name': {'type': 'string'}, - 'role': {'type': 'string'}}, - 'required': ['name', - 'role', - 'interface', - 'limit'], - 'type': 'object'}, - 'RemoteSpace': {'additionalProperties': False, - 'properties': {'cloud-type': {'type': 'string'}, - 'name': {'type': 'string'}, - 'provider-attributes': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'provider-id': {'type': 'string'}, - 'subnets': {'items': {'$ref': '#/definitions/Subnet'}, - 'type': 'array'}}, - 'required': ['cloud-type', - 'name', - 'provider-id', - 'provider-attributes', - 'subnets'], - 'type': 'object'}, - 'Subnet': {'additionalProperties': False, - 'properties': {'cidr': {'type': 'string'}, - 'life': {'type': 'string'}, - 'provider-id': {'type': 'string'}, - 'provider-network-id': {'type': 'string'}, - 'provider-space-id': {'type': 'string'}, - 'space-tag': {'type': 'string'}, - 'status': {'type': 'string'}, - 'vlan-tag': {'type': 'integer'}, - 'zones': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['cidr', - 'vlan-tag', - 'life', - 'space-tag', - 'zones'], - 'type': 'object'}}, - 'properties': {'ApplicationOffers': {'description': 'ApplicationOffers gets ' - 'details about remote ' - 'applications that match ' - 'given URLs.', - 'properties': {'Params': {'$ref': '#/definitions/OfferURLs'}, - 'Result': {'$ref': '#/definitions/ApplicationOffersResults'}}, - 'type': 'object'}, - 'DestroyOffers': {'description': 'DestroyOffers removes the ' - 'offers specified by the ' - 'given URLs, forcing if ' - 'necessary.', - 'properties': {'Params': {'$ref': '#/definitions/DestroyApplicationOffers'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'FindApplicationOffers': {'description': 'FindApplicationOffers ' - 'gets details about ' - 'remote applications ' - 'that match given ' - 'filter.', - 'properties': {'Params': {'$ref': '#/definitions/OfferFilters'}, - 'Result': {'$ref': '#/definitions/QueryApplicationOffersResults'}}, - 'type': 'object'}, - 'GetConsumeDetails': {'description': 'GetConsumeDetails ' - 'returns the details ' - 'necessary to pass to ' - 'another model\n' - 'to allow the specified ' - 'args user to consume the ' - 'offers represented by ' - 'the args URLs.', - 'properties': {'Params': {'$ref': '#/definitions/ConsumeOfferDetailsArg'}, - 'Result': {'$ref': '#/definitions/ConsumeOfferDetailsResults'}}, - 'type': 'object'}, - 'ListApplicationOffers': {'description': 'ListApplicationOffers ' - 'gets deployed ' - 'details about ' - 'application offers ' - 'that match given ' - 'filter.\n' - 'The results contain ' - 'details about the ' - 'deployed ' - 'applications such as ' - 'connection count.', - 'properties': {'Params': {'$ref': '#/definitions/OfferFilters'}, - 'Result': {'$ref': '#/definitions/QueryApplicationOffersResults'}}, - 'type': 'object'}, - 'ModifyOfferAccess': {'description': 'ModifyOfferAccess ' - 'changes the application ' - 'offer access granted to ' - 'users.', - 'properties': {'Params': {'$ref': '#/definitions/ModifyOfferAccessRequest'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'Offer': {'description': 'Offer makes application endpoints ' - 'available for consumption at a ' - 'specified URL.', - 'properties': {'Params': {'$ref': '#/definitions/AddApplicationOffers'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'RemoteApplicationInfo': {'description': 'RemoteApplicationInfo ' - 'returns information ' - 'about the requested ' - 'remote application.\n' - 'This call currently ' - 'has no client side ' - 'API, only there for ' - 'the Dashboard at ' - 'this stage.', - 'properties': {'Params': {'$ref': '#/definitions/OfferURLs'}, - 'Result': {'$ref': '#/definitions/RemoteApplicationInfoResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "AddApplicationOffer": { + "additionalProperties": False, + "properties": { + "application-description": {"type": "string"}, + "application-name": {"type": "string"}, + "endpoints": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "model-tag": {"type": "string"}, + "offer-name": {"type": "string"}, + "owner-tag": {"type": "string"}, + }, + "required": [ + "model-tag", + "offer-name", + "application-name", + "application-description", + "endpoints", + ], + "type": "object", + }, + "AddApplicationOffers": { + "additionalProperties": False, + "properties": { + "Offers": { + "items": {"$ref": "#/definitions/AddApplicationOffer"}, + "type": "array", + } + }, + "required": ["Offers"], + "type": "object", + }, + "ApplicationOfferAdminDetails": { + "additionalProperties": False, + "properties": { + "ApplicationOfferDetails": { + "$ref": "#/definitions/ApplicationOfferDetails" + }, + "application-description": {"type": "string"}, + "application-name": {"type": "string"}, + "bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "charm-url": {"type": "string"}, + "connections": { + "items": {"$ref": "#/definitions/OfferConnection"}, + "type": "array", + }, + "endpoints": { + "items": {"$ref": "#/definitions/RemoteEndpoint"}, + "type": "array", + }, + "offer-name": {"type": "string"}, + "offer-url": {"type": "string"}, + "offer-uuid": {"type": "string"}, + "source-model-tag": {"type": "string"}, + "spaces": { + "items": {"$ref": "#/definitions/RemoteSpace"}, + "type": "array", + }, + "users": { + "items": {"$ref": "#/definitions/OfferUserDetails"}, + "type": "array", + }, + }, + "required": [ + "source-model-tag", + "offer-uuid", + "offer-url", + "offer-name", + "application-description", + "ApplicationOfferDetails", + "application-name", + "charm-url", + ], + "type": "object", + }, + "ApplicationOfferDetails": { + "additionalProperties": False, + "properties": { + "application-description": {"type": "string"}, + "bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "endpoints": { + "items": {"$ref": "#/definitions/RemoteEndpoint"}, + "type": "array", + }, + "offer-name": {"type": "string"}, + "offer-url": {"type": "string"}, + "offer-uuid": {"type": "string"}, + "source-model-tag": {"type": "string"}, + "spaces": { + "items": {"$ref": "#/definitions/RemoteSpace"}, + "type": "array", + }, + "users": { + "items": {"$ref": "#/definitions/OfferUserDetails"}, + "type": "array", + }, + }, + "required": [ + "source-model-tag", + "offer-uuid", + "offer-url", + "offer-name", + "application-description", + ], + "type": "object", + }, + "ApplicationOfferResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/ApplicationOfferAdminDetails"}, + }, + "type": "object", + }, + "ApplicationOffersResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ApplicationOfferResult"}, + "type": "array", + } + }, + "type": "object", + }, + "ConsumeOfferDetails": { + "additionalProperties": False, + "properties": { + "external-controller": { + "$ref": "#/definitions/ExternalControllerInfo" + }, + "macaroon": {"$ref": "#/definitions/Macaroon"}, + "offer": {"$ref": "#/definitions/ApplicationOfferDetails"}, + }, + "type": "object", + }, + "ConsumeOfferDetailsArg": { + "additionalProperties": False, + "properties": { + "offer-urls": {"$ref": "#/definitions/OfferURLs"}, + "user-tag": {"type": "string"}, + }, + "required": ["offer-urls"], + "type": "object", + }, + "ConsumeOfferDetailsResult": { + "additionalProperties": False, + "properties": { + "ConsumeOfferDetails": { + "$ref": "#/definitions/ConsumeOfferDetails" + }, + "error": {"$ref": "#/definitions/Error"}, + "external-controller": { + "$ref": "#/definitions/ExternalControllerInfo" + }, + "macaroon": {"$ref": "#/definitions/Macaroon"}, + "offer": {"$ref": "#/definitions/ApplicationOfferDetails"}, + }, + "required": ["ConsumeOfferDetails"], + "type": "object", + }, + "ConsumeOfferDetailsResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ConsumeOfferDetailsResult"}, + "type": "array", + } + }, + "type": "object", + }, + "DestroyApplicationOffers": { + "additionalProperties": False, + "properties": { + "force": {"type": "boolean"}, + "offer-urls": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["offer-urls"], + "type": "object", + }, + "EndpointFilterAttributes": { + "additionalProperties": False, + "properties": { + "interface": {"type": "string"}, + "name": {"type": "string"}, + "role": {"type": "string"}, + }, + "required": ["role", "interface", "name"], + "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": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "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", + }, + "ExternalControllerInfo": { + "additionalProperties": False, + "properties": { + "addrs": {"items": {"type": "string"}, "type": "array"}, + "ca-cert": {"type": "string"}, + "controller-alias": {"type": "string"}, + "controller-tag": {"type": "string"}, + }, + "required": ["controller-tag", "controller-alias", "addrs", "ca-cert"], + "type": "object", + }, + "Macaroon": {"additionalProperties": False, "type": "object"}, + "ModifyOfferAccess": { + "additionalProperties": False, + "properties": { + "access": {"type": "string"}, + "action": {"type": "string"}, + "offer-url": {"type": "string"}, + "user-tag": {"type": "string"}, + }, + "required": ["user-tag", "action", "access", "offer-url"], + "type": "object", + }, + "ModifyOfferAccessRequest": { + "additionalProperties": False, + "properties": { + "changes": { + "items": {"$ref": "#/definitions/ModifyOfferAccess"}, + "type": "array", + } + }, + "required": ["changes"], + "type": "object", + }, + "OfferConnection": { + "additionalProperties": False, + "properties": { + "endpoint": {"type": "string"}, + "ingress-subnets": {"items": {"type": "string"}, "type": "array"}, + "relation-id": {"type": "integer"}, + "source-model-tag": {"type": "string"}, + "status": {"$ref": "#/definitions/EntityStatus"}, + "username": {"type": "string"}, + }, + "required": [ + "source-model-tag", + "relation-id", + "username", + "endpoint", + "status", + "ingress-subnets", + ], + "type": "object", + }, + "OfferFilter": { + "additionalProperties": False, + "properties": { + "allowed-users": {"items": {"type": "string"}, "type": "array"}, + "application-description": {"type": "string"}, + "application-name": {"type": "string"}, + "application-user": {"type": "string"}, + "connected-users": {"items": {"type": "string"}, "type": "array"}, + "endpoints": { + "items": {"$ref": "#/definitions/EndpointFilterAttributes"}, + "type": "array", + }, + "model-name": {"type": "string"}, + "offer-name": {"type": "string"}, + "owner-name": {"type": "string"}, + }, + "required": [ + "owner-name", + "model-name", + "offer-name", + "application-name", + "application-description", + "application-user", + "endpoints", + "connected-users", + "allowed-users", + ], + "type": "object", + }, + "OfferFilters": { + "additionalProperties": False, + "properties": { + "Filters": { + "items": {"$ref": "#/definitions/OfferFilter"}, + "type": "array", + } + }, + "required": ["Filters"], + "type": "object", + }, + "OfferURLs": { + "additionalProperties": False, + "properties": { + "bakery-version": {"type": "integer"}, + "offer-urls": {"items": {"type": "string"}, "type": "array"}, + }, + "type": "object", + }, + "OfferUserDetails": { + "additionalProperties": False, + "properties": { + "access": {"type": "string"}, + "display-name": {"type": "string"}, + "user": {"type": "string"}, + }, + "required": ["user", "display-name", "access"], + "type": "object", + }, + "QueryApplicationOffersResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ApplicationOfferAdminDetails"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "RemoteApplicationInfo": { + "additionalProperties": False, + "properties": { + "description": {"type": "string"}, + "endpoints": { + "items": {"$ref": "#/definitions/RemoteEndpoint"}, + "type": "array", + }, + "icon-url-path": {"type": "string"}, + "model-tag": {"type": "string"}, + "name": {"type": "string"}, + "offer-url": {"type": "string"}, + "source-model-label": {"type": "string"}, + }, + "required": [ + "model-tag", + "name", + "description", + "offer-url", + "endpoints", + "icon-url-path", + ], + "type": "object", + }, + "RemoteApplicationInfoResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/RemoteApplicationInfo"}, + }, + "type": "object", + }, + "RemoteApplicationInfoResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/RemoteApplicationInfoResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "RemoteEndpoint": { + "additionalProperties": False, + "properties": { + "interface": {"type": "string"}, + "limit": {"type": "integer"}, + "name": {"type": "string"}, + "role": {"type": "string"}, + }, + "required": ["name", "role", "interface", "limit"], + "type": "object", + }, + "RemoteSpace": { + "additionalProperties": False, + "properties": { + "cloud-type": {"type": "string"}, + "name": {"type": "string"}, + "provider-attributes": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "provider-id": {"type": "string"}, + "subnets": { + "items": {"$ref": "#/definitions/Subnet"}, + "type": "array", + }, + }, + "required": [ + "cloud-type", + "name", + "provider-id", + "provider-attributes", + "subnets", + ], + "type": "object", + }, + "Subnet": { + "additionalProperties": False, + "properties": { + "cidr": {"type": "string"}, + "life": {"type": "string"}, + "provider-id": {"type": "string"}, + "provider-network-id": {"type": "string"}, + "provider-space-id": {"type": "string"}, + "space-tag": {"type": "string"}, + "status": {"type": "string"}, + "vlan-tag": {"type": "integer"}, + "zones": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["cidr", "vlan-tag", "life", "space-tag", "zones"], + "type": "object", + }, + }, + "properties": { + "ApplicationOffers": { + "description": "ApplicationOffers gets " + "details about remote " + "applications that match " + "given URLs.", + "properties": { + "Params": {"$ref": "#/definitions/OfferURLs"}, + "Result": {"$ref": "#/definitions/ApplicationOffersResults"}, + }, + "type": "object", + }, + "DestroyOffers": { + "description": "DestroyOffers removes the " + "offers specified by the " + "given URLs, forcing if " + "necessary.", + "properties": { + "Params": {"$ref": "#/definitions/DestroyApplicationOffers"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "FindApplicationOffers": { + "description": "FindApplicationOffers " + "gets details about " + "remote applications " + "that match given " + "filter.", + "properties": { + "Params": {"$ref": "#/definitions/OfferFilters"}, + "Result": {"$ref": "#/definitions/QueryApplicationOffersResults"}, + }, + "type": "object", + }, + "GetConsumeDetails": { + "description": "GetConsumeDetails " + "returns the details " + "necessary to pass to " + "another model\n" + "to allow the specified " + "args user to consume the " + "offers represented by " + "the args URLs.", + "properties": { + "Params": {"$ref": "#/definitions/ConsumeOfferDetailsArg"}, + "Result": {"$ref": "#/definitions/ConsumeOfferDetailsResults"}, + }, + "type": "object", + }, + "ListApplicationOffers": { + "description": "ListApplicationOffers " + "gets deployed " + "details about " + "application offers " + "that match given " + "filter.\n" + "The results contain " + "details about the " + "deployed " + "applications such as " + "connection count.", + "properties": { + "Params": {"$ref": "#/definitions/OfferFilters"}, + "Result": {"$ref": "#/definitions/QueryApplicationOffersResults"}, + }, + "type": "object", + }, + "ModifyOfferAccess": { + "description": "ModifyOfferAccess " + "changes the application " + "offer access granted to " + "users.", + "properties": { + "Params": {"$ref": "#/definitions/ModifyOfferAccessRequest"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "Offer": { + "description": "Offer makes application endpoints " + "available for consumption at a " + "specified URL.", + "properties": { + "Params": {"$ref": "#/definitions/AddApplicationOffers"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "RemoteApplicationInfo": { + "description": "RemoteApplicationInfo " + "returns information " + "about the requested " + "remote application.\n" + "This call currently " + "has no client side " + "API, only there for " + "the Dashboard at " + "this stage.", + "properties": { + "Params": {"$ref": "#/definitions/OfferURLs"}, + "Result": {"$ref": "#/definitions/RemoteApplicationInfoResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(ApplicationOffersResults) async def ApplicationOffers(self, bakery_version=None, offer_urls=None): - ''' + """ ApplicationOffers gets details about remote applications that match given URLs. bakery_version : int offer_urls : typing.Sequence[str] Returns -> ApplicationOffersResults - ''' + """ if bakery_version is not None and not isinstance(bakery_version, int): - raise Exception("Expected bakery_version to be a int, received: {}".format(type(bakery_version))) + raise Exception( + "Expected bakery_version to be a int, received: {}".format( + type(bakery_version) + ) + ) if offer_urls is not None and not isinstance(offer_urls, (bytes, str, list)): - raise Exception("Expected offer_urls to be a Sequence, received: {}".format(type(offer_urls))) + raise Exception( + "Expected offer_urls to be a Sequence, received: {}".format( + type(offer_urls) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ApplicationOffers', - request='ApplicationOffers', - version=4, - params=_params) - _params['bakery-version'] = bakery_version - _params['offer-urls'] = offer_urls + msg = dict( + type="ApplicationOffers", + request="ApplicationOffers", + version=4, + params=_params, + ) + _params["bakery-version"] = bakery_version + _params["offer-urls"] = offer_urls reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def DestroyOffers(self, force=None, offer_urls=None): - ''' + """ DestroyOffers removes the offers specified by the given URLs, forcing if necessary. force : bool offer_urls : typing.Sequence[str] Returns -> ErrorResults - ''' + """ if force is not None and not isinstance(force, bool): - raise Exception("Expected force to be a bool, received: {}".format(type(force))) + raise Exception( + "Expected force to be a bool, received: {}".format(type(force)) + ) if offer_urls is not None and not isinstance(offer_urls, (bytes, str, list)): - raise Exception("Expected offer_urls to be a Sequence, received: {}".format(type(offer_urls))) + raise Exception( + "Expected offer_urls to be a Sequence, received: {}".format( + type(offer_urls) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ApplicationOffers', - request='DestroyOffers', - version=4, - params=_params) - _params['force'] = force - _params['offer-urls'] = offer_urls + msg = dict( + type="ApplicationOffers", request="DestroyOffers", version=4, params=_params + ) + _params["force"] = force + _params["offer-urls"] = offer_urls reply = await self.rpc(msg) return reply - - @ReturnMapping(QueryApplicationOffersResults) async def FindApplicationOffers(self, filters=None): - ''' + """ FindApplicationOffers gets details about remote applications that match given filter. filters : typing.Sequence[~OfferFilter] Returns -> QueryApplicationOffersResults - ''' + """ if filters is not None and not isinstance(filters, (bytes, str, list)): - raise Exception("Expected filters to be a Sequence, received: {}".format(type(filters))) + raise Exception( + "Expected filters to be a Sequence, received: {}".format(type(filters)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ApplicationOffers', - request='FindApplicationOffers', - version=4, - params=_params) - _params['Filters'] = filters + msg = dict( + type="ApplicationOffers", + request="FindApplicationOffers", + version=4, + params=_params, + ) + _params["Filters"] = filters reply = await self.rpc(msg) return reply - - @ReturnMapping(ConsumeOfferDetailsResults) async def GetConsumeDetails(self, offer_urls=None, user_tag=None): - ''' + """ GetConsumeDetails returns the details necessary to pass to another model to allow the specified args user to consume the offers represented by the args URLs. offer_urls : OfferURLs user_tag : str Returns -> ConsumeOfferDetailsResults - ''' + """ if offer_urls is not None and not isinstance(offer_urls, (dict, OfferURLs)): - raise Exception("Expected offer_urls to be a OfferURLs, received: {}".format(type(offer_urls))) + raise Exception( + "Expected offer_urls to be a OfferURLs, received: {}".format( + type(offer_urls) + ) + ) if user_tag is not None and not isinstance(user_tag, (bytes, str)): - raise Exception("Expected user_tag to be a str, received: {}".format(type(user_tag))) + raise Exception( + "Expected user_tag to be a str, received: {}".format(type(user_tag)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ApplicationOffers', - request='GetConsumeDetails', - version=4, - params=_params) - _params['offer-urls'] = offer_urls - _params['user-tag'] = user_tag + msg = dict( + type="ApplicationOffers", + request="GetConsumeDetails", + version=4, + params=_params, + ) + _params["offer-urls"] = offer_urls + _params["user-tag"] = user_tag reply = await self.rpc(msg) return reply - - @ReturnMapping(QueryApplicationOffersResults) async def ListApplicationOffers(self, filters=None): - ''' + """ ListApplicationOffers gets deployed details about application offers that match given filter. The results contain details about the deployed applications such as connection count. filters : typing.Sequence[~OfferFilter] Returns -> QueryApplicationOffersResults - ''' + """ if filters is not None and not isinstance(filters, (bytes, str, list)): - raise Exception("Expected filters to be a Sequence, received: {}".format(type(filters))) + raise Exception( + "Expected filters to be a Sequence, received: {}".format(type(filters)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ApplicationOffers', - request='ListApplicationOffers', - version=4, - params=_params) - _params['Filters'] = filters + msg = dict( + type="ApplicationOffers", + request="ListApplicationOffers", + version=4, + params=_params, + ) + _params["Filters"] = filters reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def ModifyOfferAccess(self, changes=None): - ''' + """ ModifyOfferAccess changes the application offer access granted to users. changes : typing.Sequence[~ModifyOfferAccess] Returns -> ErrorResults - ''' + """ if changes is not None and not isinstance(changes, (bytes, str, list)): - raise Exception("Expected changes to be a Sequence, received: {}".format(type(changes))) + raise Exception( + "Expected changes to be a Sequence, received: {}".format(type(changes)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ApplicationOffers', - request='ModifyOfferAccess', - version=4, - params=_params) - _params['changes'] = changes + msg = dict( + type="ApplicationOffers", + request="ModifyOfferAccess", + version=4, + params=_params, + ) + _params["changes"] = changes reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def Offer(self, offers=None): - ''' + """ Offer makes application endpoints available for consumption at a specified URL. offers : typing.Sequence[~AddApplicationOffer] Returns -> ErrorResults - ''' + """ if offers is not None and not isinstance(offers, (bytes, str, list)): - raise Exception("Expected offers to be a Sequence, received: {}".format(type(offers))) + raise Exception( + "Expected offers to be a Sequence, received: {}".format(type(offers)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ApplicationOffers', - request='Offer', - version=4, - params=_params) - _params['Offers'] = offers + msg = dict(type="ApplicationOffers", request="Offer", version=4, params=_params) + _params["Offers"] = offers reply = await self.rpc(msg) return reply - - @ReturnMapping(RemoteApplicationInfoResults) async def RemoteApplicationInfo(self, bakery_version=None, offer_urls=None): - ''' + """ RemoteApplicationInfo returns information about the requested remote application. This call currently has no client side API, only there for the Dashboard at this stage. bakery_version : int offer_urls : typing.Sequence[str] Returns -> RemoteApplicationInfoResults - ''' + """ if bakery_version is not None and not isinstance(bakery_version, int): - raise Exception("Expected bakery_version to be a int, received: {}".format(type(bakery_version))) + raise Exception( + "Expected bakery_version to be a int, received: {}".format( + type(bakery_version) + ) + ) if offer_urls is not None and not isinstance(offer_urls, (bytes, str, list)): - raise Exception("Expected offer_urls to be a Sequence, received: {}".format(type(offer_urls))) + raise Exception( + "Expected offer_urls to be a Sequence, received: {}".format( + type(offer_urls) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ApplicationOffers', - request='RemoteApplicationInfo', - version=4, - params=_params) - _params['bakery-version'] = bakery_version - _params['offer-urls'] = offer_urls + msg = dict( + type="ApplicationOffers", + request="RemoteApplicationInfo", + version=4, + params=_params, + ) + _params["bakery-version"] = bakery_version + _params["offer-urls"] = offer_urls reply = await self.rpc(msg) return reply - class ModelGenerationFacade(Type): - name = 'ModelGeneration' + name = "ModelGeneration" version = 4 - schema = {'definitions': {'BoolResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'type': 'boolean'}}, - 'required': ['result'], - 'type': 'object'}, - 'BranchArg': {'additionalProperties': False, - 'properties': {'branch': {'type': 'string'}}, - 'required': ['branch'], - 'type': 'object'}, - 'BranchInfoArgs': {'additionalProperties': False, - 'properties': {'branches': {'items': {'type': 'string'}, - 'type': 'array'}, - 'detailed': {'type': 'boolean'}}, - 'required': ['branches', 'detailed'], - 'type': 'object'}, - 'BranchResults': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'generations': {'items': {'$ref': '#/definitions/Generation'}, - 'type': 'array'}}, - 'required': ['generations'], - 'type': 'object'}, - 'BranchTrackArg': {'additionalProperties': False, - 'properties': {'branch': {'type': 'string'}, - 'entities': {'items': {'$ref': '#/definitions/Entity'}, - 'type': 'array'}, - 'num-units': {'type': 'integer'}}, - 'required': ['branch', 'entities'], - 'type': 'object'}, - 'Entity': {'additionalProperties': False, - 'properties': {'tag': {'type': 'string'}}, - 'required': ['tag'], - 'type': 'object'}, - 'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - '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'}, - 'Generation': {'additionalProperties': False, - 'properties': {'applications': {'items': {'$ref': '#/definitions/GenerationApplication'}, - 'type': 'array'}, - 'branch': {'type': 'string'}, - 'completed': {'type': 'integer'}, - 'completed-by': {'type': 'string'}, - 'created': {'type': 'integer'}, - 'created-by': {'type': 'string'}, - 'generation-id': {'type': 'integer'}}, - 'required': ['branch', - 'created', - 'created-by', - 'applications'], - 'type': 'object'}, - 'GenerationApplication': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'pending': {'items': {'type': 'string'}, - 'type': 'array'}, - 'progress': {'type': 'string'}, - 'tracking': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['application', - 'progress', - 'config'], - 'type': 'object'}, - 'GenerationId': {'additionalProperties': False, - 'properties': {'generation-id': {'type': 'integer'}}, - 'required': ['generation-id'], - 'type': 'object'}, - 'GenerationResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'generation': {'$ref': '#/definitions/Generation'}}, - 'required': ['generation'], - 'type': 'object'}, - 'IntResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'type': 'integer'}}, - 'required': ['result'], - 'type': 'object'}}, - 'properties': {'AbortBranch': {'description': 'AbortBranch aborts the input ' - 'branch, marking it complete. ' - 'However no\n' - 'changes are made applicable to ' - 'the whole model. No units may ' - 'be assigned\n' - 'to the branch when aborting.', - 'properties': {'Params': {'$ref': '#/definitions/BranchArg'}, - 'Result': {'$ref': '#/definitions/ErrorResult'}}, - 'type': 'object'}, - 'AddBranch': {'description': 'AddBranch adds a new branch with ' - 'the input name to the model.', - 'properties': {'Params': {'$ref': '#/definitions/BranchArg'}, - 'Result': {'$ref': '#/definitions/ErrorResult'}}, - 'type': 'object'}, - 'BranchInfo': {'description': 'BranchInfo will return details ' - 'of branch identified by the ' - 'input argument,\n' - 'including units on the branch ' - 'and the configuration disjoint ' - 'with the\n' - 'master generation.\n' - 'An error is returned if no ' - 'in-flight branch matching in ' - 'input is found.', - 'properties': {'Params': {'$ref': '#/definitions/BranchInfoArgs'}, - 'Result': {'$ref': '#/definitions/BranchResults'}}, - 'type': 'object'}, - 'CommitBranch': {'description': 'CommitBranch commits the ' - 'input branch, making its ' - 'changes applicable to\n' - 'the whole model and marking ' - 'it complete.', - 'properties': {'Params': {'$ref': '#/definitions/BranchArg'}, - 'Result': {'$ref': '#/definitions/IntResult'}}, - 'type': 'object'}, - 'HasActiveBranch': {'description': 'HasActiveBranch returns a ' - 'true result if the input ' - 'model has an "in-flight"\n' - 'branch matching the input ' - 'name.', - 'properties': {'Params': {'$ref': '#/definitions/BranchArg'}, - 'Result': {'$ref': '#/definitions/BoolResult'}}, - 'type': 'object'}, - 'ListCommits': {'description': 'ListCommits will return the ' - 'commits, hence only branches ' - 'with generation_id higher than ' - '0', - 'properties': {'Result': {'$ref': '#/definitions/BranchResults'}}, - 'type': 'object'}, - 'ShowCommit': {'description': 'ShowCommit will return details ' - 'a commit given by its ' - 'generationId\n' - 'An error is returned if either ' - 'no branch can be found ' - 'corresponding to the generation ' - 'id.\n' - 'Or the generation id given is ' - 'below 1.', - 'properties': {'Params': {'$ref': '#/definitions/GenerationId'}, - 'Result': {'$ref': '#/definitions/GenerationResult'}}, - 'type': 'object'}, - 'TrackBranch': {'description': 'TrackBranch marks the input ' - 'units and/or applications as ' - 'tracking the input\n' - 'branch, causing them to ' - 'realise changes made under ' - 'that branch.', - 'properties': {'Params': {'$ref': '#/definitions/BranchTrackArg'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "BoolResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"type": "boolean"}, + }, + "required": ["result"], + "type": "object", + }, + "BranchArg": { + "additionalProperties": False, + "properties": {"branch": {"type": "string"}}, + "required": ["branch"], + "type": "object", + }, + "BranchInfoArgs": { + "additionalProperties": False, + "properties": { + "branches": {"items": {"type": "string"}, "type": "array"}, + "detailed": {"type": "boolean"}, + }, + "required": ["branches", "detailed"], + "type": "object", + }, + "BranchResults": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "generations": { + "items": {"$ref": "#/definitions/Generation"}, + "type": "array", + }, + }, + "required": ["generations"], + "type": "object", + }, + "BranchTrackArg": { + "additionalProperties": False, + "properties": { + "branch": {"type": "string"}, + "entities": { + "items": {"$ref": "#/definitions/Entity"}, + "type": "array", + }, + "num-units": {"type": "integer"}, + }, + "required": ["branch", "entities"], + "type": "object", + }, + "Entity": { + "additionalProperties": False, + "properties": {"tag": {"type": "string"}}, + "required": ["tag"], + "type": "object", + }, + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "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", + }, + "Generation": { + "additionalProperties": False, + "properties": { + "applications": { + "items": {"$ref": "#/definitions/GenerationApplication"}, + "type": "array", + }, + "branch": {"type": "string"}, + "completed": {"type": "integer"}, + "completed-by": {"type": "string"}, + "created": {"type": "integer"}, + "created-by": {"type": "string"}, + "generation-id": {"type": "integer"}, + }, + "required": ["branch", "created", "created-by", "applications"], + "type": "object", + }, + "GenerationApplication": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "pending": {"items": {"type": "string"}, "type": "array"}, + "progress": {"type": "string"}, + "tracking": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["application", "progress", "config"], + "type": "object", + }, + "GenerationId": { + "additionalProperties": False, + "properties": {"generation-id": {"type": "integer"}}, + "required": ["generation-id"], + "type": "object", + }, + "GenerationResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "generation": {"$ref": "#/definitions/Generation"}, + }, + "required": ["generation"], + "type": "object", + }, + "IntResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"type": "integer"}, + }, + "required": ["result"], + "type": "object", + }, + }, + "properties": { + "AbortBranch": { + "description": "AbortBranch aborts the input " + "branch, marking it complete. " + "However no\n" + "changes are made applicable to " + "the whole model. No units may " + "be assigned\n" + "to the branch when aborting.", + "properties": { + "Params": {"$ref": "#/definitions/BranchArg"}, + "Result": {"$ref": "#/definitions/ErrorResult"}, + }, + "type": "object", + }, + "AddBranch": { + "description": "AddBranch adds a new branch with " + "the input name to the model.", + "properties": { + "Params": {"$ref": "#/definitions/BranchArg"}, + "Result": {"$ref": "#/definitions/ErrorResult"}, + }, + "type": "object", + }, + "BranchInfo": { + "description": "BranchInfo will return details " + "of branch identified by the " + "input argument,\n" + "including units on the branch " + "and the configuration disjoint " + "with the\n" + "master generation.\n" + "An error is returned if no " + "in-flight branch matching in " + "input is found.", + "properties": { + "Params": {"$ref": "#/definitions/BranchInfoArgs"}, + "Result": {"$ref": "#/definitions/BranchResults"}, + }, + "type": "object", + }, + "CommitBranch": { + "description": "CommitBranch commits the " + "input branch, making its " + "changes applicable to\n" + "the whole model and marking " + "it complete.", + "properties": { + "Params": {"$ref": "#/definitions/BranchArg"}, + "Result": {"$ref": "#/definitions/IntResult"}, + }, + "type": "object", + }, + "HasActiveBranch": { + "description": "HasActiveBranch returns a " + "true result if the input " + 'model has an "in-flight"\n' + "branch matching the input " + "name.", + "properties": { + "Params": {"$ref": "#/definitions/BranchArg"}, + "Result": {"$ref": "#/definitions/BoolResult"}, + }, + "type": "object", + }, + "ListCommits": { + "description": "ListCommits will return the " + "commits, hence only branches " + "with generation_id higher than " + "0", + "properties": {"Result": {"$ref": "#/definitions/BranchResults"}}, + "type": "object", + }, + "ShowCommit": { + "description": "ShowCommit will return details " + "a commit given by its " + "generationId\n" + "An error is returned if either " + "no branch can be found " + "corresponding to the generation " + "id.\n" + "Or the generation id given is " + "below 1.", + "properties": { + "Params": {"$ref": "#/definitions/GenerationId"}, + "Result": {"$ref": "#/definitions/GenerationResult"}, + }, + "type": "object", + }, + "TrackBranch": { + "description": "TrackBranch marks the input " + "units and/or applications as " + "tracking the input\n" + "branch, causing them to " + "realise changes made under " + "that branch.", + "properties": { + "Params": {"$ref": "#/definitions/BranchTrackArg"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(ErrorResult) async def AbortBranch(self, branch=None): - ''' + """ AbortBranch aborts the input branch, marking it complete. However no changes are made applicable to the whole model. No units may be assigned to the branch when aborting. branch : str Returns -> ErrorResult - ''' + """ if branch is not None and not isinstance(branch, (bytes, str)): - raise Exception("Expected branch to be a str, received: {}".format(type(branch))) + raise Exception( + "Expected branch to be a str, received: {}".format(type(branch)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelGeneration', - request='AbortBranch', - version=4, - params=_params) - _params['branch'] = branch + msg = dict( + type="ModelGeneration", request="AbortBranch", version=4, params=_params + ) + _params["branch"] = branch reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResult) async def AddBranch(self, branch=None): - ''' + """ AddBranch adds a new branch with the input name to the model. branch : str Returns -> ErrorResult - ''' + """ if branch is not None and not isinstance(branch, (bytes, str)): - raise Exception("Expected branch to be a str, received: {}".format(type(branch))) + raise Exception( + "Expected branch to be a str, received: {}".format(type(branch)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelGeneration', - request='AddBranch', - version=4, - params=_params) - _params['branch'] = branch + msg = dict( + type="ModelGeneration", request="AddBranch", version=4, params=_params + ) + _params["branch"] = branch reply = await self.rpc(msg) return reply - - @ReturnMapping(BranchResults) async def BranchInfo(self, branches=None, detailed=None): - ''' + """ BranchInfo will return details of branch identified by the input argument, including units on the branch and the configuration disjoint with the master generation. @@ -889,123 +1219,122 @@ async def BranchInfo(self, branches=None, detailed=None): branches : typing.Sequence[str] detailed : bool Returns -> BranchResults - ''' + """ if branches is not None and not isinstance(branches, (bytes, str, list)): - raise Exception("Expected branches to be a Sequence, received: {}".format(type(branches))) + raise Exception( + "Expected branches to be a Sequence, received: {}".format( + type(branches) + ) + ) if detailed is not None and not isinstance(detailed, bool): - raise Exception("Expected detailed to be a bool, received: {}".format(type(detailed))) + raise Exception( + "Expected detailed to be a bool, received: {}".format(type(detailed)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelGeneration', - request='BranchInfo', - version=4, - params=_params) - _params['branches'] = branches - _params['detailed'] = detailed + msg = dict( + type="ModelGeneration", request="BranchInfo", version=4, params=_params + ) + _params["branches"] = branches + _params["detailed"] = detailed reply = await self.rpc(msg) return reply - - @ReturnMapping(IntResult) async def CommitBranch(self, branch=None): - ''' + """ CommitBranch commits the input branch, making its changes applicable to the whole model and marking it complete. branch : str Returns -> IntResult - ''' + """ if branch is not None and not isinstance(branch, (bytes, str)): - raise Exception("Expected branch to be a str, received: {}".format(type(branch))) + raise Exception( + "Expected branch to be a str, received: {}".format(type(branch)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelGeneration', - request='CommitBranch', - version=4, - params=_params) - _params['branch'] = branch + msg = dict( + type="ModelGeneration", request="CommitBranch", version=4, params=_params + ) + _params["branch"] = branch reply = await self.rpc(msg) return reply - - @ReturnMapping(BoolResult) async def HasActiveBranch(self, branch=None): - ''' + """ HasActiveBranch returns a true result if the input model has an "in-flight" branch matching the input name. branch : str Returns -> BoolResult - ''' + """ if branch is not None and not isinstance(branch, (bytes, str)): - raise Exception("Expected branch to be a str, received: {}".format(type(branch))) + raise Exception( + "Expected branch to be a str, received: {}".format(type(branch)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelGeneration', - request='HasActiveBranch', - version=4, - params=_params) - _params['branch'] = branch + msg = dict( + type="ModelGeneration", request="HasActiveBranch", version=4, params=_params + ) + _params["branch"] = branch reply = await self.rpc(msg) return reply - - @ReturnMapping(BranchResults) async def ListCommits(self): - ''' + """ ListCommits will return the commits, hence only branches with generation_id higher than 0 Returns -> BranchResults - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='ModelGeneration', - request='ListCommits', - version=4, - params=_params) + msg = dict( + type="ModelGeneration", request="ListCommits", version=4, params=_params + ) reply = await self.rpc(msg) return reply - - @ReturnMapping(GenerationResult) async def ShowCommit(self, generation_id=None): - ''' + """ ShowCommit will return details a commit given by its generationId An error is returned if either no branch can be found corresponding to the generation id. Or the generation id given is below 1. generation_id : int Returns -> GenerationResult - ''' + """ if generation_id is not None and not isinstance(generation_id, int): - raise Exception("Expected generation_id to be a int, received: {}".format(type(generation_id))) + raise Exception( + "Expected generation_id to be a int, received: {}".format( + type(generation_id) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelGeneration', - request='ShowCommit', - version=4, - params=_params) - _params['generation-id'] = generation_id + msg = dict( + type="ModelGeneration", request="ShowCommit", version=4, params=_params + ) + _params["generation-id"] = generation_id reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def TrackBranch(self, branch=None, entities=None, num_units=None): - ''' + """ TrackBranch marks the input units and/or applications as tracking the input branch, causing them to realise changes made under that branch. @@ -1013,299 +1342,377 @@ async def TrackBranch(self, branch=None, entities=None, num_units=None): entities : typing.Sequence[~Entity] num_units : int Returns -> ErrorResults - ''' + """ if branch is not None and not isinstance(branch, (bytes, str)): - raise Exception("Expected branch to be a str, received: {}".format(type(branch))) + raise Exception( + "Expected branch to be a str, received: {}".format(type(branch)) + ) if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) if num_units is not None and not isinstance(num_units, int): - raise Exception("Expected num_units to be a int, received: {}".format(type(num_units))) + raise Exception( + "Expected num_units to be a int, received: {}".format(type(num_units)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelGeneration', - request='TrackBranch', - version=4, - params=_params) - _params['branch'] = branch - _params['entities'] = entities - _params['num-units'] = num_units + msg = dict( + type="ModelGeneration", request="TrackBranch", version=4, params=_params + ) + _params["branch"] = branch + _params["entities"] = entities + _params["num-units"] = num_units reply = await self.rpc(msg) return reply - class SSHClientFacade(Type): - name = 'SSHClient' + name = "SSHClient" version = 4 - schema = {'definitions': {'CloudCredential': {'additionalProperties': False, - 'properties': {'attrs': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - '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'}, - 'is-controller-cloud': {'type': 'boolean'}, - 'name': {'type': 'string'}, - 'region': {'type': 'string'}, - 'skip-tls-verify': {'type': 'boolean'}, - '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'}, - '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'}, - 'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - 'type': 'object'}, - 'SSHAddressResult': {'additionalProperties': False, - 'properties': {'address': {'type': 'string'}, - 'error': {'$ref': '#/definitions/Error'}}, - 'type': 'object'}, - 'SSHAddressResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/SSHAddressResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'SSHAddressesResult': {'additionalProperties': False, - 'properties': {'addresses': {'items': {'type': 'string'}, - 'type': 'array'}, - 'error': {'$ref': '#/definitions/Error'}}, - 'required': ['addresses'], - 'type': 'object'}, - 'SSHAddressesResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/SSHAddressesResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'SSHProxyResult': {'additionalProperties': False, - 'properties': {'use-proxy': {'type': 'boolean'}}, - 'required': ['use-proxy'], - 'type': 'object'}, - 'SSHPublicKeysResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'public-keys': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'SSHPublicKeysResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/SSHPublicKeysResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}}, - 'properties': {'AllAddresses': {'description': 'AllAddresses reports all ' - 'addresses that might have SSH ' - 'listening for each\n' - 'entity in args. The result is ' - 'sorted with public addresses ' - 'first.\n' - 'Machines and units are ' - 'supported as entity types.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/SSHAddressesResults'}}, - 'type': 'object'}, - 'ModelCredentialForSSH': {'description': 'ModelCredentialForSSH ' - 'returns a cloud spec ' - 'for ssh purpose.\n' - 'This facade call is ' - 'only used for k8s ' - 'model.', - 'properties': {'Result': {'$ref': '#/definitions/CloudSpecResult'}}, - 'type': 'object'}, - 'PrivateAddress': {'description': 'PrivateAddress reports the ' - 'preferred private network ' - 'address for one or\n' - 'more entities. Machines and ' - 'units are supported.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/SSHAddressResults'}}, - 'type': 'object'}, - 'Proxy': {'description': 'Proxy returns whether SSH ' - 'connections should be proxied ' - 'through the\n' - 'controller hosts for the model ' - 'associated with the API connection.', - 'properties': {'Result': {'$ref': '#/definitions/SSHProxyResult'}}, - 'type': 'object'}, - 'PublicAddress': {'description': 'PublicAddress reports the ' - 'preferred public network ' - 'address for one\n' - 'or more entities. Machines ' - 'and units are supported.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/SSHAddressResults'}}, - 'type': 'object'}, - 'PublicKeys': {'description': 'PublicKeys returns the public ' - 'SSH hosts for one or more\n' - 'entities. Machines and units ' - 'are supported.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/SSHPublicKeysResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "CloudCredential": { + "additionalProperties": False, + "properties": { + "attrs": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "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"}, + "is-controller-cloud": {"type": "boolean"}, + "name": {"type": "string"}, + "region": {"type": "string"}, + "skip-tls-verify": {"type": "boolean"}, + "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", + }, + "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", + }, + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "type": "object", + }, + "SSHAddressResult": { + "additionalProperties": False, + "properties": { + "address": {"type": "string"}, + "error": {"$ref": "#/definitions/Error"}, + }, + "type": "object", + }, + "SSHAddressResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/SSHAddressResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "SSHAddressesResult": { + "additionalProperties": False, + "properties": { + "addresses": {"items": {"type": "string"}, "type": "array"}, + "error": {"$ref": "#/definitions/Error"}, + }, + "required": ["addresses"], + "type": "object", + }, + "SSHAddressesResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/SSHAddressesResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "SSHProxyResult": { + "additionalProperties": False, + "properties": {"use-proxy": {"type": "boolean"}}, + "required": ["use-proxy"], + "type": "object", + }, + "SSHPublicKeysResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "public-keys": {"items": {"type": "string"}, "type": "array"}, + }, + "type": "object", + }, + "SSHPublicKeysResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/SSHPublicKeysResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + }, + "properties": { + "AllAddresses": { + "description": "AllAddresses reports all " + "addresses that might have SSH " + "listening for each\n" + "entity in args. The result is " + "sorted with public addresses " + "first.\n" + "Machines and units are " + "supported as entity types.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/SSHAddressesResults"}, + }, + "type": "object", + }, + "ModelCredentialForSSH": { + "description": "ModelCredentialForSSH " + "returns a cloud spec " + "for ssh purpose.\n" + "This facade call is " + "only used for k8s " + "model.", + "properties": {"Result": {"$ref": "#/definitions/CloudSpecResult"}}, + "type": "object", + }, + "PrivateAddress": { + "description": "PrivateAddress reports the " + "preferred private network " + "address for one or\n" + "more entities. Machines and " + "units are supported.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/SSHAddressResults"}, + }, + "type": "object", + }, + "Proxy": { + "description": "Proxy returns whether SSH " + "connections should be proxied " + "through the\n" + "controller hosts for the model " + "associated with the API connection.", + "properties": {"Result": {"$ref": "#/definitions/SSHProxyResult"}}, + "type": "object", + }, + "PublicAddress": { + "description": "PublicAddress reports the " + "preferred public network " + "address for one\n" + "or more entities. Machines " + "and units are supported.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/SSHAddressResults"}, + }, + "type": "object", + }, + "PublicKeys": { + "description": "PublicKeys returns the public " + "SSH hosts for one or more\n" + "entities. Machines and units " + "are supported.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/SSHPublicKeysResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(SSHAddressesResults) async def AllAddresses(self, entities=None): - ''' + """ AllAddresses reports all addresses that might have SSH listening for each entity in args. The result is sorted with public addresses first. Machines and units are supported as entity types. entities : typing.Sequence[~Entity] Returns -> SSHAddressesResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='SSHClient', - request='AllAddresses', - version=4, - params=_params) - _params['entities'] = entities + msg = dict(type="SSHClient", request="AllAddresses", version=4, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(CloudSpecResult) async def ModelCredentialForSSH(self): - ''' + """ ModelCredentialForSSH returns a cloud spec for ssh purpose. This facade call is only used for k8s model. Returns -> CloudSpecResult - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='SSHClient', - request='ModelCredentialForSSH', - version=4, - params=_params) + msg = dict( + type="SSHClient", request="ModelCredentialForSSH", version=4, params=_params + ) reply = await self.rpc(msg) return reply - - @ReturnMapping(SSHAddressResults) async def PrivateAddress(self, entities=None): - ''' + """ PrivateAddress reports the preferred private network address for one or more entities. Machines and units are supported. entities : typing.Sequence[~Entity] Returns -> SSHAddressResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='SSHClient', - request='PrivateAddress', - version=4, - params=_params) - _params['entities'] = entities + msg = dict( + type="SSHClient", request="PrivateAddress", version=4, params=_params + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(SSHProxyResult) async def Proxy(self): - ''' + """ Proxy returns whether SSH connections should be proxied through the controller hosts for the model associated with the API connection. Returns -> SSHProxyResult - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='SSHClient', - request='Proxy', - version=4, - params=_params) + msg = dict(type="SSHClient", request="Proxy", version=4, params=_params) reply = await self.rpc(msg) return reply - - @ReturnMapping(SSHAddressResults) async def PublicAddress(self, entities=None): - ''' + """ PublicAddress reports the preferred public network address for one or more entities. Machines and units are supported. entities : typing.Sequence[~Entity] Returns -> SSHAddressResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='SSHClient', - request='PublicAddress', - version=4, - params=_params) - _params['entities'] = entities + msg = dict(type="SSHClient", request="PublicAddress", version=4, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(SSHPublicKeysResults) async def PublicKeys(self, entities=None): - ''' + """ PublicKeys returns the public SSH hosts for one or more entities. Machines and units are supported. entities : typing.Sequence[~Entity] Returns -> SSHPublicKeysResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='SSHClient', - request='PublicKeys', - version=4, - params=_params) - _params['entities'] = entities + msg = dict(type="SSHClient", request="PublicKeys", version=4, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - diff --git a/juju/client/_client5.py b/juju/client/_client5.py index dff0e09cb..633c2bd25 100644 --- a/juju/client/_client5.py +++ b/juju/client/_client5.py @@ -6,720 +6,990 @@ class ApplicationOffersFacade(Type): - name = 'ApplicationOffers' + name = "ApplicationOffers" version = 5 - schema = {'definitions': {'AddApplicationOffer': {'additionalProperties': False, - 'properties': {'application-description': {'type': 'string'}, - 'application-name': {'type': 'string'}, - 'endpoints': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'model-tag': {'type': 'string'}, - 'offer-name': {'type': 'string'}, - 'owner-tag': {'type': 'string'}}, - 'required': ['model-tag', - 'offer-name', - 'application-name', - 'application-description', - 'endpoints'], - 'type': 'object'}, - 'AddApplicationOffers': {'additionalProperties': False, - 'properties': {'Offers': {'items': {'$ref': '#/definitions/AddApplicationOffer'}, - 'type': 'array'}}, - 'required': ['Offers'], - 'type': 'object'}, - 'ApplicationOfferAdminDetailsV5': {'additionalProperties': False, - 'properties': {'ApplicationOfferDetailsV5': {'$ref': '#/definitions/ApplicationOfferDetailsV5'}, - 'application-description': {'type': 'string'}, - 'application-name': {'type': 'string'}, - 'charm-url': {'type': 'string'}, - 'connections': {'items': {'$ref': '#/definitions/OfferConnection'}, - 'type': 'array'}, - 'endpoints': {'items': {'$ref': '#/definitions/RemoteEndpoint'}, - 'type': 'array'}, - 'offer-name': {'type': 'string'}, - 'offer-url': {'type': 'string'}, - 'offer-uuid': {'type': 'string'}, - 'source-model-tag': {'type': 'string'}, - 'users': {'items': {'$ref': '#/definitions/OfferUserDetails'}, - 'type': 'array'}}, - 'required': ['source-model-tag', - 'offer-uuid', - 'offer-url', - 'offer-name', - 'application-description', - 'ApplicationOfferDetailsV5', - 'application-name', - 'charm-url'], - 'type': 'object'}, - 'ApplicationOfferDetailsV5': {'additionalProperties': False, - 'properties': {'application-description': {'type': 'string'}, - 'endpoints': {'items': {'$ref': '#/definitions/RemoteEndpoint'}, - 'type': 'array'}, - 'offer-name': {'type': 'string'}, - 'offer-url': {'type': 'string'}, - 'offer-uuid': {'type': 'string'}, - 'source-model-tag': {'type': 'string'}, - 'users': {'items': {'$ref': '#/definitions/OfferUserDetails'}, - 'type': 'array'}}, - 'required': ['source-model-tag', - 'offer-uuid', - 'offer-url', - 'offer-name', - 'application-description'], - 'type': 'object'}, - 'ApplicationOfferResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/ApplicationOfferAdminDetailsV5'}}, - 'type': 'object'}, - 'ApplicationOffersResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ApplicationOfferResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'ConsumeOfferDetails': {'additionalProperties': False, - 'properties': {'external-controller': {'$ref': '#/definitions/ExternalControllerInfo'}, - 'macaroon': {'$ref': '#/definitions/Macaroon'}, - 'offer': {'$ref': '#/definitions/ApplicationOfferDetailsV5'}}, - 'type': 'object'}, - 'ConsumeOfferDetailsArg': {'additionalProperties': False, - 'properties': {'offer-urls': {'$ref': '#/definitions/OfferURLs'}, - 'user-tag': {'type': 'string'}}, - 'required': ['offer-urls'], - 'type': 'object'}, - 'ConsumeOfferDetailsResult': {'additionalProperties': False, - 'properties': {'ConsumeOfferDetails': {'$ref': '#/definitions/ConsumeOfferDetails'}, - 'error': {'$ref': '#/definitions/Error'}, - 'external-controller': {'$ref': '#/definitions/ExternalControllerInfo'}, - 'macaroon': {'$ref': '#/definitions/Macaroon'}, - 'offer': {'$ref': '#/definitions/ApplicationOfferDetailsV5'}}, - 'required': ['ConsumeOfferDetails'], - 'type': 'object'}, - 'ConsumeOfferDetailsResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ConsumeOfferDetailsResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'DestroyApplicationOffers': {'additionalProperties': False, - 'properties': {'force': {'type': 'boolean'}, - 'offer-urls': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['offer-urls'], - 'type': 'object'}, - 'EndpointFilterAttributes': {'additionalProperties': False, - 'properties': {'interface': {'type': 'string'}, - 'name': {'type': 'string'}, - 'role': {'type': 'string'}}, - 'required': ['role', - 'interface', - 'name'], - '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': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - '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'}, - 'ExternalControllerInfo': {'additionalProperties': False, - 'properties': {'addrs': {'items': {'type': 'string'}, - 'type': 'array'}, - 'ca-cert': {'type': 'string'}, - 'controller-alias': {'type': 'string'}, - 'controller-tag': {'type': 'string'}}, - 'required': ['controller-tag', - 'controller-alias', - 'addrs', - 'ca-cert'], - 'type': 'object'}, - 'Macaroon': {'additionalProperties': False, 'type': 'object'}, - 'ModifyOfferAccess': {'additionalProperties': False, - 'properties': {'access': {'type': 'string'}, - 'action': {'type': 'string'}, - 'offer-url': {'type': 'string'}, - 'user-tag': {'type': 'string'}}, - 'required': ['user-tag', - 'action', - 'access', - 'offer-url'], - 'type': 'object'}, - 'ModifyOfferAccessRequest': {'additionalProperties': False, - 'properties': {'changes': {'items': {'$ref': '#/definitions/ModifyOfferAccess'}, - 'type': 'array'}}, - 'required': ['changes'], - 'type': 'object'}, - 'OfferConnection': {'additionalProperties': False, - 'properties': {'endpoint': {'type': 'string'}, - 'ingress-subnets': {'items': {'type': 'string'}, - 'type': 'array'}, - 'relation-id': {'type': 'integer'}, - 'source-model-tag': {'type': 'string'}, - 'status': {'$ref': '#/definitions/EntityStatus'}, - 'username': {'type': 'string'}}, - 'required': ['source-model-tag', - 'relation-id', - 'username', - 'endpoint', - 'status', - 'ingress-subnets'], - 'type': 'object'}, - 'OfferFilter': {'additionalProperties': False, - 'properties': {'allowed-users': {'items': {'type': 'string'}, - 'type': 'array'}, - 'application-description': {'type': 'string'}, - 'application-name': {'type': 'string'}, - 'application-user': {'type': 'string'}, - 'connected-users': {'items': {'type': 'string'}, - 'type': 'array'}, - 'endpoints': {'items': {'$ref': '#/definitions/EndpointFilterAttributes'}, - 'type': 'array'}, - 'model-name': {'type': 'string'}, - 'offer-name': {'type': 'string'}, - 'owner-name': {'type': 'string'}}, - 'required': ['owner-name', - 'model-name', - 'offer-name', - 'application-name', - 'application-description', - 'application-user', - 'endpoints', - 'connected-users', - 'allowed-users'], - 'type': 'object'}, - 'OfferFilters': {'additionalProperties': False, - 'properties': {'Filters': {'items': {'$ref': '#/definitions/OfferFilter'}, - 'type': 'array'}}, - 'required': ['Filters'], - 'type': 'object'}, - 'OfferURLs': {'additionalProperties': False, - 'properties': {'bakery-version': {'type': 'integer'}, - 'offer-urls': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'OfferUserDetails': {'additionalProperties': False, - 'properties': {'access': {'type': 'string'}, - 'display-name': {'type': 'string'}, - 'user': {'type': 'string'}}, - 'required': ['user', - 'display-name', - 'access'], - 'type': 'object'}, - 'QueryApplicationOffersResultsV5': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ApplicationOfferAdminDetailsV5'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'RemoteApplicationInfo': {'additionalProperties': False, - 'properties': {'description': {'type': 'string'}, - 'endpoints': {'items': {'$ref': '#/definitions/RemoteEndpoint'}, - 'type': 'array'}, - 'icon-url-path': {'type': 'string'}, - 'model-tag': {'type': 'string'}, - 'name': {'type': 'string'}, - 'offer-url': {'type': 'string'}, - 'source-model-label': {'type': 'string'}}, - 'required': ['model-tag', - 'name', - 'description', - 'offer-url', - 'endpoints', - 'icon-url-path'], - 'type': 'object'}, - 'RemoteApplicationInfoResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/RemoteApplicationInfo'}}, - 'type': 'object'}, - 'RemoteApplicationInfoResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/RemoteApplicationInfoResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'RemoteEndpoint': {'additionalProperties': False, - 'properties': {'interface': {'type': 'string'}, - 'limit': {'type': 'integer'}, - 'name': {'type': 'string'}, - 'role': {'type': 'string'}}, - 'required': ['name', - 'role', - 'interface', - 'limit'], - 'type': 'object'}}, - 'properties': {'ApplicationOffers': {'description': 'ApplicationOffers gets ' - 'details about remote ' - 'applications that match ' - 'given URLs.', - 'properties': {'Params': {'$ref': '#/definitions/OfferURLs'}, - 'Result': {'$ref': '#/definitions/ApplicationOffersResults'}}, - 'type': 'object'}, - 'DestroyOffers': {'description': 'DestroyOffers removes the ' - 'offers specified by the ' - 'given URLs, forcing if ' - 'necessary.', - 'properties': {'Params': {'$ref': '#/definitions/DestroyApplicationOffers'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'FindApplicationOffers': {'description': 'FindApplicationOffers ' - 'gets details about ' - 'remote applications ' - 'that match given ' - 'filter.', - 'properties': {'Params': {'$ref': '#/definitions/OfferFilters'}, - 'Result': {'$ref': '#/definitions/QueryApplicationOffersResultsV5'}}, - 'type': 'object'}, - 'GetConsumeDetails': {'description': 'GetConsumeDetails ' - 'returns the details ' - 'necessary to pass to ' - 'another model\n' - 'to allow the specified ' - 'args user to consume the ' - 'offers represented by ' - 'the args URLs.', - 'properties': {'Params': {'$ref': '#/definitions/ConsumeOfferDetailsArg'}, - 'Result': {'$ref': '#/definitions/ConsumeOfferDetailsResults'}}, - 'type': 'object'}, - 'ListApplicationOffers': {'description': 'ListApplicationOffers ' - 'gets deployed ' - 'details about ' - 'application offers ' - 'that match given ' - 'filter.\n' - 'The results contain ' - 'details about the ' - 'deployed ' - 'applications such as ' - 'connection count.', - 'properties': {'Params': {'$ref': '#/definitions/OfferFilters'}, - 'Result': {'$ref': '#/definitions/QueryApplicationOffersResultsV5'}}, - 'type': 'object'}, - 'ModifyOfferAccess': {'description': 'ModifyOfferAccess ' - 'changes the application ' - 'offer access granted to ' - 'users.', - 'properties': {'Params': {'$ref': '#/definitions/ModifyOfferAccessRequest'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'Offer': {'description': 'Offer makes application endpoints ' - 'available for consumption at a ' - 'specified URL.', - 'properties': {'Params': {'$ref': '#/definitions/AddApplicationOffers'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'RemoteApplicationInfo': {'description': 'RemoteApplicationInfo ' - 'returns information ' - 'about the requested ' - 'remote application.\n' - 'This call currently ' - 'has no client side ' - 'API, only there for ' - 'the Dashboard at ' - 'this stage.', - 'properties': {'Params': {'$ref': '#/definitions/OfferURLs'}, - 'Result': {'$ref': '#/definitions/RemoteApplicationInfoResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "AddApplicationOffer": { + "additionalProperties": False, + "properties": { + "application-description": {"type": "string"}, + "application-name": {"type": "string"}, + "endpoints": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "model-tag": {"type": "string"}, + "offer-name": {"type": "string"}, + "owner-tag": {"type": "string"}, + }, + "required": [ + "model-tag", + "offer-name", + "application-name", + "application-description", + "endpoints", + ], + "type": "object", + }, + "AddApplicationOffers": { + "additionalProperties": False, + "properties": { + "Offers": { + "items": {"$ref": "#/definitions/AddApplicationOffer"}, + "type": "array", + } + }, + "required": ["Offers"], + "type": "object", + }, + "ApplicationOfferAdminDetailsV5": { + "additionalProperties": False, + "properties": { + "ApplicationOfferDetailsV5": { + "$ref": "#/definitions/ApplicationOfferDetailsV5" + }, + "application-description": {"type": "string"}, + "application-name": {"type": "string"}, + "charm-url": {"type": "string"}, + "connections": { + "items": {"$ref": "#/definitions/OfferConnection"}, + "type": "array", + }, + "endpoints": { + "items": {"$ref": "#/definitions/RemoteEndpoint"}, + "type": "array", + }, + "offer-name": {"type": "string"}, + "offer-url": {"type": "string"}, + "offer-uuid": {"type": "string"}, + "source-model-tag": {"type": "string"}, + "users": { + "items": {"$ref": "#/definitions/OfferUserDetails"}, + "type": "array", + }, + }, + "required": [ + "source-model-tag", + "offer-uuid", + "offer-url", + "offer-name", + "application-description", + "ApplicationOfferDetailsV5", + "application-name", + "charm-url", + ], + "type": "object", + }, + "ApplicationOfferDetailsV5": { + "additionalProperties": False, + "properties": { + "application-description": {"type": "string"}, + "endpoints": { + "items": {"$ref": "#/definitions/RemoteEndpoint"}, + "type": "array", + }, + "offer-name": {"type": "string"}, + "offer-url": {"type": "string"}, + "offer-uuid": {"type": "string"}, + "source-model-tag": {"type": "string"}, + "users": { + "items": {"$ref": "#/definitions/OfferUserDetails"}, + "type": "array", + }, + }, + "required": [ + "source-model-tag", + "offer-uuid", + "offer-url", + "offer-name", + "application-description", + ], + "type": "object", + }, + "ApplicationOfferResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/ApplicationOfferAdminDetailsV5"}, + }, + "type": "object", + }, + "ApplicationOffersResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ApplicationOfferResult"}, + "type": "array", + } + }, + "type": "object", + }, + "ConsumeOfferDetails": { + "additionalProperties": False, + "properties": { + "external-controller": { + "$ref": "#/definitions/ExternalControllerInfo" + }, + "macaroon": {"$ref": "#/definitions/Macaroon"}, + "offer": {"$ref": "#/definitions/ApplicationOfferDetailsV5"}, + }, + "type": "object", + }, + "ConsumeOfferDetailsArg": { + "additionalProperties": False, + "properties": { + "offer-urls": {"$ref": "#/definitions/OfferURLs"}, + "user-tag": {"type": "string"}, + }, + "required": ["offer-urls"], + "type": "object", + }, + "ConsumeOfferDetailsResult": { + "additionalProperties": False, + "properties": { + "ConsumeOfferDetails": { + "$ref": "#/definitions/ConsumeOfferDetails" + }, + "error": {"$ref": "#/definitions/Error"}, + "external-controller": { + "$ref": "#/definitions/ExternalControllerInfo" + }, + "macaroon": {"$ref": "#/definitions/Macaroon"}, + "offer": {"$ref": "#/definitions/ApplicationOfferDetailsV5"}, + }, + "required": ["ConsumeOfferDetails"], + "type": "object", + }, + "ConsumeOfferDetailsResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ConsumeOfferDetailsResult"}, + "type": "array", + } + }, + "type": "object", + }, + "DestroyApplicationOffers": { + "additionalProperties": False, + "properties": { + "force": {"type": "boolean"}, + "offer-urls": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["offer-urls"], + "type": "object", + }, + "EndpointFilterAttributes": { + "additionalProperties": False, + "properties": { + "interface": {"type": "string"}, + "name": {"type": "string"}, + "role": {"type": "string"}, + }, + "required": ["role", "interface", "name"], + "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": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "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", + }, + "ExternalControllerInfo": { + "additionalProperties": False, + "properties": { + "addrs": {"items": {"type": "string"}, "type": "array"}, + "ca-cert": {"type": "string"}, + "controller-alias": {"type": "string"}, + "controller-tag": {"type": "string"}, + }, + "required": ["controller-tag", "controller-alias", "addrs", "ca-cert"], + "type": "object", + }, + "Macaroon": {"additionalProperties": False, "type": "object"}, + "ModifyOfferAccess": { + "additionalProperties": False, + "properties": { + "access": {"type": "string"}, + "action": {"type": "string"}, + "offer-url": {"type": "string"}, + "user-tag": {"type": "string"}, + }, + "required": ["user-tag", "action", "access", "offer-url"], + "type": "object", + }, + "ModifyOfferAccessRequest": { + "additionalProperties": False, + "properties": { + "changes": { + "items": {"$ref": "#/definitions/ModifyOfferAccess"}, + "type": "array", + } + }, + "required": ["changes"], + "type": "object", + }, + "OfferConnection": { + "additionalProperties": False, + "properties": { + "endpoint": {"type": "string"}, + "ingress-subnets": {"items": {"type": "string"}, "type": "array"}, + "relation-id": {"type": "integer"}, + "source-model-tag": {"type": "string"}, + "status": {"$ref": "#/definitions/EntityStatus"}, + "username": {"type": "string"}, + }, + "required": [ + "source-model-tag", + "relation-id", + "username", + "endpoint", + "status", + "ingress-subnets", + ], + "type": "object", + }, + "OfferFilter": { + "additionalProperties": False, + "properties": { + "allowed-users": {"items": {"type": "string"}, "type": "array"}, + "application-description": {"type": "string"}, + "application-name": {"type": "string"}, + "application-user": {"type": "string"}, + "connected-users": {"items": {"type": "string"}, "type": "array"}, + "endpoints": { + "items": {"$ref": "#/definitions/EndpointFilterAttributes"}, + "type": "array", + }, + "model-name": {"type": "string"}, + "offer-name": {"type": "string"}, + "owner-name": {"type": "string"}, + }, + "required": [ + "owner-name", + "model-name", + "offer-name", + "application-name", + "application-description", + "application-user", + "endpoints", + "connected-users", + "allowed-users", + ], + "type": "object", + }, + "OfferFilters": { + "additionalProperties": False, + "properties": { + "Filters": { + "items": {"$ref": "#/definitions/OfferFilter"}, + "type": "array", + } + }, + "required": ["Filters"], + "type": "object", + }, + "OfferURLs": { + "additionalProperties": False, + "properties": { + "bakery-version": {"type": "integer"}, + "offer-urls": {"items": {"type": "string"}, "type": "array"}, + }, + "type": "object", + }, + "OfferUserDetails": { + "additionalProperties": False, + "properties": { + "access": {"type": "string"}, + "display-name": {"type": "string"}, + "user": {"type": "string"}, + }, + "required": ["user", "display-name", "access"], + "type": "object", + }, + "QueryApplicationOffersResultsV5": { + "additionalProperties": False, + "properties": { + "results": { + "items": { + "$ref": "#/definitions/ApplicationOfferAdminDetailsV5" + }, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "RemoteApplicationInfo": { + "additionalProperties": False, + "properties": { + "description": {"type": "string"}, + "endpoints": { + "items": {"$ref": "#/definitions/RemoteEndpoint"}, + "type": "array", + }, + "icon-url-path": {"type": "string"}, + "model-tag": {"type": "string"}, + "name": {"type": "string"}, + "offer-url": {"type": "string"}, + "source-model-label": {"type": "string"}, + }, + "required": [ + "model-tag", + "name", + "description", + "offer-url", + "endpoints", + "icon-url-path", + ], + "type": "object", + }, + "RemoteApplicationInfoResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/RemoteApplicationInfo"}, + }, + "type": "object", + }, + "RemoteApplicationInfoResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/RemoteApplicationInfoResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "RemoteEndpoint": { + "additionalProperties": False, + "properties": { + "interface": {"type": "string"}, + "limit": {"type": "integer"}, + "name": {"type": "string"}, + "role": {"type": "string"}, + }, + "required": ["name", "role", "interface", "limit"], + "type": "object", + }, + }, + "properties": { + "ApplicationOffers": { + "description": "ApplicationOffers gets " + "details about remote " + "applications that match " + "given URLs.", + "properties": { + "Params": {"$ref": "#/definitions/OfferURLs"}, + "Result": {"$ref": "#/definitions/ApplicationOffersResults"}, + }, + "type": "object", + }, + "DestroyOffers": { + "description": "DestroyOffers removes the " + "offers specified by the " + "given URLs, forcing if " + "necessary.", + "properties": { + "Params": {"$ref": "#/definitions/DestroyApplicationOffers"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "FindApplicationOffers": { + "description": "FindApplicationOffers " + "gets details about " + "remote applications " + "that match given " + "filter.", + "properties": { + "Params": {"$ref": "#/definitions/OfferFilters"}, + "Result": {"$ref": "#/definitions/QueryApplicationOffersResultsV5"}, + }, + "type": "object", + }, + "GetConsumeDetails": { + "description": "GetConsumeDetails " + "returns the details " + "necessary to pass to " + "another model\n" + "to allow the specified " + "args user to consume the " + "offers represented by " + "the args URLs.", + "properties": { + "Params": {"$ref": "#/definitions/ConsumeOfferDetailsArg"}, + "Result": {"$ref": "#/definitions/ConsumeOfferDetailsResults"}, + }, + "type": "object", + }, + "ListApplicationOffers": { + "description": "ListApplicationOffers " + "gets deployed " + "details about " + "application offers " + "that match given " + "filter.\n" + "The results contain " + "details about the " + "deployed " + "applications such as " + "connection count.", + "properties": { + "Params": {"$ref": "#/definitions/OfferFilters"}, + "Result": {"$ref": "#/definitions/QueryApplicationOffersResultsV5"}, + }, + "type": "object", + }, + "ModifyOfferAccess": { + "description": "ModifyOfferAccess " + "changes the application " + "offer access granted to " + "users.", + "properties": { + "Params": {"$ref": "#/definitions/ModifyOfferAccessRequest"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "Offer": { + "description": "Offer makes application endpoints " + "available for consumption at a " + "specified URL.", + "properties": { + "Params": {"$ref": "#/definitions/AddApplicationOffers"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "RemoteApplicationInfo": { + "description": "RemoteApplicationInfo " + "returns information " + "about the requested " + "remote application.\n" + "This call currently " + "has no client side " + "API, only there for " + "the Dashboard at " + "this stage.", + "properties": { + "Params": {"$ref": "#/definitions/OfferURLs"}, + "Result": {"$ref": "#/definitions/RemoteApplicationInfoResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(ApplicationOffersResults) async def ApplicationOffers(self, bakery_version=None, offer_urls=None): - ''' + """ ApplicationOffers gets details about remote applications that match given URLs. bakery_version : int offer_urls : typing.Sequence[str] Returns -> ApplicationOffersResults - ''' + """ if bakery_version is not None and not isinstance(bakery_version, int): - raise Exception("Expected bakery_version to be a int, received: {}".format(type(bakery_version))) + raise Exception( + "Expected bakery_version to be a int, received: {}".format( + type(bakery_version) + ) + ) if offer_urls is not None and not isinstance(offer_urls, (bytes, str, list)): - raise Exception("Expected offer_urls to be a Sequence, received: {}".format(type(offer_urls))) + raise Exception( + "Expected offer_urls to be a Sequence, received: {}".format( + type(offer_urls) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ApplicationOffers', - request='ApplicationOffers', - version=5, - params=_params) - _params['bakery-version'] = bakery_version - _params['offer-urls'] = offer_urls + msg = dict( + type="ApplicationOffers", + request="ApplicationOffers", + version=5, + params=_params, + ) + _params["bakery-version"] = bakery_version + _params["offer-urls"] = offer_urls reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def DestroyOffers(self, force=None, offer_urls=None): - ''' + """ DestroyOffers removes the offers specified by the given URLs, forcing if necessary. force : bool offer_urls : typing.Sequence[str] Returns -> ErrorResults - ''' + """ if force is not None and not isinstance(force, bool): - raise Exception("Expected force to be a bool, received: {}".format(type(force))) + raise Exception( + "Expected force to be a bool, received: {}".format(type(force)) + ) if offer_urls is not None and not isinstance(offer_urls, (bytes, str, list)): - raise Exception("Expected offer_urls to be a Sequence, received: {}".format(type(offer_urls))) + raise Exception( + "Expected offer_urls to be a Sequence, received: {}".format( + type(offer_urls) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ApplicationOffers', - request='DestroyOffers', - version=5, - params=_params) - _params['force'] = force - _params['offer-urls'] = offer_urls + msg = dict( + type="ApplicationOffers", request="DestroyOffers", version=5, params=_params + ) + _params["force"] = force + _params["offer-urls"] = offer_urls reply = await self.rpc(msg) return reply - - @ReturnMapping(QueryApplicationOffersResultsV5) async def FindApplicationOffers(self, filters=None): - ''' + """ FindApplicationOffers gets details about remote applications that match given filter. filters : typing.Sequence[~OfferFilter] Returns -> QueryApplicationOffersResultsV5 - ''' + """ if filters is not None and not isinstance(filters, (bytes, str, list)): - raise Exception("Expected filters to be a Sequence, received: {}".format(type(filters))) + raise Exception( + "Expected filters to be a Sequence, received: {}".format(type(filters)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ApplicationOffers', - request='FindApplicationOffers', - version=5, - params=_params) - _params['Filters'] = filters + msg = dict( + type="ApplicationOffers", + request="FindApplicationOffers", + version=5, + params=_params, + ) + _params["Filters"] = filters reply = await self.rpc(msg) return reply - - @ReturnMapping(ConsumeOfferDetailsResults) async def GetConsumeDetails(self, offer_urls=None, user_tag=None): - ''' + """ GetConsumeDetails returns the details necessary to pass to another model to allow the specified args user to consume the offers represented by the args URLs. offer_urls : OfferURLs user_tag : str Returns -> ConsumeOfferDetailsResults - ''' + """ if offer_urls is not None and not isinstance(offer_urls, (dict, OfferURLs)): - raise Exception("Expected offer_urls to be a OfferURLs, received: {}".format(type(offer_urls))) + raise Exception( + "Expected offer_urls to be a OfferURLs, received: {}".format( + type(offer_urls) + ) + ) if user_tag is not None and not isinstance(user_tag, (bytes, str)): - raise Exception("Expected user_tag to be a str, received: {}".format(type(user_tag))) + raise Exception( + "Expected user_tag to be a str, received: {}".format(type(user_tag)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ApplicationOffers', - request='GetConsumeDetails', - version=5, - params=_params) - _params['offer-urls'] = offer_urls - _params['user-tag'] = user_tag + msg = dict( + type="ApplicationOffers", + request="GetConsumeDetails", + version=5, + params=_params, + ) + _params["offer-urls"] = offer_urls + _params["user-tag"] = user_tag reply = await self.rpc(msg) return reply - - @ReturnMapping(QueryApplicationOffersResultsV5) async def ListApplicationOffers(self, filters=None): - ''' + """ ListApplicationOffers gets deployed details about application offers that match given filter. The results contain details about the deployed applications such as connection count. filters : typing.Sequence[~OfferFilter] Returns -> QueryApplicationOffersResultsV5 - ''' + """ if filters is not None and not isinstance(filters, (bytes, str, list)): - raise Exception("Expected filters to be a Sequence, received: {}".format(type(filters))) + raise Exception( + "Expected filters to be a Sequence, received: {}".format(type(filters)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ApplicationOffers', - request='ListApplicationOffers', - version=5, - params=_params) - _params['Filters'] = filters + msg = dict( + type="ApplicationOffers", + request="ListApplicationOffers", + version=5, + params=_params, + ) + _params["Filters"] = filters reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def ModifyOfferAccess(self, changes=None): - ''' + """ ModifyOfferAccess changes the application offer access granted to users. changes : typing.Sequence[~ModifyOfferAccess] Returns -> ErrorResults - ''' + """ if changes is not None and not isinstance(changes, (bytes, str, list)): - raise Exception("Expected changes to be a Sequence, received: {}".format(type(changes))) + raise Exception( + "Expected changes to be a Sequence, received: {}".format(type(changes)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ApplicationOffers', - request='ModifyOfferAccess', - version=5, - params=_params) - _params['changes'] = changes + msg = dict( + type="ApplicationOffers", + request="ModifyOfferAccess", + version=5, + params=_params, + ) + _params["changes"] = changes reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def Offer(self, offers=None): - ''' + """ Offer makes application endpoints available for consumption at a specified URL. offers : typing.Sequence[~AddApplicationOffer] Returns -> ErrorResults - ''' + """ if offers is not None and not isinstance(offers, (bytes, str, list)): - raise Exception("Expected offers to be a Sequence, received: {}".format(type(offers))) + raise Exception( + "Expected offers to be a Sequence, received: {}".format(type(offers)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ApplicationOffers', - request='Offer', - version=5, - params=_params) - _params['Offers'] = offers + msg = dict(type="ApplicationOffers", request="Offer", version=5, params=_params) + _params["Offers"] = offers reply = await self.rpc(msg) return reply - - @ReturnMapping(RemoteApplicationInfoResults) async def RemoteApplicationInfo(self, bakery_version=None, offer_urls=None): - ''' + """ RemoteApplicationInfo returns information about the requested remote application. This call currently has no client side API, only there for the Dashboard at this stage. bakery_version : int offer_urls : typing.Sequence[str] Returns -> RemoteApplicationInfoResults - ''' + """ if bakery_version is not None and not isinstance(bakery_version, int): - raise Exception("Expected bakery_version to be a int, received: {}".format(type(bakery_version))) + raise Exception( + "Expected bakery_version to be a int, received: {}".format( + type(bakery_version) + ) + ) if offer_urls is not None and not isinstance(offer_urls, (bytes, str, list)): - raise Exception("Expected offer_urls to be a Sequence, received: {}".format(type(offer_urls))) + raise Exception( + "Expected offer_urls to be a Sequence, received: {}".format( + type(offer_urls) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ApplicationOffers', - request='RemoteApplicationInfo', - version=5, - params=_params) - _params['bakery-version'] = bakery_version - _params['offer-urls'] = offer_urls + msg = dict( + type="ApplicationOffers", + request="RemoteApplicationInfo", + version=5, + params=_params, + ) + _params["bakery-version"] = bakery_version + _params["offer-urls"] = offer_urls reply = await self.rpc(msg) return reply - class SubnetsFacade(Type): - name = 'Subnets' + name = "Subnets" version = 5 - schema = {'definitions': {'CIDRParams': {'additionalProperties': False, - 'properties': {'cidrs': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['cidrs'], - 'type': 'object'}, - 'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - 'type': 'object'}, - 'ListSubnetsResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/Subnet'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'Subnet': {'additionalProperties': False, - 'properties': {'cidr': {'type': 'string'}, - 'life': {'type': 'string'}, - 'provider-id': {'type': 'string'}, - 'provider-network-id': {'type': 'string'}, - 'provider-space-id': {'type': 'string'}, - 'space-tag': {'type': 'string'}, - 'status': {'type': 'string'}, - 'vlan-tag': {'type': 'integer'}, - 'zones': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['cidr', - 'vlan-tag', - 'life', - 'space-tag', - 'zones'], - 'type': 'object'}, - 'SubnetV2': {'additionalProperties': False, - 'properties': {'Subnet': {'$ref': '#/definitions/Subnet'}, - 'cidr': {'type': 'string'}, - 'id': {'type': 'string'}, - 'life': {'type': 'string'}, - 'provider-id': {'type': 'string'}, - 'provider-network-id': {'type': 'string'}, - 'provider-space-id': {'type': 'string'}, - 'space-tag': {'type': 'string'}, - 'status': {'type': 'string'}, - 'vlan-tag': {'type': 'integer'}, - 'zones': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['cidr', - 'vlan-tag', - 'life', - 'space-tag', - 'zones', - 'Subnet'], - 'type': 'object'}, - 'SubnetsFilters': {'additionalProperties': False, - 'properties': {'space-tag': {'type': 'string'}, - 'zone': {'type': 'string'}}, - 'type': 'object'}, - 'SubnetsResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'subnets': {'items': {'$ref': '#/definitions/SubnetV2'}, - 'type': 'array'}}, - 'type': 'object'}, - 'SubnetsResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/SubnetsResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'ZoneResult': {'additionalProperties': False, - 'properties': {'available': {'type': 'boolean'}, - 'error': {'$ref': '#/definitions/Error'}, - 'name': {'type': 'string'}}, - 'required': ['name', 'available'], - 'type': 'object'}, - 'ZoneResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ZoneResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}}, - 'properties': {'AllZones': {'description': 'AllZones returns all availability ' - 'zones known to Juju. If a\n' - 'zone is unusable, unavailable, or ' - 'deprecated the Available\n' - 'field will be false.', - 'properties': {'Result': {'$ref': '#/definitions/ZoneResults'}}, - 'type': 'object'}, - 'ListSubnets': {'description': 'ListSubnets returns the ' - 'matching subnets after ' - 'applying\n' - 'optional filters.', - 'properties': {'Params': {'$ref': '#/definitions/SubnetsFilters'}, - 'Result': {'$ref': '#/definitions/ListSubnetsResults'}}, - 'type': 'object'}, - 'SubnetsByCIDR': {'description': 'SubnetsByCIDR returns the ' - 'collection of subnets ' - 'matching each CIDR in the ' - 'input.', - 'properties': {'Params': {'$ref': '#/definitions/CIDRParams'}, - 'Result': {'$ref': '#/definitions/SubnetsResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "CIDRParams": { + "additionalProperties": False, + "properties": {"cidrs": {"items": {"type": "string"}, "type": "array"}}, + "required": ["cidrs"], + "type": "object", + }, + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "type": "object", + }, + "ListSubnetsResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/Subnet"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "Subnet": { + "additionalProperties": False, + "properties": { + "cidr": {"type": "string"}, + "life": {"type": "string"}, + "provider-id": {"type": "string"}, + "provider-network-id": {"type": "string"}, + "provider-space-id": {"type": "string"}, + "space-tag": {"type": "string"}, + "status": {"type": "string"}, + "vlan-tag": {"type": "integer"}, + "zones": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["cidr", "vlan-tag", "life", "space-tag", "zones"], + "type": "object", + }, + "SubnetV2": { + "additionalProperties": False, + "properties": { + "Subnet": {"$ref": "#/definitions/Subnet"}, + "cidr": {"type": "string"}, + "id": {"type": "string"}, + "life": {"type": "string"}, + "provider-id": {"type": "string"}, + "provider-network-id": {"type": "string"}, + "provider-space-id": {"type": "string"}, + "space-tag": {"type": "string"}, + "status": {"type": "string"}, + "vlan-tag": {"type": "integer"}, + "zones": {"items": {"type": "string"}, "type": "array"}, + }, + "required": [ + "cidr", + "vlan-tag", + "life", + "space-tag", + "zones", + "Subnet", + ], + "type": "object", + }, + "SubnetsFilters": { + "additionalProperties": False, + "properties": { + "space-tag": {"type": "string"}, + "zone": {"type": "string"}, + }, + "type": "object", + }, + "SubnetsResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "subnets": { + "items": {"$ref": "#/definitions/SubnetV2"}, + "type": "array", + }, + }, + "type": "object", + }, + "SubnetsResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/SubnetsResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "ZoneResult": { + "additionalProperties": False, + "properties": { + "available": {"type": "boolean"}, + "error": {"$ref": "#/definitions/Error"}, + "name": {"type": "string"}, + }, + "required": ["name", "available"], + "type": "object", + }, + "ZoneResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ZoneResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + }, + "properties": { + "AllZones": { + "description": "AllZones returns all availability " + "zones known to Juju. If a\n" + "zone is unusable, unavailable, or " + "deprecated the Available\n" + "field will be false.", + "properties": {"Result": {"$ref": "#/definitions/ZoneResults"}}, + "type": "object", + }, + "ListSubnets": { + "description": "ListSubnets returns the " + "matching subnets after " + "applying\n" + "optional filters.", + "properties": { + "Params": {"$ref": "#/definitions/SubnetsFilters"}, + "Result": {"$ref": "#/definitions/ListSubnetsResults"}, + }, + "type": "object", + }, + "SubnetsByCIDR": { + "description": "SubnetsByCIDR returns the " + "collection of subnets " + "matching each CIDR in the " + "input.", + "properties": { + "Params": {"$ref": "#/definitions/CIDRParams"}, + "Result": {"$ref": "#/definitions/SubnetsResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(ZoneResults) async def AllZones(self): - ''' + """ AllZones returns all availability zones known to Juju. If a zone is unusable, unavailable, or deprecated the Available field will be false. Returns -> ZoneResults - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Subnets', - request='AllZones', - version=5, - params=_params) + msg = dict(type="Subnets", request="AllZones", version=5, params=_params) reply = await self.rpc(msg) return reply - - @ReturnMapping(ListSubnetsResults) async def ListSubnets(self, space_tag=None, zone=None): - ''' + """ ListSubnets returns the matching subnets after applying optional filters. space_tag : str zone : str Returns -> ListSubnetsResults - ''' + """ if space_tag is not None and not isinstance(space_tag, (bytes, str)): - raise Exception("Expected space_tag to be a str, received: {}".format(type(space_tag))) + raise Exception( + "Expected space_tag to be a str, received: {}".format(type(space_tag)) + ) if zone is not None and not isinstance(zone, (bytes, str)): - raise Exception("Expected zone to be a str, received: {}".format(type(zone))) + raise Exception( + "Expected zone to be a str, received: {}".format(type(zone)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Subnets', - request='ListSubnets', - version=5, - params=_params) - _params['space-tag'] = space_tag - _params['zone'] = zone + msg = dict(type="Subnets", request="ListSubnets", version=5, params=_params) + _params["space-tag"] = space_tag + _params["zone"] = zone reply = await self.rpc(msg) return reply - - @ReturnMapping(SubnetsResults) async def SubnetsByCIDR(self, cidrs=None): - ''' + """ SubnetsByCIDR returns the collection of subnets matching each CIDR in the input. cidrs : typing.Sequence[str] Returns -> SubnetsResults - ''' + """ if cidrs is not None and not isinstance(cidrs, (bytes, str, list)): - raise Exception("Expected cidrs to be a Sequence, received: {}".format(type(cidrs))) + raise Exception( + "Expected cidrs to be a Sequence, received: {}".format(type(cidrs)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Subnets', - request='SubnetsByCIDR', - version=5, - params=_params) - _params['cidrs'] = cidrs + msg = dict(type="Subnets", request="SubnetsByCIDR", version=5, params=_params) + _params["cidrs"] = cidrs reply = await self.rpc(msg) return reply - - diff --git a/juju/client/_client6.py b/juju/client/_client6.py index 95b3ca84a..f93652338 100644 --- a/juju/client/_client6.py +++ b/juju/client/_client6.py @@ -6,140 +6,195 @@ class BundleFacade(Type): - name = 'Bundle' + name = "Bundle" version = 6 - schema = {'definitions': {'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'}, - 'BundleChangesMapArgs': {'additionalProperties': False, - 'properties': {'args': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'id': {'type': 'string'}, - 'method': {'type': 'string'}, - 'requires': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['id', - 'method', - 'args', - 'requires'], - 'type': 'object'}, - 'BundleChangesMapArgsResults': {'additionalProperties': False, - 'properties': {'changes': {'items': {'$ref': '#/definitions/BundleChangesMapArgs'}, - 'type': 'array'}, - 'errors': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'BundleChangesParams': {'additionalProperties': False, - 'properties': {'bundleURL': {'type': 'string'}, - 'yaml': {'type': 'string'}}, - 'required': ['yaml', 'bundleURL'], - 'type': 'object'}, - 'BundleChangesResults': {'additionalProperties': False, - 'properties': {'changes': {'items': {'$ref': '#/definitions/BundleChange'}, - 'type': 'array'}, - 'errors': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - 'type': 'object'}, - 'ExportBundleParams': {'additionalProperties': False, - 'properties': {'include-charm-defaults': {'type': 'boolean'}, - 'include-series': {'type': 'boolean'}}, - 'type': 'object'}, - 'StringResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'type': 'string'}}, - 'required': ['result'], - 'type': 'object'}}, - 'properties': {'ExportBundle': {'description': 'ExportBundle exports the ' - 'current model configuration ' - 'as bundle.', - 'properties': {'Params': {'$ref': '#/definitions/ExportBundleParams'}, - 'Result': {'$ref': '#/definitions/StringResult'}}, - 'type': 'object'}, - 'GetChanges': {'description': 'GetChanges returns the list of ' - 'changes required to deploy the ' - 'given bundle\n' - 'data. The changes are sorted by ' - 'requirements, so that they can ' - 'be applied in\n' - 'order.\n' - 'GetChanges has been superseded ' - 'in favour of GetChangesMapArgs. ' - "It's\n" - 'preferable to use that new ' - 'method to add new functionality ' - 'and move clients\n' - 'away from this one.', - 'properties': {'Params': {'$ref': '#/definitions/BundleChangesParams'}, - 'Result': {'$ref': '#/definitions/BundleChangesResults'}}, - 'type': 'object'}, - 'GetChangesMapArgs': {'description': 'GetChangesMapArgs ' - 'returns the list of ' - 'changes required to ' - 'deploy the given\n' - 'bundle data. The changes ' - 'are sorted by ' - 'requirements, so that ' - 'they can be\n' - 'applied in order.\n' - 'V4 GetChangesMapArgs is ' - 'not supported on ' - 'anything less than v4', - 'properties': {'Params': {'$ref': '#/definitions/BundleChangesParams'}, - 'Result': {'$ref': '#/definitions/BundleChangesMapArgsResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "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", + }, + "BundleChangesMapArgs": { + "additionalProperties": False, + "properties": { + "args": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "id": {"type": "string"}, + "method": {"type": "string"}, + "requires": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["id", "method", "args", "requires"], + "type": "object", + }, + "BundleChangesMapArgsResults": { + "additionalProperties": False, + "properties": { + "changes": { + "items": {"$ref": "#/definitions/BundleChangesMapArgs"}, + "type": "array", + }, + "errors": {"items": {"type": "string"}, "type": "array"}, + }, + "type": "object", + }, + "BundleChangesParams": { + "additionalProperties": False, + "properties": { + "bundleURL": {"type": "string"}, + "yaml": {"type": "string"}, + }, + "required": ["yaml", "bundleURL"], + "type": "object", + }, + "BundleChangesResults": { + "additionalProperties": False, + "properties": { + "changes": { + "items": {"$ref": "#/definitions/BundleChange"}, + "type": "array", + }, + "errors": {"items": {"type": "string"}, "type": "array"}, + }, + "type": "object", + }, + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "type": "object", + }, + "ExportBundleParams": { + "additionalProperties": False, + "properties": { + "include-charm-defaults": {"type": "boolean"}, + "include-series": {"type": "boolean"}, + }, + "type": "object", + }, + "StringResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"type": "string"}, + }, + "required": ["result"], + "type": "object", + }, + }, + "properties": { + "ExportBundle": { + "description": "ExportBundle exports the " + "current model configuration " + "as bundle.", + "properties": { + "Params": {"$ref": "#/definitions/ExportBundleParams"}, + "Result": {"$ref": "#/definitions/StringResult"}, + }, + "type": "object", + }, + "GetChanges": { + "description": "GetChanges returns the list of " + "changes required to deploy the " + "given bundle\n" + "data. The changes are sorted by " + "requirements, so that they can " + "be applied in\n" + "order.\n" + "GetChanges has been superseded " + "in favour of GetChangesMapArgs. " + "It's\n" + "preferable to use that new " + "method to add new functionality " + "and move clients\n" + "away from this one.", + "properties": { + "Params": {"$ref": "#/definitions/BundleChangesParams"}, + "Result": {"$ref": "#/definitions/BundleChangesResults"}, + }, + "type": "object", + }, + "GetChangesMapArgs": { + "description": "GetChangesMapArgs " + "returns the list of " + "changes required to " + "deploy the given\n" + "bundle data. The changes " + "are sorted by " + "requirements, so that " + "they can be\n" + "applied in order.\n" + "V4 GetChangesMapArgs is " + "not supported on " + "anything less than v4", + "properties": { + "Params": {"$ref": "#/definitions/BundleChangesParams"}, + "Result": {"$ref": "#/definitions/BundleChangesMapArgsResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(StringResult) async def ExportBundle(self, include_charm_defaults=None, include_series=None): - ''' + """ ExportBundle exports the current model configuration as bundle. include_charm_defaults : bool include_series : bool Returns -> StringResult - ''' - if include_charm_defaults is not None and not isinstance(include_charm_defaults, bool): - raise Exception("Expected include_charm_defaults to be a bool, received: {}".format(type(include_charm_defaults))) + """ + if include_charm_defaults is not None and not isinstance( + include_charm_defaults, bool + ): + raise Exception( + "Expected include_charm_defaults to be a bool, received: {}".format( + type(include_charm_defaults) + ) + ) if include_series is not None and not isinstance(include_series, bool): - raise Exception("Expected include_series to be a bool, received: {}".format(type(include_series))) + raise Exception( + "Expected include_series to be a bool, received: {}".format( + type(include_series) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Bundle', - request='ExportBundle', - version=6, - params=_params) - _params['include-charm-defaults'] = include_charm_defaults - _params['include-series'] = include_series + msg = dict(type="Bundle", request="ExportBundle", version=6, params=_params) + _params["include-charm-defaults"] = include_charm_defaults + _params["include-series"] = include_series reply = await self.rpc(msg) return reply - - @ReturnMapping(BundleChangesResults) async def GetChanges(self, bundleurl=None, yaml=None): - ''' + """ GetChanges returns the list of changes required to deploy the given bundle data. The changes are sorted by requirements, so that they can be applied in order. @@ -150,29 +205,28 @@ async def GetChanges(self, bundleurl=None, yaml=None): bundleurl : str yaml : str Returns -> BundleChangesResults - ''' + """ if bundleurl is not None and not isinstance(bundleurl, (bytes, str)): - raise Exception("Expected bundleurl to be a str, received: {}".format(type(bundleurl))) + raise Exception( + "Expected bundleurl to be a str, received: {}".format(type(bundleurl)) + ) if yaml is not None and not isinstance(yaml, (bytes, str)): - raise Exception("Expected yaml to be a str, received: {}".format(type(yaml))) + raise Exception( + "Expected yaml to be a str, received: {}".format(type(yaml)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Bundle', - request='GetChanges', - version=6, - params=_params) - _params['bundleURL'] = bundleurl - _params['yaml'] = yaml + msg = dict(type="Bundle", request="GetChanges", version=6, params=_params) + _params["bundleURL"] = bundleurl + _params["yaml"] = yaml reply = await self.rpc(msg) return reply - - @ReturnMapping(BundleChangesMapArgsResults) async def GetChangesMapArgs(self, bundleurl=None, yaml=None): - ''' + """ GetChangesMapArgs returns the list of changes required to deploy the given bundle data. The changes are sorted by requirements, so that they can be applied in order. @@ -181,462 +235,711 @@ async def GetChangesMapArgs(self, bundleurl=None, yaml=None): bundleurl : str yaml : str Returns -> BundleChangesMapArgsResults - ''' + """ if bundleurl is not None and not isinstance(bundleurl, (bytes, str)): - raise Exception("Expected bundleurl to be a str, received: {}".format(type(bundleurl))) + raise Exception( + "Expected bundleurl to be a str, received: {}".format(type(bundleurl)) + ) if yaml is not None and not isinstance(yaml, (bytes, str)): - raise Exception("Expected yaml to be a str, received: {}".format(type(yaml))) + raise Exception( + "Expected yaml to be a str, received: {}".format(type(yaml)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Bundle', - request='GetChangesMapArgs', - version=6, - params=_params) - _params['bundleURL'] = bundleurl - _params['yaml'] = yaml + msg = dict( + type="Bundle", request="GetChangesMapArgs", version=6, params=_params + ) + _params["bundleURL"] = bundleurl + _params["yaml"] = yaml reply = await self.rpc(msg) return reply - class CharmsFacade(Type): - name = 'Charms' + name = "Charms" version = 6 - schema = {'definitions': {'AddCharmWithOrigin': {'additionalProperties': False, - 'properties': {'charm-origin': {'$ref': '#/definitions/CharmOrigin'}, - 'force': {'type': 'boolean'}, - 'url': {'type': 'string'}}, - 'required': ['url', - 'charm-origin', - 'force'], - 'type': 'object'}, - 'ApplicationCharmPlacement': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'charm-url': {'type': 'string'}}, - 'required': ['application', - 'charm-url'], - 'type': 'object'}, - 'ApplicationCharmPlacements': {'additionalProperties': False, - 'properties': {'placements': {'items': {'$ref': '#/definitions/ApplicationCharmPlacement'}, - 'type': 'array'}}, - 'required': ['placements'], - 'type': 'object'}, - 'Base': {'additionalProperties': False, - 'properties': {'channel': {'type': 'string'}, - 'name': {'type': 'string'}}, - 'required': ['name', 'channel'], - 'type': 'object'}, - 'Charm': {'additionalProperties': False, - 'properties': {'actions': {'$ref': '#/definitions/CharmActions'}, - 'config': {'patternProperties': {'.*': {'$ref': '#/definitions/CharmOption'}}, - 'type': 'object'}, - 'lxd-profile': {'$ref': '#/definitions/CharmLXDProfile'}, - 'manifest': {'$ref': '#/definitions/CharmManifest'}, - 'meta': {'$ref': '#/definitions/CharmMeta'}, - 'metrics': {'$ref': '#/definitions/CharmMetrics'}, - 'revision': {'type': 'integer'}, - 'url': {'type': 'string'}}, - 'required': ['revision', 'url', 'config'], - 'type': 'object'}, - 'CharmActionSpec': {'additionalProperties': False, - 'properties': {'description': {'type': 'string'}, - 'params': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}}, - 'required': ['description', 'params'], - 'type': 'object'}, - 'CharmActions': {'additionalProperties': False, - 'properties': {'specs': {'patternProperties': {'.*': {'$ref': '#/definitions/CharmActionSpec'}}, - 'type': 'object'}}, - 'type': 'object'}, - 'CharmBase': {'additionalProperties': False, - 'properties': {'architectures': {'items': {'type': 'string'}, - 'type': 'array'}, - 'channel': {'type': 'string'}, - 'name': {'type': 'string'}}, - 'type': 'object'}, - 'CharmContainer': {'additionalProperties': False, - 'properties': {'mounts': {'items': {'$ref': '#/definitions/CharmMount'}, - 'type': 'array'}, - 'resource': {'type': 'string'}}, - 'type': 'object'}, - 'CharmDeployment': {'additionalProperties': False, - 'properties': {'min-version': {'type': 'string'}, - 'mode': {'type': 'string'}, - 'service': {'type': 'string'}, - 'type': {'type': 'string'}}, - 'required': ['type', - 'mode', - 'service', - 'min-version'], - 'type': 'object'}, - 'CharmDevice': {'additionalProperties': False, - 'properties': {'CountMax': {'type': 'integer'}, - 'CountMin': {'type': 'integer'}, - 'Description': {'type': 'string'}, - 'Name': {'type': 'string'}, - 'Type': {'type': 'string'}}, - 'required': ['Name', - 'Description', - 'Type', - 'CountMin', - 'CountMax'], - 'type': 'object'}, - 'CharmLXDProfile': {'additionalProperties': False, - 'properties': {'config': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'description': {'type': 'string'}, - 'devices': {'patternProperties': {'.*': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}}, - 'type': 'object'}}, - 'required': ['config', - 'description', - 'devices'], - 'type': 'object'}, - 'CharmManifest': {'additionalProperties': False, - 'properties': {'bases': {'items': {'$ref': '#/definitions/CharmBase'}, - 'type': 'array'}}, - 'type': 'object'}, - 'CharmMeta': {'additionalProperties': False, - 'properties': {'assumes-expr': {'$ref': '#/definitions/ExpressionTree'}, - 'categories': {'items': {'type': 'string'}, - 'type': 'array'}, - 'containers': {'patternProperties': {'.*': {'$ref': '#/definitions/CharmContainer'}}, - 'type': 'object'}, - 'deployment': {'$ref': '#/definitions/CharmDeployment'}, - 'description': {'type': 'string'}, - 'devices': {'patternProperties': {'.*': {'$ref': '#/definitions/CharmDevice'}}, - 'type': 'object'}, - 'extra-bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'min-juju-version': {'type': 'string'}, - 'name': {'type': 'string'}, - 'payload-classes': {'patternProperties': {'.*': {'$ref': '#/definitions/CharmPayloadClass'}}, - 'type': 'object'}, - 'peers': {'patternProperties': {'.*': {'$ref': '#/definitions/CharmRelation'}}, - 'type': 'object'}, - 'provides': {'patternProperties': {'.*': {'$ref': '#/definitions/CharmRelation'}}, - 'type': 'object'}, - 'requires': {'patternProperties': {'.*': {'$ref': '#/definitions/CharmRelation'}}, - 'type': 'object'}, - 'resources': {'patternProperties': {'.*': {'$ref': '#/definitions/CharmResourceMeta'}}, - 'type': 'object'}, - 'series': {'items': {'type': 'string'}, - 'type': 'array'}, - 'storage': {'patternProperties': {'.*': {'$ref': '#/definitions/CharmStorage'}}, - 'type': 'object'}, - 'subordinate': {'type': 'boolean'}, - 'summary': {'type': 'string'}, - 'tags': {'items': {'type': 'string'}, - 'type': 'array'}, - 'terms': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['name', - 'summary', - 'description', - 'subordinate'], - 'type': 'object'}, - 'CharmMetric': {'additionalProperties': False, - 'properties': {'description': {'type': 'string'}, - 'type': {'type': 'string'}}, - 'required': ['type', 'description'], - 'type': 'object'}, - 'CharmMetrics': {'additionalProperties': False, - 'properties': {'metrics': {'patternProperties': {'.*': {'$ref': '#/definitions/CharmMetric'}}, - 'type': 'object'}, - 'plan': {'$ref': '#/definitions/CharmPlan'}}, - 'required': ['metrics', 'plan'], - 'type': 'object'}, - 'CharmMount': {'additionalProperties': False, - 'properties': {'location': {'type': 'string'}, - 'storage': {'type': 'string'}}, - 'type': 'object'}, - 'CharmOption': {'additionalProperties': False, - 'properties': {'default': {'additionalProperties': True, - 'type': 'object'}, - 'description': {'type': 'string'}, - 'type': {'type': 'string'}}, - 'required': ['type'], - 'type': 'object'}, - 'CharmOrigin': {'additionalProperties': False, - 'properties': {'architecture': {'type': 'string'}, - 'base': {'$ref': '#/definitions/Base'}, - 'branch': {'type': 'string'}, - 'hash': {'type': 'string'}, - 'id': {'type': 'string'}, - 'instance-key': {'type': 'string'}, - 'revision': {'type': 'integer'}, - 'risk': {'type': 'string'}, - 'source': {'type': 'string'}, - 'track': {'type': 'string'}, - 'type': {'type': 'string'}}, - 'required': ['source', 'type', 'id'], - 'type': 'object'}, - 'CharmOriginResult': {'additionalProperties': False, - 'properties': {'charm-origin': {'$ref': '#/definitions/CharmOrigin'}, - 'error': {'$ref': '#/definitions/Error'}}, - 'required': ['charm-origin'], - 'type': 'object'}, - 'CharmPayloadClass': {'additionalProperties': False, - 'properties': {'name': {'type': 'string'}, - 'type': {'type': 'string'}}, - 'required': ['name', 'type'], - 'type': 'object'}, - 'CharmPlan': {'additionalProperties': False, - 'properties': {'required': {'type': 'boolean'}}, - 'required': ['required'], - 'type': 'object'}, - 'CharmRelation': {'additionalProperties': False, - 'properties': {'interface': {'type': 'string'}, - 'limit': {'type': 'integer'}, - 'name': {'type': 'string'}, - 'optional': {'type': 'boolean'}, - 'role': {'type': 'string'}, - 'scope': {'type': 'string'}}, - 'required': ['name', - 'role', - 'interface', - 'optional', - 'limit', - 'scope'], - 'type': 'object'}, - 'CharmResource': {'additionalProperties': False, - 'properties': {'description': {'type': 'string'}, - 'fingerprint': {'items': {'type': 'integer'}, - 'type': 'array'}, - 'name': {'type': 'string'}, - 'origin': {'type': 'string'}, - 'path': {'type': 'string'}, - 'revision': {'type': 'integer'}, - 'size': {'type': 'integer'}, - 'type': {'type': 'string'}}, - 'required': ['name', - 'type', - 'path', - 'origin', - 'revision', - 'fingerprint', - 'size'], - 'type': 'object'}, - 'CharmResourceMeta': {'additionalProperties': False, - 'properties': {'description': {'type': 'string'}, - 'name': {'type': 'string'}, - 'path': {'type': 'string'}, - 'type': {'type': 'string'}}, - 'required': ['name', - 'type', - 'path', - 'description'], - 'type': 'object'}, - 'CharmResourceResult': {'additionalProperties': False, - 'properties': {'CharmResource': {'$ref': '#/definitions/CharmResource'}, - 'ErrorResult': {'$ref': '#/definitions/ErrorResult'}, - 'description': {'type': 'string'}, - 'error': {'$ref': '#/definitions/Error'}, - 'fingerprint': {'items': {'type': 'integer'}, - 'type': 'array'}, - 'name': {'type': 'string'}, - 'origin': {'type': 'string'}, - 'path': {'type': 'string'}, - 'revision': {'type': 'integer'}, - 'size': {'type': 'integer'}, - 'type': {'type': 'string'}}, - 'required': ['ErrorResult', - 'name', - 'type', - 'path', - 'origin', - 'revision', - 'fingerprint', - 'size', - 'CharmResource'], - 'type': 'object'}, - 'CharmResourcesResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'items': {'$ref': '#/definitions/CharmResourceResult'}, - 'type': 'array'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'CharmStorage': {'additionalProperties': False, - 'properties': {'count-max': {'type': 'integer'}, - 'count-min': {'type': 'integer'}, - 'description': {'type': 'string'}, - 'location': {'type': 'string'}, - 'minimum-size': {'type': 'integer'}, - 'name': {'type': 'string'}, - 'properties': {'items': {'type': 'string'}, - 'type': 'array'}, - 'read-only': {'type': 'boolean'}, - 'shared': {'type': 'boolean'}, - 'type': {'type': 'string'}}, - 'required': ['name', - 'description', - 'type', - 'shared', - 'read-only', - 'count-min', - 'count-max', - 'minimum-size'], - 'type': 'object'}, - 'CharmURL': {'additionalProperties': False, - 'properties': {'url': {'type': 'string'}}, - 'required': ['url'], - 'type': 'object'}, - 'CharmURLAndOrigin': {'additionalProperties': False, - 'properties': {'charm-origin': {'$ref': '#/definitions/CharmOrigin'}, - 'charm-url': {'type': 'string'}, - 'macaroon': {'$ref': '#/definitions/Macaroon'}}, - 'required': ['charm-url', - 'charm-origin'], - 'type': 'object'}, - 'CharmURLAndOrigins': {'additionalProperties': False, - 'properties': {'entities': {'items': {'$ref': '#/definitions/CharmURLAndOrigin'}, - 'type': 'array'}}, - 'required': ['entities'], - 'type': 'object'}, - 'CharmsList': {'additionalProperties': False, - 'properties': {'names': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['names'], - 'type': 'object'}, - 'CharmsListResult': {'additionalProperties': False, - 'properties': {'charm-urls': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['charm-urls'], - 'type': 'object'}, - 'DownloadInfoResult': {'additionalProperties': False, - 'properties': {'charm-origin': {'$ref': '#/definitions/CharmOrigin'}, - 'url': {'type': 'string'}}, - 'required': ['url', 'charm-origin'], - 'type': 'object'}, - 'DownloadInfoResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/DownloadInfoResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - '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'}, - 'ExpressionTree': {'additionalProperties': False, - 'properties': {'Expression': {'additionalProperties': True, - 'type': 'object'}}, - 'required': ['Expression'], - 'type': 'object'}, - 'IsMeteredResult': {'additionalProperties': False, - 'properties': {'metered': {'type': 'boolean'}}, - 'required': ['metered'], - 'type': 'object'}, - 'Macaroon': {'additionalProperties': False, 'type': 'object'}, - 'ResolveCharmWithChannel': {'additionalProperties': False, - 'properties': {'charm-origin': {'$ref': '#/definitions/CharmOrigin'}, - 'reference': {'type': 'string'}, - 'switch-charm': {'type': 'boolean'}}, - 'required': ['reference', - 'charm-origin'], - 'type': 'object'}, - 'ResolveCharmWithChannelResult': {'additionalProperties': False, - 'properties': {'charm-origin': {'$ref': '#/definitions/CharmOrigin'}, - 'error': {'$ref': '#/definitions/Error'}, - 'supported-series': {'items': {'type': 'string'}, - 'type': 'array'}, - 'url': {'type': 'string'}}, - 'required': ['url', - 'charm-origin', - 'supported-series'], - 'type': 'object'}, - 'ResolveCharmWithChannelResults': {'additionalProperties': False, - 'properties': {'Results': {'items': {'$ref': '#/definitions/ResolveCharmWithChannelResult'}, - 'type': 'array'}}, - 'required': ['Results'], - 'type': 'object'}, - 'ResolveCharmsWithChannel': {'additionalProperties': False, - 'properties': {'macaroon': {'$ref': '#/definitions/Macaroon'}, - 'resolve': {'items': {'$ref': '#/definitions/ResolveCharmWithChannel'}, - 'type': 'array'}}, - 'required': ['resolve'], - 'type': 'object'}}, - 'properties': {'AddCharm': {'description': 'AddCharm adds the given charm URL ' - '(which must include revision) to ' - 'the\n' - 'environment, if it does not exist ' - 'yet. Local charms are not ' - 'supported,\n' - 'only charm store and charm hub ' - 'URLs. See also AddLocalCharm().', - 'properties': {'Params': {'$ref': '#/definitions/AddCharmWithOrigin'}, - 'Result': {'$ref': '#/definitions/CharmOriginResult'}}, - 'type': 'object'}, - 'CharmInfo': {'description': 'CharmInfo returns information ' - 'about the requested charm.', - 'properties': {'Params': {'$ref': '#/definitions/CharmURL'}, - 'Result': {'$ref': '#/definitions/Charm'}}, - 'type': 'object'}, - 'CheckCharmPlacement': {'description': 'CheckCharmPlacement ' - 'checks if a charm is ' - 'allowed to be placed ' - 'with in a\n' - 'given application.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationCharmPlacements'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'GetDownloadInfos': {'description': 'GetDownloadInfos attempts ' - 'to get the bundle ' - 'corresponding to the ' - 'charm url\n' - 'and origin.', - 'properties': {'Params': {'$ref': '#/definitions/CharmURLAndOrigins'}, - 'Result': {'$ref': '#/definitions/DownloadInfoResults'}}, - 'type': 'object'}, - 'IsMetered': {'description': 'IsMetered returns whether or not ' - 'the charm is metered.', - 'properties': {'Params': {'$ref': '#/definitions/CharmURL'}, - 'Result': {'$ref': '#/definitions/IsMeteredResult'}}, - 'type': 'object'}, - 'List': {'description': 'List returns a list of charm URLs ' - 'currently in the state.\n' - 'If supplied parameter contains any ' - 'names, the result will\n' - 'be filtered to return only the charms ' - 'with supplied names.', - 'properties': {'Params': {'$ref': '#/definitions/CharmsList'}, - 'Result': {'$ref': '#/definitions/CharmsListResult'}}, - 'type': 'object'}, - 'ListCharmResources': {'description': 'ListCharmResources ' - 'returns a series of ' - 'resources for a given ' - 'charm.', - 'properties': {'Params': {'$ref': '#/definitions/CharmURLAndOrigins'}, - 'Result': {'$ref': '#/definitions/CharmResourcesResults'}}, - 'type': 'object'}, - 'ResolveCharms': {'description': 'ResolveCharms resolves the ' - 'given charm URLs with an ' - 'optionally specified\n' - 'preferred channel. Channel ' - 'provided via CharmOrigin.', - 'properties': {'Params': {'$ref': '#/definitions/ResolveCharmsWithChannel'}, - 'Result': {'$ref': '#/definitions/ResolveCharmWithChannelResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "AddCharmWithOrigin": { + "additionalProperties": False, + "properties": { + "charm-origin": {"$ref": "#/definitions/CharmOrigin"}, + "force": {"type": "boolean"}, + "url": {"type": "string"}, + }, + "required": ["url", "charm-origin", "force"], + "type": "object", + }, + "ApplicationCharmPlacement": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "charm-url": {"type": "string"}, + }, + "required": ["application", "charm-url"], + "type": "object", + }, + "ApplicationCharmPlacements": { + "additionalProperties": False, + "properties": { + "placements": { + "items": {"$ref": "#/definitions/ApplicationCharmPlacement"}, + "type": "array", + } + }, + "required": ["placements"], + "type": "object", + }, + "Base": { + "additionalProperties": False, + "properties": { + "channel": {"type": "string"}, + "name": {"type": "string"}, + }, + "required": ["name", "channel"], + "type": "object", + }, + "Charm": { + "additionalProperties": False, + "properties": { + "actions": {"$ref": "#/definitions/CharmActions"}, + "config": { + "patternProperties": { + ".*": {"$ref": "#/definitions/CharmOption"} + }, + "type": "object", + }, + "lxd-profile": {"$ref": "#/definitions/CharmLXDProfile"}, + "manifest": {"$ref": "#/definitions/CharmManifest"}, + "meta": {"$ref": "#/definitions/CharmMeta"}, + "metrics": {"$ref": "#/definitions/CharmMetrics"}, + "revision": {"type": "integer"}, + "url": {"type": "string"}, + }, + "required": ["revision", "url", "config"], + "type": "object", + }, + "CharmActionSpec": { + "additionalProperties": False, + "properties": { + "description": {"type": "string"}, + "params": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + }, + "required": ["description", "params"], + "type": "object", + }, + "CharmActions": { + "additionalProperties": False, + "properties": { + "specs": { + "patternProperties": { + ".*": {"$ref": "#/definitions/CharmActionSpec"} + }, + "type": "object", + } + }, + "type": "object", + }, + "CharmBase": { + "additionalProperties": False, + "properties": { + "architectures": {"items": {"type": "string"}, "type": "array"}, + "channel": {"type": "string"}, + "name": {"type": "string"}, + }, + "type": "object", + }, + "CharmContainer": { + "additionalProperties": False, + "properties": { + "mounts": { + "items": {"$ref": "#/definitions/CharmMount"}, + "type": "array", + }, + "resource": {"type": "string"}, + }, + "type": "object", + }, + "CharmDeployment": { + "additionalProperties": False, + "properties": { + "min-version": {"type": "string"}, + "mode": {"type": "string"}, + "service": {"type": "string"}, + "type": {"type": "string"}, + }, + "required": ["type", "mode", "service", "min-version"], + "type": "object", + }, + "CharmDevice": { + "additionalProperties": False, + "properties": { + "CountMax": {"type": "integer"}, + "CountMin": {"type": "integer"}, + "Description": {"type": "string"}, + "Name": {"type": "string"}, + "Type": {"type": "string"}, + }, + "required": ["Name", "Description", "Type", "CountMin", "CountMax"], + "type": "object", + }, + "CharmLXDProfile": { + "additionalProperties": False, + "properties": { + "config": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "description": {"type": "string"}, + "devices": { + "patternProperties": { + ".*": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + } + }, + "type": "object", + }, + }, + "required": ["config", "description", "devices"], + "type": "object", + }, + "CharmManifest": { + "additionalProperties": False, + "properties": { + "bases": { + "items": {"$ref": "#/definitions/CharmBase"}, + "type": "array", + } + }, + "type": "object", + }, + "CharmMeta": { + "additionalProperties": False, + "properties": { + "assumes-expr": {"$ref": "#/definitions/ExpressionTree"}, + "categories": {"items": {"type": "string"}, "type": "array"}, + "containers": { + "patternProperties": { + ".*": {"$ref": "#/definitions/CharmContainer"} + }, + "type": "object", + }, + "deployment": {"$ref": "#/definitions/CharmDeployment"}, + "description": {"type": "string"}, + "devices": { + "patternProperties": { + ".*": {"$ref": "#/definitions/CharmDevice"} + }, + "type": "object", + }, + "extra-bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "min-juju-version": {"type": "string"}, + "name": {"type": "string"}, + "payload-classes": { + "patternProperties": { + ".*": {"$ref": "#/definitions/CharmPayloadClass"} + }, + "type": "object", + }, + "peers": { + "patternProperties": { + ".*": {"$ref": "#/definitions/CharmRelation"} + }, + "type": "object", + }, + "provides": { + "patternProperties": { + ".*": {"$ref": "#/definitions/CharmRelation"} + }, + "type": "object", + }, + "requires": { + "patternProperties": { + ".*": {"$ref": "#/definitions/CharmRelation"} + }, + "type": "object", + }, + "resources": { + "patternProperties": { + ".*": {"$ref": "#/definitions/CharmResourceMeta"} + }, + "type": "object", + }, + "series": {"items": {"type": "string"}, "type": "array"}, + "storage": { + "patternProperties": { + ".*": {"$ref": "#/definitions/CharmStorage"} + }, + "type": "object", + }, + "subordinate": {"type": "boolean"}, + "summary": {"type": "string"}, + "tags": {"items": {"type": "string"}, "type": "array"}, + "terms": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["name", "summary", "description", "subordinate"], + "type": "object", + }, + "CharmMetric": { + "additionalProperties": False, + "properties": { + "description": {"type": "string"}, + "type": {"type": "string"}, + }, + "required": ["type", "description"], + "type": "object", + }, + "CharmMetrics": { + "additionalProperties": False, + "properties": { + "metrics": { + "patternProperties": { + ".*": {"$ref": "#/definitions/CharmMetric"} + }, + "type": "object", + }, + "plan": {"$ref": "#/definitions/CharmPlan"}, + }, + "required": ["metrics", "plan"], + "type": "object", + }, + "CharmMount": { + "additionalProperties": False, + "properties": { + "location": {"type": "string"}, + "storage": {"type": "string"}, + }, + "type": "object", + }, + "CharmOption": { + "additionalProperties": False, + "properties": { + "default": {"additionalProperties": True, "type": "object"}, + "description": {"type": "string"}, + "type": {"type": "string"}, + }, + "required": ["type"], + "type": "object", + }, + "CharmOrigin": { + "additionalProperties": False, + "properties": { + "architecture": {"type": "string"}, + "base": {"$ref": "#/definitions/Base"}, + "branch": {"type": "string"}, + "hash": {"type": "string"}, + "id": {"type": "string"}, + "instance-key": {"type": "string"}, + "revision": {"type": "integer"}, + "risk": {"type": "string"}, + "source": {"type": "string"}, + "track": {"type": "string"}, + "type": {"type": "string"}, + }, + "required": ["source", "type", "id"], + "type": "object", + }, + "CharmOriginResult": { + "additionalProperties": False, + "properties": { + "charm-origin": {"$ref": "#/definitions/CharmOrigin"}, + "error": {"$ref": "#/definitions/Error"}, + }, + "required": ["charm-origin"], + "type": "object", + }, + "CharmPayloadClass": { + "additionalProperties": False, + "properties": {"name": {"type": "string"}, "type": {"type": "string"}}, + "required": ["name", "type"], + "type": "object", + }, + "CharmPlan": { + "additionalProperties": False, + "properties": {"required": {"type": "boolean"}}, + "required": ["required"], + "type": "object", + }, + "CharmRelation": { + "additionalProperties": False, + "properties": { + "interface": {"type": "string"}, + "limit": {"type": "integer"}, + "name": {"type": "string"}, + "optional": {"type": "boolean"}, + "role": {"type": "string"}, + "scope": {"type": "string"}, + }, + "required": ["name", "role", "interface", "optional", "limit", "scope"], + "type": "object", + }, + "CharmResource": { + "additionalProperties": False, + "properties": { + "description": {"type": "string"}, + "fingerprint": {"items": {"type": "integer"}, "type": "array"}, + "name": {"type": "string"}, + "origin": {"type": "string"}, + "path": {"type": "string"}, + "revision": {"type": "integer"}, + "size": {"type": "integer"}, + "type": {"type": "string"}, + }, + "required": [ + "name", + "type", + "path", + "origin", + "revision", + "fingerprint", + "size", + ], + "type": "object", + }, + "CharmResourceMeta": { + "additionalProperties": False, + "properties": { + "description": {"type": "string"}, + "name": {"type": "string"}, + "path": {"type": "string"}, + "type": {"type": "string"}, + }, + "required": ["name", "type", "path", "description"], + "type": "object", + }, + "CharmResourceResult": { + "additionalProperties": False, + "properties": { + "CharmResource": {"$ref": "#/definitions/CharmResource"}, + "ErrorResult": {"$ref": "#/definitions/ErrorResult"}, + "description": {"type": "string"}, + "error": {"$ref": "#/definitions/Error"}, + "fingerprint": {"items": {"type": "integer"}, "type": "array"}, + "name": {"type": "string"}, + "origin": {"type": "string"}, + "path": {"type": "string"}, + "revision": {"type": "integer"}, + "size": {"type": "integer"}, + "type": {"type": "string"}, + }, + "required": [ + "ErrorResult", + "name", + "type", + "path", + "origin", + "revision", + "fingerprint", + "size", + "CharmResource", + ], + "type": "object", + }, + "CharmResourcesResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": { + "items": {"$ref": "#/definitions/CharmResourceResult"}, + "type": "array", + }, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "CharmStorage": { + "additionalProperties": False, + "properties": { + "count-max": {"type": "integer"}, + "count-min": {"type": "integer"}, + "description": {"type": "string"}, + "location": {"type": "string"}, + "minimum-size": {"type": "integer"}, + "name": {"type": "string"}, + "properties": {"items": {"type": "string"}, "type": "array"}, + "read-only": {"type": "boolean"}, + "shared": {"type": "boolean"}, + "type": {"type": "string"}, + }, + "required": [ + "name", + "description", + "type", + "shared", + "read-only", + "count-min", + "count-max", + "minimum-size", + ], + "type": "object", + }, + "CharmURL": { + "additionalProperties": False, + "properties": {"url": {"type": "string"}}, + "required": ["url"], + "type": "object", + }, + "CharmURLAndOrigin": { + "additionalProperties": False, + "properties": { + "charm-origin": {"$ref": "#/definitions/CharmOrigin"}, + "charm-url": {"type": "string"}, + "macaroon": {"$ref": "#/definitions/Macaroon"}, + }, + "required": ["charm-url", "charm-origin"], + "type": "object", + }, + "CharmURLAndOrigins": { + "additionalProperties": False, + "properties": { + "entities": { + "items": {"$ref": "#/definitions/CharmURLAndOrigin"}, + "type": "array", + } + }, + "required": ["entities"], + "type": "object", + }, + "CharmsList": { + "additionalProperties": False, + "properties": {"names": {"items": {"type": "string"}, "type": "array"}}, + "required": ["names"], + "type": "object", + }, + "CharmsListResult": { + "additionalProperties": False, + "properties": { + "charm-urls": {"items": {"type": "string"}, "type": "array"} + }, + "required": ["charm-urls"], + "type": "object", + }, + "DownloadInfoResult": { + "additionalProperties": False, + "properties": { + "charm-origin": {"$ref": "#/definitions/CharmOrigin"}, + "url": {"type": "string"}, + }, + "required": ["url", "charm-origin"], + "type": "object", + }, + "DownloadInfoResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/DownloadInfoResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "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", + }, + "ExpressionTree": { + "additionalProperties": False, + "properties": { + "Expression": {"additionalProperties": True, "type": "object"} + }, + "required": ["Expression"], + "type": "object", + }, + "IsMeteredResult": { + "additionalProperties": False, + "properties": {"metered": {"type": "boolean"}}, + "required": ["metered"], + "type": "object", + }, + "Macaroon": {"additionalProperties": False, "type": "object"}, + "ResolveCharmWithChannel": { + "additionalProperties": False, + "properties": { + "charm-origin": {"$ref": "#/definitions/CharmOrigin"}, + "reference": {"type": "string"}, + "switch-charm": {"type": "boolean"}, + }, + "required": ["reference", "charm-origin"], + "type": "object", + }, + "ResolveCharmWithChannelResult": { + "additionalProperties": False, + "properties": { + "charm-origin": {"$ref": "#/definitions/CharmOrigin"}, + "error": {"$ref": "#/definitions/Error"}, + "supported-series": {"items": {"type": "string"}, "type": "array"}, + "url": {"type": "string"}, + }, + "required": ["url", "charm-origin", "supported-series"], + "type": "object", + }, + "ResolveCharmWithChannelResults": { + "additionalProperties": False, + "properties": { + "Results": { + "items": { + "$ref": "#/definitions/ResolveCharmWithChannelResult" + }, + "type": "array", + } + }, + "required": ["Results"], + "type": "object", + }, + "ResolveCharmsWithChannel": { + "additionalProperties": False, + "properties": { + "macaroon": {"$ref": "#/definitions/Macaroon"}, + "resolve": { + "items": {"$ref": "#/definitions/ResolveCharmWithChannel"}, + "type": "array", + }, + }, + "required": ["resolve"], + "type": "object", + }, + }, + "properties": { + "AddCharm": { + "description": "AddCharm adds the given charm URL " + "(which must include revision) to " + "the\n" + "environment, if it does not exist " + "yet. Local charms are not " + "supported,\n" + "only charm store and charm hub " + "URLs. See also AddLocalCharm().", + "properties": { + "Params": {"$ref": "#/definitions/AddCharmWithOrigin"}, + "Result": {"$ref": "#/definitions/CharmOriginResult"}, + }, + "type": "object", + }, + "CharmInfo": { + "description": "CharmInfo returns information " + "about the requested charm.", + "properties": { + "Params": {"$ref": "#/definitions/CharmURL"}, + "Result": {"$ref": "#/definitions/Charm"}, + }, + "type": "object", + }, + "CheckCharmPlacement": { + "description": "CheckCharmPlacement " + "checks if a charm is " + "allowed to be placed " + "with in a\n" + "given application.", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationCharmPlacements"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "GetDownloadInfos": { + "description": "GetDownloadInfos attempts " + "to get the bundle " + "corresponding to the " + "charm url\n" + "and origin.", + "properties": { + "Params": {"$ref": "#/definitions/CharmURLAndOrigins"}, + "Result": {"$ref": "#/definitions/DownloadInfoResults"}, + }, + "type": "object", + }, + "IsMetered": { + "description": "IsMetered returns whether or not the charm is metered.", + "properties": { + "Params": {"$ref": "#/definitions/CharmURL"}, + "Result": {"$ref": "#/definitions/IsMeteredResult"}, + }, + "type": "object", + }, + "List": { + "description": "List returns a list of charm URLs " + "currently in the state.\n" + "If supplied parameter contains any " + "names, the result will\n" + "be filtered to return only the charms " + "with supplied names.", + "properties": { + "Params": {"$ref": "#/definitions/CharmsList"}, + "Result": {"$ref": "#/definitions/CharmsListResult"}, + }, + "type": "object", + }, + "ListCharmResources": { + "description": "ListCharmResources " + "returns a series of " + "resources for a given " + "charm.", + "properties": { + "Params": {"$ref": "#/definitions/CharmURLAndOrigins"}, + "Result": {"$ref": "#/definitions/CharmResourcesResults"}, + }, + "type": "object", + }, + "ResolveCharms": { + "description": "ResolveCharms resolves the " + "given charm URLs with an " + "optionally specified\n" + "preferred channel. Channel " + "provided via CharmOrigin.", + "properties": { + "Params": {"$ref": "#/definitions/ResolveCharmsWithChannel"}, + "Result": {"$ref": "#/definitions/ResolveCharmWithChannelResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(CharmOriginResult) async def AddCharm(self, charm_origin=None, force=None, url=None): - ''' + """ AddCharm adds the given charm URL (which must include revision) to the environment, if it does not exist yet. Local charms are not supported, only charm store and charm hub URLs. See also AddLocalCharm(). @@ -645,639 +948,837 @@ async def AddCharm(self, charm_origin=None, force=None, url=None): force : bool url : str Returns -> CharmOriginResult - ''' - if charm_origin is not None and not isinstance(charm_origin, (dict, CharmOrigin)): - raise Exception("Expected charm_origin to be a CharmOrigin, received: {}".format(type(charm_origin))) + """ + if charm_origin is not None and not isinstance( + charm_origin, (dict, CharmOrigin) + ): + raise Exception( + "Expected charm_origin to be a CharmOrigin, received: {}".format( + type(charm_origin) + ) + ) if force is not None and not isinstance(force, bool): - raise Exception("Expected force to be a bool, received: {}".format(type(force))) + raise Exception( + "Expected force to be a bool, received: {}".format(type(force)) + ) if url is not None and not isinstance(url, (bytes, str)): raise Exception("Expected url to be a str, received: {}".format(type(url))) # map input types to rpc msg _params = dict() - msg = dict(type='Charms', - request='AddCharm', - version=6, - params=_params) - _params['charm-origin'] = charm_origin - _params['force'] = force - _params['url'] = url + msg = dict(type="Charms", request="AddCharm", version=6, params=_params) + _params["charm-origin"] = charm_origin + _params["force"] = force + _params["url"] = url reply = await self.rpc(msg) return reply - - @ReturnMapping(Charm) async def CharmInfo(self, url=None): - ''' + """ CharmInfo returns information about the requested charm. url : str Returns -> Charm - ''' + """ if url is not None and not isinstance(url, (bytes, str)): raise Exception("Expected url to be a str, received: {}".format(type(url))) # map input types to rpc msg _params = dict() - msg = dict(type='Charms', - request='CharmInfo', - version=6, - params=_params) - _params['url'] = url + msg = dict(type="Charms", request="CharmInfo", version=6, params=_params) + _params["url"] = url reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def CheckCharmPlacement(self, placements=None): - ''' + """ CheckCharmPlacement checks if a charm is allowed to be placed with in a given application. placements : typing.Sequence[~ApplicationCharmPlacement] Returns -> ErrorResults - ''' + """ if placements is not None and not isinstance(placements, (bytes, str, list)): - raise Exception("Expected placements to be a Sequence, received: {}".format(type(placements))) + raise Exception( + "Expected placements to be a Sequence, received: {}".format( + type(placements) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Charms', - request='CheckCharmPlacement', - version=6, - params=_params) - _params['placements'] = placements + msg = dict( + type="Charms", request="CheckCharmPlacement", version=6, params=_params + ) + _params["placements"] = placements reply = await self.rpc(msg) return reply - - @ReturnMapping(DownloadInfoResults) async def GetDownloadInfos(self, entities=None): - ''' + """ GetDownloadInfos attempts to get the bundle corresponding to the charm url and origin. entities : typing.Sequence[~CharmURLAndOrigin] Returns -> DownloadInfoResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Charms', - request='GetDownloadInfos', - version=6, - params=_params) - _params['entities'] = entities + msg = dict(type="Charms", request="GetDownloadInfos", version=6, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(IsMeteredResult) async def IsMetered(self, url=None): - ''' + """ IsMetered returns whether or not the charm is metered. url : str Returns -> IsMeteredResult - ''' + """ if url is not None and not isinstance(url, (bytes, str)): raise Exception("Expected url to be a str, received: {}".format(type(url))) # map input types to rpc msg _params = dict() - msg = dict(type='Charms', - request='IsMetered', - version=6, - params=_params) - _params['url'] = url + msg = dict(type="Charms", request="IsMetered", version=6, params=_params) + _params["url"] = url reply = await self.rpc(msg) return reply - - @ReturnMapping(CharmsListResult) async def List(self, names=None): - ''' + """ List returns a list of charm URLs currently in the state. If supplied parameter contains any names, the result will be filtered to return only the charms with supplied names. names : typing.Sequence[str] Returns -> CharmsListResult - ''' + """ if names is not None and not isinstance(names, (bytes, str, list)): - raise Exception("Expected names to be a Sequence, received: {}".format(type(names))) + raise Exception( + "Expected names to be a Sequence, received: {}".format(type(names)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Charms', - request='List', - version=6, - params=_params) - _params['names'] = names + msg = dict(type="Charms", request="List", version=6, params=_params) + _params["names"] = names reply = await self.rpc(msg) return reply - - @ReturnMapping(CharmResourcesResults) async def ListCharmResources(self, entities=None): - ''' + """ ListCharmResources returns a series of resources for a given charm. entities : typing.Sequence[~CharmURLAndOrigin] Returns -> CharmResourcesResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Charms', - request='ListCharmResources', - version=6, - params=_params) - _params['entities'] = entities + msg = dict( + type="Charms", request="ListCharmResources", version=6, params=_params + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ResolveCharmWithChannelResults) async def ResolveCharms(self, macaroon=None, resolve=None): - ''' + """ ResolveCharms resolves the given charm URLs with an optionally specified preferred channel. Channel provided via CharmOrigin. macaroon : Macaroon resolve : typing.Sequence[~ResolveCharmWithChannel] Returns -> ResolveCharmWithChannelResults - ''' + """ if macaroon is not None and not isinstance(macaroon, (dict, Macaroon)): - raise Exception("Expected macaroon to be a Macaroon, received: {}".format(type(macaroon))) + raise Exception( + "Expected macaroon to be a Macaroon, received: {}".format( + type(macaroon) + ) + ) if resolve is not None and not isinstance(resolve, (bytes, str, list)): - raise Exception("Expected resolve to be a Sequence, received: {}".format(type(resolve))) + raise Exception( + "Expected resolve to be a Sequence, received: {}".format(type(resolve)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Charms', - request='ResolveCharms', - version=6, - params=_params) - _params['macaroon'] = macaroon - _params['resolve'] = resolve + msg = dict(type="Charms", request="ResolveCharms", version=6, params=_params) + _params["macaroon"] = macaroon + _params["resolve"] = resolve reply = await self.rpc(msg) return reply - class ClientFacade(Type): - name = 'Client' + name = "Client" version = 6 - schema = {'definitions': {'AllWatcherId': {'additionalProperties': False, - 'properties': {'watcher-id': {'type': 'string'}}, - 'required': ['watcher-id'], - 'type': 'object'}, - 'ApplicationOfferStatus': {'additionalProperties': False, - 'properties': {'active-connected-count': {'type': 'integer'}, - 'application-name': {'type': 'string'}, - 'charm': {'type': 'string'}, - 'endpoints': {'patternProperties': {'.*': {'$ref': '#/definitions/RemoteEndpoint'}}, - 'type': 'object'}, - 'err': {'$ref': '#/definitions/Error'}, - 'offer-name': {'type': 'string'}, - 'total-connected-count': {'type': 'integer'}}, - 'required': ['offer-name', - 'application-name', - 'charm', - 'endpoints', - 'active-connected-count', - 'total-connected-count'], - 'type': 'object'}, - 'ApplicationStatus': {'additionalProperties': False, - 'properties': {'base': {'$ref': '#/definitions/Base'}, - 'can-upgrade-to': {'type': 'string'}, - 'charm': {'type': 'string'}, - 'charm-channel': {'type': 'string'}, - 'charm-profile': {'type': 'string'}, - 'charm-version': {'type': 'string'}, - 'endpoint-bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'err': {'$ref': '#/definitions/Error'}, - 'exposed': {'type': 'boolean'}, - 'exposed-endpoints': {'patternProperties': {'.*': {'$ref': '#/definitions/ExposedEndpoint'}}, - 'type': 'object'}, - 'int': {'type': 'integer'}, - 'life': {'type': 'string'}, - 'meter-statuses': {'patternProperties': {'.*': {'$ref': '#/definitions/MeterStatus'}}, - 'type': 'object'}, - 'provider-id': {'type': 'string'}, - 'public-address': {'type': 'string'}, - 'relations': {'patternProperties': {'.*': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'status': {'$ref': '#/definitions/DetailedStatus'}, - 'subordinate-to': {'items': {'type': 'string'}, - 'type': 'array'}, - 'units': {'patternProperties': {'.*': {'$ref': '#/definitions/UnitStatus'}}, - 'type': 'object'}, - 'workload-version': {'type': 'string'}}, - 'required': ['charm', - 'charm-version', - 'charm-profile', - 'base', - 'exposed', - 'life', - 'relations', - 'can-upgrade-to', - 'subordinate-to', - 'units', - 'meter-statuses', - 'status', - 'workload-version', - 'endpoint-bindings', - 'public-address'], - 'type': 'object'}, - 'Base': {'additionalProperties': False, - 'properties': {'channel': {'type': 'string'}, - 'name': {'type': 'string'}}, - 'required': ['name', 'channel'], - 'type': 'object'}, - 'Binary': {'additionalProperties': False, - 'properties': {'Arch': {'type': 'string'}, - 'Build': {'type': 'integer'}, - 'Major': {'type': 'integer'}, - 'Minor': {'type': 'integer'}, - 'Number': {'$ref': '#/definitions/Number'}, - 'Patch': {'type': 'integer'}, - 'Release': {'type': 'string'}, - 'Tag': {'type': 'string'}}, - 'required': ['Major', - 'Minor', - 'Tag', - 'Patch', - 'Build', - 'Number', - 'Release', - 'Arch'], - 'type': 'object'}, - 'BranchStatus': {'additionalProperties': False, - 'properties': {'assigned-units': {'patternProperties': {'.*': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'created': {'type': 'integer'}, - 'created-by': {'type': 'string'}}, - 'required': ['assigned-units', - 'created', - 'created-by'], - 'type': 'object'}, - 'DetailedStatus': {'additionalProperties': False, - 'properties': {'data': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'err': {'$ref': '#/definitions/Error'}, - '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': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - 'type': 'object'}, - 'ExposedEndpoint': {'additionalProperties': False, - 'properties': {'expose-to-cidrs': {'items': {'type': 'string'}, - 'type': 'array'}, - 'expose-to-spaces': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'FindToolsParams': {'additionalProperties': False, - 'properties': {'agentstream': {'type': 'string'}, - 'arch': {'type': 'string'}, - 'major': {'type': 'integer'}, - 'number': {'$ref': '#/definitions/Number'}, - 'os-type': {'type': 'string'}}, - 'required': ['number', - 'major', - 'arch', - 'os-type', - 'agentstream'], - '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'}, - 'branches': {'patternProperties': {'.*': {'$ref': '#/definitions/BranchStatus'}}, - 'type': 'object'}, - 'controller-timestamp': {'format': 'date-time', - 'type': 'string'}, - 'machines': {'patternProperties': {'.*': {'$ref': '#/definitions/MachineStatus'}}, - 'type': 'object'}, - 'model': {'$ref': '#/definitions/ModelStatusInfo'}, - 'offers': {'patternProperties': {'.*': {'$ref': '#/definitions/ApplicationOfferStatus'}}, - 'type': 'object'}, - 'relations': {'items': {'$ref': '#/definitions/RelationStatus'}, - 'type': 'array'}, - 'remote-applications': {'patternProperties': {'.*': {'$ref': '#/definitions/RemoteApplicationStatus'}}, - 'type': 'object'}}, - 'required': ['model', - 'machines', - 'applications', - 'remote-applications', - 'offers', - 'relations', - 'controller-timestamp', - 'branches'], - 'type': 'object'}, - 'History': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'statuses': {'items': {'$ref': '#/definitions/DetailedStatus'}, - 'type': 'array'}}, - 'required': ['statuses'], - 'type': 'object'}, - 'LXDProfile': {'additionalProperties': False, - 'properties': {'config': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'description': {'type': 'string'}, - 'devices': {'patternProperties': {'.*': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}}, - 'type': 'object'}}, - 'required': ['config', - 'description', - 'devices'], - 'type': 'object'}, - 'MachineStatus': {'additionalProperties': False, - 'properties': {'agent-status': {'$ref': '#/definitions/DetailedStatus'}, - 'base': {'$ref': '#/definitions/Base'}, - 'constraints': {'type': 'string'}, - 'containers': {'patternProperties': {'.*': {'$ref': '#/definitions/MachineStatus'}}, - 'type': 'object'}, - 'display-name': {'type': 'string'}, - 'dns-name': {'type': 'string'}, - 'hardware': {'type': 'string'}, - 'has-vote': {'type': 'boolean'}, - 'hostname': {'type': 'string'}, - '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'}, - 'lxd-profiles': {'patternProperties': {'.*': {'$ref': '#/definitions/LXDProfile'}}, - 'type': 'object'}, - 'modification-status': {'$ref': '#/definitions/DetailedStatus'}, - 'network-interfaces': {'patternProperties': {'.*': {'$ref': '#/definitions/NetworkInterface'}}, - 'type': 'object'}, - 'primary-controller-machine': {'type': 'boolean'}, - 'wants-vote': {'type': 'boolean'}}, - 'required': ['agent-status', - 'instance-status', - 'modification-status', - 'dns-name', - 'instance-id', - 'display-name', - 'base', - 'id', - 'containers', - 'constraints', - 'hardware', - 'jobs', - 'has-vote', - 'wants-vote'], - 'type': 'object'}, - 'MeterStatus': {'additionalProperties': False, - 'properties': {'color': {'type': 'string'}, - 'message': {'type': 'string'}}, - 'required': ['color', 'message'], - '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'}, - 'type': {'type': 'string'}, - 'version': {'type': 'string'}}, - 'required': ['name', - 'type', - 'cloud-tag', - 'version', - 'available-version', - 'model-status', - 'meter-status', - 'sla'], - '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'], - 'type': 'object'}, - 'RelationStatus': {'additionalProperties': False, - 'properties': {'endpoints': {'items': {'$ref': '#/definitions/EndpointStatus'}, - 'type': 'array'}, - 'id': {'type': 'integer'}, - 'interface': {'type': 'string'}, - 'key': {'type': 'string'}, - 'scope': {'type': 'string'}, - 'status': {'$ref': '#/definitions/DetailedStatus'}}, - 'required': ['id', - 'key', - 'interface', - 'scope', - 'endpoints', - 'status'], - 'type': 'object'}, - 'RemoteApplicationStatus': {'additionalProperties': False, - 'properties': {'endpoints': {'items': {'$ref': '#/definitions/RemoteEndpoint'}, - 'type': 'array'}, - 'err': {'$ref': '#/definitions/Error'}, - 'life': {'type': 'string'}, - 'offer-name': {'type': 'string'}, - 'offer-url': {'type': 'string'}, - 'relations': {'patternProperties': {'.*': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'status': {'$ref': '#/definitions/DetailedStatus'}}, - 'required': ['offer-url', - 'offer-name', - 'endpoints', - 'life', - 'relations', - 'status'], - 'type': 'object'}, - 'RemoteEndpoint': {'additionalProperties': False, - 'properties': {'interface': {'type': 'string'}, - 'limit': {'type': 'integer'}, - 'name': {'type': 'string'}, - 'role': {'type': 'string'}}, - 'required': ['name', - 'role', - 'interface', - 'limit'], - 'type': 'object'}, - 'StatusHistoryFilter': {'additionalProperties': False, - 'properties': {'date': {'format': 'date-time', - 'type': 'string'}, - 'delta': {'type': 'integer'}, - 'exclude': {'items': {'type': 'string'}, - 'type': 'array'}, - 'size': {'type': 'integer'}}, - 'required': ['size', - 'date', - 'delta', - 'exclude'], - 'type': 'object'}, - 'StatusHistoryRequest': {'additionalProperties': False, - 'properties': {'filter': {'$ref': '#/definitions/StatusHistoryFilter'}, - 'historyKind': {'type': 'string'}, - 'size': {'type': 'integer'}, - 'tag': {'type': 'string'}}, - 'required': ['historyKind', - 'size', - 'filter', - 'tag'], - 'type': 'object'}, - 'StatusHistoryRequests': {'additionalProperties': False, - 'properties': {'requests': {'items': {'$ref': '#/definitions/StatusHistoryRequest'}, - 'type': 'array'}}, - 'required': ['requests'], - 'type': 'object'}, - 'StatusHistoryResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'history': {'$ref': '#/definitions/History'}}, - 'required': ['history'], - 'type': 'object'}, - 'StatusHistoryResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/StatusHistoryResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'StatusParams': {'additionalProperties': False, - 'properties': {'patterns': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['patterns'], - 'type': 'object'}, - 'Tools': {'additionalProperties': False, - 'properties': {'sha256': {'type': 'string'}, - 'size': {'type': 'integer'}, - 'url': {'type': 'string'}, - 'version': {'$ref': '#/definitions/Binary'}}, - 'required': ['version', 'url', 'size'], - 'type': 'object'}, - 'UnitStatus': {'additionalProperties': False, - 'properties': {'address': {'type': 'string'}, - 'agent-status': {'$ref': '#/definitions/DetailedStatus'}, - 'charm': {'type': 'string'}, - 'leader': {'type': 'boolean'}, - 'machine': {'type': 'string'}, - 'opened-ports': {'items': {'type': 'string'}, - 'type': 'array'}, - 'provider-id': {'type': 'string'}, - 'public-address': {'type': 'string'}, - 'subordinates': {'patternProperties': {'.*': {'$ref': '#/definitions/UnitStatus'}}, - 'type': 'object'}, - 'workload-status': {'$ref': '#/definitions/DetailedStatus'}, - 'workload-version': {'type': 'string'}}, - 'required': ['agent-status', - 'workload-status', - 'workload-version', - 'machine', - 'opened-ports', - 'public-address', - 'charm', - 'subordinates'], - 'type': 'object'}}, - 'properties': {'FindTools': {'description': 'FindTools returns a List ' - 'containing all tools matching ' - 'the given parameters.\n' - 'TODO(juju 3.1) - remove, used by ' - '2.9 client only', - 'properties': {'Params': {'$ref': '#/definitions/FindToolsParams'}, - 'Result': {'$ref': '#/definitions/FindToolsResult'}}, - 'type': 'object'}, - 'FullStatus': {'description': 'FullStatus gives the ' - 'information needed for juju ' - 'status over the api', - 'properties': {'Params': {'$ref': '#/definitions/StatusParams'}, - 'Result': {'$ref': '#/definitions/FullStatus'}}, - 'type': 'object'}, - 'StatusHistory': {'description': 'StatusHistory returns a ' - 'slice of past statuses for ' - 'several entities.', - 'properties': {'Params': {'$ref': '#/definitions/StatusHistoryRequests'}, - 'Result': {'$ref': '#/definitions/StatusHistoryResults'}}, - 'type': 'object'}, - 'WatchAll': {'description': 'WatchAll initiates a watcher for ' - 'entities in the connected model.', - 'properties': {'Result': {'$ref': '#/definitions/AllWatcherId'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "AllWatcherId": { + "additionalProperties": False, + "properties": {"watcher-id": {"type": "string"}}, + "required": ["watcher-id"], + "type": "object", + }, + "ApplicationOfferStatus": { + "additionalProperties": False, + "properties": { + "active-connected-count": {"type": "integer"}, + "application-name": {"type": "string"}, + "charm": {"type": "string"}, + "endpoints": { + "patternProperties": { + ".*": {"$ref": "#/definitions/RemoteEndpoint"} + }, + "type": "object", + }, + "err": {"$ref": "#/definitions/Error"}, + "offer-name": {"type": "string"}, + "total-connected-count": {"type": "integer"}, + }, + "required": [ + "offer-name", + "application-name", + "charm", + "endpoints", + "active-connected-count", + "total-connected-count", + ], + "type": "object", + }, + "ApplicationStatus": { + "additionalProperties": False, + "properties": { + "base": {"$ref": "#/definitions/Base"}, + "can-upgrade-to": {"type": "string"}, + "charm": {"type": "string"}, + "charm-channel": {"type": "string"}, + "charm-profile": {"type": "string"}, + "charm-version": {"type": "string"}, + "endpoint-bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "err": {"$ref": "#/definitions/Error"}, + "exposed": {"type": "boolean"}, + "exposed-endpoints": { + "patternProperties": { + ".*": {"$ref": "#/definitions/ExposedEndpoint"} + }, + "type": "object", + }, + "int": {"type": "integer"}, + "life": {"type": "string"}, + "meter-statuses": { + "patternProperties": { + ".*": {"$ref": "#/definitions/MeterStatus"} + }, + "type": "object", + }, + "provider-id": {"type": "string"}, + "public-address": {"type": "string"}, + "relations": { + "patternProperties": { + ".*": {"items": {"type": "string"}, "type": "array"} + }, + "type": "object", + }, + "status": {"$ref": "#/definitions/DetailedStatus"}, + "subordinate-to": {"items": {"type": "string"}, "type": "array"}, + "units": { + "patternProperties": { + ".*": {"$ref": "#/definitions/UnitStatus"} + }, + "type": "object", + }, + "workload-version": {"type": "string"}, + }, + "required": [ + "charm", + "charm-version", + "charm-profile", + "base", + "exposed", + "life", + "relations", + "can-upgrade-to", + "subordinate-to", + "units", + "meter-statuses", + "status", + "workload-version", + "endpoint-bindings", + "public-address", + ], + "type": "object", + }, + "Base": { + "additionalProperties": False, + "properties": { + "channel": {"type": "string"}, + "name": {"type": "string"}, + }, + "required": ["name", "channel"], + "type": "object", + }, + "Binary": { + "additionalProperties": False, + "properties": { + "Arch": {"type": "string"}, + "Build": {"type": "integer"}, + "Major": {"type": "integer"}, + "Minor": {"type": "integer"}, + "Number": {"$ref": "#/definitions/Number"}, + "Patch": {"type": "integer"}, + "Release": {"type": "string"}, + "Tag": {"type": "string"}, + }, + "required": [ + "Major", + "Minor", + "Tag", + "Patch", + "Build", + "Number", + "Release", + "Arch", + ], + "type": "object", + }, + "BranchStatus": { + "additionalProperties": False, + "properties": { + "assigned-units": { + "patternProperties": { + ".*": {"items": {"type": "string"}, "type": "array"} + }, + "type": "object", + }, + "created": {"type": "integer"}, + "created-by": {"type": "string"}, + }, + "required": ["assigned-units", "created", "created-by"], + "type": "object", + }, + "DetailedStatus": { + "additionalProperties": False, + "properties": { + "data": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "err": {"$ref": "#/definitions/Error"}, + "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": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "type": "object", + }, + "ExposedEndpoint": { + "additionalProperties": False, + "properties": { + "expose-to-cidrs": {"items": {"type": "string"}, "type": "array"}, + "expose-to-spaces": {"items": {"type": "string"}, "type": "array"}, + }, + "type": "object", + }, + "FindToolsParams": { + "additionalProperties": False, + "properties": { + "agentstream": {"type": "string"}, + "arch": {"type": "string"}, + "major": {"type": "integer"}, + "number": {"$ref": "#/definitions/Number"}, + "os-type": {"type": "string"}, + }, + "required": ["number", "major", "arch", "os-type", "agentstream"], + "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", + }, + "branches": { + "patternProperties": { + ".*": {"$ref": "#/definitions/BranchStatus"} + }, + "type": "object", + }, + "controller-timestamp": {"format": "date-time", "type": "string"}, + "machines": { + "patternProperties": { + ".*": {"$ref": "#/definitions/MachineStatus"} + }, + "type": "object", + }, + "model": {"$ref": "#/definitions/ModelStatusInfo"}, + "offers": { + "patternProperties": { + ".*": {"$ref": "#/definitions/ApplicationOfferStatus"} + }, + "type": "object", + }, + "relations": { + "items": {"$ref": "#/definitions/RelationStatus"}, + "type": "array", + }, + "remote-applications": { + "patternProperties": { + ".*": {"$ref": "#/definitions/RemoteApplicationStatus"} + }, + "type": "object", + }, + }, + "required": [ + "model", + "machines", + "applications", + "remote-applications", + "offers", + "relations", + "controller-timestamp", + "branches", + ], + "type": "object", + }, + "History": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "statuses": { + "items": {"$ref": "#/definitions/DetailedStatus"}, + "type": "array", + }, + }, + "required": ["statuses"], + "type": "object", + }, + "LXDProfile": { + "additionalProperties": False, + "properties": { + "config": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "description": {"type": "string"}, + "devices": { + "patternProperties": { + ".*": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + } + }, + "type": "object", + }, + }, + "required": ["config", "description", "devices"], + "type": "object", + }, + "MachineStatus": { + "additionalProperties": False, + "properties": { + "agent-status": {"$ref": "#/definitions/DetailedStatus"}, + "base": {"$ref": "#/definitions/Base"}, + "constraints": {"type": "string"}, + "containers": { + "patternProperties": { + ".*": {"$ref": "#/definitions/MachineStatus"} + }, + "type": "object", + }, + "display-name": {"type": "string"}, + "dns-name": {"type": "string"}, + "hardware": {"type": "string"}, + "has-vote": {"type": "boolean"}, + "hostname": {"type": "string"}, + "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"}, + "lxd-profiles": { + "patternProperties": { + ".*": {"$ref": "#/definitions/LXDProfile"} + }, + "type": "object", + }, + "modification-status": {"$ref": "#/definitions/DetailedStatus"}, + "network-interfaces": { + "patternProperties": { + ".*": {"$ref": "#/definitions/NetworkInterface"} + }, + "type": "object", + }, + "primary-controller-machine": {"type": "boolean"}, + "wants-vote": {"type": "boolean"}, + }, + "required": [ + "agent-status", + "instance-status", + "modification-status", + "dns-name", + "instance-id", + "display-name", + "base", + "id", + "containers", + "constraints", + "hardware", + "jobs", + "has-vote", + "wants-vote", + ], + "type": "object", + }, + "MeterStatus": { + "additionalProperties": False, + "properties": { + "color": {"type": "string"}, + "message": {"type": "string"}, + }, + "required": ["color", "message"], + "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"}, + "type": {"type": "string"}, + "version": {"type": "string"}, + }, + "required": [ + "name", + "type", + "cloud-tag", + "version", + "available-version", + "model-status", + "meter-status", + "sla", + ], + "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"], + "type": "object", + }, + "RelationStatus": { + "additionalProperties": False, + "properties": { + "endpoints": { + "items": {"$ref": "#/definitions/EndpointStatus"}, + "type": "array", + }, + "id": {"type": "integer"}, + "interface": {"type": "string"}, + "key": {"type": "string"}, + "scope": {"type": "string"}, + "status": {"$ref": "#/definitions/DetailedStatus"}, + }, + "required": ["id", "key", "interface", "scope", "endpoints", "status"], + "type": "object", + }, + "RemoteApplicationStatus": { + "additionalProperties": False, + "properties": { + "endpoints": { + "items": {"$ref": "#/definitions/RemoteEndpoint"}, + "type": "array", + }, + "err": {"$ref": "#/definitions/Error"}, + "life": {"type": "string"}, + "offer-name": {"type": "string"}, + "offer-url": {"type": "string"}, + "relations": { + "patternProperties": { + ".*": {"items": {"type": "string"}, "type": "array"} + }, + "type": "object", + }, + "status": {"$ref": "#/definitions/DetailedStatus"}, + }, + "required": [ + "offer-url", + "offer-name", + "endpoints", + "life", + "relations", + "status", + ], + "type": "object", + }, + "RemoteEndpoint": { + "additionalProperties": False, + "properties": { + "interface": {"type": "string"}, + "limit": {"type": "integer"}, + "name": {"type": "string"}, + "role": {"type": "string"}, + }, + "required": ["name", "role", "interface", "limit"], + "type": "object", + }, + "StatusHistoryFilter": { + "additionalProperties": False, + "properties": { + "date": {"format": "date-time", "type": "string"}, + "delta": {"type": "integer"}, + "exclude": {"items": {"type": "string"}, "type": "array"}, + "size": {"type": "integer"}, + }, + "required": ["size", "date", "delta", "exclude"], + "type": "object", + }, + "StatusHistoryRequest": { + "additionalProperties": False, + "properties": { + "filter": {"$ref": "#/definitions/StatusHistoryFilter"}, + "historyKind": {"type": "string"}, + "size": {"type": "integer"}, + "tag": {"type": "string"}, + }, + "required": ["historyKind", "size", "filter", "tag"], + "type": "object", + }, + "StatusHistoryRequests": { + "additionalProperties": False, + "properties": { + "requests": { + "items": {"$ref": "#/definitions/StatusHistoryRequest"}, + "type": "array", + } + }, + "required": ["requests"], + "type": "object", + }, + "StatusHistoryResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "history": {"$ref": "#/definitions/History"}, + }, + "required": ["history"], + "type": "object", + }, + "StatusHistoryResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/StatusHistoryResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "StatusParams": { + "additionalProperties": False, + "properties": { + "patterns": {"items": {"type": "string"}, "type": "array"} + }, + "required": ["patterns"], + "type": "object", + }, + "Tools": { + "additionalProperties": False, + "properties": { + "sha256": {"type": "string"}, + "size": {"type": "integer"}, + "url": {"type": "string"}, + "version": {"$ref": "#/definitions/Binary"}, + }, + "required": ["version", "url", "size"], + "type": "object", + }, + "UnitStatus": { + "additionalProperties": False, + "properties": { + "address": {"type": "string"}, + "agent-status": {"$ref": "#/definitions/DetailedStatus"}, + "charm": {"type": "string"}, + "leader": {"type": "boolean"}, + "machine": {"type": "string"}, + "opened-ports": {"items": {"type": "string"}, "type": "array"}, + "provider-id": {"type": "string"}, + "public-address": {"type": "string"}, + "subordinates": { + "patternProperties": { + ".*": {"$ref": "#/definitions/UnitStatus"} + }, + "type": "object", + }, + "workload-status": {"$ref": "#/definitions/DetailedStatus"}, + "workload-version": {"type": "string"}, + }, + "required": [ + "agent-status", + "workload-status", + "workload-version", + "machine", + "opened-ports", + "public-address", + "charm", + "subordinates", + ], + "type": "object", + }, + }, + "properties": { + "FindTools": { + "description": "FindTools returns a List " + "containing all tools matching " + "the given parameters.\n" + "TODO(juju 3.1) - remove, used by " + "2.9 client only", + "properties": { + "Params": {"$ref": "#/definitions/FindToolsParams"}, + "Result": {"$ref": "#/definitions/FindToolsResult"}, + }, + "type": "object", + }, + "FullStatus": { + "description": "FullStatus gives the " + "information needed for juju " + "status over the api", + "properties": { + "Params": {"$ref": "#/definitions/StatusParams"}, + "Result": {"$ref": "#/definitions/FullStatus"}, + }, + "type": "object", + }, + "StatusHistory": { + "description": "StatusHistory returns a " + "slice of past statuses for " + "several entities.", + "properties": { + "Params": {"$ref": "#/definitions/StatusHistoryRequests"}, + "Result": {"$ref": "#/definitions/StatusHistoryResults"}, + }, + "type": "object", + }, + "WatchAll": { + "description": "WatchAll initiates a watcher for " + "entities in the connected model.", + "properties": {"Result": {"$ref": "#/definitions/AllWatcherId"}}, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(FindToolsResult) - async def FindTools(self, agentstream=None, arch=None, major=None, number=None, os_type=None): - ''' + async def FindTools( + self, agentstream=None, arch=None, major=None, number=None, os_type=None + ): + """ FindTools returns a List containing all tools matching the given parameters. TODO(juju 3.1) - remove, used by 2.9 client only @@ -1287,989 +1788,1424 @@ async def FindTools(self, agentstream=None, arch=None, major=None, number=None, number : Number os_type : str Returns -> FindToolsResult - ''' + """ if agentstream is not None and not isinstance(agentstream, (bytes, str)): - raise Exception("Expected agentstream to be a str, received: {}".format(type(agentstream))) + raise Exception( + "Expected agentstream to be a str, received: {}".format( + type(agentstream) + ) + ) if arch is not None and not isinstance(arch, (bytes, str)): - raise Exception("Expected arch to be a str, received: {}".format(type(arch))) + raise Exception( + "Expected arch to be a str, received: {}".format(type(arch)) + ) if major is not None and not isinstance(major, int): - raise Exception("Expected major to be a int, received: {}".format(type(major))) + raise Exception( + "Expected major to be a int, received: {}".format(type(major)) + ) if number is not None and not isinstance(number, (dict, Number)): - raise Exception("Expected number to be a Number, received: {}".format(type(number))) + raise Exception( + "Expected number to be a Number, received: {}".format(type(number)) + ) if os_type is not None and not isinstance(os_type, (bytes, str)): - raise Exception("Expected os_type to be a str, received: {}".format(type(os_type))) + raise Exception( + "Expected os_type to be a str, received: {}".format(type(os_type)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Client', - request='FindTools', - version=6, - params=_params) - _params['agentstream'] = agentstream - _params['arch'] = arch - _params['major'] = major - _params['number'] = number - _params['os-type'] = os_type + msg = dict(type="Client", request="FindTools", version=6, params=_params) + _params["agentstream"] = agentstream + _params["arch"] = arch + _params["major"] = major + _params["number"] = number + _params["os-type"] = os_type reply = await self.rpc(msg) return reply - - @ReturnMapping(FullStatus) async def FullStatus(self, patterns=None): - ''' + """ FullStatus gives the information needed for juju status over the api patterns : typing.Sequence[str] Returns -> FullStatus - ''' + """ if patterns is not None and not isinstance(patterns, (bytes, str, list)): - raise Exception("Expected patterns to be a Sequence, received: {}".format(type(patterns))) + raise Exception( + "Expected patterns to be a Sequence, received: {}".format( + type(patterns) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Client', - request='FullStatus', - version=6, - params=_params) - _params['patterns'] = patterns + msg = dict(type="Client", request="FullStatus", version=6, params=_params) + _params["patterns"] = patterns reply = await self.rpc(msg) return reply - - @ReturnMapping(StatusHistoryResults) async def StatusHistory(self, requests=None): - ''' + """ StatusHistory returns a slice of past statuses for several entities. requests : typing.Sequence[~StatusHistoryRequest] Returns -> StatusHistoryResults - ''' + """ if requests is not None and not isinstance(requests, (bytes, str, list)): - raise Exception("Expected requests to be a Sequence, received: {}".format(type(requests))) + raise Exception( + "Expected requests to be a Sequence, received: {}".format( + type(requests) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Client', - request='StatusHistory', - version=6, - params=_params) - _params['requests'] = requests + msg = dict(type="Client", request="StatusHistory", version=6, params=_params) + _params["requests"] = requests reply = await self.rpc(msg) return reply - - @ReturnMapping(AllWatcherId) async def WatchAll(self): - ''' + """ WatchAll initiates a watcher for entities in the connected model. Returns -> AllWatcherId - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Client', - request='WatchAll', - version=6, - params=_params) + msg = dict(type="Client", request="WatchAll", version=6, params=_params) reply = await self.rpc(msg) return reply - class SpacesFacade(Type): - name = 'Spaces' + name = "Spaces" version = 6 - schema = {'definitions': {'CreateSpaceParams': {'additionalProperties': False, - 'properties': {'cidrs': {'items': {'type': 'string'}, - 'type': 'array'}, - 'provider-id': {'type': 'string'}, - 'public': {'type': 'boolean'}, - 'space-tag': {'type': 'string'}}, - 'required': ['cidrs', - 'space-tag', - 'public'], - 'type': 'object'}, - 'CreateSpacesParams': {'additionalProperties': False, - 'properties': {'spaces': {'items': {'$ref': '#/definitions/CreateSpaceParams'}, - 'type': 'array'}}, - 'required': ['spaces'], - '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'}, - 'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - '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'}, - 'ListSpacesResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/Space'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'MoveSubnetsParam': {'additionalProperties': False, - 'properties': {'force': {'type': 'boolean'}, - 'space-tag': {'type': 'string'}, - 'subnets': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['subnets', - 'space-tag', - 'force'], - 'type': 'object'}, - 'MoveSubnetsParams': {'additionalProperties': False, - 'properties': {'args': {'items': {'$ref': '#/definitions/MoveSubnetsParam'}, - 'type': 'array'}}, - 'required': ['args'], - 'type': 'object'}, - 'MoveSubnetsResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'moved-subnets': {'items': {'$ref': '#/definitions/MovedSubnet'}, - 'type': 'array'}, - 'new-space': {'type': 'string'}}, - 'required': ['new-space'], - 'type': 'object'}, - 'MoveSubnetsResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/MoveSubnetsResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'MovedSubnet': {'additionalProperties': False, - 'properties': {'cidr': {'type': 'string'}, - 'old-space': {'type': 'string'}, - 'subnet': {'type': 'string'}}, - 'required': ['subnet', 'old-space', 'cidr'], - 'type': 'object'}, - 'RemoveSpaceParam': {'additionalProperties': False, - 'properties': {'dry-run': {'type': 'boolean'}, - 'force': {'type': 'boolean'}, - 'space': {'$ref': '#/definitions/Entity'}}, - 'required': ['space'], - 'type': 'object'}, - 'RemoveSpaceParams': {'additionalProperties': False, - 'properties': {'space-param': {'items': {'$ref': '#/definitions/RemoveSpaceParam'}, - 'type': 'array'}}, - 'required': ['space-param'], - 'type': 'object'}, - 'RemoveSpaceResult': {'additionalProperties': False, - 'properties': {'bindings': {'items': {'$ref': '#/definitions/Entity'}, - 'type': 'array'}, - 'constraints': {'items': {'$ref': '#/definitions/Entity'}, - 'type': 'array'}, - 'controller-settings': {'items': {'type': 'string'}, - 'type': 'array'}, - 'error': {'$ref': '#/definitions/Error'}}, - 'type': 'object'}, - 'RemoveSpaceResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/RemoveSpaceResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'RenameSpaceParams': {'additionalProperties': False, - 'properties': {'from-space-tag': {'type': 'string'}, - 'to-space-tag': {'type': 'string'}}, - 'required': ['from-space-tag', - 'to-space-tag'], - 'type': 'object'}, - 'RenameSpacesParams': {'additionalProperties': False, - 'properties': {'changes': {'items': {'$ref': '#/definitions/RenameSpaceParams'}, - 'type': 'array'}}, - 'required': ['changes'], - 'type': 'object'}, - 'ShowSpaceResult': {'additionalProperties': False, - 'properties': {'applications': {'items': {'type': 'string'}, - 'type': 'array'}, - 'error': {'$ref': '#/definitions/Error'}, - 'machine-count': {'type': 'integer'}, - 'space': {'$ref': '#/definitions/Space'}}, - 'required': ['space', - 'applications', - 'machine-count'], - 'type': 'object'}, - 'ShowSpaceResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ShowSpaceResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'Space': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'id': {'type': 'string'}, - 'name': {'type': 'string'}, - 'subnets': {'items': {'$ref': '#/definitions/Subnet'}, - 'type': 'array'}}, - 'required': ['id', 'name', 'subnets'], - 'type': 'object'}, - 'Subnet': {'additionalProperties': False, - 'properties': {'cidr': {'type': 'string'}, - 'life': {'type': 'string'}, - 'provider-id': {'type': 'string'}, - 'provider-network-id': {'type': 'string'}, - 'provider-space-id': {'type': 'string'}, - 'space-tag': {'type': 'string'}, - 'status': {'type': 'string'}, - 'vlan-tag': {'type': 'integer'}, - 'zones': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['cidr', - 'vlan-tag', - 'life', - 'space-tag', - 'zones'], - 'type': 'object'}}, - 'properties': {'CreateSpaces': {'description': 'CreateSpaces creates a new ' - 'Juju network space, ' - 'associating the\n' - 'specified subnets with it ' - '(optional; can be empty).', - 'properties': {'Params': {'$ref': '#/definitions/CreateSpacesParams'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'ListSpaces': {'description': 'ListSpaces lists all the ' - 'available spaces and their ' - 'associated subnets.', - 'properties': {'Result': {'$ref': '#/definitions/ListSpacesResults'}}, - 'type': 'object'}, - 'MoveSubnets': {'description': 'MoveSubnets ensures that the ' - 'input subnets are in the input ' - 'space.', - 'properties': {'Params': {'$ref': '#/definitions/MoveSubnetsParams'}, - 'Result': {'$ref': '#/definitions/MoveSubnetsResults'}}, - 'type': 'object'}, - 'ReloadSpaces': {'description': 'ReloadSpaces refreshes spaces ' - 'from substrate', - 'type': 'object'}, - 'RemoveSpace': {'description': 'RemoveSpace removes a space.\n' - 'Returns SpaceResults if ' - 'entities/settings are found ' - 'which makes the deletion not ' - 'possible.', - 'properties': {'Params': {'$ref': '#/definitions/RemoveSpaceParams'}, - 'Result': {'$ref': '#/definitions/RemoveSpaceResults'}}, - 'type': 'object'}, - 'RenameSpace': {'description': 'RenameSpace renames a space.', - 'properties': {'Params': {'$ref': '#/definitions/RenameSpacesParams'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'ShowSpace': {'description': 'ShowSpace shows the spaces for a ' - 'set of given entities.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ShowSpaceResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "CreateSpaceParams": { + "additionalProperties": False, + "properties": { + "cidrs": {"items": {"type": "string"}, "type": "array"}, + "provider-id": {"type": "string"}, + "public": {"type": "boolean"}, + "space-tag": {"type": "string"}, + }, + "required": ["cidrs", "space-tag", "public"], + "type": "object", + }, + "CreateSpacesParams": { + "additionalProperties": False, + "properties": { + "spaces": { + "items": {"$ref": "#/definitions/CreateSpaceParams"}, + "type": "array", + } + }, + "required": ["spaces"], + "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", + }, + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "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", + }, + "ListSpacesResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/Space"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "MoveSubnetsParam": { + "additionalProperties": False, + "properties": { + "force": {"type": "boolean"}, + "space-tag": {"type": "string"}, + "subnets": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["subnets", "space-tag", "force"], + "type": "object", + }, + "MoveSubnetsParams": { + "additionalProperties": False, + "properties": { + "args": { + "items": {"$ref": "#/definitions/MoveSubnetsParam"}, + "type": "array", + } + }, + "required": ["args"], + "type": "object", + }, + "MoveSubnetsResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "moved-subnets": { + "items": {"$ref": "#/definitions/MovedSubnet"}, + "type": "array", + }, + "new-space": {"type": "string"}, + }, + "required": ["new-space"], + "type": "object", + }, + "MoveSubnetsResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/MoveSubnetsResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "MovedSubnet": { + "additionalProperties": False, + "properties": { + "cidr": {"type": "string"}, + "old-space": {"type": "string"}, + "subnet": {"type": "string"}, + }, + "required": ["subnet", "old-space", "cidr"], + "type": "object", + }, + "RemoveSpaceParam": { + "additionalProperties": False, + "properties": { + "dry-run": {"type": "boolean"}, + "force": {"type": "boolean"}, + "space": {"$ref": "#/definitions/Entity"}, + }, + "required": ["space"], + "type": "object", + }, + "RemoveSpaceParams": { + "additionalProperties": False, + "properties": { + "space-param": { + "items": {"$ref": "#/definitions/RemoveSpaceParam"}, + "type": "array", + } + }, + "required": ["space-param"], + "type": "object", + }, + "RemoveSpaceResult": { + "additionalProperties": False, + "properties": { + "bindings": { + "items": {"$ref": "#/definitions/Entity"}, + "type": "array", + }, + "constraints": { + "items": {"$ref": "#/definitions/Entity"}, + "type": "array", + }, + "controller-settings": { + "items": {"type": "string"}, + "type": "array", + }, + "error": {"$ref": "#/definitions/Error"}, + }, + "type": "object", + }, + "RemoveSpaceResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/RemoveSpaceResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "RenameSpaceParams": { + "additionalProperties": False, + "properties": { + "from-space-tag": {"type": "string"}, + "to-space-tag": {"type": "string"}, + }, + "required": ["from-space-tag", "to-space-tag"], + "type": "object", + }, + "RenameSpacesParams": { + "additionalProperties": False, + "properties": { + "changes": { + "items": {"$ref": "#/definitions/RenameSpaceParams"}, + "type": "array", + } + }, + "required": ["changes"], + "type": "object", + }, + "ShowSpaceResult": { + "additionalProperties": False, + "properties": { + "applications": {"items": {"type": "string"}, "type": "array"}, + "error": {"$ref": "#/definitions/Error"}, + "machine-count": {"type": "integer"}, + "space": {"$ref": "#/definitions/Space"}, + }, + "required": ["space", "applications", "machine-count"], + "type": "object", + }, + "ShowSpaceResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ShowSpaceResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "Space": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "id": {"type": "string"}, + "name": {"type": "string"}, + "subnets": { + "items": {"$ref": "#/definitions/Subnet"}, + "type": "array", + }, + }, + "required": ["id", "name", "subnets"], + "type": "object", + }, + "Subnet": { + "additionalProperties": False, + "properties": { + "cidr": {"type": "string"}, + "life": {"type": "string"}, + "provider-id": {"type": "string"}, + "provider-network-id": {"type": "string"}, + "provider-space-id": {"type": "string"}, + "space-tag": {"type": "string"}, + "status": {"type": "string"}, + "vlan-tag": {"type": "integer"}, + "zones": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["cidr", "vlan-tag", "life", "space-tag", "zones"], + "type": "object", + }, + }, + "properties": { + "CreateSpaces": { + "description": "CreateSpaces creates a new " + "Juju network space, " + "associating the\n" + "specified subnets with it " + "(optional; can be empty).", + "properties": { + "Params": {"$ref": "#/definitions/CreateSpacesParams"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "ListSpaces": { + "description": "ListSpaces lists all the " + "available spaces and their " + "associated subnets.", + "properties": {"Result": {"$ref": "#/definitions/ListSpacesResults"}}, + "type": "object", + }, + "MoveSubnets": { + "description": "MoveSubnets ensures that the " + "input subnets are in the input " + "space.", + "properties": { + "Params": {"$ref": "#/definitions/MoveSubnetsParams"}, + "Result": {"$ref": "#/definitions/MoveSubnetsResults"}, + }, + "type": "object", + }, + "ReloadSpaces": { + "description": "ReloadSpaces refreshes spaces from substrate", + "type": "object", + }, + "RemoveSpace": { + "description": "RemoveSpace removes a space.\n" + "Returns SpaceResults if " + "entities/settings are found " + "which makes the deletion not " + "possible.", + "properties": { + "Params": {"$ref": "#/definitions/RemoveSpaceParams"}, + "Result": {"$ref": "#/definitions/RemoveSpaceResults"}, + }, + "type": "object", + }, + "RenameSpace": { + "description": "RenameSpace renames a space.", + "properties": { + "Params": {"$ref": "#/definitions/RenameSpacesParams"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "ShowSpace": { + "description": "ShowSpace shows the spaces for a " + "set of given entities.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/ShowSpaceResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(ErrorResults) async def CreateSpaces(self, spaces=None): - ''' + """ CreateSpaces creates a new Juju network space, associating the specified subnets with it (optional; can be empty). spaces : typing.Sequence[~CreateSpaceParams] Returns -> ErrorResults - ''' + """ if spaces is not None and not isinstance(spaces, (bytes, str, list)): - raise Exception("Expected spaces to be a Sequence, received: {}".format(type(spaces))) + raise Exception( + "Expected spaces to be a Sequence, received: {}".format(type(spaces)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Spaces', - request='CreateSpaces', - version=6, - params=_params) - _params['spaces'] = spaces + msg = dict(type="Spaces", request="CreateSpaces", version=6, params=_params) + _params["spaces"] = spaces reply = await self.rpc(msg) return reply - - @ReturnMapping(ListSpacesResults) async def ListSpaces(self): - ''' + """ ListSpaces lists all the available spaces and their associated subnets. Returns -> ListSpacesResults - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Spaces', - request='ListSpaces', - version=6, - params=_params) + msg = dict(type="Spaces", request="ListSpaces", version=6, params=_params) reply = await self.rpc(msg) return reply - - @ReturnMapping(MoveSubnetsResults) async def MoveSubnets(self, args=None): - ''' + """ MoveSubnets ensures that the input subnets are in the input space. args : typing.Sequence[~MoveSubnetsParam] Returns -> MoveSubnetsResults - ''' + """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception("Expected args to be a Sequence, received: {}".format(type(args))) + raise Exception( + "Expected args to be a Sequence, received: {}".format(type(args)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Spaces', - request='MoveSubnets', - version=6, - params=_params) - _params['args'] = args + msg = dict(type="Spaces", request="MoveSubnets", version=6, params=_params) + _params["args"] = args reply = await self.rpc(msg) return reply - - @ReturnMapping(None) async def ReloadSpaces(self): - ''' + """ ReloadSpaces refreshes spaces from substrate Returns -> None - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Spaces', - request='ReloadSpaces', - version=6, - params=_params) + msg = dict(type="Spaces", request="ReloadSpaces", version=6, params=_params) reply = await self.rpc(msg) return reply - - @ReturnMapping(RemoveSpaceResults) async def RemoveSpace(self, space_param=None): - ''' + """ RemoveSpace removes a space. Returns SpaceResults if entities/settings are found which makes the deletion not possible. space_param : typing.Sequence[~RemoveSpaceParam] Returns -> RemoveSpaceResults - ''' + """ if space_param is not None and not isinstance(space_param, (bytes, str, list)): - raise Exception("Expected space_param to be a Sequence, received: {}".format(type(space_param))) + raise Exception( + "Expected space_param to be a Sequence, received: {}".format( + type(space_param) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Spaces', - request='RemoveSpace', - version=6, - params=_params) - _params['space-param'] = space_param + msg = dict(type="Spaces", request="RemoveSpace", version=6, params=_params) + _params["space-param"] = space_param reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def RenameSpace(self, changes=None): - ''' + """ RenameSpace renames a space. changes : typing.Sequence[~RenameSpaceParams] Returns -> ErrorResults - ''' + """ if changes is not None and not isinstance(changes, (bytes, str, list)): - raise Exception("Expected changes to be a Sequence, received: {}".format(type(changes))) + raise Exception( + "Expected changes to be a Sequence, received: {}".format(type(changes)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Spaces', - request='RenameSpace', - version=6, - params=_params) - _params['changes'] = changes + msg = dict(type="Spaces", request="RenameSpace", version=6, params=_params) + _params["changes"] = changes reply = await self.rpc(msg) return reply - - @ReturnMapping(ShowSpaceResults) async def ShowSpace(self, entities=None): - ''' + """ ShowSpace shows the spaces for a set of given entities. entities : typing.Sequence[~Entity] Returns -> ShowSpaceResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Spaces', - request='ShowSpace', - version=6, - params=_params) - _params['entities'] = entities + msg = dict(type="Spaces", request="ShowSpace", version=6, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - class StorageFacade(Type): - name = 'Storage' + name = "Storage" version = 6 - schema = {'definitions': {'AddStorageDetails': {'additionalProperties': False, - 'properties': {'storage-tags': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['storage-tags'], - 'type': 'object'}, - 'AddStorageResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/AddStorageDetails'}}, - 'type': 'object'}, - 'AddStorageResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/AddStorageResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'BulkImportStorageParams': {'additionalProperties': False, - 'properties': {'storage': {'items': {'$ref': '#/definitions/ImportStorageParams'}, - 'type': 'array'}}, - 'required': ['storage'], - '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'}, - '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': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - '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'}, - 'FilesystemAttachmentDetails': {'additionalProperties': False, - 'properties': {'FilesystemAttachmentInfo': {'$ref': '#/definitions/FilesystemAttachmentInfo'}, - 'life': {'type': 'string'}, - 'mount-point': {'type': 'string'}, - 'read-only': {'type': 'boolean'}}, - 'required': ['FilesystemAttachmentInfo'], - 'type': 'object'}, - 'FilesystemAttachmentInfo': {'additionalProperties': False, - 'properties': {'mount-point': {'type': 'string'}, - 'read-only': {'type': 'boolean'}}, - 'type': 'object'}, - 'FilesystemDetails': {'additionalProperties': False, - 'properties': {'filesystem-tag': {'type': 'string'}, - 'info': {'$ref': '#/definitions/FilesystemInfo'}, - 'life': {'type': 'string'}, - 'machine-attachments': {'patternProperties': {'.*': {'$ref': '#/definitions/FilesystemAttachmentDetails'}}, - 'type': 'object'}, - 'status': {'$ref': '#/definitions/EntityStatus'}, - 'storage': {'$ref': '#/definitions/StorageDetails'}, - 'unit-attachments': {'patternProperties': {'.*': {'$ref': '#/definitions/FilesystemAttachmentDetails'}}, - 'type': 'object'}, - 'volume-tag': {'type': 'string'}}, - 'required': ['filesystem-tag', - 'info', - 'status'], - 'type': 'object'}, - 'FilesystemDetailsListResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'items': {'$ref': '#/definitions/FilesystemDetails'}, - 'type': 'array'}}, - 'type': 'object'}, - 'FilesystemDetailsListResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/FilesystemDetailsListResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'FilesystemFilter': {'additionalProperties': False, - 'properties': {'machines': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'FilesystemFilters': {'additionalProperties': False, - 'properties': {'filters': {'items': {'$ref': '#/definitions/FilesystemFilter'}, - 'type': 'array'}}, - 'type': 'object'}, - 'FilesystemInfo': {'additionalProperties': False, - 'properties': {'filesystem-id': {'type': 'string'}, - 'pool': {'type': 'string'}, - 'size': {'type': 'integer'}}, - 'required': ['filesystem-id', - 'pool', - 'size'], - 'type': 'object'}, - 'ImportStorageDetails': {'additionalProperties': False, - 'properties': {'storage-tag': {'type': 'string'}}, - 'required': ['storage-tag'], - 'type': 'object'}, - 'ImportStorageParams': {'additionalProperties': False, - 'properties': {'kind': {'type': 'integer'}, - 'pool': {'type': 'string'}, - 'provider-id': {'type': 'string'}, - 'storage-name': {'type': 'string'}}, - 'required': ['kind', - 'pool', - 'provider-id', - 'storage-name'], - 'type': 'object'}, - 'ImportStorageResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/ImportStorageDetails'}}, - 'type': 'object'}, - 'ImportStorageResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ImportStorageResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'RemoveStorage': {'additionalProperties': False, - 'properties': {'storage': {'items': {'$ref': '#/definitions/RemoveStorageInstance'}, - 'type': 'array'}}, - 'required': ['storage'], - 'type': 'object'}, - 'RemoveStorageInstance': {'additionalProperties': False, - 'properties': {'destroy-attachments': {'type': 'boolean'}, - 'destroy-storage': {'type': 'boolean'}, - 'force': {'type': 'boolean'}, - 'max-wait': {'type': 'integer'}, - 'tag': {'type': 'string'}}, - 'required': ['tag'], - 'type': 'object'}, - 'StorageAddParams': {'additionalProperties': False, - 'properties': {'name': {'type': 'string'}, - 'storage': {'$ref': '#/definitions/StorageConstraints'}, - 'unit': {'type': 'string'}}, - 'required': ['unit', 'name', 'storage'], - 'type': 'object'}, - 'StorageAttachmentDetails': {'additionalProperties': False, - 'properties': {'life': {'type': 'string'}, - 'location': {'type': 'string'}, - 'machine-tag': {'type': 'string'}, - 'storage-tag': {'type': 'string'}, - 'unit-tag': {'type': 'string'}}, - 'required': ['storage-tag', - 'unit-tag', - 'machine-tag'], - 'type': 'object'}, - 'StorageAttachmentId': {'additionalProperties': False, - 'properties': {'storage-tag': {'type': 'string'}, - 'unit-tag': {'type': 'string'}}, - 'required': ['storage-tag', - 'unit-tag'], - 'type': 'object'}, - 'StorageAttachmentIds': {'additionalProperties': False, - 'properties': {'ids': {'items': {'$ref': '#/definitions/StorageAttachmentId'}, - 'type': 'array'}}, - 'required': ['ids'], - 'type': 'object'}, - 'StorageConstraints': {'additionalProperties': False, - 'properties': {'count': {'type': 'integer'}, - 'pool': {'type': 'string'}, - 'size': {'type': 'integer'}}, - 'type': 'object'}, - 'StorageDetachmentParams': {'additionalProperties': False, - 'properties': {'force': {'type': 'boolean'}, - 'ids': {'$ref': '#/definitions/StorageAttachmentIds'}, - 'max-wait': {'type': 'integer'}}, - 'required': ['ids'], - 'type': 'object'}, - 'StorageDetails': {'additionalProperties': False, - 'properties': {'attachments': {'patternProperties': {'.*': {'$ref': '#/definitions/StorageAttachmentDetails'}}, - 'type': 'object'}, - 'kind': {'type': 'integer'}, - 'life': {'type': 'string'}, - 'owner-tag': {'type': 'string'}, - 'persistent': {'type': 'boolean'}, - 'status': {'$ref': '#/definitions/EntityStatus'}, - 'storage-tag': {'type': 'string'}}, - 'required': ['storage-tag', - 'owner-tag', - 'kind', - 'status', - 'persistent'], - 'type': 'object'}, - 'StorageDetailsListResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'items': {'$ref': '#/definitions/StorageDetails'}, - 'type': 'array'}}, - 'type': 'object'}, - 'StorageDetailsListResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/StorageDetailsListResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'StorageDetailsResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/StorageDetails'}}, - 'type': 'object'}, - 'StorageDetailsResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/StorageDetailsResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'StorageFilter': {'additionalProperties': False, - 'type': 'object'}, - 'StorageFilters': {'additionalProperties': False, - 'properties': {'filters': {'items': {'$ref': '#/definitions/StorageFilter'}, - 'type': 'array'}}, - 'type': 'object'}, - 'StoragePool': {'additionalProperties': False, - 'properties': {'attrs': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'name': {'type': 'string'}, - 'provider': {'type': 'string'}}, - 'required': ['name', 'provider', 'attrs'], - 'type': 'object'}, - 'StoragePoolArgs': {'additionalProperties': False, - 'properties': {'pools': {'items': {'$ref': '#/definitions/StoragePool'}, - 'type': 'array'}}, - 'required': ['pools'], - 'type': 'object'}, - 'StoragePoolDeleteArg': {'additionalProperties': False, - 'properties': {'name': {'type': 'string'}}, - 'required': ['name'], - 'type': 'object'}, - 'StoragePoolDeleteArgs': {'additionalProperties': False, - 'properties': {'pools': {'items': {'$ref': '#/definitions/StoragePoolDeleteArg'}, - 'type': 'array'}}, - 'required': ['pools'], - 'type': 'object'}, - 'StoragePoolFilter': {'additionalProperties': False, - 'properties': {'names': {'items': {'type': 'string'}, - 'type': 'array'}, - 'providers': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'StoragePoolFilters': {'additionalProperties': False, - 'properties': {'filters': {'items': {'$ref': '#/definitions/StoragePoolFilter'}, - 'type': 'array'}}, - 'type': 'object'}, - 'StoragePoolsResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'storage-pools': {'items': {'$ref': '#/definitions/StoragePool'}, - 'type': 'array'}}, - 'type': 'object'}, - 'StoragePoolsResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/StoragePoolsResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'StoragesAddParams': {'additionalProperties': False, - 'properties': {'storages': {'items': {'$ref': '#/definitions/StorageAddParams'}, - 'type': 'array'}}, - 'required': ['storages'], - 'type': 'object'}, - 'VolumeAttachmentDetails': {'additionalProperties': False, - 'properties': {'VolumeAttachmentInfo': {'$ref': '#/definitions/VolumeAttachmentInfo'}, - 'bus-address': {'type': 'string'}, - 'device-link': {'type': 'string'}, - 'device-name': {'type': 'string'}, - 'life': {'type': 'string'}, - 'plan-info': {'$ref': '#/definitions/VolumeAttachmentPlanInfo'}, - 'read-only': {'type': 'boolean'}}, - 'required': ['VolumeAttachmentInfo'], - 'type': 'object'}, - 'VolumeAttachmentInfo': {'additionalProperties': False, - 'properties': {'bus-address': {'type': 'string'}, - 'device-link': {'type': 'string'}, - 'device-name': {'type': 'string'}, - 'plan-info': {'$ref': '#/definitions/VolumeAttachmentPlanInfo'}, - 'read-only': {'type': 'boolean'}}, - 'type': 'object'}, - 'VolumeAttachmentPlanInfo': {'additionalProperties': False, - 'properties': {'device-attributes': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'device-type': {'type': 'string'}}, - 'type': 'object'}, - 'VolumeDetails': {'additionalProperties': False, - 'properties': {'info': {'$ref': '#/definitions/VolumeInfo'}, - 'life': {'type': 'string'}, - 'machine-attachments': {'patternProperties': {'.*': {'$ref': '#/definitions/VolumeAttachmentDetails'}}, - 'type': 'object'}, - 'status': {'$ref': '#/definitions/EntityStatus'}, - 'storage': {'$ref': '#/definitions/StorageDetails'}, - 'unit-attachments': {'patternProperties': {'.*': {'$ref': '#/definitions/VolumeAttachmentDetails'}}, - 'type': 'object'}, - 'volume-tag': {'type': 'string'}}, - 'required': ['volume-tag', 'info', 'status'], - 'type': 'object'}, - 'VolumeDetailsListResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'items': {'$ref': '#/definitions/VolumeDetails'}, - 'type': 'array'}}, - 'type': 'object'}, - 'VolumeDetailsListResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/VolumeDetailsListResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'VolumeFilter': {'additionalProperties': False, - 'properties': {'machines': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'VolumeFilters': {'additionalProperties': False, - 'properties': {'filters': {'items': {'$ref': '#/definitions/VolumeFilter'}, - 'type': 'array'}}, - 'type': 'object'}, - 'VolumeInfo': {'additionalProperties': False, - 'properties': {'hardware-id': {'type': 'string'}, - 'persistent': {'type': 'boolean'}, - 'pool': {'type': 'string'}, - 'size': {'type': 'integer'}, - 'volume-id': {'type': 'string'}, - 'wwn': {'type': 'string'}}, - 'required': ['volume-id', 'size', 'persistent'], - 'type': 'object'}}, - 'properties': {'AddToUnit': {'description': 'AddToUnit validates and creates ' - 'additional storage instances for ' - 'units.\n' - 'A "CHANGE" block can block this ' - 'operation.', - 'properties': {'Params': {'$ref': '#/definitions/StoragesAddParams'}, - 'Result': {'$ref': '#/definitions/AddStorageResults'}}, - 'type': 'object'}, - 'Attach': {'description': 'Attach attaches existing storage ' - 'instances to units.\n' - 'A "CHANGE" block can block this ' - 'operation.', - 'properties': {'Params': {'$ref': '#/definitions/StorageAttachmentIds'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'CreatePool': {'description': 'CreatePool creates a new pool ' - 'with specified parameters.', - 'properties': {'Params': {'$ref': '#/definitions/StoragePoolArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'DetachStorage': {'description': 'DetachStorage sets the ' - 'specified storage ' - 'attachments to Dying, unless ' - 'they are\n' - 'already Dying or Dead. Any ' - 'associated, persistent ' - 'storage will remain\n' - 'alive. This call can be ' - 'forced.', - 'properties': {'Params': {'$ref': '#/definitions/StorageDetachmentParams'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'Import': {'description': 'Import imports existing storage ' - 'into the model.\n' - 'A "CHANGE" block can block this ' - 'operation.', - 'properties': {'Params': {'$ref': '#/definitions/BulkImportStorageParams'}, - 'Result': {'$ref': '#/definitions/ImportStorageResults'}}, - 'type': 'object'}, - 'ListFilesystems': {'description': 'ListFilesystems returns a ' - 'list of filesystems in the ' - 'environment matching\n' - 'the provided filter. Each ' - 'result describes a ' - 'filesystem in detail, ' - 'including\n' - "the filesystem's " - 'attachments.', - 'properties': {'Params': {'$ref': '#/definitions/FilesystemFilters'}, - 'Result': {'$ref': '#/definitions/FilesystemDetailsListResults'}}, - 'type': 'object'}, - 'ListPools': {'description': 'ListPools returns a list of ' - 'pools.\n' - 'If filter is provided, returned ' - 'list only contains pools that ' - 'match\n' - 'the filter.\n' - 'Pools can be filtered on names ' - 'and provider types.\n' - 'If both names and types are ' - 'provided as filter,\n' - 'pools that match either are ' - 'returned.\n' - 'This method lists union of pools ' - 'and environment provider types.\n' - 'If no filter is provided, all ' - 'pools are returned.', - 'properties': {'Params': {'$ref': '#/definitions/StoragePoolFilters'}, - 'Result': {'$ref': '#/definitions/StoragePoolsResults'}}, - 'type': 'object'}, - 'ListStorageDetails': {'description': 'ListStorageDetails ' - 'returns storage ' - 'matching a filter.', - 'properties': {'Params': {'$ref': '#/definitions/StorageFilters'}, - 'Result': {'$ref': '#/definitions/StorageDetailsListResults'}}, - 'type': 'object'}, - 'ListVolumes': {'description': 'ListVolumes lists volumes with ' - 'the given filters. Each filter ' - 'produces\n' - 'an independent list of ' - 'volumes, or an error if the ' - 'filter is invalid\n' - 'or the volumes could not be ' - 'listed.', - 'properties': {'Params': {'$ref': '#/definitions/VolumeFilters'}, - 'Result': {'$ref': '#/definitions/VolumeDetailsListResults'}}, - 'type': 'object'}, - 'Remove': {'description': 'Remove sets the specified storage ' - 'entities to Dying, unless they are\n' - 'already Dying or Dead, such that ' - 'the storage will eventually be ' - 'removed\n' - 'from the model. If the arguments ' - 'specify that the storage should be\n' - 'destroyed, then the associated ' - 'cloud storage will be destroyed ' - 'first;\n' - 'otherwise it will only be released ' - "from Juju's control.", - 'properties': {'Params': {'$ref': '#/definitions/RemoveStorage'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'RemovePool': {'description': 'RemovePool deletes the named ' - 'pool', - 'properties': {'Params': {'$ref': '#/definitions/StoragePoolDeleteArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'StorageDetails': {'description': 'StorageDetails retrieves ' - 'and returns detailed ' - 'information about desired\n' - 'storage identified by ' - 'supplied tags. If specified ' - 'storage cannot be\n' - 'retrieved, individual error ' - 'is returned instead of ' - 'storage information.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/StorageDetailsResults'}}, - 'type': 'object'}, - 'UpdatePool': {'description': 'UpdatePool deletes the named ' - 'pool', - 'properties': {'Params': {'$ref': '#/definitions/StoragePoolArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "AddStorageDetails": { + "additionalProperties": False, + "properties": { + "storage-tags": {"items": {"type": "string"}, "type": "array"} + }, + "required": ["storage-tags"], + "type": "object", + }, + "AddStorageResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/AddStorageDetails"}, + }, + "type": "object", + }, + "AddStorageResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/AddStorageResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "BulkImportStorageParams": { + "additionalProperties": False, + "properties": { + "storage": { + "items": {"$ref": "#/definitions/ImportStorageParams"}, + "type": "array", + } + }, + "required": ["storage"], + "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", + }, + "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": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "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", + }, + "FilesystemAttachmentDetails": { + "additionalProperties": False, + "properties": { + "FilesystemAttachmentInfo": { + "$ref": "#/definitions/FilesystemAttachmentInfo" + }, + "life": {"type": "string"}, + "mount-point": {"type": "string"}, + "read-only": {"type": "boolean"}, + }, + "required": ["FilesystemAttachmentInfo"], + "type": "object", + }, + "FilesystemAttachmentInfo": { + "additionalProperties": False, + "properties": { + "mount-point": {"type": "string"}, + "read-only": {"type": "boolean"}, + }, + "type": "object", + }, + "FilesystemDetails": { + "additionalProperties": False, + "properties": { + "filesystem-tag": {"type": "string"}, + "info": {"$ref": "#/definitions/FilesystemInfo"}, + "life": {"type": "string"}, + "machine-attachments": { + "patternProperties": { + ".*": {"$ref": "#/definitions/FilesystemAttachmentDetails"} + }, + "type": "object", + }, + "status": {"$ref": "#/definitions/EntityStatus"}, + "storage": {"$ref": "#/definitions/StorageDetails"}, + "unit-attachments": { + "patternProperties": { + ".*": {"$ref": "#/definitions/FilesystemAttachmentDetails"} + }, + "type": "object", + }, + "volume-tag": {"type": "string"}, + }, + "required": ["filesystem-tag", "info", "status"], + "type": "object", + }, + "FilesystemDetailsListResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": { + "items": {"$ref": "#/definitions/FilesystemDetails"}, + "type": "array", + }, + }, + "type": "object", + }, + "FilesystemDetailsListResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/FilesystemDetailsListResult"}, + "type": "array", + } + }, + "type": "object", + }, + "FilesystemFilter": { + "additionalProperties": False, + "properties": { + "machines": {"items": {"type": "string"}, "type": "array"} + }, + "type": "object", + }, + "FilesystemFilters": { + "additionalProperties": False, + "properties": { + "filters": { + "items": {"$ref": "#/definitions/FilesystemFilter"}, + "type": "array", + } + }, + "type": "object", + }, + "FilesystemInfo": { + "additionalProperties": False, + "properties": { + "filesystem-id": {"type": "string"}, + "pool": {"type": "string"}, + "size": {"type": "integer"}, + }, + "required": ["filesystem-id", "pool", "size"], + "type": "object", + }, + "ImportStorageDetails": { + "additionalProperties": False, + "properties": {"storage-tag": {"type": "string"}}, + "required": ["storage-tag"], + "type": "object", + }, + "ImportStorageParams": { + "additionalProperties": False, + "properties": { + "kind": {"type": "integer"}, + "pool": {"type": "string"}, + "provider-id": {"type": "string"}, + "storage-name": {"type": "string"}, + }, + "required": ["kind", "pool", "provider-id", "storage-name"], + "type": "object", + }, + "ImportStorageResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/ImportStorageDetails"}, + }, + "type": "object", + }, + "ImportStorageResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ImportStorageResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "RemoveStorage": { + "additionalProperties": False, + "properties": { + "storage": { + "items": {"$ref": "#/definitions/RemoveStorageInstance"}, + "type": "array", + } + }, + "required": ["storage"], + "type": "object", + }, + "RemoveStorageInstance": { + "additionalProperties": False, + "properties": { + "destroy-attachments": {"type": "boolean"}, + "destroy-storage": {"type": "boolean"}, + "force": {"type": "boolean"}, + "max-wait": {"type": "integer"}, + "tag": {"type": "string"}, + }, + "required": ["tag"], + "type": "object", + }, + "StorageAddParams": { + "additionalProperties": False, + "properties": { + "name": {"type": "string"}, + "storage": {"$ref": "#/definitions/StorageConstraints"}, + "unit": {"type": "string"}, + }, + "required": ["unit", "name", "storage"], + "type": "object", + }, + "StorageAttachmentDetails": { + "additionalProperties": False, + "properties": { + "life": {"type": "string"}, + "location": {"type": "string"}, + "machine-tag": {"type": "string"}, + "storage-tag": {"type": "string"}, + "unit-tag": {"type": "string"}, + }, + "required": ["storage-tag", "unit-tag", "machine-tag"], + "type": "object", + }, + "StorageAttachmentId": { + "additionalProperties": False, + "properties": { + "storage-tag": {"type": "string"}, + "unit-tag": {"type": "string"}, + }, + "required": ["storage-tag", "unit-tag"], + "type": "object", + }, + "StorageAttachmentIds": { + "additionalProperties": False, + "properties": { + "ids": { + "items": {"$ref": "#/definitions/StorageAttachmentId"}, + "type": "array", + } + }, + "required": ["ids"], + "type": "object", + }, + "StorageConstraints": { + "additionalProperties": False, + "properties": { + "count": {"type": "integer"}, + "pool": {"type": "string"}, + "size": {"type": "integer"}, + }, + "type": "object", + }, + "StorageDetachmentParams": { + "additionalProperties": False, + "properties": { + "force": {"type": "boolean"}, + "ids": {"$ref": "#/definitions/StorageAttachmentIds"}, + "max-wait": {"type": "integer"}, + }, + "required": ["ids"], + "type": "object", + }, + "StorageDetails": { + "additionalProperties": False, + "properties": { + "attachments": { + "patternProperties": { + ".*": {"$ref": "#/definitions/StorageAttachmentDetails"} + }, + "type": "object", + }, + "kind": {"type": "integer"}, + "life": {"type": "string"}, + "owner-tag": {"type": "string"}, + "persistent": {"type": "boolean"}, + "status": {"$ref": "#/definitions/EntityStatus"}, + "storage-tag": {"type": "string"}, + }, + "required": [ + "storage-tag", + "owner-tag", + "kind", + "status", + "persistent", + ], + "type": "object", + }, + "StorageDetailsListResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": { + "items": {"$ref": "#/definitions/StorageDetails"}, + "type": "array", + }, + }, + "type": "object", + }, + "StorageDetailsListResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/StorageDetailsListResult"}, + "type": "array", + } + }, + "type": "object", + }, + "StorageDetailsResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/StorageDetails"}, + }, + "type": "object", + }, + "StorageDetailsResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/StorageDetailsResult"}, + "type": "array", + } + }, + "type": "object", + }, + "StorageFilter": {"additionalProperties": False, "type": "object"}, + "StorageFilters": { + "additionalProperties": False, + "properties": { + "filters": { + "items": {"$ref": "#/definitions/StorageFilter"}, + "type": "array", + } + }, + "type": "object", + }, + "StoragePool": { + "additionalProperties": False, + "properties": { + "attrs": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "name": {"type": "string"}, + "provider": {"type": "string"}, + }, + "required": ["name", "provider", "attrs"], + "type": "object", + }, + "StoragePoolArgs": { + "additionalProperties": False, + "properties": { + "pools": { + "items": {"$ref": "#/definitions/StoragePool"}, + "type": "array", + } + }, + "required": ["pools"], + "type": "object", + }, + "StoragePoolDeleteArg": { + "additionalProperties": False, + "properties": {"name": {"type": "string"}}, + "required": ["name"], + "type": "object", + }, + "StoragePoolDeleteArgs": { + "additionalProperties": False, + "properties": { + "pools": { + "items": {"$ref": "#/definitions/StoragePoolDeleteArg"}, + "type": "array", + } + }, + "required": ["pools"], + "type": "object", + }, + "StoragePoolFilter": { + "additionalProperties": False, + "properties": { + "names": {"items": {"type": "string"}, "type": "array"}, + "providers": {"items": {"type": "string"}, "type": "array"}, + }, + "type": "object", + }, + "StoragePoolFilters": { + "additionalProperties": False, + "properties": { + "filters": { + "items": {"$ref": "#/definitions/StoragePoolFilter"}, + "type": "array", + } + }, + "type": "object", + }, + "StoragePoolsResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "storage-pools": { + "items": {"$ref": "#/definitions/StoragePool"}, + "type": "array", + }, + }, + "type": "object", + }, + "StoragePoolsResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/StoragePoolsResult"}, + "type": "array", + } + }, + "type": "object", + }, + "StoragesAddParams": { + "additionalProperties": False, + "properties": { + "storages": { + "items": {"$ref": "#/definitions/StorageAddParams"}, + "type": "array", + } + }, + "required": ["storages"], + "type": "object", + }, + "VolumeAttachmentDetails": { + "additionalProperties": False, + "properties": { + "VolumeAttachmentInfo": { + "$ref": "#/definitions/VolumeAttachmentInfo" + }, + "bus-address": {"type": "string"}, + "device-link": {"type": "string"}, + "device-name": {"type": "string"}, + "life": {"type": "string"}, + "plan-info": {"$ref": "#/definitions/VolumeAttachmentPlanInfo"}, + "read-only": {"type": "boolean"}, + }, + "required": ["VolumeAttachmentInfo"], + "type": "object", + }, + "VolumeAttachmentInfo": { + "additionalProperties": False, + "properties": { + "bus-address": {"type": "string"}, + "device-link": {"type": "string"}, + "device-name": {"type": "string"}, + "plan-info": {"$ref": "#/definitions/VolumeAttachmentPlanInfo"}, + "read-only": {"type": "boolean"}, + }, + "type": "object", + }, + "VolumeAttachmentPlanInfo": { + "additionalProperties": False, + "properties": { + "device-attributes": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "device-type": {"type": "string"}, + }, + "type": "object", + }, + "VolumeDetails": { + "additionalProperties": False, + "properties": { + "info": {"$ref": "#/definitions/VolumeInfo"}, + "life": {"type": "string"}, + "machine-attachments": { + "patternProperties": { + ".*": {"$ref": "#/definitions/VolumeAttachmentDetails"} + }, + "type": "object", + }, + "status": {"$ref": "#/definitions/EntityStatus"}, + "storage": {"$ref": "#/definitions/StorageDetails"}, + "unit-attachments": { + "patternProperties": { + ".*": {"$ref": "#/definitions/VolumeAttachmentDetails"} + }, + "type": "object", + }, + "volume-tag": {"type": "string"}, + }, + "required": ["volume-tag", "info", "status"], + "type": "object", + }, + "VolumeDetailsListResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": { + "items": {"$ref": "#/definitions/VolumeDetails"}, + "type": "array", + }, + }, + "type": "object", + }, + "VolumeDetailsListResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/VolumeDetailsListResult"}, + "type": "array", + } + }, + "type": "object", + }, + "VolumeFilter": { + "additionalProperties": False, + "properties": { + "machines": {"items": {"type": "string"}, "type": "array"} + }, + "type": "object", + }, + "VolumeFilters": { + "additionalProperties": False, + "properties": { + "filters": { + "items": {"$ref": "#/definitions/VolumeFilter"}, + "type": "array", + } + }, + "type": "object", + }, + "VolumeInfo": { + "additionalProperties": False, + "properties": { + "hardware-id": {"type": "string"}, + "persistent": {"type": "boolean"}, + "pool": {"type": "string"}, + "size": {"type": "integer"}, + "volume-id": {"type": "string"}, + "wwn": {"type": "string"}, + }, + "required": ["volume-id", "size", "persistent"], + "type": "object", + }, + }, + "properties": { + "AddToUnit": { + "description": "AddToUnit validates and creates " + "additional storage instances for " + "units.\n" + 'A "CHANGE" block can block this ' + "operation.", + "properties": { + "Params": {"$ref": "#/definitions/StoragesAddParams"}, + "Result": {"$ref": "#/definitions/AddStorageResults"}, + }, + "type": "object", + }, + "Attach": { + "description": "Attach attaches existing storage " + "instances to units.\n" + 'A "CHANGE" block can block this ' + "operation.", + "properties": { + "Params": {"$ref": "#/definitions/StorageAttachmentIds"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "CreatePool": { + "description": "CreatePool creates a new pool " + "with specified parameters.", + "properties": { + "Params": {"$ref": "#/definitions/StoragePoolArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "DetachStorage": { + "description": "DetachStorage sets the " + "specified storage " + "attachments to Dying, unless " + "they are\n" + "already Dying or Dead. Any " + "associated, persistent " + "storage will remain\n" + "alive. This call can be " + "forced.", + "properties": { + "Params": {"$ref": "#/definitions/StorageDetachmentParams"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "Import": { + "description": "Import imports existing storage " + "into the model.\n" + 'A "CHANGE" block can block this ' + "operation.", + "properties": { + "Params": {"$ref": "#/definitions/BulkImportStorageParams"}, + "Result": {"$ref": "#/definitions/ImportStorageResults"}, + }, + "type": "object", + }, + "ListFilesystems": { + "description": "ListFilesystems returns a " + "list of filesystems in the " + "environment matching\n" + "the provided filter. Each " + "result describes a " + "filesystem in detail, " + "including\n" + "the filesystem's " + "attachments.", + "properties": { + "Params": {"$ref": "#/definitions/FilesystemFilters"}, + "Result": {"$ref": "#/definitions/FilesystemDetailsListResults"}, + }, + "type": "object", + }, + "ListPools": { + "description": "ListPools returns a list of " + "pools.\n" + "If filter is provided, returned " + "list only contains pools that " + "match\n" + "the filter.\n" + "Pools can be filtered on names " + "and provider types.\n" + "If both names and types are " + "provided as filter,\n" + "pools that match either are " + "returned.\n" + "This method lists union of pools " + "and environment provider types.\n" + "If no filter is provided, all " + "pools are returned.", + "properties": { + "Params": {"$ref": "#/definitions/StoragePoolFilters"}, + "Result": {"$ref": "#/definitions/StoragePoolsResults"}, + }, + "type": "object", + }, + "ListStorageDetails": { + "description": "ListStorageDetails returns storage matching a filter.", + "properties": { + "Params": {"$ref": "#/definitions/StorageFilters"}, + "Result": {"$ref": "#/definitions/StorageDetailsListResults"}, + }, + "type": "object", + }, + "ListVolumes": { + "description": "ListVolumes lists volumes with " + "the given filters. Each filter " + "produces\n" + "an independent list of " + "volumes, or an error if the " + "filter is invalid\n" + "or the volumes could not be " + "listed.", + "properties": { + "Params": {"$ref": "#/definitions/VolumeFilters"}, + "Result": {"$ref": "#/definitions/VolumeDetailsListResults"}, + }, + "type": "object", + }, + "Remove": { + "description": "Remove sets the specified storage " + "entities to Dying, unless they are\n" + "already Dying or Dead, such that " + "the storage will eventually be " + "removed\n" + "from the model. If the arguments " + "specify that the storage should be\n" + "destroyed, then the associated " + "cloud storage will be destroyed " + "first;\n" + "otherwise it will only be released " + "from Juju's control.", + "properties": { + "Params": {"$ref": "#/definitions/RemoveStorage"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "RemovePool": { + "description": "RemovePool deletes the named pool", + "properties": { + "Params": {"$ref": "#/definitions/StoragePoolDeleteArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "StorageDetails": { + "description": "StorageDetails retrieves " + "and returns detailed " + "information about desired\n" + "storage identified by " + "supplied tags. If specified " + "storage cannot be\n" + "retrieved, individual error " + "is returned instead of " + "storage information.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/StorageDetailsResults"}, + }, + "type": "object", + }, + "UpdatePool": { + "description": "UpdatePool deletes the named pool", + "properties": { + "Params": {"$ref": "#/definitions/StoragePoolArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(AddStorageResults) async def AddToUnit(self, storages=None): - ''' + """ AddToUnit validates and creates additional storage instances for units. A "CHANGE" block can block this operation. storages : typing.Sequence[~StorageAddParams] Returns -> AddStorageResults - ''' + """ if storages is not None and not isinstance(storages, (bytes, str, list)): - raise Exception("Expected storages to be a Sequence, received: {}".format(type(storages))) + raise Exception( + "Expected storages to be a Sequence, received: {}".format( + type(storages) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Storage', - request='AddToUnit', - version=6, - params=_params) - _params['storages'] = storages + msg = dict(type="Storage", request="AddToUnit", version=6, params=_params) + _params["storages"] = storages reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def Attach(self, ids=None): - ''' + """ Attach attaches existing storage instances to units. A "CHANGE" block can block this operation. ids : typing.Sequence[~StorageAttachmentId] Returns -> ErrorResults - ''' + """ if ids is not None and not isinstance(ids, (bytes, str, list)): - raise Exception("Expected ids to be a Sequence, received: {}".format(type(ids))) + raise Exception( + "Expected ids to be a Sequence, received: {}".format(type(ids)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Storage', - request='Attach', - version=6, - params=_params) - _params['ids'] = ids + msg = dict(type="Storage", request="Attach", version=6, params=_params) + _params["ids"] = ids reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def CreatePool(self, pools=None): - ''' + """ CreatePool creates a new pool with specified parameters. pools : typing.Sequence[~StoragePool] Returns -> ErrorResults - ''' + """ if pools is not None and not isinstance(pools, (bytes, str, list)): - raise Exception("Expected pools to be a Sequence, received: {}".format(type(pools))) + raise Exception( + "Expected pools to be a Sequence, received: {}".format(type(pools)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Storage', - request='CreatePool', - version=6, - params=_params) - _params['pools'] = pools + msg = dict(type="Storage", request="CreatePool", version=6, params=_params) + _params["pools"] = pools reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def DetachStorage(self, force=None, ids=None, max_wait=None): - ''' + """ DetachStorage sets the specified storage attachments to Dying, unless they are already Dying or Dead. Any associated, persistent storage will remain alive. This call can be forced. @@ -2278,82 +3214,79 @@ async def DetachStorage(self, force=None, ids=None, max_wait=None): ids : StorageAttachmentIds max_wait : int Returns -> ErrorResults - ''' + """ if force is not None and not isinstance(force, bool): - raise Exception("Expected force to be a bool, received: {}".format(type(force))) + raise Exception( + "Expected force to be a bool, received: {}".format(type(force)) + ) if ids is not None and not isinstance(ids, (dict, StorageAttachmentIds)): - raise Exception("Expected ids to be a StorageAttachmentIds, received: {}".format(type(ids))) + raise Exception( + "Expected ids to be a StorageAttachmentIds, received: {}".format( + type(ids) + ) + ) if max_wait is not None and not isinstance(max_wait, int): - raise Exception("Expected max_wait to be a int, received: {}".format(type(max_wait))) + raise Exception( + "Expected max_wait to be a int, received: {}".format(type(max_wait)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Storage', - request='DetachStorage', - version=6, - params=_params) - _params['force'] = force - _params['ids'] = ids - _params['max-wait'] = max_wait + msg = dict(type="Storage", request="DetachStorage", version=6, params=_params) + _params["force"] = force + _params["ids"] = ids + _params["max-wait"] = max_wait reply = await self.rpc(msg) return reply - - @ReturnMapping(ImportStorageResults) async def Import(self, storage=None): - ''' + """ Import imports existing storage into the model. A "CHANGE" block can block this operation. storage : typing.Sequence[~ImportStorageParams] Returns -> ImportStorageResults - ''' + """ if storage is not None and not isinstance(storage, (bytes, str, list)): - raise Exception("Expected storage to be a Sequence, received: {}".format(type(storage))) + raise Exception( + "Expected storage to be a Sequence, received: {}".format(type(storage)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Storage', - request='Import', - version=6, - params=_params) - _params['storage'] = storage + msg = dict(type="Storage", request="Import", version=6, params=_params) + _params["storage"] = storage reply = await self.rpc(msg) return reply - - @ReturnMapping(FilesystemDetailsListResults) async def ListFilesystems(self, filters=None): - ''' + """ ListFilesystems returns a list of filesystems in the environment matching the provided filter. Each result describes a filesystem in detail, including the filesystem's attachments. filters : typing.Sequence[~FilesystemFilter] Returns -> FilesystemDetailsListResults - ''' + """ if filters is not None and not isinstance(filters, (bytes, str, list)): - raise Exception("Expected filters to be a Sequence, received: {}".format(type(filters))) + raise Exception( + "Expected filters to be a Sequence, received: {}".format(type(filters)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Storage', - request='ListFilesystems', - version=6, - params=_params) - _params['filters'] = filters + msg = dict(type="Storage", request="ListFilesystems", version=6, params=_params) + _params["filters"] = filters reply = await self.rpc(msg) return reply - - @ReturnMapping(StoragePoolsResults) async def ListPools(self, filters=None): - ''' + """ ListPools returns a list of pools. If filter is provided, returned list only contains pools that match the filter. @@ -2365,73 +3298,66 @@ async def ListPools(self, filters=None): filters : typing.Sequence[~StoragePoolFilter] Returns -> StoragePoolsResults - ''' + """ if filters is not None and not isinstance(filters, (bytes, str, list)): - raise Exception("Expected filters to be a Sequence, received: {}".format(type(filters))) + raise Exception( + "Expected filters to be a Sequence, received: {}".format(type(filters)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Storage', - request='ListPools', - version=6, - params=_params) - _params['filters'] = filters + msg = dict(type="Storage", request="ListPools", version=6, params=_params) + _params["filters"] = filters reply = await self.rpc(msg) return reply - - @ReturnMapping(StorageDetailsListResults) async def ListStorageDetails(self, filters=None): - ''' + """ ListStorageDetails returns storage matching a filter. filters : typing.Sequence[~StorageFilter] Returns -> StorageDetailsListResults - ''' + """ if filters is not None and not isinstance(filters, (bytes, str, list)): - raise Exception("Expected filters to be a Sequence, received: {}".format(type(filters))) + raise Exception( + "Expected filters to be a Sequence, received: {}".format(type(filters)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Storage', - request='ListStorageDetails', - version=6, - params=_params) - _params['filters'] = filters + msg = dict( + type="Storage", request="ListStorageDetails", version=6, params=_params + ) + _params["filters"] = filters reply = await self.rpc(msg) return reply - - @ReturnMapping(VolumeDetailsListResults) async def ListVolumes(self, filters=None): - ''' + """ ListVolumes lists volumes with the given filters. Each filter produces an independent list of volumes, or an error if the filter is invalid or the volumes could not be listed. filters : typing.Sequence[~VolumeFilter] Returns -> VolumeDetailsListResults - ''' + """ if filters is not None and not isinstance(filters, (bytes, str, list)): - raise Exception("Expected filters to be a Sequence, received: {}".format(type(filters))) + raise Exception( + "Expected filters to be a Sequence, received: {}".format(type(filters)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Storage', - request='ListVolumes', - version=6, - params=_params) - _params['filters'] = filters + msg = dict(type="Storage", request="ListVolumes", version=6, params=_params) + _params["filters"] = filters reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def Remove(self, storage=None): - ''' + """ Remove sets the specified storage entities to Dying, unless they are already Dying or Dead, such that the storage will eventually be removed from the model. If the arguments specify that the storage should be @@ -2440,89 +3366,79 @@ async def Remove(self, storage=None): storage : typing.Sequence[~RemoveStorageInstance] Returns -> ErrorResults - ''' + """ if storage is not None and not isinstance(storage, (bytes, str, list)): - raise Exception("Expected storage to be a Sequence, received: {}".format(type(storage))) + raise Exception( + "Expected storage to be a Sequence, received: {}".format(type(storage)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Storage', - request='Remove', - version=6, - params=_params) - _params['storage'] = storage + msg = dict(type="Storage", request="Remove", version=6, params=_params) + _params["storage"] = storage reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def RemovePool(self, pools=None): - ''' + """ RemovePool deletes the named pool pools : typing.Sequence[~StoragePoolDeleteArg] Returns -> ErrorResults - ''' + """ if pools is not None and not isinstance(pools, (bytes, str, list)): - raise Exception("Expected pools to be a Sequence, received: {}".format(type(pools))) + raise Exception( + "Expected pools to be a Sequence, received: {}".format(type(pools)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Storage', - request='RemovePool', - version=6, - params=_params) - _params['pools'] = pools + msg = dict(type="Storage", request="RemovePool", version=6, params=_params) + _params["pools"] = pools reply = await self.rpc(msg) return reply - - @ReturnMapping(StorageDetailsResults) async def StorageDetails(self, entities=None): - ''' + """ StorageDetails retrieves and returns detailed information about desired storage identified by supplied tags. If specified storage cannot be retrieved, individual error is returned instead of storage information. entities : typing.Sequence[~Entity] Returns -> StorageDetailsResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Storage', - request='StorageDetails', - version=6, - params=_params) - _params['entities'] = entities + msg = dict(type="Storage", request="StorageDetails", version=6, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def UpdatePool(self, pools=None): - ''' + """ UpdatePool deletes the named pool pools : typing.Sequence[~StoragePool] Returns -> ErrorResults - ''' + """ if pools is not None and not isinstance(pools, (bytes, str, list)): - raise Exception("Expected pools to be a Sequence, received: {}".format(type(pools))) + raise Exception( + "Expected pools to be a Sequence, received: {}".format(type(pools)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Storage', - request='UpdatePool', - version=6, - params=_params) - _params['pools'] = pools + msg = dict(type="Storage", request="UpdatePool", version=6, params=_params) + _params["pools"] = pools reply = await self.rpc(msg) return reply - - diff --git a/juju/client/_client7.py b/juju/client/_client7.py index 7cc11fbcd..bdf738b4c 100644 --- a/juju/client/_client7.py +++ b/juju/client/_client7.py @@ -6,318 +6,456 @@ class ActionFacade(Type): - name = 'Action' + name = "Action" version = 7 - schema = {'definitions': {'Action': {'additionalProperties': False, - 'properties': {'execution-group': {'type': 'string'}, - 'name': {'type': 'string'}, - 'parallel': {'type': 'boolean'}, - 'parameters': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'receiver': {'type': 'string'}, - 'tag': {'type': 'string'}}, - 'required': ['tag', 'receiver', 'name'], - 'type': 'object'}, - 'ActionMessage': {'additionalProperties': False, - 'properties': {'message': {'type': 'string'}, - 'timestamp': {'format': 'date-time', - 'type': 'string'}}, - 'required': ['timestamp', 'message'], - 'type': 'object'}, - 'ActionResult': {'additionalProperties': False, - 'properties': {'action': {'$ref': '#/definitions/Action'}, - 'completed': {'format': 'date-time', - 'type': 'string'}, - 'enqueued': {'format': 'date-time', - 'type': 'string'}, - 'error': {'$ref': '#/definitions/Error'}, - 'log': {'items': {'$ref': '#/definitions/ActionMessage'}, - 'type': 'array'}, - 'message': {'type': 'string'}, - 'output': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'started': {'format': 'date-time', - 'type': 'string'}, - 'status': {'type': 'string'}}, - 'type': 'object'}, - 'ActionResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ActionResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'ActionSpec': {'additionalProperties': False, - 'properties': {'description': {'type': 'string'}, - 'params': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}}, - 'required': ['description', 'params'], - 'type': 'object'}, - 'Actions': {'additionalProperties': False, - 'properties': {'actions': {'items': {'$ref': '#/definitions/Action'}, - 'type': 'array'}}, - 'type': 'object'}, - 'ApplicationCharmActionsResult': {'additionalProperties': False, - 'properties': {'actions': {'patternProperties': {'.*': {'$ref': '#/definitions/ActionSpec'}}, - 'type': 'object'}, - 'application-tag': {'type': 'string'}, - 'error': {'$ref': '#/definitions/Error'}}, - 'type': 'object'}, - 'ApplicationsCharmActionsResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ApplicationCharmActionsResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'EnqueuedActions': {'additionalProperties': False, - 'properties': {'actions': {'items': {'$ref': '#/definitions/ActionResult'}, - 'type': 'array'}, - 'operation': {'type': 'string'}}, - 'required': ['operation'], - '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'}, - 'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - 'type': 'object'}, - 'OperationQueryArgs': {'additionalProperties': False, - 'properties': {'actions': {'items': {'type': 'string'}, - 'type': 'array'}, - 'applications': {'items': {'type': 'string'}, - 'type': 'array'}, - 'limit': {'type': 'integer'}, - 'machines': {'items': {'type': 'string'}, - 'type': 'array'}, - 'offset': {'type': 'integer'}, - 'status': {'items': {'type': 'string'}, - 'type': 'array'}, - 'units': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'OperationResult': {'additionalProperties': False, - 'properties': {'actions': {'items': {'$ref': '#/definitions/ActionResult'}, - 'type': 'array'}, - 'completed': {'format': 'date-time', - 'type': 'string'}, - 'enqueued': {'format': 'date-time', - 'type': 'string'}, - 'error': {'$ref': '#/definitions/Error'}, - 'fail': {'type': 'string'}, - 'operation': {'type': 'string'}, - 'started': {'format': 'date-time', - 'type': 'string'}, - 'status': {'type': 'string'}, - 'summary': {'type': 'string'}}, - 'required': ['operation', 'summary'], - 'type': 'object'}, - 'OperationResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/OperationResult'}, - 'type': 'array'}, - 'truncated': {'type': 'boolean'}}, - 'type': 'object'}, - 'RunParams': {'additionalProperties': False, - 'properties': {'applications': {'items': {'type': 'string'}, - 'type': 'array'}, - 'commands': {'type': 'string'}, - 'execution-group': {'type': 'string'}, - 'machines': {'items': {'type': 'string'}, - 'type': 'array'}, - 'parallel': {'type': 'boolean'}, - 'timeout': {'type': 'integer'}, - 'units': {'items': {'type': 'string'}, - 'type': 'array'}, - 'workload-context': {'type': 'boolean'}}, - 'required': ['commands', 'timeout'], - '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'}}, - 'properties': {'Actions': {'description': 'Actions takes a list of ' - 'ActionTags, and returns the full ' - 'Action for\n' - 'each ID.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ActionResults'}}, - 'type': 'object'}, - 'ApplicationsCharmsActions': {'description': 'ApplicationsCharmsActions ' - 'returns a slice ' - 'of charm Actions ' - 'for a slice of\n' - 'services.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ApplicationsCharmActionsResults'}}, - 'type': 'object'}, - 'Cancel': {'description': 'Cancel attempts to cancel enqueued ' - 'Actions from running.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ActionResults'}}, - 'type': 'object'}, - 'EnqueueOperation': {'description': 'EnqueueOperation takes a ' - 'list of Actions and ' - 'queues them up to be ' - 'executed as\n' - 'an operation, each action ' - 'running as a task on the ' - 'designated ' - 'ActionReceiver.\n' - 'We return the ID of the ' - 'overall operation and ' - 'each individual task.', - 'properties': {'Params': {'$ref': '#/definitions/Actions'}, - 'Result': {'$ref': '#/definitions/EnqueuedActions'}}, - 'type': 'object'}, - 'ListOperations': {'description': 'ListOperations fetches the ' - 'called actions for ' - 'specified apps/units.', - 'properties': {'Params': {'$ref': '#/definitions/OperationQueryArgs'}, - 'Result': {'$ref': '#/definitions/OperationResults'}}, - 'type': 'object'}, - 'Operations': {'description': 'Operations fetches the ' - 'specified operation ids.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/OperationResults'}}, - 'type': 'object'}, - 'Run': {'description': 'Run the commands specified on the ' - 'machines identified through the\n' - 'list of machines, units and services.', - 'properties': {'Params': {'$ref': '#/definitions/RunParams'}, - 'Result': {'$ref': '#/definitions/EnqueuedActions'}}, - 'type': 'object'}, - 'RunOnAllMachines': {'description': 'RunOnAllMachines attempts ' - 'to run the specified ' - 'command on all the ' - 'machines.', - 'properties': {'Params': {'$ref': '#/definitions/RunParams'}, - 'Result': {'$ref': '#/definitions/EnqueuedActions'}}, - 'type': 'object'}, - 'WatchActionsProgress': {'description': 'WatchActionsProgress ' - 'creates a watcher ' - 'that reports on ' - 'action log messages.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/StringsWatchResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "Action": { + "additionalProperties": False, + "properties": { + "execution-group": {"type": "string"}, + "name": {"type": "string"}, + "parallel": {"type": "boolean"}, + "parameters": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "receiver": {"type": "string"}, + "tag": {"type": "string"}, + }, + "required": ["tag", "receiver", "name"], + "type": "object", + }, + "ActionMessage": { + "additionalProperties": False, + "properties": { + "message": {"type": "string"}, + "timestamp": {"format": "date-time", "type": "string"}, + }, + "required": ["timestamp", "message"], + "type": "object", + }, + "ActionResult": { + "additionalProperties": False, + "properties": { + "action": {"$ref": "#/definitions/Action"}, + "completed": {"format": "date-time", "type": "string"}, + "enqueued": {"format": "date-time", "type": "string"}, + "error": {"$ref": "#/definitions/Error"}, + "log": { + "items": {"$ref": "#/definitions/ActionMessage"}, + "type": "array", + }, + "message": {"type": "string"}, + "output": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "started": {"format": "date-time", "type": "string"}, + "status": {"type": "string"}, + }, + "type": "object", + }, + "ActionResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ActionResult"}, + "type": "array", + } + }, + "type": "object", + }, + "ActionSpec": { + "additionalProperties": False, + "properties": { + "description": {"type": "string"}, + "params": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + }, + "required": ["description", "params"], + "type": "object", + }, + "Actions": { + "additionalProperties": False, + "properties": { + "actions": { + "items": {"$ref": "#/definitions/Action"}, + "type": "array", + } + }, + "type": "object", + }, + "ApplicationCharmActionsResult": { + "additionalProperties": False, + "properties": { + "actions": { + "patternProperties": { + ".*": {"$ref": "#/definitions/ActionSpec"} + }, + "type": "object", + }, + "application-tag": {"type": "string"}, + "error": {"$ref": "#/definitions/Error"}, + }, + "type": "object", + }, + "ApplicationsCharmActionsResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": { + "$ref": "#/definitions/ApplicationCharmActionsResult" + }, + "type": "array", + } + }, + "type": "object", + }, + "EnqueuedActions": { + "additionalProperties": False, + "properties": { + "actions": { + "items": {"$ref": "#/definitions/ActionResult"}, + "type": "array", + }, + "operation": {"type": "string"}, + }, + "required": ["operation"], + "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", + }, + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "type": "object", + }, + "OperationQueryArgs": { + "additionalProperties": False, + "properties": { + "actions": {"items": {"type": "string"}, "type": "array"}, + "applications": {"items": {"type": "string"}, "type": "array"}, + "limit": {"type": "integer"}, + "machines": {"items": {"type": "string"}, "type": "array"}, + "offset": {"type": "integer"}, + "status": {"items": {"type": "string"}, "type": "array"}, + "units": {"items": {"type": "string"}, "type": "array"}, + }, + "type": "object", + }, + "OperationResult": { + "additionalProperties": False, + "properties": { + "actions": { + "items": {"$ref": "#/definitions/ActionResult"}, + "type": "array", + }, + "completed": {"format": "date-time", "type": "string"}, + "enqueued": {"format": "date-time", "type": "string"}, + "error": {"$ref": "#/definitions/Error"}, + "fail": {"type": "string"}, + "operation": {"type": "string"}, + "started": {"format": "date-time", "type": "string"}, + "status": {"type": "string"}, + "summary": {"type": "string"}, + }, + "required": ["operation", "summary"], + "type": "object", + }, + "OperationResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/OperationResult"}, + "type": "array", + }, + "truncated": {"type": "boolean"}, + }, + "type": "object", + }, + "RunParams": { + "additionalProperties": False, + "properties": { + "applications": {"items": {"type": "string"}, "type": "array"}, + "commands": {"type": "string"}, + "execution-group": {"type": "string"}, + "machines": {"items": {"type": "string"}, "type": "array"}, + "parallel": {"type": "boolean"}, + "timeout": {"type": "integer"}, + "units": {"items": {"type": "string"}, "type": "array"}, + "workload-context": {"type": "boolean"}, + }, + "required": ["commands", "timeout"], + "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", + }, + }, + "properties": { + "Actions": { + "description": "Actions takes a list of " + "ActionTags, and returns the full " + "Action for\n" + "each ID.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/ActionResults"}, + }, + "type": "object", + }, + "ApplicationsCharmsActions": { + "description": "ApplicationsCharmsActions " + "returns a slice " + "of charm Actions " + "for a slice of\n" + "services.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/ApplicationsCharmActionsResults"}, + }, + "type": "object", + }, + "Cancel": { + "description": "Cancel attempts to cancel enqueued " + "Actions from running.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/ActionResults"}, + }, + "type": "object", + }, + "EnqueueOperation": { + "description": "EnqueueOperation takes a " + "list of Actions and " + "queues them up to be " + "executed as\n" + "an operation, each action " + "running as a task on the " + "designated " + "ActionReceiver.\n" + "We return the ID of the " + "overall operation and " + "each individual task.", + "properties": { + "Params": {"$ref": "#/definitions/Actions"}, + "Result": {"$ref": "#/definitions/EnqueuedActions"}, + }, + "type": "object", + }, + "ListOperations": { + "description": "ListOperations fetches the " + "called actions for " + "specified apps/units.", + "properties": { + "Params": {"$ref": "#/definitions/OperationQueryArgs"}, + "Result": {"$ref": "#/definitions/OperationResults"}, + }, + "type": "object", + }, + "Operations": { + "description": "Operations fetches the specified operation ids.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/OperationResults"}, + }, + "type": "object", + }, + "Run": { + "description": "Run the commands specified on the " + "machines identified through the\n" + "list of machines, units and services.", + "properties": { + "Params": {"$ref": "#/definitions/RunParams"}, + "Result": {"$ref": "#/definitions/EnqueuedActions"}, + }, + "type": "object", + }, + "RunOnAllMachines": { + "description": "RunOnAllMachines attempts " + "to run the specified " + "command on all the " + "machines.", + "properties": { + "Params": {"$ref": "#/definitions/RunParams"}, + "Result": {"$ref": "#/definitions/EnqueuedActions"}, + }, + "type": "object", + }, + "WatchActionsProgress": { + "description": "WatchActionsProgress " + "creates a watcher " + "that reports on " + "action log messages.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/StringsWatchResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(ActionResults) async def Actions(self, entities=None): - ''' + """ Actions takes a list of ActionTags, and returns the full Action for each ID. entities : typing.Sequence[~Entity] Returns -> ActionResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Action', - request='Actions', - version=7, - params=_params) - _params['entities'] = entities + msg = dict(type="Action", request="Actions", version=7, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ApplicationsCharmActionsResults) async def ApplicationsCharmsActions(self, entities=None): - ''' + """ ApplicationsCharmsActions returns a slice of charm Actions for a slice of services. entities : typing.Sequence[~Entity] Returns -> ApplicationsCharmActionsResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Action', - request='ApplicationsCharmsActions', - version=7, - params=_params) - _params['entities'] = entities + msg = dict( + type="Action", + request="ApplicationsCharmsActions", + version=7, + params=_params, + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ActionResults) async def Cancel(self, entities=None): - ''' + """ Cancel attempts to cancel enqueued Actions from running. entities : typing.Sequence[~Entity] Returns -> ActionResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Action', - request='Cancel', - version=7, - params=_params) - _params['entities'] = entities + msg = dict(type="Action", request="Cancel", version=7, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(EnqueuedActions) async def EnqueueOperation(self, actions=None): - ''' + """ EnqueueOperation takes a list of Actions and queues them up to be executed as an operation, each action running as a task on the designated ActionReceiver. We return the ID of the overall operation and each individual task. actions : typing.Sequence[~Action] Returns -> EnqueuedActions - ''' + """ if actions is not None and not isinstance(actions, (bytes, str, list)): - raise Exception("Expected actions to be a Sequence, received: {}".format(type(actions))) + raise Exception( + "Expected actions to be a Sequence, received: {}".format(type(actions)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Action', - request='EnqueueOperation', - version=7, - params=_params) - _params['actions'] = actions + msg = dict(type="Action", request="EnqueueOperation", version=7, params=_params) + _params["actions"] = actions reply = await self.rpc(msg) return reply - - @ReturnMapping(OperationResults) - async def ListOperations(self, actions=None, applications=None, limit=None, machines=None, offset=None, status=None, units=None): - ''' + async def ListOperations( + self, + actions=None, + applications=None, + limit=None, + machines=None, + offset=None, + status=None, + units=None, + ): + """ ListOperations fetches the called actions for specified apps/units. actions : typing.Sequence[str] @@ -328,72 +466,96 @@ async def ListOperations(self, actions=None, applications=None, limit=None, mach status : typing.Sequence[str] units : typing.Sequence[str] Returns -> OperationResults - ''' + """ if actions is not None and not isinstance(actions, (bytes, str, list)): - raise Exception("Expected actions to be a Sequence, received: {}".format(type(actions))) - - if applications is not None and not isinstance(applications, (bytes, str, list)): - raise Exception("Expected applications to be a Sequence, received: {}".format(type(applications))) + raise Exception( + "Expected actions to be a Sequence, received: {}".format(type(actions)) + ) + + if applications is not None and not isinstance( + applications, (bytes, str, list) + ): + raise Exception( + "Expected applications to be a Sequence, received: {}".format( + type(applications) + ) + ) if limit is not None and not isinstance(limit, int): - raise Exception("Expected limit to be a int, received: {}".format(type(limit))) + raise Exception( + "Expected limit to be a int, received: {}".format(type(limit)) + ) if machines is not None and not isinstance(machines, (bytes, str, list)): - raise Exception("Expected machines to be a Sequence, received: {}".format(type(machines))) + raise Exception( + "Expected machines to be a Sequence, received: {}".format( + type(machines) + ) + ) if offset is not None and not isinstance(offset, int): - raise Exception("Expected offset to be a int, received: {}".format(type(offset))) + raise Exception( + "Expected offset to be a int, received: {}".format(type(offset)) + ) if status is not None and not isinstance(status, (bytes, str, list)): - raise Exception("Expected status to be a Sequence, received: {}".format(type(status))) + raise Exception( + "Expected status to be a Sequence, received: {}".format(type(status)) + ) if units is not None and not isinstance(units, (bytes, str, list)): - raise Exception("Expected units to be a Sequence, received: {}".format(type(units))) + raise Exception( + "Expected units to be a Sequence, received: {}".format(type(units)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Action', - request='ListOperations', - version=7, - params=_params) - _params['actions'] = actions - _params['applications'] = applications - _params['limit'] = limit - _params['machines'] = machines - _params['offset'] = offset - _params['status'] = status - _params['units'] = units + msg = dict(type="Action", request="ListOperations", version=7, params=_params) + _params["actions"] = actions + _params["applications"] = applications + _params["limit"] = limit + _params["machines"] = machines + _params["offset"] = offset + _params["status"] = status + _params["units"] = units reply = await self.rpc(msg) return reply - - @ReturnMapping(OperationResults) async def Operations(self, entities=None): - ''' + """ Operations fetches the specified operation ids. entities : typing.Sequence[~Entity] Returns -> OperationResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Action', - request='Operations', - version=7, - params=_params) - _params['entities'] = entities + msg = dict(type="Action", request="Operations", version=7, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(EnqueuedActions) - async def Run(self, applications=None, commands=None, execution_group=None, machines=None, parallel=None, timeout=None, units=None, workload_context=None): - ''' + async def Run( + self, + applications=None, + commands=None, + execution_group=None, + machines=None, + parallel=None, + timeout=None, + units=None, + workload_context=None, + ): + """ Run the commands specified on the machines identified through the list of machines, units and services. @@ -406,53 +568,86 @@ async def Run(self, applications=None, commands=None, execution_group=None, mach units : typing.Sequence[str] workload_context : bool Returns -> EnqueuedActions - ''' - if applications is not None and not isinstance(applications, (bytes, str, list)): - raise Exception("Expected applications to be a Sequence, received: {}".format(type(applications))) + """ + if applications is not None and not isinstance( + applications, (bytes, str, list) + ): + raise Exception( + "Expected applications to be a Sequence, received: {}".format( + type(applications) + ) + ) if commands is not None and not isinstance(commands, (bytes, str)): - raise Exception("Expected commands to be a str, received: {}".format(type(commands))) - - if execution_group is not None and not isinstance(execution_group, (bytes, str)): - raise Exception("Expected execution_group to be a str, received: {}".format(type(execution_group))) + raise Exception( + "Expected commands to be a str, received: {}".format(type(commands)) + ) + + if execution_group is not None and not isinstance( + execution_group, (bytes, str) + ): + raise Exception( + "Expected execution_group to be a str, received: {}".format( + type(execution_group) + ) + ) if machines is not None and not isinstance(machines, (bytes, str, list)): - raise Exception("Expected machines to be a Sequence, received: {}".format(type(machines))) + raise Exception( + "Expected machines to be a Sequence, received: {}".format( + type(machines) + ) + ) if parallel is not None and not isinstance(parallel, bool): - raise Exception("Expected parallel to be a bool, received: {}".format(type(parallel))) + raise Exception( + "Expected parallel to be a bool, received: {}".format(type(parallel)) + ) if timeout is not None and not isinstance(timeout, int): - raise Exception("Expected timeout to be a int, received: {}".format(type(timeout))) + raise Exception( + "Expected timeout to be a int, received: {}".format(type(timeout)) + ) if units is not None and not isinstance(units, (bytes, str, list)): - raise Exception("Expected units to be a Sequence, received: {}".format(type(units))) + raise Exception( + "Expected units to be a Sequence, received: {}".format(type(units)) + ) if workload_context is not None and not isinstance(workload_context, bool): - raise Exception("Expected workload_context to be a bool, received: {}".format(type(workload_context))) + raise Exception( + "Expected workload_context to be a bool, received: {}".format( + type(workload_context) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Action', - request='Run', - version=7, - params=_params) - _params['applications'] = applications - _params['commands'] = commands - _params['execution-group'] = execution_group - _params['machines'] = machines - _params['parallel'] = parallel - _params['timeout'] = timeout - _params['units'] = units - _params['workload-context'] = workload_context + msg = dict(type="Action", request="Run", version=7, params=_params) + _params["applications"] = applications + _params["commands"] = commands + _params["execution-group"] = execution_group + _params["machines"] = machines + _params["parallel"] = parallel + _params["timeout"] = timeout + _params["units"] = units + _params["workload-context"] = workload_context reply = await self.rpc(msg) return reply - - @ReturnMapping(EnqueuedActions) - async def RunOnAllMachines(self, applications=None, commands=None, execution_group=None, machines=None, parallel=None, timeout=None, units=None, workload_context=None): - ''' + async def RunOnAllMachines( + self, + applications=None, + commands=None, + execution_group=None, + machines=None, + parallel=None, + timeout=None, + units=None, + workload_context=None, + ): + """ RunOnAllMachines attempts to run the specified command on all the machines. applications : typing.Sequence[str] @@ -464,517 +659,793 @@ async def RunOnAllMachines(self, applications=None, commands=None, execution_gro units : typing.Sequence[str] workload_context : bool Returns -> EnqueuedActions - ''' - if applications is not None and not isinstance(applications, (bytes, str, list)): - raise Exception("Expected applications to be a Sequence, received: {}".format(type(applications))) + """ + if applications is not None and not isinstance( + applications, (bytes, str, list) + ): + raise Exception( + "Expected applications to be a Sequence, received: {}".format( + type(applications) + ) + ) if commands is not None and not isinstance(commands, (bytes, str)): - raise Exception("Expected commands to be a str, received: {}".format(type(commands))) - - if execution_group is not None and not isinstance(execution_group, (bytes, str)): - raise Exception("Expected execution_group to be a str, received: {}".format(type(execution_group))) + raise Exception( + "Expected commands to be a str, received: {}".format(type(commands)) + ) + + if execution_group is not None and not isinstance( + execution_group, (bytes, str) + ): + raise Exception( + "Expected execution_group to be a str, received: {}".format( + type(execution_group) + ) + ) if machines is not None and not isinstance(machines, (bytes, str, list)): - raise Exception("Expected machines to be a Sequence, received: {}".format(type(machines))) + raise Exception( + "Expected machines to be a Sequence, received: {}".format( + type(machines) + ) + ) if parallel is not None and not isinstance(parallel, bool): - raise Exception("Expected parallel to be a bool, received: {}".format(type(parallel))) + raise Exception( + "Expected parallel to be a bool, received: {}".format(type(parallel)) + ) if timeout is not None and not isinstance(timeout, int): - raise Exception("Expected timeout to be a int, received: {}".format(type(timeout))) + raise Exception( + "Expected timeout to be a int, received: {}".format(type(timeout)) + ) if units is not None and not isinstance(units, (bytes, str, list)): - raise Exception("Expected units to be a Sequence, received: {}".format(type(units))) + raise Exception( + "Expected units to be a Sequence, received: {}".format(type(units)) + ) if workload_context is not None and not isinstance(workload_context, bool): - raise Exception("Expected workload_context to be a bool, received: {}".format(type(workload_context))) + raise Exception( + "Expected workload_context to be a bool, received: {}".format( + type(workload_context) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Action', - request='RunOnAllMachines', - version=7, - params=_params) - _params['applications'] = applications - _params['commands'] = commands - _params['execution-group'] = execution_group - _params['machines'] = machines - _params['parallel'] = parallel - _params['timeout'] = timeout - _params['units'] = units - _params['workload-context'] = workload_context + msg = dict(type="Action", request="RunOnAllMachines", version=7, params=_params) + _params["applications"] = applications + _params["commands"] = commands + _params["execution-group"] = execution_group + _params["machines"] = machines + _params["parallel"] = parallel + _params["timeout"] = timeout + _params["units"] = units + _params["workload-context"] = workload_context reply = await self.rpc(msg) return reply - - @ReturnMapping(StringsWatchResults) async def WatchActionsProgress(self, entities=None): - ''' + """ WatchActionsProgress creates a watcher that reports on action log messages. entities : typing.Sequence[~Entity] Returns -> StringsWatchResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Action', - request='WatchActionsProgress', - version=7, - params=_params) - _params['entities'] = entities + msg = dict( + type="Action", request="WatchActionsProgress", version=7, params=_params + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - class CharmsFacade(Type): - name = 'Charms' + name = "Charms" version = 7 - schema = {'definitions': {'AddCharmWithOrigin': {'additionalProperties': False, - 'properties': {'charm-origin': {'$ref': '#/definitions/CharmOrigin'}, - 'force': {'type': 'boolean'}, - 'url': {'type': 'string'}}, - 'required': ['url', - 'charm-origin', - 'force'], - 'type': 'object'}, - 'ApplicationCharmPlacement': {'additionalProperties': False, - 'properties': {'application': {'type': 'string'}, - 'charm-url': {'type': 'string'}}, - 'required': ['application', - 'charm-url'], - 'type': 'object'}, - 'ApplicationCharmPlacements': {'additionalProperties': False, - 'properties': {'placements': {'items': {'$ref': '#/definitions/ApplicationCharmPlacement'}, - 'type': 'array'}}, - 'required': ['placements'], - 'type': 'object'}, - 'Base': {'additionalProperties': False, - 'properties': {'channel': {'type': 'string'}, - 'name': {'type': 'string'}}, - 'required': ['name', 'channel'], - 'type': 'object'}, - 'Charm': {'additionalProperties': False, - 'properties': {'actions': {'$ref': '#/definitions/CharmActions'}, - 'config': {'patternProperties': {'.*': {'$ref': '#/definitions/CharmOption'}}, - 'type': 'object'}, - 'lxd-profile': {'$ref': '#/definitions/CharmLXDProfile'}, - 'manifest': {'$ref': '#/definitions/CharmManifest'}, - 'meta': {'$ref': '#/definitions/CharmMeta'}, - 'metrics': {'$ref': '#/definitions/CharmMetrics'}, - 'revision': {'type': 'integer'}, - 'url': {'type': 'string'}}, - 'required': ['revision', 'url', 'config'], - 'type': 'object'}, - 'CharmActionSpec': {'additionalProperties': False, - 'properties': {'description': {'type': 'string'}, - 'params': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}}, - 'required': ['description', 'params'], - 'type': 'object'}, - 'CharmActions': {'additionalProperties': False, - 'properties': {'specs': {'patternProperties': {'.*': {'$ref': '#/definitions/CharmActionSpec'}}, - 'type': 'object'}}, - 'type': 'object'}, - 'CharmBase': {'additionalProperties': False, - 'properties': {'architectures': {'items': {'type': 'string'}, - 'type': 'array'}, - 'channel': {'type': 'string'}, - 'name': {'type': 'string'}}, - 'type': 'object'}, - 'CharmContainer': {'additionalProperties': False, - 'properties': {'gid': {'type': 'integer'}, - 'mounts': {'items': {'$ref': '#/definitions/CharmMount'}, - 'type': 'array'}, - 'resource': {'type': 'string'}, - 'uid': {'type': 'integer'}}, - 'type': 'object'}, - 'CharmDeployment': {'additionalProperties': False, - 'properties': {'min-version': {'type': 'string'}, - 'mode': {'type': 'string'}, - 'service': {'type': 'string'}, - 'type': {'type': 'string'}}, - 'required': ['type', - 'mode', - 'service', - 'min-version'], - 'type': 'object'}, - 'CharmDevice': {'additionalProperties': False, - 'properties': {'CountMax': {'type': 'integer'}, - 'CountMin': {'type': 'integer'}, - 'Description': {'type': 'string'}, - 'Name': {'type': 'string'}, - 'Type': {'type': 'string'}}, - 'required': ['Name', - 'Description', - 'Type', - 'CountMin', - 'CountMax'], - 'type': 'object'}, - 'CharmLXDProfile': {'additionalProperties': False, - 'properties': {'config': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'description': {'type': 'string'}, - 'devices': {'patternProperties': {'.*': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}}, - 'type': 'object'}}, - 'required': ['config', - 'description', - 'devices'], - 'type': 'object'}, - 'CharmManifest': {'additionalProperties': False, - 'properties': {'bases': {'items': {'$ref': '#/definitions/CharmBase'}, - 'type': 'array'}}, - 'type': 'object'}, - 'CharmMeta': {'additionalProperties': False, - 'properties': {'assumes-expr': {'$ref': '#/definitions/ExpressionTree'}, - 'categories': {'items': {'type': 'string'}, - 'type': 'array'}, - 'charm-user': {'type': 'string'}, - 'containers': {'patternProperties': {'.*': {'$ref': '#/definitions/CharmContainer'}}, - 'type': 'object'}, - 'deployment': {'$ref': '#/definitions/CharmDeployment'}, - 'description': {'type': 'string'}, - 'devices': {'patternProperties': {'.*': {'$ref': '#/definitions/CharmDevice'}}, - 'type': 'object'}, - 'extra-bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'min-juju-version': {'type': 'string'}, - 'name': {'type': 'string'}, - 'payload-classes': {'patternProperties': {'.*': {'$ref': '#/definitions/CharmPayloadClass'}}, - 'type': 'object'}, - 'peers': {'patternProperties': {'.*': {'$ref': '#/definitions/CharmRelation'}}, - 'type': 'object'}, - 'provides': {'patternProperties': {'.*': {'$ref': '#/definitions/CharmRelation'}}, - 'type': 'object'}, - 'requires': {'patternProperties': {'.*': {'$ref': '#/definitions/CharmRelation'}}, - 'type': 'object'}, - 'resources': {'patternProperties': {'.*': {'$ref': '#/definitions/CharmResourceMeta'}}, - 'type': 'object'}, - 'series': {'items': {'type': 'string'}, - 'type': 'array'}, - 'storage': {'patternProperties': {'.*': {'$ref': '#/definitions/CharmStorage'}}, - 'type': 'object'}, - 'subordinate': {'type': 'boolean'}, - 'summary': {'type': 'string'}, - 'tags': {'items': {'type': 'string'}, - 'type': 'array'}, - 'terms': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['name', - 'summary', - 'description', - 'subordinate'], - 'type': 'object'}, - 'CharmMetric': {'additionalProperties': False, - 'properties': {'description': {'type': 'string'}, - 'type': {'type': 'string'}}, - 'required': ['type', 'description'], - 'type': 'object'}, - 'CharmMetrics': {'additionalProperties': False, - 'properties': {'metrics': {'patternProperties': {'.*': {'$ref': '#/definitions/CharmMetric'}}, - 'type': 'object'}, - 'plan': {'$ref': '#/definitions/CharmPlan'}}, - 'required': ['metrics', 'plan'], - 'type': 'object'}, - 'CharmMount': {'additionalProperties': False, - 'properties': {'location': {'type': 'string'}, - 'storage': {'type': 'string'}}, - 'type': 'object'}, - 'CharmOption': {'additionalProperties': False, - 'properties': {'default': {'additionalProperties': True, - 'type': 'object'}, - 'description': {'type': 'string'}, - 'type': {'type': 'string'}}, - 'required': ['type'], - 'type': 'object'}, - 'CharmOrigin': {'additionalProperties': False, - 'properties': {'architecture': {'type': 'string'}, - 'base': {'$ref': '#/definitions/Base'}, - 'branch': {'type': 'string'}, - 'hash': {'type': 'string'}, - 'id': {'type': 'string'}, - 'instance-key': {'type': 'string'}, - 'revision': {'type': 'integer'}, - 'risk': {'type': 'string'}, - 'source': {'type': 'string'}, - 'track': {'type': 'string'}, - 'type': {'type': 'string'}}, - 'required': ['source', 'type', 'id'], - 'type': 'object'}, - 'CharmOriginResult': {'additionalProperties': False, - 'properties': {'charm-origin': {'$ref': '#/definitions/CharmOrigin'}, - 'error': {'$ref': '#/definitions/Error'}}, - 'required': ['charm-origin'], - 'type': 'object'}, - 'CharmPayloadClass': {'additionalProperties': False, - 'properties': {'name': {'type': 'string'}, - 'type': {'type': 'string'}}, - 'required': ['name', 'type'], - 'type': 'object'}, - 'CharmPlan': {'additionalProperties': False, - 'properties': {'required': {'type': 'boolean'}}, - 'required': ['required'], - 'type': 'object'}, - 'CharmRelation': {'additionalProperties': False, - 'properties': {'interface': {'type': 'string'}, - 'limit': {'type': 'integer'}, - 'name': {'type': 'string'}, - 'optional': {'type': 'boolean'}, - 'role': {'type': 'string'}, - 'scope': {'type': 'string'}}, - 'required': ['name', - 'role', - 'interface', - 'optional', - 'limit', - 'scope'], - 'type': 'object'}, - 'CharmResource': {'additionalProperties': False, - 'properties': {'description': {'type': 'string'}, - 'fingerprint': {'items': {'type': 'integer'}, - 'type': 'array'}, - 'name': {'type': 'string'}, - 'origin': {'type': 'string'}, - 'path': {'type': 'string'}, - 'revision': {'type': 'integer'}, - 'size': {'type': 'integer'}, - 'type': {'type': 'string'}}, - 'required': ['name', - 'type', - 'path', - 'origin', - 'revision', - 'fingerprint', - 'size'], - 'type': 'object'}, - 'CharmResourceMeta': {'additionalProperties': False, - 'properties': {'description': {'type': 'string'}, - 'name': {'type': 'string'}, - 'path': {'type': 'string'}, - 'type': {'type': 'string'}}, - 'required': ['name', - 'type', - 'path', - 'description'], - 'type': 'object'}, - 'CharmResourceResult': {'additionalProperties': False, - 'properties': {'CharmResource': {'$ref': '#/definitions/CharmResource'}, - 'ErrorResult': {'$ref': '#/definitions/ErrorResult'}, - 'description': {'type': 'string'}, - 'error': {'$ref': '#/definitions/Error'}, - 'fingerprint': {'items': {'type': 'integer'}, - 'type': 'array'}, - 'name': {'type': 'string'}, - 'origin': {'type': 'string'}, - 'path': {'type': 'string'}, - 'revision': {'type': 'integer'}, - 'size': {'type': 'integer'}, - 'type': {'type': 'string'}}, - 'required': ['ErrorResult', - 'name', - 'type', - 'path', - 'origin', - 'revision', - 'fingerprint', - 'size', - 'CharmResource'], - 'type': 'object'}, - 'CharmResourcesResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'items': {'$ref': '#/definitions/CharmResourceResult'}, - 'type': 'array'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'CharmStorage': {'additionalProperties': False, - 'properties': {'count-max': {'type': 'integer'}, - 'count-min': {'type': 'integer'}, - 'description': {'type': 'string'}, - 'location': {'type': 'string'}, - 'minimum-size': {'type': 'integer'}, - 'name': {'type': 'string'}, - 'properties': {'items': {'type': 'string'}, - 'type': 'array'}, - 'read-only': {'type': 'boolean'}, - 'shared': {'type': 'boolean'}, - 'type': {'type': 'string'}}, - 'required': ['name', - 'description', - 'type', - 'shared', - 'read-only', - 'count-min', - 'count-max', - 'minimum-size'], - 'type': 'object'}, - 'CharmURL': {'additionalProperties': False, - 'properties': {'url': {'type': 'string'}}, - 'required': ['url'], - 'type': 'object'}, - 'CharmURLAndOrigin': {'additionalProperties': False, - 'properties': {'charm-origin': {'$ref': '#/definitions/CharmOrigin'}, - 'charm-url': {'type': 'string'}, - 'macaroon': {'$ref': '#/definitions/Macaroon'}}, - 'required': ['charm-url', - 'charm-origin'], - 'type': 'object'}, - 'CharmURLAndOrigins': {'additionalProperties': False, - 'properties': {'entities': {'items': {'$ref': '#/definitions/CharmURLAndOrigin'}, - 'type': 'array'}}, - 'required': ['entities'], - 'type': 'object'}, - 'CharmsList': {'additionalProperties': False, - 'properties': {'names': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['names'], - 'type': 'object'}, - 'CharmsListResult': {'additionalProperties': False, - 'properties': {'charm-urls': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['charm-urls'], - 'type': 'object'}, - 'DownloadInfoResult': {'additionalProperties': False, - 'properties': {'charm-origin': {'$ref': '#/definitions/CharmOrigin'}, - 'url': {'type': 'string'}}, - 'required': ['url', 'charm-origin'], - 'type': 'object'}, - 'DownloadInfoResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/DownloadInfoResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - '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'}, - 'ExpressionTree': {'additionalProperties': False, - 'properties': {'Expression': {'additionalProperties': True, - 'type': 'object'}}, - 'required': ['Expression'], - 'type': 'object'}, - 'IsMeteredResult': {'additionalProperties': False, - 'properties': {'metered': {'type': 'boolean'}}, - 'required': ['metered'], - 'type': 'object'}, - 'Macaroon': {'additionalProperties': False, 'type': 'object'}, - 'ResolveCharmWithChannel': {'additionalProperties': False, - 'properties': {'charm-origin': {'$ref': '#/definitions/CharmOrigin'}, - 'reference': {'type': 'string'}, - 'switch-charm': {'type': 'boolean'}}, - 'required': ['reference', - 'charm-origin'], - 'type': 'object'}, - 'ResolveCharmWithChannelResult': {'additionalProperties': False, - 'properties': {'charm-origin': {'$ref': '#/definitions/CharmOrigin'}, - 'error': {'$ref': '#/definitions/Error'}, - 'supported-bases': {'items': {'$ref': '#/definitions/Base'}, - 'type': 'array'}, - 'url': {'type': 'string'}}, - 'required': ['url', - 'charm-origin', - 'supported-bases'], - 'type': 'object'}, - 'ResolveCharmWithChannelResults': {'additionalProperties': False, - 'properties': {'Results': {'items': {'$ref': '#/definitions/ResolveCharmWithChannelResult'}, - 'type': 'array'}}, - 'required': ['Results'], - 'type': 'object'}, - 'ResolveCharmsWithChannel': {'additionalProperties': False, - 'properties': {'macaroon': {'$ref': '#/definitions/Macaroon'}, - 'resolve': {'items': {'$ref': '#/definitions/ResolveCharmWithChannel'}, - 'type': 'array'}}, - 'required': ['resolve'], - 'type': 'object'}}, - 'properties': {'AddCharm': {'description': 'AddCharm adds the given charm URL ' - '(which must include revision) to ' - 'the\n' - 'environment, if it does not exist ' - 'yet. Local charms are not ' - 'supported,\n' - 'only charm store and charm hub ' - 'URLs. See also AddLocalCharm().', - 'properties': {'Params': {'$ref': '#/definitions/AddCharmWithOrigin'}, - 'Result': {'$ref': '#/definitions/CharmOriginResult'}}, - 'type': 'object'}, - 'CharmInfo': {'description': 'CharmInfo returns information ' - 'about the requested charm.', - 'properties': {'Params': {'$ref': '#/definitions/CharmURL'}, - 'Result': {'$ref': '#/definitions/Charm'}}, - 'type': 'object'}, - 'CheckCharmPlacement': {'description': 'CheckCharmPlacement ' - 'checks if a charm is ' - 'allowed to be placed ' - 'with in a\n' - 'given application.', - 'properties': {'Params': {'$ref': '#/definitions/ApplicationCharmPlacements'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'GetDownloadInfos': {'description': 'GetDownloadInfos attempts ' - 'to get the bundle ' - 'corresponding to the ' - 'charm url\n' - 'and origin.', - 'properties': {'Params': {'$ref': '#/definitions/CharmURLAndOrigins'}, - 'Result': {'$ref': '#/definitions/DownloadInfoResults'}}, - 'type': 'object'}, - 'IsMetered': {'description': 'IsMetered returns whether or not ' - 'the charm is metered.\n' - 'TODO (cderici) only used for ' - 'metered charms in cmd ' - 'MeteredDeployAPI,\n' - 'kept for client compatibility, ' - 'remove in juju 4.0', - 'properties': {'Params': {'$ref': '#/definitions/CharmURL'}, - 'Result': {'$ref': '#/definitions/IsMeteredResult'}}, - 'type': 'object'}, - 'List': {'description': 'List returns a list of charm URLs ' - 'currently in the state.\n' - 'If supplied parameter contains any ' - 'names, the result will\n' - 'be filtered to return only the charms ' - 'with supplied names.', - 'properties': {'Params': {'$ref': '#/definitions/CharmsList'}, - 'Result': {'$ref': '#/definitions/CharmsListResult'}}, - 'type': 'object'}, - 'ListCharmResources': {'description': 'ListCharmResources ' - 'returns a series of ' - 'resources for a given ' - 'charm.', - 'properties': {'Params': {'$ref': '#/definitions/CharmURLAndOrigins'}, - 'Result': {'$ref': '#/definitions/CharmResourcesResults'}}, - 'type': 'object'}, - 'ResolveCharms': {'description': 'ResolveCharms resolves the ' - 'given charm URLs with an ' - 'optionally specified\n' - 'preferred channel. Channel ' - 'provided via CharmOrigin.', - 'properties': {'Params': {'$ref': '#/definitions/ResolveCharmsWithChannel'}, - 'Result': {'$ref': '#/definitions/ResolveCharmWithChannelResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "AddCharmWithOrigin": { + "additionalProperties": False, + "properties": { + "charm-origin": {"$ref": "#/definitions/CharmOrigin"}, + "force": {"type": "boolean"}, + "url": {"type": "string"}, + }, + "required": ["url", "charm-origin", "force"], + "type": "object", + }, + "ApplicationCharmPlacement": { + "additionalProperties": False, + "properties": { + "application": {"type": "string"}, + "charm-url": {"type": "string"}, + }, + "required": ["application", "charm-url"], + "type": "object", + }, + "ApplicationCharmPlacements": { + "additionalProperties": False, + "properties": { + "placements": { + "items": {"$ref": "#/definitions/ApplicationCharmPlacement"}, + "type": "array", + } + }, + "required": ["placements"], + "type": "object", + }, + "Base": { + "additionalProperties": False, + "properties": { + "channel": {"type": "string"}, + "name": {"type": "string"}, + }, + "required": ["name", "channel"], + "type": "object", + }, + "Charm": { + "additionalProperties": False, + "properties": { + "actions": {"$ref": "#/definitions/CharmActions"}, + "config": { + "patternProperties": { + ".*": {"$ref": "#/definitions/CharmOption"} + }, + "type": "object", + }, + "lxd-profile": {"$ref": "#/definitions/CharmLXDProfile"}, + "manifest": {"$ref": "#/definitions/CharmManifest"}, + "meta": {"$ref": "#/definitions/CharmMeta"}, + "metrics": {"$ref": "#/definitions/CharmMetrics"}, + "revision": {"type": "integer"}, + "url": {"type": "string"}, + }, + "required": ["revision", "url", "config"], + "type": "object", + }, + "CharmActionSpec": { + "additionalProperties": False, + "properties": { + "description": {"type": "string"}, + "params": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + }, + "required": ["description", "params"], + "type": "object", + }, + "CharmActions": { + "additionalProperties": False, + "properties": { + "specs": { + "patternProperties": { + ".*": {"$ref": "#/definitions/CharmActionSpec"} + }, + "type": "object", + } + }, + "type": "object", + }, + "CharmBase": { + "additionalProperties": False, + "properties": { + "architectures": {"items": {"type": "string"}, "type": "array"}, + "channel": {"type": "string"}, + "name": {"type": "string"}, + }, + "type": "object", + }, + "CharmContainer": { + "additionalProperties": False, + "properties": { + "gid": {"type": "integer"}, + "mounts": { + "items": {"$ref": "#/definitions/CharmMount"}, + "type": "array", + }, + "resource": {"type": "string"}, + "uid": {"type": "integer"}, + }, + "type": "object", + }, + "CharmDeployment": { + "additionalProperties": False, + "properties": { + "min-version": {"type": "string"}, + "mode": {"type": "string"}, + "service": {"type": "string"}, + "type": {"type": "string"}, + }, + "required": ["type", "mode", "service", "min-version"], + "type": "object", + }, + "CharmDevice": { + "additionalProperties": False, + "properties": { + "CountMax": {"type": "integer"}, + "CountMin": {"type": "integer"}, + "Description": {"type": "string"}, + "Name": {"type": "string"}, + "Type": {"type": "string"}, + }, + "required": ["Name", "Description", "Type", "CountMin", "CountMax"], + "type": "object", + }, + "CharmLXDProfile": { + "additionalProperties": False, + "properties": { + "config": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "description": {"type": "string"}, + "devices": { + "patternProperties": { + ".*": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + } + }, + "type": "object", + }, + }, + "required": ["config", "description", "devices"], + "type": "object", + }, + "CharmManifest": { + "additionalProperties": False, + "properties": { + "bases": { + "items": {"$ref": "#/definitions/CharmBase"}, + "type": "array", + } + }, + "type": "object", + }, + "CharmMeta": { + "additionalProperties": False, + "properties": { + "assumes-expr": {"$ref": "#/definitions/ExpressionTree"}, + "categories": {"items": {"type": "string"}, "type": "array"}, + "charm-user": {"type": "string"}, + "containers": { + "patternProperties": { + ".*": {"$ref": "#/definitions/CharmContainer"} + }, + "type": "object", + }, + "deployment": {"$ref": "#/definitions/CharmDeployment"}, + "description": {"type": "string"}, + "devices": { + "patternProperties": { + ".*": {"$ref": "#/definitions/CharmDevice"} + }, + "type": "object", + }, + "extra-bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "min-juju-version": {"type": "string"}, + "name": {"type": "string"}, + "payload-classes": { + "patternProperties": { + ".*": {"$ref": "#/definitions/CharmPayloadClass"} + }, + "type": "object", + }, + "peers": { + "patternProperties": { + ".*": {"$ref": "#/definitions/CharmRelation"} + }, + "type": "object", + }, + "provides": { + "patternProperties": { + ".*": {"$ref": "#/definitions/CharmRelation"} + }, + "type": "object", + }, + "requires": { + "patternProperties": { + ".*": {"$ref": "#/definitions/CharmRelation"} + }, + "type": "object", + }, + "resources": { + "patternProperties": { + ".*": {"$ref": "#/definitions/CharmResourceMeta"} + }, + "type": "object", + }, + "series": {"items": {"type": "string"}, "type": "array"}, + "storage": { + "patternProperties": { + ".*": {"$ref": "#/definitions/CharmStorage"} + }, + "type": "object", + }, + "subordinate": {"type": "boolean"}, + "summary": {"type": "string"}, + "tags": {"items": {"type": "string"}, "type": "array"}, + "terms": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["name", "summary", "description", "subordinate"], + "type": "object", + }, + "CharmMetric": { + "additionalProperties": False, + "properties": { + "description": {"type": "string"}, + "type": {"type": "string"}, + }, + "required": ["type", "description"], + "type": "object", + }, + "CharmMetrics": { + "additionalProperties": False, + "properties": { + "metrics": { + "patternProperties": { + ".*": {"$ref": "#/definitions/CharmMetric"} + }, + "type": "object", + }, + "plan": {"$ref": "#/definitions/CharmPlan"}, + }, + "required": ["metrics", "plan"], + "type": "object", + }, + "CharmMount": { + "additionalProperties": False, + "properties": { + "location": {"type": "string"}, + "storage": {"type": "string"}, + }, + "type": "object", + }, + "CharmOption": { + "additionalProperties": False, + "properties": { + "default": {"additionalProperties": True, "type": "object"}, + "description": {"type": "string"}, + "type": {"type": "string"}, + }, + "required": ["type"], + "type": "object", + }, + "CharmOrigin": { + "additionalProperties": False, + "properties": { + "architecture": {"type": "string"}, + "base": {"$ref": "#/definitions/Base"}, + "branch": {"type": "string"}, + "hash": {"type": "string"}, + "id": {"type": "string"}, + "instance-key": {"type": "string"}, + "revision": {"type": "integer"}, + "risk": {"type": "string"}, + "source": {"type": "string"}, + "track": {"type": "string"}, + "type": {"type": "string"}, + }, + "required": ["source", "type", "id"], + "type": "object", + }, + "CharmOriginResult": { + "additionalProperties": False, + "properties": { + "charm-origin": {"$ref": "#/definitions/CharmOrigin"}, + "error": {"$ref": "#/definitions/Error"}, + }, + "required": ["charm-origin"], + "type": "object", + }, + "CharmPayloadClass": { + "additionalProperties": False, + "properties": {"name": {"type": "string"}, "type": {"type": "string"}}, + "required": ["name", "type"], + "type": "object", + }, + "CharmPlan": { + "additionalProperties": False, + "properties": {"required": {"type": "boolean"}}, + "required": ["required"], + "type": "object", + }, + "CharmRelation": { + "additionalProperties": False, + "properties": { + "interface": {"type": "string"}, + "limit": {"type": "integer"}, + "name": {"type": "string"}, + "optional": {"type": "boolean"}, + "role": {"type": "string"}, + "scope": {"type": "string"}, + }, + "required": ["name", "role", "interface", "optional", "limit", "scope"], + "type": "object", + }, + "CharmResource": { + "additionalProperties": False, + "properties": { + "description": {"type": "string"}, + "fingerprint": {"items": {"type": "integer"}, "type": "array"}, + "name": {"type": "string"}, + "origin": {"type": "string"}, + "path": {"type": "string"}, + "revision": {"type": "integer"}, + "size": {"type": "integer"}, + "type": {"type": "string"}, + }, + "required": [ + "name", + "type", + "path", + "origin", + "revision", + "fingerprint", + "size", + ], + "type": "object", + }, + "CharmResourceMeta": { + "additionalProperties": False, + "properties": { + "description": {"type": "string"}, + "name": {"type": "string"}, + "path": {"type": "string"}, + "type": {"type": "string"}, + }, + "required": ["name", "type", "path", "description"], + "type": "object", + }, + "CharmResourceResult": { + "additionalProperties": False, + "properties": { + "CharmResource": {"$ref": "#/definitions/CharmResource"}, + "ErrorResult": {"$ref": "#/definitions/ErrorResult"}, + "description": {"type": "string"}, + "error": {"$ref": "#/definitions/Error"}, + "fingerprint": {"items": {"type": "integer"}, "type": "array"}, + "name": {"type": "string"}, + "origin": {"type": "string"}, + "path": {"type": "string"}, + "revision": {"type": "integer"}, + "size": {"type": "integer"}, + "type": {"type": "string"}, + }, + "required": [ + "ErrorResult", + "name", + "type", + "path", + "origin", + "revision", + "fingerprint", + "size", + "CharmResource", + ], + "type": "object", + }, + "CharmResourcesResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": { + "items": {"$ref": "#/definitions/CharmResourceResult"}, + "type": "array", + }, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "CharmStorage": { + "additionalProperties": False, + "properties": { + "count-max": {"type": "integer"}, + "count-min": {"type": "integer"}, + "description": {"type": "string"}, + "location": {"type": "string"}, + "minimum-size": {"type": "integer"}, + "name": {"type": "string"}, + "properties": {"items": {"type": "string"}, "type": "array"}, + "read-only": {"type": "boolean"}, + "shared": {"type": "boolean"}, + "type": {"type": "string"}, + }, + "required": [ + "name", + "description", + "type", + "shared", + "read-only", + "count-min", + "count-max", + "minimum-size", + ], + "type": "object", + }, + "CharmURL": { + "additionalProperties": False, + "properties": {"url": {"type": "string"}}, + "required": ["url"], + "type": "object", + }, + "CharmURLAndOrigin": { + "additionalProperties": False, + "properties": { + "charm-origin": {"$ref": "#/definitions/CharmOrigin"}, + "charm-url": {"type": "string"}, + "macaroon": {"$ref": "#/definitions/Macaroon"}, + }, + "required": ["charm-url", "charm-origin"], + "type": "object", + }, + "CharmURLAndOrigins": { + "additionalProperties": False, + "properties": { + "entities": { + "items": {"$ref": "#/definitions/CharmURLAndOrigin"}, + "type": "array", + } + }, + "required": ["entities"], + "type": "object", + }, + "CharmsList": { + "additionalProperties": False, + "properties": {"names": {"items": {"type": "string"}, "type": "array"}}, + "required": ["names"], + "type": "object", + }, + "CharmsListResult": { + "additionalProperties": False, + "properties": { + "charm-urls": {"items": {"type": "string"}, "type": "array"} + }, + "required": ["charm-urls"], + "type": "object", + }, + "DownloadInfoResult": { + "additionalProperties": False, + "properties": { + "charm-origin": {"$ref": "#/definitions/CharmOrigin"}, + "url": {"type": "string"}, + }, + "required": ["url", "charm-origin"], + "type": "object", + }, + "DownloadInfoResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/DownloadInfoResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "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", + }, + "ExpressionTree": { + "additionalProperties": False, + "properties": { + "Expression": {"additionalProperties": True, "type": "object"} + }, + "required": ["Expression"], + "type": "object", + }, + "IsMeteredResult": { + "additionalProperties": False, + "properties": {"metered": {"type": "boolean"}}, + "required": ["metered"], + "type": "object", + }, + "Macaroon": {"additionalProperties": False, "type": "object"}, + "ResolveCharmWithChannel": { + "additionalProperties": False, + "properties": { + "charm-origin": {"$ref": "#/definitions/CharmOrigin"}, + "reference": {"type": "string"}, + "switch-charm": {"type": "boolean"}, + }, + "required": ["reference", "charm-origin"], + "type": "object", + }, + "ResolveCharmWithChannelResult": { + "additionalProperties": False, + "properties": { + "charm-origin": {"$ref": "#/definitions/CharmOrigin"}, + "error": {"$ref": "#/definitions/Error"}, + "supported-bases": { + "items": {"$ref": "#/definitions/Base"}, + "type": "array", + }, + "url": {"type": "string"}, + }, + "required": ["url", "charm-origin", "supported-bases"], + "type": "object", + }, + "ResolveCharmWithChannelResults": { + "additionalProperties": False, + "properties": { + "Results": { + "items": { + "$ref": "#/definitions/ResolveCharmWithChannelResult" + }, + "type": "array", + } + }, + "required": ["Results"], + "type": "object", + }, + "ResolveCharmsWithChannel": { + "additionalProperties": False, + "properties": { + "macaroon": {"$ref": "#/definitions/Macaroon"}, + "resolve": { + "items": {"$ref": "#/definitions/ResolveCharmWithChannel"}, + "type": "array", + }, + }, + "required": ["resolve"], + "type": "object", + }, + }, + "properties": { + "AddCharm": { + "description": "AddCharm adds the given charm URL " + "(which must include revision) to " + "the\n" + "environment, if it does not exist " + "yet. Local charms are not " + "supported,\n" + "only charm store and charm hub " + "URLs. See also AddLocalCharm().", + "properties": { + "Params": {"$ref": "#/definitions/AddCharmWithOrigin"}, + "Result": {"$ref": "#/definitions/CharmOriginResult"}, + }, + "type": "object", + }, + "CharmInfo": { + "description": "CharmInfo returns information " + "about the requested charm.", + "properties": { + "Params": {"$ref": "#/definitions/CharmURL"}, + "Result": {"$ref": "#/definitions/Charm"}, + }, + "type": "object", + }, + "CheckCharmPlacement": { + "description": "CheckCharmPlacement " + "checks if a charm is " + "allowed to be placed " + "with in a\n" + "given application.", + "properties": { + "Params": {"$ref": "#/definitions/ApplicationCharmPlacements"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "GetDownloadInfos": { + "description": "GetDownloadInfos attempts " + "to get the bundle " + "corresponding to the " + "charm url\n" + "and origin.", + "properties": { + "Params": {"$ref": "#/definitions/CharmURLAndOrigins"}, + "Result": {"$ref": "#/definitions/DownloadInfoResults"}, + }, + "type": "object", + }, + "IsMetered": { + "description": "IsMetered returns whether or not " + "the charm is metered.\n" + "TODO (cderici) only used for " + "metered charms in cmd " + "MeteredDeployAPI,\n" + "kept for client compatibility, " + "remove in juju 4.0", + "properties": { + "Params": {"$ref": "#/definitions/CharmURL"}, + "Result": {"$ref": "#/definitions/IsMeteredResult"}, + }, + "type": "object", + }, + "List": { + "description": "List returns a list of charm URLs " + "currently in the state.\n" + "If supplied parameter contains any " + "names, the result will\n" + "be filtered to return only the charms " + "with supplied names.", + "properties": { + "Params": {"$ref": "#/definitions/CharmsList"}, + "Result": {"$ref": "#/definitions/CharmsListResult"}, + }, + "type": "object", + }, + "ListCharmResources": { + "description": "ListCharmResources " + "returns a series of " + "resources for a given " + "charm.", + "properties": { + "Params": {"$ref": "#/definitions/CharmURLAndOrigins"}, + "Result": {"$ref": "#/definitions/CharmResourcesResults"}, + }, + "type": "object", + }, + "ResolveCharms": { + "description": "ResolveCharms resolves the " + "given charm URLs with an " + "optionally specified\n" + "preferred channel. Channel " + "provided via CharmOrigin.", + "properties": { + "Params": {"$ref": "#/definitions/ResolveCharmsWithChannel"}, + "Result": {"$ref": "#/definitions/ResolveCharmWithChannelResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(CharmOriginResult) async def AddCharm(self, charm_origin=None, force=None, url=None): - ''' + """ AddCharm adds the given charm URL (which must include revision) to the environment, if it does not exist yet. Local charms are not supported, only charm store and charm hub URLs. See also AddLocalCharm(). @@ -983,760 +1454,1036 @@ async def AddCharm(self, charm_origin=None, force=None, url=None): force : bool url : str Returns -> CharmOriginResult - ''' - if charm_origin is not None and not isinstance(charm_origin, (dict, CharmOrigin)): - raise Exception("Expected charm_origin to be a CharmOrigin, received: {}".format(type(charm_origin))) + """ + if charm_origin is not None and not isinstance( + charm_origin, (dict, CharmOrigin) + ): + raise Exception( + "Expected charm_origin to be a CharmOrigin, received: {}".format( + type(charm_origin) + ) + ) if force is not None and not isinstance(force, bool): - raise Exception("Expected force to be a bool, received: {}".format(type(force))) + raise Exception( + "Expected force to be a bool, received: {}".format(type(force)) + ) if url is not None and not isinstance(url, (bytes, str)): raise Exception("Expected url to be a str, received: {}".format(type(url))) # map input types to rpc msg _params = dict() - msg = dict(type='Charms', - request='AddCharm', - version=7, - params=_params) - _params['charm-origin'] = charm_origin - _params['force'] = force - _params['url'] = url + msg = dict(type="Charms", request="AddCharm", version=7, params=_params) + _params["charm-origin"] = charm_origin + _params["force"] = force + _params["url"] = url reply = await self.rpc(msg) return reply - - @ReturnMapping(Charm) async def CharmInfo(self, url=None): - ''' + """ CharmInfo returns information about the requested charm. url : str Returns -> Charm - ''' + """ if url is not None and not isinstance(url, (bytes, str)): raise Exception("Expected url to be a str, received: {}".format(type(url))) # map input types to rpc msg _params = dict() - msg = dict(type='Charms', - request='CharmInfo', - version=7, - params=_params) - _params['url'] = url + msg = dict(type="Charms", request="CharmInfo", version=7, params=_params) + _params["url"] = url reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def CheckCharmPlacement(self, placements=None): - ''' + """ CheckCharmPlacement checks if a charm is allowed to be placed with in a given application. placements : typing.Sequence[~ApplicationCharmPlacement] Returns -> ErrorResults - ''' + """ if placements is not None and not isinstance(placements, (bytes, str, list)): - raise Exception("Expected placements to be a Sequence, received: {}".format(type(placements))) + raise Exception( + "Expected placements to be a Sequence, received: {}".format( + type(placements) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Charms', - request='CheckCharmPlacement', - version=7, - params=_params) - _params['placements'] = placements + msg = dict( + type="Charms", request="CheckCharmPlacement", version=7, params=_params + ) + _params["placements"] = placements reply = await self.rpc(msg) return reply - - @ReturnMapping(DownloadInfoResults) async def GetDownloadInfos(self, entities=None): - ''' + """ GetDownloadInfos attempts to get the bundle corresponding to the charm url and origin. entities : typing.Sequence[~CharmURLAndOrigin] Returns -> DownloadInfoResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Charms', - request='GetDownloadInfos', - version=7, - params=_params) - _params['entities'] = entities + msg = dict(type="Charms", request="GetDownloadInfos", version=7, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(IsMeteredResult) async def IsMetered(self, url=None): - ''' + """ IsMetered returns whether or not the charm is metered. TODO (cderici) only used for metered charms in cmd MeteredDeployAPI, kept for client compatibility, remove in juju 4.0 url : str Returns -> IsMeteredResult - ''' + """ if url is not None and not isinstance(url, (bytes, str)): raise Exception("Expected url to be a str, received: {}".format(type(url))) # map input types to rpc msg _params = dict() - msg = dict(type='Charms', - request='IsMetered', - version=7, - params=_params) - _params['url'] = url + msg = dict(type="Charms", request="IsMetered", version=7, params=_params) + _params["url"] = url reply = await self.rpc(msg) return reply - - @ReturnMapping(CharmsListResult) async def List(self, names=None): - ''' + """ List returns a list of charm URLs currently in the state. If supplied parameter contains any names, the result will be filtered to return only the charms with supplied names. names : typing.Sequence[str] Returns -> CharmsListResult - ''' + """ if names is not None and not isinstance(names, (bytes, str, list)): - raise Exception("Expected names to be a Sequence, received: {}".format(type(names))) + raise Exception( + "Expected names to be a Sequence, received: {}".format(type(names)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Charms', - request='List', - version=7, - params=_params) - _params['names'] = names + msg = dict(type="Charms", request="List", version=7, params=_params) + _params["names"] = names reply = await self.rpc(msg) return reply - - @ReturnMapping(CharmResourcesResults) async def ListCharmResources(self, entities=None): - ''' + """ ListCharmResources returns a series of resources for a given charm. entities : typing.Sequence[~CharmURLAndOrigin] Returns -> CharmResourcesResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Charms', - request='ListCharmResources', - version=7, - params=_params) - _params['entities'] = entities + msg = dict( + type="Charms", request="ListCharmResources", version=7, params=_params + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ResolveCharmWithChannelResults) async def ResolveCharms(self, macaroon=None, resolve=None): - ''' + """ ResolveCharms resolves the given charm URLs with an optionally specified preferred channel. Channel provided via CharmOrigin. macaroon : Macaroon resolve : typing.Sequence[~ResolveCharmWithChannel] Returns -> ResolveCharmWithChannelResults - ''' + """ if macaroon is not None and not isinstance(macaroon, (dict, Macaroon)): - raise Exception("Expected macaroon to be a Macaroon, received: {}".format(type(macaroon))) + raise Exception( + "Expected macaroon to be a Macaroon, received: {}".format( + type(macaroon) + ) + ) if resolve is not None and not isinstance(resolve, (bytes, str, list)): - raise Exception("Expected resolve to be a Sequence, received: {}".format(type(resolve))) + raise Exception( + "Expected resolve to be a Sequence, received: {}".format(type(resolve)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Charms', - request='ResolveCharms', - version=7, - params=_params) - _params['macaroon'] = macaroon - _params['resolve'] = resolve + msg = dict(type="Charms", request="ResolveCharms", version=7, params=_params) + _params["macaroon"] = macaroon + _params["resolve"] = resolve reply = await self.rpc(msg) return reply - class ClientFacade(Type): - name = 'Client' + name = "Client" version = 7 - schema = {'definitions': {'AllWatcherId': {'additionalProperties': False, - 'properties': {'watcher-id': {'type': 'string'}}, - 'required': ['watcher-id'], - 'type': 'object'}, - 'ApplicationOfferStatus': {'additionalProperties': False, - 'properties': {'active-connected-count': {'type': 'integer'}, - 'application-name': {'type': 'string'}, - 'charm': {'type': 'string'}, - 'endpoints': {'patternProperties': {'.*': {'$ref': '#/definitions/RemoteEndpoint'}}, - 'type': 'object'}, - 'err': {'$ref': '#/definitions/Error'}, - 'offer-name': {'type': 'string'}, - 'total-connected-count': {'type': 'integer'}}, - 'required': ['offer-name', - 'application-name', - 'charm', - 'endpoints', - 'active-connected-count', - 'total-connected-count'], - 'type': 'object'}, - 'ApplicationStatus': {'additionalProperties': False, - 'properties': {'base': {'$ref': '#/definitions/Base'}, - 'can-upgrade-to': {'type': 'string'}, - 'charm': {'type': 'string'}, - 'charm-channel': {'type': 'string'}, - 'charm-profile': {'type': 'string'}, - 'charm-version': {'type': 'string'}, - 'endpoint-bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'err': {'$ref': '#/definitions/Error'}, - 'exposed': {'type': 'boolean'}, - 'exposed-endpoints': {'patternProperties': {'.*': {'$ref': '#/definitions/ExposedEndpoint'}}, - 'type': 'object'}, - 'int': {'type': 'integer'}, - 'life': {'type': 'string'}, - 'meter-statuses': {'patternProperties': {'.*': {'$ref': '#/definitions/MeterStatus'}}, - 'type': 'object'}, - 'provider-id': {'type': 'string'}, - 'public-address': {'type': 'string'}, - 'relations': {'patternProperties': {'.*': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'status': {'$ref': '#/definitions/DetailedStatus'}, - 'subordinate-to': {'items': {'type': 'string'}, - 'type': 'array'}, - 'units': {'patternProperties': {'.*': {'$ref': '#/definitions/UnitStatus'}}, - 'type': 'object'}, - 'workload-version': {'type': 'string'}}, - 'required': ['charm', - 'charm-version', - 'charm-profile', - 'base', - 'exposed', - 'life', - 'relations', - 'can-upgrade-to', - 'subordinate-to', - 'units', - 'meter-statuses', - 'status', - 'workload-version', - 'endpoint-bindings', - 'public-address'], - 'type': 'object'}, - 'Base': {'additionalProperties': False, - 'properties': {'channel': {'type': 'string'}, - 'name': {'type': 'string'}}, - 'required': ['name', 'channel'], - 'type': 'object'}, - 'Binary': {'additionalProperties': False, - 'properties': {'Arch': {'type': 'string'}, - 'Build': {'type': 'integer'}, - 'Major': {'type': 'integer'}, - 'Minor': {'type': 'integer'}, - 'Number': {'$ref': '#/definitions/Number'}, - 'Patch': {'type': 'integer'}, - 'Release': {'type': 'string'}, - 'Tag': {'type': 'string'}}, - 'required': ['Major', - 'Minor', - 'Tag', - 'Patch', - 'Build', - 'Number', - 'Release', - 'Arch'], - 'type': 'object'}, - 'BranchStatus': {'additionalProperties': False, - 'properties': {'assigned-units': {'patternProperties': {'.*': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'created': {'type': 'integer'}, - 'created-by': {'type': 'string'}}, - 'required': ['assigned-units', - 'created', - 'created-by'], - 'type': 'object'}, - 'DetailedStatus': {'additionalProperties': False, - 'properties': {'data': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'err': {'$ref': '#/definitions/Error'}, - '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'}, - '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': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - 'type': 'object'}, - 'ExposedEndpoint': {'additionalProperties': False, - 'properties': {'expose-to-cidrs': {'items': {'type': 'string'}, - 'type': 'array'}, - 'expose-to-spaces': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'FilesystemAttachmentDetails': {'additionalProperties': False, - 'properties': {'FilesystemAttachmentInfo': {'$ref': '#/definitions/FilesystemAttachmentInfo'}, - 'life': {'type': 'string'}, - 'mount-point': {'type': 'string'}, - 'read-only': {'type': 'boolean'}}, - 'required': ['FilesystemAttachmentInfo'], - 'type': 'object'}, - 'FilesystemAttachmentInfo': {'additionalProperties': False, - 'properties': {'mount-point': {'type': 'string'}, - 'read-only': {'type': 'boolean'}}, - 'type': 'object'}, - 'FilesystemDetails': {'additionalProperties': False, - 'properties': {'filesystem-tag': {'type': 'string'}, - 'info': {'$ref': '#/definitions/FilesystemInfo'}, - 'life': {'type': 'string'}, - 'machine-attachments': {'patternProperties': {'.*': {'$ref': '#/definitions/FilesystemAttachmentDetails'}}, - 'type': 'object'}, - 'status': {'$ref': '#/definitions/EntityStatus'}, - 'storage': {'$ref': '#/definitions/StorageDetails'}, - 'unit-attachments': {'patternProperties': {'.*': {'$ref': '#/definitions/FilesystemAttachmentDetails'}}, - 'type': 'object'}, - 'volume-tag': {'type': 'string'}}, - 'required': ['filesystem-tag', - 'info', - 'status'], - 'type': 'object'}, - 'FilesystemInfo': {'additionalProperties': False, - 'properties': {'filesystem-id': {'type': 'string'}, - 'pool': {'type': 'string'}, - 'size': {'type': 'integer'}}, - 'required': ['filesystem-id', - 'pool', - 'size'], - 'type': 'object'}, - 'FindToolsParams': {'additionalProperties': False, - 'properties': {'agentstream': {'type': 'string'}, - 'arch': {'type': 'string'}, - 'major': {'type': 'integer'}, - 'number': {'$ref': '#/definitions/Number'}, - 'os-type': {'type': 'string'}}, - 'required': ['number', - 'major', - 'arch', - 'os-type', - 'agentstream'], - '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'}, - 'branches': {'patternProperties': {'.*': {'$ref': '#/definitions/BranchStatus'}}, - 'type': 'object'}, - 'controller-timestamp': {'format': 'date-time', - 'type': 'string'}, - 'filesystems': {'items': {'$ref': '#/definitions/FilesystemDetails'}, - 'type': 'array'}, - 'machines': {'patternProperties': {'.*': {'$ref': '#/definitions/MachineStatus'}}, - 'type': 'object'}, - 'model': {'$ref': '#/definitions/ModelStatusInfo'}, - 'offers': {'patternProperties': {'.*': {'$ref': '#/definitions/ApplicationOfferStatus'}}, - 'type': 'object'}, - 'relations': {'items': {'$ref': '#/definitions/RelationStatus'}, - 'type': 'array'}, - 'remote-applications': {'patternProperties': {'.*': {'$ref': '#/definitions/RemoteApplicationStatus'}}, - 'type': 'object'}, - 'storage': {'items': {'$ref': '#/definitions/StorageDetails'}, - 'type': 'array'}, - 'volumes': {'items': {'$ref': '#/definitions/VolumeDetails'}, - 'type': 'array'}}, - 'required': ['model', - 'machines', - 'applications', - 'remote-applications', - 'offers', - 'relations', - 'controller-timestamp', - 'branches'], - 'type': 'object'}, - 'History': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'statuses': {'items': {'$ref': '#/definitions/DetailedStatus'}, - 'type': 'array'}}, - 'required': ['statuses'], - 'type': 'object'}, - 'LXDProfile': {'additionalProperties': False, - 'properties': {'config': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'description': {'type': 'string'}, - 'devices': {'patternProperties': {'.*': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}}, - 'type': 'object'}}, - 'required': ['config', - 'description', - 'devices'], - 'type': 'object'}, - 'MachineStatus': {'additionalProperties': False, - 'properties': {'agent-status': {'$ref': '#/definitions/DetailedStatus'}, - 'base': {'$ref': '#/definitions/Base'}, - 'constraints': {'type': 'string'}, - 'containers': {'patternProperties': {'.*': {'$ref': '#/definitions/MachineStatus'}}, - 'type': 'object'}, - 'display-name': {'type': 'string'}, - 'dns-name': {'type': 'string'}, - 'hardware': {'type': 'string'}, - 'has-vote': {'type': 'boolean'}, - 'hostname': {'type': 'string'}, - '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'}, - 'lxd-profiles': {'patternProperties': {'.*': {'$ref': '#/definitions/LXDProfile'}}, - 'type': 'object'}, - 'modification-status': {'$ref': '#/definitions/DetailedStatus'}, - 'network-interfaces': {'patternProperties': {'.*': {'$ref': '#/definitions/NetworkInterface'}}, - 'type': 'object'}, - 'primary-controller-machine': {'type': 'boolean'}, - 'wants-vote': {'type': 'boolean'}}, - 'required': ['agent-status', - 'instance-status', - 'modification-status', - 'dns-name', - 'instance-id', - 'display-name', - 'base', - 'id', - 'containers', - 'constraints', - 'hardware', - 'jobs', - 'has-vote', - 'wants-vote'], - 'type': 'object'}, - 'MeterStatus': {'additionalProperties': False, - 'properties': {'color': {'type': 'string'}, - 'message': {'type': 'string'}}, - 'required': ['color', 'message'], - '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'}, - 'type': {'type': 'string'}, - 'version': {'type': 'string'}}, - 'required': ['name', - 'type', - 'cloud-tag', - 'version', - 'available-version', - 'model-status', - 'meter-status', - 'sla'], - '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'], - 'type': 'object'}, - 'RelationStatus': {'additionalProperties': False, - 'properties': {'endpoints': {'items': {'$ref': '#/definitions/EndpointStatus'}, - 'type': 'array'}, - 'id': {'type': 'integer'}, - 'interface': {'type': 'string'}, - 'key': {'type': 'string'}, - 'scope': {'type': 'string'}, - 'status': {'$ref': '#/definitions/DetailedStatus'}}, - 'required': ['id', - 'key', - 'interface', - 'scope', - 'endpoints', - 'status'], - 'type': 'object'}, - 'RemoteApplicationStatus': {'additionalProperties': False, - 'properties': {'endpoints': {'items': {'$ref': '#/definitions/RemoteEndpoint'}, - 'type': 'array'}, - 'err': {'$ref': '#/definitions/Error'}, - 'life': {'type': 'string'}, - 'offer-name': {'type': 'string'}, - 'offer-url': {'type': 'string'}, - 'relations': {'patternProperties': {'.*': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'status': {'$ref': '#/definitions/DetailedStatus'}}, - 'required': ['offer-url', - 'offer-name', - 'endpoints', - 'life', - 'relations', - 'status'], - 'type': 'object'}, - 'RemoteEndpoint': {'additionalProperties': False, - 'properties': {'interface': {'type': 'string'}, - 'limit': {'type': 'integer'}, - 'name': {'type': 'string'}, - 'role': {'type': 'string'}}, - 'required': ['name', - 'role', - 'interface', - 'limit'], - 'type': 'object'}, - 'StatusHistoryFilter': {'additionalProperties': False, - 'properties': {'date': {'format': 'date-time', - 'type': 'string'}, - 'delta': {'type': 'integer'}, - 'exclude': {'items': {'type': 'string'}, - 'type': 'array'}, - 'size': {'type': 'integer'}}, - 'required': ['size', - 'date', - 'delta', - 'exclude'], - 'type': 'object'}, - 'StatusHistoryRequest': {'additionalProperties': False, - 'properties': {'filter': {'$ref': '#/definitions/StatusHistoryFilter'}, - 'historyKind': {'type': 'string'}, - 'size': {'type': 'integer'}, - 'tag': {'type': 'string'}}, - 'required': ['historyKind', - 'size', - 'filter', - 'tag'], - 'type': 'object'}, - 'StatusHistoryRequests': {'additionalProperties': False, - 'properties': {'requests': {'items': {'$ref': '#/definitions/StatusHistoryRequest'}, - 'type': 'array'}}, - 'required': ['requests'], - 'type': 'object'}, - 'StatusHistoryResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'history': {'$ref': '#/definitions/History'}}, - 'required': ['history'], - 'type': 'object'}, - 'StatusHistoryResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/StatusHistoryResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'StatusParams': {'additionalProperties': False, - 'properties': {'include-storage': {'type': 'boolean'}, - 'patterns': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['patterns'], - 'type': 'object'}, - 'StorageAttachmentDetails': {'additionalProperties': False, - 'properties': {'life': {'type': 'string'}, - 'location': {'type': 'string'}, - 'machine-tag': {'type': 'string'}, - 'storage-tag': {'type': 'string'}, - 'unit-tag': {'type': 'string'}}, - 'required': ['storage-tag', - 'unit-tag', - 'machine-tag'], - 'type': 'object'}, - 'StorageDetails': {'additionalProperties': False, - 'properties': {'attachments': {'patternProperties': {'.*': {'$ref': '#/definitions/StorageAttachmentDetails'}}, - 'type': 'object'}, - 'kind': {'type': 'integer'}, - 'life': {'type': 'string'}, - 'owner-tag': {'type': 'string'}, - 'persistent': {'type': 'boolean'}, - 'status': {'$ref': '#/definitions/EntityStatus'}, - 'storage-tag': {'type': 'string'}}, - 'required': ['storage-tag', - 'owner-tag', - 'kind', - 'status', - 'persistent'], - 'type': 'object'}, - 'Tools': {'additionalProperties': False, - 'properties': {'sha256': {'type': 'string'}, - 'size': {'type': 'integer'}, - 'url': {'type': 'string'}, - 'version': {'$ref': '#/definitions/Binary'}}, - 'required': ['version', 'url', 'size'], - 'type': 'object'}, - 'UnitStatus': {'additionalProperties': False, - 'properties': {'address': {'type': 'string'}, - 'agent-status': {'$ref': '#/definitions/DetailedStatus'}, - 'charm': {'type': 'string'}, - 'leader': {'type': 'boolean'}, - 'machine': {'type': 'string'}, - 'opened-ports': {'items': {'type': 'string'}, - 'type': 'array'}, - 'provider-id': {'type': 'string'}, - 'public-address': {'type': 'string'}, - 'subordinates': {'patternProperties': {'.*': {'$ref': '#/definitions/UnitStatus'}}, - 'type': 'object'}, - 'workload-status': {'$ref': '#/definitions/DetailedStatus'}, - 'workload-version': {'type': 'string'}}, - 'required': ['agent-status', - 'workload-status', - 'workload-version', - 'machine', - 'opened-ports', - 'public-address', - 'charm', - 'subordinates'], - 'type': 'object'}, - 'VolumeAttachmentDetails': {'additionalProperties': False, - 'properties': {'VolumeAttachmentInfo': {'$ref': '#/definitions/VolumeAttachmentInfo'}, - 'bus-address': {'type': 'string'}, - 'device-link': {'type': 'string'}, - 'device-name': {'type': 'string'}, - 'life': {'type': 'string'}, - 'plan-info': {'$ref': '#/definitions/VolumeAttachmentPlanInfo'}, - 'read-only': {'type': 'boolean'}}, - 'required': ['VolumeAttachmentInfo'], - 'type': 'object'}, - 'VolumeAttachmentInfo': {'additionalProperties': False, - 'properties': {'bus-address': {'type': 'string'}, - 'device-link': {'type': 'string'}, - 'device-name': {'type': 'string'}, - 'plan-info': {'$ref': '#/definitions/VolumeAttachmentPlanInfo'}, - 'read-only': {'type': 'boolean'}}, - 'type': 'object'}, - 'VolumeAttachmentPlanInfo': {'additionalProperties': False, - 'properties': {'device-attributes': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'device-type': {'type': 'string'}}, - 'type': 'object'}, - 'VolumeDetails': {'additionalProperties': False, - 'properties': {'info': {'$ref': '#/definitions/VolumeInfo'}, - 'life': {'type': 'string'}, - 'machine-attachments': {'patternProperties': {'.*': {'$ref': '#/definitions/VolumeAttachmentDetails'}}, - 'type': 'object'}, - 'status': {'$ref': '#/definitions/EntityStatus'}, - 'storage': {'$ref': '#/definitions/StorageDetails'}, - 'unit-attachments': {'patternProperties': {'.*': {'$ref': '#/definitions/VolumeAttachmentDetails'}}, - 'type': 'object'}, - 'volume-tag': {'type': 'string'}}, - 'required': ['volume-tag', 'info', 'status'], - 'type': 'object'}, - 'VolumeInfo': {'additionalProperties': False, - 'properties': {'hardware-id': {'type': 'string'}, - 'persistent': {'type': 'boolean'}, - 'pool': {'type': 'string'}, - 'size': {'type': 'integer'}, - 'volume-id': {'type': 'string'}, - 'wwn': {'type': 'string'}}, - 'required': ['volume-id', 'size', 'persistent'], - 'type': 'object'}}, - 'properties': {'FindTools': {'description': 'FindTools returns a List ' - 'containing all tools matching ' - 'the given parameters.\n' - 'TODO(juju 3.1) - remove, used by ' - '2.9 client only', - 'properties': {'Params': {'$ref': '#/definitions/FindToolsParams'}, - 'Result': {'$ref': '#/definitions/FindToolsResult'}}, - 'type': 'object'}, - 'FullStatus': {'description': 'FullStatus gives the ' - 'information needed for juju ' - 'status over the api', - 'properties': {'Params': {'$ref': '#/definitions/StatusParams'}, - 'Result': {'$ref': '#/definitions/FullStatus'}}, - 'type': 'object'}, - 'StatusHistory': {'description': 'StatusHistory returns a ' - 'slice of past statuses for ' - 'several entities.', - 'properties': {'Params': {'$ref': '#/definitions/StatusHistoryRequests'}, - 'Result': {'$ref': '#/definitions/StatusHistoryResults'}}, - 'type': 'object'}, - 'WatchAll': {'description': 'WatchAll initiates a watcher for ' - 'entities in the connected model.', - 'properties': {'Result': {'$ref': '#/definitions/AllWatcherId'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "AllWatcherId": { + "additionalProperties": False, + "properties": {"watcher-id": {"type": "string"}}, + "required": ["watcher-id"], + "type": "object", + }, + "ApplicationOfferStatus": { + "additionalProperties": False, + "properties": { + "active-connected-count": {"type": "integer"}, + "application-name": {"type": "string"}, + "charm": {"type": "string"}, + "endpoints": { + "patternProperties": { + ".*": {"$ref": "#/definitions/RemoteEndpoint"} + }, + "type": "object", + }, + "err": {"$ref": "#/definitions/Error"}, + "offer-name": {"type": "string"}, + "total-connected-count": {"type": "integer"}, + }, + "required": [ + "offer-name", + "application-name", + "charm", + "endpoints", + "active-connected-count", + "total-connected-count", + ], + "type": "object", + }, + "ApplicationStatus": { + "additionalProperties": False, + "properties": { + "base": {"$ref": "#/definitions/Base"}, + "can-upgrade-to": {"type": "string"}, + "charm": {"type": "string"}, + "charm-channel": {"type": "string"}, + "charm-profile": {"type": "string"}, + "charm-version": {"type": "string"}, + "endpoint-bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "err": {"$ref": "#/definitions/Error"}, + "exposed": {"type": "boolean"}, + "exposed-endpoints": { + "patternProperties": { + ".*": {"$ref": "#/definitions/ExposedEndpoint"} + }, + "type": "object", + }, + "int": {"type": "integer"}, + "life": {"type": "string"}, + "meter-statuses": { + "patternProperties": { + ".*": {"$ref": "#/definitions/MeterStatus"} + }, + "type": "object", + }, + "provider-id": {"type": "string"}, + "public-address": {"type": "string"}, + "relations": { + "patternProperties": { + ".*": {"items": {"type": "string"}, "type": "array"} + }, + "type": "object", + }, + "status": {"$ref": "#/definitions/DetailedStatus"}, + "subordinate-to": {"items": {"type": "string"}, "type": "array"}, + "units": { + "patternProperties": { + ".*": {"$ref": "#/definitions/UnitStatus"} + }, + "type": "object", + }, + "workload-version": {"type": "string"}, + }, + "required": [ + "charm", + "charm-version", + "charm-profile", + "base", + "exposed", + "life", + "relations", + "can-upgrade-to", + "subordinate-to", + "units", + "meter-statuses", + "status", + "workload-version", + "endpoint-bindings", + "public-address", + ], + "type": "object", + }, + "Base": { + "additionalProperties": False, + "properties": { + "channel": {"type": "string"}, + "name": {"type": "string"}, + }, + "required": ["name", "channel"], + "type": "object", + }, + "Binary": { + "additionalProperties": False, + "properties": { + "Arch": {"type": "string"}, + "Build": {"type": "integer"}, + "Major": {"type": "integer"}, + "Minor": {"type": "integer"}, + "Number": {"$ref": "#/definitions/Number"}, + "Patch": {"type": "integer"}, + "Release": {"type": "string"}, + "Tag": {"type": "string"}, + }, + "required": [ + "Major", + "Minor", + "Tag", + "Patch", + "Build", + "Number", + "Release", + "Arch", + ], + "type": "object", + }, + "BranchStatus": { + "additionalProperties": False, + "properties": { + "assigned-units": { + "patternProperties": { + ".*": {"items": {"type": "string"}, "type": "array"} + }, + "type": "object", + }, + "created": {"type": "integer"}, + "created-by": {"type": "string"}, + }, + "required": ["assigned-units", "created", "created-by"], + "type": "object", + }, + "DetailedStatus": { + "additionalProperties": False, + "properties": { + "data": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "err": {"$ref": "#/definitions/Error"}, + "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", + }, + "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": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "type": "object", + }, + "ExposedEndpoint": { + "additionalProperties": False, + "properties": { + "expose-to-cidrs": {"items": {"type": "string"}, "type": "array"}, + "expose-to-spaces": {"items": {"type": "string"}, "type": "array"}, + }, + "type": "object", + }, + "FilesystemAttachmentDetails": { + "additionalProperties": False, + "properties": { + "FilesystemAttachmentInfo": { + "$ref": "#/definitions/FilesystemAttachmentInfo" + }, + "life": {"type": "string"}, + "mount-point": {"type": "string"}, + "read-only": {"type": "boolean"}, + }, + "required": ["FilesystemAttachmentInfo"], + "type": "object", + }, + "FilesystemAttachmentInfo": { + "additionalProperties": False, + "properties": { + "mount-point": {"type": "string"}, + "read-only": {"type": "boolean"}, + }, + "type": "object", + }, + "FilesystemDetails": { + "additionalProperties": False, + "properties": { + "filesystem-tag": {"type": "string"}, + "info": {"$ref": "#/definitions/FilesystemInfo"}, + "life": {"type": "string"}, + "machine-attachments": { + "patternProperties": { + ".*": {"$ref": "#/definitions/FilesystemAttachmentDetails"} + }, + "type": "object", + }, + "status": {"$ref": "#/definitions/EntityStatus"}, + "storage": {"$ref": "#/definitions/StorageDetails"}, + "unit-attachments": { + "patternProperties": { + ".*": {"$ref": "#/definitions/FilesystemAttachmentDetails"} + }, + "type": "object", + }, + "volume-tag": {"type": "string"}, + }, + "required": ["filesystem-tag", "info", "status"], + "type": "object", + }, + "FilesystemInfo": { + "additionalProperties": False, + "properties": { + "filesystem-id": {"type": "string"}, + "pool": {"type": "string"}, + "size": {"type": "integer"}, + }, + "required": ["filesystem-id", "pool", "size"], + "type": "object", + }, + "FindToolsParams": { + "additionalProperties": False, + "properties": { + "agentstream": {"type": "string"}, + "arch": {"type": "string"}, + "major": {"type": "integer"}, + "number": {"$ref": "#/definitions/Number"}, + "os-type": {"type": "string"}, + }, + "required": ["number", "major", "arch", "os-type", "agentstream"], + "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", + }, + "branches": { + "patternProperties": { + ".*": {"$ref": "#/definitions/BranchStatus"} + }, + "type": "object", + }, + "controller-timestamp": {"format": "date-time", "type": "string"}, + "filesystems": { + "items": {"$ref": "#/definitions/FilesystemDetails"}, + "type": "array", + }, + "machines": { + "patternProperties": { + ".*": {"$ref": "#/definitions/MachineStatus"} + }, + "type": "object", + }, + "model": {"$ref": "#/definitions/ModelStatusInfo"}, + "offers": { + "patternProperties": { + ".*": {"$ref": "#/definitions/ApplicationOfferStatus"} + }, + "type": "object", + }, + "relations": { + "items": {"$ref": "#/definitions/RelationStatus"}, + "type": "array", + }, + "remote-applications": { + "patternProperties": { + ".*": {"$ref": "#/definitions/RemoteApplicationStatus"} + }, + "type": "object", + }, + "storage": { + "items": {"$ref": "#/definitions/StorageDetails"}, + "type": "array", + }, + "volumes": { + "items": {"$ref": "#/definitions/VolumeDetails"}, + "type": "array", + }, + }, + "required": [ + "model", + "machines", + "applications", + "remote-applications", + "offers", + "relations", + "controller-timestamp", + "branches", + ], + "type": "object", + }, + "History": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "statuses": { + "items": {"$ref": "#/definitions/DetailedStatus"}, + "type": "array", + }, + }, + "required": ["statuses"], + "type": "object", + }, + "LXDProfile": { + "additionalProperties": False, + "properties": { + "config": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "description": {"type": "string"}, + "devices": { + "patternProperties": { + ".*": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + } + }, + "type": "object", + }, + }, + "required": ["config", "description", "devices"], + "type": "object", + }, + "MachineStatus": { + "additionalProperties": False, + "properties": { + "agent-status": {"$ref": "#/definitions/DetailedStatus"}, + "base": {"$ref": "#/definitions/Base"}, + "constraints": {"type": "string"}, + "containers": { + "patternProperties": { + ".*": {"$ref": "#/definitions/MachineStatus"} + }, + "type": "object", + }, + "display-name": {"type": "string"}, + "dns-name": {"type": "string"}, + "hardware": {"type": "string"}, + "has-vote": {"type": "boolean"}, + "hostname": {"type": "string"}, + "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"}, + "lxd-profiles": { + "patternProperties": { + ".*": {"$ref": "#/definitions/LXDProfile"} + }, + "type": "object", + }, + "modification-status": {"$ref": "#/definitions/DetailedStatus"}, + "network-interfaces": { + "patternProperties": { + ".*": {"$ref": "#/definitions/NetworkInterface"} + }, + "type": "object", + }, + "primary-controller-machine": {"type": "boolean"}, + "wants-vote": {"type": "boolean"}, + }, + "required": [ + "agent-status", + "instance-status", + "modification-status", + "dns-name", + "instance-id", + "display-name", + "base", + "id", + "containers", + "constraints", + "hardware", + "jobs", + "has-vote", + "wants-vote", + ], + "type": "object", + }, + "MeterStatus": { + "additionalProperties": False, + "properties": { + "color": {"type": "string"}, + "message": {"type": "string"}, + }, + "required": ["color", "message"], + "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"}, + "type": {"type": "string"}, + "version": {"type": "string"}, + }, + "required": [ + "name", + "type", + "cloud-tag", + "version", + "available-version", + "model-status", + "meter-status", + "sla", + ], + "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"], + "type": "object", + }, + "RelationStatus": { + "additionalProperties": False, + "properties": { + "endpoints": { + "items": {"$ref": "#/definitions/EndpointStatus"}, + "type": "array", + }, + "id": {"type": "integer"}, + "interface": {"type": "string"}, + "key": {"type": "string"}, + "scope": {"type": "string"}, + "status": {"$ref": "#/definitions/DetailedStatus"}, + }, + "required": ["id", "key", "interface", "scope", "endpoints", "status"], + "type": "object", + }, + "RemoteApplicationStatus": { + "additionalProperties": False, + "properties": { + "endpoints": { + "items": {"$ref": "#/definitions/RemoteEndpoint"}, + "type": "array", + }, + "err": {"$ref": "#/definitions/Error"}, + "life": {"type": "string"}, + "offer-name": {"type": "string"}, + "offer-url": {"type": "string"}, + "relations": { + "patternProperties": { + ".*": {"items": {"type": "string"}, "type": "array"} + }, + "type": "object", + }, + "status": {"$ref": "#/definitions/DetailedStatus"}, + }, + "required": [ + "offer-url", + "offer-name", + "endpoints", + "life", + "relations", + "status", + ], + "type": "object", + }, + "RemoteEndpoint": { + "additionalProperties": False, + "properties": { + "interface": {"type": "string"}, + "limit": {"type": "integer"}, + "name": {"type": "string"}, + "role": {"type": "string"}, + }, + "required": ["name", "role", "interface", "limit"], + "type": "object", + }, + "StatusHistoryFilter": { + "additionalProperties": False, + "properties": { + "date": {"format": "date-time", "type": "string"}, + "delta": {"type": "integer"}, + "exclude": {"items": {"type": "string"}, "type": "array"}, + "size": {"type": "integer"}, + }, + "required": ["size", "date", "delta", "exclude"], + "type": "object", + }, + "StatusHistoryRequest": { + "additionalProperties": False, + "properties": { + "filter": {"$ref": "#/definitions/StatusHistoryFilter"}, + "historyKind": {"type": "string"}, + "size": {"type": "integer"}, + "tag": {"type": "string"}, + }, + "required": ["historyKind", "size", "filter", "tag"], + "type": "object", + }, + "StatusHistoryRequests": { + "additionalProperties": False, + "properties": { + "requests": { + "items": {"$ref": "#/definitions/StatusHistoryRequest"}, + "type": "array", + } + }, + "required": ["requests"], + "type": "object", + }, + "StatusHistoryResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "history": {"$ref": "#/definitions/History"}, + }, + "required": ["history"], + "type": "object", + }, + "StatusHistoryResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/StatusHistoryResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "StatusParams": { + "additionalProperties": False, + "properties": { + "include-storage": {"type": "boolean"}, + "patterns": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["patterns"], + "type": "object", + }, + "StorageAttachmentDetails": { + "additionalProperties": False, + "properties": { + "life": {"type": "string"}, + "location": {"type": "string"}, + "machine-tag": {"type": "string"}, + "storage-tag": {"type": "string"}, + "unit-tag": {"type": "string"}, + }, + "required": ["storage-tag", "unit-tag", "machine-tag"], + "type": "object", + }, + "StorageDetails": { + "additionalProperties": False, + "properties": { + "attachments": { + "patternProperties": { + ".*": {"$ref": "#/definitions/StorageAttachmentDetails"} + }, + "type": "object", + }, + "kind": {"type": "integer"}, + "life": {"type": "string"}, + "owner-tag": {"type": "string"}, + "persistent": {"type": "boolean"}, + "status": {"$ref": "#/definitions/EntityStatus"}, + "storage-tag": {"type": "string"}, + }, + "required": [ + "storage-tag", + "owner-tag", + "kind", + "status", + "persistent", + ], + "type": "object", + }, + "Tools": { + "additionalProperties": False, + "properties": { + "sha256": {"type": "string"}, + "size": {"type": "integer"}, + "url": {"type": "string"}, + "version": {"$ref": "#/definitions/Binary"}, + }, + "required": ["version", "url", "size"], + "type": "object", + }, + "UnitStatus": { + "additionalProperties": False, + "properties": { + "address": {"type": "string"}, + "agent-status": {"$ref": "#/definitions/DetailedStatus"}, + "charm": {"type": "string"}, + "leader": {"type": "boolean"}, + "machine": {"type": "string"}, + "opened-ports": {"items": {"type": "string"}, "type": "array"}, + "provider-id": {"type": "string"}, + "public-address": {"type": "string"}, + "subordinates": { + "patternProperties": { + ".*": {"$ref": "#/definitions/UnitStatus"} + }, + "type": "object", + }, + "workload-status": {"$ref": "#/definitions/DetailedStatus"}, + "workload-version": {"type": "string"}, + }, + "required": [ + "agent-status", + "workload-status", + "workload-version", + "machine", + "opened-ports", + "public-address", + "charm", + "subordinates", + ], + "type": "object", + }, + "VolumeAttachmentDetails": { + "additionalProperties": False, + "properties": { + "VolumeAttachmentInfo": { + "$ref": "#/definitions/VolumeAttachmentInfo" + }, + "bus-address": {"type": "string"}, + "device-link": {"type": "string"}, + "device-name": {"type": "string"}, + "life": {"type": "string"}, + "plan-info": {"$ref": "#/definitions/VolumeAttachmentPlanInfo"}, + "read-only": {"type": "boolean"}, + }, + "required": ["VolumeAttachmentInfo"], + "type": "object", + }, + "VolumeAttachmentInfo": { + "additionalProperties": False, + "properties": { + "bus-address": {"type": "string"}, + "device-link": {"type": "string"}, + "device-name": {"type": "string"}, + "plan-info": {"$ref": "#/definitions/VolumeAttachmentPlanInfo"}, + "read-only": {"type": "boolean"}, + }, + "type": "object", + }, + "VolumeAttachmentPlanInfo": { + "additionalProperties": False, + "properties": { + "device-attributes": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "device-type": {"type": "string"}, + }, + "type": "object", + }, + "VolumeDetails": { + "additionalProperties": False, + "properties": { + "info": {"$ref": "#/definitions/VolumeInfo"}, + "life": {"type": "string"}, + "machine-attachments": { + "patternProperties": { + ".*": {"$ref": "#/definitions/VolumeAttachmentDetails"} + }, + "type": "object", + }, + "status": {"$ref": "#/definitions/EntityStatus"}, + "storage": {"$ref": "#/definitions/StorageDetails"}, + "unit-attachments": { + "patternProperties": { + ".*": {"$ref": "#/definitions/VolumeAttachmentDetails"} + }, + "type": "object", + }, + "volume-tag": {"type": "string"}, + }, + "required": ["volume-tag", "info", "status"], + "type": "object", + }, + "VolumeInfo": { + "additionalProperties": False, + "properties": { + "hardware-id": {"type": "string"}, + "persistent": {"type": "boolean"}, + "pool": {"type": "string"}, + "size": {"type": "integer"}, + "volume-id": {"type": "string"}, + "wwn": {"type": "string"}, + }, + "required": ["volume-id", "size", "persistent"], + "type": "object", + }, + }, + "properties": { + "FindTools": { + "description": "FindTools returns a List " + "containing all tools matching " + "the given parameters.\n" + "TODO(juju 3.1) - remove, used by " + "2.9 client only", + "properties": { + "Params": {"$ref": "#/definitions/FindToolsParams"}, + "Result": {"$ref": "#/definitions/FindToolsResult"}, + }, + "type": "object", + }, + "FullStatus": { + "description": "FullStatus gives the " + "information needed for juju " + "status over the api", + "properties": { + "Params": {"$ref": "#/definitions/StatusParams"}, + "Result": {"$ref": "#/definitions/FullStatus"}, + }, + "type": "object", + }, + "StatusHistory": { + "description": "StatusHistory returns a " + "slice of past statuses for " + "several entities.", + "properties": { + "Params": {"$ref": "#/definitions/StatusHistoryRequests"}, + "Result": {"$ref": "#/definitions/StatusHistoryResults"}, + }, + "type": "object", + }, + "WatchAll": { + "description": "WatchAll initiates a watcher for " + "entities in the connected model.", + "properties": {"Result": {"$ref": "#/definitions/AllWatcherId"}}, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(FindToolsResult) - async def FindTools(self, agentstream=None, arch=None, major=None, number=None, os_type=None): - ''' + async def FindTools( + self, agentstream=None, arch=None, major=None, number=None, os_type=None + ): + """ FindTools returns a List containing all tools matching the given parameters. TODO(juju 3.1) - remove, used by 2.9 client only @@ -1746,672 +2493,994 @@ async def FindTools(self, agentstream=None, arch=None, major=None, number=None, number : Number os_type : str Returns -> FindToolsResult - ''' + """ if agentstream is not None and not isinstance(agentstream, (bytes, str)): - raise Exception("Expected agentstream to be a str, received: {}".format(type(agentstream))) + raise Exception( + "Expected agentstream to be a str, received: {}".format( + type(agentstream) + ) + ) if arch is not None and not isinstance(arch, (bytes, str)): - raise Exception("Expected arch to be a str, received: {}".format(type(arch))) + raise Exception( + "Expected arch to be a str, received: {}".format(type(arch)) + ) if major is not None and not isinstance(major, int): - raise Exception("Expected major to be a int, received: {}".format(type(major))) + raise Exception( + "Expected major to be a int, received: {}".format(type(major)) + ) if number is not None and not isinstance(number, (dict, Number)): - raise Exception("Expected number to be a Number, received: {}".format(type(number))) + raise Exception( + "Expected number to be a Number, received: {}".format(type(number)) + ) if os_type is not None and not isinstance(os_type, (bytes, str)): - raise Exception("Expected os_type to be a str, received: {}".format(type(os_type))) + raise Exception( + "Expected os_type to be a str, received: {}".format(type(os_type)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Client', - request='FindTools', - version=7, - params=_params) - _params['agentstream'] = agentstream - _params['arch'] = arch - _params['major'] = major - _params['number'] = number - _params['os-type'] = os_type + msg = dict(type="Client", request="FindTools", version=7, params=_params) + _params["agentstream"] = agentstream + _params["arch"] = arch + _params["major"] = major + _params["number"] = number + _params["os-type"] = os_type reply = await self.rpc(msg) return reply - - @ReturnMapping(FullStatus) async def FullStatus(self, include_storage=None, patterns=None): - ''' + """ FullStatus gives the information needed for juju status over the api include_storage : bool patterns : typing.Sequence[str] Returns -> FullStatus - ''' + """ if include_storage is not None and not isinstance(include_storage, bool): - raise Exception("Expected include_storage to be a bool, received: {}".format(type(include_storage))) + raise Exception( + "Expected include_storage to be a bool, received: {}".format( + type(include_storage) + ) + ) if patterns is not None and not isinstance(patterns, (bytes, str, list)): - raise Exception("Expected patterns to be a Sequence, received: {}".format(type(patterns))) + raise Exception( + "Expected patterns to be a Sequence, received: {}".format( + type(patterns) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Client', - request='FullStatus', - version=7, - params=_params) - _params['include-storage'] = include_storage - _params['patterns'] = patterns + msg = dict(type="Client", request="FullStatus", version=7, params=_params) + _params["include-storage"] = include_storage + _params["patterns"] = patterns reply = await self.rpc(msg) return reply - - @ReturnMapping(StatusHistoryResults) async def StatusHistory(self, requests=None): - ''' + """ StatusHistory returns a slice of past statuses for several entities. requests : typing.Sequence[~StatusHistoryRequest] Returns -> StatusHistoryResults - ''' + """ if requests is not None and not isinstance(requests, (bytes, str, list)): - raise Exception("Expected requests to be a Sequence, received: {}".format(type(requests))) + raise Exception( + "Expected requests to be a Sequence, received: {}".format( + type(requests) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Client', - request='StatusHistory', - version=7, - params=_params) - _params['requests'] = requests + msg = dict(type="Client", request="StatusHistory", version=7, params=_params) + _params["requests"] = requests reply = await self.rpc(msg) return reply - - @ReturnMapping(AllWatcherId) async def WatchAll(self): - ''' + """ WatchAll initiates a watcher for entities in the connected model. Returns -> AllWatcherId - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Client', - request='WatchAll', - version=7, - params=_params) + msg = dict(type="Client", request="WatchAll", version=7, params=_params) reply = await self.rpc(msg) return reply - class CloudFacade(Type): - name = 'Cloud' + name = "Cloud" version = 7 - schema = {'definitions': {'AddCloudArgs': {'additionalProperties': False, - 'properties': {'cloud': {'$ref': '#/definitions/Cloud'}, - 'force': {'type': 'boolean'}, - 'name': {'type': 'string'}}, - 'required': ['cloud', 'name'], - 'type': 'object'}, - 'Cloud': {'additionalProperties': False, - 'properties': {'auth-types': {'items': {'type': 'string'}, - 'type': 'array'}, - 'ca-certificates': {'items': {'type': 'string'}, - 'type': 'array'}, - 'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'endpoint': {'type': 'string'}, - 'host-cloud-region': {'type': 'string'}, - 'identity-endpoint': {'type': 'string'}, - 'is-controller-cloud': {'type': 'boolean'}, - 'region-config': {'patternProperties': {'.*': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}}, - 'type': 'object'}, - 'regions': {'items': {'$ref': '#/definitions/CloudRegion'}, - 'type': 'array'}, - 'skip-tls-verify': {'type': 'boolean'}, - 'storage-endpoint': {'type': 'string'}, - 'type': {'type': 'string'}}, - 'required': ['type'], - 'type': 'object'}, - 'CloudCredential': {'additionalProperties': False, - 'properties': {'attrs': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'auth-type': {'type': 'string'}, - 'redacted': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['auth-type'], - 'type': 'object'}, - 'CloudCredentialArg': {'additionalProperties': False, - 'properties': {'cloud-name': {'type': 'string'}, - 'credential-name': {'type': 'string'}}, - 'required': ['cloud-name', - 'credential-name'], - 'type': 'object'}, - 'CloudCredentialArgs': {'additionalProperties': False, - 'properties': {'credentials': {'items': {'$ref': '#/definitions/CloudCredentialArg'}, - 'type': 'array'}, - 'include-secrets': {'type': 'boolean'}}, - 'required': ['include-secrets'], - 'type': 'object'}, - 'CloudCredentialResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/CloudCredential'}}, - 'type': 'object'}, - 'CloudCredentialResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/CloudCredentialResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'CloudDetails': {'additionalProperties': False, - 'properties': {'auth-types': {'items': {'type': 'string'}, - 'type': 'array'}, - 'endpoint': {'type': 'string'}, - 'identity-endpoint': {'type': 'string'}, - 'regions': {'items': {'$ref': '#/definitions/CloudRegion'}, - 'type': 'array'}, - 'storage-endpoint': {'type': 'string'}, - 'type': {'type': 'string'}}, - 'required': ['type'], - 'type': 'object'}, - 'CloudInfo': {'additionalProperties': False, - 'properties': {'CloudDetails': {'$ref': '#/definitions/CloudDetails'}, - 'users': {'items': {'$ref': '#/definitions/CloudUserInfo'}, - 'type': 'array'}}, - 'required': ['CloudDetails', 'users'], - 'type': 'object'}, - 'CloudInfoResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/CloudInfo'}}, - 'type': 'object'}, - 'CloudInfoResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/CloudInfoResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'CloudInstanceTypesConstraint': {'additionalProperties': False, - 'properties': {'cloud-tag': {'type': 'string'}, - 'constraints': {'$ref': '#/definitions/Value'}, - 'region': {'type': 'string'}}, - 'required': ['cloud-tag', - 'region'], - 'type': 'object'}, - 'CloudInstanceTypesConstraints': {'additionalProperties': False, - 'properties': {'constraints': {'items': {'$ref': '#/definitions/CloudInstanceTypesConstraint'}, - 'type': 'array'}}, - 'required': ['constraints'], - 'type': 'object'}, - 'CloudRegion': {'additionalProperties': False, - 'properties': {'endpoint': {'type': 'string'}, - 'identity-endpoint': {'type': 'string'}, - 'name': {'type': 'string'}, - 'storage-endpoint': {'type': 'string'}}, - 'required': ['name'], - 'type': 'object'}, - 'CloudResult': {'additionalProperties': False, - 'properties': {'cloud': {'$ref': '#/definitions/Cloud'}, - 'error': {'$ref': '#/definitions/Error'}}, - 'type': 'object'}, - 'CloudResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/CloudResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'CloudUserInfo': {'additionalProperties': False, - 'properties': {'access': {'type': 'string'}, - 'display-name': {'type': 'string'}, - 'user': {'type': 'string'}}, - 'required': ['user', - 'display-name', - 'access'], - 'type': 'object'}, - 'CloudsResult': {'additionalProperties': False, - 'properties': {'clouds': {'patternProperties': {'.*': {'$ref': '#/definitions/Cloud'}}, - 'type': 'object'}}, - 'type': 'object'}, - 'ControllerCredentialInfo': {'additionalProperties': False, - 'properties': {'content': {'$ref': '#/definitions/CredentialContent'}, - 'models': {'items': {'$ref': '#/definitions/ModelAccess'}, - 'type': 'array'}}, - 'type': 'object'}, - 'CredentialContent': {'additionalProperties': False, - 'properties': {'attrs': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'auth-type': {'type': 'string'}, - 'cloud': {'type': 'string'}, - 'name': {'type': 'string'}, - 'valid': {'type': 'boolean'}}, - 'required': ['name', - 'cloud', - 'auth-type'], - 'type': 'object'}, - 'CredentialContentResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/ControllerCredentialInfo'}}, - 'type': 'object'}, - 'CredentialContentResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/CredentialContentResult'}, - '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'}, - 'Error': {'additionalProperties': False, - 'properties': {'code': {'type': 'string'}, - 'info': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - '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'}, - 'InstanceType': {'additionalProperties': False, - 'properties': {'arches': {'items': {'type': 'string'}, - 'type': 'array'}, - 'cost': {'type': 'integer'}, - 'cpu-cores': {'type': 'integer'}, - 'memory': {'type': 'integer'}, - 'name': {'type': 'string'}, - 'root-disk': {'type': 'integer'}, - 'virt-type': {'type': 'string'}}, - 'required': ['arches', 'cpu-cores', 'memory'], - 'type': 'object'}, - 'InstanceTypesResult': {'additionalProperties': False, - 'properties': {'cost-currency': {'type': 'string'}, - 'cost-divisor': {'type': 'integer'}, - 'cost-unit': {'type': 'string'}, - 'error': {'$ref': '#/definitions/Error'}, - 'instance-types': {'items': {'$ref': '#/definitions/InstanceType'}, - 'type': 'array'}}, - 'type': 'object'}, - 'InstanceTypesResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/InstanceTypesResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'ListCloudInfo': {'additionalProperties': False, - 'properties': {'CloudDetails': {'$ref': '#/definitions/CloudDetails'}, - 'user-access': {'type': 'string'}}, - 'required': ['CloudDetails', 'user-access'], - 'type': 'object'}, - 'ListCloudInfoResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/ListCloudInfo'}}, - 'type': 'object'}, - 'ListCloudInfoResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ListCloudInfoResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'ListCloudsRequest': {'additionalProperties': False, - 'properties': {'all': {'type': 'boolean'}, - 'user-tag': {'type': 'string'}}, - 'required': ['user-tag'], - 'type': 'object'}, - 'ModelAccess': {'additionalProperties': False, - 'properties': {'access': {'type': 'string'}, - 'model': {'type': 'string'}}, - 'type': 'object'}, - 'ModifyCloudAccess': {'additionalProperties': False, - 'properties': {'access': {'type': 'string'}, - 'action': {'type': 'string'}, - 'cloud-tag': {'type': 'string'}, - 'user-tag': {'type': 'string'}}, - 'required': ['user-tag', - 'cloud-tag', - 'action', - 'access'], - 'type': 'object'}, - 'ModifyCloudAccessRequest': {'additionalProperties': False, - 'properties': {'changes': {'items': {'$ref': '#/definitions/ModifyCloudAccess'}, - 'type': 'array'}}, - 'required': ['changes'], - 'type': 'object'}, - 'RevokeCredentialArg': {'additionalProperties': False, - 'properties': {'force': {'type': 'boolean'}, - 'tag': {'type': 'string'}}, - 'required': ['tag', 'force'], - 'type': 'object'}, - 'RevokeCredentialArgs': {'additionalProperties': False, - 'properties': {'credentials': {'items': {'$ref': '#/definitions/RevokeCredentialArg'}, - 'type': 'array'}}, - 'required': ['credentials'], - 'type': 'object'}, - 'StringsResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'StringsResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/StringsResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'TaggedCredential': {'additionalProperties': False, - 'properties': {'credential': {'$ref': '#/definitions/CloudCredential'}, - 'tag': {'type': 'string'}}, - 'required': ['tag', 'credential'], - 'type': 'object'}, - 'TaggedCredentials': {'additionalProperties': False, - 'properties': {'credentials': {'items': {'$ref': '#/definitions/TaggedCredential'}, - 'type': 'array'}}, - 'type': 'object'}, - 'UpdateCloudArgs': {'additionalProperties': False, - 'properties': {'clouds': {'items': {'$ref': '#/definitions/AddCloudArgs'}, - 'type': 'array'}}, - 'required': ['clouds'], - 'type': 'object'}, - 'UpdateCredentialArgs': {'additionalProperties': False, - 'properties': {'credentials': {'items': {'$ref': '#/definitions/TaggedCredential'}, - 'type': 'array'}, - 'force': {'type': 'boolean'}}, - 'required': ['credentials', 'force'], - 'type': 'object'}, - 'UpdateCredentialModelResult': {'additionalProperties': False, - 'properties': {'errors': {'items': {'$ref': '#/definitions/ErrorResult'}, - 'type': 'array'}, - 'name': {'type': 'string'}, - 'uuid': {'type': 'string'}}, - 'required': ['uuid', 'name'], - 'type': 'object'}, - 'UpdateCredentialResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'models': {'items': {'$ref': '#/definitions/UpdateCredentialModelResult'}, - 'type': 'array'}, - 'tag': {'type': 'string'}}, - 'required': ['tag'], - 'type': 'object'}, - 'UpdateCredentialResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/UpdateCredentialResult'}, - 'type': 'array'}}, - 'type': 'object'}, - 'UserCloud': {'additionalProperties': False, - 'properties': {'cloud-tag': {'type': 'string'}, - 'user-tag': {'type': 'string'}}, - 'required': ['user-tag', 'cloud-tag'], - 'type': 'object'}, - 'UserClouds': {'additionalProperties': False, - 'properties': {'user-clouds': {'items': {'$ref': '#/definitions/UserCloud'}, - 'type': 'array'}}, - 'type': 'object'}, - 'Value': {'additionalProperties': False, - 'properties': {'allocate-public-ip': {'type': 'boolean'}, - 'arch': {'type': 'string'}, - 'container': {'type': 'string'}, - 'cores': {'type': 'integer'}, - 'cpu-power': {'type': 'integer'}, - 'image-id': {'type': 'string'}, - 'instance-role': {'type': 'string'}, - 'instance-type': {'type': 'string'}, - 'mem': {'type': 'integer'}, - 'root-disk': {'type': 'integer'}, - 'root-disk-source': {'type': 'string'}, - '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': {'AddCloud': {'description': 'AddCloud adds a new cloud, ' - 'different from the one managed by ' - 'the controller.', - 'properties': {'Params': {'$ref': '#/definitions/AddCloudArgs'}}, - 'type': 'object'}, - 'AddCredentials': {'description': 'AddCredentials adds new ' - 'credentials.\n' - 'In contrast to ' - 'UpdateCredentials() below, ' - 'the new credentials can be\n' - 'for a cloud that the ' - 'controller does not manage ' - '(this is required\n' - 'for CAAS models)', - 'properties': {'Params': {'$ref': '#/definitions/TaggedCredentials'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'CheckCredentialsModels': {'description': 'CheckCredentialsModels ' - 'validates supplied ' - "cloud credentials' " - 'content against\n' - 'models that ' - 'currently use these ' - 'credentials.\n' - 'If there are any ' - 'models that are ' - 'using a credential ' - 'and these models or ' - 'their\n' - 'cloud instances are ' - 'not going to be ' - 'accessible with ' - 'corresponding ' - 'credential,\n' - 'there will be ' - 'detailed validation ' - 'errors per model.\n' - "There's no Juju API " - 'client which uses ' - 'this, but JAAS ' - 'does,', - 'properties': {'Params': {'$ref': '#/definitions/TaggedCredentials'}, - 'Result': {'$ref': '#/definitions/UpdateCredentialResults'}}, - 'type': 'object'}, - 'Cloud': {'description': 'Cloud returns the cloud definitions ' - 'for the specified clouds.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/CloudResults'}}, - 'type': 'object'}, - 'CloudInfo': {'description': 'CloudInfo returns information ' - 'about the specified clouds.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/CloudInfoResults'}}, - 'type': 'object'}, - 'Clouds': {'description': 'Clouds returns the definitions of ' - 'all clouds supported by the ' - 'controller\n' - 'that the logged in user can see.', - 'properties': {'Result': {'$ref': '#/definitions/CloudsResult'}}, - 'type': 'object'}, - 'Credential': {'description': 'Credential returns the ' - 'specified cloud credential for ' - 'each tag, minus secrets.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/CloudCredentialResults'}}, - 'type': 'object'}, - 'CredentialContents': {'description': 'CredentialContents ' - 'returns the specified ' - 'cloud credentials,\n' - 'including the secrets ' - 'if requested.\n' - 'If no specific ' - 'credential name/cloud ' - 'was passed in, all ' - 'credentials for this ' - 'user\n' - 'are returned.\n' - 'Only credential owner ' - 'can see its contents as ' - 'well as what models use ' - 'it.\n' - 'Controller admin has no ' - 'special superpowers ' - 'here and is treated the ' - 'same as all other ' - 'users.', - 'properties': {'Params': {'$ref': '#/definitions/CloudCredentialArgs'}, - 'Result': {'$ref': '#/definitions/CredentialContentResults'}}, - 'type': 'object'}, - 'InstanceTypes': {'description': 'InstanceTypes returns ' - 'instance type information ' - 'for the cloud and region\n' - 'in which the current model ' - 'is deployed.', - 'properties': {'Params': {'$ref': '#/definitions/CloudInstanceTypesConstraints'}, - 'Result': {'$ref': '#/definitions/InstanceTypesResults'}}, - 'type': 'object'}, - 'ListCloudInfo': {'description': 'ListCloudInfo returns clouds ' - 'that the specified user has ' - 'access to.\n' - 'Controller admins ' - '(superuser) can list clouds ' - 'for any user.\n' - 'Other users can only ask ' - 'about their own clouds.', - 'properties': {'Params': {'$ref': '#/definitions/ListCloudsRequest'}, - 'Result': {'$ref': '#/definitions/ListCloudInfoResults'}}, - 'type': 'object'}, - 'ModifyCloudAccess': {'description': 'ModifyCloudAccess ' - 'changes the model access ' - 'granted to users.', - 'properties': {'Params': {'$ref': '#/definitions/ModifyCloudAccessRequest'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'RemoveClouds': {'description': 'RemoveClouds removes the ' - 'specified clouds from the ' - 'controller.\n' - 'If a cloud is in use (has ' - 'models deployed to it), the ' - 'removal will fail.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'RevokeCredentialsCheckModels': {'description': 'RevokeCredentialsCheckModels ' - 'revokes a set ' - 'of cloud ' - 'credentials.\n' - 'If the ' - 'credentials ' - 'are used by ' - 'any of the ' - 'models, the ' - 'credential ' - 'deletion will ' - 'be aborted.\n' - 'If ' - 'credential-in-use ' - 'needs to be ' - 'revoked ' - 'nonetheless, ' - 'this method ' - 'allows the ' - 'use of force.', - 'properties': {'Params': {'$ref': '#/definitions/RevokeCredentialArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'UpdateCloud': {'description': 'UpdateCloud updates an ' - 'existing cloud that the ' - 'controller knows about.', - 'properties': {'Params': {'$ref': '#/definitions/UpdateCloudArgs'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'UpdateCredentialsCheckModels': {'description': 'UpdateCredentialsCheckModels ' - 'updates a set ' - 'of cloud ' - "credentials' " - 'content.\n' - 'If there are ' - 'any models ' - 'that are ' - 'using a ' - 'credential ' - 'and these ' - 'models\n' - 'are not going ' - 'to be visible ' - 'with updated ' - 'credential ' - 'content,\n' - 'there will be ' - 'detailed ' - 'validation ' - 'errors per ' - 'model. Such ' - 'model errors ' - 'are returned\n' - 'separately ' - 'and do not ' - 'contribute to ' - 'the overall ' - 'method error ' - 'status.\n' - 'Controller ' - 'admins can ' - "'force' an " - 'update of the ' - 'credential\n' - 'regardless of ' - 'whether it is ' - 'deemed valid ' - 'or not.', - 'properties': {'Params': {'$ref': '#/definitions/UpdateCredentialArgs'}, - 'Result': {'$ref': '#/definitions/UpdateCredentialResults'}}, - 'type': 'object'}, - 'UserCredentials': {'description': 'UserCredentials returns ' - 'the cloud credentials for ' - 'a set of users.', - 'properties': {'Params': {'$ref': '#/definitions/UserClouds'}, - 'Result': {'$ref': '#/definitions/StringsResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "AddCloudArgs": { + "additionalProperties": False, + "properties": { + "cloud": {"$ref": "#/definitions/Cloud"}, + "force": {"type": "boolean"}, + "name": {"type": "string"}, + }, + "required": ["cloud", "name"], + "type": "object", + }, + "Cloud": { + "additionalProperties": False, + "properties": { + "auth-types": {"items": {"type": "string"}, "type": "array"}, + "ca-certificates": {"items": {"type": "string"}, "type": "array"}, + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "endpoint": {"type": "string"}, + "host-cloud-region": {"type": "string"}, + "identity-endpoint": {"type": "string"}, + "is-controller-cloud": {"type": "boolean"}, + "region-config": { + "patternProperties": { + ".*": { + "patternProperties": { + ".*": { + "additionalProperties": True, + "type": "object", + } + }, + "type": "object", + } + }, + "type": "object", + }, + "regions": { + "items": {"$ref": "#/definitions/CloudRegion"}, + "type": "array", + }, + "skip-tls-verify": {"type": "boolean"}, + "storage-endpoint": {"type": "string"}, + "type": {"type": "string"}, + }, + "required": ["type"], + "type": "object", + }, + "CloudCredential": { + "additionalProperties": False, + "properties": { + "attrs": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "auth-type": {"type": "string"}, + "redacted": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["auth-type"], + "type": "object", + }, + "CloudCredentialArg": { + "additionalProperties": False, + "properties": { + "cloud-name": {"type": "string"}, + "credential-name": {"type": "string"}, + }, + "required": ["cloud-name", "credential-name"], + "type": "object", + }, + "CloudCredentialArgs": { + "additionalProperties": False, + "properties": { + "credentials": { + "items": {"$ref": "#/definitions/CloudCredentialArg"}, + "type": "array", + }, + "include-secrets": {"type": "boolean"}, + }, + "required": ["include-secrets"], + "type": "object", + }, + "CloudCredentialResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/CloudCredential"}, + }, + "type": "object", + }, + "CloudCredentialResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/CloudCredentialResult"}, + "type": "array", + } + }, + "type": "object", + }, + "CloudDetails": { + "additionalProperties": False, + "properties": { + "auth-types": {"items": {"type": "string"}, "type": "array"}, + "endpoint": {"type": "string"}, + "identity-endpoint": {"type": "string"}, + "regions": { + "items": {"$ref": "#/definitions/CloudRegion"}, + "type": "array", + }, + "storage-endpoint": {"type": "string"}, + "type": {"type": "string"}, + }, + "required": ["type"], + "type": "object", + }, + "CloudInfo": { + "additionalProperties": False, + "properties": { + "CloudDetails": {"$ref": "#/definitions/CloudDetails"}, + "users": { + "items": {"$ref": "#/definitions/CloudUserInfo"}, + "type": "array", + }, + }, + "required": ["CloudDetails", "users"], + "type": "object", + }, + "CloudInfoResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/CloudInfo"}, + }, + "type": "object", + }, + "CloudInfoResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/CloudInfoResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "CloudInstanceTypesConstraint": { + "additionalProperties": False, + "properties": { + "cloud-tag": {"type": "string"}, + "constraints": {"$ref": "#/definitions/Value"}, + "region": {"type": "string"}, + }, + "required": ["cloud-tag", "region"], + "type": "object", + }, + "CloudInstanceTypesConstraints": { + "additionalProperties": False, + "properties": { + "constraints": { + "items": {"$ref": "#/definitions/CloudInstanceTypesConstraint"}, + "type": "array", + } + }, + "required": ["constraints"], + "type": "object", + }, + "CloudRegion": { + "additionalProperties": False, + "properties": { + "endpoint": {"type": "string"}, + "identity-endpoint": {"type": "string"}, + "name": {"type": "string"}, + "storage-endpoint": {"type": "string"}, + }, + "required": ["name"], + "type": "object", + }, + "CloudResult": { + "additionalProperties": False, + "properties": { + "cloud": {"$ref": "#/definitions/Cloud"}, + "error": {"$ref": "#/definitions/Error"}, + }, + "type": "object", + }, + "CloudResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/CloudResult"}, + "type": "array", + } + }, + "type": "object", + }, + "CloudUserInfo": { + "additionalProperties": False, + "properties": { + "access": {"type": "string"}, + "display-name": {"type": "string"}, + "user": {"type": "string"}, + }, + "required": ["user", "display-name", "access"], + "type": "object", + }, + "CloudsResult": { + "additionalProperties": False, + "properties": { + "clouds": { + "patternProperties": {".*": {"$ref": "#/definitions/Cloud"}}, + "type": "object", + } + }, + "type": "object", + }, + "ControllerCredentialInfo": { + "additionalProperties": False, + "properties": { + "content": {"$ref": "#/definitions/CredentialContent"}, + "models": { + "items": {"$ref": "#/definitions/ModelAccess"}, + "type": "array", + }, + }, + "type": "object", + }, + "CredentialContent": { + "additionalProperties": False, + "properties": { + "attrs": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "auth-type": {"type": "string"}, + "cloud": {"type": "string"}, + "name": {"type": "string"}, + "valid": {"type": "boolean"}, + }, + "required": ["name", "cloud", "auth-type"], + "type": "object", + }, + "CredentialContentResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/ControllerCredentialInfo"}, + }, + "type": "object", + }, + "CredentialContentResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/CredentialContentResult"}, + "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", + }, + "Error": { + "additionalProperties": False, + "properties": { + "code": {"type": "string"}, + "info": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "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", + }, + "InstanceType": { + "additionalProperties": False, + "properties": { + "arches": {"items": {"type": "string"}, "type": "array"}, + "cost": {"type": "integer"}, + "cpu-cores": {"type": "integer"}, + "memory": {"type": "integer"}, + "name": {"type": "string"}, + "root-disk": {"type": "integer"}, + "virt-type": {"type": "string"}, + }, + "required": ["arches", "cpu-cores", "memory"], + "type": "object", + }, + "InstanceTypesResult": { + "additionalProperties": False, + "properties": { + "cost-currency": {"type": "string"}, + "cost-divisor": {"type": "integer"}, + "cost-unit": {"type": "string"}, + "error": {"$ref": "#/definitions/Error"}, + "instance-types": { + "items": {"$ref": "#/definitions/InstanceType"}, + "type": "array", + }, + }, + "type": "object", + }, + "InstanceTypesResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/InstanceTypesResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "ListCloudInfo": { + "additionalProperties": False, + "properties": { + "CloudDetails": {"$ref": "#/definitions/CloudDetails"}, + "user-access": {"type": "string"}, + }, + "required": ["CloudDetails", "user-access"], + "type": "object", + }, + "ListCloudInfoResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/ListCloudInfo"}, + }, + "type": "object", + }, + "ListCloudInfoResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ListCloudInfoResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "ListCloudsRequest": { + "additionalProperties": False, + "properties": { + "all": {"type": "boolean"}, + "user-tag": {"type": "string"}, + }, + "required": ["user-tag"], + "type": "object", + }, + "ModelAccess": { + "additionalProperties": False, + "properties": { + "access": {"type": "string"}, + "model": {"type": "string"}, + }, + "type": "object", + }, + "ModifyCloudAccess": { + "additionalProperties": False, + "properties": { + "access": {"type": "string"}, + "action": {"type": "string"}, + "cloud-tag": {"type": "string"}, + "user-tag": {"type": "string"}, + }, + "required": ["user-tag", "cloud-tag", "action", "access"], + "type": "object", + }, + "ModifyCloudAccessRequest": { + "additionalProperties": False, + "properties": { + "changes": { + "items": {"$ref": "#/definitions/ModifyCloudAccess"}, + "type": "array", + } + }, + "required": ["changes"], + "type": "object", + }, + "RevokeCredentialArg": { + "additionalProperties": False, + "properties": {"force": {"type": "boolean"}, "tag": {"type": "string"}}, + "required": ["tag", "force"], + "type": "object", + }, + "RevokeCredentialArgs": { + "additionalProperties": False, + "properties": { + "credentials": { + "items": {"$ref": "#/definitions/RevokeCredentialArg"}, + "type": "array", + } + }, + "required": ["credentials"], + "type": "object", + }, + "StringsResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"items": {"type": "string"}, "type": "array"}, + }, + "type": "object", + }, + "StringsResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/StringsResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "TaggedCredential": { + "additionalProperties": False, + "properties": { + "credential": {"$ref": "#/definitions/CloudCredential"}, + "tag": {"type": "string"}, + }, + "required": ["tag", "credential"], + "type": "object", + }, + "TaggedCredentials": { + "additionalProperties": False, + "properties": { + "credentials": { + "items": {"$ref": "#/definitions/TaggedCredential"}, + "type": "array", + } + }, + "type": "object", + }, + "UpdateCloudArgs": { + "additionalProperties": False, + "properties": { + "clouds": { + "items": {"$ref": "#/definitions/AddCloudArgs"}, + "type": "array", + } + }, + "required": ["clouds"], + "type": "object", + }, + "UpdateCredentialArgs": { + "additionalProperties": False, + "properties": { + "credentials": { + "items": {"$ref": "#/definitions/TaggedCredential"}, + "type": "array", + }, + "force": {"type": "boolean"}, + }, + "required": ["credentials", "force"], + "type": "object", + }, + "UpdateCredentialModelResult": { + "additionalProperties": False, + "properties": { + "errors": { + "items": {"$ref": "#/definitions/ErrorResult"}, + "type": "array", + }, + "name": {"type": "string"}, + "uuid": {"type": "string"}, + }, + "required": ["uuid", "name"], + "type": "object", + }, + "UpdateCredentialResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "models": { + "items": {"$ref": "#/definitions/UpdateCredentialModelResult"}, + "type": "array", + }, + "tag": {"type": "string"}, + }, + "required": ["tag"], + "type": "object", + }, + "UpdateCredentialResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/UpdateCredentialResult"}, + "type": "array", + } + }, + "type": "object", + }, + "UserCloud": { + "additionalProperties": False, + "properties": { + "cloud-tag": {"type": "string"}, + "user-tag": {"type": "string"}, + }, + "required": ["user-tag", "cloud-tag"], + "type": "object", + }, + "UserClouds": { + "additionalProperties": False, + "properties": { + "user-clouds": { + "items": {"$ref": "#/definitions/UserCloud"}, + "type": "array", + } + }, + "type": "object", + }, + "Value": { + "additionalProperties": False, + "properties": { + "allocate-public-ip": {"type": "boolean"}, + "arch": {"type": "string"}, + "container": {"type": "string"}, + "cores": {"type": "integer"}, + "cpu-power": {"type": "integer"}, + "image-id": {"type": "string"}, + "instance-role": {"type": "string"}, + "instance-type": {"type": "string"}, + "mem": {"type": "integer"}, + "root-disk": {"type": "integer"}, + "root-disk-source": {"type": "string"}, + "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": { + "AddCloud": { + "description": "AddCloud adds a new cloud, " + "different from the one managed by " + "the controller.", + "properties": {"Params": {"$ref": "#/definitions/AddCloudArgs"}}, + "type": "object", + }, + "AddCredentials": { + "description": "AddCredentials adds new " + "credentials.\n" + "In contrast to " + "UpdateCredentials() below, " + "the new credentials can be\n" + "for a cloud that the " + "controller does not manage " + "(this is required\n" + "for CAAS models)", + "properties": { + "Params": {"$ref": "#/definitions/TaggedCredentials"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "CheckCredentialsModels": { + "description": "CheckCredentialsModels " + "validates supplied " + "cloud credentials' " + "content against\n" + "models that " + "currently use these " + "credentials.\n" + "If there are any " + "models that are " + "using a credential " + "and these models or " + "their\n" + "cloud instances are " + "not going to be " + "accessible with " + "corresponding " + "credential,\n" + "there will be " + "detailed validation " + "errors per model.\n" + "There's no Juju API " + "client which uses " + "this, but JAAS " + "does,", + "properties": { + "Params": {"$ref": "#/definitions/TaggedCredentials"}, + "Result": {"$ref": "#/definitions/UpdateCredentialResults"}, + }, + "type": "object", + }, + "Cloud": { + "description": "Cloud returns the cloud definitions " + "for the specified clouds.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/CloudResults"}, + }, + "type": "object", + }, + "CloudInfo": { + "description": "CloudInfo returns information " + "about the specified clouds.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/CloudInfoResults"}, + }, + "type": "object", + }, + "Clouds": { + "description": "Clouds returns the definitions of " + "all clouds supported by the " + "controller\n" + "that the logged in user can see.", + "properties": {"Result": {"$ref": "#/definitions/CloudsResult"}}, + "type": "object", + }, + "Credential": { + "description": "Credential returns the " + "specified cloud credential for " + "each tag, minus secrets.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/CloudCredentialResults"}, + }, + "type": "object", + }, + "CredentialContents": { + "description": "CredentialContents " + "returns the specified " + "cloud credentials,\n" + "including the secrets " + "if requested.\n" + "If no specific " + "credential name/cloud " + "was passed in, all " + "credentials for this " + "user\n" + "are returned.\n" + "Only credential owner " + "can see its contents as " + "well as what models use " + "it.\n" + "Controller admin has no " + "special superpowers " + "here and is treated the " + "same as all other " + "users.", + "properties": { + "Params": {"$ref": "#/definitions/CloudCredentialArgs"}, + "Result": {"$ref": "#/definitions/CredentialContentResults"}, + }, + "type": "object", + }, + "InstanceTypes": { + "description": "InstanceTypes returns " + "instance type information " + "for the cloud and region\n" + "in which the current model " + "is deployed.", + "properties": { + "Params": {"$ref": "#/definitions/CloudInstanceTypesConstraints"}, + "Result": {"$ref": "#/definitions/InstanceTypesResults"}, + }, + "type": "object", + }, + "ListCloudInfo": { + "description": "ListCloudInfo returns clouds " + "that the specified user has " + "access to.\n" + "Controller admins " + "(superuser) can list clouds " + "for any user.\n" + "Other users can only ask " + "about their own clouds.", + "properties": { + "Params": {"$ref": "#/definitions/ListCloudsRequest"}, + "Result": {"$ref": "#/definitions/ListCloudInfoResults"}, + }, + "type": "object", + }, + "ModifyCloudAccess": { + "description": "ModifyCloudAccess " + "changes the model access " + "granted to users.", + "properties": { + "Params": {"$ref": "#/definitions/ModifyCloudAccessRequest"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "RemoveClouds": { + "description": "RemoveClouds removes the " + "specified clouds from the " + "controller.\n" + "If a cloud is in use (has " + "models deployed to it), the " + "removal will fail.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "RevokeCredentialsCheckModels": { + "description": "RevokeCredentialsCheckModels " + "revokes a set " + "of cloud " + "credentials.\n" + "If the " + "credentials " + "are used by " + "any of the " + "models, the " + "credential " + "deletion will " + "be aborted.\n" + "If " + "credential-in-use " + "needs to be " + "revoked " + "nonetheless, " + "this method " + "allows the " + "use of force.", + "properties": { + "Params": {"$ref": "#/definitions/RevokeCredentialArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "UpdateCloud": { + "description": "UpdateCloud updates an " + "existing cloud that the " + "controller knows about.", + "properties": { + "Params": {"$ref": "#/definitions/UpdateCloudArgs"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "UpdateCredentialsCheckModels": { + "description": "UpdateCredentialsCheckModels " + "updates a set " + "of cloud " + "credentials' " + "content.\n" + "If there are " + "any models " + "that are " + "using a " + "credential " + "and these " + "models\n" + "are not going " + "to be visible " + "with updated " + "credential " + "content,\n" + "there will be " + "detailed " + "validation " + "errors per " + "model. Such " + "model errors " + "are returned\n" + "separately " + "and do not " + "contribute to " + "the overall " + "method error " + "status.\n" + "Controller " + "admins can " + "'force' an " + "update of the " + "credential\n" + "regardless of " + "whether it is " + "deemed valid " + "or not.", + "properties": { + "Params": {"$ref": "#/definitions/UpdateCredentialArgs"}, + "Result": {"$ref": "#/definitions/UpdateCredentialResults"}, + }, + "type": "object", + }, + "UserCredentials": { + "description": "UserCredentials returns " + "the cloud credentials for " + "a set of users.", + "properties": { + "Params": {"$ref": "#/definitions/UserClouds"}, + "Result": {"$ref": "#/definitions/StringsResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(None) async def AddCloud(self, cloud=None, force=None, name=None): - ''' + """ AddCloud adds a new cloud, different from the one managed by the controller. cloud : Cloud force : bool name : str Returns -> None - ''' + """ if cloud is not None and not isinstance(cloud, (dict, Cloud)): - raise Exception("Expected cloud to be a Cloud, received: {}".format(type(cloud))) + raise Exception( + "Expected cloud to be a Cloud, received: {}".format(type(cloud)) + ) if force is not None and not isinstance(force, bool): - raise Exception("Expected force to be a bool, received: {}".format(type(force))) + raise Exception( + "Expected force to be a bool, received: {}".format(type(force)) + ) if name is not None and not isinstance(name, (bytes, str)): - raise Exception("Expected name to be a str, received: {}".format(type(name))) + raise Exception( + "Expected name to be a str, received: {}".format(type(name)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Cloud', - request='AddCloud', - version=7, - params=_params) - _params['cloud'] = cloud - _params['force'] = force - _params['name'] = name + msg = dict(type="Cloud", request="AddCloud", version=7, params=_params) + _params["cloud"] = cloud + _params["force"] = force + _params["name"] = name reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def AddCredentials(self, credentials=None): - ''' + """ AddCredentials adds new credentials. In contrast to UpdateCredentials() below, the new credentials can be for a cloud that the controller does not manage (this is required @@ -2419,25 +3488,24 @@ async def AddCredentials(self, credentials=None): credentials : typing.Sequence[~TaggedCredential] Returns -> ErrorResults - ''' + """ if credentials is not None and not isinstance(credentials, (bytes, str, list)): - raise Exception("Expected credentials to be a Sequence, received: {}".format(type(credentials))) + raise Exception( + "Expected credentials to be a Sequence, received: {}".format( + type(credentials) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Cloud', - request='AddCredentials', - version=7, - params=_params) - _params['credentials'] = credentials + msg = dict(type="Cloud", request="AddCredentials", version=7, params=_params) + _params["credentials"] = credentials reply = await self.rpc(msg) return reply - - @ReturnMapping(UpdateCredentialResults) async def CheckCredentialsModels(self, credentials=None): - ''' + """ CheckCredentialsModels validates supplied cloud credentials' content against models that currently use these credentials. If there are any models that are using a credential and these models or their @@ -2447,116 +3515,109 @@ async def CheckCredentialsModels(self, credentials=None): credentials : typing.Sequence[~TaggedCredential] Returns -> UpdateCredentialResults - ''' + """ if credentials is not None and not isinstance(credentials, (bytes, str, list)): - raise Exception("Expected credentials to be a Sequence, received: {}".format(type(credentials))) + raise Exception( + "Expected credentials to be a Sequence, received: {}".format( + type(credentials) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Cloud', - request='CheckCredentialsModels', - version=7, - params=_params) - _params['credentials'] = credentials + msg = dict( + type="Cloud", request="CheckCredentialsModels", version=7, params=_params + ) + _params["credentials"] = credentials reply = await self.rpc(msg) return reply - - @ReturnMapping(CloudResults) async def Cloud(self, entities=None): - ''' + """ Cloud returns the cloud definitions for the specified clouds. entities : typing.Sequence[~Entity] Returns -> CloudResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Cloud', - request='Cloud', - version=7, - params=_params) - _params['entities'] = entities + msg = dict(type="Cloud", request="Cloud", version=7, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(CloudInfoResults) async def CloudInfo(self, entities=None): - ''' + """ CloudInfo returns information about the specified clouds. entities : typing.Sequence[~Entity] Returns -> CloudInfoResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Cloud', - request='CloudInfo', - version=7, - params=_params) - _params['entities'] = entities + msg = dict(type="Cloud", request="CloudInfo", version=7, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(CloudsResult) async def Clouds(self): - ''' + """ Clouds returns the definitions of all clouds supported by the controller that the logged in user can see. Returns -> CloudsResult - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Cloud', - request='Clouds', - version=7, - params=_params) + msg = dict(type="Cloud", request="Clouds", version=7, params=_params) reply = await self.rpc(msg) return reply - - @ReturnMapping(CloudCredentialResults) async def Credential(self, entities=None): - ''' + """ Credential returns the specified cloud credential for each tag, minus secrets. entities : typing.Sequence[~Entity] Returns -> CloudCredentialResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Cloud', - request='Credential', - version=7, - params=_params) - _params['entities'] = entities + msg = dict(type="Cloud", request="Credential", version=7, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(CredentialContentResults) async def CredentialContents(self, credentials=None, include_secrets=None): - ''' + """ CredentialContents returns the specified cloud credentials, including the secrets if requested. If no specific credential name/cloud was passed in, all credentials for this user @@ -2567,53 +3628,57 @@ async def CredentialContents(self, credentials=None, include_secrets=None): credentials : typing.Sequence[~CloudCredentialArg] include_secrets : bool Returns -> CredentialContentResults - ''' + """ if credentials is not None and not isinstance(credentials, (bytes, str, list)): - raise Exception("Expected credentials to be a Sequence, received: {}".format(type(credentials))) + raise Exception( + "Expected credentials to be a Sequence, received: {}".format( + type(credentials) + ) + ) if include_secrets is not None and not isinstance(include_secrets, bool): - raise Exception("Expected include_secrets to be a bool, received: {}".format(type(include_secrets))) + raise Exception( + "Expected include_secrets to be a bool, received: {}".format( + type(include_secrets) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Cloud', - request='CredentialContents', - version=7, - params=_params) - _params['credentials'] = credentials - _params['include-secrets'] = include_secrets + msg = dict( + type="Cloud", request="CredentialContents", version=7, params=_params + ) + _params["credentials"] = credentials + _params["include-secrets"] = include_secrets reply = await self.rpc(msg) return reply - - @ReturnMapping(InstanceTypesResults) async def InstanceTypes(self, constraints=None): - ''' + """ InstanceTypes returns instance type information for the cloud and region in which the current model is deployed. constraints : typing.Sequence[~CloudInstanceTypesConstraint] Returns -> InstanceTypesResults - ''' + """ if constraints is not None and not isinstance(constraints, (bytes, str, list)): - raise Exception("Expected constraints to be a Sequence, received: {}".format(type(constraints))) + raise Exception( + "Expected constraints to be a Sequence, received: {}".format( + type(constraints) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Cloud', - request='InstanceTypes', - version=7, - params=_params) - _params['constraints'] = constraints + msg = dict(type="Cloud", request="InstanceTypes", version=7, params=_params) + _params["constraints"] = constraints reply = await self.rpc(msg) return reply - - @ReturnMapping(ListCloudInfoResults) async def ListCloudInfo(self, all_=None, user_tag=None): - ''' + """ ListCloudInfo returns clouds that the specified user has access to. Controller admins (superuser) can list clouds for any user. Other users can only ask about their own clouds. @@ -2621,124 +3686,120 @@ async def ListCloudInfo(self, all_=None, user_tag=None): all_ : bool user_tag : str Returns -> ListCloudInfoResults - ''' + """ if all_ is not None and not isinstance(all_, bool): - raise Exception("Expected all_ to be a bool, received: {}".format(type(all_))) + raise Exception( + "Expected all_ to be a bool, received: {}".format(type(all_)) + ) if user_tag is not None and not isinstance(user_tag, (bytes, str)): - raise Exception("Expected user_tag to be a str, received: {}".format(type(user_tag))) + raise Exception( + "Expected user_tag to be a str, received: {}".format(type(user_tag)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Cloud', - request='ListCloudInfo', - version=7, - params=_params) - _params['all'] = all_ - _params['user-tag'] = user_tag + msg = dict(type="Cloud", request="ListCloudInfo", version=7, params=_params) + _params["all"] = all_ + _params["user-tag"] = user_tag reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def ModifyCloudAccess(self, changes=None): - ''' + """ ModifyCloudAccess changes the model access granted to users. changes : typing.Sequence[~ModifyCloudAccess] Returns -> ErrorResults - ''' + """ if changes is not None and not isinstance(changes, (bytes, str, list)): - raise Exception("Expected changes to be a Sequence, received: {}".format(type(changes))) + raise Exception( + "Expected changes to be a Sequence, received: {}".format(type(changes)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Cloud', - request='ModifyCloudAccess', - version=7, - params=_params) - _params['changes'] = changes + msg = dict(type="Cloud", request="ModifyCloudAccess", version=7, params=_params) + _params["changes"] = changes reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def RemoveClouds(self, entities=None): - ''' + """ RemoveClouds removes the specified clouds from the controller. If a cloud is in use (has models deployed to it), the removal will fail. entities : typing.Sequence[~Entity] Returns -> ErrorResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Cloud', - request='RemoveClouds', - version=7, - params=_params) - _params['entities'] = entities + msg = dict(type="Cloud", request="RemoveClouds", version=7, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def RevokeCredentialsCheckModels(self, credentials=None): - ''' + """ RevokeCredentialsCheckModels revokes a set of cloud credentials. If the credentials are used by any of the models, the credential deletion will be aborted. If credential-in-use needs to be revoked nonetheless, this method allows the use of force. credentials : typing.Sequence[~RevokeCredentialArg] Returns -> ErrorResults - ''' + """ if credentials is not None and not isinstance(credentials, (bytes, str, list)): - raise Exception("Expected credentials to be a Sequence, received: {}".format(type(credentials))) + raise Exception( + "Expected credentials to be a Sequence, received: {}".format( + type(credentials) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Cloud', - request='RevokeCredentialsCheckModels', - version=7, - params=_params) - _params['credentials'] = credentials + msg = dict( + type="Cloud", + request="RevokeCredentialsCheckModels", + version=7, + params=_params, + ) + _params["credentials"] = credentials reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def UpdateCloud(self, clouds=None): - ''' + """ UpdateCloud updates an existing cloud that the controller knows about. clouds : typing.Sequence[~AddCloudArgs] Returns -> ErrorResults - ''' + """ if clouds is not None and not isinstance(clouds, (bytes, str, list)): - raise Exception("Expected clouds to be a Sequence, received: {}".format(type(clouds))) + raise Exception( + "Expected clouds to be a Sequence, received: {}".format(type(clouds)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Cloud', - request='UpdateCloud', - version=7, - params=_params) - _params['clouds'] = clouds + msg = dict(type="Cloud", request="UpdateCloud", version=7, params=_params) + _params["clouds"] = clouds reply = await self.rpc(msg) return reply - - @ReturnMapping(UpdateCredentialResults) async def UpdateCredentialsCheckModels(self, credentials=None, force=None): - ''' + """ UpdateCredentialsCheckModels updates a set of cloud credentials' content. If there are any models that are using a credential and these models are not going to be visible with updated credential content, @@ -2750,45 +3811,50 @@ async def UpdateCredentialsCheckModels(self, credentials=None, force=None): credentials : typing.Sequence[~TaggedCredential] force : bool Returns -> UpdateCredentialResults - ''' + """ if credentials is not None and not isinstance(credentials, (bytes, str, list)): - raise Exception("Expected credentials to be a Sequence, received: {}".format(type(credentials))) + raise Exception( + "Expected credentials to be a Sequence, received: {}".format( + type(credentials) + ) + ) if force is not None and not isinstance(force, bool): - raise Exception("Expected force to be a bool, received: {}".format(type(force))) + raise Exception( + "Expected force to be a bool, received: {}".format(type(force)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Cloud', - request='UpdateCredentialsCheckModels', - version=7, - params=_params) - _params['credentials'] = credentials - _params['force'] = force + msg = dict( + type="Cloud", + request="UpdateCredentialsCheckModels", + version=7, + params=_params, + ) + _params["credentials"] = credentials + _params["force"] = force reply = await self.rpc(msg) return reply - - @ReturnMapping(StringsResults) async def UserCredentials(self, user_clouds=None): - ''' + """ UserCredentials returns the cloud credentials for a set of users. user_clouds : typing.Sequence[~UserCloud] Returns -> StringsResults - ''' + """ if user_clouds is not None and not isinstance(user_clouds, (bytes, str, list)): - raise Exception("Expected user_clouds to be a Sequence, received: {}".format(type(user_clouds))) + raise Exception( + "Expected user_clouds to be a Sequence, received: {}".format( + type(user_clouds) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Cloud', - request='UserCredentials', - version=7, - params=_params) - _params['user-clouds'] = user_clouds + msg = dict(type="Cloud", request="UserCredentials", version=7, params=_params) + _params["user-clouds"] = user_clouds reply = await self.rpc(msg) return reply - - diff --git a/juju/client/_client8.py b/juju/client/_client8.py index 866849125..c4c36ac57 100644 --- a/juju/client/_client8.py +++ b/juju/client/_client8.py @@ -6,564 +6,825 @@ class ClientFacade(Type): - name = 'Client' + name = "Client" version = 8 - schema = {'definitions': {'AllWatcherId': {'additionalProperties': False, - 'properties': {'watcher-id': {'type': 'string'}}, - 'required': ['watcher-id'], - 'type': 'object'}, - 'ApplicationOfferStatus': {'additionalProperties': False, - 'properties': {'active-connected-count': {'type': 'integer'}, - 'application-name': {'type': 'string'}, - 'charm': {'type': 'string'}, - 'endpoints': {'patternProperties': {'.*': {'$ref': '#/definitions/RemoteEndpoint'}}, - 'type': 'object'}, - 'err': {'$ref': '#/definitions/Error'}, - 'offer-name': {'type': 'string'}, - 'total-connected-count': {'type': 'integer'}}, - 'required': ['offer-name', - 'application-name', - 'charm', - 'endpoints', - 'active-connected-count', - 'total-connected-count'], - 'type': 'object'}, - 'ApplicationStatus': {'additionalProperties': False, - 'properties': {'base': {'$ref': '#/definitions/Base'}, - 'can-upgrade-to': {'type': 'string'}, - 'charm': {'type': 'string'}, - 'charm-channel': {'type': 'string'}, - 'charm-profile': {'type': 'string'}, - 'charm-version': {'type': 'string'}, - 'endpoint-bindings': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'err': {'$ref': '#/definitions/Error'}, - 'exposed': {'type': 'boolean'}, - 'exposed-endpoints': {'patternProperties': {'.*': {'$ref': '#/definitions/ExposedEndpoint'}}, - 'type': 'object'}, - 'int': {'type': 'integer'}, - 'life': {'type': 'string'}, - 'meter-statuses': {'patternProperties': {'.*': {'$ref': '#/definitions/MeterStatus'}}, - 'type': 'object'}, - 'provider-id': {'type': 'string'}, - 'public-address': {'type': 'string'}, - 'relations': {'patternProperties': {'.*': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'status': {'$ref': '#/definitions/DetailedStatus'}, - 'subordinate-to': {'items': {'type': 'string'}, - 'type': 'array'}, - 'units': {'patternProperties': {'.*': {'$ref': '#/definitions/UnitStatus'}}, - 'type': 'object'}, - 'workload-version': {'type': 'string'}}, - 'required': ['charm', - 'charm-version', - 'charm-profile', - 'base', - 'exposed', - 'life', - 'relations', - 'can-upgrade-to', - 'subordinate-to', - 'units', - 'meter-statuses', - 'status', - 'workload-version', - 'endpoint-bindings', - 'public-address'], - 'type': 'object'}, - 'Base': {'additionalProperties': False, - 'properties': {'channel': {'type': 'string'}, - 'name': {'type': 'string'}}, - 'required': ['name', 'channel'], - 'type': 'object'}, - 'BranchStatus': {'additionalProperties': False, - 'properties': {'assigned-units': {'patternProperties': {'.*': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'created': {'type': 'integer'}, - 'created-by': {'type': 'string'}}, - 'required': ['assigned-units', - 'created', - 'created-by'], - 'type': 'object'}, - 'DetailedStatus': {'additionalProperties': False, - 'properties': {'data': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'err': {'$ref': '#/definitions/Error'}, - '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'}, - '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': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - 'type': 'object'}, - 'ExposedEndpoint': {'additionalProperties': False, - 'properties': {'expose-to-cidrs': {'items': {'type': 'string'}, - 'type': 'array'}, - 'expose-to-spaces': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'FilesystemAttachmentDetails': {'additionalProperties': False, - 'properties': {'FilesystemAttachmentInfo': {'$ref': '#/definitions/FilesystemAttachmentInfo'}, - 'life': {'type': 'string'}, - 'mount-point': {'type': 'string'}, - 'read-only': {'type': 'boolean'}}, - 'required': ['FilesystemAttachmentInfo'], - 'type': 'object'}, - 'FilesystemAttachmentInfo': {'additionalProperties': False, - 'properties': {'mount-point': {'type': 'string'}, - 'read-only': {'type': 'boolean'}}, - 'type': 'object'}, - 'FilesystemDetails': {'additionalProperties': False, - 'properties': {'filesystem-tag': {'type': 'string'}, - 'info': {'$ref': '#/definitions/FilesystemInfo'}, - 'life': {'type': 'string'}, - 'machine-attachments': {'patternProperties': {'.*': {'$ref': '#/definitions/FilesystemAttachmentDetails'}}, - 'type': 'object'}, - 'status': {'$ref': '#/definitions/EntityStatus'}, - 'storage': {'$ref': '#/definitions/StorageDetails'}, - 'unit-attachments': {'patternProperties': {'.*': {'$ref': '#/definitions/FilesystemAttachmentDetails'}}, - 'type': 'object'}, - 'volume-tag': {'type': 'string'}}, - 'required': ['filesystem-tag', - 'info', - 'status'], - 'type': 'object'}, - 'FilesystemInfo': {'additionalProperties': False, - 'properties': {'filesystem-id': {'type': 'string'}, - 'pool': {'type': 'string'}, - 'size': {'type': 'integer'}}, - 'required': ['filesystem-id', - 'pool', - 'size'], - 'type': 'object'}, - 'FullStatus': {'additionalProperties': False, - 'properties': {'applications': {'patternProperties': {'.*': {'$ref': '#/definitions/ApplicationStatus'}}, - 'type': 'object'}, - 'branches': {'patternProperties': {'.*': {'$ref': '#/definitions/BranchStatus'}}, - 'type': 'object'}, - 'controller-timestamp': {'format': 'date-time', - 'type': 'string'}, - 'filesystems': {'items': {'$ref': '#/definitions/FilesystemDetails'}, - 'type': 'array'}, - 'machines': {'patternProperties': {'.*': {'$ref': '#/definitions/MachineStatus'}}, - 'type': 'object'}, - 'model': {'$ref': '#/definitions/ModelStatusInfo'}, - 'offers': {'patternProperties': {'.*': {'$ref': '#/definitions/ApplicationOfferStatus'}}, - 'type': 'object'}, - 'relations': {'items': {'$ref': '#/definitions/RelationStatus'}, - 'type': 'array'}, - 'remote-applications': {'patternProperties': {'.*': {'$ref': '#/definitions/RemoteApplicationStatus'}}, - 'type': 'object'}, - 'storage': {'items': {'$ref': '#/definitions/StorageDetails'}, - 'type': 'array'}, - 'volumes': {'items': {'$ref': '#/definitions/VolumeDetails'}, - 'type': 'array'}}, - 'required': ['model', - 'machines', - 'applications', - 'remote-applications', - 'offers', - 'relations', - 'controller-timestamp', - 'branches'], - 'type': 'object'}, - 'History': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'statuses': {'items': {'$ref': '#/definitions/DetailedStatus'}, - 'type': 'array'}}, - 'required': ['statuses'], - 'type': 'object'}, - 'LXDProfile': {'additionalProperties': False, - 'properties': {'config': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'description': {'type': 'string'}, - 'devices': {'patternProperties': {'.*': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}}, - 'type': 'object'}}, - 'required': ['config', - 'description', - 'devices'], - 'type': 'object'}, - 'MachineStatus': {'additionalProperties': False, - 'properties': {'agent-status': {'$ref': '#/definitions/DetailedStatus'}, - 'base': {'$ref': '#/definitions/Base'}, - 'constraints': {'type': 'string'}, - 'containers': {'patternProperties': {'.*': {'$ref': '#/definitions/MachineStatus'}}, - 'type': 'object'}, - 'display-name': {'type': 'string'}, - 'dns-name': {'type': 'string'}, - 'hardware': {'type': 'string'}, - 'has-vote': {'type': 'boolean'}, - 'hostname': {'type': 'string'}, - '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'}, - 'lxd-profiles': {'patternProperties': {'.*': {'$ref': '#/definitions/LXDProfile'}}, - 'type': 'object'}, - 'modification-status': {'$ref': '#/definitions/DetailedStatus'}, - 'network-interfaces': {'patternProperties': {'.*': {'$ref': '#/definitions/NetworkInterface'}}, - 'type': 'object'}, - 'primary-controller-machine': {'type': 'boolean'}, - 'wants-vote': {'type': 'boolean'}}, - 'required': ['agent-status', - 'instance-status', - 'modification-status', - 'dns-name', - 'instance-id', - 'display-name', - 'base', - 'id', - 'containers', - 'constraints', - 'hardware', - 'jobs', - 'has-vote', - 'wants-vote'], - 'type': 'object'}, - 'MeterStatus': {'additionalProperties': False, - 'properties': {'color': {'type': 'string'}, - 'message': {'type': 'string'}}, - 'required': ['color', 'message'], - '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'}, - 'type': {'type': 'string'}, - 'version': {'type': 'string'}}, - 'required': ['name', - 'type', - 'cloud-tag', - 'version', - 'available-version', - 'model-status', - 'meter-status', - 'sla'], - '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'}, - 'RelationStatus': {'additionalProperties': False, - 'properties': {'endpoints': {'items': {'$ref': '#/definitions/EndpointStatus'}, - 'type': 'array'}, - 'id': {'type': 'integer'}, - 'interface': {'type': 'string'}, - 'key': {'type': 'string'}, - 'scope': {'type': 'string'}, - 'status': {'$ref': '#/definitions/DetailedStatus'}}, - 'required': ['id', - 'key', - 'interface', - 'scope', - 'endpoints', - 'status'], - 'type': 'object'}, - 'RemoteApplicationStatus': {'additionalProperties': False, - 'properties': {'endpoints': {'items': {'$ref': '#/definitions/RemoteEndpoint'}, - 'type': 'array'}, - 'err': {'$ref': '#/definitions/Error'}, - 'life': {'type': 'string'}, - 'offer-name': {'type': 'string'}, - 'offer-url': {'type': 'string'}, - 'relations': {'patternProperties': {'.*': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'type': 'object'}, - 'status': {'$ref': '#/definitions/DetailedStatus'}}, - 'required': ['offer-url', - 'offer-name', - 'endpoints', - 'life', - 'relations', - 'status'], - 'type': 'object'}, - 'RemoteEndpoint': {'additionalProperties': False, - 'properties': {'interface': {'type': 'string'}, - 'limit': {'type': 'integer'}, - 'name': {'type': 'string'}, - 'role': {'type': 'string'}}, - 'required': ['name', - 'role', - 'interface', - 'limit'], - 'type': 'object'}, - 'StatusHistoryFilter': {'additionalProperties': False, - 'properties': {'date': {'format': 'date-time', - 'type': 'string'}, - 'delta': {'type': 'integer'}, - 'exclude': {'items': {'type': 'string'}, - 'type': 'array'}, - 'size': {'type': 'integer'}}, - 'required': ['size', - 'date', - 'delta', - 'exclude'], - 'type': 'object'}, - 'StatusHistoryRequest': {'additionalProperties': False, - 'properties': {'filter': {'$ref': '#/definitions/StatusHistoryFilter'}, - 'historyKind': {'type': 'string'}, - 'size': {'type': 'integer'}, - 'tag': {'type': 'string'}}, - 'required': ['historyKind', - 'size', - 'filter', - 'tag'], - 'type': 'object'}, - 'StatusHistoryRequests': {'additionalProperties': False, - 'properties': {'requests': {'items': {'$ref': '#/definitions/StatusHistoryRequest'}, - 'type': 'array'}}, - 'required': ['requests'], - 'type': 'object'}, - 'StatusHistoryResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'history': {'$ref': '#/definitions/History'}}, - 'required': ['history'], - 'type': 'object'}, - 'StatusHistoryResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/StatusHistoryResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'StatusParams': {'additionalProperties': False, - 'properties': {'include-storage': {'type': 'boolean'}, - 'patterns': {'items': {'type': 'string'}, - 'type': 'array'}}, - 'required': ['patterns'], - 'type': 'object'}, - 'StorageAttachmentDetails': {'additionalProperties': False, - 'properties': {'life': {'type': 'string'}, - 'location': {'type': 'string'}, - 'machine-tag': {'type': 'string'}, - 'storage-tag': {'type': 'string'}, - 'unit-tag': {'type': 'string'}}, - 'required': ['storage-tag', - 'unit-tag', - 'machine-tag'], - 'type': 'object'}, - 'StorageDetails': {'additionalProperties': False, - 'properties': {'attachments': {'patternProperties': {'.*': {'$ref': '#/definitions/StorageAttachmentDetails'}}, - 'type': 'object'}, - 'kind': {'type': 'integer'}, - 'life': {'type': 'string'}, - 'owner-tag': {'type': 'string'}, - 'persistent': {'type': 'boolean'}, - 'status': {'$ref': '#/definitions/EntityStatus'}, - 'storage-tag': {'type': 'string'}}, - 'required': ['storage-tag', - 'owner-tag', - 'kind', - 'status', - 'persistent'], - 'type': 'object'}, - 'UnitStatus': {'additionalProperties': False, - 'properties': {'address': {'type': 'string'}, - 'agent-status': {'$ref': '#/definitions/DetailedStatus'}, - 'charm': {'type': 'string'}, - 'leader': {'type': 'boolean'}, - 'machine': {'type': 'string'}, - 'opened-ports': {'items': {'type': 'string'}, - 'type': 'array'}, - 'provider-id': {'type': 'string'}, - 'public-address': {'type': 'string'}, - 'subordinates': {'patternProperties': {'.*': {'$ref': '#/definitions/UnitStatus'}}, - 'type': 'object'}, - 'workload-status': {'$ref': '#/definitions/DetailedStatus'}, - 'workload-version': {'type': 'string'}}, - 'required': ['agent-status', - 'workload-status', - 'workload-version', - 'machine', - 'opened-ports', - 'public-address', - 'charm', - 'subordinates'], - 'type': 'object'}, - 'VolumeAttachmentDetails': {'additionalProperties': False, - 'properties': {'VolumeAttachmentInfo': {'$ref': '#/definitions/VolumeAttachmentInfo'}, - 'bus-address': {'type': 'string'}, - 'device-link': {'type': 'string'}, - 'device-name': {'type': 'string'}, - 'life': {'type': 'string'}, - 'plan-info': {'$ref': '#/definitions/VolumeAttachmentPlanInfo'}, - 'read-only': {'type': 'boolean'}}, - 'required': ['VolumeAttachmentInfo'], - 'type': 'object'}, - 'VolumeAttachmentInfo': {'additionalProperties': False, - 'properties': {'bus-address': {'type': 'string'}, - 'device-link': {'type': 'string'}, - 'device-name': {'type': 'string'}, - 'plan-info': {'$ref': '#/definitions/VolumeAttachmentPlanInfo'}, - 'read-only': {'type': 'boolean'}}, - 'type': 'object'}, - 'VolumeAttachmentPlanInfo': {'additionalProperties': False, - 'properties': {'device-attributes': {'patternProperties': {'.*': {'type': 'string'}}, - 'type': 'object'}, - 'device-type': {'type': 'string'}}, - 'type': 'object'}, - 'VolumeDetails': {'additionalProperties': False, - 'properties': {'info': {'$ref': '#/definitions/VolumeInfo'}, - 'life': {'type': 'string'}, - 'machine-attachments': {'patternProperties': {'.*': {'$ref': '#/definitions/VolumeAttachmentDetails'}}, - 'type': 'object'}, - 'status': {'$ref': '#/definitions/EntityStatus'}, - 'storage': {'$ref': '#/definitions/StorageDetails'}, - 'unit-attachments': {'patternProperties': {'.*': {'$ref': '#/definitions/VolumeAttachmentDetails'}}, - 'type': 'object'}, - 'volume-tag': {'type': 'string'}}, - 'required': ['volume-tag', 'info', 'status'], - 'type': 'object'}, - 'VolumeInfo': {'additionalProperties': False, - 'properties': {'hardware-id': {'type': 'string'}, - 'persistent': {'type': 'boolean'}, - 'pool': {'type': 'string'}, - 'size': {'type': 'integer'}, - 'volume-id': {'type': 'string'}, - 'wwn': {'type': 'string'}}, - 'required': ['volume-id', 'size', 'persistent'], - 'type': 'object'}}, - 'properties': {'FullStatus': {'description': 'FullStatus gives the ' - 'information needed for juju ' - 'status over the api', - 'properties': {'Params': {'$ref': '#/definitions/StatusParams'}, - 'Result': {'$ref': '#/definitions/FullStatus'}}, - 'type': 'object'}, - 'StatusHistory': {'description': 'StatusHistory returns a ' - 'slice of past statuses for ' - 'several entities.', - 'properties': {'Params': {'$ref': '#/definitions/StatusHistoryRequests'}, - 'Result': {'$ref': '#/definitions/StatusHistoryResults'}}, - 'type': 'object'}, - 'WatchAll': {'description': 'WatchAll initiates a watcher for ' - 'entities in the connected model.', - 'properties': {'Result': {'$ref': '#/definitions/AllWatcherId'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "AllWatcherId": { + "additionalProperties": False, + "properties": {"watcher-id": {"type": "string"}}, + "required": ["watcher-id"], + "type": "object", + }, + "ApplicationOfferStatus": { + "additionalProperties": False, + "properties": { + "active-connected-count": {"type": "integer"}, + "application-name": {"type": "string"}, + "charm": {"type": "string"}, + "endpoints": { + "patternProperties": { + ".*": {"$ref": "#/definitions/RemoteEndpoint"} + }, + "type": "object", + }, + "err": {"$ref": "#/definitions/Error"}, + "offer-name": {"type": "string"}, + "total-connected-count": {"type": "integer"}, + }, + "required": [ + "offer-name", + "application-name", + "charm", + "endpoints", + "active-connected-count", + "total-connected-count", + ], + "type": "object", + }, + "ApplicationStatus": { + "additionalProperties": False, + "properties": { + "base": {"$ref": "#/definitions/Base"}, + "can-upgrade-to": {"type": "string"}, + "charm": {"type": "string"}, + "charm-channel": {"type": "string"}, + "charm-profile": {"type": "string"}, + "charm-version": {"type": "string"}, + "endpoint-bindings": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "err": {"$ref": "#/definitions/Error"}, + "exposed": {"type": "boolean"}, + "exposed-endpoints": { + "patternProperties": { + ".*": {"$ref": "#/definitions/ExposedEndpoint"} + }, + "type": "object", + }, + "int": {"type": "integer"}, + "life": {"type": "string"}, + "meter-statuses": { + "patternProperties": { + ".*": {"$ref": "#/definitions/MeterStatus"} + }, + "type": "object", + }, + "provider-id": {"type": "string"}, + "public-address": {"type": "string"}, + "relations": { + "patternProperties": { + ".*": {"items": {"type": "string"}, "type": "array"} + }, + "type": "object", + }, + "status": {"$ref": "#/definitions/DetailedStatus"}, + "subordinate-to": {"items": {"type": "string"}, "type": "array"}, + "units": { + "patternProperties": { + ".*": {"$ref": "#/definitions/UnitStatus"} + }, + "type": "object", + }, + "workload-version": {"type": "string"}, + }, + "required": [ + "charm", + "charm-version", + "charm-profile", + "base", + "exposed", + "life", + "relations", + "can-upgrade-to", + "subordinate-to", + "units", + "meter-statuses", + "status", + "workload-version", + "endpoint-bindings", + "public-address", + ], + "type": "object", + }, + "Base": { + "additionalProperties": False, + "properties": { + "channel": {"type": "string"}, + "name": {"type": "string"}, + }, + "required": ["name", "channel"], + "type": "object", + }, + "BranchStatus": { + "additionalProperties": False, + "properties": { + "assigned-units": { + "patternProperties": { + ".*": {"items": {"type": "string"}, "type": "array"} + }, + "type": "object", + }, + "created": {"type": "integer"}, + "created-by": {"type": "string"}, + }, + "required": ["assigned-units", "created", "created-by"], + "type": "object", + }, + "DetailedStatus": { + "additionalProperties": False, + "properties": { + "data": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "err": {"$ref": "#/definitions/Error"}, + "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", + }, + "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": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "type": "object", + }, + "ExposedEndpoint": { + "additionalProperties": False, + "properties": { + "expose-to-cidrs": {"items": {"type": "string"}, "type": "array"}, + "expose-to-spaces": {"items": {"type": "string"}, "type": "array"}, + }, + "type": "object", + }, + "FilesystemAttachmentDetails": { + "additionalProperties": False, + "properties": { + "FilesystemAttachmentInfo": { + "$ref": "#/definitions/FilesystemAttachmentInfo" + }, + "life": {"type": "string"}, + "mount-point": {"type": "string"}, + "read-only": {"type": "boolean"}, + }, + "required": ["FilesystemAttachmentInfo"], + "type": "object", + }, + "FilesystemAttachmentInfo": { + "additionalProperties": False, + "properties": { + "mount-point": {"type": "string"}, + "read-only": {"type": "boolean"}, + }, + "type": "object", + }, + "FilesystemDetails": { + "additionalProperties": False, + "properties": { + "filesystem-tag": {"type": "string"}, + "info": {"$ref": "#/definitions/FilesystemInfo"}, + "life": {"type": "string"}, + "machine-attachments": { + "patternProperties": { + ".*": {"$ref": "#/definitions/FilesystemAttachmentDetails"} + }, + "type": "object", + }, + "status": {"$ref": "#/definitions/EntityStatus"}, + "storage": {"$ref": "#/definitions/StorageDetails"}, + "unit-attachments": { + "patternProperties": { + ".*": {"$ref": "#/definitions/FilesystemAttachmentDetails"} + }, + "type": "object", + }, + "volume-tag": {"type": "string"}, + }, + "required": ["filesystem-tag", "info", "status"], + "type": "object", + }, + "FilesystemInfo": { + "additionalProperties": False, + "properties": { + "filesystem-id": {"type": "string"}, + "pool": {"type": "string"}, + "size": {"type": "integer"}, + }, + "required": ["filesystem-id", "pool", "size"], + "type": "object", + }, + "FullStatus": { + "additionalProperties": False, + "properties": { + "applications": { + "patternProperties": { + ".*": {"$ref": "#/definitions/ApplicationStatus"} + }, + "type": "object", + }, + "branches": { + "patternProperties": { + ".*": {"$ref": "#/definitions/BranchStatus"} + }, + "type": "object", + }, + "controller-timestamp": {"format": "date-time", "type": "string"}, + "filesystems": { + "items": {"$ref": "#/definitions/FilesystemDetails"}, + "type": "array", + }, + "machines": { + "patternProperties": { + ".*": {"$ref": "#/definitions/MachineStatus"} + }, + "type": "object", + }, + "model": {"$ref": "#/definitions/ModelStatusInfo"}, + "offers": { + "patternProperties": { + ".*": {"$ref": "#/definitions/ApplicationOfferStatus"} + }, + "type": "object", + }, + "relations": { + "items": {"$ref": "#/definitions/RelationStatus"}, + "type": "array", + }, + "remote-applications": { + "patternProperties": { + ".*": {"$ref": "#/definitions/RemoteApplicationStatus"} + }, + "type": "object", + }, + "storage": { + "items": {"$ref": "#/definitions/StorageDetails"}, + "type": "array", + }, + "volumes": { + "items": {"$ref": "#/definitions/VolumeDetails"}, + "type": "array", + }, + }, + "required": [ + "model", + "machines", + "applications", + "remote-applications", + "offers", + "relations", + "controller-timestamp", + "branches", + ], + "type": "object", + }, + "History": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "statuses": { + "items": {"$ref": "#/definitions/DetailedStatus"}, + "type": "array", + }, + }, + "required": ["statuses"], + "type": "object", + }, + "LXDProfile": { + "additionalProperties": False, + "properties": { + "config": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "description": {"type": "string"}, + "devices": { + "patternProperties": { + ".*": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + } + }, + "type": "object", + }, + }, + "required": ["config", "description", "devices"], + "type": "object", + }, + "MachineStatus": { + "additionalProperties": False, + "properties": { + "agent-status": {"$ref": "#/definitions/DetailedStatus"}, + "base": {"$ref": "#/definitions/Base"}, + "constraints": {"type": "string"}, + "containers": { + "patternProperties": { + ".*": {"$ref": "#/definitions/MachineStatus"} + }, + "type": "object", + }, + "display-name": {"type": "string"}, + "dns-name": {"type": "string"}, + "hardware": {"type": "string"}, + "has-vote": {"type": "boolean"}, + "hostname": {"type": "string"}, + "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"}, + "lxd-profiles": { + "patternProperties": { + ".*": {"$ref": "#/definitions/LXDProfile"} + }, + "type": "object", + }, + "modification-status": {"$ref": "#/definitions/DetailedStatus"}, + "network-interfaces": { + "patternProperties": { + ".*": {"$ref": "#/definitions/NetworkInterface"} + }, + "type": "object", + }, + "primary-controller-machine": {"type": "boolean"}, + "wants-vote": {"type": "boolean"}, + }, + "required": [ + "agent-status", + "instance-status", + "modification-status", + "dns-name", + "instance-id", + "display-name", + "base", + "id", + "containers", + "constraints", + "hardware", + "jobs", + "has-vote", + "wants-vote", + ], + "type": "object", + }, + "MeterStatus": { + "additionalProperties": False, + "properties": { + "color": {"type": "string"}, + "message": {"type": "string"}, + }, + "required": ["color", "message"], + "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"}, + "type": {"type": "string"}, + "version": {"type": "string"}, + }, + "required": [ + "name", + "type", + "cloud-tag", + "version", + "available-version", + "model-status", + "meter-status", + "sla", + ], + "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", + }, + "RelationStatus": { + "additionalProperties": False, + "properties": { + "endpoints": { + "items": {"$ref": "#/definitions/EndpointStatus"}, + "type": "array", + }, + "id": {"type": "integer"}, + "interface": {"type": "string"}, + "key": {"type": "string"}, + "scope": {"type": "string"}, + "status": {"$ref": "#/definitions/DetailedStatus"}, + }, + "required": ["id", "key", "interface", "scope", "endpoints", "status"], + "type": "object", + }, + "RemoteApplicationStatus": { + "additionalProperties": False, + "properties": { + "endpoints": { + "items": {"$ref": "#/definitions/RemoteEndpoint"}, + "type": "array", + }, + "err": {"$ref": "#/definitions/Error"}, + "life": {"type": "string"}, + "offer-name": {"type": "string"}, + "offer-url": {"type": "string"}, + "relations": { + "patternProperties": { + ".*": {"items": {"type": "string"}, "type": "array"} + }, + "type": "object", + }, + "status": {"$ref": "#/definitions/DetailedStatus"}, + }, + "required": [ + "offer-url", + "offer-name", + "endpoints", + "life", + "relations", + "status", + ], + "type": "object", + }, + "RemoteEndpoint": { + "additionalProperties": False, + "properties": { + "interface": {"type": "string"}, + "limit": {"type": "integer"}, + "name": {"type": "string"}, + "role": {"type": "string"}, + }, + "required": ["name", "role", "interface", "limit"], + "type": "object", + }, + "StatusHistoryFilter": { + "additionalProperties": False, + "properties": { + "date": {"format": "date-time", "type": "string"}, + "delta": {"type": "integer"}, + "exclude": {"items": {"type": "string"}, "type": "array"}, + "size": {"type": "integer"}, + }, + "required": ["size", "date", "delta", "exclude"], + "type": "object", + }, + "StatusHistoryRequest": { + "additionalProperties": False, + "properties": { + "filter": {"$ref": "#/definitions/StatusHistoryFilter"}, + "historyKind": {"type": "string"}, + "size": {"type": "integer"}, + "tag": {"type": "string"}, + }, + "required": ["historyKind", "size", "filter", "tag"], + "type": "object", + }, + "StatusHistoryRequests": { + "additionalProperties": False, + "properties": { + "requests": { + "items": {"$ref": "#/definitions/StatusHistoryRequest"}, + "type": "array", + } + }, + "required": ["requests"], + "type": "object", + }, + "StatusHistoryResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "history": {"$ref": "#/definitions/History"}, + }, + "required": ["history"], + "type": "object", + }, + "StatusHistoryResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/StatusHistoryResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "StatusParams": { + "additionalProperties": False, + "properties": { + "include-storage": {"type": "boolean"}, + "patterns": {"items": {"type": "string"}, "type": "array"}, + }, + "required": ["patterns"], + "type": "object", + }, + "StorageAttachmentDetails": { + "additionalProperties": False, + "properties": { + "life": {"type": "string"}, + "location": {"type": "string"}, + "machine-tag": {"type": "string"}, + "storage-tag": {"type": "string"}, + "unit-tag": {"type": "string"}, + }, + "required": ["storage-tag", "unit-tag", "machine-tag"], + "type": "object", + }, + "StorageDetails": { + "additionalProperties": False, + "properties": { + "attachments": { + "patternProperties": { + ".*": {"$ref": "#/definitions/StorageAttachmentDetails"} + }, + "type": "object", + }, + "kind": {"type": "integer"}, + "life": {"type": "string"}, + "owner-tag": {"type": "string"}, + "persistent": {"type": "boolean"}, + "status": {"$ref": "#/definitions/EntityStatus"}, + "storage-tag": {"type": "string"}, + }, + "required": [ + "storage-tag", + "owner-tag", + "kind", + "status", + "persistent", + ], + "type": "object", + }, + "UnitStatus": { + "additionalProperties": False, + "properties": { + "address": {"type": "string"}, + "agent-status": {"$ref": "#/definitions/DetailedStatus"}, + "charm": {"type": "string"}, + "leader": {"type": "boolean"}, + "machine": {"type": "string"}, + "opened-ports": {"items": {"type": "string"}, "type": "array"}, + "provider-id": {"type": "string"}, + "public-address": {"type": "string"}, + "subordinates": { + "patternProperties": { + ".*": {"$ref": "#/definitions/UnitStatus"} + }, + "type": "object", + }, + "workload-status": {"$ref": "#/definitions/DetailedStatus"}, + "workload-version": {"type": "string"}, + }, + "required": [ + "agent-status", + "workload-status", + "workload-version", + "machine", + "opened-ports", + "public-address", + "charm", + "subordinates", + ], + "type": "object", + }, + "VolumeAttachmentDetails": { + "additionalProperties": False, + "properties": { + "VolumeAttachmentInfo": { + "$ref": "#/definitions/VolumeAttachmentInfo" + }, + "bus-address": {"type": "string"}, + "device-link": {"type": "string"}, + "device-name": {"type": "string"}, + "life": {"type": "string"}, + "plan-info": {"$ref": "#/definitions/VolumeAttachmentPlanInfo"}, + "read-only": {"type": "boolean"}, + }, + "required": ["VolumeAttachmentInfo"], + "type": "object", + }, + "VolumeAttachmentInfo": { + "additionalProperties": False, + "properties": { + "bus-address": {"type": "string"}, + "device-link": {"type": "string"}, + "device-name": {"type": "string"}, + "plan-info": {"$ref": "#/definitions/VolumeAttachmentPlanInfo"}, + "read-only": {"type": "boolean"}, + }, + "type": "object", + }, + "VolumeAttachmentPlanInfo": { + "additionalProperties": False, + "properties": { + "device-attributes": { + "patternProperties": {".*": {"type": "string"}}, + "type": "object", + }, + "device-type": {"type": "string"}, + }, + "type": "object", + }, + "VolumeDetails": { + "additionalProperties": False, + "properties": { + "info": {"$ref": "#/definitions/VolumeInfo"}, + "life": {"type": "string"}, + "machine-attachments": { + "patternProperties": { + ".*": {"$ref": "#/definitions/VolumeAttachmentDetails"} + }, + "type": "object", + }, + "status": {"$ref": "#/definitions/EntityStatus"}, + "storage": {"$ref": "#/definitions/StorageDetails"}, + "unit-attachments": { + "patternProperties": { + ".*": {"$ref": "#/definitions/VolumeAttachmentDetails"} + }, + "type": "object", + }, + "volume-tag": {"type": "string"}, + }, + "required": ["volume-tag", "info", "status"], + "type": "object", + }, + "VolumeInfo": { + "additionalProperties": False, + "properties": { + "hardware-id": {"type": "string"}, + "persistent": {"type": "boolean"}, + "pool": {"type": "string"}, + "size": {"type": "integer"}, + "volume-id": {"type": "string"}, + "wwn": {"type": "string"}, + }, + "required": ["volume-id", "size", "persistent"], + "type": "object", + }, + }, + "properties": { + "FullStatus": { + "description": "FullStatus gives the " + "information needed for juju " + "status over the api", + "properties": { + "Params": {"$ref": "#/definitions/StatusParams"}, + "Result": {"$ref": "#/definitions/FullStatus"}, + }, + "type": "object", + }, + "StatusHistory": { + "description": "StatusHistory returns a " + "slice of past statuses for " + "several entities.", + "properties": { + "Params": {"$ref": "#/definitions/StatusHistoryRequests"}, + "Result": {"$ref": "#/definitions/StatusHistoryResults"}, + }, + "type": "object", + }, + "WatchAll": { + "description": "WatchAll initiates a watcher for " + "entities in the connected model.", + "properties": {"Result": {"$ref": "#/definitions/AllWatcherId"}}, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(FullStatus) async def FullStatus(self, include_storage=None, patterns=None): - ''' + """ FullStatus gives the information needed for juju status over the api include_storage : bool patterns : typing.Sequence[str] Returns -> FullStatus - ''' + """ if include_storage is not None and not isinstance(include_storage, bool): - raise Exception("Expected include_storage to be a bool, received: {}".format(type(include_storage))) + raise Exception( + "Expected include_storage to be a bool, received: {}".format( + type(include_storage) + ) + ) if patterns is not None and not isinstance(patterns, (bytes, str, list)): - raise Exception("Expected patterns to be a Sequence, received: {}".format(type(patterns))) + raise Exception( + "Expected patterns to be a Sequence, received: {}".format( + type(patterns) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Client', - request='FullStatus', - version=8, - params=_params) - _params['include-storage'] = include_storage - _params['patterns'] = patterns + msg = dict(type="Client", request="FullStatus", version=8, params=_params) + _params["include-storage"] = include_storage + _params["patterns"] = patterns reply = await self.rpc(msg) return reply - - @ReturnMapping(StatusHistoryResults) async def StatusHistory(self, requests=None): - ''' + """ StatusHistory returns a slice of past statuses for several entities. requests : typing.Sequence[~StatusHistoryRequest] Returns -> StatusHistoryResults - ''' + """ if requests is not None and not isinstance(requests, (bytes, str, list)): - raise Exception("Expected requests to be a Sequence, received: {}".format(type(requests))) + raise Exception( + "Expected requests to be a Sequence, received: {}".format( + type(requests) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='Client', - request='StatusHistory', - version=8, - params=_params) - _params['requests'] = requests + msg = dict(type="Client", request="StatusHistory", version=8, params=_params) + _params["requests"] = requests reply = await self.rpc(msg) return reply - - @ReturnMapping(AllWatcherId) async def WatchAll(self): - ''' + """ WatchAll initiates a watcher for entities in the connected model. Returns -> AllWatcherId - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Client', - request='WatchAll', - version=8, - params=_params) + msg = dict(type="Client", request="WatchAll", version=8, params=_params) reply = await self.rpc(msg) return reply - - diff --git a/juju/client/_client9.py b/juju/client/_client9.py index 7aa58aa6b..63d6110cd 100644 --- a/juju/client/_client9.py +++ b/juju/client/_client9.py @@ -6,580 +6,904 @@ class ModelManagerFacade(Type): - name = 'ModelManager' + name = "ModelManager" version = 9 - schema = {'definitions': {'ChangeModelCredentialParams': {'additionalProperties': False, - 'properties': {'credential-tag': {'type': 'string'}, - 'model-tag': {'type': 'string'}}, - 'required': ['model-tag', - 'credential-tag'], - 'type': 'object'}, - 'ChangeModelCredentialsParams': {'additionalProperties': False, - 'properties': {'model-credentials': {'items': {'$ref': '#/definitions/ChangeModelCredentialParams'}, - 'type': 'array'}}, - 'required': ['model-credentials'], - 'type': 'object'}, - 'DestroyModelParams': {'additionalProperties': False, - 'properties': {'destroy-storage': {'type': 'boolean'}, - 'force': {'type': 'boolean'}, - 'max-wait': {'type': 'integer'}, - 'model-tag': {'type': 'string'}, - 'timeout': {'type': 'integer'}}, - 'required': ['model-tag'], - 'type': 'object'}, - 'DestroyModelsParams': {'additionalProperties': False, - 'properties': {'models': {'items': {'$ref': '#/definitions/DestroyModelParams'}, - 'type': 'array'}}, - 'required': ['models'], - 'type': 'object'}, - 'DumpModelRequest': {'additionalProperties': False, - 'properties': {'entities': {'items': {'$ref': '#/definitions/Entity'}, - 'type': 'array'}, - 'simplified': {'type': 'boolean'}}, - 'required': ['entities', 'simplified'], - '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'}, - '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': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'message': {'type': 'string'}}, - 'required': ['message', 'code'], - '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'}, - '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'}, - 'virt-type': {'type': 'string'}}, - 'type': 'object'}, - 'MapResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}}, - 'required': ['result'], - 'type': 'object'}, - 'MapResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/MapResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'Model': {'additionalProperties': False, - 'properties': {'name': {'type': 'string'}, - 'owner-tag': {'type': 'string'}, - 'type': {'type': 'string'}, - 'uuid': {'type': 'string'}}, - 'required': ['name', 'uuid', 'type', 'owner-tag'], - 'type': 'object'}, - 'ModelApplicationInfo': {'additionalProperties': False, - 'properties': {'name': {'type': 'string'}}, - 'required': ['name'], - 'type': 'object'}, - 'ModelCreateArgs': {'additionalProperties': False, - 'properties': {'cloud-tag': {'type': 'string'}, - 'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'credential': {'type': 'string'}, - 'name': {'type': 'string'}, - 'owner-tag': {'type': 'string'}, - 'region': {'type': 'string'}}, - 'required': ['name', 'owner-tag'], - 'type': 'object'}, - 'ModelDefaultValues': {'additionalProperties': False, - 'properties': {'cloud-region': {'type': 'string'}, - 'cloud-tag': {'type': 'string'}, - 'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}}, - 'required': ['config'], - 'type': 'object'}, - 'ModelDefaults': {'additionalProperties': False, - 'properties': {'controller': {'additionalProperties': True, - 'type': 'object'}, - 'default': {'additionalProperties': True, - 'type': 'object'}, - 'regions': {'items': {'$ref': '#/definitions/RegionDefaults'}, - 'type': 'array'}}, - 'type': 'object'}, - 'ModelDefaultsResult': {'additionalProperties': False, - 'properties': {'config': {'patternProperties': {'.*': {'$ref': '#/definitions/ModelDefaults'}}, - 'type': 'object'}, - 'error': {'$ref': '#/definitions/Error'}}, - 'required': ['config'], - 'type': 'object'}, - 'ModelDefaultsResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ModelDefaultsResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'ModelEntityCount': {'additionalProperties': False, - 'properties': {'count': {'type': 'integer'}, - 'entity': {'type': 'string'}}, - 'required': ['entity', 'count'], - 'type': 'object'}, - 'ModelFilesystemInfo': {'additionalProperties': False, - 'properties': {'detachable': {'type': 'boolean'}, - 'id': {'type': 'string'}, - 'message': {'type': 'string'}, - 'provider-id': {'type': 'string'}, - 'status': {'type': 'string'}}, - 'required': ['id'], - 'type': 'object'}, - 'ModelInfo': {'additionalProperties': False, - 'properties': {'agent-version': {'$ref': '#/definitions/Number'}, - 'cloud-credential-tag': {'type': 'string'}, - 'cloud-credential-validity': {'type': 'boolean'}, - 'cloud-region': {'type': 'string'}, - 'cloud-tag': {'type': 'string'}, - 'controller-uuid': {'type': 'string'}, - 'default-base': {'type': 'string'}, - 'default-series': {'type': 'string'}, - 'is-controller': {'type': 'boolean'}, - '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'}, - 'secret-backends': {'items': {'$ref': '#/definitions/SecretBackendResult'}, - 'type': 'array'}, - 'sla': {'$ref': '#/definitions/ModelSLAInfo'}, - 'status': {'$ref': '#/definitions/EntityStatus'}, - 'supported-features': {'items': {'$ref': '#/definitions/SupportedFeature'}, - 'type': 'array'}, - 'type': {'type': 'string'}, - 'users': {'items': {'$ref': '#/definitions/ModelUserInfo'}, - 'type': 'array'}, - 'uuid': {'type': 'string'}}, - 'required': ['name', - 'type', - 'uuid', - 'controller-uuid', - 'is-controller', - 'cloud-tag', - 'owner-tag', - 'life', - 'users', - 'machines', - 'secret-backends', - 'sla', - 'agent-version'], - 'type': 'object'}, - 'ModelInfoResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/ModelInfo'}}, - 'type': 'object'}, - 'ModelInfoResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ModelInfoResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'ModelMachineInfo': {'additionalProperties': False, - 'properties': {'display-name': {'type': 'string'}, - 'ha-primary': {'type': 'boolean'}, - 'hardware': {'$ref': '#/definitions/MachineHardware'}, - 'has-vote': {'type': 'boolean'}, - 'id': {'type': 'string'}, - 'instance-id': {'type': 'string'}, - 'message': {'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'}, - 'ModelSLAInfo': {'additionalProperties': False, - 'properties': {'level': {'type': 'string'}, - 'owner': {'type': 'string'}}, - 'required': ['level', 'owner'], - 'type': 'object'}, - 'ModelStatus': {'additionalProperties': False, - 'properties': {'application-count': {'type': 'integer'}, - 'applications': {'items': {'$ref': '#/definitions/ModelApplicationInfo'}, - 'type': 'array'}, - 'error': {'$ref': '#/definitions/Error'}, - 'filesystems': {'items': {'$ref': '#/definitions/ModelFilesystemInfo'}, - 'type': 'array'}, - 'hosted-machine-count': {'type': 'integer'}, - 'life': {'type': 'string'}, - 'machines': {'items': {'$ref': '#/definitions/ModelMachineInfo'}, - 'type': 'array'}, - 'model-tag': {'type': 'string'}, - 'owner-tag': {'type': 'string'}, - 'type': {'type': 'string'}, - 'unit-count': {'type': 'integer'}, - 'volumes': {'items': {'$ref': '#/definitions/ModelVolumeInfo'}, - 'type': 'array'}}, - 'required': ['model-tag', - 'life', - 'type', - 'hosted-machine-count', - 'application-count', - 'unit-count', - 'owner-tag'], - 'type': 'object'}, - 'ModelStatusResults': {'additionalProperties': False, - 'properties': {'models': {'items': {'$ref': '#/definitions/ModelStatus'}, - 'type': 'array'}}, - 'required': ['models'], - 'type': 'object'}, - 'ModelSummariesRequest': {'additionalProperties': False, - 'properties': {'all': {'type': 'boolean'}, - 'user-tag': {'type': 'string'}}, - 'required': ['user-tag'], - 'type': 'object'}, - 'ModelSummary': {'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'}, - 'counts': {'items': {'$ref': '#/definitions/ModelEntityCount'}, - 'type': 'array'}, - 'default-series': {'type': 'string'}, - 'is-controller': {'type': 'boolean'}, - 'last-connection': {'format': 'date-time', - 'type': 'string'}, - 'life': {'type': 'string'}, - 'migration': {'$ref': '#/definitions/ModelMigrationStatus'}, - 'name': {'type': 'string'}, - 'owner-tag': {'type': 'string'}, - 'provider-type': {'type': 'string'}, - 'sla': {'$ref': '#/definitions/ModelSLAInfo'}, - 'status': {'$ref': '#/definitions/EntityStatus'}, - 'type': {'type': 'string'}, - 'user-access': {'type': 'string'}, - 'uuid': {'type': 'string'}}, - 'required': ['name', - 'uuid', - 'type', - 'controller-uuid', - 'is-controller', - 'cloud-tag', - 'owner-tag', - 'life', - 'user-access', - 'last-connection', - 'counts', - 'sla', - 'agent-version'], - 'type': 'object'}, - 'ModelSummaryResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'$ref': '#/definitions/ModelSummary'}}, - 'type': 'object'}, - 'ModelSummaryResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/ModelSummaryResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'ModelUnsetKeys': {'additionalProperties': False, - 'properties': {'cloud-region': {'type': 'string'}, - 'cloud-tag': {'type': 'string'}, - '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'}, - 'model-tag': {'type': 'string'}, - 'user': {'type': 'string'}}, - 'required': ['model-tag', - 'user', - 'display-name', - 'last-connection', - 'access'], - 'type': 'object'}, - 'ModelVolumeInfo': {'additionalProperties': False, - 'properties': {'detachable': {'type': 'boolean'}, - 'id': {'type': 'string'}, - 'message': {'type': 'string'}, - 'provider-id': {'type': 'string'}, - 'status': {'type': 'string'}}, - 'required': ['id'], - 'type': 'object'}, - 'ModifyModelAccess': {'additionalProperties': False, - 'properties': {'access': {'type': 'string'}, - 'action': {'type': 'string'}, - 'model-tag': {'type': 'string'}, - 'user-tag': {'type': 'string'}}, - 'required': ['user-tag', - 'action', - 'access', - 'model-tag'], - 'type': 'object'}, - 'ModifyModelAccessRequest': {'additionalProperties': False, - 'properties': {'changes': {'items': {'$ref': '#/definitions/ModifyModelAccess'}, - 'type': 'array'}}, - 'required': ['changes'], - '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'}, - 'RegionDefaults': {'additionalProperties': False, - 'properties': {'region-name': {'type': 'string'}, - 'value': {'additionalProperties': True, - 'type': 'object'}}, - 'required': ['region-name', 'value'], - 'type': 'object'}, - 'SecretBackend': {'additionalProperties': False, - 'properties': {'backend-type': {'type': 'string'}, - 'config': {'patternProperties': {'.*': {'additionalProperties': True, - 'type': 'object'}}, - 'type': 'object'}, - 'name': {'type': 'string'}, - 'token-rotate-interval': {'type': 'integer'}}, - 'required': ['name', - 'backend-type', - 'config'], - 'type': 'object'}, - 'SecretBackendResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'id': {'type': 'string'}, - 'message': {'type': 'string'}, - 'num-secrets': {'type': 'integer'}, - 'result': {'$ref': '#/definitions/SecretBackend'}, - 'status': {'type': 'string'}}, - 'required': ['result', - 'id', - 'num-secrets', - 'status'], - 'type': 'object'}, - 'SetModelDefaults': {'additionalProperties': False, - 'properties': {'config': {'items': {'$ref': '#/definitions/ModelDefaultValues'}, - 'type': 'array'}}, - 'required': ['config'], - 'type': 'object'}, - 'StringResult': {'additionalProperties': False, - 'properties': {'error': {'$ref': '#/definitions/Error'}, - 'result': {'type': 'string'}}, - 'required': ['result'], - 'type': 'object'}, - 'StringResults': {'additionalProperties': False, - 'properties': {'results': {'items': {'$ref': '#/definitions/StringResult'}, - 'type': 'array'}}, - 'required': ['results'], - 'type': 'object'}, - 'SupportedFeature': {'additionalProperties': False, - 'properties': {'description': {'type': 'string'}, - 'name': {'type': 'string'}, - 'version': {'type': 'string'}}, - 'required': ['name', 'description'], - 'type': 'object'}, - 'UnsetModelDefaults': {'additionalProperties': False, - 'properties': {'keys': {'items': {'$ref': '#/definitions/ModelUnsetKeys'}, - 'type': 'array'}}, - 'required': ['keys'], - 'type': 'object'}, - 'UserModel': {'additionalProperties': False, - 'properties': {'last-connection': {'format': 'date-time', - 'type': 'string'}, - 'model': {'$ref': '#/definitions/Model'}}, - 'required': ['model', 'last-connection'], - 'type': 'object'}, - 'UserModelList': {'additionalProperties': False, - 'properties': {'user-models': {'items': {'$ref': '#/definitions/UserModel'}, - 'type': 'array'}}, - 'required': ['user-models'], - 'type': 'object'}}, - 'properties': {'ChangeModelCredential': {'description': 'ChangeModelCredential ' - 'changes cloud ' - 'credential reference ' - 'for models.\n' - 'These new cloud ' - 'credentials must ' - 'already exist on the ' - 'controller.', - 'properties': {'Params': {'$ref': '#/definitions/ChangeModelCredentialsParams'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'CreateModel': {'description': 'CreateModel creates a new ' - 'model using the account and\n' - 'model config specified in the ' - 'args.', - 'properties': {'Params': {'$ref': '#/definitions/ModelCreateArgs'}, - 'Result': {'$ref': '#/definitions/ModelInfo'}}, - 'type': 'object'}, - 'DestroyModels': {'description': 'DestroyModels will try to ' - 'destroy the specified ' - 'models.\n' - 'If there is a block on ' - 'destruction, this method ' - 'will return an error.\n' - 'From ModelManager v7 ' - 'onwards, DestroyModels gains ' - "'force' and 'max-wait' " - 'parameters.', - 'properties': {'Params': {'$ref': '#/definitions/DestroyModelsParams'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'DumpModels': {'description': 'DumpModels will export the ' - 'models into the database ' - 'agnostic\n' - 'representation. The user needs ' - 'to either be a controller ' - 'admin, or have\n' - 'admin privileges on the model ' - 'itself.', - 'properties': {'Params': {'$ref': '#/definitions/DumpModelRequest'}, - 'Result': {'$ref': '#/definitions/StringResults'}}, - 'type': 'object'}, - 'DumpModelsDB': {'description': 'DumpModelsDB will gather all ' - 'documents from all model ' - 'collections\n' - 'for the specified model. The ' - 'map result contains a map of ' - 'collection\n' - 'names to lists of documents ' - 'represented as maps.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/MapResults'}}, - 'type': 'object'}, - 'ListModelSummaries': {'description': 'ListModelSummaries ' - 'returns models that the ' - 'specified user\n' - 'has access to in the ' - 'current server. ' - 'Controller admins ' - '(superuser)\n' - 'can list models for any ' - 'user. Other users\n' - 'can only ask about ' - 'their own models.', - 'properties': {'Params': {'$ref': '#/definitions/ModelSummariesRequest'}, - 'Result': {'$ref': '#/definitions/ModelSummaryResults'}}, - 'type': 'object'}, - 'ListModels': {'description': 'ListModels returns the models ' - 'that the specified user\n' - 'has access to in the current ' - 'server. Controller admins ' - '(superuser)\n' - 'can list models for any user. ' - 'Other users\n' - 'can only ask about their own ' - 'models.', - 'properties': {'Params': {'$ref': '#/definitions/Entity'}, - 'Result': {'$ref': '#/definitions/UserModelList'}}, - 'type': 'object'}, - 'ModelDefaultsForClouds': {'description': 'ModelDefaultsForClouds ' - 'returns the default ' - 'config values for ' - 'the specified\n' - 'clouds.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ModelDefaultsResults'}}, - 'type': 'object'}, - 'ModelInfo': {'description': 'ModelInfo returns information ' - 'about the specified models.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ModelInfoResults'}}, - 'type': 'object'}, - 'ModelStatus': {'description': 'ModelStatus returns a summary ' - 'of the model.', - 'properties': {'Params': {'$ref': '#/definitions/Entities'}, - 'Result': {'$ref': '#/definitions/ModelStatusResults'}}, - 'type': 'object'}, - 'ModifyModelAccess': {'description': 'ModifyModelAccess ' - 'changes the model access ' - 'granted to users.', - 'properties': {'Params': {'$ref': '#/definitions/ModifyModelAccessRequest'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'SetModelDefaults': {'description': 'SetModelDefaults writes ' - 'new values for the ' - 'specified default model ' - 'settings.', - 'properties': {'Params': {'$ref': '#/definitions/SetModelDefaults'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}, - 'UnsetModelDefaults': {'description': 'UnsetModelDefaults ' - 'removes the specified ' - 'default model settings.', - 'properties': {'Params': {'$ref': '#/definitions/UnsetModelDefaults'}, - 'Result': {'$ref': '#/definitions/ErrorResults'}}, - 'type': 'object'}}, - 'type': 'object'} - + schema = { + "definitions": { + "ChangeModelCredentialParams": { + "additionalProperties": False, + "properties": { + "credential-tag": {"type": "string"}, + "model-tag": {"type": "string"}, + }, + "required": ["model-tag", "credential-tag"], + "type": "object", + }, + "ChangeModelCredentialsParams": { + "additionalProperties": False, + "properties": { + "model-credentials": { + "items": {"$ref": "#/definitions/ChangeModelCredentialParams"}, + "type": "array", + } + }, + "required": ["model-credentials"], + "type": "object", + }, + "DestroyModelParams": { + "additionalProperties": False, + "properties": { + "destroy-storage": {"type": "boolean"}, + "force": {"type": "boolean"}, + "max-wait": {"type": "integer"}, + "model-tag": {"type": "string"}, + "timeout": {"type": "integer"}, + }, + "required": ["model-tag"], + "type": "object", + }, + "DestroyModelsParams": { + "additionalProperties": False, + "properties": { + "models": { + "items": {"$ref": "#/definitions/DestroyModelParams"}, + "type": "array", + } + }, + "required": ["models"], + "type": "object", + }, + "DumpModelRequest": { + "additionalProperties": False, + "properties": { + "entities": { + "items": {"$ref": "#/definitions/Entity"}, + "type": "array", + }, + "simplified": {"type": "boolean"}, + }, + "required": ["entities", "simplified"], + "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", + }, + "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": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "message": {"type": "string"}, + }, + "required": ["message", "code"], + "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", + }, + "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"}, + "virt-type": {"type": "string"}, + }, + "type": "object", + }, + "MapResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + }, + "required": ["result"], + "type": "object", + }, + "MapResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/MapResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "Model": { + "additionalProperties": False, + "properties": { + "name": {"type": "string"}, + "owner-tag": {"type": "string"}, + "type": {"type": "string"}, + "uuid": {"type": "string"}, + }, + "required": ["name", "uuid", "type", "owner-tag"], + "type": "object", + }, + "ModelApplicationInfo": { + "additionalProperties": False, + "properties": {"name": {"type": "string"}}, + "required": ["name"], + "type": "object", + }, + "ModelCreateArgs": { + "additionalProperties": False, + "properties": { + "cloud-tag": {"type": "string"}, + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "credential": {"type": "string"}, + "name": {"type": "string"}, + "owner-tag": {"type": "string"}, + "region": {"type": "string"}, + }, + "required": ["name", "owner-tag"], + "type": "object", + }, + "ModelDefaultValues": { + "additionalProperties": False, + "properties": { + "cloud-region": {"type": "string"}, + "cloud-tag": {"type": "string"}, + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + }, + "required": ["config"], + "type": "object", + }, + "ModelDefaults": { + "additionalProperties": False, + "properties": { + "controller": {"additionalProperties": True, "type": "object"}, + "default": {"additionalProperties": True, "type": "object"}, + "regions": { + "items": {"$ref": "#/definitions/RegionDefaults"}, + "type": "array", + }, + }, + "type": "object", + }, + "ModelDefaultsResult": { + "additionalProperties": False, + "properties": { + "config": { + "patternProperties": { + ".*": {"$ref": "#/definitions/ModelDefaults"} + }, + "type": "object", + }, + "error": {"$ref": "#/definitions/Error"}, + }, + "required": ["config"], + "type": "object", + }, + "ModelDefaultsResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ModelDefaultsResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "ModelEntityCount": { + "additionalProperties": False, + "properties": { + "count": {"type": "integer"}, + "entity": {"type": "string"}, + }, + "required": ["entity", "count"], + "type": "object", + }, + "ModelFilesystemInfo": { + "additionalProperties": False, + "properties": { + "detachable": {"type": "boolean"}, + "id": {"type": "string"}, + "message": {"type": "string"}, + "provider-id": {"type": "string"}, + "status": {"type": "string"}, + }, + "required": ["id"], + "type": "object", + }, + "ModelInfo": { + "additionalProperties": False, + "properties": { + "agent-version": {"$ref": "#/definitions/Number"}, + "cloud-credential-tag": {"type": "string"}, + "cloud-credential-validity": {"type": "boolean"}, + "cloud-region": {"type": "string"}, + "cloud-tag": {"type": "string"}, + "controller-uuid": {"type": "string"}, + "default-base": {"type": "string"}, + "default-series": {"type": "string"}, + "is-controller": {"type": "boolean"}, + "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"}, + "secret-backends": { + "items": {"$ref": "#/definitions/SecretBackendResult"}, + "type": "array", + }, + "sla": {"$ref": "#/definitions/ModelSLAInfo"}, + "status": {"$ref": "#/definitions/EntityStatus"}, + "supported-features": { + "items": {"$ref": "#/definitions/SupportedFeature"}, + "type": "array", + }, + "type": {"type": "string"}, + "users": { + "items": {"$ref": "#/definitions/ModelUserInfo"}, + "type": "array", + }, + "uuid": {"type": "string"}, + }, + "required": [ + "name", + "type", + "uuid", + "controller-uuid", + "is-controller", + "cloud-tag", + "owner-tag", + "life", + "users", + "machines", + "secret-backends", + "sla", + "agent-version", + ], + "type": "object", + }, + "ModelInfoResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/ModelInfo"}, + }, + "type": "object", + }, + "ModelInfoResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ModelInfoResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "ModelMachineInfo": { + "additionalProperties": False, + "properties": { + "display-name": {"type": "string"}, + "ha-primary": {"type": "boolean"}, + "hardware": {"$ref": "#/definitions/MachineHardware"}, + "has-vote": {"type": "boolean"}, + "id": {"type": "string"}, + "instance-id": {"type": "string"}, + "message": {"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", + }, + "ModelSLAInfo": { + "additionalProperties": False, + "properties": { + "level": {"type": "string"}, + "owner": {"type": "string"}, + }, + "required": ["level", "owner"], + "type": "object", + }, + "ModelStatus": { + "additionalProperties": False, + "properties": { + "application-count": {"type": "integer"}, + "applications": { + "items": {"$ref": "#/definitions/ModelApplicationInfo"}, + "type": "array", + }, + "error": {"$ref": "#/definitions/Error"}, + "filesystems": { + "items": {"$ref": "#/definitions/ModelFilesystemInfo"}, + "type": "array", + }, + "hosted-machine-count": {"type": "integer"}, + "life": {"type": "string"}, + "machines": { + "items": {"$ref": "#/definitions/ModelMachineInfo"}, + "type": "array", + }, + "model-tag": {"type": "string"}, + "owner-tag": {"type": "string"}, + "type": {"type": "string"}, + "unit-count": {"type": "integer"}, + "volumes": { + "items": {"$ref": "#/definitions/ModelVolumeInfo"}, + "type": "array", + }, + }, + "required": [ + "model-tag", + "life", + "type", + "hosted-machine-count", + "application-count", + "unit-count", + "owner-tag", + ], + "type": "object", + }, + "ModelStatusResults": { + "additionalProperties": False, + "properties": { + "models": { + "items": {"$ref": "#/definitions/ModelStatus"}, + "type": "array", + } + }, + "required": ["models"], + "type": "object", + }, + "ModelSummariesRequest": { + "additionalProperties": False, + "properties": { + "all": {"type": "boolean"}, + "user-tag": {"type": "string"}, + }, + "required": ["user-tag"], + "type": "object", + }, + "ModelSummary": { + "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"}, + "counts": { + "items": {"$ref": "#/definitions/ModelEntityCount"}, + "type": "array", + }, + "default-series": {"type": "string"}, + "is-controller": {"type": "boolean"}, + "last-connection": {"format": "date-time", "type": "string"}, + "life": {"type": "string"}, + "migration": {"$ref": "#/definitions/ModelMigrationStatus"}, + "name": {"type": "string"}, + "owner-tag": {"type": "string"}, + "provider-type": {"type": "string"}, + "sla": {"$ref": "#/definitions/ModelSLAInfo"}, + "status": {"$ref": "#/definitions/EntityStatus"}, + "type": {"type": "string"}, + "user-access": {"type": "string"}, + "uuid": {"type": "string"}, + }, + "required": [ + "name", + "uuid", + "type", + "controller-uuid", + "is-controller", + "cloud-tag", + "owner-tag", + "life", + "user-access", + "last-connection", + "counts", + "sla", + "agent-version", + ], + "type": "object", + }, + "ModelSummaryResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"$ref": "#/definitions/ModelSummary"}, + }, + "type": "object", + }, + "ModelSummaryResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/ModelSummaryResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "ModelUnsetKeys": { + "additionalProperties": False, + "properties": { + "cloud-region": {"type": "string"}, + "cloud-tag": {"type": "string"}, + "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"}, + "model-tag": {"type": "string"}, + "user": {"type": "string"}, + }, + "required": [ + "model-tag", + "user", + "display-name", + "last-connection", + "access", + ], + "type": "object", + }, + "ModelVolumeInfo": { + "additionalProperties": False, + "properties": { + "detachable": {"type": "boolean"}, + "id": {"type": "string"}, + "message": {"type": "string"}, + "provider-id": {"type": "string"}, + "status": {"type": "string"}, + }, + "required": ["id"], + "type": "object", + }, + "ModifyModelAccess": { + "additionalProperties": False, + "properties": { + "access": {"type": "string"}, + "action": {"type": "string"}, + "model-tag": {"type": "string"}, + "user-tag": {"type": "string"}, + }, + "required": ["user-tag", "action", "access", "model-tag"], + "type": "object", + }, + "ModifyModelAccessRequest": { + "additionalProperties": False, + "properties": { + "changes": { + "items": {"$ref": "#/definitions/ModifyModelAccess"}, + "type": "array", + } + }, + "required": ["changes"], + "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", + }, + "RegionDefaults": { + "additionalProperties": False, + "properties": { + "region-name": {"type": "string"}, + "value": {"additionalProperties": True, "type": "object"}, + }, + "required": ["region-name", "value"], + "type": "object", + }, + "SecretBackend": { + "additionalProperties": False, + "properties": { + "backend-type": {"type": "string"}, + "config": { + "patternProperties": { + ".*": {"additionalProperties": True, "type": "object"} + }, + "type": "object", + }, + "name": {"type": "string"}, + "token-rotate-interval": {"type": "integer"}, + }, + "required": ["name", "backend-type", "config"], + "type": "object", + }, + "SecretBackendResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "id": {"type": "string"}, + "message": {"type": "string"}, + "num-secrets": {"type": "integer"}, + "result": {"$ref": "#/definitions/SecretBackend"}, + "status": {"type": "string"}, + }, + "required": ["result", "id", "num-secrets", "status"], + "type": "object", + }, + "SetModelDefaults": { + "additionalProperties": False, + "properties": { + "config": { + "items": {"$ref": "#/definitions/ModelDefaultValues"}, + "type": "array", + } + }, + "required": ["config"], + "type": "object", + }, + "StringResult": { + "additionalProperties": False, + "properties": { + "error": {"$ref": "#/definitions/Error"}, + "result": {"type": "string"}, + }, + "required": ["result"], + "type": "object", + }, + "StringResults": { + "additionalProperties": False, + "properties": { + "results": { + "items": {"$ref": "#/definitions/StringResult"}, + "type": "array", + } + }, + "required": ["results"], + "type": "object", + }, + "SupportedFeature": { + "additionalProperties": False, + "properties": { + "description": {"type": "string"}, + "name": {"type": "string"}, + "version": {"type": "string"}, + }, + "required": ["name", "description"], + "type": "object", + }, + "UnsetModelDefaults": { + "additionalProperties": False, + "properties": { + "keys": { + "items": {"$ref": "#/definitions/ModelUnsetKeys"}, + "type": "array", + } + }, + "required": ["keys"], + "type": "object", + }, + "UserModel": { + "additionalProperties": False, + "properties": { + "last-connection": {"format": "date-time", "type": "string"}, + "model": {"$ref": "#/definitions/Model"}, + }, + "required": ["model", "last-connection"], + "type": "object", + }, + "UserModelList": { + "additionalProperties": False, + "properties": { + "user-models": { + "items": {"$ref": "#/definitions/UserModel"}, + "type": "array", + } + }, + "required": ["user-models"], + "type": "object", + }, + }, + "properties": { + "ChangeModelCredential": { + "description": "ChangeModelCredential " + "changes cloud " + "credential reference " + "for models.\n" + "These new cloud " + "credentials must " + "already exist on the " + "controller.", + "properties": { + "Params": {"$ref": "#/definitions/ChangeModelCredentialsParams"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "CreateModel": { + "description": "CreateModel creates a new " + "model using the account and\n" + "model config specified in the " + "args.", + "properties": { + "Params": {"$ref": "#/definitions/ModelCreateArgs"}, + "Result": {"$ref": "#/definitions/ModelInfo"}, + }, + "type": "object", + }, + "DestroyModels": { + "description": "DestroyModels will try to " + "destroy the specified " + "models.\n" + "If there is a block on " + "destruction, this method " + "will return an error.\n" + "From ModelManager v7 " + "onwards, DestroyModels gains " + "'force' and 'max-wait' " + "parameters.", + "properties": { + "Params": {"$ref": "#/definitions/DestroyModelsParams"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "DumpModels": { + "description": "DumpModels will export the " + "models into the database " + "agnostic\n" + "representation. The user needs " + "to either be a controller " + "admin, or have\n" + "admin privileges on the model " + "itself.", + "properties": { + "Params": {"$ref": "#/definitions/DumpModelRequest"}, + "Result": {"$ref": "#/definitions/StringResults"}, + }, + "type": "object", + }, + "DumpModelsDB": { + "description": "DumpModelsDB will gather all " + "documents from all model " + "collections\n" + "for the specified model. The " + "map result contains a map of " + "collection\n" + "names to lists of documents " + "represented as maps.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/MapResults"}, + }, + "type": "object", + }, + "ListModelSummaries": { + "description": "ListModelSummaries " + "returns models that the " + "specified user\n" + "has access to in the " + "current server. " + "Controller admins " + "(superuser)\n" + "can list models for any " + "user. Other users\n" + "can only ask about " + "their own models.", + "properties": { + "Params": {"$ref": "#/definitions/ModelSummariesRequest"}, + "Result": {"$ref": "#/definitions/ModelSummaryResults"}, + }, + "type": "object", + }, + "ListModels": { + "description": "ListModels returns the models " + "that the specified user\n" + "has access to in the current " + "server. Controller admins " + "(superuser)\n" + "can list models for any user. " + "Other users\n" + "can only ask about their own " + "models.", + "properties": { + "Params": {"$ref": "#/definitions/Entity"}, + "Result": {"$ref": "#/definitions/UserModelList"}, + }, + "type": "object", + }, + "ModelDefaultsForClouds": { + "description": "ModelDefaultsForClouds " + "returns the default " + "config values for " + "the specified\n" + "clouds.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/ModelDefaultsResults"}, + }, + "type": "object", + }, + "ModelInfo": { + "description": "ModelInfo returns information " + "about the specified models.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/ModelInfoResults"}, + }, + "type": "object", + }, + "ModelStatus": { + "description": "ModelStatus returns a summary of the model.", + "properties": { + "Params": {"$ref": "#/definitions/Entities"}, + "Result": {"$ref": "#/definitions/ModelStatusResults"}, + }, + "type": "object", + }, + "ModifyModelAccess": { + "description": "ModifyModelAccess " + "changes the model access " + "granted to users.", + "properties": { + "Params": {"$ref": "#/definitions/ModifyModelAccessRequest"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "SetModelDefaults": { + "description": "SetModelDefaults writes " + "new values for the " + "specified default model " + "settings.", + "properties": { + "Params": {"$ref": "#/definitions/SetModelDefaults"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + "UnsetModelDefaults": { + "description": "UnsetModelDefaults " + "removes the specified " + "default model settings.", + "properties": { + "Params": {"$ref": "#/definitions/UnsetModelDefaults"}, + "Result": {"$ref": "#/definitions/ErrorResults"}, + }, + "type": "object", + }, + }, + "type": "object", + } @ReturnMapping(ErrorResults) async def ChangeModelCredential(self, model_credentials=None): - ''' + """ ChangeModelCredential changes cloud credential reference for models. These new cloud credentials must already exist on the controller. model_credentials : typing.Sequence[~ChangeModelCredentialParams] Returns -> ErrorResults - ''' - if model_credentials is not None and not isinstance(model_credentials, (bytes, str, list)): - raise Exception("Expected model_credentials to be a Sequence, received: {}".format(type(model_credentials))) + """ + if model_credentials is not None and not isinstance( + model_credentials, (bytes, str, list) + ): + raise Exception( + "Expected model_credentials to be a Sequence, received: {}".format( + type(model_credentials) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='ChangeModelCredential', - version=9, - params=_params) - _params['model-credentials'] = model_credentials + msg = dict( + type="ModelManager", + request="ChangeModelCredential", + version=9, + params=_params, + ) + _params["model-credentials"] = model_credentials reply = await self.rpc(msg) return reply - - @ReturnMapping(ModelInfo) - async def CreateModel(self, cloud_tag=None, config=None, credential=None, name=None, owner_tag=None, region=None): - ''' + async def CreateModel( + self, + cloud_tag=None, + config=None, + credential=None, + name=None, + owner_tag=None, + region=None, + ): + """ CreateModel creates a new model using the account and model config specified in the args. @@ -590,70 +914,78 @@ async def CreateModel(self, cloud_tag=None, config=None, credential=None, name=N owner_tag : str region : str Returns -> ModelInfo - ''' + """ if cloud_tag is not None and not isinstance(cloud_tag, (bytes, str)): - raise Exception("Expected cloud_tag to be a str, received: {}".format(type(cloud_tag))) + raise Exception( + "Expected cloud_tag to be a str, received: {}".format(type(cloud_tag)) + ) if config is not None and not isinstance(config, dict): - raise Exception("Expected config to be a Mapping, received: {}".format(type(config))) + raise Exception( + "Expected config to be a Mapping, received: {}".format(type(config)) + ) if credential is not None and not isinstance(credential, (bytes, str)): - raise Exception("Expected credential to be a str, received: {}".format(type(credential))) + raise Exception( + "Expected credential to be a str, received: {}".format(type(credential)) + ) if name is not None and not isinstance(name, (bytes, str)): - raise Exception("Expected name to be a str, received: {}".format(type(name))) + raise Exception( + "Expected name to be a str, received: {}".format(type(name)) + ) if owner_tag is not None and not isinstance(owner_tag, (bytes, str)): - raise Exception("Expected owner_tag to be a str, received: {}".format(type(owner_tag))) + raise Exception( + "Expected owner_tag to be a str, received: {}".format(type(owner_tag)) + ) if region is not None and not isinstance(region, (bytes, str)): - raise Exception("Expected region to be a str, received: {}".format(type(region))) + raise Exception( + "Expected region to be a str, received: {}".format(type(region)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='CreateModel', - version=9, - params=_params) - _params['cloud-tag'] = cloud_tag - _params['config'] = config - _params['credential'] = credential - _params['name'] = name - _params['owner-tag'] = owner_tag - _params['region'] = region + msg = dict( + type="ModelManager", request="CreateModel", version=9, params=_params + ) + _params["cloud-tag"] = cloud_tag + _params["config"] = config + _params["credential"] = credential + _params["name"] = name + _params["owner-tag"] = owner_tag + _params["region"] = region reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def DestroyModels(self, models=None): - ''' + """ DestroyModels will try to destroy the specified models. If there is a block on destruction, this method will return an error. From ModelManager v7 onwards, DestroyModels gains 'force' and 'max-wait' parameters. models : typing.Sequence[~DestroyModelParams] Returns -> ErrorResults - ''' + """ if models is not None and not isinstance(models, (bytes, str, list)): - raise Exception("Expected models to be a Sequence, received: {}".format(type(models))) + raise Exception( + "Expected models to be a Sequence, received: {}".format(type(models)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='DestroyModels', - version=9, - params=_params) - _params['models'] = models + msg = dict( + type="ModelManager", request="DestroyModels", version=9, params=_params + ) + _params["models"] = models reply = await self.rpc(msg) return reply - - @ReturnMapping(StringResults) async def DumpModels(self, entities=None, simplified=None): - ''' + """ DumpModels will export the models into the database agnostic representation. The user needs to either be a controller admin, or have admin privileges on the model itself. @@ -661,54 +993,58 @@ async def DumpModels(self, entities=None, simplified=None): entities : typing.Sequence[~Entity] simplified : bool Returns -> StringResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) if simplified is not None and not isinstance(simplified, bool): - raise Exception("Expected simplified to be a bool, received: {}".format(type(simplified))) + raise Exception( + "Expected simplified to be a bool, received: {}".format( + type(simplified) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='DumpModels', - version=9, - params=_params) - _params['entities'] = entities - _params['simplified'] = simplified + msg = dict(type="ModelManager", request="DumpModels", version=9, params=_params) + _params["entities"] = entities + _params["simplified"] = simplified reply = await self.rpc(msg) return reply - - @ReturnMapping(MapResults) async def DumpModelsDB(self, entities=None): - ''' + """ DumpModelsDB will gather all documents from all model collections for the specified model. The map result contains a map of collection names to lists of documents represented as maps. entities : typing.Sequence[~Entity] Returns -> MapResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='DumpModelsDB', - version=9, - params=_params) - _params['entities'] = entities + msg = dict( + type="ModelManager", request="DumpModelsDB", version=9, params=_params + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ModelSummaryResults) async def ListModelSummaries(self, all_=None, user_tag=None): - ''' + """ ListModelSummaries returns models that the specified user has access to in the current server. Controller admins (superuser) can list models for any user. Other users @@ -717,29 +1053,30 @@ async def ListModelSummaries(self, all_=None, user_tag=None): all_ : bool user_tag : str Returns -> ModelSummaryResults - ''' + """ if all_ is not None and not isinstance(all_, bool): - raise Exception("Expected all_ to be a bool, received: {}".format(type(all_))) + raise Exception( + "Expected all_ to be a bool, received: {}".format(type(all_)) + ) if user_tag is not None and not isinstance(user_tag, (bytes, str)): - raise Exception("Expected user_tag to be a str, received: {}".format(type(user_tag))) + raise Exception( + "Expected user_tag to be a str, received: {}".format(type(user_tag)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='ListModelSummaries', - version=9, - params=_params) - _params['all'] = all_ - _params['user-tag'] = user_tag + msg = dict( + type="ModelManager", request="ListModelSummaries", version=9, params=_params + ) + _params["all"] = all_ + _params["user-tag"] = user_tag reply = await self.rpc(msg) return reply - - @ReturnMapping(UserModelList) async def ListModels(self, tag=None): - ''' + """ ListModels returns the models that the specified user has access to in the current server. Controller admins (superuser) can list models for any user. Other users @@ -747,157 +1084,153 @@ async def ListModels(self, tag=None): tag : str Returns -> UserModelList - ''' + """ if tag is not None and not isinstance(tag, (bytes, str)): raise Exception("Expected tag to be a str, received: {}".format(type(tag))) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='ListModels', - version=9, - params=_params) - _params['tag'] = tag + msg = dict(type="ModelManager", request="ListModels", version=9, params=_params) + _params["tag"] = tag reply = await self.rpc(msg) return reply - - @ReturnMapping(ModelDefaultsResults) async def ModelDefaultsForClouds(self, entities=None): - ''' + """ ModelDefaultsForClouds returns the default config values for the specified clouds. entities : typing.Sequence[~Entity] Returns -> ModelDefaultsResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='ModelDefaultsForClouds', - version=9, - params=_params) - _params['entities'] = entities + msg = dict( + type="ModelManager", + request="ModelDefaultsForClouds", + version=9, + params=_params, + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ModelInfoResults) async def ModelInfo(self, entities=None): - ''' + """ ModelInfo returns information about the specified models. entities : typing.Sequence[~Entity] Returns -> ModelInfoResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='ModelInfo', - version=9, - params=_params) - _params['entities'] = entities + msg = dict(type="ModelManager", request="ModelInfo", version=9, params=_params) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ModelStatusResults) async def ModelStatus(self, entities=None): - ''' + """ ModelStatus returns a summary of the model. entities : typing.Sequence[~Entity] Returns -> ModelStatusResults - ''' + """ if entities is not None and not isinstance(entities, (bytes, str, list)): - raise Exception("Expected entities to be a Sequence, received: {}".format(type(entities))) + raise Exception( + "Expected entities to be a Sequence, received: {}".format( + type(entities) + ) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='ModelStatus', - version=9, - params=_params) - _params['entities'] = entities + msg = dict( + type="ModelManager", request="ModelStatus", version=9, params=_params + ) + _params["entities"] = entities reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def ModifyModelAccess(self, changes=None): - ''' + """ ModifyModelAccess changes the model access granted to users. changes : typing.Sequence[~ModifyModelAccess] Returns -> ErrorResults - ''' + """ if changes is not None and not isinstance(changes, (bytes, str, list)): - raise Exception("Expected changes to be a Sequence, received: {}".format(type(changes))) + raise Exception( + "Expected changes to be a Sequence, received: {}".format(type(changes)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='ModifyModelAccess', - version=9, - params=_params) - _params['changes'] = changes + msg = dict( + type="ModelManager", request="ModifyModelAccess", version=9, params=_params + ) + _params["changes"] = changes reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def SetModelDefaults(self, config=None): - ''' + """ SetModelDefaults writes new values for the specified default model settings. config : typing.Sequence[~ModelDefaultValues] Returns -> ErrorResults - ''' + """ if config is not None and not isinstance(config, (bytes, str, list)): - raise Exception("Expected config to be a Sequence, received: {}".format(type(config))) + raise Exception( + "Expected config to be a Sequence, received: {}".format(type(config)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='SetModelDefaults', - version=9, - params=_params) - _params['config'] = config + msg = dict( + type="ModelManager", request="SetModelDefaults", version=9, params=_params + ) + _params["config"] = config reply = await self.rpc(msg) return reply - - @ReturnMapping(ErrorResults) async def UnsetModelDefaults(self, keys=None): - ''' + """ UnsetModelDefaults removes the specified default model settings. keys : typing.Sequence[~ModelUnsetKeys] Returns -> ErrorResults - ''' + """ if keys is not None and not isinstance(keys, (bytes, str, list)): - raise Exception("Expected keys to be a Sequence, received: {}".format(type(keys))) + raise Exception( + "Expected keys to be a Sequence, received: {}".format(type(keys)) + ) # map input types to rpc msg _params = dict() - msg = dict(type='ModelManager', - request='UnsetModelDefaults', - version=9, - params=_params) - _params['keys'] = keys + msg = dict( + type="ModelManager", request="UnsetModelDefaults", version=9, params=_params + ) + _params["keys"] = keys reply = await self.rpc(msg) return reply - - diff --git a/juju/client/_definitions.py b/juju/client/_definitions.py index b89fa4f6e..a6df91afb 100644 --- a/juju/client/_definitions.py +++ b/juju/client/_definitions.py @@ -5,27 +5,36 @@ class AccessInfo(Type): - _toSchema = {'role': 'role', 'scope_tag': 'scope-tag', 'target_tag': 'target-tag'} - _toPy = {'role': 'role', 'scope-tag': 'scope_tag', 'target-tag': 'target_tag'} + _toSchema = {"role": "role", "scope_tag": "scope-tag", "target_tag": "target-tag"} + _toPy = {"role": "role", "scope-tag": "scope_tag", "target-tag": "target_tag"} + def __init__(self, role=None, scope_tag=None, target_tag=None, **unknown_fields): - ''' + """ role : str scope_tag : str target_tag : str - ''' + """ role_ = role scope_tag_ = scope_tag target_tag_ = target_tag # Validate arguments against known Juju API types. if role_ is not None and not isinstance(role_, (bytes, str)): - raise Exception("Expected role_ to be a str, received: {}".format(type(role_))) + raise Exception( + "Expected role_ to be a str, received: {}".format(type(role_)) + ) if scope_tag_ is not None and not isinstance(scope_tag_, (bytes, str)): - raise Exception("Expected scope_tag_ to be a str, received: {}".format(type(scope_tag_))) + raise Exception( + "Expected scope_tag_ to be a str, received: {}".format(type(scope_tag_)) + ) if target_tag_ is not None and not isinstance(target_tag_, (bytes, str)): - raise Exception("Expected target_tag_ to be a str, received: {}".format(type(target_tag_))) + raise Exception( + "Expected target_tag_ to be a str, received: {}".format( + type(target_tag_) + ) + ) self.role = role_ self.scope_tag = scope_tag_ @@ -33,19 +42,42 @@ def __init__(self, role=None, scope_tag=None, target_tag=None, **unknown_fields) self.unknown_fields = unknown_fields - class Action(Type): - _toSchema = {'execution_group': 'execution-group', 'name': 'name', 'parallel': 'parallel', 'parameters': 'parameters', 'receiver': 'receiver', 'tag': 'tag'} - _toPy = {'execution-group': 'execution_group', 'name': 'name', 'parallel': 'parallel', 'parameters': 'parameters', 'receiver': 'receiver', 'tag': 'tag'} - def __init__(self, execution_group=None, name=None, parallel=None, parameters=None, receiver=None, tag=None, **unknown_fields): - ''' + _toSchema = { + "execution_group": "execution-group", + "name": "name", + "parallel": "parallel", + "parameters": "parameters", + "receiver": "receiver", + "tag": "tag", + } + _toPy = { + "execution-group": "execution_group", + "name": "name", + "parallel": "parallel", + "parameters": "parameters", + "receiver": "receiver", + "tag": "tag", + } + + def __init__( + self, + execution_group=None, + name=None, + parallel=None, + parameters=None, + receiver=None, + tag=None, + **unknown_fields, + ): + """ execution_group : str name : str parallel : bool parameters : typing.Mapping[str, typing.Any] receiver : str tag : str - ''' + """ execution_group_ = execution_group name_ = name parallel_ = parallel @@ -54,23 +86,41 @@ def __init__(self, execution_group=None, name=None, parallel=None, parameters=No tag_ = tag # Validate arguments against known Juju API types. - if execution_group_ is not None and not isinstance(execution_group_, (bytes, str)): - raise Exception("Expected execution_group_ to be a str, received: {}".format(type(execution_group_))) + if execution_group_ is not None and not isinstance( + execution_group_, (bytes, str) + ): + raise Exception( + "Expected execution_group_ to be a str, received: {}".format( + type(execution_group_) + ) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if parallel_ is not None and not isinstance(parallel_, bool): - raise Exception("Expected parallel_ to be a bool, received: {}".format(type(parallel_))) + raise Exception( + "Expected parallel_ to be a bool, received: {}".format(type(parallel_)) + ) if parameters_ is not None and not isinstance(parameters_, dict): - raise Exception("Expected parameters_ to be a Mapping, received: {}".format(type(parameters_))) + raise Exception( + "Expected parameters_ to be a Mapping, received: {}".format( + type(parameters_) + ) + ) if receiver_ is not None and not isinstance(receiver_, (bytes, str)): - raise Exception("Expected receiver_ to be a str, received: {}".format(type(receiver_))) + raise Exception( + "Expected receiver_ to be a str, received: {}".format(type(receiver_)) + ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception("Expected tag_ to be a str, received: {}".format(type(tag_))) + raise Exception( + "Expected tag_ to be a str, received: {}".format(type(tag_)) + ) self.execution_group = execution_group_ self.name = name_ @@ -81,36 +131,72 @@ def __init__(self, execution_group=None, name=None, parallel=None, parameters=No self.unknown_fields = unknown_fields - class ActionMessage(Type): - _toSchema = {'message': 'message', 'timestamp': 'timestamp'} - _toPy = {'message': 'message', 'timestamp': 'timestamp'} + _toSchema = {"message": "message", "timestamp": "timestamp"} + _toPy = {"message": "message", "timestamp": "timestamp"} + def __init__(self, message=None, timestamp=None, **unknown_fields): - ''' + """ message : str timestamp : str - ''' + """ message_ = message timestamp_ = timestamp # Validate arguments against known Juju API types. if message_ is not None and not isinstance(message_, (bytes, str)): - raise Exception("Expected message_ to be a str, received: {}".format(type(message_))) + raise Exception( + "Expected message_ to be a str, received: {}".format(type(message_)) + ) if timestamp_ is not None and not isinstance(timestamp_, (bytes, str)): - raise Exception("Expected timestamp_ to be a str, received: {}".format(type(timestamp_))) + raise Exception( + "Expected timestamp_ to be a str, received: {}".format(type(timestamp_)) + ) self.message = message_ self.timestamp = timestamp_ self.unknown_fields = unknown_fields - class ActionResult(Type): - _toSchema = {'action': 'action', 'completed': 'completed', 'enqueued': 'enqueued', 'error': 'error', 'log': 'log', 'message': 'message', 'output': 'output', 'started': 'started', 'status': 'status'} - _toPy = {'action': 'action', 'completed': 'completed', 'enqueued': 'enqueued', 'error': 'error', 'log': 'log', 'message': 'message', 'output': 'output', 'started': 'started', 'status': 'status'} - def __init__(self, action=None, completed=None, enqueued=None, error=None, log=None, message=None, output=None, started=None, status=None, **unknown_fields): - ''' + _toSchema = { + "action": "action", + "completed": "completed", + "enqueued": "enqueued", + "error": "error", + "log": "log", + "message": "message", + "output": "output", + "started": "started", + "status": "status", + } + _toPy = { + "action": "action", + "completed": "completed", + "enqueued": "enqueued", + "error": "error", + "log": "log", + "message": "message", + "output": "output", + "started": "started", + "status": "status", + } + + def __init__( + self, + action=None, + completed=None, + enqueued=None, + error=None, + log=None, + message=None, + output=None, + started=None, + status=None, + **unknown_fields, + ): + """ action : Action completed : str enqueued : str @@ -120,7 +206,7 @@ def __init__(self, action=None, completed=None, enqueued=None, error=None, log=N output : typing.Mapping[str, typing.Any] started : str status : str - ''' + """ action_ = Action.from_json(action) if action else None completed_ = completed enqueued_ = enqueued @@ -133,31 +219,49 @@ def __init__(self, action=None, completed=None, enqueued=None, error=None, log=N # Validate arguments against known Juju API types. if action_ is not None and not isinstance(action_, (dict, Action)): - raise Exception("Expected action_ to be a Action, received: {}".format(type(action_))) + raise Exception( + "Expected action_ to be a Action, received: {}".format(type(action_)) + ) if completed_ is not None and not isinstance(completed_, (bytes, str)): - raise Exception("Expected completed_ to be a str, received: {}".format(type(completed_))) + raise Exception( + "Expected completed_ to be a str, received: {}".format(type(completed_)) + ) if enqueued_ is not None and not isinstance(enqueued_, (bytes, str)): - raise Exception("Expected enqueued_ to be a str, received: {}".format(type(enqueued_))) + raise Exception( + "Expected enqueued_ to be a str, received: {}".format(type(enqueued_)) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if log_ is not None and not isinstance(log_, (bytes, str, list)): - raise Exception("Expected log_ to be a Sequence, received: {}".format(type(log_))) + raise Exception( + "Expected log_ to be a Sequence, received: {}".format(type(log_)) + ) if message_ is not None and not isinstance(message_, (bytes, str)): - raise Exception("Expected message_ to be a str, received: {}".format(type(message_))) + raise Exception( + "Expected message_ to be a str, received: {}".format(type(message_)) + ) if output_ is not None and not isinstance(output_, dict): - raise Exception("Expected output_ to be a Mapping, received: {}".format(type(output_))) + raise Exception( + "Expected output_ to be a Mapping, received: {}".format(type(output_)) + ) if started_ is not None and not isinstance(started_, (bytes, str)): - raise Exception("Expected started_ to be a str, received: {}".format(type(started_))) + raise Exception( + "Expected started_ to be a str, received: {}".format(type(started_)) + ) if status_ is not None and not isinstance(status_, (bytes, str)): - raise Exception("Expected status_ to be a str, received: {}".format(type(status_))) + raise Exception( + "Expected status_ to be a str, received: {}".format(type(status_)) + ) self.action = action_ self.completed = completed_ @@ -171,79 +275,116 @@ def __init__(self, action=None, completed=None, enqueued=None, error=None, log=N self.unknown_fields = unknown_fields - class ActionResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~ActionResult] - ''' + """ results_ = [ActionResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class ActionSpec(Type): - _toSchema = {'description': 'description', 'params': 'params'} - _toPy = {'description': 'description', 'params': 'params'} + _toSchema = {"description": "description", "params": "params"} + _toPy = {"description": "description", "params": "params"} + def __init__(self, description=None, params=None, **unknown_fields): - ''' + """ description : str params : typing.Mapping[str, typing.Any] - ''' + """ description_ = description params_ = params # Validate arguments against known Juju API types. if description_ is not None and not isinstance(description_, (bytes, str)): - raise Exception("Expected description_ to be a str, received: {}".format(type(description_))) + raise Exception( + "Expected description_ to be a str, received: {}".format( + type(description_) + ) + ) if params_ is not None and not isinstance(params_, dict): - raise Exception("Expected params_ to be a Mapping, received: {}".format(type(params_))) + raise Exception( + "Expected params_ to be a Mapping, received: {}".format(type(params_)) + ) self.description = description_ self.params = params_ self.unknown_fields = unknown_fields - class Actions(Type): - _toSchema = {'actions': 'actions'} - _toPy = {'actions': 'actions'} + _toSchema = {"actions": "actions"} + _toPy = {"actions": "actions"} + def __init__(self, actions=None, **unknown_fields): - ''' + """ actions : typing.Sequence[~Action] - ''' + """ actions_ = [Action.from_json(o) for o in actions or []] # Validate arguments against known Juju API types. if actions_ is not None and not isinstance(actions_, (bytes, str, list)): - raise Exception("Expected actions_ to be a Sequence, received: {}".format(type(actions_))) + raise Exception( + "Expected actions_ to be a Sequence, received: {}".format( + type(actions_) + ) + ) self.actions = actions_ self.unknown_fields = unknown_fields - class AddApplicationOffer(Type): - _toSchema = {'application_description': 'application-description', 'application_name': 'application-name', 'endpoints': 'endpoints', 'model_tag': 'model-tag', 'offer_name': 'offer-name', 'owner_tag': 'owner-tag'} - _toPy = {'application-description': 'application_description', 'application-name': 'application_name', 'endpoints': 'endpoints', 'model-tag': 'model_tag', 'offer-name': 'offer_name', 'owner-tag': 'owner_tag'} - def __init__(self, application_description=None, application_name=None, endpoints=None, model_tag=None, offer_name=None, owner_tag=None, **unknown_fields): - ''' + _toSchema = { + "application_description": "application-description", + "application_name": "application-name", + "endpoints": "endpoints", + "model_tag": "model-tag", + "offer_name": "offer-name", + "owner_tag": "owner-tag", + } + _toPy = { + "application-description": "application_description", + "application-name": "application_name", + "endpoints": "endpoints", + "model-tag": "model_tag", + "offer-name": "offer_name", + "owner-tag": "owner_tag", + } + + def __init__( + self, + application_description=None, + application_name=None, + endpoints=None, + model_tag=None, + offer_name=None, + owner_tag=None, + **unknown_fields, + ): + """ application_description : str application_name : str endpoints : typing.Mapping[str, str] model_tag : str offer_name : str owner_tag : str - ''' + """ application_description_ = application_description application_name_ = application_name endpoints_ = endpoints @@ -252,23 +393,47 @@ def __init__(self, application_description=None, application_name=None, endpoint owner_tag_ = owner_tag # Validate arguments against known Juju API types. - if application_description_ is not None and not isinstance(application_description_, (bytes, str)): - raise Exception("Expected application_description_ to be a str, received: {}".format(type(application_description_))) - - if application_name_ is not None and not isinstance(application_name_, (bytes, str)): - raise Exception("Expected application_name_ to be a str, received: {}".format(type(application_name_))) + if application_description_ is not None and not isinstance( + application_description_, (bytes, str) + ): + raise Exception( + "Expected application_description_ to be a str, received: {}".format( + type(application_description_) + ) + ) + + if application_name_ is not None and not isinstance( + application_name_, (bytes, str) + ): + raise Exception( + "Expected application_name_ to be a str, received: {}".format( + type(application_name_) + ) + ) if endpoints_ is not None and not isinstance(endpoints_, dict): - raise Exception("Expected endpoints_ to be a Mapping, received: {}".format(type(endpoints_))) + raise Exception( + "Expected endpoints_ to be a Mapping, received: {}".format( + type(endpoints_) + ) + ) if model_tag_ is not None and not isinstance(model_tag_, (bytes, str)): - raise Exception("Expected model_tag_ to be a str, received: {}".format(type(model_tag_))) + raise Exception( + "Expected model_tag_ to be a str, received: {}".format(type(model_tag_)) + ) if offer_name_ is not None and not isinstance(offer_name_, (bytes, str)): - raise Exception("Expected offer_name_ to be a str, received: {}".format(type(offer_name_))) + raise Exception( + "Expected offer_name_ to be a str, received: {}".format( + type(offer_name_) + ) + ) if owner_tag_ is not None and not isinstance(owner_tag_, (bytes, str)): - raise Exception("Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_))) + raise Exception( + "Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_)) + ) self.application_description = application_description_ self.application_name = application_name_ @@ -279,36 +444,58 @@ def __init__(self, application_description=None, application_name=None, endpoint self.unknown_fields = unknown_fields - class AddApplicationOffers(Type): - _toSchema = {'offers': 'Offers'} - _toPy = {'Offers': 'offers'} + _toSchema = {"offers": "Offers"} + _toPy = {"Offers": "offers"} + def __init__(self, offers=None, **unknown_fields): - ''' + """ offers : typing.Sequence[~AddApplicationOffer] - ''' + """ offers_ = [AddApplicationOffer.from_json(o) for o in offers or []] # Validate arguments against known Juju API types. if offers_ is not None and not isinstance(offers_, (bytes, str, list)): - raise Exception("Expected offers_ to be a Sequence, received: {}".format(type(offers_))) + raise Exception( + "Expected offers_ to be a Sequence, received: {}".format(type(offers_)) + ) self.offers = offers_ self.unknown_fields = unknown_fields - class AddApplicationUnits(Type): - _toSchema = {'application': 'application', 'attach_storage': 'attach-storage', 'num_units': 'num-units', 'placement': 'placement', 'policy': 'policy'} - _toPy = {'application': 'application', 'attach-storage': 'attach_storage', 'num-units': 'num_units', 'placement': 'placement', 'policy': 'policy'} - def __init__(self, application=None, attach_storage=None, num_units=None, placement=None, policy=None, **unknown_fields): - ''' + _toSchema = { + "application": "application", + "attach_storage": "attach-storage", + "num_units": "num-units", + "placement": "placement", + "policy": "policy", + } + _toPy = { + "application": "application", + "attach-storage": "attach_storage", + "num-units": "num_units", + "placement": "placement", + "policy": "policy", + } + + def __init__( + self, + application=None, + attach_storage=None, + num_units=None, + placement=None, + policy=None, + **unknown_fields, + ): + """ application : str attach_storage : typing.Sequence[str] num_units : int placement : typing.Sequence[~Placement] policy : str - ''' + """ application_ = application attach_storage_ = attach_storage num_units_ = num_units @@ -317,19 +504,37 @@ def __init__(self, application=None, attach_storage=None, num_units=None, placem # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): - raise Exception("Expected application_ to be a str, received: {}".format(type(application_))) - - if attach_storage_ is not None and not isinstance(attach_storage_, (bytes, str, list)): - raise Exception("Expected attach_storage_ to be a Sequence, received: {}".format(type(attach_storage_))) + raise Exception( + "Expected application_ to be a str, received: {}".format( + type(application_) + ) + ) + + if attach_storage_ is not None and not isinstance( + attach_storage_, (bytes, str, list) + ): + raise Exception( + "Expected attach_storage_ to be a Sequence, received: {}".format( + type(attach_storage_) + ) + ) if num_units_ is not None and not isinstance(num_units_, int): - raise Exception("Expected num_units_ to be a int, received: {}".format(type(num_units_))) + raise Exception( + "Expected num_units_ to be a int, received: {}".format(type(num_units_)) + ) if placement_ is not None and not isinstance(placement_, (bytes, str, list)): - raise Exception("Expected placement_ to be a Sequence, received: {}".format(type(placement_))) + raise Exception( + "Expected placement_ to be a Sequence, received: {}".format( + type(placement_) + ) + ) if policy_ is not None and not isinstance(policy_, (bytes, str)): - raise Exception("Expected policy_ to be a str, received: {}".format(type(policy_))) + raise Exception( + "Expected policy_ to be a str, received: {}".format(type(policy_)) + ) self.application = application_ self.attach_storage = attach_storage_ @@ -339,47 +544,59 @@ def __init__(self, application=None, attach_storage=None, num_units=None, placem self.unknown_fields = unknown_fields - class AddApplicationUnitsResults(Type): - _toSchema = {'units': 'units'} - _toPy = {'units': 'units'} + _toSchema = {"units": "units"} + _toPy = {"units": "units"} + def __init__(self, units=None, **unknown_fields): - ''' + """ units : typing.Sequence[str] - ''' + """ units_ = units # Validate arguments against known Juju API types. if units_ is not None and not isinstance(units_, (bytes, str, list)): - raise Exception("Expected units_ to be a Sequence, received: {}".format(type(units_))) + raise Exception( + "Expected units_ to be a Sequence, received: {}".format(type(units_)) + ) self.units = units_ self.unknown_fields = unknown_fields - class AddCharmWithOrigin(Type): - _toSchema = {'charm_origin': 'charm-origin', 'force': 'force', 'url': 'url'} - _toPy = {'charm-origin': 'charm_origin', 'force': 'force', 'url': 'url'} + _toSchema = {"charm_origin": "charm-origin", "force": "force", "url": "url"} + _toPy = {"charm-origin": "charm_origin", "force": "force", "url": "url"} + def __init__(self, charm_origin=None, force=None, url=None, **unknown_fields): - ''' + """ charm_origin : CharmOrigin force : bool url : str - ''' + """ charm_origin_ = CharmOrigin.from_json(charm_origin) if charm_origin else None force_ = force url_ = url # Validate arguments against known Juju API types. - if charm_origin_ is not None and not isinstance(charm_origin_, (dict, CharmOrigin)): - raise Exception("Expected charm_origin_ to be a CharmOrigin, received: {}".format(type(charm_origin_))) + if charm_origin_ is not None and not isinstance( + charm_origin_, (dict, CharmOrigin) + ): + raise Exception( + "Expected charm_origin_ to be a CharmOrigin, received: {}".format( + type(charm_origin_) + ) + ) if force_ is not None and not isinstance(force_, bool): - raise Exception("Expected force_ to be a bool, received: {}".format(type(force_))) + raise Exception( + "Expected force_ to be a bool, received: {}".format(type(force_)) + ) if url_ is not None and not isinstance(url_, (bytes, str)): - raise Exception("Expected url_ to be a str, received: {}".format(type(url_))) + raise Exception( + "Expected url_ to be a str, received: {}".format(type(url_)) + ) self.charm_origin = charm_origin_ self.force = force_ @@ -387,29 +604,35 @@ def __init__(self, charm_origin=None, force=None, url=None, **unknown_fields): self.unknown_fields = unknown_fields - class AddCloudArgs(Type): - _toSchema = {'cloud': 'cloud', 'force': 'force', 'name': 'name'} - _toPy = {'cloud': 'cloud', 'force': 'force', 'name': 'name'} + _toSchema = {"cloud": "cloud", "force": "force", "name": "name"} + _toPy = {"cloud": "cloud", "force": "force", "name": "name"} + def __init__(self, cloud=None, force=None, name=None, **unknown_fields): - ''' + """ cloud : Cloud force : bool name : str - ''' + """ cloud_ = Cloud.from_json(cloud) if cloud else None force_ = force name_ = name # Validate arguments against known Juju API types. if cloud_ is not None and not isinstance(cloud_, (dict, Cloud)): - raise Exception("Expected cloud_ to be a Cloud, received: {}".format(type(cloud_))) + raise Exception( + "Expected cloud_ to be a Cloud, received: {}".format(type(cloud_)) + ) if force_ is not None and not isinstance(force_, bool): - raise Exception("Expected force_ to be a bool, received: {}".format(type(force_))) + raise Exception( + "Expected force_ to be a bool, received: {}".format(type(force_)) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) self.cloud = cloud_ self.force = force_ @@ -417,12 +640,50 @@ def __init__(self, cloud=None, force=None, name=None, **unknown_fields): self.unknown_fields = unknown_fields - class AddMachineParams(Type): - _toSchema = {'addresses': 'addresses', 'base': 'base', 'constraints': 'constraints', 'container_type': 'container-type', 'disks': 'disks', 'hardware_characteristics': 'hardware-characteristics', 'instance_id': 'instance-id', 'jobs': 'jobs', 'nonce': 'nonce', 'parent_id': 'parent-id', 'placement': 'placement'} - _toPy = {'addresses': 'addresses', 'base': 'base', 'constraints': 'constraints', 'container-type': 'container_type', 'disks': 'disks', 'hardware-characteristics': 'hardware_characteristics', 'instance-id': 'instance_id', 'jobs': 'jobs', 'nonce': 'nonce', 'parent-id': 'parent_id', 'placement': 'placement'} - def __init__(self, addresses=None, base=None, constraints=None, container_type=None, disks=None, hardware_characteristics=None, instance_id=None, jobs=None, nonce=None, parent_id=None, placement=None, **unknown_fields): - ''' + _toSchema = { + "addresses": "addresses", + "base": "base", + "constraints": "constraints", + "container_type": "container-type", + "disks": "disks", + "hardware_characteristics": "hardware-characteristics", + "instance_id": "instance-id", + "jobs": "jobs", + "nonce": "nonce", + "parent_id": "parent-id", + "placement": "placement", + } + _toPy = { + "addresses": "addresses", + "base": "base", + "constraints": "constraints", + "container-type": "container_type", + "disks": "disks", + "hardware-characteristics": "hardware_characteristics", + "instance-id": "instance_id", + "jobs": "jobs", + "nonce": "nonce", + "parent-id": "parent_id", + "placement": "placement", + } + + def __init__( + self, + addresses=None, + base=None, + constraints=None, + container_type=None, + disks=None, + hardware_characteristics=None, + instance_id=None, + jobs=None, + nonce=None, + parent_id=None, + placement=None, + **unknown_fields, + ): + """ addresses : typing.Sequence[~Address] base : Base constraints : Value @@ -434,13 +695,17 @@ def __init__(self, addresses=None, base=None, constraints=None, container_type=N nonce : str parent_id : str placement : Placement - ''' + """ addresses_ = [Address.from_json(o) for o in addresses or []] base_ = Base.from_json(base) if base else None constraints_ = Value.from_json(constraints) if constraints else None container_type_ = container_type disks_ = [Constraints.from_json(o) for o in disks or []] - hardware_characteristics_ = HardwareCharacteristics.from_json(hardware_characteristics) if hardware_characteristics else None + hardware_characteristics_ = ( + HardwareCharacteristics.from_json(hardware_characteristics) + if hardware_characteristics + else None + ) instance_id_ = instance_id jobs_ = jobs nonce_ = nonce @@ -449,37 +714,75 @@ def __init__(self, addresses=None, base=None, constraints=None, container_type=N # Validate arguments against known Juju API types. if addresses_ is not None and not isinstance(addresses_, (bytes, str, list)): - raise Exception("Expected addresses_ to be a Sequence, received: {}".format(type(addresses_))) + raise Exception( + "Expected addresses_ to be a Sequence, received: {}".format( + type(addresses_) + ) + ) if base_ is not None and not isinstance(base_, (dict, Base)): - raise Exception("Expected base_ to be a Base, received: {}".format(type(base_))) + raise Exception( + "Expected base_ to be a Base, received: {}".format(type(base_)) + ) if constraints_ is not None and not isinstance(constraints_, (dict, Value)): - raise Exception("Expected constraints_ to be a Value, received: {}".format(type(constraints_))) - - if container_type_ is not None and not isinstance(container_type_, (bytes, str)): - raise Exception("Expected container_type_ to be a str, received: {}".format(type(container_type_))) + raise Exception( + "Expected constraints_ to be a Value, received: {}".format( + type(constraints_) + ) + ) + + if container_type_ is not None and not isinstance( + container_type_, (bytes, str) + ): + raise Exception( + "Expected container_type_ to be a str, received: {}".format( + type(container_type_) + ) + ) if disks_ is not None and not isinstance(disks_, (bytes, str, list)): - raise Exception("Expected disks_ to be a Sequence, received: {}".format(type(disks_))) - - if hardware_characteristics_ is not None and not isinstance(hardware_characteristics_, (dict, HardwareCharacteristics)): - raise Exception("Expected hardware_characteristics_ to be a HardwareCharacteristics, received: {}".format(type(hardware_characteristics_))) + raise Exception( + "Expected disks_ to be a Sequence, received: {}".format(type(disks_)) + ) + + if hardware_characteristics_ is not None and not isinstance( + hardware_characteristics_, (dict, HardwareCharacteristics) + ): + raise Exception( + "Expected hardware_characteristics_ to be a HardwareCharacteristics, received: {}".format( + type(hardware_characteristics_) + ) + ) if instance_id_ is not None and not isinstance(instance_id_, (bytes, str)): - raise Exception("Expected instance_id_ to be a str, received: {}".format(type(instance_id_))) + raise Exception( + "Expected instance_id_ to be a str, received: {}".format( + type(instance_id_) + ) + ) if jobs_ is not None and not isinstance(jobs_, (bytes, str, list)): - raise Exception("Expected jobs_ to be a Sequence, received: {}".format(type(jobs_))) + raise Exception( + "Expected jobs_ to be a Sequence, received: {}".format(type(jobs_)) + ) if nonce_ is not None and not isinstance(nonce_, (bytes, str)): - raise Exception("Expected nonce_ to be a str, received: {}".format(type(nonce_))) + raise Exception( + "Expected nonce_ to be a str, received: {}".format(type(nonce_)) + ) if parent_id_ is not None and not isinstance(parent_id_, (bytes, str)): - raise Exception("Expected parent_id_ to be a str, received: {}".format(type(parent_id_))) + raise Exception( + "Expected parent_id_ to be a str, received: {}".format(type(parent_id_)) + ) if placement_ is not None and not isinstance(placement_, (dict, Placement)): - raise Exception("Expected placement_ to be a Placement, received: {}".format(type(placement_))) + raise Exception( + "Expected placement_ to be a Placement, received: {}".format( + type(placement_) + ) + ) self.addresses = addresses_ self.base = base_ @@ -495,79 +798,112 @@ def __init__(self, addresses=None, base=None, constraints=None, container_type=N self.unknown_fields = unknown_fields - class AddMachines(Type): - _toSchema = {'params': 'params'} - _toPy = {'params': 'params'} + _toSchema = {"params": "params"} + _toPy = {"params": "params"} + def __init__(self, params=None, **unknown_fields): - ''' + """ params : typing.Sequence[~AddMachineParams] - ''' + """ params_ = [AddMachineParams.from_json(o) for o in params or []] # Validate arguments against known Juju API types. if params_ is not None and not isinstance(params_, (bytes, str, list)): - raise Exception("Expected params_ to be a Sequence, received: {}".format(type(params_))) + raise Exception( + "Expected params_ to be a Sequence, received: {}".format(type(params_)) + ) self.params = params_ self.unknown_fields = unknown_fields - class AddMachinesResult(Type): - _toSchema = {'error': 'error', 'machine': 'machine'} - _toPy = {'error': 'error', 'machine': 'machine'} + _toSchema = {"error": "error", "machine": "machine"} + _toPy = {"error": "error", "machine": "machine"} + def __init__(self, error=None, machine=None, **unknown_fields): - ''' + """ error : Error machine : str - ''' + """ error_ = Error.from_json(error) if error else None machine_ = machine # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if machine_ is not None and not isinstance(machine_, (bytes, str)): - raise Exception("Expected machine_ to be a str, received: {}".format(type(machine_))) + raise Exception( + "Expected machine_ to be a str, received: {}".format(type(machine_)) + ) self.error = error_ self.machine = machine_ self.unknown_fields = unknown_fields - class AddMachinesResults(Type): - _toSchema = {'machines': 'machines'} - _toPy = {'machines': 'machines'} + _toSchema = {"machines": "machines"} + _toPy = {"machines": "machines"} + def __init__(self, machines=None, **unknown_fields): - ''' + """ machines : typing.Sequence[~AddMachinesResult] - ''' + """ machines_ = [AddMachinesResult.from_json(o) for o in machines or []] # Validate arguments against known Juju API types. if machines_ is not None and not isinstance(machines_, (bytes, str, list)): - raise Exception("Expected machines_ to be a Sequence, received: {}".format(type(machines_))) + raise Exception( + "Expected machines_ to be a Sequence, received: {}".format( + type(machines_) + ) + ) self.machines = machines_ self.unknown_fields = unknown_fields - class AddPendingResourcesArgsV2(Type): - _toSchema = {'charm_origin': 'charm-origin', 'entity': 'Entity', 'macaroon': 'macaroon', 'resources': 'resources', 'tag': 'tag', 'url': 'url'} - _toPy = {'Entity': 'entity', 'charm-origin': 'charm_origin', 'macaroon': 'macaroon', 'resources': 'resources', 'tag': 'tag', 'url': 'url'} - def __init__(self, entity=None, charm_origin=None, macaroon=None, resources=None, tag=None, url=None, **unknown_fields): - ''' + _toSchema = { + "charm_origin": "charm-origin", + "entity": "Entity", + "macaroon": "macaroon", + "resources": "resources", + "tag": "tag", + "url": "url", + } + _toPy = { + "Entity": "entity", + "charm-origin": "charm_origin", + "macaroon": "macaroon", + "resources": "resources", + "tag": "tag", + "url": "url", + } + + def __init__( + self, + entity=None, + charm_origin=None, + macaroon=None, + resources=None, + tag=None, + url=None, + **unknown_fields, + ): + """ entity : Entity charm_origin : CharmOrigin macaroon : Macaroon resources : typing.Sequence[~CharmResource] tag : str url : str - ''' + """ entity_ = Entity.from_json(entity) if entity else None charm_origin_ = CharmOrigin.from_json(charm_origin) if charm_origin else None macaroon_ = Macaroon.from_json(macaroon) if macaroon else None @@ -577,22 +913,42 @@ def __init__(self, entity=None, charm_origin=None, macaroon=None, resources=None # Validate arguments against known Juju API types. if entity_ is not None and not isinstance(entity_, (dict, Entity)): - raise Exception("Expected entity_ to be a Entity, received: {}".format(type(entity_))) - - if charm_origin_ is not None and not isinstance(charm_origin_, (dict, CharmOrigin)): - raise Exception("Expected charm_origin_ to be a CharmOrigin, received: {}".format(type(charm_origin_))) + raise Exception( + "Expected entity_ to be a Entity, received: {}".format(type(entity_)) + ) + + if charm_origin_ is not None and not isinstance( + charm_origin_, (dict, CharmOrigin) + ): + raise Exception( + "Expected charm_origin_ to be a CharmOrigin, received: {}".format( + type(charm_origin_) + ) + ) if macaroon_ is not None and not isinstance(macaroon_, (dict, Macaroon)): - raise Exception("Expected macaroon_ to be a Macaroon, received: {}".format(type(macaroon_))) + raise Exception( + "Expected macaroon_ to be a Macaroon, received: {}".format( + type(macaroon_) + ) + ) if resources_ is not None and not isinstance(resources_, (bytes, str, list)): - raise Exception("Expected resources_ to be a Sequence, received: {}".format(type(resources_))) + raise Exception( + "Expected resources_ to be a Sequence, received: {}".format( + type(resources_) + ) + ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception("Expected tag_ to be a str, received: {}".format(type(tag_))) + raise Exception( + "Expected tag_ to be a str, received: {}".format(type(tag_)) + ) if url_ is not None and not isinstance(url_, (bytes, str)): - raise Exception("Expected url_ to be a str, received: {}".format(type(url_))) + raise Exception( + "Expected url_ to be a str, received: {}".format(type(url_)) + ) self.entity = entity_ self.charm_origin = charm_origin_ @@ -603,29 +959,53 @@ def __init__(self, entity=None, charm_origin=None, macaroon=None, resources=None self.unknown_fields = unknown_fields - class AddPendingResourcesResult(Type): - _toSchema = {'error': 'error', 'errorresult': 'ErrorResult', 'pending_ids': 'pending-ids'} - _toPy = {'ErrorResult': 'errorresult', 'error': 'error', 'pending-ids': 'pending_ids'} - def __init__(self, errorresult=None, error=None, pending_ids=None, **unknown_fields): - ''' + _toSchema = { + "error": "error", + "errorresult": "ErrorResult", + "pending_ids": "pending-ids", + } + _toPy = { + "ErrorResult": "errorresult", + "error": "error", + "pending-ids": "pending_ids", + } + + def __init__( + self, errorresult=None, error=None, pending_ids=None, **unknown_fields + ): + """ errorresult : ErrorResult error : Error pending_ids : typing.Sequence[str] - ''' + """ errorresult_ = ErrorResult.from_json(errorresult) if errorresult else None error_ = Error.from_json(error) if error else None pending_ids_ = pending_ids # Validate arguments against known Juju API types. - if errorresult_ is not None and not isinstance(errorresult_, (dict, ErrorResult)): - raise Exception("Expected errorresult_ to be a ErrorResult, received: {}".format(type(errorresult_))) + if errorresult_ is not None and not isinstance( + errorresult_, (dict, ErrorResult) + ): + raise Exception( + "Expected errorresult_ to be a ErrorResult, received: {}".format( + type(errorresult_) + ) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) - - if pending_ids_ is not None and not isinstance(pending_ids_, (bytes, str, list)): - raise Exception("Expected pending_ids_ to be a Sequence, received: {}".format(type(pending_ids_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) + + if pending_ids_ is not None and not isinstance( + pending_ids_, (bytes, str, list) + ): + raise Exception( + "Expected pending_ids_ to be a Sequence, received: {}".format( + type(pending_ids_) + ) + ) self.errorresult = errorresult_ self.error = error_ @@ -633,62 +1013,101 @@ def __init__(self, errorresult=None, error=None, pending_ids=None, **unknown_fie self.unknown_fields = unknown_fields - class AddRelation(Type): - _toSchema = {'endpoints': 'endpoints', 'via_cidrs': 'via-cidrs'} - _toPy = {'endpoints': 'endpoints', 'via-cidrs': 'via_cidrs'} + _toSchema = {"endpoints": "endpoints", "via_cidrs": "via-cidrs"} + _toPy = {"endpoints": "endpoints", "via-cidrs": "via_cidrs"} + def __init__(self, endpoints=None, via_cidrs=None, **unknown_fields): - ''' + """ endpoints : typing.Sequence[str] via_cidrs : typing.Sequence[str] - ''' + """ endpoints_ = endpoints via_cidrs_ = via_cidrs # Validate arguments against known Juju API types. if endpoints_ is not None and not isinstance(endpoints_, (bytes, str, list)): - raise Exception("Expected endpoints_ to be a Sequence, received: {}".format(type(endpoints_))) + raise Exception( + "Expected endpoints_ to be a Sequence, received: {}".format( + type(endpoints_) + ) + ) if via_cidrs_ is not None and not isinstance(via_cidrs_, (bytes, str, list)): - raise Exception("Expected via_cidrs_ to be a Sequence, received: {}".format(type(via_cidrs_))) + raise Exception( + "Expected via_cidrs_ to be a Sequence, received: {}".format( + type(via_cidrs_) + ) + ) self.endpoints = endpoints_ self.via_cidrs = via_cidrs_ self.unknown_fields = unknown_fields - class AddRelationResults(Type): - _toSchema = {'endpoints': 'endpoints'} - _toPy = {'endpoints': 'endpoints'} + _toSchema = {"endpoints": "endpoints"} + _toPy = {"endpoints": "endpoints"} + def __init__(self, endpoints=None, **unknown_fields): - ''' + """ endpoints : typing.Mapping[str, ~CharmRelation] - ''' - endpoints_ = {k: CharmRelation.from_json(v) for k, v in (endpoints or dict()).items()} + """ + endpoints_ = { + k: CharmRelation.from_json(v) for k, v in (endpoints or dict()).items() + } # Validate arguments against known Juju API types. if endpoints_ is not None and not isinstance(endpoints_, dict): - raise Exception("Expected endpoints_ to be a Mapping, received: {}".format(type(endpoints_))) + raise Exception( + "Expected endpoints_ to be a Mapping, received: {}".format( + type(endpoints_) + ) + ) self.endpoints = endpoints_ self.unknown_fields = unknown_fields - class AddSecretBackendArg(Type): - _toSchema = {'backend_type': 'backend-type', 'config': 'config', 'id_': 'id', 'name': 'name', 'secretbackend': 'SecretBackend', 'token_rotate_interval': 'token-rotate-interval'} - _toPy = {'SecretBackend': 'secretbackend', 'backend-type': 'backend_type', 'config': 'config', 'id': 'id_', 'name': 'name', 'token-rotate-interval': 'token_rotate_interval'} - def __init__(self, secretbackend=None, backend_type=None, config=None, id_=None, name=None, token_rotate_interval=None, **unknown_fields): - ''' + _toSchema = { + "backend_type": "backend-type", + "config": "config", + "id_": "id", + "name": "name", + "secretbackend": "SecretBackend", + "token_rotate_interval": "token-rotate-interval", + } + _toPy = { + "SecretBackend": "secretbackend", + "backend-type": "backend_type", + "config": "config", + "id": "id_", + "name": "name", + "token-rotate-interval": "token_rotate_interval", + } + + def __init__( + self, + secretbackend=None, + backend_type=None, + config=None, + id_=None, + name=None, + token_rotate_interval=None, + **unknown_fields, + ): + """ secretbackend : SecretBackend backend_type : str config : typing.Mapping[str, typing.Any] id_ : str name : str token_rotate_interval : int - ''' - secretbackend_ = SecretBackend.from_json(secretbackend) if secretbackend else None + """ + secretbackend_ = ( + SecretBackend.from_json(secretbackend) if secretbackend else None + ) backend_type_ = backend_type config_ = config id__ = id_ @@ -696,23 +1115,45 @@ def __init__(self, secretbackend=None, backend_type=None, config=None, id_=None, token_rotate_interval_ = token_rotate_interval # Validate arguments against known Juju API types. - if secretbackend_ is not None and not isinstance(secretbackend_, (dict, SecretBackend)): - raise Exception("Expected secretbackend_ to be a SecretBackend, received: {}".format(type(secretbackend_))) + if secretbackend_ is not None and not isinstance( + secretbackend_, (dict, SecretBackend) + ): + raise Exception( + "Expected secretbackend_ to be a SecretBackend, received: {}".format( + type(secretbackend_) + ) + ) if backend_type_ is not None and not isinstance(backend_type_, (bytes, str)): - raise Exception("Expected backend_type_ to be a str, received: {}".format(type(backend_type_))) + raise Exception( + "Expected backend_type_ to be a str, received: {}".format( + type(backend_type_) + ) + ) if config_ is not None and not isinstance(config_, dict): - raise Exception("Expected config_ to be a Mapping, received: {}".format(type(config_))) + raise Exception( + "Expected config_ to be a Mapping, received: {}".format(type(config_)) + ) if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception("Expected id__ to be a str, received: {}".format(type(id__))) + raise Exception( + "Expected id__ to be a str, received: {}".format(type(id__)) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) - - if token_rotate_interval_ is not None and not isinstance(token_rotate_interval_, int): - raise Exception("Expected token_rotate_interval_ to be a int, received: {}".format(type(token_rotate_interval_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) + + if token_rotate_interval_ is not None and not isinstance( + token_rotate_interval_, int + ): + raise Exception( + "Expected token_rotate_interval_ to be a int, received: {}".format( + type(token_rotate_interval_) + ) + ) self.secretbackend = secretbackend_ self.backend_type = backend_type_ @@ -723,107 +1164,143 @@ def __init__(self, secretbackend=None, backend_type=None, config=None, id_=None, self.unknown_fields = unknown_fields - class AddSecretBackendArgs(Type): - _toSchema = {'args': 'args'} - _toPy = {'args': 'args'} + _toSchema = {"args": "args"} + _toPy = {"args": "args"} + def __init__(self, args=None, **unknown_fields): - ''' + """ args : typing.Sequence[~AddSecretBackendArg] - ''' + """ args_ = [AddSecretBackendArg.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception("Expected args_ to be a Sequence, received: {}".format(type(args_))) + raise Exception( + "Expected args_ to be a Sequence, received: {}".format(type(args_)) + ) self.args = args_ self.unknown_fields = unknown_fields - class AddStorageDetails(Type): - _toSchema = {'storage_tags': 'storage-tags'} - _toPy = {'storage-tags': 'storage_tags'} + _toSchema = {"storage_tags": "storage-tags"} + _toPy = {"storage-tags": "storage_tags"} + def __init__(self, storage_tags=None, **unknown_fields): - ''' + """ storage_tags : typing.Sequence[str] - ''' + """ storage_tags_ = storage_tags # Validate arguments against known Juju API types. - if storage_tags_ is not None and not isinstance(storage_tags_, (bytes, str, list)): - raise Exception("Expected storage_tags_ to be a Sequence, received: {}".format(type(storage_tags_))) + if storage_tags_ is not None and not isinstance( + storage_tags_, (bytes, str, list) + ): + raise Exception( + "Expected storage_tags_ to be a Sequence, received: {}".format( + type(storage_tags_) + ) + ) self.storage_tags = storage_tags_ self.unknown_fields = unknown_fields - class AddStorageResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : AddStorageDetails - ''' + """ error_ = Error.from_json(error) if error else None result_ = AddStorageDetails.from_json(result) if result else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if result_ is not None and not isinstance(result_, (dict, AddStorageDetails)): - raise Exception("Expected result_ to be a AddStorageDetails, received: {}".format(type(result_))) + raise Exception( + "Expected result_ to be a AddStorageDetails, received: {}".format( + type(result_) + ) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class AddStorageResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~AddStorageResult] - ''' + """ results_ = [AddStorageResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class AddUser(Type): - _toSchema = {'display_name': 'display-name', 'password': 'password', 'username': 'username'} - _toPy = {'display-name': 'display_name', 'password': 'password', 'username': 'username'} - def __init__(self, display_name=None, password=None, username=None, **unknown_fields): - ''' + _toSchema = { + "display_name": "display-name", + "password": "password", + "username": "username", + } + _toPy = { + "display-name": "display_name", + "password": "password", + "username": "username", + } + + def __init__( + self, display_name=None, password=None, username=None, **unknown_fields + ): + """ display_name : str password : str username : str - ''' + """ display_name_ = display_name password_ = password username_ = username # Validate arguments against known Juju API types. if display_name_ is not None and not isinstance(display_name_, (bytes, str)): - raise Exception("Expected display_name_ to be a str, received: {}".format(type(display_name_))) + raise Exception( + "Expected display_name_ to be a str, received: {}".format( + type(display_name_) + ) + ) if password_ is not None and not isinstance(password_, (bytes, str)): - raise Exception("Expected password_ to be a str, received: {}".format(type(password_))) + raise Exception( + "Expected password_ to be a str, received: {}".format(type(password_)) + ) if username_ is not None and not isinstance(username_, (bytes, str)): - raise Exception("Expected username_ to be a str, received: {}".format(type(username_))) + raise Exception( + "Expected username_ to be a str, received: {}".format(type(username_)) + ) self.display_name = display_name_ self.password = password_ @@ -831,29 +1308,37 @@ def __init__(self, display_name=None, password=None, username=None, **unknown_fi self.unknown_fields = unknown_fields - class AddUserResult(Type): - _toSchema = {'error': 'error', 'secret_key': 'secret-key', 'tag': 'tag'} - _toPy = {'error': 'error', 'secret-key': 'secret_key', 'tag': 'tag'} + _toSchema = {"error": "error", "secret_key": "secret-key", "tag": "tag"} + _toPy = {"error": "error", "secret-key": "secret_key", "tag": "tag"} + def __init__(self, error=None, secret_key=None, tag=None, **unknown_fields): - ''' + """ error : Error secret_key : typing.Sequence[int] tag : str - ''' + """ error_ = Error.from_json(error) if error else None secret_key_ = secret_key tag_ = tag # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if secret_key_ is not None and not isinstance(secret_key_, (bytes, str, list)): - raise Exception("Expected secret_key_ to be a Sequence, received: {}".format(type(secret_key_))) + raise Exception( + "Expected secret_key_ to be a Sequence, received: {}".format( + type(secret_key_) + ) + ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception("Expected tag_ to be a str, received: {}".format(type(tag_))) + raise Exception( + "Expected tag_ to be a str, received: {}".format(type(tag_)) + ) self.error = error_ self.secret_key = secret_key_ @@ -861,48 +1346,83 @@ def __init__(self, error=None, secret_key=None, tag=None, **unknown_fields): self.unknown_fields = unknown_fields - class AddUserResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~AddUserResult] - ''' + """ results_ = [AddUserResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class AddUsers(Type): - _toSchema = {'users': 'users'} - _toPy = {'users': 'users'} + _toSchema = {"users": "users"} + _toPy = {"users": "users"} + def __init__(self, users=None, **unknown_fields): - ''' + """ users : typing.Sequence[~AddUser] - ''' + """ users_ = [AddUser.from_json(o) for o in users or []] # Validate arguments against known Juju API types. if users_ is not None and not isinstance(users_, (bytes, str, list)): - raise Exception("Expected users_ to be a Sequence, received: {}".format(type(users_))) + raise Exception( + "Expected users_ to be a Sequence, received: {}".format(type(users_)) + ) self.users = users_ self.unknown_fields = unknown_fields - class Address(Type): - _toSchema = {'cidr': 'cidr', 'config_type': 'config-type', 'is_secondary': 'is-secondary', 'scope': 'scope', 'space_id': 'space-id', 'space_name': 'space-name', 'type_': 'type', 'value': 'value'} - _toPy = {'cidr': 'cidr', 'config-type': 'config_type', 'is-secondary': 'is_secondary', 'scope': 'scope', 'space-id': 'space_id', 'space-name': 'space_name', 'type': 'type_', 'value': 'value'} - def __init__(self, cidr=None, config_type=None, is_secondary=None, scope=None, space_id=None, space_name=None, type_=None, value=None, **unknown_fields): - ''' + _toSchema = { + "cidr": "cidr", + "config_type": "config-type", + "is_secondary": "is-secondary", + "scope": "scope", + "space_id": "space-id", + "space_name": "space-name", + "type_": "type", + "value": "value", + } + _toPy = { + "cidr": "cidr", + "config-type": "config_type", + "is-secondary": "is_secondary", + "scope": "scope", + "space-id": "space_id", + "space-name": "space_name", + "type": "type_", + "value": "value", + } + + def __init__( + self, + cidr=None, + config_type=None, + is_secondary=None, + scope=None, + space_id=None, + space_name=None, + type_=None, + value=None, + **unknown_fields, + ): + """ cidr : str config_type : str is_secondary : bool @@ -911,7 +1431,7 @@ def __init__(self, cidr=None, config_type=None, is_secondary=None, scope=None, s space_name : str type_ : str value : str - ''' + """ cidr_ = cidr config_type_ = config_type is_secondary_ = is_secondary @@ -923,28 +1443,50 @@ def __init__(self, cidr=None, config_type=None, is_secondary=None, scope=None, s # Validate arguments against known Juju API types. if cidr_ is not None and not isinstance(cidr_, (bytes, str)): - raise Exception("Expected cidr_ to be a str, received: {}".format(type(cidr_))) + raise Exception( + "Expected cidr_ to be a str, received: {}".format(type(cidr_)) + ) if config_type_ is not None and not isinstance(config_type_, (bytes, str)): - raise Exception("Expected config_type_ to be a str, received: {}".format(type(config_type_))) + raise Exception( + "Expected config_type_ to be a str, received: {}".format( + type(config_type_) + ) + ) if is_secondary_ is not None and not isinstance(is_secondary_, bool): - raise Exception("Expected is_secondary_ to be a bool, received: {}".format(type(is_secondary_))) + raise Exception( + "Expected is_secondary_ to be a bool, received: {}".format( + type(is_secondary_) + ) + ) if scope_ is not None and not isinstance(scope_, (bytes, str)): - raise Exception("Expected scope_ to be a str, received: {}".format(type(scope_))) + raise Exception( + "Expected scope_ to be a str, received: {}".format(type(scope_)) + ) if space_id_ is not None and not isinstance(space_id_, (bytes, str)): - raise Exception("Expected space_id_ to be a str, received: {}".format(type(space_id_))) + raise Exception( + "Expected space_id_ to be a str, received: {}".format(type(space_id_)) + ) if space_name_ is not None and not isinstance(space_name_, (bytes, str)): - raise Exception("Expected space_name_ to be a str, received: {}".format(type(space_name_))) + raise Exception( + "Expected space_name_ to be a str, received: {}".format( + type(space_name_) + ) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) if value_ is not None and not isinstance(value_, (bytes, str)): - raise Exception("Expected value_ to be a str, received: {}".format(type(value_))) + raise Exception( + "Expected value_ to be a str, received: {}".format(type(value_)) + ) self.cidr = cidr_ self.config_type = config_type_ @@ -957,65 +1499,79 @@ def __init__(self, cidr=None, config_type=None, is_secondary=None, scope=None, s self.unknown_fields = unknown_fields - class AllWatcherId(Type): - _toSchema = {'watcher_id': 'watcher-id'} - _toPy = {'watcher-id': 'watcher_id'} + _toSchema = {"watcher_id": "watcher-id"} + _toPy = {"watcher-id": "watcher_id"} + def __init__(self, watcher_id=None, **unknown_fields): - ''' + """ watcher_id : str - ''' + """ watcher_id_ = watcher_id # Validate arguments against known Juju API types. if watcher_id_ is not None and not isinstance(watcher_id_, (bytes, str)): - raise Exception("Expected watcher_id_ to be a str, received: {}".format(type(watcher_id_))) + raise Exception( + "Expected watcher_id_ to be a str, received: {}".format( + type(watcher_id_) + ) + ) self.watcher_id = watcher_id_ self.unknown_fields = unknown_fields - class AllWatcherNextResults(Type): - _toSchema = {'deltas': 'deltas'} - _toPy = {'deltas': 'deltas'} + _toSchema = {"deltas": "deltas"} + _toPy = {"deltas": "deltas"} + def __init__(self, deltas=None, **unknown_fields): - ''' + """ deltas : typing.Sequence[~Delta] - ''' + """ deltas_ = [Delta.from_json(o) for o in deltas or []] # Validate arguments against known Juju API types. if deltas_ is not None and not isinstance(deltas_, (bytes, str, list)): - raise Exception("Expected deltas_ to be a Sequence, received: {}".format(type(deltas_))) + raise Exception( + "Expected deltas_ to be a Sequence, received: {}".format(type(deltas_)) + ) self.deltas = deltas_ self.unknown_fields = unknown_fields - class AnnotationsGetResult(Type): - _toSchema = {'annotations': 'annotations', 'entity': 'entity', 'error': 'error'} - _toPy = {'annotations': 'annotations', 'entity': 'entity', 'error': 'error'} + _toSchema = {"annotations": "annotations", "entity": "entity", "error": "error"} + _toPy = {"annotations": "annotations", "entity": "entity", "error": "error"} + def __init__(self, annotations=None, entity=None, error=None, **unknown_fields): - ''' + """ annotations : typing.Mapping[str, str] entity : str error : ErrorResult - ''' + """ annotations_ = annotations entity_ = entity error_ = ErrorResult.from_json(error) if error else None # Validate arguments against known Juju API types. if annotations_ is not None and not isinstance(annotations_, dict): - raise Exception("Expected annotations_ to be a Mapping, received: {}".format(type(annotations_))) + raise Exception( + "Expected annotations_ to be a Mapping, received: {}".format( + type(annotations_) + ) + ) if entity_ is not None and not isinstance(entity_, (bytes, str)): - raise Exception("Expected entity_ to be a str, received: {}".format(type(entity_))) + raise Exception( + "Expected entity_ to be a str, received: {}".format(type(entity_)) + ) if error_ is not None and not isinstance(error_, (dict, ErrorResult)): - raise Exception("Expected error_ to be a ErrorResult, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a ErrorResult, received: {}".format(type(error_)) + ) self.annotations = annotations_ self.entity = entity_ @@ -1023,65 +1579,95 @@ def __init__(self, annotations=None, entity=None, error=None, **unknown_fields): self.unknown_fields = unknown_fields - class AnnotationsGetResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~AnnotationsGetResult] - ''' + """ results_ = [AnnotationsGetResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class AnnotationsSet(Type): - _toSchema = {'annotations': 'annotations'} - _toPy = {'annotations': 'annotations'} + _toSchema = {"annotations": "annotations"} + _toPy = {"annotations": "annotations"} + def __init__(self, annotations=None, **unknown_fields): - ''' + """ annotations : typing.Sequence[~EntityAnnotations] - ''' + """ annotations_ = [EntityAnnotations.from_json(o) for o in annotations or []] # Validate arguments against known Juju API types. - if annotations_ is not None and not isinstance(annotations_, (bytes, str, list)): - raise Exception("Expected annotations_ to be a Sequence, received: {}".format(type(annotations_))) + if annotations_ is not None and not isinstance( + annotations_, (bytes, str, list) + ): + raise Exception( + "Expected annotations_ to be a Sequence, received: {}".format( + type(annotations_) + ) + ) self.annotations = annotations_ self.unknown_fields = unknown_fields - class ApplicationCharmActionsResult(Type): - _toSchema = {'actions': 'actions', 'application_tag': 'application-tag', 'error': 'error'} - _toPy = {'actions': 'actions', 'application-tag': 'application_tag', 'error': 'error'} - def __init__(self, actions=None, application_tag=None, error=None, **unknown_fields): - ''' + _toSchema = { + "actions": "actions", + "application_tag": "application-tag", + "error": "error", + } + _toPy = { + "actions": "actions", + "application-tag": "application_tag", + "error": "error", + } + + def __init__( + self, actions=None, application_tag=None, error=None, **unknown_fields + ): + """ actions : typing.Mapping[str, ~ActionSpec] application_tag : str error : Error - ''' + """ actions_ = {k: ActionSpec.from_json(v) for k, v in (actions or dict()).items()} application_tag_ = application_tag error_ = Error.from_json(error) if error else None # Validate arguments against known Juju API types. if actions_ is not None and not isinstance(actions_, dict): - raise Exception("Expected actions_ to be a Mapping, received: {}".format(type(actions_))) - - if application_tag_ is not None and not isinstance(application_tag_, (bytes, str)): - raise Exception("Expected application_tag_ to be a str, received: {}".format(type(application_tag_))) + raise Exception( + "Expected actions_ to be a Mapping, received: {}".format(type(actions_)) + ) + + if application_tag_ is not None and not isinstance( + application_tag_, (bytes, str) + ): + raise Exception( + "Expected application_tag_ to be a str, received: {}".format( + type(application_tag_) + ) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) self.actions = actions_ self.application_tag = application_tag_ @@ -1089,132 +1675,213 @@ def __init__(self, actions=None, application_tag=None, error=None, **unknown_fie self.unknown_fields = unknown_fields - class ApplicationCharmPlacement(Type): - _toSchema = {'application': 'application', 'charm_url': 'charm-url'} - _toPy = {'application': 'application', 'charm-url': 'charm_url'} + _toSchema = {"application": "application", "charm_url": "charm-url"} + _toPy = {"application": "application", "charm-url": "charm_url"} + def __init__(self, application=None, charm_url=None, **unknown_fields): - ''' + """ application : str charm_url : str - ''' + """ application_ = application charm_url_ = charm_url # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): - raise Exception("Expected application_ to be a str, received: {}".format(type(application_))) + raise Exception( + "Expected application_ to be a str, received: {}".format( + type(application_) + ) + ) if charm_url_ is not None and not isinstance(charm_url_, (bytes, str)): - raise Exception("Expected charm_url_ to be a str, received: {}".format(type(charm_url_))) + raise Exception( + "Expected charm_url_ to be a str, received: {}".format(type(charm_url_)) + ) self.application = application_ self.charm_url = charm_url_ self.unknown_fields = unknown_fields - class ApplicationCharmPlacements(Type): - _toSchema = {'placements': 'placements'} - _toPy = {'placements': 'placements'} + _toSchema = {"placements": "placements"} + _toPy = {"placements": "placements"} + def __init__(self, placements=None, **unknown_fields): - ''' + """ placements : typing.Sequence[~ApplicationCharmPlacement] - ''' + """ placements_ = [ApplicationCharmPlacement.from_json(o) for o in placements or []] # Validate arguments against known Juju API types. if placements_ is not None and not isinstance(placements_, (bytes, str, list)): - raise Exception("Expected placements_ to be a Sequence, received: {}".format(type(placements_))) + raise Exception( + "Expected placements_ to be a Sequence, received: {}".format( + type(placements_) + ) + ) self.placements = placements_ self.unknown_fields = unknown_fields - class ApplicationCharmRelations(Type): - _toSchema = {'application': 'application'} - _toPy = {'application': 'application'} + _toSchema = {"application": "application"} + _toPy = {"application": "application"} + def __init__(self, application=None, **unknown_fields): - ''' + """ application : str - ''' + """ application_ = application # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): - raise Exception("Expected application_ to be a str, received: {}".format(type(application_))) + raise Exception( + "Expected application_ to be a str, received: {}".format( + type(application_) + ) + ) self.application = application_ self.unknown_fields = unknown_fields - class ApplicationCharmRelationsResults(Type): - _toSchema = {'charm_relations': 'charm-relations'} - _toPy = {'charm-relations': 'charm_relations'} + _toSchema = {"charm_relations": "charm-relations"} + _toPy = {"charm-relations": "charm_relations"} + def __init__(self, charm_relations=None, **unknown_fields): - ''' + """ charm_relations : typing.Sequence[str] - ''' + """ charm_relations_ = charm_relations # Validate arguments against known Juju API types. - if charm_relations_ is not None and not isinstance(charm_relations_, (bytes, str, list)): - raise Exception("Expected charm_relations_ to be a Sequence, received: {}".format(type(charm_relations_))) + if charm_relations_ is not None and not isinstance( + charm_relations_, (bytes, str, list) + ): + raise Exception( + "Expected charm_relations_ to be a Sequence, received: {}".format( + type(charm_relations_) + ) + ) self.charm_relations = charm_relations_ self.unknown_fields = unknown_fields - class ApplicationConfigUnsetArgs(Type): - _toSchema = {'args': 'Args'} - _toPy = {'Args': 'args'} + _toSchema = {"args": "Args"} + _toPy = {"Args": "args"} + def __init__(self, args=None, **unknown_fields): - ''' + """ args : typing.Sequence[~ApplicationUnset] - ''' + """ args_ = [ApplicationUnset.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception("Expected args_ to be a Sequence, received: {}".format(type(args_))) + raise Exception( + "Expected args_ to be a Sequence, received: {}".format(type(args_)) + ) self.args = args_ self.unknown_fields = unknown_fields - class ApplicationConstraint(Type): - _toSchema = {'constraints': 'constraints', 'error': 'error'} - _toPy = {'constraints': 'constraints', 'error': 'error'} + _toSchema = {"constraints": "constraints", "error": "error"} + _toPy = {"constraints": "constraints", "error": "error"} + def __init__(self, constraints=None, error=None, **unknown_fields): - ''' + """ constraints : Value error : Error - ''' + """ constraints_ = Value.from_json(constraints) if constraints else None error_ = Error.from_json(error) if error else None # Validate arguments against known Juju API types. if constraints_ is not None and not isinstance(constraints_, (dict, Value)): - raise Exception("Expected constraints_ to be a Value, received: {}".format(type(constraints_))) + raise Exception( + "Expected constraints_ to be a Value, received: {}".format( + type(constraints_) + ) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) self.constraints = constraints_ self.error = error_ self.unknown_fields = unknown_fields - class ApplicationDeploy(Type): - _toSchema = {'application': 'application', 'attach_storage': 'attach-storage', 'channel': 'channel', 'charm_origin': 'charm-origin', 'charm_url': 'charm-url', 'config': 'config', 'config_yaml': 'config-yaml', 'constraints': 'constraints', 'devices': 'devices', 'endpoint_bindings': 'endpoint-bindings', 'force': 'Force', 'num_units': 'num-units', 'placement': 'placement', 'policy': 'policy', 'resources': 'resources', 'storage': 'storage'} - _toPy = {'Force': 'force', 'application': 'application', 'attach-storage': 'attach_storage', 'channel': 'channel', 'charm-origin': 'charm_origin', 'charm-url': 'charm_url', 'config': 'config', 'config-yaml': 'config_yaml', 'constraints': 'constraints', 'devices': 'devices', 'endpoint-bindings': 'endpoint_bindings', 'num-units': 'num_units', 'placement': 'placement', 'policy': 'policy', 'resources': 'resources', 'storage': 'storage'} - def __init__(self, force=None, application=None, attach_storage=None, channel=None, charm_origin=None, charm_url=None, config=None, config_yaml=None, constraints=None, devices=None, endpoint_bindings=None, num_units=None, placement=None, policy=None, resources=None, storage=None, **unknown_fields): - ''' + _toSchema = { + "application": "application", + "attach_storage": "attach-storage", + "channel": "channel", + "charm_origin": "charm-origin", + "charm_url": "charm-url", + "config": "config", + "config_yaml": "config-yaml", + "constraints": "constraints", + "devices": "devices", + "endpoint_bindings": "endpoint-bindings", + "force": "Force", + "num_units": "num-units", + "placement": "placement", + "policy": "policy", + "resources": "resources", + "storage": "storage", + } + _toPy = { + "Force": "force", + "application": "application", + "attach-storage": "attach_storage", + "channel": "channel", + "charm-origin": "charm_origin", + "charm-url": "charm_url", + "config": "config", + "config-yaml": "config_yaml", + "constraints": "constraints", + "devices": "devices", + "endpoint-bindings": "endpoint_bindings", + "num-units": "num_units", + "placement": "placement", + "policy": "policy", + "resources": "resources", + "storage": "storage", + } + + def __init__( + self, + force=None, + application=None, + attach_storage=None, + channel=None, + charm_origin=None, + charm_url=None, + config=None, + config_yaml=None, + constraints=None, + devices=None, + endpoint_bindings=None, + num_units=None, + placement=None, + policy=None, + resources=None, + storage=None, + **unknown_fields, + ): + """ force : bool application : str attach_storage : typing.Sequence[str] @@ -1231,7 +1898,7 @@ def __init__(self, force=None, application=None, attach_storage=None, channel=No policy : str resources : typing.Mapping[str, str] storage : typing.Mapping[str, ~Constraints] - ''' + """ force_ = force application_ = application attach_storage_ = attach_storage @@ -1251,52 +1918,104 @@ def __init__(self, force=None, application=None, attach_storage=None, channel=No # Validate arguments against known Juju API types. if force_ is not None and not isinstance(force_, bool): - raise Exception("Expected force_ to be a bool, received: {}".format(type(force_))) + raise Exception( + "Expected force_ to be a bool, received: {}".format(type(force_)) + ) if application_ is not None and not isinstance(application_, (bytes, str)): - raise Exception("Expected application_ to be a str, received: {}".format(type(application_))) - - if attach_storage_ is not None and not isinstance(attach_storage_, (bytes, str, list)): - raise Exception("Expected attach_storage_ to be a Sequence, received: {}".format(type(attach_storage_))) + raise Exception( + "Expected application_ to be a str, received: {}".format( + type(application_) + ) + ) + + if attach_storage_ is not None and not isinstance( + attach_storage_, (bytes, str, list) + ): + raise Exception( + "Expected attach_storage_ to be a Sequence, received: {}".format( + type(attach_storage_) + ) + ) if channel_ is not None and not isinstance(channel_, (bytes, str)): - raise Exception("Expected channel_ to be a str, received: {}".format(type(channel_))) - - if charm_origin_ is not None and not isinstance(charm_origin_, (dict, CharmOrigin)): - raise Exception("Expected charm_origin_ to be a CharmOrigin, received: {}".format(type(charm_origin_))) + raise Exception( + "Expected channel_ to be a str, received: {}".format(type(channel_)) + ) + + if charm_origin_ is not None and not isinstance( + charm_origin_, (dict, CharmOrigin) + ): + raise Exception( + "Expected charm_origin_ to be a CharmOrigin, received: {}".format( + type(charm_origin_) + ) + ) if charm_url_ is not None and not isinstance(charm_url_, (bytes, str)): - raise Exception("Expected charm_url_ to be a str, received: {}".format(type(charm_url_))) + raise Exception( + "Expected charm_url_ to be a str, received: {}".format(type(charm_url_)) + ) if config_ is not None and not isinstance(config_, dict): - raise Exception("Expected config_ to be a Mapping, received: {}".format(type(config_))) + raise Exception( + "Expected config_ to be a Mapping, received: {}".format(type(config_)) + ) if config_yaml_ is not None and not isinstance(config_yaml_, (bytes, str)): - raise Exception("Expected config_yaml_ to be a str, received: {}".format(type(config_yaml_))) + raise Exception( + "Expected config_yaml_ to be a str, received: {}".format( + type(config_yaml_) + ) + ) if constraints_ is not None and not isinstance(constraints_, (dict, Value)): - raise Exception("Expected constraints_ to be a Value, received: {}".format(type(constraints_))) + raise Exception( + "Expected constraints_ to be a Value, received: {}".format( + type(constraints_) + ) + ) if devices_ is not None and not isinstance(devices_, dict): - raise Exception("Expected devices_ to be a Mapping, received: {}".format(type(devices_))) + raise Exception( + "Expected devices_ to be a Mapping, received: {}".format(type(devices_)) + ) if endpoint_bindings_ is not None and not isinstance(endpoint_bindings_, dict): - raise Exception("Expected endpoint_bindings_ to be a Mapping, received: {}".format(type(endpoint_bindings_))) + raise Exception( + "Expected endpoint_bindings_ to be a Mapping, received: {}".format( + type(endpoint_bindings_) + ) + ) if num_units_ is not None and not isinstance(num_units_, int): - raise Exception("Expected num_units_ to be a int, received: {}".format(type(num_units_))) + raise Exception( + "Expected num_units_ to be a int, received: {}".format(type(num_units_)) + ) if placement_ is not None and not isinstance(placement_, (bytes, str, list)): - raise Exception("Expected placement_ to be a Sequence, received: {}".format(type(placement_))) + raise Exception( + "Expected placement_ to be a Sequence, received: {}".format( + type(placement_) + ) + ) if policy_ is not None and not isinstance(policy_, (bytes, str)): - raise Exception("Expected policy_ to be a str, received: {}".format(type(policy_))) + raise Exception( + "Expected policy_ to be a str, received: {}".format(type(policy_)) + ) if resources_ is not None and not isinstance(resources_, dict): - raise Exception("Expected resources_ to be a Mapping, received: {}".format(type(resources_))) + raise Exception( + "Expected resources_ to be a Mapping, received: {}".format( + type(resources_) + ) + ) if storage_ is not None and not isinstance(storage_, dict): - raise Exception("Expected storage_ to be a Mapping, received: {}".format(type(storage_))) + raise Exception( + "Expected storage_ to be a Mapping, received: {}".format(type(storage_)) + ) self.force = force_ self.application = application_ @@ -1317,114 +2036,170 @@ def __init__(self, force=None, application=None, attach_storage=None, channel=No self.unknown_fields = unknown_fields - class ApplicationExpose(Type): - _toSchema = {'application': 'application', 'exposed_endpoints': 'exposed-endpoints'} - _toPy = {'application': 'application', 'exposed-endpoints': 'exposed_endpoints'} + _toSchema = {"application": "application", "exposed_endpoints": "exposed-endpoints"} + _toPy = {"application": "application", "exposed-endpoints": "exposed_endpoints"} + def __init__(self, application=None, exposed_endpoints=None, **unknown_fields): - ''' + """ application : str exposed_endpoints : typing.Mapping[str, ~ExposedEndpoint] - ''' + """ application_ = application - exposed_endpoints_ = {k: ExposedEndpoint.from_json(v) for k, v in (exposed_endpoints or dict()).items()} + exposed_endpoints_ = { + k: ExposedEndpoint.from_json(v) + for k, v in (exposed_endpoints or dict()).items() + } # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): - raise Exception("Expected application_ to be a str, received: {}".format(type(application_))) + raise Exception( + "Expected application_ to be a str, received: {}".format( + type(application_) + ) + ) if exposed_endpoints_ is not None and not isinstance(exposed_endpoints_, dict): - raise Exception("Expected exposed_endpoints_ to be a Mapping, received: {}".format(type(exposed_endpoints_))) + raise Exception( + "Expected exposed_endpoints_ to be a Mapping, received: {}".format( + type(exposed_endpoints_) + ) + ) self.application = application_ self.exposed_endpoints = exposed_endpoints_ self.unknown_fields = unknown_fields - class ApplicationGet(Type): - _toSchema = {'application': 'application', 'branch': 'branch'} - _toPy = {'application': 'application', 'branch': 'branch'} + _toSchema = {"application": "application", "branch": "branch"} + _toPy = {"application": "application", "branch": "branch"} + def __init__(self, application=None, branch=None, **unknown_fields): - ''' + """ application : str branch : str - ''' + """ application_ = application branch_ = branch # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): - raise Exception("Expected application_ to be a str, received: {}".format(type(application_))) + raise Exception( + "Expected application_ to be a str, received: {}".format( + type(application_) + ) + ) if branch_ is not None and not isinstance(branch_, (bytes, str)): - raise Exception("Expected branch_ to be a str, received: {}".format(type(branch_))) + raise Exception( + "Expected branch_ to be a str, received: {}".format(type(branch_)) + ) self.application = application_ self.branch = branch_ self.unknown_fields = unknown_fields - class ApplicationGetArgs(Type): - _toSchema = {'args': 'args'} - _toPy = {'args': 'args'} + _toSchema = {"args": "args"} + _toPy = {"args": "args"} + def __init__(self, args=None, **unknown_fields): - ''' + """ args : typing.Sequence[~ApplicationGet] - ''' + """ args_ = [ApplicationGet.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception("Expected args_ to be a Sequence, received: {}".format(type(args_))) + raise Exception( + "Expected args_ to be a Sequence, received: {}".format(type(args_)) + ) self.args = args_ self.unknown_fields = unknown_fields - class ApplicationGetConfigResults(Type): - _toSchema = {'results': 'Results'} - _toPy = {'Results': 'results'} + _toSchema = {"results": "Results"} + _toPy = {"Results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~ConfigResult] - ''' + """ results_ = [ConfigResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class ApplicationGetConstraintsResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~ApplicationConstraint] - ''' + """ results_ = [ApplicationConstraint.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class ApplicationGetResults(Type): - _toSchema = {'application': 'application', 'application_config': 'application-config', 'base': 'base', 'channel': 'channel', 'charm': 'charm', 'config': 'config', 'constraints': 'constraints', 'endpoint_bindings': 'endpoint-bindings'} - _toPy = {'application': 'application', 'application-config': 'application_config', 'base': 'base', 'channel': 'channel', 'charm': 'charm', 'config': 'config', 'constraints': 'constraints', 'endpoint-bindings': 'endpoint_bindings'} - def __init__(self, application=None, application_config=None, base=None, channel=None, charm=None, config=None, constraints=None, endpoint_bindings=None, **unknown_fields): - ''' + _toSchema = { + "application": "application", + "application_config": "application-config", + "base": "base", + "channel": "channel", + "charm": "charm", + "config": "config", + "constraints": "constraints", + "endpoint_bindings": "endpoint-bindings", + } + _toPy = { + "application": "application", + "application-config": "application_config", + "base": "base", + "channel": "channel", + "charm": "charm", + "config": "config", + "constraints": "constraints", + "endpoint-bindings": "endpoint_bindings", + } + + def __init__( + self, + application=None, + application_config=None, + base=None, + channel=None, + charm=None, + config=None, + constraints=None, + endpoint_bindings=None, + **unknown_fields, + ): + """ application : str application_config : typing.Mapping[str, typing.Any] base : Base @@ -1433,7 +2208,7 @@ def __init__(self, application=None, application_config=None, base=None, channel config : typing.Mapping[str, typing.Any] constraints : Value endpoint_bindings : typing.Mapping[str, str] - ''' + """ application_ = application application_config_ = application_config base_ = Base.from_json(base) if base else None @@ -1445,28 +2220,54 @@ def __init__(self, application=None, application_config=None, base=None, channel # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): - raise Exception("Expected application_ to be a str, received: {}".format(type(application_))) - - if application_config_ is not None and not isinstance(application_config_, dict): - raise Exception("Expected application_config_ to be a Mapping, received: {}".format(type(application_config_))) + raise Exception( + "Expected application_ to be a str, received: {}".format( + type(application_) + ) + ) + + if application_config_ is not None and not isinstance( + application_config_, dict + ): + raise Exception( + "Expected application_config_ to be a Mapping, received: {}".format( + type(application_config_) + ) + ) if base_ is not None and not isinstance(base_, (dict, Base)): - raise Exception("Expected base_ to be a Base, received: {}".format(type(base_))) + raise Exception( + "Expected base_ to be a Base, received: {}".format(type(base_)) + ) if channel_ is not None and not isinstance(channel_, (bytes, str)): - raise Exception("Expected channel_ to be a str, received: {}".format(type(channel_))) + raise Exception( + "Expected channel_ to be a str, received: {}".format(type(channel_)) + ) if charm_ is not None and not isinstance(charm_, (bytes, str)): - raise Exception("Expected charm_ to be a str, received: {}".format(type(charm_))) + raise Exception( + "Expected charm_ to be a str, received: {}".format(type(charm_)) + ) if config_ is not None and not isinstance(config_, dict): - raise Exception("Expected config_ to be a Mapping, received: {}".format(type(config_))) + raise Exception( + "Expected config_ to be a Mapping, received: {}".format(type(config_)) + ) if constraints_ is not None and not isinstance(constraints_, (dict, Value)): - raise Exception("Expected constraints_ to be a Value, received: {}".format(type(constraints_))) + raise Exception( + "Expected constraints_ to be a Value, received: {}".format( + type(constraints_) + ) + ) if endpoint_bindings_ is not None and not isinstance(endpoint_bindings_, dict): - raise Exception("Expected endpoint_bindings_ to be a Mapping, received: {}".format(type(endpoint_bindings_))) + raise Exception( + "Expected endpoint_bindings_ to be a Mapping, received: {}".format( + type(endpoint_bindings_) + ) + ) self.application = application_ self.application_config = application_config_ @@ -1479,71 +2280,103 @@ def __init__(self, application=None, application_config=None, base=None, channel self.unknown_fields = unknown_fields - class ApplicationInfoResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : ApplicationResult - ''' + """ error_ = Error.from_json(error) if error else None result_ = ApplicationResult.from_json(result) if result else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if result_ is not None and not isinstance(result_, (dict, ApplicationResult)): - raise Exception("Expected result_ to be a ApplicationResult, received: {}".format(type(result_))) + raise Exception( + "Expected result_ to be a ApplicationResult, received: {}".format( + type(result_) + ) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class ApplicationInfoResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~ApplicationInfoResult] - ''' + """ results_ = [ApplicationInfoResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class ApplicationMergeBindings(Type): - _toSchema = {'application_tag': 'application-tag', 'bindings': 'bindings', 'force': 'force'} - _toPy = {'application-tag': 'application_tag', 'bindings': 'bindings', 'force': 'force'} - def __init__(self, application_tag=None, bindings=None, force=None, **unknown_fields): - ''' + _toSchema = { + "application_tag": "application-tag", + "bindings": "bindings", + "force": "force", + } + _toPy = { + "application-tag": "application_tag", + "bindings": "bindings", + "force": "force", + } + + def __init__( + self, application_tag=None, bindings=None, force=None, **unknown_fields + ): + """ application_tag : str bindings : typing.Mapping[str, str] force : bool - ''' + """ application_tag_ = application_tag bindings_ = bindings force_ = force # Validate arguments against known Juju API types. - if application_tag_ is not None and not isinstance(application_tag_, (bytes, str)): - raise Exception("Expected application_tag_ to be a str, received: {}".format(type(application_tag_))) + if application_tag_ is not None and not isinstance( + application_tag_, (bytes, str) + ): + raise Exception( + "Expected application_tag_ to be a str, received: {}".format( + type(application_tag_) + ) + ) if bindings_ is not None and not isinstance(bindings_, dict): - raise Exception("Expected bindings_ to be a Mapping, received: {}".format(type(bindings_))) + raise Exception( + "Expected bindings_ to be a Mapping, received: {}".format( + type(bindings_) + ) + ) if force_ is not None and not isinstance(force_, bool): - raise Exception("Expected force_ to be a bool, received: {}".format(type(force_))) + raise Exception( + "Expected force_ to be a bool, received: {}".format(type(force_)) + ) self.application_tag = application_tag_ self.bindings = bindings_ @@ -1551,72 +2384,133 @@ def __init__(self, application_tag=None, bindings=None, force=None, **unknown_fi self.unknown_fields = unknown_fields - class ApplicationMergeBindingsArgs(Type): - _toSchema = {'args': 'args'} - _toPy = {'args': 'args'} + _toSchema = {"args": "args"} + _toPy = {"args": "args"} + def __init__(self, args=None, **unknown_fields): - ''' + """ args : typing.Sequence[~ApplicationMergeBindings] - ''' + """ args_ = [ApplicationMergeBindings.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception("Expected args_ to be a Sequence, received: {}".format(type(args_))) + raise Exception( + "Expected args_ to be a Sequence, received: {}".format(type(args_)) + ) self.args = args_ self.unknown_fields = unknown_fields - class ApplicationMetricCredential(Type): - _toSchema = {'application': 'application', 'metrics_credentials': 'metrics-credentials'} - _toPy = {'application': 'application', 'metrics-credentials': 'metrics_credentials'} + _toSchema = { + "application": "application", + "metrics_credentials": "metrics-credentials", + } + _toPy = {"application": "application", "metrics-credentials": "metrics_credentials"} + def __init__(self, application=None, metrics_credentials=None, **unknown_fields): - ''' + """ application : str metrics_credentials : typing.Sequence[int] - ''' + """ application_ = application metrics_credentials_ = metrics_credentials # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): - raise Exception("Expected application_ to be a str, received: {}".format(type(application_))) - - if metrics_credentials_ is not None and not isinstance(metrics_credentials_, (bytes, str, list)): - raise Exception("Expected metrics_credentials_ to be a Sequence, received: {}".format(type(metrics_credentials_))) + raise Exception( + "Expected application_ to be a str, received: {}".format( + type(application_) + ) + ) + + if metrics_credentials_ is not None and not isinstance( + metrics_credentials_, (bytes, str, list) + ): + raise Exception( + "Expected metrics_credentials_ to be a Sequence, received: {}".format( + type(metrics_credentials_) + ) + ) self.application = application_ self.metrics_credentials = metrics_credentials_ self.unknown_fields = unknown_fields - class ApplicationMetricCredentials(Type): - _toSchema = {'creds': 'creds'} - _toPy = {'creds': 'creds'} + _toSchema = {"creds": "creds"} + _toPy = {"creds": "creds"} + def __init__(self, creds=None, **unknown_fields): - ''' + """ creds : typing.Sequence[~ApplicationMetricCredential] - ''' + """ creds_ = [ApplicationMetricCredential.from_json(o) for o in creds or []] # Validate arguments against known Juju API types. if creds_ is not None and not isinstance(creds_, (bytes, str, list)): - raise Exception("Expected creds_ to be a Sequence, received: {}".format(type(creds_))) + raise Exception( + "Expected creds_ to be a Sequence, received: {}".format(type(creds_)) + ) self.creds = creds_ self.unknown_fields = unknown_fields - class ApplicationOfferAdminDetails(Type): - _toSchema = {'application_description': 'application-description', 'application_name': 'application-name', 'applicationofferdetails': 'ApplicationOfferDetails', 'bindings': 'bindings', 'charm_url': 'charm-url', 'connections': 'connections', 'endpoints': 'endpoints', 'offer_name': 'offer-name', 'offer_url': 'offer-url', 'offer_uuid': 'offer-uuid', 'source_model_tag': 'source-model-tag', 'spaces': 'spaces', 'users': 'users'} - _toPy = {'ApplicationOfferDetails': 'applicationofferdetails', 'application-description': 'application_description', 'application-name': 'application_name', 'bindings': 'bindings', 'charm-url': 'charm_url', 'connections': 'connections', 'endpoints': 'endpoints', 'offer-name': 'offer_name', 'offer-url': 'offer_url', 'offer-uuid': 'offer_uuid', 'source-model-tag': 'source_model_tag', 'spaces': 'spaces', 'users': 'users'} - def __init__(self, applicationofferdetails=None, application_description=None, application_name=None, bindings=None, charm_url=None, connections=None, endpoints=None, offer_name=None, offer_url=None, offer_uuid=None, source_model_tag=None, spaces=None, users=None, **unknown_fields): - ''' + _toSchema = { + "application_description": "application-description", + "application_name": "application-name", + "applicationofferdetails": "ApplicationOfferDetails", + "bindings": "bindings", + "charm_url": "charm-url", + "connections": "connections", + "endpoints": "endpoints", + "offer_name": "offer-name", + "offer_url": "offer-url", + "offer_uuid": "offer-uuid", + "source_model_tag": "source-model-tag", + "spaces": "spaces", + "users": "users", + } + _toPy = { + "ApplicationOfferDetails": "applicationofferdetails", + "application-description": "application_description", + "application-name": "application_name", + "bindings": "bindings", + "charm-url": "charm_url", + "connections": "connections", + "endpoints": "endpoints", + "offer-name": "offer_name", + "offer-url": "offer_url", + "offer-uuid": "offer_uuid", + "source-model-tag": "source_model_tag", + "spaces": "spaces", + "users": "users", + } + + def __init__( + self, + applicationofferdetails=None, + application_description=None, + application_name=None, + bindings=None, + charm_url=None, + connections=None, + endpoints=None, + offer_name=None, + offer_url=None, + offer_uuid=None, + source_model_tag=None, + spaces=None, + users=None, + **unknown_fields, + ): + """ applicationofferdetails : ApplicationOfferDetails application_description : str application_name : str @@ -1630,8 +2524,12 @@ def __init__(self, applicationofferdetails=None, application_description=None, a source_model_tag : str spaces : typing.Sequence[~RemoteSpace] users : typing.Sequence[~OfferUserDetails] - ''' - applicationofferdetails_ = ApplicationOfferDetails.from_json(applicationofferdetails) if applicationofferdetails else None + """ + applicationofferdetails_ = ( + ApplicationOfferDetails.from_json(applicationofferdetails) + if applicationofferdetails + else None + ) application_description_ = application_description application_name_ = application_name bindings_ = bindings @@ -1646,44 +2544,98 @@ def __init__(self, applicationofferdetails=None, application_description=None, a users_ = [OfferUserDetails.from_json(o) for o in users or []] # Validate arguments against known Juju API types. - if applicationofferdetails_ is not None and not isinstance(applicationofferdetails_, (dict, ApplicationOfferDetails)): - raise Exception("Expected applicationofferdetails_ to be a ApplicationOfferDetails, received: {}".format(type(applicationofferdetails_))) - - if application_description_ is not None and not isinstance(application_description_, (bytes, str)): - raise Exception("Expected application_description_ to be a str, received: {}".format(type(application_description_))) - - if application_name_ is not None and not isinstance(application_name_, (bytes, str)): - raise Exception("Expected application_name_ to be a str, received: {}".format(type(application_name_))) + if applicationofferdetails_ is not None and not isinstance( + applicationofferdetails_, (dict, ApplicationOfferDetails) + ): + raise Exception( + "Expected applicationofferdetails_ to be a ApplicationOfferDetails, received: {}".format( + type(applicationofferdetails_) + ) + ) + + if application_description_ is not None and not isinstance( + application_description_, (bytes, str) + ): + raise Exception( + "Expected application_description_ to be a str, received: {}".format( + type(application_description_) + ) + ) + + if application_name_ is not None and not isinstance( + application_name_, (bytes, str) + ): + raise Exception( + "Expected application_name_ to be a str, received: {}".format( + type(application_name_) + ) + ) if bindings_ is not None and not isinstance(bindings_, dict): - raise Exception("Expected bindings_ to be a Mapping, received: {}".format(type(bindings_))) + raise Exception( + "Expected bindings_ to be a Mapping, received: {}".format( + type(bindings_) + ) + ) if charm_url_ is not None and not isinstance(charm_url_, (bytes, str)): - raise Exception("Expected charm_url_ to be a str, received: {}".format(type(charm_url_))) - - if connections_ is not None and not isinstance(connections_, (bytes, str, list)): - raise Exception("Expected connections_ to be a Sequence, received: {}".format(type(connections_))) + raise Exception( + "Expected charm_url_ to be a str, received: {}".format(type(charm_url_)) + ) + + if connections_ is not None and not isinstance( + connections_, (bytes, str, list) + ): + raise Exception( + "Expected connections_ to be a Sequence, received: {}".format( + type(connections_) + ) + ) if endpoints_ is not None and not isinstance(endpoints_, (bytes, str, list)): - raise Exception("Expected endpoints_ to be a Sequence, received: {}".format(type(endpoints_))) + raise Exception( + "Expected endpoints_ to be a Sequence, received: {}".format( + type(endpoints_) + ) + ) if offer_name_ is not None and not isinstance(offer_name_, (bytes, str)): - raise Exception("Expected offer_name_ to be a str, received: {}".format(type(offer_name_))) + raise Exception( + "Expected offer_name_ to be a str, received: {}".format( + type(offer_name_) + ) + ) if offer_url_ is not None and not isinstance(offer_url_, (bytes, str)): - raise Exception("Expected offer_url_ to be a str, received: {}".format(type(offer_url_))) + raise Exception( + "Expected offer_url_ to be a str, received: {}".format(type(offer_url_)) + ) if offer_uuid_ is not None and not isinstance(offer_uuid_, (bytes, str)): - raise Exception("Expected offer_uuid_ to be a str, received: {}".format(type(offer_uuid_))) - - if source_model_tag_ is not None and not isinstance(source_model_tag_, (bytes, str)): - raise Exception("Expected source_model_tag_ to be a str, received: {}".format(type(source_model_tag_))) + raise Exception( + "Expected offer_uuid_ to be a str, received: {}".format( + type(offer_uuid_) + ) + ) + + if source_model_tag_ is not None and not isinstance( + source_model_tag_, (bytes, str) + ): + raise Exception( + "Expected source_model_tag_ to be a str, received: {}".format( + type(source_model_tag_) + ) + ) if spaces_ is not None and not isinstance(spaces_, (bytes, str, list)): - raise Exception("Expected spaces_ to be a Sequence, received: {}".format(type(spaces_))) + raise Exception( + "Expected spaces_ to be a Sequence, received: {}".format(type(spaces_)) + ) if users_ is not None and not isinstance(users_, (bytes, str, list)): - raise Exception("Expected users_ to be a Sequence, received: {}".format(type(users_))) + raise Exception( + "Expected users_ to be a Sequence, received: {}".format(type(users_)) + ) self.applicationofferdetails = applicationofferdetails_ self.application_description = application_description_ @@ -1701,12 +2653,50 @@ def __init__(self, applicationofferdetails=None, application_description=None, a self.unknown_fields = unknown_fields - class ApplicationOfferAdminDetailsV5(Type): - _toSchema = {'application_description': 'application-description', 'application_name': 'application-name', 'applicationofferdetailsv5': 'ApplicationOfferDetailsV5', 'charm_url': 'charm-url', 'connections': 'connections', 'endpoints': 'endpoints', 'offer_name': 'offer-name', 'offer_url': 'offer-url', 'offer_uuid': 'offer-uuid', 'source_model_tag': 'source-model-tag', 'users': 'users'} - _toPy = {'ApplicationOfferDetailsV5': 'applicationofferdetailsv5', 'application-description': 'application_description', 'application-name': 'application_name', 'charm-url': 'charm_url', 'connections': 'connections', 'endpoints': 'endpoints', 'offer-name': 'offer_name', 'offer-url': 'offer_url', 'offer-uuid': 'offer_uuid', 'source-model-tag': 'source_model_tag', 'users': 'users'} - def __init__(self, applicationofferdetailsv5=None, application_description=None, application_name=None, charm_url=None, connections=None, endpoints=None, offer_name=None, offer_url=None, offer_uuid=None, source_model_tag=None, users=None, **unknown_fields): - ''' + _toSchema = { + "application_description": "application-description", + "application_name": "application-name", + "applicationofferdetailsv5": "ApplicationOfferDetailsV5", + "charm_url": "charm-url", + "connections": "connections", + "endpoints": "endpoints", + "offer_name": "offer-name", + "offer_url": "offer-url", + "offer_uuid": "offer-uuid", + "source_model_tag": "source-model-tag", + "users": "users", + } + _toPy = { + "ApplicationOfferDetailsV5": "applicationofferdetailsv5", + "application-description": "application_description", + "application-name": "application_name", + "charm-url": "charm_url", + "connections": "connections", + "endpoints": "endpoints", + "offer-name": "offer_name", + "offer-url": "offer_url", + "offer-uuid": "offer_uuid", + "source-model-tag": "source_model_tag", + "users": "users", + } + + def __init__( + self, + applicationofferdetailsv5=None, + application_description=None, + application_name=None, + charm_url=None, + connections=None, + endpoints=None, + offer_name=None, + offer_url=None, + offer_uuid=None, + source_model_tag=None, + users=None, + **unknown_fields, + ): + """ applicationofferdetailsv5 : ApplicationOfferDetailsV5 application_description : str application_name : str @@ -1718,8 +2708,12 @@ def __init__(self, applicationofferdetailsv5=None, application_description=None, offer_uuid : str source_model_tag : str users : typing.Sequence[~OfferUserDetails] - ''' - applicationofferdetailsv5_ = ApplicationOfferDetailsV5.from_json(applicationofferdetailsv5) if applicationofferdetailsv5 else None + """ + applicationofferdetailsv5_ = ( + ApplicationOfferDetailsV5.from_json(applicationofferdetailsv5) + if applicationofferdetailsv5 + else None + ) application_description_ = application_description application_name_ = application_name charm_url_ = charm_url @@ -1732,38 +2726,86 @@ def __init__(self, applicationofferdetailsv5=None, application_description=None, users_ = [OfferUserDetails.from_json(o) for o in users or []] # Validate arguments against known Juju API types. - if applicationofferdetailsv5_ is not None and not isinstance(applicationofferdetailsv5_, (dict, ApplicationOfferDetailsV5)): - raise Exception("Expected applicationofferdetailsv5_ to be a ApplicationOfferDetailsV5, received: {}".format(type(applicationofferdetailsv5_))) - - if application_description_ is not None and not isinstance(application_description_, (bytes, str)): - raise Exception("Expected application_description_ to be a str, received: {}".format(type(application_description_))) - - if application_name_ is not None and not isinstance(application_name_, (bytes, str)): - raise Exception("Expected application_name_ to be a str, received: {}".format(type(application_name_))) + if applicationofferdetailsv5_ is not None and not isinstance( + applicationofferdetailsv5_, (dict, ApplicationOfferDetailsV5) + ): + raise Exception( + "Expected applicationofferdetailsv5_ to be a ApplicationOfferDetailsV5, received: {}".format( + type(applicationofferdetailsv5_) + ) + ) + + if application_description_ is not None and not isinstance( + application_description_, (bytes, str) + ): + raise Exception( + "Expected application_description_ to be a str, received: {}".format( + type(application_description_) + ) + ) + + if application_name_ is not None and not isinstance( + application_name_, (bytes, str) + ): + raise Exception( + "Expected application_name_ to be a str, received: {}".format( + type(application_name_) + ) + ) if charm_url_ is not None and not isinstance(charm_url_, (bytes, str)): - raise Exception("Expected charm_url_ to be a str, received: {}".format(type(charm_url_))) - - if connections_ is not None and not isinstance(connections_, (bytes, str, list)): - raise Exception("Expected connections_ to be a Sequence, received: {}".format(type(connections_))) + raise Exception( + "Expected charm_url_ to be a str, received: {}".format(type(charm_url_)) + ) + + if connections_ is not None and not isinstance( + connections_, (bytes, str, list) + ): + raise Exception( + "Expected connections_ to be a Sequence, received: {}".format( + type(connections_) + ) + ) if endpoints_ is not None and not isinstance(endpoints_, (bytes, str, list)): - raise Exception("Expected endpoints_ to be a Sequence, received: {}".format(type(endpoints_))) + raise Exception( + "Expected endpoints_ to be a Sequence, received: {}".format( + type(endpoints_) + ) + ) if offer_name_ is not None and not isinstance(offer_name_, (bytes, str)): - raise Exception("Expected offer_name_ to be a str, received: {}".format(type(offer_name_))) + raise Exception( + "Expected offer_name_ to be a str, received: {}".format( + type(offer_name_) + ) + ) if offer_url_ is not None and not isinstance(offer_url_, (bytes, str)): - raise Exception("Expected offer_url_ to be a str, received: {}".format(type(offer_url_))) + raise Exception( + "Expected offer_url_ to be a str, received: {}".format(type(offer_url_)) + ) if offer_uuid_ is not None and not isinstance(offer_uuid_, (bytes, str)): - raise Exception("Expected offer_uuid_ to be a str, received: {}".format(type(offer_uuid_))) - - if source_model_tag_ is not None and not isinstance(source_model_tag_, (bytes, str)): - raise Exception("Expected source_model_tag_ to be a str, received: {}".format(type(source_model_tag_))) + raise Exception( + "Expected offer_uuid_ to be a str, received: {}".format( + type(offer_uuid_) + ) + ) + + if source_model_tag_ is not None and not isinstance( + source_model_tag_, (bytes, str) + ): + raise Exception( + "Expected source_model_tag_ to be a str, received: {}".format( + type(source_model_tag_) + ) + ) if users_ is not None and not isinstance(users_, (bytes, str, list)): - raise Exception("Expected users_ to be a Sequence, received: {}".format(type(users_))) + raise Exception( + "Expected users_ to be a Sequence, received: {}".format(type(users_)) + ) self.applicationofferdetailsv5 = applicationofferdetailsv5_ self.application_description = application_description_ @@ -1779,12 +2821,44 @@ def __init__(self, applicationofferdetailsv5=None, application_description=None, self.unknown_fields = unknown_fields - class ApplicationOfferDetails(Type): - _toSchema = {'application_description': 'application-description', 'bindings': 'bindings', 'endpoints': 'endpoints', 'offer_name': 'offer-name', 'offer_url': 'offer-url', 'offer_uuid': 'offer-uuid', 'source_model_tag': 'source-model-tag', 'spaces': 'spaces', 'users': 'users'} - _toPy = {'application-description': 'application_description', 'bindings': 'bindings', 'endpoints': 'endpoints', 'offer-name': 'offer_name', 'offer-url': 'offer_url', 'offer-uuid': 'offer_uuid', 'source-model-tag': 'source_model_tag', 'spaces': 'spaces', 'users': 'users'} - def __init__(self, application_description=None, bindings=None, endpoints=None, offer_name=None, offer_url=None, offer_uuid=None, source_model_tag=None, spaces=None, users=None, **unknown_fields): - ''' + _toSchema = { + "application_description": "application-description", + "bindings": "bindings", + "endpoints": "endpoints", + "offer_name": "offer-name", + "offer_url": "offer-url", + "offer_uuid": "offer-uuid", + "source_model_tag": "source-model-tag", + "spaces": "spaces", + "users": "users", + } + _toPy = { + "application-description": "application_description", + "bindings": "bindings", + "endpoints": "endpoints", + "offer-name": "offer_name", + "offer-url": "offer_url", + "offer-uuid": "offer_uuid", + "source-model-tag": "source_model_tag", + "spaces": "spaces", + "users": "users", + } + + def __init__( + self, + application_description=None, + bindings=None, + endpoints=None, + offer_name=None, + offer_url=None, + offer_uuid=None, + source_model_tag=None, + spaces=None, + users=None, + **unknown_fields, + ): + """ application_description : str bindings : typing.Mapping[str, str] endpoints : typing.Sequence[~RemoteEndpoint] @@ -1794,7 +2868,7 @@ def __init__(self, application_description=None, bindings=None, endpoints=None, source_model_tag : str spaces : typing.Sequence[~RemoteSpace] users : typing.Sequence[~OfferUserDetails] - ''' + """ application_description_ = application_description bindings_ = bindings endpoints_ = [RemoteEndpoint.from_json(o) for o in endpoints or []] @@ -1806,32 +2880,66 @@ def __init__(self, application_description=None, bindings=None, endpoints=None, users_ = [OfferUserDetails.from_json(o) for o in users or []] # Validate arguments against known Juju API types. - if application_description_ is not None and not isinstance(application_description_, (bytes, str)): - raise Exception("Expected application_description_ to be a str, received: {}".format(type(application_description_))) + if application_description_ is not None and not isinstance( + application_description_, (bytes, str) + ): + raise Exception( + "Expected application_description_ to be a str, received: {}".format( + type(application_description_) + ) + ) if bindings_ is not None and not isinstance(bindings_, dict): - raise Exception("Expected bindings_ to be a Mapping, received: {}".format(type(bindings_))) + raise Exception( + "Expected bindings_ to be a Mapping, received: {}".format( + type(bindings_) + ) + ) if endpoints_ is not None and not isinstance(endpoints_, (bytes, str, list)): - raise Exception("Expected endpoints_ to be a Sequence, received: {}".format(type(endpoints_))) + raise Exception( + "Expected endpoints_ to be a Sequence, received: {}".format( + type(endpoints_) + ) + ) if offer_name_ is not None and not isinstance(offer_name_, (bytes, str)): - raise Exception("Expected offer_name_ to be a str, received: {}".format(type(offer_name_))) + raise Exception( + "Expected offer_name_ to be a str, received: {}".format( + type(offer_name_) + ) + ) if offer_url_ is not None and not isinstance(offer_url_, (bytes, str)): - raise Exception("Expected offer_url_ to be a str, received: {}".format(type(offer_url_))) + raise Exception( + "Expected offer_url_ to be a str, received: {}".format(type(offer_url_)) + ) if offer_uuid_ is not None and not isinstance(offer_uuid_, (bytes, str)): - raise Exception("Expected offer_uuid_ to be a str, received: {}".format(type(offer_uuid_))) - - if source_model_tag_ is not None and not isinstance(source_model_tag_, (bytes, str)): - raise Exception("Expected source_model_tag_ to be a str, received: {}".format(type(source_model_tag_))) + raise Exception( + "Expected offer_uuid_ to be a str, received: {}".format( + type(offer_uuid_) + ) + ) + + if source_model_tag_ is not None and not isinstance( + source_model_tag_, (bytes, str) + ): + raise Exception( + "Expected source_model_tag_ to be a str, received: {}".format( + type(source_model_tag_) + ) + ) if spaces_ is not None and not isinstance(spaces_, (bytes, str, list)): - raise Exception("Expected spaces_ to be a Sequence, received: {}".format(type(spaces_))) + raise Exception( + "Expected spaces_ to be a Sequence, received: {}".format(type(spaces_)) + ) if users_ is not None and not isinstance(users_, (bytes, str, list)): - raise Exception("Expected users_ to be a Sequence, received: {}".format(type(users_))) + raise Exception( + "Expected users_ to be a Sequence, received: {}".format(type(users_)) + ) self.application_description = application_description_ self.bindings = bindings_ @@ -1845,12 +2953,38 @@ def __init__(self, application_description=None, bindings=None, endpoints=None, self.unknown_fields = unknown_fields - class ApplicationOfferDetailsV5(Type): - _toSchema = {'application_description': 'application-description', 'endpoints': 'endpoints', 'offer_name': 'offer-name', 'offer_url': 'offer-url', 'offer_uuid': 'offer-uuid', 'source_model_tag': 'source-model-tag', 'users': 'users'} - _toPy = {'application-description': 'application_description', 'endpoints': 'endpoints', 'offer-name': 'offer_name', 'offer-url': 'offer_url', 'offer-uuid': 'offer_uuid', 'source-model-tag': 'source_model_tag', 'users': 'users'} - def __init__(self, application_description=None, endpoints=None, offer_name=None, offer_url=None, offer_uuid=None, source_model_tag=None, users=None, **unknown_fields): - ''' + _toSchema = { + "application_description": "application-description", + "endpoints": "endpoints", + "offer_name": "offer-name", + "offer_url": "offer-url", + "offer_uuid": "offer-uuid", + "source_model_tag": "source-model-tag", + "users": "users", + } + _toPy = { + "application-description": "application_description", + "endpoints": "endpoints", + "offer-name": "offer_name", + "offer-url": "offer_url", + "offer-uuid": "offer_uuid", + "source-model-tag": "source_model_tag", + "users": "users", + } + + def __init__( + self, + application_description=None, + endpoints=None, + offer_name=None, + offer_url=None, + offer_uuid=None, + source_model_tag=None, + users=None, + **unknown_fields, + ): + """ application_description : str endpoints : typing.Sequence[~RemoteEndpoint] offer_name : str @@ -1858,7 +2992,7 @@ def __init__(self, application_description=None, endpoints=None, offer_name=None offer_uuid : str source_model_tag : str users : typing.Sequence[~OfferUserDetails] - ''' + """ application_description_ = application_description endpoints_ = [RemoteEndpoint.from_json(o) for o in endpoints or []] offer_name_ = offer_name @@ -1868,26 +3002,54 @@ def __init__(self, application_description=None, endpoints=None, offer_name=None users_ = [OfferUserDetails.from_json(o) for o in users or []] # Validate arguments against known Juju API types. - if application_description_ is not None and not isinstance(application_description_, (bytes, str)): - raise Exception("Expected application_description_ to be a str, received: {}".format(type(application_description_))) + if application_description_ is not None and not isinstance( + application_description_, (bytes, str) + ): + raise Exception( + "Expected application_description_ to be a str, received: {}".format( + type(application_description_) + ) + ) if endpoints_ is not None and not isinstance(endpoints_, (bytes, str, list)): - raise Exception("Expected endpoints_ to be a Sequence, received: {}".format(type(endpoints_))) + raise Exception( + "Expected endpoints_ to be a Sequence, received: {}".format( + type(endpoints_) + ) + ) if offer_name_ is not None and not isinstance(offer_name_, (bytes, str)): - raise Exception("Expected offer_name_ to be a str, received: {}".format(type(offer_name_))) + raise Exception( + "Expected offer_name_ to be a str, received: {}".format( + type(offer_name_) + ) + ) if offer_url_ is not None and not isinstance(offer_url_, (bytes, str)): - raise Exception("Expected offer_url_ to be a str, received: {}".format(type(offer_url_))) + raise Exception( + "Expected offer_url_ to be a str, received: {}".format(type(offer_url_)) + ) if offer_uuid_ is not None and not isinstance(offer_uuid_, (bytes, str)): - raise Exception("Expected offer_uuid_ to be a str, received: {}".format(type(offer_uuid_))) - - if source_model_tag_ is not None and not isinstance(source_model_tag_, (bytes, str)): - raise Exception("Expected source_model_tag_ to be a str, received: {}".format(type(source_model_tag_))) + raise Exception( + "Expected offer_uuid_ to be a str, received: {}".format( + type(offer_uuid_) + ) + ) + + if source_model_tag_ is not None and not isinstance( + source_model_tag_, (bytes, str) + ): + raise Exception( + "Expected source_model_tag_ to be a str, received: {}".format( + type(source_model_tag_) + ) + ) if users_ is not None and not isinstance(users_, (bytes, str, list)): - raise Exception("Expected users_ to be a Sequence, received: {}".format(type(users_))) + raise Exception( + "Expected users_ to be a Sequence, received: {}".format(type(users_)) + ) self.application_description = application_description_ self.endpoints = endpoints_ @@ -1899,36 +3061,70 @@ def __init__(self, application_description=None, endpoints=None, offer_name=None self.unknown_fields = unknown_fields - class ApplicationOfferResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : ApplicationOfferAdminDetailsV5 - ''' + """ error_ = Error.from_json(error) if error else None result_ = ApplicationOfferAdminDetailsV5.from_json(result) if result else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) - - if result_ is not None and not isinstance(result_, (dict, ApplicationOfferAdminDetailsV5)): - raise Exception("Expected result_ to be a ApplicationOfferAdminDetailsV5, received: {}".format(type(result_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) + + if result_ is not None and not isinstance( + result_, (dict, ApplicationOfferAdminDetailsV5) + ): + raise Exception( + "Expected result_ to be a ApplicationOfferAdminDetailsV5, received: {}".format( + type(result_) + ) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class ApplicationOfferStatus(Type): - _toSchema = {'active_connected_count': 'active-connected-count', 'application_name': 'application-name', 'charm': 'charm', 'endpoints': 'endpoints', 'err': 'err', 'offer_name': 'offer-name', 'total_connected_count': 'total-connected-count'} - _toPy = {'active-connected-count': 'active_connected_count', 'application-name': 'application_name', 'charm': 'charm', 'endpoints': 'endpoints', 'err': 'err', 'offer-name': 'offer_name', 'total-connected-count': 'total_connected_count'} - def __init__(self, active_connected_count=None, application_name=None, charm=None, endpoints=None, err=None, offer_name=None, total_connected_count=None, **unknown_fields): - ''' + _toSchema = { + "active_connected_count": "active-connected-count", + "application_name": "application-name", + "charm": "charm", + "endpoints": "endpoints", + "err": "err", + "offer_name": "offer-name", + "total_connected_count": "total-connected-count", + } + _toPy = { + "active-connected-count": "active_connected_count", + "application-name": "application_name", + "charm": "charm", + "endpoints": "endpoints", + "err": "err", + "offer-name": "offer_name", + "total-connected-count": "total_connected_count", + } + + def __init__( + self, + active_connected_count=None, + application_name=None, + charm=None, + endpoints=None, + err=None, + offer_name=None, + total_connected_count=None, + **unknown_fields, + ): + """ active_connected_count : int application_name : str charm : str @@ -1936,36 +3132,68 @@ def __init__(self, active_connected_count=None, application_name=None, charm=Non err : Error offer_name : str total_connected_count : int - ''' + """ active_connected_count_ = active_connected_count application_name_ = application_name charm_ = charm - endpoints_ = {k: RemoteEndpoint.from_json(v) for k, v in (endpoints or dict()).items()} + endpoints_ = { + k: RemoteEndpoint.from_json(v) for k, v in (endpoints or dict()).items() + } err_ = Error.from_json(err) if err else None offer_name_ = offer_name total_connected_count_ = total_connected_count # Validate arguments against known Juju API types. - if active_connected_count_ is not None and not isinstance(active_connected_count_, int): - raise Exception("Expected active_connected_count_ to be a int, received: {}".format(type(active_connected_count_))) - - if application_name_ is not None and not isinstance(application_name_, (bytes, str)): - raise Exception("Expected application_name_ to be a str, received: {}".format(type(application_name_))) + if active_connected_count_ is not None and not isinstance( + active_connected_count_, int + ): + raise Exception( + "Expected active_connected_count_ to be a int, received: {}".format( + type(active_connected_count_) + ) + ) + + if application_name_ is not None and not isinstance( + application_name_, (bytes, str) + ): + raise Exception( + "Expected application_name_ to be a str, received: {}".format( + type(application_name_) + ) + ) if charm_ is not None and not isinstance(charm_, (bytes, str)): - raise Exception("Expected charm_ to be a str, received: {}".format(type(charm_))) + raise Exception( + "Expected charm_ to be a str, received: {}".format(type(charm_)) + ) if endpoints_ is not None and not isinstance(endpoints_, dict): - raise Exception("Expected endpoints_ to be a Mapping, received: {}".format(type(endpoints_))) + raise Exception( + "Expected endpoints_ to be a Mapping, received: {}".format( + type(endpoints_) + ) + ) if err_ is not None and not isinstance(err_, (dict, Error)): - raise Exception("Expected err_ to be a Error, received: {}".format(type(err_))) + raise Exception( + "Expected err_ to be a Error, received: {}".format(type(err_)) + ) if offer_name_ is not None and not isinstance(offer_name_, (bytes, str)): - raise Exception("Expected offer_name_ to be a str, received: {}".format(type(offer_name_))) - - if total_connected_count_ is not None and not isinstance(total_connected_count_, int): - raise Exception("Expected total_connected_count_ to be a int, received: {}".format(type(total_connected_count_))) + raise Exception( + "Expected offer_name_ to be a str, received: {}".format( + type(offer_name_) + ) + ) + + if total_connected_count_ is not None and not isinstance( + total_connected_count_, int + ): + raise Exception( + "Expected total_connected_count_ to be a int, received: {}".format( + type(total_connected_count_) + ) + ) self.active_connected_count = active_connected_count_ self.application_name = application_name_ @@ -1977,30 +3205,72 @@ def __init__(self, active_connected_count=None, application_name=None, charm=Non self.unknown_fields = unknown_fields - class ApplicationOffersResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~ApplicationOfferResult] - ''' + """ results_ = [ApplicationOfferResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class ApplicationResult(Type): - _toSchema = {'base': 'base', 'channel': 'channel', 'charm': 'charm', 'constraints': 'constraints', 'endpoint_bindings': 'endpoint-bindings', 'exposed': 'exposed', 'exposed_endpoints': 'exposed-endpoints', 'life': 'life', 'principal': 'principal', 'remote': 'remote', 'tag': 'tag'} - _toPy = {'base': 'base', 'channel': 'channel', 'charm': 'charm', 'constraints': 'constraints', 'endpoint-bindings': 'endpoint_bindings', 'exposed': 'exposed', 'exposed-endpoints': 'exposed_endpoints', 'life': 'life', 'principal': 'principal', 'remote': 'remote', 'tag': 'tag'} - def __init__(self, base=None, channel=None, charm=None, constraints=None, endpoint_bindings=None, exposed=None, exposed_endpoints=None, life=None, principal=None, remote=None, tag=None, **unknown_fields): - ''' + _toSchema = { + "base": "base", + "channel": "channel", + "charm": "charm", + "constraints": "constraints", + "endpoint_bindings": "endpoint-bindings", + "exposed": "exposed", + "exposed_endpoints": "exposed-endpoints", + "life": "life", + "principal": "principal", + "remote": "remote", + "tag": "tag", + } + _toPy = { + "base": "base", + "channel": "channel", + "charm": "charm", + "constraints": "constraints", + "endpoint-bindings": "endpoint_bindings", + "exposed": "exposed", + "exposed-endpoints": "exposed_endpoints", + "life": "life", + "principal": "principal", + "remote": "remote", + "tag": "tag", + } + + def __init__( + self, + base=None, + channel=None, + charm=None, + constraints=None, + endpoint_bindings=None, + exposed=None, + exposed_endpoints=None, + life=None, + principal=None, + remote=None, + tag=None, + **unknown_fields, + ): + """ base : Base channel : str charm : str @@ -2012,14 +3282,17 @@ def __init__(self, base=None, channel=None, charm=None, constraints=None, endpoi principal : bool remote : bool tag : str - ''' + """ base_ = Base.from_json(base) if base else None channel_ = channel charm_ = charm constraints_ = Value.from_json(constraints) if constraints else None endpoint_bindings_ = endpoint_bindings exposed_ = exposed - exposed_endpoints_ = {k: ExposedEndpoint.from_json(v) for k, v in (exposed_endpoints or dict()).items()} + exposed_endpoints_ = { + k: ExposedEndpoint.from_json(v) + for k, v in (exposed_endpoints or dict()).items() + } life_ = life principal_ = principal remote_ = remote @@ -2027,37 +3300,67 @@ def __init__(self, base=None, channel=None, charm=None, constraints=None, endpoi # Validate arguments against known Juju API types. if base_ is not None and not isinstance(base_, (dict, Base)): - raise Exception("Expected base_ to be a Base, received: {}".format(type(base_))) + raise Exception( + "Expected base_ to be a Base, received: {}".format(type(base_)) + ) if channel_ is not None and not isinstance(channel_, (bytes, str)): - raise Exception("Expected channel_ to be a str, received: {}".format(type(channel_))) + raise Exception( + "Expected channel_ to be a str, received: {}".format(type(channel_)) + ) if charm_ is not None and not isinstance(charm_, (bytes, str)): - raise Exception("Expected charm_ to be a str, received: {}".format(type(charm_))) + raise Exception( + "Expected charm_ to be a str, received: {}".format(type(charm_)) + ) if constraints_ is not None and not isinstance(constraints_, (dict, Value)): - raise Exception("Expected constraints_ to be a Value, received: {}".format(type(constraints_))) + raise Exception( + "Expected constraints_ to be a Value, received: {}".format( + type(constraints_) + ) + ) if endpoint_bindings_ is not None and not isinstance(endpoint_bindings_, dict): - raise Exception("Expected endpoint_bindings_ to be a Mapping, received: {}".format(type(endpoint_bindings_))) + raise Exception( + "Expected endpoint_bindings_ to be a Mapping, received: {}".format( + type(endpoint_bindings_) + ) + ) if exposed_ is not None and not isinstance(exposed_, bool): - raise Exception("Expected exposed_ to be a bool, received: {}".format(type(exposed_))) + raise Exception( + "Expected exposed_ to be a bool, received: {}".format(type(exposed_)) + ) if exposed_endpoints_ is not None and not isinstance(exposed_endpoints_, dict): - raise Exception("Expected exposed_endpoints_ to be a Mapping, received: {}".format(type(exposed_endpoints_))) + raise Exception( + "Expected exposed_endpoints_ to be a Mapping, received: {}".format( + type(exposed_endpoints_) + ) + ) if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception("Expected life_ to be a str, received: {}".format(type(life_))) + raise Exception( + "Expected life_ to be a str, received: {}".format(type(life_)) + ) if principal_ is not None and not isinstance(principal_, bool): - raise Exception("Expected principal_ to be a bool, received: {}".format(type(principal_))) + raise Exception( + "Expected principal_ to be a bool, received: {}".format( + type(principal_) + ) + ) if remote_ is not None and not isinstance(remote_, bool): - raise Exception("Expected remote_ to be a bool, received: {}".format(type(remote_))) + raise Exception( + "Expected remote_ to be a bool, received: {}".format(type(remote_)) + ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception("Expected tag_ to be a str, received: {}".format(type(tag_))) + raise Exception( + "Expected tag_ to be a str, received: {}".format(type(tag_)) + ) self.base = base_ self.channel = channel_ @@ -2073,12 +3376,56 @@ def __init__(self, base=None, channel=None, charm=None, constraints=None, endpoi self.unknown_fields = unknown_fields - class ApplicationSetCharm(Type): - _toSchema = {'application': 'application', 'channel': 'channel', 'charm_origin': 'charm-origin', 'charm_url': 'charm-url', 'config_settings': 'config-settings', 'config_settings_yaml': 'config-settings-yaml', 'endpoint_bindings': 'endpoint-bindings', 'force': 'force', 'force_base': 'force-base', 'force_units': 'force-units', 'generation': 'generation', 'resource_ids': 'resource-ids', 'storage_constraints': 'storage-constraints'} - _toPy = {'application': 'application', 'channel': 'channel', 'charm-origin': 'charm_origin', 'charm-url': 'charm_url', 'config-settings': 'config_settings', 'config-settings-yaml': 'config_settings_yaml', 'endpoint-bindings': 'endpoint_bindings', 'force': 'force', 'force-base': 'force_base', 'force-units': 'force_units', 'generation': 'generation', 'resource-ids': 'resource_ids', 'storage-constraints': 'storage_constraints'} - def __init__(self, application=None, channel=None, charm_origin=None, charm_url=None, config_settings=None, config_settings_yaml=None, endpoint_bindings=None, force=None, force_base=None, force_units=None, generation=None, resource_ids=None, storage_constraints=None, **unknown_fields): - ''' + _toSchema = { + "application": "application", + "channel": "channel", + "charm_origin": "charm-origin", + "charm_url": "charm-url", + "config_settings": "config-settings", + "config_settings_yaml": "config-settings-yaml", + "endpoint_bindings": "endpoint-bindings", + "force": "force", + "force_base": "force-base", + "force_units": "force-units", + "generation": "generation", + "resource_ids": "resource-ids", + "storage_constraints": "storage-constraints", + } + _toPy = { + "application": "application", + "channel": "channel", + "charm-origin": "charm_origin", + "charm-url": "charm_url", + "config-settings": "config_settings", + "config-settings-yaml": "config_settings_yaml", + "endpoint-bindings": "endpoint_bindings", + "force": "force", + "force-base": "force_base", + "force-units": "force_units", + "generation": "generation", + "resource-ids": "resource_ids", + "storage-constraints": "storage_constraints", + } + + def __init__( + self, + application=None, + channel=None, + charm_origin=None, + charm_url=None, + config_settings=None, + config_settings_yaml=None, + endpoint_bindings=None, + force=None, + force_base=None, + force_units=None, + generation=None, + resource_ids=None, + storage_constraints=None, + **unknown_fields, + ): + """ application : str channel : str charm_origin : CharmOrigin @@ -2092,7 +3439,7 @@ def __init__(self, application=None, channel=None, charm_origin=None, charm_url= generation : str resource_ids : typing.Mapping[str, str] storage_constraints : typing.Mapping[str, ~StorageConstraints] - ''' + """ application_ = application channel_ = channel charm_origin_ = CharmOrigin.from_json(charm_origin) if charm_origin else None @@ -2105,47 +3452,102 @@ def __init__(self, application=None, channel=None, charm_origin=None, charm_url= force_units_ = force_units generation_ = generation resource_ids_ = resource_ids - storage_constraints_ = {k: StorageConstraints.from_json(v) for k, v in (storage_constraints or dict()).items()} + storage_constraints_ = { + k: StorageConstraints.from_json(v) + for k, v in (storage_constraints or dict()).items() + } # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): - raise Exception("Expected application_ to be a str, received: {}".format(type(application_))) + raise Exception( + "Expected application_ to be a str, received: {}".format( + type(application_) + ) + ) if channel_ is not None and not isinstance(channel_, (bytes, str)): - raise Exception("Expected channel_ to be a str, received: {}".format(type(channel_))) - - if charm_origin_ is not None and not isinstance(charm_origin_, (dict, CharmOrigin)): - raise Exception("Expected charm_origin_ to be a CharmOrigin, received: {}".format(type(charm_origin_))) + raise Exception( + "Expected channel_ to be a str, received: {}".format(type(channel_)) + ) + + if charm_origin_ is not None and not isinstance( + charm_origin_, (dict, CharmOrigin) + ): + raise Exception( + "Expected charm_origin_ to be a CharmOrigin, received: {}".format( + type(charm_origin_) + ) + ) if charm_url_ is not None and not isinstance(charm_url_, (bytes, str)): - raise Exception("Expected charm_url_ to be a str, received: {}".format(type(charm_url_))) + raise Exception( + "Expected charm_url_ to be a str, received: {}".format(type(charm_url_)) + ) if config_settings_ is not None and not isinstance(config_settings_, dict): - raise Exception("Expected config_settings_ to be a Mapping, received: {}".format(type(config_settings_))) - - if config_settings_yaml_ is not None and not isinstance(config_settings_yaml_, (bytes, str)): - raise Exception("Expected config_settings_yaml_ to be a str, received: {}".format(type(config_settings_yaml_))) + raise Exception( + "Expected config_settings_ to be a Mapping, received: {}".format( + type(config_settings_) + ) + ) + + if config_settings_yaml_ is not None and not isinstance( + config_settings_yaml_, (bytes, str) + ): + raise Exception( + "Expected config_settings_yaml_ to be a str, received: {}".format( + type(config_settings_yaml_) + ) + ) if endpoint_bindings_ is not None and not isinstance(endpoint_bindings_, dict): - raise Exception("Expected endpoint_bindings_ to be a Mapping, received: {}".format(type(endpoint_bindings_))) + raise Exception( + "Expected endpoint_bindings_ to be a Mapping, received: {}".format( + type(endpoint_bindings_) + ) + ) if force_ is not None and not isinstance(force_, bool): - raise Exception("Expected force_ to be a bool, received: {}".format(type(force_))) + raise Exception( + "Expected force_ to be a bool, received: {}".format(type(force_)) + ) if force_base_ is not None and not isinstance(force_base_, bool): - raise Exception("Expected force_base_ to be a bool, received: {}".format(type(force_base_))) + raise Exception( + "Expected force_base_ to be a bool, received: {}".format( + type(force_base_) + ) + ) if force_units_ is not None and not isinstance(force_units_, bool): - raise Exception("Expected force_units_ to be a bool, received: {}".format(type(force_units_))) + raise Exception( + "Expected force_units_ to be a bool, received: {}".format( + type(force_units_) + ) + ) if generation_ is not None and not isinstance(generation_, (bytes, str)): - raise Exception("Expected generation_ to be a str, received: {}".format(type(generation_))) + raise Exception( + "Expected generation_ to be a str, received: {}".format( + type(generation_) + ) + ) if resource_ids_ is not None and not isinstance(resource_ids_, dict): - raise Exception("Expected resource_ids_ to be a Mapping, received: {}".format(type(resource_ids_))) - - if storage_constraints_ is not None and not isinstance(storage_constraints_, dict): - raise Exception("Expected storage_constraints_ to be a Mapping, received: {}".format(type(storage_constraints_))) + raise Exception( + "Expected resource_ids_ to be a Mapping, received: {}".format( + type(resource_ids_) + ) + ) + + if storage_constraints_ is not None and not isinstance( + storage_constraints_, dict + ): + raise Exception( + "Expected storage_constraints_ to be a Mapping, received: {}".format( + type(storage_constraints_) + ) + ) self.application = application_ self.channel = channel_ @@ -2163,12 +3565,77 @@ def __init__(self, application=None, channel=None, charm_origin=None, charm_url= self.unknown_fields = unknown_fields - class ApplicationStatus(Type): - _toSchema = {'base': 'base', 'can_upgrade_to': 'can-upgrade-to', 'charm': 'charm', 'charm_channel': 'charm-channel', 'charm_profile': 'charm-profile', 'charm_version': 'charm-version', 'endpoint_bindings': 'endpoint-bindings', 'err': 'err', 'exposed': 'exposed', 'exposed_endpoints': 'exposed-endpoints', 'int_': 'int', 'life': 'life', 'meter_statuses': 'meter-statuses', 'provider_id': 'provider-id', 'public_address': 'public-address', 'relations': 'relations', 'status': 'status', 'subordinate_to': 'subordinate-to', 'units': 'units', 'workload_version': 'workload-version'} - _toPy = {'base': 'base', 'can-upgrade-to': 'can_upgrade_to', 'charm': 'charm', 'charm-channel': 'charm_channel', 'charm-profile': 'charm_profile', 'charm-version': 'charm_version', 'endpoint-bindings': 'endpoint_bindings', 'err': 'err', 'exposed': 'exposed', 'exposed-endpoints': 'exposed_endpoints', 'int': 'int_', 'life': 'life', 'meter-statuses': 'meter_statuses', 'provider-id': 'provider_id', 'public-address': 'public_address', 'relations': 'relations', 'status': 'status', 'subordinate-to': 'subordinate_to', 'units': 'units', 'workload-version': 'workload_version'} - def __init__(self, base=None, can_upgrade_to=None, charm=None, charm_channel=None, charm_profile=None, charm_version=None, endpoint_bindings=None, err=None, exposed=None, exposed_endpoints=None, int_=None, life=None, meter_statuses=None, provider_id=None, public_address=None, relations=None, status=None, subordinate_to=None, units=None, workload_version=None, **unknown_fields): - ''' + _toSchema = { + "base": "base", + "can_upgrade_to": "can-upgrade-to", + "charm": "charm", + "charm_channel": "charm-channel", + "charm_profile": "charm-profile", + "charm_version": "charm-version", + "endpoint_bindings": "endpoint-bindings", + "err": "err", + "exposed": "exposed", + "exposed_endpoints": "exposed-endpoints", + "int_": "int", + "life": "life", + "meter_statuses": "meter-statuses", + "provider_id": "provider-id", + "public_address": "public-address", + "relations": "relations", + "status": "status", + "subordinate_to": "subordinate-to", + "units": "units", + "workload_version": "workload-version", + } + _toPy = { + "base": "base", + "can-upgrade-to": "can_upgrade_to", + "charm": "charm", + "charm-channel": "charm_channel", + "charm-profile": "charm_profile", + "charm-version": "charm_version", + "endpoint-bindings": "endpoint_bindings", + "err": "err", + "exposed": "exposed", + "exposed-endpoints": "exposed_endpoints", + "int": "int_", + "life": "life", + "meter-statuses": "meter_statuses", + "provider-id": "provider_id", + "public-address": "public_address", + "relations": "relations", + "status": "status", + "subordinate-to": "subordinate_to", + "units": "units", + "workload-version": "workload_version", + } + + def __init__( + self, + base=None, + can_upgrade_to=None, + charm=None, + charm_channel=None, + charm_profile=None, + charm_version=None, + endpoint_bindings=None, + err=None, + exposed=None, + exposed_endpoints=None, + int_=None, + life=None, + meter_statuses=None, + provider_id=None, + public_address=None, + relations=None, + status=None, + subordinate_to=None, + units=None, + workload_version=None, + **unknown_fields, + ): + """ base : Base can_upgrade_to : str charm : str @@ -2189,7 +3656,7 @@ def __init__(self, base=None, can_upgrade_to=None, charm=None, charm_channel=Non subordinate_to : typing.Sequence[str] units : typing.Mapping[str, ~UnitStatus] workload_version : str - ''' + """ base_ = Base.from_json(base) if base else None can_upgrade_to_ = can_upgrade_to charm_ = charm @@ -2199,10 +3666,15 @@ def __init__(self, base=None, can_upgrade_to=None, charm=None, charm_channel=Non endpoint_bindings_ = endpoint_bindings err_ = Error.from_json(err) if err else None exposed_ = exposed - exposed_endpoints_ = {k: ExposedEndpoint.from_json(v) for k, v in (exposed_endpoints or dict()).items()} + exposed_endpoints_ = { + k: ExposedEndpoint.from_json(v) + for k, v in (exposed_endpoints or dict()).items() + } int__ = int_ life_ = life - meter_statuses_ = {k: MeterStatus.from_json(v) for k, v in (meter_statuses or dict()).items()} + meter_statuses_ = { + k: MeterStatus.from_json(v) for k, v in (meter_statuses or dict()).items() + } provider_id_ = provider_id public_address_ = public_address relations_ = relations @@ -2213,64 +3685,138 @@ def __init__(self, base=None, can_upgrade_to=None, charm=None, charm_channel=Non # Validate arguments against known Juju API types. if base_ is not None and not isinstance(base_, (dict, Base)): - raise Exception("Expected base_ to be a Base, received: {}".format(type(base_))) - - if can_upgrade_to_ is not None and not isinstance(can_upgrade_to_, (bytes, str)): - raise Exception("Expected can_upgrade_to_ to be a str, received: {}".format(type(can_upgrade_to_))) + raise Exception( + "Expected base_ to be a Base, received: {}".format(type(base_)) + ) + + if can_upgrade_to_ is not None and not isinstance( + can_upgrade_to_, (bytes, str) + ): + raise Exception( + "Expected can_upgrade_to_ to be a str, received: {}".format( + type(can_upgrade_to_) + ) + ) if charm_ is not None and not isinstance(charm_, (bytes, str)): - raise Exception("Expected charm_ to be a str, received: {}".format(type(charm_))) + raise Exception( + "Expected charm_ to be a str, received: {}".format(type(charm_)) + ) if charm_channel_ is not None and not isinstance(charm_channel_, (bytes, str)): - raise Exception("Expected charm_channel_ to be a str, received: {}".format(type(charm_channel_))) + raise Exception( + "Expected charm_channel_ to be a str, received: {}".format( + type(charm_channel_) + ) + ) if charm_profile_ is not None and not isinstance(charm_profile_, (bytes, str)): - raise Exception("Expected charm_profile_ to be a str, received: {}".format(type(charm_profile_))) + raise Exception( + "Expected charm_profile_ to be a str, received: {}".format( + type(charm_profile_) + ) + ) if charm_version_ is not None and not isinstance(charm_version_, (bytes, str)): - raise Exception("Expected charm_version_ to be a str, received: {}".format(type(charm_version_))) + raise Exception( + "Expected charm_version_ to be a str, received: {}".format( + type(charm_version_) + ) + ) if endpoint_bindings_ is not None and not isinstance(endpoint_bindings_, dict): - raise Exception("Expected endpoint_bindings_ to be a Mapping, received: {}".format(type(endpoint_bindings_))) + raise Exception( + "Expected endpoint_bindings_ to be a Mapping, received: {}".format( + type(endpoint_bindings_) + ) + ) if err_ is not None and not isinstance(err_, (dict, Error)): - raise Exception("Expected err_ to be a Error, received: {}".format(type(err_))) + raise Exception( + "Expected err_ to be a Error, received: {}".format(type(err_)) + ) if exposed_ is not None and not isinstance(exposed_, bool): - raise Exception("Expected exposed_ to be a bool, received: {}".format(type(exposed_))) + raise Exception( + "Expected exposed_ to be a bool, received: {}".format(type(exposed_)) + ) if exposed_endpoints_ is not None and not isinstance(exposed_endpoints_, dict): - raise Exception("Expected exposed_endpoints_ to be a Mapping, received: {}".format(type(exposed_endpoints_))) + raise Exception( + "Expected exposed_endpoints_ to be a Mapping, received: {}".format( + type(exposed_endpoints_) + ) + ) if int__ is not None and not isinstance(int__, int): - raise Exception("Expected int__ to be a int, received: {}".format(type(int__))) + raise Exception( + "Expected int__ to be a int, received: {}".format(type(int__)) + ) if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception("Expected life_ to be a str, received: {}".format(type(life_))) + raise Exception( + "Expected life_ to be a str, received: {}".format(type(life_)) + ) if meter_statuses_ is not None and not isinstance(meter_statuses_, dict): - raise Exception("Expected meter_statuses_ to be a Mapping, received: {}".format(type(meter_statuses_))) + raise Exception( + "Expected meter_statuses_ to be a Mapping, received: {}".format( + type(meter_statuses_) + ) + ) if provider_id_ is not None and not isinstance(provider_id_, (bytes, str)): - raise Exception("Expected provider_id_ to be a str, received: {}".format(type(provider_id_))) - - if public_address_ is not None and not isinstance(public_address_, (bytes, str)): - raise Exception("Expected public_address_ to be a str, received: {}".format(type(public_address_))) + raise Exception( + "Expected provider_id_ to be a str, received: {}".format( + type(provider_id_) + ) + ) + + if public_address_ is not None and not isinstance( + public_address_, (bytes, str) + ): + raise Exception( + "Expected public_address_ to be a str, received: {}".format( + type(public_address_) + ) + ) if relations_ is not None and not isinstance(relations_, dict): - raise Exception("Expected relations_ to be a Mapping, received: {}".format(type(relations_))) + raise Exception( + "Expected relations_ to be a Mapping, received: {}".format( + type(relations_) + ) + ) if status_ is not None and not isinstance(status_, (dict, DetailedStatus)): - raise Exception("Expected status_ to be a DetailedStatus, received: {}".format(type(status_))) - - if subordinate_to_ is not None and not isinstance(subordinate_to_, (bytes, str, list)): - raise Exception("Expected subordinate_to_ to be a Sequence, received: {}".format(type(subordinate_to_))) + raise Exception( + "Expected status_ to be a DetailedStatus, received: {}".format( + type(status_) + ) + ) + + if subordinate_to_ is not None and not isinstance( + subordinate_to_, (bytes, str, list) + ): + raise Exception( + "Expected subordinate_to_ to be a Sequence, received: {}".format( + type(subordinate_to_) + ) + ) if units_ is not None and not isinstance(units_, dict): - raise Exception("Expected units_ to be a Mapping, received: {}".format(type(units_))) - - if workload_version_ is not None and not isinstance(workload_version_, (bytes, str)): - raise Exception("Expected workload_version_ to be a str, received: {}".format(type(workload_version_))) + raise Exception( + "Expected units_ to be a Mapping, received: {}".format(type(units_)) + ) + + if workload_version_ is not None and not isinstance( + workload_version_, (bytes, str) + ): + raise Exception( + "Expected workload_version_ to be a str, received: {}".format( + type(workload_version_) + ) + ) self.base = base_ self.can_upgrade_to = can_upgrade_to_ @@ -2295,53 +3841,73 @@ def __init__(self, base=None, can_upgrade_to=None, charm=None, charm_channel=Non self.unknown_fields = unknown_fields - class ApplicationUnexpose(Type): - _toSchema = {'application': 'application', 'exposed_endpoints': 'exposed-endpoints'} - _toPy = {'application': 'application', 'exposed-endpoints': 'exposed_endpoints'} + _toSchema = {"application": "application", "exposed_endpoints": "exposed-endpoints"} + _toPy = {"application": "application", "exposed-endpoints": "exposed_endpoints"} + def __init__(self, application=None, exposed_endpoints=None, **unknown_fields): - ''' + """ application : str exposed_endpoints : typing.Sequence[str] - ''' + """ application_ = application exposed_endpoints_ = exposed_endpoints # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): - raise Exception("Expected application_ to be a str, received: {}".format(type(application_))) - - if exposed_endpoints_ is not None and not isinstance(exposed_endpoints_, (bytes, str, list)): - raise Exception("Expected exposed_endpoints_ to be a Sequence, received: {}".format(type(exposed_endpoints_))) + raise Exception( + "Expected application_ to be a str, received: {}".format( + type(application_) + ) + ) + + if exposed_endpoints_ is not None and not isinstance( + exposed_endpoints_, (bytes, str, list) + ): + raise Exception( + "Expected exposed_endpoints_ to be a Sequence, received: {}".format( + type(exposed_endpoints_) + ) + ) self.application = application_ self.exposed_endpoints = exposed_endpoints_ self.unknown_fields = unknown_fields - class ApplicationUnset(Type): - _toSchema = {'application': 'application', 'branch': 'branch', 'options': 'options'} - _toPy = {'application': 'application', 'branch': 'branch', 'options': 'options'} + _toSchema = {"application": "application", "branch": "branch", "options": "options"} + _toPy = {"application": "application", "branch": "branch", "options": "options"} + def __init__(self, application=None, branch=None, options=None, **unknown_fields): - ''' + """ application : str branch : str options : typing.Sequence[str] - ''' + """ application_ = application branch_ = branch options_ = options # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): - raise Exception("Expected application_ to be a str, received: {}".format(type(application_))) + raise Exception( + "Expected application_ to be a str, received: {}".format( + type(application_) + ) + ) if branch_ is not None and not isinstance(branch_, (bytes, str)): - raise Exception("Expected branch_ to be a str, received: {}".format(type(branch_))) + raise Exception( + "Expected branch_ to be a str, received: {}".format(type(branch_)) + ) if options_ is not None and not isinstance(options_, (bytes, str, list)): - raise Exception("Expected options_ to be a Sequence, received: {}".format(type(options_))) + raise Exception( + "Expected options_ to be a Sequence, received: {}".format( + type(options_) + ) + ) self.application = application_ self.branch = branch_ @@ -2349,55 +3915,88 @@ def __init__(self, application=None, branch=None, options=None, **unknown_fields self.unknown_fields = unknown_fields - class ApplicationsCharmActionsResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~ApplicationCharmActionsResult] - ''' + """ results_ = [ApplicationCharmActionsResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class ApplicationsDeploy(Type): - _toSchema = {'applications': 'applications'} - _toPy = {'applications': 'applications'} + _toSchema = {"applications": "applications"} + _toPy = {"applications": "applications"} + def __init__(self, applications=None, **unknown_fields): - ''' + """ applications : typing.Sequence[~ApplicationDeploy] - ''' + """ applications_ = [ApplicationDeploy.from_json(o) for o in applications or []] # Validate arguments against known Juju API types. - if applications_ is not None and not isinstance(applications_, (bytes, str, list)): - raise Exception("Expected applications_ to be a Sequence, received: {}".format(type(applications_))) + if applications_ is not None and not isinstance( + applications_, (bytes, str, list) + ): + raise Exception( + "Expected applications_ to be a Sequence, received: {}".format( + type(applications_) + ) + ) self.applications = applications_ self.unknown_fields = unknown_fields - class AuthUserInfo(Type): - _toSchema = {'controller_access': 'controller-access', 'credentials': 'credentials', 'display_name': 'display-name', 'identity': 'identity', 'last_connection': 'last-connection', 'model_access': 'model-access'} - _toPy = {'controller-access': 'controller_access', 'credentials': 'credentials', 'display-name': 'display_name', 'identity': 'identity', 'last-connection': 'last_connection', 'model-access': 'model_access'} - def __init__(self, controller_access=None, credentials=None, display_name=None, identity=None, last_connection=None, model_access=None, **unknown_fields): - ''' + _toSchema = { + "controller_access": "controller-access", + "credentials": "credentials", + "display_name": "display-name", + "identity": "identity", + "last_connection": "last-connection", + "model_access": "model-access", + } + _toPy = { + "controller-access": "controller_access", + "credentials": "credentials", + "display-name": "display_name", + "identity": "identity", + "last-connection": "last_connection", + "model-access": "model_access", + } + + def __init__( + self, + controller_access=None, + credentials=None, + display_name=None, + identity=None, + last_connection=None, + model_access=None, + **unknown_fields, + ): + """ controller_access : str credentials : str display_name : str identity : str last_connection : str model_access : str - ''' + """ controller_access_ = controller_access credentials_ = credentials display_name_ = display_name @@ -2406,23 +4005,49 @@ def __init__(self, controller_access=None, credentials=None, display_name=None, model_access_ = model_access # Validate arguments against known Juju API types. - if controller_access_ is not None and not isinstance(controller_access_, (bytes, str)): - raise Exception("Expected controller_access_ to be a str, received: {}".format(type(controller_access_))) + if controller_access_ is not None and not isinstance( + controller_access_, (bytes, str) + ): + raise Exception( + "Expected controller_access_ to be a str, received: {}".format( + type(controller_access_) + ) + ) if credentials_ is not None and not isinstance(credentials_, (bytes, str)): - raise Exception("Expected credentials_ to be a str, received: {}".format(type(credentials_))) + raise Exception( + "Expected credentials_ to be a str, received: {}".format( + type(credentials_) + ) + ) if display_name_ is not None and not isinstance(display_name_, (bytes, str)): - raise Exception("Expected display_name_ to be a str, received: {}".format(type(display_name_))) + raise Exception( + "Expected display_name_ to be a str, received: {}".format( + type(display_name_) + ) + ) if identity_ is not None and not isinstance(identity_, (bytes, str)): - raise Exception("Expected identity_ to be a str, received: {}".format(type(identity_))) - - if last_connection_ is not None and not isinstance(last_connection_, (bytes, str)): - raise Exception("Expected last_connection_ to be a str, received: {}".format(type(last_connection_))) + raise Exception( + "Expected identity_ to be a str, received: {}".format(type(identity_)) + ) + + if last_connection_ is not None and not isinstance( + last_connection_, (bytes, str) + ): + raise Exception( + "Expected last_connection_ to be a str, received: {}".format( + type(last_connection_) + ) + ) if model_access_ is not None and not isinstance(model_access_, (bytes, str)): - raise Exception("Expected model_access_ to be a str, received: {}".format(type(model_access_))) + raise Exception( + "Expected model_access_ to be a str, received: {}".format( + type(model_access_) + ) + ) self.controller_access = controller_access_ self.credentials = credentials_ @@ -2433,36 +4058,104 @@ def __init__(self, controller_access=None, credentials=None, display_name=None, self.unknown_fields = unknown_fields - class BackupsCreateArgs(Type): - _toSchema = {'no_download': 'no-download', 'notes': 'notes'} - _toPy = {'no-download': 'no_download', 'notes': 'notes'} + _toSchema = {"no_download": "no-download", "notes": "notes"} + _toPy = {"no-download": "no_download", "notes": "notes"} + def __init__(self, no_download=None, notes=None, **unknown_fields): - ''' + """ no_download : bool notes : str - ''' + """ no_download_ = no_download notes_ = notes # Validate arguments against known Juju API types. if no_download_ is not None and not isinstance(no_download_, bool): - raise Exception("Expected no_download_ to be a bool, received: {}".format(type(no_download_))) + raise Exception( + "Expected no_download_ to be a bool, received: {}".format( + type(no_download_) + ) + ) if notes_ is not None and not isinstance(notes_, (bytes, str)): - raise Exception("Expected notes_ to be a str, received: {}".format(type(notes_))) + raise Exception( + "Expected notes_ to be a str, received: {}".format(type(notes_)) + ) self.no_download = no_download_ self.notes = notes_ self.unknown_fields = unknown_fields - class BackupsMetadataResult(Type): - _toSchema = {'base': 'base', 'checksum': 'checksum', 'checksum_format': 'checksum-format', 'controller_machine_id': 'controller-machine-id', 'controller_machine_inst_id': 'controller-machine-inst-id', 'controller_uuid': 'controller-uuid', 'filename': 'filename', 'finished': 'finished', 'format_version': 'format-version', 'ha_nodes': 'ha-nodes', 'hostname': 'hostname', 'id_': 'id', 'machine': 'machine', 'model': 'model', 'notes': 'notes', 'size': 'size', 'started': 'started', 'stored': 'stored', 'version': 'version'} - _toPy = {'base': 'base', 'checksum': 'checksum', 'checksum-format': 'checksum_format', 'controller-machine-id': 'controller_machine_id', 'controller-machine-inst-id': 'controller_machine_inst_id', 'controller-uuid': 'controller_uuid', 'filename': 'filename', 'finished': 'finished', 'format-version': 'format_version', 'ha-nodes': 'ha_nodes', 'hostname': 'hostname', 'id': 'id_', 'machine': 'machine', 'model': 'model', 'notes': 'notes', 'size': 'size', 'started': 'started', 'stored': 'stored', 'version': 'version'} - def __init__(self, base=None, checksum=None, checksum_format=None, controller_machine_id=None, controller_machine_inst_id=None, controller_uuid=None, filename=None, finished=None, format_version=None, ha_nodes=None, hostname=None, id_=None, machine=None, model=None, notes=None, size=None, started=None, stored=None, version=None, **unknown_fields): - ''' + _toSchema = { + "base": "base", + "checksum": "checksum", + "checksum_format": "checksum-format", + "controller_machine_id": "controller-machine-id", + "controller_machine_inst_id": "controller-machine-inst-id", + "controller_uuid": "controller-uuid", + "filename": "filename", + "finished": "finished", + "format_version": "format-version", + "ha_nodes": "ha-nodes", + "hostname": "hostname", + "id_": "id", + "machine": "machine", + "model": "model", + "notes": "notes", + "size": "size", + "started": "started", + "stored": "stored", + "version": "version", + } + _toPy = { + "base": "base", + "checksum": "checksum", + "checksum-format": "checksum_format", + "controller-machine-id": "controller_machine_id", + "controller-machine-inst-id": "controller_machine_inst_id", + "controller-uuid": "controller_uuid", + "filename": "filename", + "finished": "finished", + "format-version": "format_version", + "ha-nodes": "ha_nodes", + "hostname": "hostname", + "id": "id_", + "machine": "machine", + "model": "model", + "notes": "notes", + "size": "size", + "started": "started", + "stored": "stored", + "version": "version", + } + + def __init__( + self, + base=None, + checksum=None, + checksum_format=None, + controller_machine_id=None, + controller_machine_inst_id=None, + controller_uuid=None, + filename=None, + finished=None, + format_version=None, + ha_nodes=None, + hostname=None, + id_=None, + machine=None, + model=None, + notes=None, + size=None, + started=None, + stored=None, + version=None, + **unknown_fields, + ): + """ base : str checksum : str checksum_format : str @@ -2482,7 +4175,7 @@ def __init__(self, base=None, checksum=None, checksum_format=None, controller_ma started : str stored : str version : Number - ''' + """ base_ = base checksum_ = checksum checksum_format_ = checksum_format @@ -2505,61 +4198,117 @@ def __init__(self, base=None, checksum=None, checksum_format=None, controller_ma # Validate arguments against known Juju API types. if base_ is not None and not isinstance(base_, (bytes, str)): - raise Exception("Expected base_ to be a str, received: {}".format(type(base_))) + raise Exception( + "Expected base_ to be a str, received: {}".format(type(base_)) + ) if checksum_ is not None and not isinstance(checksum_, (bytes, str)): - raise Exception("Expected checksum_ to be a str, received: {}".format(type(checksum_))) - - if checksum_format_ is not None and not isinstance(checksum_format_, (bytes, str)): - raise Exception("Expected checksum_format_ to be a str, received: {}".format(type(checksum_format_))) - - if controller_machine_id_ is not None and not isinstance(controller_machine_id_, (bytes, str)): - raise Exception("Expected controller_machine_id_ to be a str, received: {}".format(type(controller_machine_id_))) - - if controller_machine_inst_id_ is not None and not isinstance(controller_machine_inst_id_, (bytes, str)): - raise Exception("Expected controller_machine_inst_id_ to be a str, received: {}".format(type(controller_machine_inst_id_))) - - if controller_uuid_ is not None and not isinstance(controller_uuid_, (bytes, str)): - raise Exception("Expected controller_uuid_ to be a str, received: {}".format(type(controller_uuid_))) + raise Exception( + "Expected checksum_ to be a str, received: {}".format(type(checksum_)) + ) + + if checksum_format_ is not None and not isinstance( + checksum_format_, (bytes, str) + ): + raise Exception( + "Expected checksum_format_ to be a str, received: {}".format( + type(checksum_format_) + ) + ) + + if controller_machine_id_ is not None and not isinstance( + controller_machine_id_, (bytes, str) + ): + raise Exception( + "Expected controller_machine_id_ to be a str, received: {}".format( + type(controller_machine_id_) + ) + ) + + if controller_machine_inst_id_ is not None and not isinstance( + controller_machine_inst_id_, (bytes, str) + ): + raise Exception( + "Expected controller_machine_inst_id_ to be a str, received: {}".format( + type(controller_machine_inst_id_) + ) + ) + + if controller_uuid_ is not None and not isinstance( + controller_uuid_, (bytes, str) + ): + raise Exception( + "Expected controller_uuid_ to be a str, received: {}".format( + type(controller_uuid_) + ) + ) if filename_ is not None and not isinstance(filename_, (bytes, str)): - raise Exception("Expected filename_ to be a str, received: {}".format(type(filename_))) + raise Exception( + "Expected filename_ to be a str, received: {}".format(type(filename_)) + ) if finished_ is not None and not isinstance(finished_, (bytes, str)): - raise Exception("Expected finished_ to be a str, received: {}".format(type(finished_))) + raise Exception( + "Expected finished_ to be a str, received: {}".format(type(finished_)) + ) if format_version_ is not None and not isinstance(format_version_, int): - raise Exception("Expected format_version_ to be a int, received: {}".format(type(format_version_))) + raise Exception( + "Expected format_version_ to be a int, received: {}".format( + type(format_version_) + ) + ) if ha_nodes_ is not None and not isinstance(ha_nodes_, int): - raise Exception("Expected ha_nodes_ to be a int, received: {}".format(type(ha_nodes_))) + raise Exception( + "Expected ha_nodes_ to be a int, received: {}".format(type(ha_nodes_)) + ) if hostname_ is not None and not isinstance(hostname_, (bytes, str)): - raise Exception("Expected hostname_ to be a str, received: {}".format(type(hostname_))) + raise Exception( + "Expected hostname_ to be a str, received: {}".format(type(hostname_)) + ) if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception("Expected id__ to be a str, received: {}".format(type(id__))) + raise Exception( + "Expected id__ to be a str, received: {}".format(type(id__)) + ) if machine_ is not None and not isinstance(machine_, (bytes, str)): - raise Exception("Expected machine_ to be a str, received: {}".format(type(machine_))) + raise Exception( + "Expected machine_ to be a str, received: {}".format(type(machine_)) + ) if model_ is not None and not isinstance(model_, (bytes, str)): - raise Exception("Expected model_ to be a str, received: {}".format(type(model_))) + raise Exception( + "Expected model_ to be a str, received: {}".format(type(model_)) + ) if notes_ is not None and not isinstance(notes_, (bytes, str)): - raise Exception("Expected notes_ to be a str, received: {}".format(type(notes_))) + raise Exception( + "Expected notes_ to be a str, received: {}".format(type(notes_)) + ) if size_ is not None and not isinstance(size_, int): - raise Exception("Expected size_ to be a int, received: {}".format(type(size_))) + raise Exception( + "Expected size_ to be a int, received: {}".format(type(size_)) + ) if started_ is not None and not isinstance(started_, (bytes, str)): - raise Exception("Expected started_ to be a str, received: {}".format(type(started_))) + raise Exception( + "Expected started_ to be a str, received: {}".format(type(started_)) + ) if stored_ is not None and not isinstance(stored_, (bytes, str)): - raise Exception("Expected stored_ to be a str, received: {}".format(type(stored_))) + raise Exception( + "Expected stored_ to be a str, received: {}".format(type(stored_)) + ) if version_ is not None and not isinstance(version_, (dict, Number)): - raise Exception("Expected version_ to be a Number, received: {}".format(type(version_))) + raise Exception( + "Expected version_ to be a Number, received: {}".format(type(version_)) + ) self.base = base_ self.checksum = checksum_ @@ -2583,36 +4332,69 @@ def __init__(self, base=None, checksum=None, checksum_format=None, controller_ma self.unknown_fields = unknown_fields - class Base(Type): - _toSchema = {'channel': 'channel', 'name': 'name'} - _toPy = {'channel': 'channel', 'name': 'name'} + _toSchema = {"channel": "channel", "name": "name"} + _toPy = {"channel": "channel", "name": "name"} + def __init__(self, channel=None, name=None, **unknown_fields): - ''' + """ channel : str name : str - ''' + """ channel_ = channel name_ = name # Validate arguments against known Juju API types. if channel_ is not None and not isinstance(channel_, (bytes, str)): - raise Exception("Expected channel_ to be a str, received: {}".format(type(channel_))) + raise Exception( + "Expected channel_ to be a str, received: {}".format(type(channel_)) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) self.channel = channel_ self.name = name_ self.unknown_fields = unknown_fields - class Binary(Type): - _toSchema = {'arch': 'Arch', 'build': 'Build', 'major': 'Major', 'minor': 'Minor', 'number': 'Number', 'patch': 'Patch', 'release': 'Release', 'tag': 'Tag'} - _toPy = {'Arch': 'arch', 'Build': 'build', 'Major': 'major', 'Minor': 'minor', 'Number': 'number', 'Patch': 'patch', 'Release': 'release', 'Tag': 'tag'} - def __init__(self, arch=None, build=None, major=None, minor=None, number=None, patch=None, release=None, tag=None, **unknown_fields): - ''' + _toSchema = { + "arch": "Arch", + "build": "Build", + "major": "Major", + "minor": "Minor", + "number": "Number", + "patch": "Patch", + "release": "Release", + "tag": "Tag", + } + _toPy = { + "Arch": "arch", + "Build": "build", + "Major": "major", + "Minor": "minor", + "Number": "number", + "Patch": "patch", + "Release": "release", + "Tag": "tag", + } + + def __init__( + self, + arch=None, + build=None, + major=None, + minor=None, + number=None, + patch=None, + release=None, + tag=None, + **unknown_fields, + ): + """ arch : str build : int major : int @@ -2621,7 +4403,7 @@ def __init__(self, arch=None, build=None, major=None, minor=None, number=None, p patch : int release : str tag : str - ''' + """ arch_ = arch build_ = build major_ = major @@ -2633,28 +4415,44 @@ def __init__(self, arch=None, build=None, major=None, minor=None, number=None, p # Validate arguments against known Juju API types. if arch_ is not None and not isinstance(arch_, (bytes, str)): - raise Exception("Expected arch_ to be a str, received: {}".format(type(arch_))) + raise Exception( + "Expected arch_ to be a str, received: {}".format(type(arch_)) + ) if build_ is not None and not isinstance(build_, int): - raise Exception("Expected build_ to be a int, received: {}".format(type(build_))) + raise Exception( + "Expected build_ to be a int, received: {}".format(type(build_)) + ) if major_ is not None and not isinstance(major_, int): - raise Exception("Expected major_ to be a int, received: {}".format(type(major_))) + raise Exception( + "Expected major_ to be a int, received: {}".format(type(major_)) + ) if minor_ is not None and not isinstance(minor_, int): - raise Exception("Expected minor_ to be a int, received: {}".format(type(minor_))) + raise Exception( + "Expected minor_ to be a int, received: {}".format(type(minor_)) + ) if number_ is not None and not isinstance(number_, (dict, Number)): - raise Exception("Expected number_ to be a Number, received: {}".format(type(number_))) + raise Exception( + "Expected number_ to be a Number, received: {}".format(type(number_)) + ) if patch_ is not None and not isinstance(patch_, int): - raise Exception("Expected patch_ to be a int, received: {}".format(type(patch_))) + raise Exception( + "Expected patch_ to be a int, received: {}".format(type(patch_)) + ) if release_ is not None and not isinstance(release_, (bytes, str)): - raise Exception("Expected release_ to be a str, received: {}".format(type(release_))) + raise Exception( + "Expected release_ to be a str, received: {}".format(type(release_)) + ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception("Expected tag_ to be a str, received: {}".format(type(tag_))) + raise Exception( + "Expected tag_ to be a str, received: {}".format(type(tag_)) + ) self.arch = arch_ self.build = build_ @@ -2667,17 +4465,17 @@ def __init__(self, arch=None, build=None, major=None, minor=None, number=None, p self.unknown_fields = unknown_fields - class Block(Type): - _toSchema = {'id_': 'id', 'message': 'message', 'tag': 'tag', 'type_': 'type'} - _toPy = {'id': 'id_', 'message': 'message', 'tag': 'tag', 'type': 'type_'} + _toSchema = {"id_": "id", "message": "message", "tag": "tag", "type_": "type"} + _toPy = {"id": "id_", "message": "message", "tag": "tag", "type": "type_"} + def __init__(self, id_=None, message=None, tag=None, type_=None, **unknown_fields): - ''' + """ id_ : str message : str tag : str type_ : str - ''' + """ id__ = id_ message_ = message tag_ = tag @@ -2685,16 +4483,24 @@ def __init__(self, id_=None, message=None, tag=None, type_=None, **unknown_field # Validate arguments against known Juju API types. if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception("Expected id__ to be a str, received: {}".format(type(id__))) + raise Exception( + "Expected id__ to be a str, received: {}".format(type(id__)) + ) if message_ is not None and not isinstance(message_, (bytes, str)): - raise Exception("Expected message_ to be a str, received: {}".format(type(message_))) + raise Exception( + "Expected message_ to be a str, received: {}".format(type(message_)) + ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception("Expected tag_ to be a str, received: {}".format(type(tag_))) + raise Exception( + "Expected tag_ to be a str, received: {}".format(type(tag_)) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) self.id_ = id__ self.message = message_ @@ -2703,185 +4509,237 @@ def __init__(self, id_=None, message=None, tag=None, type_=None, **unknown_field self.unknown_fields = unknown_fields - class BlockResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : Block - ''' + """ error_ = Error.from_json(error) if error else None result_ = Block.from_json(result) if result else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if result_ is not None and not isinstance(result_, (dict, Block)): - raise Exception("Expected result_ to be a Block, received: {}".format(type(result_))) + raise Exception( + "Expected result_ to be a Block, received: {}".format(type(result_)) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class BlockResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~BlockResult] - ''' + """ results_ = [BlockResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class BlockSwitchParams(Type): - _toSchema = {'message': 'message', 'type_': 'type'} - _toPy = {'message': 'message', 'type': 'type_'} + _toSchema = {"message": "message", "type_": "type"} + _toPy = {"message": "message", "type": "type_"} + def __init__(self, message=None, type_=None, **unknown_fields): - ''' + """ message : str type_ : str - ''' + """ message_ = message type__ = type_ # Validate arguments against known Juju API types. if message_ is not None and not isinstance(message_, (bytes, str)): - raise Exception("Expected message_ to be a str, received: {}".format(type(message_))) + raise Exception( + "Expected message_ to be a str, received: {}".format(type(message_)) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) self.message = message_ self.type_ = type__ self.unknown_fields = unknown_fields - class BoolResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : bool - ''' + """ error_ = Error.from_json(error) if error else None result_ = result # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if result_ is not None and not isinstance(result_, bool): - raise Exception("Expected result_ to be a bool, received: {}".format(type(result_))) + raise Exception( + "Expected result_ to be a bool, received: {}".format(type(result_)) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class BranchArg(Type): - _toSchema = {'branch': 'branch'} - _toPy = {'branch': 'branch'} + _toSchema = {"branch": "branch"} + _toPy = {"branch": "branch"} + def __init__(self, branch=None, **unknown_fields): - ''' + """ branch : str - ''' + """ branch_ = branch # Validate arguments against known Juju API types. if branch_ is not None and not isinstance(branch_, (bytes, str)): - raise Exception("Expected branch_ to be a str, received: {}".format(type(branch_))) + raise Exception( + "Expected branch_ to be a str, received: {}".format(type(branch_)) + ) self.branch = branch_ self.unknown_fields = unknown_fields - class BranchInfoArgs(Type): - _toSchema = {'branches': 'branches', 'detailed': 'detailed'} - _toPy = {'branches': 'branches', 'detailed': 'detailed'} + _toSchema = {"branches": "branches", "detailed": "detailed"} + _toPy = {"branches": "branches", "detailed": "detailed"} + def __init__(self, branches=None, detailed=None, **unknown_fields): - ''' + """ branches : typing.Sequence[str] detailed : bool - ''' + """ branches_ = branches detailed_ = detailed # Validate arguments against known Juju API types. if branches_ is not None and not isinstance(branches_, (bytes, str, list)): - raise Exception("Expected branches_ to be a Sequence, received: {}".format(type(branches_))) + raise Exception( + "Expected branches_ to be a Sequence, received: {}".format( + type(branches_) + ) + ) if detailed_ is not None and not isinstance(detailed_, bool): - raise Exception("Expected detailed_ to be a bool, received: {}".format(type(detailed_))) + raise Exception( + "Expected detailed_ to be a bool, received: {}".format(type(detailed_)) + ) self.branches = branches_ self.detailed = detailed_ self.unknown_fields = unknown_fields - class BranchResults(Type): - _toSchema = {'error': 'error', 'generations': 'generations'} - _toPy = {'error': 'error', 'generations': 'generations'} + _toSchema = {"error": "error", "generations": "generations"} + _toPy = {"error": "error", "generations": "generations"} + def __init__(self, error=None, generations=None, **unknown_fields): - ''' + """ error : Error generations : typing.Sequence[~Generation] - ''' + """ error_ = Error.from_json(error) if error else None generations_ = [Generation.from_json(o) for o in generations or []] # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) - - if generations_ is not None and not isinstance(generations_, (bytes, str, list)): - raise Exception("Expected generations_ to be a Sequence, received: {}".format(type(generations_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) + + if generations_ is not None and not isinstance( + generations_, (bytes, str, list) + ): + raise Exception( + "Expected generations_ to be a Sequence, received: {}".format( + type(generations_) + ) + ) self.error = error_ self.generations = generations_ self.unknown_fields = unknown_fields - class BranchStatus(Type): - _toSchema = {'assigned_units': 'assigned-units', 'created': 'created', 'created_by': 'created-by'} - _toPy = {'assigned-units': 'assigned_units', 'created': 'created', 'created-by': 'created_by'} - def __init__(self, assigned_units=None, created=None, created_by=None, **unknown_fields): - ''' + _toSchema = { + "assigned_units": "assigned-units", + "created": "created", + "created_by": "created-by", + } + _toPy = { + "assigned-units": "assigned_units", + "created": "created", + "created-by": "created_by", + } + + def __init__( + self, assigned_units=None, created=None, created_by=None, **unknown_fields + ): + """ assigned_units : typing.Mapping[str, typing.Sequence[str]] created : int created_by : str - ''' + """ assigned_units_ = assigned_units created_ = created created_by_ = created_by # Validate arguments against known Juju API types. if assigned_units_ is not None and not isinstance(assigned_units_, dict): - raise Exception("Expected assigned_units_ to be a Mapping, received: {}".format(type(assigned_units_))) + raise Exception( + "Expected assigned_units_ to be a Mapping, received: {}".format( + type(assigned_units_) + ) + ) if created_ is not None and not isinstance(created_, int): - raise Exception("Expected created_ to be a int, received: {}".format(type(created_))) + raise Exception( + "Expected created_ to be a int, received: {}".format(type(created_)) + ) if created_by_ is not None and not isinstance(created_by_, (bytes, str)): - raise Exception("Expected created_by_ to be a str, received: {}".format(type(created_by_))) + raise Exception( + "Expected created_by_ to be a str, received: {}".format( + type(created_by_) + ) + ) self.assigned_units = assigned_units_ self.created = created_ @@ -2889,29 +4747,37 @@ def __init__(self, assigned_units=None, created=None, created_by=None, **unknown self.unknown_fields = unknown_fields - class BranchTrackArg(Type): - _toSchema = {'branch': 'branch', 'entities': 'entities', 'num_units': 'num-units'} - _toPy = {'branch': 'branch', 'entities': 'entities', 'num-units': 'num_units'} + _toSchema = {"branch": "branch", "entities": "entities", "num_units": "num-units"} + _toPy = {"branch": "branch", "entities": "entities", "num-units": "num_units"} + def __init__(self, branch=None, entities=None, num_units=None, **unknown_fields): - ''' + """ branch : str entities : typing.Sequence[~Entity] num_units : int - ''' + """ branch_ = branch entities_ = [Entity.from_json(o) for o in entities or []] num_units_ = num_units # Validate arguments against known Juju API types. if branch_ is not None and not isinstance(branch_, (bytes, str)): - raise Exception("Expected branch_ to be a str, received: {}".format(type(branch_))) + raise Exception( + "Expected branch_ to be a str, received: {}".format(type(branch_)) + ) if entities_ is not None and not isinstance(entities_, (bytes, str, list)): - raise Exception("Expected entities_ to be a Sequence, received: {}".format(type(entities_))) + raise Exception( + "Expected entities_ to be a Sequence, received: {}".format( + type(entities_) + ) + ) if num_units_ is not None and not isinstance(num_units_, int): - raise Exception("Expected num_units_ to be a int, received: {}".format(type(num_units_))) + raise Exception( + "Expected num_units_ to be a int, received: {}".format(type(num_units_)) + ) self.branch = branch_ self.entities = entities_ @@ -2919,35 +4785,46 @@ def __init__(self, branch=None, entities=None, num_units=None, **unknown_fields) self.unknown_fields = unknown_fields - class BulkImportStorageParams(Type): - _toSchema = {'storage': 'storage'} - _toPy = {'storage': 'storage'} + _toSchema = {"storage": "storage"} + _toPy = {"storage": "storage"} + def __init__(self, storage=None, **unknown_fields): - ''' + """ storage : typing.Sequence[~ImportStorageParams] - ''' + """ storage_ = [ImportStorageParams.from_json(o) for o in storage or []] # Validate arguments against known Juju API types. if storage_ is not None and not isinstance(storage_, (bytes, str, list)): - raise Exception("Expected storage_ to be a Sequence, received: {}".format(type(storage_))) + raise Exception( + "Expected storage_ to be a Sequence, received: {}".format( + type(storage_) + ) + ) self.storage = storage_ self.unknown_fields = unknown_fields - class BundleChange(Type): - _toSchema = {'args': 'args', 'id_': 'id', 'method': 'method', 'requires': 'requires'} - _toPy = {'args': 'args', 'id': 'id_', 'method': 'method', 'requires': 'requires'} - def __init__(self, args=None, id_=None, method=None, requires=None, **unknown_fields): - ''' + _toSchema = { + "args": "args", + "id_": "id", + "method": "method", + "requires": "requires", + } + _toPy = {"args": "args", "id": "id_", "method": "method", "requires": "requires"} + + def __init__( + self, args=None, id_=None, method=None, requires=None, **unknown_fields + ): + """ args : typing.Sequence[typing.Any] id_ : str method : str requires : typing.Sequence[str] - ''' + """ args_ = args id__ = id_ method_ = method @@ -2955,16 +4832,26 @@ def __init__(self, args=None, id_=None, method=None, requires=None, **unknown_fi # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception("Expected args_ to be a Sequence, received: {}".format(type(args_))) + raise Exception( + "Expected args_ to be a Sequence, received: {}".format(type(args_)) + ) if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception("Expected id__ to be a str, received: {}".format(type(id__))) + raise Exception( + "Expected id__ to be a str, received: {}".format(type(id__)) + ) if method_ is not None and not isinstance(method_, (bytes, str)): - raise Exception("Expected method_ to be a str, received: {}".format(type(method_))) + raise Exception( + "Expected method_ to be a str, received: {}".format(type(method_)) + ) if requires_ is not None and not isinstance(requires_, (bytes, str, list)): - raise Exception("Expected requires_ to be a Sequence, received: {}".format(type(requires_))) + raise Exception( + "Expected requires_ to be a Sequence, received: {}".format( + type(requires_) + ) + ) self.args = args_ self.id_ = id__ @@ -2973,17 +4860,24 @@ def __init__(self, args=None, id_=None, method=None, requires=None, **unknown_fi self.unknown_fields = unknown_fields - class BundleChangesMapArgs(Type): - _toSchema = {'args': 'args', 'id_': 'id', 'method': 'method', 'requires': 'requires'} - _toPy = {'args': 'args', 'id': 'id_', 'method': 'method', 'requires': 'requires'} - def __init__(self, args=None, id_=None, method=None, requires=None, **unknown_fields): - ''' + _toSchema = { + "args": "args", + "id_": "id", + "method": "method", + "requires": "requires", + } + _toPy = {"args": "args", "id": "id_", "method": "method", "requires": "requires"} + + def __init__( + self, args=None, id_=None, method=None, requires=None, **unknown_fields + ): + """ args : typing.Mapping[str, typing.Any] id_ : str method : str requires : typing.Sequence[str] - ''' + """ args_ = args id__ = id_ method_ = method @@ -2991,16 +4885,26 @@ def __init__(self, args=None, id_=None, method=None, requires=None, **unknown_fi # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, dict): - raise Exception("Expected args_ to be a Mapping, received: {}".format(type(args_))) + raise Exception( + "Expected args_ to be a Mapping, received: {}".format(type(args_)) + ) if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception("Expected id__ to be a str, received: {}".format(type(id__))) + raise Exception( + "Expected id__ to be a str, received: {}".format(type(id__)) + ) if method_ is not None and not isinstance(method_, (bytes, str)): - raise Exception("Expected method_ to be a str, received: {}".format(type(method_))) + raise Exception( + "Expected method_ to be a str, received: {}".format(type(method_)) + ) if requires_ is not None and not isinstance(requires_, (bytes, str, list)): - raise Exception("Expected requires_ to be a Sequence, received: {}".format(type(requires_))) + raise Exception( + "Expected requires_ to be a Sequence, received: {}".format( + type(requires_) + ) + ) self.args = args_ self.id_ = id__ @@ -3009,144 +4913,207 @@ def __init__(self, args=None, id_=None, method=None, requires=None, **unknown_fi self.unknown_fields = unknown_fields - class BundleChangesMapArgsResults(Type): - _toSchema = {'changes': 'changes', 'errors': 'errors'} - _toPy = {'changes': 'changes', 'errors': 'errors'} + _toSchema = {"changes": "changes", "errors": "errors"} + _toPy = {"changes": "changes", "errors": "errors"} + def __init__(self, changes=None, errors=None, **unknown_fields): - ''' + """ changes : typing.Sequence[~BundleChangesMapArgs] errors : typing.Sequence[str] - ''' + """ changes_ = [BundleChangesMapArgs.from_json(o) for o in changes or []] errors_ = errors # Validate arguments against known Juju API types. if changes_ is not None and not isinstance(changes_, (bytes, str, list)): - raise Exception("Expected changes_ to be a Sequence, received: {}".format(type(changes_))) + raise Exception( + "Expected changes_ to be a Sequence, received: {}".format( + type(changes_) + ) + ) if errors_ is not None and not isinstance(errors_, (bytes, str, list)): - raise Exception("Expected errors_ to be a Sequence, received: {}".format(type(errors_))) + raise Exception( + "Expected errors_ to be a Sequence, received: {}".format(type(errors_)) + ) self.changes = changes_ self.errors = errors_ self.unknown_fields = unknown_fields - class BundleChangesParams(Type): - _toSchema = {'bundleurl': 'bundleURL', 'yaml': 'yaml'} - _toPy = {'bundleURL': 'bundleurl', 'yaml': 'yaml'} + _toSchema = {"bundleurl": "bundleURL", "yaml": "yaml"} + _toPy = {"bundleURL": "bundleurl", "yaml": "yaml"} + def __init__(self, bundleurl=None, yaml=None, **unknown_fields): - ''' + """ bundleurl : str yaml : str - ''' + """ bundleurl_ = bundleurl yaml_ = yaml # Validate arguments against known Juju API types. if bundleurl_ is not None and not isinstance(bundleurl_, (bytes, str)): - raise Exception("Expected bundleurl_ to be a str, received: {}".format(type(bundleurl_))) + raise Exception( + "Expected bundleurl_ to be a str, received: {}".format(type(bundleurl_)) + ) if yaml_ is not None and not isinstance(yaml_, (bytes, str)): - raise Exception("Expected yaml_ to be a str, received: {}".format(type(yaml_))) + raise Exception( + "Expected yaml_ to be a str, received: {}".format(type(yaml_)) + ) self.bundleurl = bundleurl_ self.yaml = yaml_ self.unknown_fields = unknown_fields - class BundleChangesResults(Type): - _toSchema = {'changes': 'changes', 'errors': 'errors'} - _toPy = {'changes': 'changes', 'errors': 'errors'} + _toSchema = {"changes": "changes", "errors": "errors"} + _toPy = {"changes": "changes", "errors": "errors"} + def __init__(self, changes=None, errors=None, **unknown_fields): - ''' + """ changes : typing.Sequence[~BundleChange] errors : typing.Sequence[str] - ''' + """ changes_ = [BundleChange.from_json(o) for o in changes or []] errors_ = errors # Validate arguments against known Juju API types. if changes_ is not None and not isinstance(changes_, (bytes, str, list)): - raise Exception("Expected changes_ to be a Sequence, received: {}".format(type(changes_))) + raise Exception( + "Expected changes_ to be a Sequence, received: {}".format( + type(changes_) + ) + ) if errors_ is not None and not isinstance(errors_, (bytes, str, list)): - raise Exception("Expected errors_ to be a Sequence, received: {}".format(type(errors_))) + raise Exception( + "Expected errors_ to be a Sequence, received: {}".format(type(errors_)) + ) self.changes = changes_ self.errors = errors_ self.unknown_fields = unknown_fields - class CIDRParams(Type): - _toSchema = {'cidrs': 'cidrs'} - _toPy = {'cidrs': 'cidrs'} + _toSchema = {"cidrs": "cidrs"} + _toPy = {"cidrs": "cidrs"} + def __init__(self, cidrs=None, **unknown_fields): - ''' + """ cidrs : typing.Sequence[str] - ''' + """ cidrs_ = cidrs # Validate arguments against known Juju API types. if cidrs_ is not None and not isinstance(cidrs_, (bytes, str, list)): - raise Exception("Expected cidrs_ to be a Sequence, received: {}".format(type(cidrs_))) + raise Exception( + "Expected cidrs_ to be a Sequence, received: {}".format(type(cidrs_)) + ) self.cidrs = cidrs_ self.unknown_fields = unknown_fields - class ChangeModelCredentialParams(Type): - _toSchema = {'credential_tag': 'credential-tag', 'model_tag': 'model-tag'} - _toPy = {'credential-tag': 'credential_tag', 'model-tag': 'model_tag'} + _toSchema = {"credential_tag": "credential-tag", "model_tag": "model-tag"} + _toPy = {"credential-tag": "credential_tag", "model-tag": "model_tag"} + def __init__(self, credential_tag=None, model_tag=None, **unknown_fields): - ''' + """ credential_tag : str model_tag : str - ''' + """ credential_tag_ = credential_tag model_tag_ = model_tag # Validate arguments against known Juju API types. - if credential_tag_ is not None and not isinstance(credential_tag_, (bytes, str)): - raise Exception("Expected credential_tag_ to be a str, received: {}".format(type(credential_tag_))) + if credential_tag_ is not None and not isinstance( + credential_tag_, (bytes, str) + ): + raise Exception( + "Expected credential_tag_ to be a str, received: {}".format( + type(credential_tag_) + ) + ) if model_tag_ is not None and not isinstance(model_tag_, (bytes, str)): - raise Exception("Expected model_tag_ to be a str, received: {}".format(type(model_tag_))) + raise Exception( + "Expected model_tag_ to be a str, received: {}".format(type(model_tag_)) + ) self.credential_tag = credential_tag_ self.model_tag = model_tag_ self.unknown_fields = unknown_fields - class ChangeModelCredentialsParams(Type): - _toSchema = {'model_credentials': 'model-credentials'} - _toPy = {'model-credentials': 'model_credentials'} + _toSchema = {"model_credentials": "model-credentials"} + _toPy = {"model-credentials": "model_credentials"} + def __init__(self, model_credentials=None, **unknown_fields): - ''' + """ model_credentials : typing.Sequence[~ChangeModelCredentialParams] - ''' - model_credentials_ = [ChangeModelCredentialParams.from_json(o) for o in model_credentials or []] + """ + model_credentials_ = [ + ChangeModelCredentialParams.from_json(o) for o in model_credentials or [] + ] # Validate arguments against known Juju API types. - if model_credentials_ is not None and not isinstance(model_credentials_, (bytes, str, list)): - raise Exception("Expected model_credentials_ to be a Sequence, received: {}".format(type(model_credentials_))) + if model_credentials_ is not None and not isinstance( + model_credentials_, (bytes, str, list) + ): + raise Exception( + "Expected model_credentials_ to be a Sequence, received: {}".format( + type(model_credentials_) + ) + ) self.model_credentials = model_credentials_ self.unknown_fields = unknown_fields - class Charm(Type): - _toSchema = {'actions': 'actions', 'config': 'config', 'lxd_profile': 'lxd-profile', 'manifest': 'manifest', 'meta': 'meta', 'metrics': 'metrics', 'revision': 'revision', 'url': 'url'} - _toPy = {'actions': 'actions', 'config': 'config', 'lxd-profile': 'lxd_profile', 'manifest': 'manifest', 'meta': 'meta', 'metrics': 'metrics', 'revision': 'revision', 'url': 'url'} - def __init__(self, actions=None, config=None, lxd_profile=None, manifest=None, meta=None, metrics=None, revision=None, url=None, **unknown_fields): - ''' + _toSchema = { + "actions": "actions", + "config": "config", + "lxd_profile": "lxd-profile", + "manifest": "manifest", + "meta": "meta", + "metrics": "metrics", + "revision": "revision", + "url": "url", + } + _toPy = { + "actions": "actions", + "config": "config", + "lxd-profile": "lxd_profile", + "manifest": "manifest", + "meta": "meta", + "metrics": "metrics", + "revision": "revision", + "url": "url", + } + + def __init__( + self, + actions=None, + config=None, + lxd_profile=None, + manifest=None, + meta=None, + metrics=None, + revision=None, + url=None, + **unknown_fields, + ): + """ actions : CharmActions config : typing.Mapping[str, ~CharmOption] lxd_profile : CharmLXDProfile @@ -3155,7 +5122,7 @@ def __init__(self, actions=None, config=None, lxd_profile=None, manifest=None, m metrics : CharmMetrics revision : int url : str - ''' + """ actions_ = CharmActions.from_json(actions) if actions else None config_ = {k: CharmOption.from_json(v) for k, v in (config or dict()).items()} lxd_profile_ = CharmLXDProfile.from_json(lxd_profile) if lxd_profile else None @@ -3167,28 +5134,54 @@ def __init__(self, actions=None, config=None, lxd_profile=None, manifest=None, m # Validate arguments against known Juju API types. if actions_ is not None and not isinstance(actions_, (dict, CharmActions)): - raise Exception("Expected actions_ to be a CharmActions, received: {}".format(type(actions_))) + raise Exception( + "Expected actions_ to be a CharmActions, received: {}".format( + type(actions_) + ) + ) if config_ is not None and not isinstance(config_, dict): - raise Exception("Expected config_ to be a Mapping, received: {}".format(type(config_))) - - if lxd_profile_ is not None and not isinstance(lxd_profile_, (dict, CharmLXDProfile)): - raise Exception("Expected lxd_profile_ to be a CharmLXDProfile, received: {}".format(type(lxd_profile_))) + raise Exception( + "Expected config_ to be a Mapping, received: {}".format(type(config_)) + ) + + if lxd_profile_ is not None and not isinstance( + lxd_profile_, (dict, CharmLXDProfile) + ): + raise Exception( + "Expected lxd_profile_ to be a CharmLXDProfile, received: {}".format( + type(lxd_profile_) + ) + ) if manifest_ is not None and not isinstance(manifest_, (dict, CharmManifest)): - raise Exception("Expected manifest_ to be a CharmManifest, received: {}".format(type(manifest_))) + raise Exception( + "Expected manifest_ to be a CharmManifest, received: {}".format( + type(manifest_) + ) + ) if meta_ is not None and not isinstance(meta_, (dict, CharmMeta)): - raise Exception("Expected meta_ to be a CharmMeta, received: {}".format(type(meta_))) + raise Exception( + "Expected meta_ to be a CharmMeta, received: {}".format(type(meta_)) + ) if metrics_ is not None and not isinstance(metrics_, (dict, CharmMetrics)): - raise Exception("Expected metrics_ to be a CharmMetrics, received: {}".format(type(metrics_))) + raise Exception( + "Expected metrics_ to be a CharmMetrics, received: {}".format( + type(metrics_) + ) + ) if revision_ is not None and not isinstance(revision_, int): - raise Exception("Expected revision_ to be a int, received: {}".format(type(revision_))) + raise Exception( + "Expected revision_ to be a int, received: {}".format(type(revision_)) + ) if url_ is not None and not isinstance(url_, (bytes, str)): - raise Exception("Expected url_ to be a str, received: {}".format(type(url_))) + raise Exception( + "Expected url_ to be a str, received: {}".format(type(url_)) + ) self.actions = actions_ self.config = config_ @@ -3201,71 +5194,89 @@ def __init__(self, actions=None, config=None, lxd_profile=None, manifest=None, m self.unknown_fields = unknown_fields - class CharmActionSpec(Type): - _toSchema = {'description': 'description', 'params': 'params'} - _toPy = {'description': 'description', 'params': 'params'} + _toSchema = {"description": "description", "params": "params"} + _toPy = {"description": "description", "params": "params"} + def __init__(self, description=None, params=None, **unknown_fields): - ''' + """ description : str params : typing.Mapping[str, typing.Any] - ''' + """ description_ = description params_ = params # Validate arguments against known Juju API types. if description_ is not None and not isinstance(description_, (bytes, str)): - raise Exception("Expected description_ to be a str, received: {}".format(type(description_))) + raise Exception( + "Expected description_ to be a str, received: {}".format( + type(description_) + ) + ) if params_ is not None and not isinstance(params_, dict): - raise Exception("Expected params_ to be a Mapping, received: {}".format(type(params_))) + raise Exception( + "Expected params_ to be a Mapping, received: {}".format(type(params_)) + ) self.description = description_ self.params = params_ self.unknown_fields = unknown_fields - class CharmActions(Type): - _toSchema = {'specs': 'specs'} - _toPy = {'specs': 'specs'} + _toSchema = {"specs": "specs"} + _toPy = {"specs": "specs"} + def __init__(self, specs=None, **unknown_fields): - ''' + """ specs : typing.Mapping[str, ~CharmActionSpec] - ''' + """ specs_ = {k: CharmActionSpec.from_json(v) for k, v in (specs or dict()).items()} # Validate arguments against known Juju API types. if specs_ is not None and not isinstance(specs_, dict): - raise Exception("Expected specs_ to be a Mapping, received: {}".format(type(specs_))) + raise Exception( + "Expected specs_ to be a Mapping, received: {}".format(type(specs_)) + ) self.specs = specs_ self.unknown_fields = unknown_fields - class CharmBase(Type): - _toSchema = {'architectures': 'architectures', 'channel': 'channel', 'name': 'name'} - _toPy = {'architectures': 'architectures', 'channel': 'channel', 'name': 'name'} + _toSchema = {"architectures": "architectures", "channel": "channel", "name": "name"} + _toPy = {"architectures": "architectures", "channel": "channel", "name": "name"} + def __init__(self, architectures=None, channel=None, name=None, **unknown_fields): - ''' + """ architectures : typing.Sequence[str] channel : str name : str - ''' + """ architectures_ = architectures channel_ = channel name_ = name # Validate arguments against known Juju API types. - if architectures_ is not None and not isinstance(architectures_, (bytes, str, list)): - raise Exception("Expected architectures_ to be a Sequence, received: {}".format(type(architectures_))) + if architectures_ is not None and not isinstance( + architectures_, (bytes, str, list) + ): + raise Exception( + "Expected architectures_ to be a Sequence, received: {}".format( + type(architectures_) + ) + ) if channel_ is not None and not isinstance(channel_, (bytes, str)): - raise Exception("Expected channel_ to be a str, received: {}".format(type(channel_))) + raise Exception( + "Expected channel_ to be a str, received: {}".format(type(channel_)) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) self.architectures = architectures_ self.channel = channel_ @@ -3273,17 +5284,19 @@ def __init__(self, architectures=None, channel=None, name=None, **unknown_fields self.unknown_fields = unknown_fields - class CharmContainer(Type): - _toSchema = {'gid': 'gid', 'mounts': 'mounts', 'resource': 'resource', 'uid': 'uid'} - _toPy = {'gid': 'gid', 'mounts': 'mounts', 'resource': 'resource', 'uid': 'uid'} - def __init__(self, gid=None, mounts=None, resource=None, uid=None, **unknown_fields): - ''' + _toSchema = {"gid": "gid", "mounts": "mounts", "resource": "resource", "uid": "uid"} + _toPy = {"gid": "gid", "mounts": "mounts", "resource": "resource", "uid": "uid"} + + def __init__( + self, gid=None, mounts=None, resource=None, uid=None, **unknown_fields + ): + """ gid : int mounts : typing.Sequence[~CharmMount] resource : str uid : int - ''' + """ gid_ = gid mounts_ = [CharmMount.from_json(o) for o in mounts or []] resource_ = resource @@ -3291,16 +5304,24 @@ def __init__(self, gid=None, mounts=None, resource=None, uid=None, **unknown_fie # Validate arguments against known Juju API types. if gid_ is not None and not isinstance(gid_, int): - raise Exception("Expected gid_ to be a int, received: {}".format(type(gid_))) + raise Exception( + "Expected gid_ to be a int, received: {}".format(type(gid_)) + ) if mounts_ is not None and not isinstance(mounts_, (bytes, str, list)): - raise Exception("Expected mounts_ to be a Sequence, received: {}".format(type(mounts_))) + raise Exception( + "Expected mounts_ to be a Sequence, received: {}".format(type(mounts_)) + ) if resource_ is not None and not isinstance(resource_, (bytes, str)): - raise Exception("Expected resource_ to be a str, received: {}".format(type(resource_))) + raise Exception( + "Expected resource_ to be a str, received: {}".format(type(resource_)) + ) if uid_ is not None and not isinstance(uid_, int): - raise Exception("Expected uid_ to be a int, received: {}".format(type(uid_))) + raise Exception( + "Expected uid_ to be a int, received: {}".format(type(uid_)) + ) self.gid = gid_ self.mounts = mounts_ @@ -3309,17 +5330,29 @@ def __init__(self, gid=None, mounts=None, resource=None, uid=None, **unknown_fie self.unknown_fields = unknown_fields - class CharmDeployment(Type): - _toSchema = {'min_version': 'min-version', 'mode': 'mode', 'service': 'service', 'type_': 'type'} - _toPy = {'min-version': 'min_version', 'mode': 'mode', 'service': 'service', 'type': 'type_'} - def __init__(self, min_version=None, mode=None, service=None, type_=None, **unknown_fields): - ''' + _toSchema = { + "min_version": "min-version", + "mode": "mode", + "service": "service", + "type_": "type", + } + _toPy = { + "min-version": "min_version", + "mode": "mode", + "service": "service", + "type": "type_", + } + + def __init__( + self, min_version=None, mode=None, service=None, type_=None, **unknown_fields + ): + """ min_version : str mode : str service : str type_ : str - ''' + """ min_version_ = min_version mode_ = mode service_ = service @@ -3327,16 +5360,26 @@ def __init__(self, min_version=None, mode=None, service=None, type_=None, **unkn # Validate arguments against known Juju API types. if min_version_ is not None and not isinstance(min_version_, (bytes, str)): - raise Exception("Expected min_version_ to be a str, received: {}".format(type(min_version_))) + raise Exception( + "Expected min_version_ to be a str, received: {}".format( + type(min_version_) + ) + ) if mode_ is not None and not isinstance(mode_, (bytes, str)): - raise Exception("Expected mode_ to be a str, received: {}".format(type(mode_))) + raise Exception( + "Expected mode_ to be a str, received: {}".format(type(mode_)) + ) if service_ is not None and not isinstance(service_, (bytes, str)): - raise Exception("Expected service_ to be a str, received: {}".format(type(service_))) + raise Exception( + "Expected service_ to be a str, received: {}".format(type(service_)) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) self.min_version = min_version_ self.mode = mode_ @@ -3345,18 +5388,38 @@ def __init__(self, min_version=None, mode=None, service=None, type_=None, **unkn self.unknown_fields = unknown_fields - class CharmDevice(Type): - _toSchema = {'countmax': 'CountMax', 'countmin': 'CountMin', 'description': 'Description', 'name': 'Name', 'type_': 'Type'} - _toPy = {'CountMax': 'countmax', 'CountMin': 'countmin', 'Description': 'description', 'Name': 'name', 'Type': 'type_'} - def __init__(self, countmax=None, countmin=None, description=None, name=None, type_=None, **unknown_fields): - ''' + _toSchema = { + "countmax": "CountMax", + "countmin": "CountMin", + "description": "Description", + "name": "Name", + "type_": "Type", + } + _toPy = { + "CountMax": "countmax", + "CountMin": "countmin", + "Description": "description", + "Name": "name", + "Type": "type_", + } + + def __init__( + self, + countmax=None, + countmin=None, + description=None, + name=None, + type_=None, + **unknown_fields, + ): + """ countmax : int countmin : int description : str name : str type_ : str - ''' + """ countmax_ = countmax countmin_ = countmin description_ = description @@ -3365,19 +5428,31 @@ def __init__(self, countmax=None, countmin=None, description=None, name=None, ty # Validate arguments against known Juju API types. if countmax_ is not None and not isinstance(countmax_, int): - raise Exception("Expected countmax_ to be a int, received: {}".format(type(countmax_))) + raise Exception( + "Expected countmax_ to be a int, received: {}".format(type(countmax_)) + ) if countmin_ is not None and not isinstance(countmin_, int): - raise Exception("Expected countmin_ to be a int, received: {}".format(type(countmin_))) + raise Exception( + "Expected countmin_ to be a int, received: {}".format(type(countmin_)) + ) if description_ is not None and not isinstance(description_, (bytes, str)): - raise Exception("Expected description_ to be a str, received: {}".format(type(description_))) + raise Exception( + "Expected description_ to be a str, received: {}".format( + type(description_) + ) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) self.countmax = countmax_ self.countmin = countmin_ @@ -3387,29 +5462,37 @@ def __init__(self, countmax=None, countmin=None, description=None, name=None, ty self.unknown_fields = unknown_fields - class CharmLXDProfile(Type): - _toSchema = {'config': 'config', 'description': 'description', 'devices': 'devices'} - _toPy = {'config': 'config', 'description': 'description', 'devices': 'devices'} + _toSchema = {"config": "config", "description": "description", "devices": "devices"} + _toPy = {"config": "config", "description": "description", "devices": "devices"} + def __init__(self, config=None, description=None, devices=None, **unknown_fields): - ''' + """ config : typing.Mapping[str, str] description : str devices : typing.Mapping[str, typing.Any] - ''' + """ config_ = config description_ = description devices_ = devices # Validate arguments against known Juju API types. if config_ is not None and not isinstance(config_, dict): - raise Exception("Expected config_ to be a Mapping, received: {}".format(type(config_))) + raise Exception( + "Expected config_ to be a Mapping, received: {}".format(type(config_)) + ) if description_ is not None and not isinstance(description_, (bytes, str)): - raise Exception("Expected description_ to be a str, received: {}".format(type(description_))) + raise Exception( + "Expected description_ to be a str, received: {}".format( + type(description_) + ) + ) if devices_ is not None and not isinstance(devices_, dict): - raise Exception("Expected devices_ to be a Mapping, received: {}".format(type(devices_))) + raise Exception( + "Expected devices_ to be a Mapping, received: {}".format(type(devices_)) + ) self.config = config_ self.description = description_ @@ -3417,30 +5500,100 @@ def __init__(self, config=None, description=None, devices=None, **unknown_fields self.unknown_fields = unknown_fields - class CharmManifest(Type): - _toSchema = {'bases': 'bases'} - _toPy = {'bases': 'bases'} + _toSchema = {"bases": "bases"} + _toPy = {"bases": "bases"} + def __init__(self, bases=None, **unknown_fields): - ''' + """ bases : typing.Sequence[~CharmBase] - ''' + """ bases_ = [CharmBase.from_json(o) for o in bases or []] # Validate arguments against known Juju API types. if bases_ is not None and not isinstance(bases_, (bytes, str, list)): - raise Exception("Expected bases_ to be a Sequence, received: {}".format(type(bases_))) + raise Exception( + "Expected bases_ to be a Sequence, received: {}".format(type(bases_)) + ) self.bases = bases_ self.unknown_fields = unknown_fields - class CharmMeta(Type): - _toSchema = {'assumes_expr': 'assumes-expr', 'categories': 'categories', 'charm_user': 'charm-user', 'containers': 'containers', 'deployment': 'deployment', 'description': 'description', 'devices': 'devices', 'extra_bindings': 'extra-bindings', 'min_juju_version': 'min-juju-version', 'name': 'name', 'payload_classes': 'payload-classes', 'peers': 'peers', 'provides': 'provides', 'requires': 'requires', 'resources': 'resources', 'series': 'series', 'storage': 'storage', 'subordinate': 'subordinate', 'summary': 'summary', 'tags': 'tags', 'terms': 'terms'} - _toPy = {'assumes-expr': 'assumes_expr', 'categories': 'categories', 'charm-user': 'charm_user', 'containers': 'containers', 'deployment': 'deployment', 'description': 'description', 'devices': 'devices', 'extra-bindings': 'extra_bindings', 'min-juju-version': 'min_juju_version', 'name': 'name', 'payload-classes': 'payload_classes', 'peers': 'peers', 'provides': 'provides', 'requires': 'requires', 'resources': 'resources', 'series': 'series', 'storage': 'storage', 'subordinate': 'subordinate', 'summary': 'summary', 'tags': 'tags', 'terms': 'terms'} - def __init__(self, assumes_expr=None, categories=None, charm_user=None, containers=None, deployment=None, description=None, devices=None, extra_bindings=None, min_juju_version=None, name=None, payload_classes=None, peers=None, provides=None, requires=None, resources=None, series=None, storage=None, subordinate=None, summary=None, tags=None, terms=None, **unknown_fields): - ''' + _toSchema = { + "assumes_expr": "assumes-expr", + "categories": "categories", + "charm_user": "charm-user", + "containers": "containers", + "deployment": "deployment", + "description": "description", + "devices": "devices", + "extra_bindings": "extra-bindings", + "min_juju_version": "min-juju-version", + "name": "name", + "payload_classes": "payload-classes", + "peers": "peers", + "provides": "provides", + "requires": "requires", + "resources": "resources", + "series": "series", + "storage": "storage", + "subordinate": "subordinate", + "summary": "summary", + "tags": "tags", + "terms": "terms", + } + _toPy = { + "assumes-expr": "assumes_expr", + "categories": "categories", + "charm-user": "charm_user", + "containers": "containers", + "deployment": "deployment", + "description": "description", + "devices": "devices", + "extra-bindings": "extra_bindings", + "min-juju-version": "min_juju_version", + "name": "name", + "payload-classes": "payload_classes", + "peers": "peers", + "provides": "provides", + "requires": "requires", + "resources": "resources", + "series": "series", + "storage": "storage", + "subordinate": "subordinate", + "summary": "summary", + "tags": "tags", + "terms": "terms", + } + + def __init__( + self, + assumes_expr=None, + categories=None, + charm_user=None, + containers=None, + deployment=None, + description=None, + devices=None, + extra_bindings=None, + min_juju_version=None, + name=None, + payload_classes=None, + peers=None, + provides=None, + requires=None, + resources=None, + series=None, + storage=None, + subordinate=None, + summary=None, + tags=None, + terms=None, + **unknown_fields, + ): + """ assumes_expr : ExpressionTree categories : typing.Sequence[str] charm_user : str @@ -3462,92 +5615,179 @@ def __init__(self, assumes_expr=None, categories=None, charm_user=None, containe summary : str tags : typing.Sequence[str] terms : typing.Sequence[str] - ''' + """ assumes_expr_ = ExpressionTree.from_json(assumes_expr) if assumes_expr else None categories_ = categories charm_user_ = charm_user - containers_ = {k: CharmContainer.from_json(v) for k, v in (containers or dict()).items()} + containers_ = { + k: CharmContainer.from_json(v) for k, v in (containers or dict()).items() + } deployment_ = CharmDeployment.from_json(deployment) if deployment else None description_ = description devices_ = {k: CharmDevice.from_json(v) for k, v in (devices or dict()).items()} extra_bindings_ = extra_bindings min_juju_version_ = min_juju_version name_ = name - payload_classes_ = {k: CharmPayloadClass.from_json(v) for k, v in (payload_classes or dict()).items()} + payload_classes_ = { + k: CharmPayloadClass.from_json(v) + for k, v in (payload_classes or dict()).items() + } peers_ = {k: CharmRelation.from_json(v) for k, v in (peers or dict()).items()} - provides_ = {k: CharmRelation.from_json(v) for k, v in (provides or dict()).items()} - requires_ = {k: CharmRelation.from_json(v) for k, v in (requires or dict()).items()} - resources_ = {k: CharmResourceMeta.from_json(v) for k, v in (resources or dict()).items()} + provides_ = { + k: CharmRelation.from_json(v) for k, v in (provides or dict()).items() + } + requires_ = { + k: CharmRelation.from_json(v) for k, v in (requires or dict()).items() + } + resources_ = { + k: CharmResourceMeta.from_json(v) for k, v in (resources or dict()).items() + } series_ = series - storage_ = {k: CharmStorage.from_json(v) for k, v in (storage or dict()).items()} + storage_ = { + k: CharmStorage.from_json(v) for k, v in (storage or dict()).items() + } subordinate_ = subordinate summary_ = summary tags_ = tags terms_ = terms # Validate arguments against known Juju API types. - if assumes_expr_ is not None and not isinstance(assumes_expr_, (dict, ExpressionTree)): - raise Exception("Expected assumes_expr_ to be a ExpressionTree, received: {}".format(type(assumes_expr_))) + if assumes_expr_ is not None and not isinstance( + assumes_expr_, (dict, ExpressionTree) + ): + raise Exception( + "Expected assumes_expr_ to be a ExpressionTree, received: {}".format( + type(assumes_expr_) + ) + ) if categories_ is not None and not isinstance(categories_, (bytes, str, list)): - raise Exception("Expected categories_ to be a Sequence, received: {}".format(type(categories_))) + raise Exception( + "Expected categories_ to be a Sequence, received: {}".format( + type(categories_) + ) + ) if charm_user_ is not None and not isinstance(charm_user_, (bytes, str)): - raise Exception("Expected charm_user_ to be a str, received: {}".format(type(charm_user_))) + raise Exception( + "Expected charm_user_ to be a str, received: {}".format( + type(charm_user_) + ) + ) if containers_ is not None and not isinstance(containers_, dict): - raise Exception("Expected containers_ to be a Mapping, received: {}".format(type(containers_))) - - if deployment_ is not None and not isinstance(deployment_, (dict, CharmDeployment)): - raise Exception("Expected deployment_ to be a CharmDeployment, received: {}".format(type(deployment_))) + raise Exception( + "Expected containers_ to be a Mapping, received: {}".format( + type(containers_) + ) + ) + + if deployment_ is not None and not isinstance( + deployment_, (dict, CharmDeployment) + ): + raise Exception( + "Expected deployment_ to be a CharmDeployment, received: {}".format( + type(deployment_) + ) + ) if description_ is not None and not isinstance(description_, (bytes, str)): - raise Exception("Expected description_ to be a str, received: {}".format(type(description_))) + raise Exception( + "Expected description_ to be a str, received: {}".format( + type(description_) + ) + ) if devices_ is not None and not isinstance(devices_, dict): - raise Exception("Expected devices_ to be a Mapping, received: {}".format(type(devices_))) + raise Exception( + "Expected devices_ to be a Mapping, received: {}".format(type(devices_)) + ) if extra_bindings_ is not None and not isinstance(extra_bindings_, dict): - raise Exception("Expected extra_bindings_ to be a Mapping, received: {}".format(type(extra_bindings_))) - - if min_juju_version_ is not None and not isinstance(min_juju_version_, (bytes, str)): - raise Exception("Expected min_juju_version_ to be a str, received: {}".format(type(min_juju_version_))) + raise Exception( + "Expected extra_bindings_ to be a Mapping, received: {}".format( + type(extra_bindings_) + ) + ) + + if min_juju_version_ is not None and not isinstance( + min_juju_version_, (bytes, str) + ): + raise Exception( + "Expected min_juju_version_ to be a str, received: {}".format( + type(min_juju_version_) + ) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if payload_classes_ is not None and not isinstance(payload_classes_, dict): - raise Exception("Expected payload_classes_ to be a Mapping, received: {}".format(type(payload_classes_))) + raise Exception( + "Expected payload_classes_ to be a Mapping, received: {}".format( + type(payload_classes_) + ) + ) if peers_ is not None and not isinstance(peers_, dict): - raise Exception("Expected peers_ to be a Mapping, received: {}".format(type(peers_))) + raise Exception( + "Expected peers_ to be a Mapping, received: {}".format(type(peers_)) + ) if provides_ is not None and not isinstance(provides_, dict): - raise Exception("Expected provides_ to be a Mapping, received: {}".format(type(provides_))) + raise Exception( + "Expected provides_ to be a Mapping, received: {}".format( + type(provides_) + ) + ) if requires_ is not None and not isinstance(requires_, dict): - raise Exception("Expected requires_ to be a Mapping, received: {}".format(type(requires_))) + raise Exception( + "Expected requires_ to be a Mapping, received: {}".format( + type(requires_) + ) + ) if resources_ is not None and not isinstance(resources_, dict): - raise Exception("Expected resources_ to be a Mapping, received: {}".format(type(resources_))) + raise Exception( + "Expected resources_ to be a Mapping, received: {}".format( + type(resources_) + ) + ) if series_ is not None and not isinstance(series_, (bytes, str, list)): - raise Exception("Expected series_ to be a Sequence, received: {}".format(type(series_))) + raise Exception( + "Expected series_ to be a Sequence, received: {}".format(type(series_)) + ) if storage_ is not None and not isinstance(storage_, dict): - raise Exception("Expected storage_ to be a Mapping, received: {}".format(type(storage_))) + raise Exception( + "Expected storage_ to be a Mapping, received: {}".format(type(storage_)) + ) if subordinate_ is not None and not isinstance(subordinate_, bool): - raise Exception("Expected subordinate_ to be a bool, received: {}".format(type(subordinate_))) + raise Exception( + "Expected subordinate_ to be a bool, received: {}".format( + type(subordinate_) + ) + ) if summary_ is not None and not isinstance(summary_, (bytes, str)): - raise Exception("Expected summary_ to be a str, received: {}".format(type(summary_))) + raise Exception( + "Expected summary_ to be a str, received: {}".format(type(summary_)) + ) if tags_ is not None and not isinstance(tags_, (bytes, str, list)): - raise Exception("Expected tags_ to be a Sequence, received: {}".format(type(tags_))) + raise Exception( + "Expected tags_ to be a Sequence, received: {}".format(type(tags_)) + ) if terms_ is not None and not isinstance(terms_, (bytes, str, list)): - raise Exception("Expected terms_ to be a Sequence, received: {}".format(type(terms_))) + raise Exception( + "Expected terms_ to be a Sequence, received: {}".format(type(terms_)) + ) self.assumes_expr = assumes_expr_ self.categories = categories_ @@ -3573,98 +5813,118 @@ def __init__(self, assumes_expr=None, categories=None, charm_user=None, containe self.unknown_fields = unknown_fields - class CharmMetric(Type): - _toSchema = {'description': 'description', 'type_': 'type'} - _toPy = {'description': 'description', 'type': 'type_'} + _toSchema = {"description": "description", "type_": "type"} + _toPy = {"description": "description", "type": "type_"} + def __init__(self, description=None, type_=None, **unknown_fields): - ''' + """ description : str type_ : str - ''' + """ description_ = description type__ = type_ # Validate arguments against known Juju API types. if description_ is not None and not isinstance(description_, (bytes, str)): - raise Exception("Expected description_ to be a str, received: {}".format(type(description_))) + raise Exception( + "Expected description_ to be a str, received: {}".format( + type(description_) + ) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) self.description = description_ self.type_ = type__ self.unknown_fields = unknown_fields - class CharmMetrics(Type): - _toSchema = {'metrics': 'metrics', 'plan': 'plan'} - _toPy = {'metrics': 'metrics', 'plan': 'plan'} + _toSchema = {"metrics": "metrics", "plan": "plan"} + _toPy = {"metrics": "metrics", "plan": "plan"} + def __init__(self, metrics=None, plan=None, **unknown_fields): - ''' + """ metrics : typing.Mapping[str, ~CharmMetric] plan : CharmPlan - ''' + """ metrics_ = {k: CharmMetric.from_json(v) for k, v in (metrics or dict()).items()} plan_ = CharmPlan.from_json(plan) if plan else None # Validate arguments against known Juju API types. if metrics_ is not None and not isinstance(metrics_, dict): - raise Exception("Expected metrics_ to be a Mapping, received: {}".format(type(metrics_))) + raise Exception( + "Expected metrics_ to be a Mapping, received: {}".format(type(metrics_)) + ) if plan_ is not None and not isinstance(plan_, (dict, CharmPlan)): - raise Exception("Expected plan_ to be a CharmPlan, received: {}".format(type(plan_))) + raise Exception( + "Expected plan_ to be a CharmPlan, received: {}".format(type(plan_)) + ) self.metrics = metrics_ self.plan = plan_ self.unknown_fields = unknown_fields - class CharmMount(Type): - _toSchema = {'location': 'location', 'storage': 'storage'} - _toPy = {'location': 'location', 'storage': 'storage'} + _toSchema = {"location": "location", "storage": "storage"} + _toPy = {"location": "location", "storage": "storage"} + def __init__(self, location=None, storage=None, **unknown_fields): - ''' + """ location : str storage : str - ''' + """ location_ = location storage_ = storage # Validate arguments against known Juju API types. if location_ is not None and not isinstance(location_, (bytes, str)): - raise Exception("Expected location_ to be a str, received: {}".format(type(location_))) + raise Exception( + "Expected location_ to be a str, received: {}".format(type(location_)) + ) if storage_ is not None and not isinstance(storage_, (bytes, str)): - raise Exception("Expected storage_ to be a str, received: {}".format(type(storage_))) + raise Exception( + "Expected storage_ to be a str, received: {}".format(type(storage_)) + ) self.location = location_ self.storage = storage_ self.unknown_fields = unknown_fields - class CharmOption(Type): - _toSchema = {'default': 'default', 'description': 'description', 'type_': 'type'} - _toPy = {'default': 'default', 'description': 'description', 'type': 'type_'} + _toSchema = {"default": "default", "description": "description", "type_": "type"} + _toPy = {"default": "default", "description": "description", "type": "type_"} + def __init__(self, default=None, description=None, type_=None, **unknown_fields): - ''' + """ default : Any description : str type_ : str - ''' + """ default_ = default description_ = description type__ = type_ # Validate arguments against known Juju API types. if description_ is not None and not isinstance(description_, (bytes, str)): - raise Exception("Expected description_ to be a str, received: {}".format(type(description_))) + raise Exception( + "Expected description_ to be a str, received: {}".format( + type(description_) + ) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) self.default = default_ self.description = description_ @@ -3672,12 +5932,50 @@ def __init__(self, default=None, description=None, type_=None, **unknown_fields) self.unknown_fields = unknown_fields - class CharmOrigin(Type): - _toSchema = {'architecture': 'architecture', 'base': 'base', 'branch': 'branch', 'hash_': 'hash', 'id_': 'id', 'instance_key': 'instance-key', 'revision': 'revision', 'risk': 'risk', 'source': 'source', 'track': 'track', 'type_': 'type'} - _toPy = {'architecture': 'architecture', 'base': 'base', 'branch': 'branch', 'hash': 'hash_', 'id': 'id_', 'instance-key': 'instance_key', 'revision': 'revision', 'risk': 'risk', 'source': 'source', 'track': 'track', 'type': 'type_'} - def __init__(self, architecture=None, base=None, branch=None, hash_=None, id_=None, instance_key=None, revision=None, risk=None, source=None, track=None, type_=None, **unknown_fields): - ''' + _toSchema = { + "architecture": "architecture", + "base": "base", + "branch": "branch", + "hash_": "hash", + "id_": "id", + "instance_key": "instance-key", + "revision": "revision", + "risk": "risk", + "source": "source", + "track": "track", + "type_": "type", + } + _toPy = { + "architecture": "architecture", + "base": "base", + "branch": "branch", + "hash": "hash_", + "id": "id_", + "instance-key": "instance_key", + "revision": "revision", + "risk": "risk", + "source": "source", + "track": "track", + "type": "type_", + } + + def __init__( + self, + architecture=None, + base=None, + branch=None, + hash_=None, + id_=None, + instance_key=None, + revision=None, + risk=None, + source=None, + track=None, + type_=None, + **unknown_fields, + ): + """ architecture : str base : Base branch : str @@ -3689,7 +5987,7 @@ def __init__(self, architecture=None, base=None, branch=None, hash_=None, id_=No source : str track : str type_ : str - ''' + """ architecture_ = architecture base_ = Base.from_json(base) if base else None branch_ = branch @@ -3704,37 +6002,63 @@ def __init__(self, architecture=None, base=None, branch=None, hash_=None, id_=No # Validate arguments against known Juju API types. if architecture_ is not None and not isinstance(architecture_, (bytes, str)): - raise Exception("Expected architecture_ to be a str, received: {}".format(type(architecture_))) + raise Exception( + "Expected architecture_ to be a str, received: {}".format( + type(architecture_) + ) + ) if base_ is not None and not isinstance(base_, (dict, Base)): - raise Exception("Expected base_ to be a Base, received: {}".format(type(base_))) + raise Exception( + "Expected base_ to be a Base, received: {}".format(type(base_)) + ) if branch_ is not None and not isinstance(branch_, (bytes, str)): - raise Exception("Expected branch_ to be a str, received: {}".format(type(branch_))) + raise Exception( + "Expected branch_ to be a str, received: {}".format(type(branch_)) + ) if hash__ is not None and not isinstance(hash__, (bytes, str)): - raise Exception("Expected hash__ to be a str, received: {}".format(type(hash__))) + raise Exception( + "Expected hash__ to be a str, received: {}".format(type(hash__)) + ) if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception("Expected id__ to be a str, received: {}".format(type(id__))) + raise Exception( + "Expected id__ to be a str, received: {}".format(type(id__)) + ) if instance_key_ is not None and not isinstance(instance_key_, (bytes, str)): - raise Exception("Expected instance_key_ to be a str, received: {}".format(type(instance_key_))) + raise Exception( + "Expected instance_key_ to be a str, received: {}".format( + type(instance_key_) + ) + ) if revision_ is not None and not isinstance(revision_, int): - raise Exception("Expected revision_ to be a int, received: {}".format(type(revision_))) + raise Exception( + "Expected revision_ to be a int, received: {}".format(type(revision_)) + ) if risk_ is not None and not isinstance(risk_, (bytes, str)): - raise Exception("Expected risk_ to be a str, received: {}".format(type(risk_))) + raise Exception( + "Expected risk_ to be a str, received: {}".format(type(risk_)) + ) if source_ is not None and not isinstance(source_, (bytes, str)): - raise Exception("Expected source_ to be a str, received: {}".format(type(source_))) + raise Exception( + "Expected source_ to be a str, received: {}".format(type(source_)) + ) if track_ is not None and not isinstance(track_, (bytes, str)): - raise Exception("Expected track_ to be a str, received: {}".format(type(track_))) + raise Exception( + "Expected track_ to be a str, received: {}".format(type(track_)) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) self.architecture = architecture_ self.base = base_ @@ -3750,85 +6074,122 @@ def __init__(self, architecture=None, base=None, branch=None, hash_=None, id_=No self.unknown_fields = unknown_fields - class CharmOriginResult(Type): - _toSchema = {'charm_origin': 'charm-origin', 'error': 'error'} - _toPy = {'charm-origin': 'charm_origin', 'error': 'error'} + _toSchema = {"charm_origin": "charm-origin", "error": "error"} + _toPy = {"charm-origin": "charm_origin", "error": "error"} + def __init__(self, charm_origin=None, error=None, **unknown_fields): - ''' + """ charm_origin : CharmOrigin error : Error - ''' + """ charm_origin_ = CharmOrigin.from_json(charm_origin) if charm_origin else None error_ = Error.from_json(error) if error else None # Validate arguments against known Juju API types. - if charm_origin_ is not None and not isinstance(charm_origin_, (dict, CharmOrigin)): - raise Exception("Expected charm_origin_ to be a CharmOrigin, received: {}".format(type(charm_origin_))) + if charm_origin_ is not None and not isinstance( + charm_origin_, (dict, CharmOrigin) + ): + raise Exception( + "Expected charm_origin_ to be a CharmOrigin, received: {}".format( + type(charm_origin_) + ) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) self.charm_origin = charm_origin_ self.error = error_ self.unknown_fields = unknown_fields - class CharmPayloadClass(Type): - _toSchema = {'name': 'name', 'type_': 'type'} - _toPy = {'name': 'name', 'type': 'type_'} + _toSchema = {"name": "name", "type_": "type"} + _toPy = {"name": "name", "type": "type_"} + def __init__(self, name=None, type_=None, **unknown_fields): - ''' + """ name : str type_ : str - ''' + """ name_ = name type__ = type_ # Validate arguments against known Juju API types. if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) self.name = name_ self.type_ = type__ self.unknown_fields = unknown_fields - class CharmPlan(Type): - _toSchema = {'required': 'required'} - _toPy = {'required': 'required'} + _toSchema = {"required": "required"} + _toPy = {"required": "required"} + def __init__(self, required=None, **unknown_fields): - ''' + """ required : bool - ''' + """ required_ = required # Validate arguments against known Juju API types. if required_ is not None and not isinstance(required_, bool): - raise Exception("Expected required_ to be a bool, received: {}".format(type(required_))) + raise Exception( + "Expected required_ to be a bool, received: {}".format(type(required_)) + ) self.required = required_ self.unknown_fields = unknown_fields - class CharmRelation(Type): - _toSchema = {'interface': 'interface', 'limit': 'limit', 'name': 'name', 'optional': 'optional', 'role': 'role', 'scope': 'scope'} - _toPy = {'interface': 'interface', 'limit': 'limit', 'name': 'name', 'optional': 'optional', 'role': 'role', 'scope': 'scope'} - def __init__(self, interface=None, limit=None, name=None, optional=None, role=None, scope=None, **unknown_fields): - ''' + _toSchema = { + "interface": "interface", + "limit": "limit", + "name": "name", + "optional": "optional", + "role": "role", + "scope": "scope", + } + _toPy = { + "interface": "interface", + "limit": "limit", + "name": "name", + "optional": "optional", + "role": "role", + "scope": "scope", + } + + def __init__( + self, + interface=None, + limit=None, + name=None, + optional=None, + role=None, + scope=None, + **unknown_fields, + ): + """ interface : str limit : int name : str optional : bool role : str scope : str - ''' + """ interface_ = interface limit_ = limit name_ = name @@ -3838,22 +6199,34 @@ def __init__(self, interface=None, limit=None, name=None, optional=None, role=No # Validate arguments against known Juju API types. if interface_ is not None and not isinstance(interface_, (bytes, str)): - raise Exception("Expected interface_ to be a str, received: {}".format(type(interface_))) + raise Exception( + "Expected interface_ to be a str, received: {}".format(type(interface_)) + ) if limit_ is not None and not isinstance(limit_, int): - raise Exception("Expected limit_ to be a int, received: {}".format(type(limit_))) + raise Exception( + "Expected limit_ to be a int, received: {}".format(type(limit_)) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if optional_ is not None and not isinstance(optional_, bool): - raise Exception("Expected optional_ to be a bool, received: {}".format(type(optional_))) + raise Exception( + "Expected optional_ to be a bool, received: {}".format(type(optional_)) + ) if role_ is not None and not isinstance(role_, (bytes, str)): - raise Exception("Expected role_ to be a str, received: {}".format(type(role_))) + raise Exception( + "Expected role_ to be a str, received: {}".format(type(role_)) + ) if scope_ is not None and not isinstance(scope_, (bytes, str)): - raise Exception("Expected scope_ to be a str, received: {}".format(type(scope_))) + raise Exception( + "Expected scope_ to be a str, received: {}".format(type(scope_)) + ) self.interface = interface_ self.limit = limit_ @@ -3864,12 +6237,41 @@ def __init__(self, interface=None, limit=None, name=None, optional=None, role=No self.unknown_fields = unknown_fields - class CharmResource(Type): - _toSchema = {'description': 'description', 'fingerprint': 'fingerprint', 'name': 'name', 'origin': 'origin', 'path': 'path', 'revision': 'revision', 'size': 'size', 'type_': 'type'} - _toPy = {'description': 'description', 'fingerprint': 'fingerprint', 'name': 'name', 'origin': 'origin', 'path': 'path', 'revision': 'revision', 'size': 'size', 'type': 'type_'} - def __init__(self, description=None, fingerprint=None, name=None, origin=None, path=None, revision=None, size=None, type_=None, **unknown_fields): - ''' + _toSchema = { + "description": "description", + "fingerprint": "fingerprint", + "name": "name", + "origin": "origin", + "path": "path", + "revision": "revision", + "size": "size", + "type_": "type", + } + _toPy = { + "description": "description", + "fingerprint": "fingerprint", + "name": "name", + "origin": "origin", + "path": "path", + "revision": "revision", + "size": "size", + "type": "type_", + } + + def __init__( + self, + description=None, + fingerprint=None, + name=None, + origin=None, + path=None, + revision=None, + size=None, + type_=None, + **unknown_fields, + ): + """ description : str fingerprint : typing.Sequence[int] name : str @@ -3878,7 +6280,7 @@ def __init__(self, description=None, fingerprint=None, name=None, origin=None, p revision : int size : int type_ : str - ''' + """ description_ = description fingerprint_ = fingerprint name_ = name @@ -3890,28 +6292,50 @@ def __init__(self, description=None, fingerprint=None, name=None, origin=None, p # Validate arguments against known Juju API types. if description_ is not None and not isinstance(description_, (bytes, str)): - raise Exception("Expected description_ to be a str, received: {}".format(type(description_))) - - if fingerprint_ is not None and not isinstance(fingerprint_, (bytes, str, list)): - raise Exception("Expected fingerprint_ to be a Sequence, received: {}".format(type(fingerprint_))) + raise Exception( + "Expected description_ to be a str, received: {}".format( + type(description_) + ) + ) + + if fingerprint_ is not None and not isinstance( + fingerprint_, (bytes, str, list) + ): + raise Exception( + "Expected fingerprint_ to be a Sequence, received: {}".format( + type(fingerprint_) + ) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if origin_ is not None and not isinstance(origin_, (bytes, str)): - raise Exception("Expected origin_ to be a str, received: {}".format(type(origin_))) + raise Exception( + "Expected origin_ to be a str, received: {}".format(type(origin_)) + ) if path_ is not None and not isinstance(path_, (bytes, str)): - raise Exception("Expected path_ to be a str, received: {}".format(type(path_))) + raise Exception( + "Expected path_ to be a str, received: {}".format(type(path_)) + ) if revision_ is not None and not isinstance(revision_, int): - raise Exception("Expected revision_ to be a int, received: {}".format(type(revision_))) + raise Exception( + "Expected revision_ to be a int, received: {}".format(type(revision_)) + ) if size_ is not None and not isinstance(size_, int): - raise Exception("Expected size_ to be a int, received: {}".format(type(size_))) + raise Exception( + "Expected size_ to be a int, received: {}".format(type(size_)) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) self.description = description_ self.fingerprint = fingerprint_ @@ -3924,17 +6348,29 @@ def __init__(self, description=None, fingerprint=None, name=None, origin=None, p self.unknown_fields = unknown_fields - class CharmResourceMeta(Type): - _toSchema = {'description': 'description', 'name': 'name', 'path': 'path', 'type_': 'type'} - _toPy = {'description': 'description', 'name': 'name', 'path': 'path', 'type': 'type_'} - def __init__(self, description=None, name=None, path=None, type_=None, **unknown_fields): - ''' + _toSchema = { + "description": "description", + "name": "name", + "path": "path", + "type_": "type", + } + _toPy = { + "description": "description", + "name": "name", + "path": "path", + "type": "type_", + } + + def __init__( + self, description=None, name=None, path=None, type_=None, **unknown_fields + ): + """ description : str name : str path : str type_ : str - ''' + """ description_ = description name_ = name path_ = path @@ -3942,16 +6378,26 @@ def __init__(self, description=None, name=None, path=None, type_=None, **unknown # Validate arguments against known Juju API types. if description_ is not None and not isinstance(description_, (bytes, str)): - raise Exception("Expected description_ to be a str, received: {}".format(type(description_))) + raise Exception( + "Expected description_ to be a str, received: {}".format( + type(description_) + ) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if path_ is not None and not isinstance(path_, (bytes, str)): - raise Exception("Expected path_ to be a str, received: {}".format(type(path_))) + raise Exception( + "Expected path_ to be a str, received: {}".format(type(path_)) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) self.description = description_ self.name = name_ @@ -3960,12 +6406,50 @@ def __init__(self, description=None, name=None, path=None, type_=None, **unknown self.unknown_fields = unknown_fields - class CharmResourceResult(Type): - _toSchema = {'charmresource': 'CharmResource', 'description': 'description', 'error': 'error', 'errorresult': 'ErrorResult', 'fingerprint': 'fingerprint', 'name': 'name', 'origin': 'origin', 'path': 'path', 'revision': 'revision', 'size': 'size', 'type_': 'type'} - _toPy = {'CharmResource': 'charmresource', 'ErrorResult': 'errorresult', 'description': 'description', 'error': 'error', 'fingerprint': 'fingerprint', 'name': 'name', 'origin': 'origin', 'path': 'path', 'revision': 'revision', 'size': 'size', 'type': 'type_'} - def __init__(self, charmresource=None, errorresult=None, description=None, error=None, fingerprint=None, name=None, origin=None, path=None, revision=None, size=None, type_=None, **unknown_fields): - ''' + _toSchema = { + "charmresource": "CharmResource", + "description": "description", + "error": "error", + "errorresult": "ErrorResult", + "fingerprint": "fingerprint", + "name": "name", + "origin": "origin", + "path": "path", + "revision": "revision", + "size": "size", + "type_": "type", + } + _toPy = { + "CharmResource": "charmresource", + "ErrorResult": "errorresult", + "description": "description", + "error": "error", + "fingerprint": "fingerprint", + "name": "name", + "origin": "origin", + "path": "path", + "revision": "revision", + "size": "size", + "type": "type_", + } + + def __init__( + self, + charmresource=None, + errorresult=None, + description=None, + error=None, + fingerprint=None, + name=None, + origin=None, + path=None, + revision=None, + size=None, + type_=None, + **unknown_fields, + ): + """ charmresource : CharmResource errorresult : ErrorResult description : str @@ -3977,8 +6461,10 @@ def __init__(self, charmresource=None, errorresult=None, description=None, error revision : int size : int type_ : str - ''' - charmresource_ = CharmResource.from_json(charmresource) if charmresource else None + """ + charmresource_ = ( + CharmResource.from_json(charmresource) if charmresource else None + ) errorresult_ = ErrorResult.from_json(errorresult) if errorresult else None description_ = description error_ = Error.from_json(error) if error else None @@ -3991,38 +6477,74 @@ def __init__(self, charmresource=None, errorresult=None, description=None, error type__ = type_ # Validate arguments against known Juju API types. - if charmresource_ is not None and not isinstance(charmresource_, (dict, CharmResource)): - raise Exception("Expected charmresource_ to be a CharmResource, received: {}".format(type(charmresource_))) - - if errorresult_ is not None and not isinstance(errorresult_, (dict, ErrorResult)): - raise Exception("Expected errorresult_ to be a ErrorResult, received: {}".format(type(errorresult_))) + if charmresource_ is not None and not isinstance( + charmresource_, (dict, CharmResource) + ): + raise Exception( + "Expected charmresource_ to be a CharmResource, received: {}".format( + type(charmresource_) + ) + ) + + if errorresult_ is not None and not isinstance( + errorresult_, (dict, ErrorResult) + ): + raise Exception( + "Expected errorresult_ to be a ErrorResult, received: {}".format( + type(errorresult_) + ) + ) if description_ is not None and not isinstance(description_, (bytes, str)): - raise Exception("Expected description_ to be a str, received: {}".format(type(description_))) + raise Exception( + "Expected description_ to be a str, received: {}".format( + type(description_) + ) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) - - if fingerprint_ is not None and not isinstance(fingerprint_, (bytes, str, list)): - raise Exception("Expected fingerprint_ to be a Sequence, received: {}".format(type(fingerprint_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) + + if fingerprint_ is not None and not isinstance( + fingerprint_, (bytes, str, list) + ): + raise Exception( + "Expected fingerprint_ to be a Sequence, received: {}".format( + type(fingerprint_) + ) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if origin_ is not None and not isinstance(origin_, (bytes, str)): - raise Exception("Expected origin_ to be a str, received: {}".format(type(origin_))) + raise Exception( + "Expected origin_ to be a str, received: {}".format(type(origin_)) + ) if path_ is not None and not isinstance(path_, (bytes, str)): - raise Exception("Expected path_ to be a str, received: {}".format(type(path_))) + raise Exception( + "Expected path_ to be a str, received: {}".format(type(path_)) + ) if revision_ is not None and not isinstance(revision_, int): - raise Exception("Expected revision_ to be a int, received: {}".format(type(revision_))) + raise Exception( + "Expected revision_ to be a int, received: {}".format(type(revision_)) + ) if size_ is not None and not isinstance(size_, int): - raise Exception("Expected size_ to be a int, received: {}".format(type(size_))) + raise Exception( + "Expected size_ to be a int, received: {}".format(type(size_)) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) self.charmresource = charmresource_ self.errorresult = errorresult_ @@ -4038,30 +6560,69 @@ def __init__(self, charmresource=None, errorresult=None, description=None, error self.unknown_fields = unknown_fields - class CharmResourcesResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~CharmResourceResult] - ''' + """ results_ = [CharmResourceResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class CharmStorage(Type): - _toSchema = {'count_max': 'count-max', 'count_min': 'count-min', 'description': 'description', 'location': 'location', 'minimum_size': 'minimum-size', 'name': 'name', 'properties': 'properties', 'read_only': 'read-only', 'shared': 'shared', 'type_': 'type'} - _toPy = {'count-max': 'count_max', 'count-min': 'count_min', 'description': 'description', 'location': 'location', 'minimum-size': 'minimum_size', 'name': 'name', 'properties': 'properties', 'read-only': 'read_only', 'shared': 'shared', 'type': 'type_'} - def __init__(self, count_max=None, count_min=None, description=None, location=None, minimum_size=None, name=None, properties=None, read_only=None, shared=None, type_=None, **unknown_fields): - ''' + _toSchema = { + "count_max": "count-max", + "count_min": "count-min", + "description": "description", + "location": "location", + "minimum_size": "minimum-size", + "name": "name", + "properties": "properties", + "read_only": "read-only", + "shared": "shared", + "type_": "type", + } + _toPy = { + "count-max": "count_max", + "count-min": "count_min", + "description": "description", + "location": "location", + "minimum-size": "minimum_size", + "name": "name", + "properties": "properties", + "read-only": "read_only", + "shared": "shared", + "type": "type_", + } + + def __init__( + self, + count_max=None, + count_min=None, + description=None, + location=None, + minimum_size=None, + name=None, + properties=None, + read_only=None, + shared=None, + type_=None, + **unknown_fields, + ): + """ count_max : int count_min : int description : str @@ -4072,7 +6633,7 @@ def __init__(self, count_max=None, count_min=None, description=None, location=No read_only : bool shared : bool type_ : str - ''' + """ count_max_ = count_max count_min_ = count_min description_ = description @@ -4086,34 +6647,62 @@ def __init__(self, count_max=None, count_min=None, description=None, location=No # Validate arguments against known Juju API types. if count_max_ is not None and not isinstance(count_max_, int): - raise Exception("Expected count_max_ to be a int, received: {}".format(type(count_max_))) + raise Exception( + "Expected count_max_ to be a int, received: {}".format(type(count_max_)) + ) if count_min_ is not None and not isinstance(count_min_, int): - raise Exception("Expected count_min_ to be a int, received: {}".format(type(count_min_))) + raise Exception( + "Expected count_min_ to be a int, received: {}".format(type(count_min_)) + ) if description_ is not None and not isinstance(description_, (bytes, str)): - raise Exception("Expected description_ to be a str, received: {}".format(type(description_))) + raise Exception( + "Expected description_ to be a str, received: {}".format( + type(description_) + ) + ) if location_ is not None and not isinstance(location_, (bytes, str)): - raise Exception("Expected location_ to be a str, received: {}".format(type(location_))) + raise Exception( + "Expected location_ to be a str, received: {}".format(type(location_)) + ) if minimum_size_ is not None and not isinstance(minimum_size_, int): - raise Exception("Expected minimum_size_ to be a int, received: {}".format(type(minimum_size_))) + raise Exception( + "Expected minimum_size_ to be a int, received: {}".format( + type(minimum_size_) + ) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if properties_ is not None and not isinstance(properties_, (bytes, str, list)): - raise Exception("Expected properties_ to be a Sequence, received: {}".format(type(properties_))) + raise Exception( + "Expected properties_ to be a Sequence, received: {}".format( + type(properties_) + ) + ) if read_only_ is not None and not isinstance(read_only_, bool): - raise Exception("Expected read_only_ to be a bool, received: {}".format(type(read_only_))) + raise Exception( + "Expected read_only_ to be a bool, received: {}".format( + type(read_only_) + ) + ) if shared_ is not None and not isinstance(shared_, bool): - raise Exception("Expected shared_ to be a bool, received: {}".format(type(shared_))) + raise Exception( + "Expected shared_ to be a bool, received: {}".format(type(shared_)) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) self.count_max = count_max_ self.count_min = count_min_ @@ -4128,47 +6717,71 @@ def __init__(self, count_max=None, count_min=None, description=None, location=No self.unknown_fields = unknown_fields - class CharmURL(Type): - _toSchema = {'url': 'url'} - _toPy = {'url': 'url'} + _toSchema = {"url": "url"} + _toPy = {"url": "url"} + def __init__(self, url=None, **unknown_fields): - ''' + """ url : str - ''' + """ url_ = url # Validate arguments against known Juju API types. if url_ is not None and not isinstance(url_, (bytes, str)): - raise Exception("Expected url_ to be a str, received: {}".format(type(url_))) + raise Exception( + "Expected url_ to be a str, received: {}".format(type(url_)) + ) self.url = url_ self.unknown_fields = unknown_fields - class CharmURLAndOrigin(Type): - _toSchema = {'charm_origin': 'charm-origin', 'charm_url': 'charm-url', 'macaroon': 'macaroon'} - _toPy = {'charm-origin': 'charm_origin', 'charm-url': 'charm_url', 'macaroon': 'macaroon'} - def __init__(self, charm_origin=None, charm_url=None, macaroon=None, **unknown_fields): - ''' + _toSchema = { + "charm_origin": "charm-origin", + "charm_url": "charm-url", + "macaroon": "macaroon", + } + _toPy = { + "charm-origin": "charm_origin", + "charm-url": "charm_url", + "macaroon": "macaroon", + } + + def __init__( + self, charm_origin=None, charm_url=None, macaroon=None, **unknown_fields + ): + """ charm_origin : CharmOrigin charm_url : str macaroon : Macaroon - ''' + """ charm_origin_ = CharmOrigin.from_json(charm_origin) if charm_origin else None charm_url_ = charm_url macaroon_ = Macaroon.from_json(macaroon) if macaroon else None # Validate arguments against known Juju API types. - if charm_origin_ is not None and not isinstance(charm_origin_, (dict, CharmOrigin)): - raise Exception("Expected charm_origin_ to be a CharmOrigin, received: {}".format(type(charm_origin_))) + if charm_origin_ is not None and not isinstance( + charm_origin_, (dict, CharmOrigin) + ): + raise Exception( + "Expected charm_origin_ to be a CharmOrigin, received: {}".format( + type(charm_origin_) + ) + ) if charm_url_ is not None and not isinstance(charm_url_, (bytes, str)): - raise Exception("Expected charm_url_ to be a str, received: {}".format(type(charm_url_))) + raise Exception( + "Expected charm_url_ to be a str, received: {}".format(type(charm_url_)) + ) if macaroon_ is not None and not isinstance(macaroon_, (dict, Macaroon)): - raise Exception("Expected macaroon_ to be a Macaroon, received: {}".format(type(macaroon_))) + raise Exception( + "Expected macaroon_ to be a Macaroon, received: {}".format( + type(macaroon_) + ) + ) self.charm_origin = charm_origin_ self.charm_url = charm_url_ @@ -4176,47 +6789,61 @@ def __init__(self, charm_origin=None, charm_url=None, macaroon=None, **unknown_f self.unknown_fields = unknown_fields - class CharmURLAndOrigins(Type): - _toSchema = {'entities': 'entities'} - _toPy = {'entities': 'entities'} + _toSchema = {"entities": "entities"} + _toPy = {"entities": "entities"} + def __init__(self, entities=None, **unknown_fields): - ''' + """ entities : typing.Sequence[~CharmURLAndOrigin] - ''' + """ entities_ = [CharmURLAndOrigin.from_json(o) for o in entities or []] # Validate arguments against known Juju API types. if entities_ is not None and not isinstance(entities_, (bytes, str, list)): - raise Exception("Expected entities_ to be a Sequence, received: {}".format(type(entities_))) + raise Exception( + "Expected entities_ to be a Sequence, received: {}".format( + type(entities_) + ) + ) self.entities = entities_ self.unknown_fields = unknown_fields - class CharmURLOriginResult(Type): - _toSchema = {'charm_origin': 'charm-origin', 'error': 'error', 'url': 'url'} - _toPy = {'charm-origin': 'charm_origin', 'error': 'error', 'url': 'url'} + _toSchema = {"charm_origin": "charm-origin", "error": "error", "url": "url"} + _toPy = {"charm-origin": "charm_origin", "error": "error", "url": "url"} + def __init__(self, charm_origin=None, error=None, url=None, **unknown_fields): - ''' + """ charm_origin : CharmOrigin error : Error url : str - ''' + """ charm_origin_ = CharmOrigin.from_json(charm_origin) if charm_origin else None error_ = Error.from_json(error) if error else None url_ = url # Validate arguments against known Juju API types. - if charm_origin_ is not None and not isinstance(charm_origin_, (dict, CharmOrigin)): - raise Exception("Expected charm_origin_ to be a CharmOrigin, received: {}".format(type(charm_origin_))) + if charm_origin_ is not None and not isinstance( + charm_origin_, (dict, CharmOrigin) + ): + raise Exception( + "Expected charm_origin_ to be a CharmOrigin, received: {}".format( + type(charm_origin_) + ) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if url_ is not None and not isinstance(url_, (bytes, str)): - raise Exception("Expected url_ to be a str, received: {}".format(type(url_))) + raise Exception( + "Expected url_ to be a str, received: {}".format(type(url_)) + ) self.charm_origin = charm_origin_ self.error = error_ @@ -4224,48 +6851,95 @@ def __init__(self, charm_origin=None, error=None, url=None, **unknown_fields): self.unknown_fields = unknown_fields - class CharmsList(Type): - _toSchema = {'names': 'names'} - _toPy = {'names': 'names'} + _toSchema = {"names": "names"} + _toPy = {"names": "names"} + def __init__(self, names=None, **unknown_fields): - ''' + """ names : typing.Sequence[str] - ''' + """ names_ = names # Validate arguments against known Juju API types. if names_ is not None and not isinstance(names_, (bytes, str, list)): - raise Exception("Expected names_ to be a Sequence, received: {}".format(type(names_))) + raise Exception( + "Expected names_ to be a Sequence, received: {}".format(type(names_)) + ) self.names = names_ self.unknown_fields = unknown_fields - class CharmsListResult(Type): - _toSchema = {'charm_urls': 'charm-urls'} - _toPy = {'charm-urls': 'charm_urls'} + _toSchema = {"charm_urls": "charm-urls"} + _toPy = {"charm-urls": "charm_urls"} + def __init__(self, charm_urls=None, **unknown_fields): - ''' + """ charm_urls : typing.Sequence[str] - ''' + """ charm_urls_ = charm_urls # Validate arguments against known Juju API types. if charm_urls_ is not None and not isinstance(charm_urls_, (bytes, str, list)): - raise Exception("Expected charm_urls_ to be a Sequence, received: {}".format(type(charm_urls_))) + raise Exception( + "Expected charm_urls_ to be a Sequence, received: {}".format( + type(charm_urls_) + ) + ) self.charm_urls = charm_urls_ self.unknown_fields = unknown_fields - class Cloud(Type): - _toSchema = {'auth_types': 'auth-types', 'ca_certificates': 'ca-certificates', 'config': 'config', 'endpoint': 'endpoint', 'host_cloud_region': 'host-cloud-region', 'identity_endpoint': 'identity-endpoint', 'is_controller_cloud': 'is-controller-cloud', 'region_config': 'region-config', 'regions': 'regions', 'skip_tls_verify': 'skip-tls-verify', 'storage_endpoint': 'storage-endpoint', 'type_': 'type'} - _toPy = {'auth-types': 'auth_types', 'ca-certificates': 'ca_certificates', 'config': 'config', 'endpoint': 'endpoint', 'host-cloud-region': 'host_cloud_region', 'identity-endpoint': 'identity_endpoint', 'is-controller-cloud': 'is_controller_cloud', 'region-config': 'region_config', 'regions': 'regions', 'skip-tls-verify': 'skip_tls_verify', 'storage-endpoint': 'storage_endpoint', 'type': 'type_'} - def __init__(self, auth_types=None, ca_certificates=None, config=None, endpoint=None, host_cloud_region=None, identity_endpoint=None, is_controller_cloud=None, region_config=None, regions=None, skip_tls_verify=None, storage_endpoint=None, type_=None, **unknown_fields): - ''' + _toSchema = { + "auth_types": "auth-types", + "ca_certificates": "ca-certificates", + "config": "config", + "endpoint": "endpoint", + "host_cloud_region": "host-cloud-region", + "identity_endpoint": "identity-endpoint", + "is_controller_cloud": "is-controller-cloud", + "region_config": "region-config", + "regions": "regions", + "skip_tls_verify": "skip-tls-verify", + "storage_endpoint": "storage-endpoint", + "type_": "type", + } + _toPy = { + "auth-types": "auth_types", + "ca-certificates": "ca_certificates", + "config": "config", + "endpoint": "endpoint", + "host-cloud-region": "host_cloud_region", + "identity-endpoint": "identity_endpoint", + "is-controller-cloud": "is_controller_cloud", + "region-config": "region_config", + "regions": "regions", + "skip-tls-verify": "skip_tls_verify", + "storage-endpoint": "storage_endpoint", + "type": "type_", + } + + def __init__( + self, + auth_types=None, + ca_certificates=None, + config=None, + endpoint=None, + host_cloud_region=None, + identity_endpoint=None, + is_controller_cloud=None, + region_config=None, + regions=None, + skip_tls_verify=None, + storage_endpoint=None, + type_=None, + **unknown_fields, + ): + """ auth_types : typing.Sequence[str] ca_certificates : typing.Sequence[str] config : typing.Mapping[str, typing.Any] @@ -4278,7 +6952,7 @@ def __init__(self, auth_types=None, ca_certificates=None, config=None, endpoint= skip_tls_verify : bool storage_endpoint : str type_ : str - ''' + """ auth_types_ = auth_types ca_certificates_ = ca_certificates config_ = config @@ -4294,40 +6968,92 @@ def __init__(self, auth_types=None, ca_certificates=None, config=None, endpoint= # Validate arguments against known Juju API types. if auth_types_ is not None and not isinstance(auth_types_, (bytes, str, list)): - raise Exception("Expected auth_types_ to be a Sequence, received: {}".format(type(auth_types_))) - - if ca_certificates_ is not None and not isinstance(ca_certificates_, (bytes, str, list)): - raise Exception("Expected ca_certificates_ to be a Sequence, received: {}".format(type(ca_certificates_))) + raise Exception( + "Expected auth_types_ to be a Sequence, received: {}".format( + type(auth_types_) + ) + ) + + if ca_certificates_ is not None and not isinstance( + ca_certificates_, (bytes, str, list) + ): + raise Exception( + "Expected ca_certificates_ to be a Sequence, received: {}".format( + type(ca_certificates_) + ) + ) if config_ is not None and not isinstance(config_, dict): - raise Exception("Expected config_ to be a Mapping, received: {}".format(type(config_))) + raise Exception( + "Expected config_ to be a Mapping, received: {}".format(type(config_)) + ) if endpoint_ is not None and not isinstance(endpoint_, (bytes, str)): - raise Exception("Expected endpoint_ to be a str, received: {}".format(type(endpoint_))) + raise Exception( + "Expected endpoint_ to be a str, received: {}".format(type(endpoint_)) + ) + + if host_cloud_region_ is not None and not isinstance( + host_cloud_region_, (bytes, str) + ): + raise Exception( + "Expected host_cloud_region_ to be a str, received: {}".format( + type(host_cloud_region_) + ) + ) + + if identity_endpoint_ is not None and not isinstance( + identity_endpoint_, (bytes, str) + ): + raise Exception( + "Expected identity_endpoint_ to be a str, received: {}".format( + type(identity_endpoint_) + ) + ) + + if is_controller_cloud_ is not None and not isinstance( + is_controller_cloud_, bool + ): + raise Exception( + "Expected is_controller_cloud_ to be a bool, received: {}".format( + type(is_controller_cloud_) + ) + ) - if host_cloud_region_ is not None and not isinstance(host_cloud_region_, (bytes, str)): - raise Exception("Expected host_cloud_region_ to be a str, received: {}".format(type(host_cloud_region_))) - - if identity_endpoint_ is not None and not isinstance(identity_endpoint_, (bytes, str)): - raise Exception("Expected identity_endpoint_ to be a str, received: {}".format(type(identity_endpoint_))) - - if is_controller_cloud_ is not None and not isinstance(is_controller_cloud_, bool): - raise Exception("Expected is_controller_cloud_ to be a bool, received: {}".format(type(is_controller_cloud_))) - - if region_config_ is not None and not isinstance(region_config_, dict): - raise Exception("Expected region_config_ to be a Mapping, received: {}".format(type(region_config_))) + if region_config_ is not None and not isinstance(region_config_, dict): + raise Exception( + "Expected region_config_ to be a Mapping, received: {}".format( + type(region_config_) + ) + ) if regions_ is not None and not isinstance(regions_, (bytes, str, list)): - raise Exception("Expected regions_ to be a Sequence, received: {}".format(type(regions_))) + raise Exception( + "Expected regions_ to be a Sequence, received: {}".format( + type(regions_) + ) + ) if skip_tls_verify_ is not None and not isinstance(skip_tls_verify_, bool): - raise Exception("Expected skip_tls_verify_ to be a bool, received: {}".format(type(skip_tls_verify_))) - - if storage_endpoint_ is not None and not isinstance(storage_endpoint_, (bytes, str)): - raise Exception("Expected storage_endpoint_ to be a str, received: {}".format(type(storage_endpoint_))) + raise Exception( + "Expected skip_tls_verify_ to be a bool, received: {}".format( + type(skip_tls_verify_) + ) + ) + + if storage_endpoint_ is not None and not isinstance( + storage_endpoint_, (bytes, str) + ): + raise Exception( + "Expected storage_endpoint_ to be a str, received: {}".format( + type(storage_endpoint_) + ) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) self.auth_types = auth_types_ self.ca_certificates = ca_certificates_ @@ -4344,29 +7070,37 @@ def __init__(self, auth_types=None, ca_certificates=None, config=None, endpoint= self.unknown_fields = unknown_fields - class CloudCredential(Type): - _toSchema = {'attrs': 'attrs', 'auth_type': 'auth-type', 'redacted': 'redacted'} - _toPy = {'attrs': 'attrs', 'auth-type': 'auth_type', 'redacted': 'redacted'} + _toSchema = {"attrs": "attrs", "auth_type": "auth-type", "redacted": "redacted"} + _toPy = {"attrs": "attrs", "auth-type": "auth_type", "redacted": "redacted"} + def __init__(self, attrs=None, auth_type=None, redacted=None, **unknown_fields): - ''' + """ attrs : typing.Mapping[str, str] auth_type : str redacted : typing.Sequence[str] - ''' + """ attrs_ = attrs auth_type_ = auth_type redacted_ = redacted # Validate arguments against known Juju API types. if attrs_ is not None and not isinstance(attrs_, dict): - raise Exception("Expected attrs_ to be a Mapping, received: {}".format(type(attrs_))) + raise Exception( + "Expected attrs_ to be a Mapping, received: {}".format(type(attrs_)) + ) if auth_type_ is not None and not isinstance(auth_type_, (bytes, str)): - raise Exception("Expected auth_type_ to be a str, received: {}".format(type(auth_type_))) + raise Exception( + "Expected auth_type_ to be a str, received: {}".format(type(auth_type_)) + ) if redacted_ is not None and not isinstance(redacted_, (bytes, str, list)): - raise Exception("Expected redacted_ to be a Sequence, received: {}".format(type(redacted_))) + raise Exception( + "Expected redacted_ to be a Sequence, received: {}".format( + type(redacted_) + ) + ) self.attrs = attrs_ self.auth_type = auth_type_ @@ -4374,109 +7108,162 @@ def __init__(self, attrs=None, auth_type=None, redacted=None, **unknown_fields): self.unknown_fields = unknown_fields - class CloudCredentialArg(Type): - _toSchema = {'cloud_name': 'cloud-name', 'credential_name': 'credential-name'} - _toPy = {'cloud-name': 'cloud_name', 'credential-name': 'credential_name'} + _toSchema = {"cloud_name": "cloud-name", "credential_name": "credential-name"} + _toPy = {"cloud-name": "cloud_name", "credential-name": "credential_name"} + def __init__(self, cloud_name=None, credential_name=None, **unknown_fields): - ''' + """ cloud_name : str credential_name : str - ''' + """ cloud_name_ = cloud_name credential_name_ = credential_name # Validate arguments against known Juju API types. if cloud_name_ is not None and not isinstance(cloud_name_, (bytes, str)): - raise Exception("Expected cloud_name_ to be a str, received: {}".format(type(cloud_name_))) - - if credential_name_ is not None and not isinstance(credential_name_, (bytes, str)): - raise Exception("Expected credential_name_ to be a str, received: {}".format(type(credential_name_))) + raise Exception( + "Expected cloud_name_ to be a str, received: {}".format( + type(cloud_name_) + ) + ) + + if credential_name_ is not None and not isinstance( + credential_name_, (bytes, str) + ): + raise Exception( + "Expected credential_name_ to be a str, received: {}".format( + type(credential_name_) + ) + ) self.cloud_name = cloud_name_ self.credential_name = credential_name_ self.unknown_fields = unknown_fields - class CloudCredentialArgs(Type): - _toSchema = {'credentials': 'credentials', 'include_secrets': 'include-secrets'} - _toPy = {'credentials': 'credentials', 'include-secrets': 'include_secrets'} + _toSchema = {"credentials": "credentials", "include_secrets": "include-secrets"} + _toPy = {"credentials": "credentials", "include-secrets": "include_secrets"} + def __init__(self, credentials=None, include_secrets=None, **unknown_fields): - ''' + """ credentials : typing.Sequence[~CloudCredentialArg] include_secrets : bool - ''' + """ credentials_ = [CloudCredentialArg.from_json(o) for o in credentials or []] include_secrets_ = include_secrets # Validate arguments against known Juju API types. - if credentials_ is not None and not isinstance(credentials_, (bytes, str, list)): - raise Exception("Expected credentials_ to be a Sequence, received: {}".format(type(credentials_))) + if credentials_ is not None and not isinstance( + credentials_, (bytes, str, list) + ): + raise Exception( + "Expected credentials_ to be a Sequence, received: {}".format( + type(credentials_) + ) + ) if include_secrets_ is not None and not isinstance(include_secrets_, bool): - raise Exception("Expected include_secrets_ to be a bool, received: {}".format(type(include_secrets_))) + raise Exception( + "Expected include_secrets_ to be a bool, received: {}".format( + type(include_secrets_) + ) + ) self.credentials = credentials_ self.include_secrets = include_secrets_ self.unknown_fields = unknown_fields - class CloudCredentialResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : CloudCredential - ''' + """ error_ = Error.from_json(error) if error else None result_ = CloudCredential.from_json(result) if result else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if result_ is not None and not isinstance(result_, (dict, CloudCredential)): - raise Exception("Expected result_ to be a CloudCredential, received: {}".format(type(result_))) + raise Exception( + "Expected result_ to be a CloudCredential, received: {}".format( + type(result_) + ) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class CloudCredentialResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~CloudCredentialResult] - ''' + """ results_ = [CloudCredentialResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class CloudDetails(Type): - _toSchema = {'auth_types': 'auth-types', 'endpoint': 'endpoint', 'identity_endpoint': 'identity-endpoint', 'regions': 'regions', 'storage_endpoint': 'storage-endpoint', 'type_': 'type'} - _toPy = {'auth-types': 'auth_types', 'endpoint': 'endpoint', 'identity-endpoint': 'identity_endpoint', 'regions': 'regions', 'storage-endpoint': 'storage_endpoint', 'type': 'type_'} - def __init__(self, auth_types=None, endpoint=None, identity_endpoint=None, regions=None, storage_endpoint=None, type_=None, **unknown_fields): - ''' + _toSchema = { + "auth_types": "auth-types", + "endpoint": "endpoint", + "identity_endpoint": "identity-endpoint", + "regions": "regions", + "storage_endpoint": "storage-endpoint", + "type_": "type", + } + _toPy = { + "auth-types": "auth_types", + "endpoint": "endpoint", + "identity-endpoint": "identity_endpoint", + "regions": "regions", + "storage-endpoint": "storage_endpoint", + "type": "type_", + } + + def __init__( + self, + auth_types=None, + endpoint=None, + identity_endpoint=None, + regions=None, + storage_endpoint=None, + type_=None, + **unknown_fields, + ): + """ auth_types : typing.Sequence[str] endpoint : str identity_endpoint : str regions : typing.Sequence[~CloudRegion] storage_endpoint : str type_ : str - ''' + """ auth_types_ = auth_types endpoint_ = endpoint identity_endpoint_ = identity_endpoint @@ -4486,22 +7273,46 @@ def __init__(self, auth_types=None, endpoint=None, identity_endpoint=None, regio # Validate arguments against known Juju API types. if auth_types_ is not None and not isinstance(auth_types_, (bytes, str, list)): - raise Exception("Expected auth_types_ to be a Sequence, received: {}".format(type(auth_types_))) + raise Exception( + "Expected auth_types_ to be a Sequence, received: {}".format( + type(auth_types_) + ) + ) if endpoint_ is not None and not isinstance(endpoint_, (bytes, str)): - raise Exception("Expected endpoint_ to be a str, received: {}".format(type(endpoint_))) - - if identity_endpoint_ is not None and not isinstance(identity_endpoint_, (bytes, str)): - raise Exception("Expected identity_endpoint_ to be a str, received: {}".format(type(identity_endpoint_))) + raise Exception( + "Expected endpoint_ to be a str, received: {}".format(type(endpoint_)) + ) + + if identity_endpoint_ is not None and not isinstance( + identity_endpoint_, (bytes, str) + ): + raise Exception( + "Expected identity_endpoint_ to be a str, received: {}".format( + type(identity_endpoint_) + ) + ) if regions_ is not None and not isinstance(regions_, (bytes, str, list)): - raise Exception("Expected regions_ to be a Sequence, received: {}".format(type(regions_))) - - if storage_endpoint_ is not None and not isinstance(storage_endpoint_, (bytes, str)): - raise Exception("Expected storage_endpoint_ to be a str, received: {}".format(type(storage_endpoint_))) + raise Exception( + "Expected regions_ to be a Sequence, received: {}".format( + type(regions_) + ) + ) + + if storage_endpoint_ is not None and not isinstance( + storage_endpoint_, (bytes, str) + ): + raise Exception( + "Expected storage_endpoint_ to be a str, received: {}".format( + type(storage_endpoint_) + ) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) self.auth_types = auth_types_ self.endpoint = endpoint_ @@ -4512,12 +7323,47 @@ def __init__(self, auth_types=None, endpoint=None, identity_endpoint=None, regio self.unknown_fields = unknown_fields - class CloudImageMetadata(Type): - _toSchema = {'arch': 'arch', 'image_id': 'image-id', 'priority': 'priority', 'region': 'region', 'root_storage_size': 'root-storage-size', 'root_storage_type': 'root-storage-type', 'source': 'source', 'stream': 'stream', 'version': 'version', 'virt_type': 'virt-type'} - _toPy = {'arch': 'arch', 'image-id': 'image_id', 'priority': 'priority', 'region': 'region', 'root-storage-size': 'root_storage_size', 'root-storage-type': 'root_storage_type', 'source': 'source', 'stream': 'stream', 'version': 'version', 'virt-type': 'virt_type'} - def __init__(self, arch=None, image_id=None, priority=None, region=None, root_storage_size=None, root_storage_type=None, source=None, stream=None, version=None, virt_type=None, **unknown_fields): - ''' + _toSchema = { + "arch": "arch", + "image_id": "image-id", + "priority": "priority", + "region": "region", + "root_storage_size": "root-storage-size", + "root_storage_type": "root-storage-type", + "source": "source", + "stream": "stream", + "version": "version", + "virt_type": "virt-type", + } + _toPy = { + "arch": "arch", + "image-id": "image_id", + "priority": "priority", + "region": "region", + "root-storage-size": "root_storage_size", + "root-storage-type": "root_storage_type", + "source": "source", + "stream": "stream", + "version": "version", + "virt-type": "virt_type", + } + + def __init__( + self, + arch=None, + image_id=None, + priority=None, + region=None, + root_storage_size=None, + root_storage_type=None, + source=None, + stream=None, + version=None, + virt_type=None, + **unknown_fields, + ): + """ arch : str image_id : str priority : int @@ -4528,7 +7374,7 @@ def __init__(self, arch=None, image_id=None, priority=None, region=None, root_st stream : str version : str virt_type : str - ''' + """ arch_ = arch image_id_ = image_id priority_ = priority @@ -4542,34 +7388,60 @@ def __init__(self, arch=None, image_id=None, priority=None, region=None, root_st # Validate arguments against known Juju API types. if arch_ is not None and not isinstance(arch_, (bytes, str)): - raise Exception("Expected arch_ to be a str, received: {}".format(type(arch_))) + raise Exception( + "Expected arch_ to be a str, received: {}".format(type(arch_)) + ) if image_id_ is not None and not isinstance(image_id_, (bytes, str)): - raise Exception("Expected image_id_ to be a str, received: {}".format(type(image_id_))) + raise Exception( + "Expected image_id_ to be a str, received: {}".format(type(image_id_)) + ) if priority_ is not None and not isinstance(priority_, int): - raise Exception("Expected priority_ to be a int, received: {}".format(type(priority_))) + raise Exception( + "Expected priority_ to be a int, received: {}".format(type(priority_)) + ) if region_ is not None and not isinstance(region_, (bytes, str)): - raise Exception("Expected region_ to be a str, received: {}".format(type(region_))) + raise Exception( + "Expected region_ to be a str, received: {}".format(type(region_)) + ) if root_storage_size_ is not None and not isinstance(root_storage_size_, int): - raise Exception("Expected root_storage_size_ to be a int, received: {}".format(type(root_storage_size_))) - - if root_storage_type_ is not None and not isinstance(root_storage_type_, (bytes, str)): - raise Exception("Expected root_storage_type_ to be a str, received: {}".format(type(root_storage_type_))) + raise Exception( + "Expected root_storage_size_ to be a int, received: {}".format( + type(root_storage_size_) + ) + ) + + if root_storage_type_ is not None and not isinstance( + root_storage_type_, (bytes, str) + ): + raise Exception( + "Expected root_storage_type_ to be a str, received: {}".format( + type(root_storage_type_) + ) + ) if source_ is not None and not isinstance(source_, (bytes, str)): - raise Exception("Expected source_ to be a str, received: {}".format(type(source_))) + raise Exception( + "Expected source_ to be a str, received: {}".format(type(source_)) + ) if stream_ is not None and not isinstance(stream_, (bytes, str)): - raise Exception("Expected stream_ to be a str, received: {}".format(type(stream_))) + raise Exception( + "Expected stream_ to be a str, received: {}".format(type(stream_)) + ) if version_ is not None and not isinstance(version_, (bytes, str)): - raise Exception("Expected version_ to be a str, received: {}".format(type(version_))) + raise Exception( + "Expected version_ to be a str, received: {}".format(type(version_)) + ) if virt_type_ is not None and not isinstance(virt_type_, (bytes, str)): - raise Exception("Expected virt_type_ to be a str, received: {}".format(type(virt_type_))) + raise Exception( + "Expected virt_type_ to be a str, received: {}".format(type(virt_type_)) + ) self.arch = arch_ self.image_id = image_id_ @@ -4584,113 +7456,145 @@ def __init__(self, arch=None, image_id=None, priority=None, region=None, root_st self.unknown_fields = unknown_fields - class CloudImageMetadataList(Type): - _toSchema = {'metadata': 'metadata'} - _toPy = {'metadata': 'metadata'} + _toSchema = {"metadata": "metadata"} + _toPy = {"metadata": "metadata"} + def __init__(self, metadata=None, **unknown_fields): - ''' + """ metadata : typing.Sequence[~CloudImageMetadata] - ''' + """ metadata_ = [CloudImageMetadata.from_json(o) for o in metadata or []] # Validate arguments against known Juju API types. if metadata_ is not None and not isinstance(metadata_, (bytes, str, list)): - raise Exception("Expected metadata_ to be a Sequence, received: {}".format(type(metadata_))) + raise Exception( + "Expected metadata_ to be a Sequence, received: {}".format( + type(metadata_) + ) + ) self.metadata = metadata_ self.unknown_fields = unknown_fields - class CloudInfo(Type): - _toSchema = {'clouddetails': 'CloudDetails', 'users': 'users'} - _toPy = {'CloudDetails': 'clouddetails', 'users': 'users'} + _toSchema = {"clouddetails": "CloudDetails", "users": "users"} + _toPy = {"CloudDetails": "clouddetails", "users": "users"} + def __init__(self, clouddetails=None, users=None, **unknown_fields): - ''' + """ clouddetails : CloudDetails users : typing.Sequence[~CloudUserInfo] - ''' + """ clouddetails_ = CloudDetails.from_json(clouddetails) if clouddetails else None users_ = [CloudUserInfo.from_json(o) for o in users or []] # Validate arguments against known Juju API types. - if clouddetails_ is not None and not isinstance(clouddetails_, (dict, CloudDetails)): - raise Exception("Expected clouddetails_ to be a CloudDetails, received: {}".format(type(clouddetails_))) + if clouddetails_ is not None and not isinstance( + clouddetails_, (dict, CloudDetails) + ): + raise Exception( + "Expected clouddetails_ to be a CloudDetails, received: {}".format( + type(clouddetails_) + ) + ) if users_ is not None and not isinstance(users_, (bytes, str, list)): - raise Exception("Expected users_ to be a Sequence, received: {}".format(type(users_))) + raise Exception( + "Expected users_ to be a Sequence, received: {}".format(type(users_)) + ) self.clouddetails = clouddetails_ self.users = users_ self.unknown_fields = unknown_fields - class CloudInfoResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : CloudInfo - ''' + """ error_ = Error.from_json(error) if error else None result_ = CloudInfo.from_json(result) if result else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if result_ is not None and not isinstance(result_, (dict, CloudInfo)): - raise Exception("Expected result_ to be a CloudInfo, received: {}".format(type(result_))) + raise Exception( + "Expected result_ to be a CloudInfo, received: {}".format(type(result_)) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class CloudInfoResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~CloudInfoResult] - ''' + """ results_ = [CloudInfoResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class CloudInstanceTypesConstraint(Type): - _toSchema = {'cloud_tag': 'cloud-tag', 'constraints': 'constraints', 'region': 'region'} - _toPy = {'cloud-tag': 'cloud_tag', 'constraints': 'constraints', 'region': 'region'} + _toSchema = { + "cloud_tag": "cloud-tag", + "constraints": "constraints", + "region": "region", + } + _toPy = {"cloud-tag": "cloud_tag", "constraints": "constraints", "region": "region"} + def __init__(self, cloud_tag=None, constraints=None, region=None, **unknown_fields): - ''' + """ cloud_tag : str constraints : Value region : str - ''' + """ cloud_tag_ = cloud_tag constraints_ = Value.from_json(constraints) if constraints else None region_ = region # Validate arguments against known Juju API types. if cloud_tag_ is not None and not isinstance(cloud_tag_, (bytes, str)): - raise Exception("Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_))) + raise Exception( + "Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_)) + ) if constraints_ is not None and not isinstance(constraints_, (dict, Value)): - raise Exception("Expected constraints_ to be a Value, received: {}".format(type(constraints_))) + raise Exception( + "Expected constraints_ to be a Value, received: {}".format( + type(constraints_) + ) + ) if region_ is not None and not isinstance(region_, (bytes, str)): - raise Exception("Expected region_ to be a str, received: {}".format(type(region_))) + raise Exception( + "Expected region_ to be a str, received: {}".format(type(region_)) + ) self.cloud_tag = cloud_tag_ self.constraints = constraints_ @@ -4698,35 +7602,60 @@ def __init__(self, cloud_tag=None, constraints=None, region=None, **unknown_fiel self.unknown_fields = unknown_fields - class CloudInstanceTypesConstraints(Type): - _toSchema = {'constraints': 'constraints'} - _toPy = {'constraints': 'constraints'} + _toSchema = {"constraints": "constraints"} + _toPy = {"constraints": "constraints"} + def __init__(self, constraints=None, **unknown_fields): - ''' + """ constraints : typing.Sequence[~CloudInstanceTypesConstraint] - ''' - constraints_ = [CloudInstanceTypesConstraint.from_json(o) for o in constraints or []] + """ + constraints_ = [ + CloudInstanceTypesConstraint.from_json(o) for o in constraints or [] + ] # Validate arguments against known Juju API types. - if constraints_ is not None and not isinstance(constraints_, (bytes, str, list)): - raise Exception("Expected constraints_ to be a Sequence, received: {}".format(type(constraints_))) + if constraints_ is not None and not isinstance( + constraints_, (bytes, str, list) + ): + raise Exception( + "Expected constraints_ to be a Sequence, received: {}".format( + type(constraints_) + ) + ) self.constraints = constraints_ self.unknown_fields = unknown_fields - class CloudRegion(Type): - _toSchema = {'endpoint': 'endpoint', 'identity_endpoint': 'identity-endpoint', 'name': 'name', 'storage_endpoint': 'storage-endpoint'} - _toPy = {'endpoint': 'endpoint', 'identity-endpoint': 'identity_endpoint', 'name': 'name', 'storage-endpoint': 'storage_endpoint'} - def __init__(self, endpoint=None, identity_endpoint=None, name=None, storage_endpoint=None, **unknown_fields): - ''' + _toSchema = { + "endpoint": "endpoint", + "identity_endpoint": "identity-endpoint", + "name": "name", + "storage_endpoint": "storage-endpoint", + } + _toPy = { + "endpoint": "endpoint", + "identity-endpoint": "identity_endpoint", + "name": "name", + "storage-endpoint": "storage_endpoint", + } + + def __init__( + self, + endpoint=None, + identity_endpoint=None, + name=None, + storage_endpoint=None, + **unknown_fields, + ): + """ endpoint : str identity_endpoint : str name : str storage_endpoint : str - ''' + """ endpoint_ = endpoint identity_endpoint_ = identity_endpoint name_ = name @@ -4734,16 +7663,32 @@ def __init__(self, endpoint=None, identity_endpoint=None, name=None, storage_end # Validate arguments against known Juju API types. if endpoint_ is not None and not isinstance(endpoint_, (bytes, str)): - raise Exception("Expected endpoint_ to be a str, received: {}".format(type(endpoint_))) - - if identity_endpoint_ is not None and not isinstance(identity_endpoint_, (bytes, str)): - raise Exception("Expected identity_endpoint_ to be a str, received: {}".format(type(identity_endpoint_))) + raise Exception( + "Expected endpoint_ to be a str, received: {}".format(type(endpoint_)) + ) + + if identity_endpoint_ is not None and not isinstance( + identity_endpoint_, (bytes, str) + ): + raise Exception( + "Expected identity_endpoint_ to be a str, received: {}".format( + type(identity_endpoint_) + ) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) - - if storage_endpoint_ is not None and not isinstance(storage_endpoint_, (bytes, str)): - raise Exception("Expected storage_endpoint_ to be a str, received: {}".format(type(storage_endpoint_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) + + if storage_endpoint_ is not None and not isinstance( + storage_endpoint_, (bytes, str) + ): + raise Exception( + "Expected storage_endpoint_ to be a str, received: {}".format( + type(storage_endpoint_) + ) + ) self.endpoint = endpoint_ self.identity_endpoint = identity_endpoint_ @@ -4752,54 +7697,97 @@ def __init__(self, endpoint=None, identity_endpoint=None, name=None, storage_end self.unknown_fields = unknown_fields - class CloudResult(Type): - _toSchema = {'cloud': 'cloud', 'error': 'error'} - _toPy = {'cloud': 'cloud', 'error': 'error'} + _toSchema = {"cloud": "cloud", "error": "error"} + _toPy = {"cloud": "cloud", "error": "error"} + def __init__(self, cloud=None, error=None, **unknown_fields): - ''' + """ cloud : Cloud error : Error - ''' + """ cloud_ = Cloud.from_json(cloud) if cloud else None error_ = Error.from_json(error) if error else None # Validate arguments against known Juju API types. if cloud_ is not None and not isinstance(cloud_, (dict, Cloud)): - raise Exception("Expected cloud_ to be a Cloud, received: {}".format(type(cloud_))) + raise Exception( + "Expected cloud_ to be a Cloud, received: {}".format(type(cloud_)) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) self.cloud = cloud_ self.error = error_ self.unknown_fields = unknown_fields - class CloudResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~CloudResult] - ''' + """ results_ = [CloudResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class CloudSpec(Type): - _toSchema = {'cacertificates': 'cacertificates', 'credential': 'credential', 'endpoint': 'endpoint', 'identity_endpoint': 'identity-endpoint', 'is_controller_cloud': 'is-controller-cloud', 'name': 'name', 'region': 'region', 'skip_tls_verify': 'skip-tls-verify', 'storage_endpoint': 'storage-endpoint', 'type_': 'type'} - _toPy = {'cacertificates': 'cacertificates', 'credential': 'credential', 'endpoint': 'endpoint', 'identity-endpoint': 'identity_endpoint', 'is-controller-cloud': 'is_controller_cloud', 'name': 'name', 'region': 'region', 'skip-tls-verify': 'skip_tls_verify', 'storage-endpoint': 'storage_endpoint', 'type': 'type_'} - def __init__(self, cacertificates=None, credential=None, endpoint=None, identity_endpoint=None, is_controller_cloud=None, name=None, region=None, skip_tls_verify=None, storage_endpoint=None, type_=None, **unknown_fields): - ''' + _toSchema = { + "cacertificates": "cacertificates", + "credential": "credential", + "endpoint": "endpoint", + "identity_endpoint": "identity-endpoint", + "is_controller_cloud": "is-controller-cloud", + "name": "name", + "region": "region", + "skip_tls_verify": "skip-tls-verify", + "storage_endpoint": "storage-endpoint", + "type_": "type", + } + _toPy = { + "cacertificates": "cacertificates", + "credential": "credential", + "endpoint": "endpoint", + "identity-endpoint": "identity_endpoint", + "is-controller-cloud": "is_controller_cloud", + "name": "name", + "region": "region", + "skip-tls-verify": "skip_tls_verify", + "storage-endpoint": "storage_endpoint", + "type": "type_", + } + + def __init__( + self, + cacertificates=None, + credential=None, + endpoint=None, + identity_endpoint=None, + is_controller_cloud=None, + name=None, + region=None, + skip_tls_verify=None, + storage_endpoint=None, + type_=None, + **unknown_fields, + ): + """ cacertificates : typing.Sequence[str] credential : CloudCredential endpoint : str @@ -4810,7 +7798,7 @@ def __init__(self, cacertificates=None, credential=None, endpoint=None, identity skip_tls_verify : bool storage_endpoint : str type_ : str - ''' + """ cacertificates_ = cacertificates credential_ = CloudCredential.from_json(credential) if credential else None endpoint_ = endpoint @@ -4823,35 +7811,77 @@ def __init__(self, cacertificates=None, credential=None, endpoint=None, identity type__ = type_ # Validate arguments against known Juju API types. - if cacertificates_ is not None and not isinstance(cacertificates_, (bytes, str, list)): - raise Exception("Expected cacertificates_ to be a Sequence, received: {}".format(type(cacertificates_))) - - if credential_ is not None and not isinstance(credential_, (dict, CloudCredential)): - raise Exception("Expected credential_ to be a CloudCredential, received: {}".format(type(credential_))) + if cacertificates_ is not None and not isinstance( + cacertificates_, (bytes, str, list) + ): + raise Exception( + "Expected cacertificates_ to be a Sequence, received: {}".format( + type(cacertificates_) + ) + ) + + if credential_ is not None and not isinstance( + credential_, (dict, CloudCredential) + ): + raise Exception( + "Expected credential_ to be a CloudCredential, received: {}".format( + type(credential_) + ) + ) if endpoint_ is not None and not isinstance(endpoint_, (bytes, str)): - raise Exception("Expected endpoint_ to be a str, received: {}".format(type(endpoint_))) - - if identity_endpoint_ is not None and not isinstance(identity_endpoint_, (bytes, str)): - raise Exception("Expected identity_endpoint_ to be a str, received: {}".format(type(identity_endpoint_))) - - if is_controller_cloud_ is not None and not isinstance(is_controller_cloud_, bool): - raise Exception("Expected is_controller_cloud_ to be a bool, received: {}".format(type(is_controller_cloud_))) + raise Exception( + "Expected endpoint_ to be a str, received: {}".format(type(endpoint_)) + ) + + if identity_endpoint_ is not None and not isinstance( + identity_endpoint_, (bytes, str) + ): + raise Exception( + "Expected identity_endpoint_ to be a str, received: {}".format( + type(identity_endpoint_) + ) + ) + + if is_controller_cloud_ is not None and not isinstance( + is_controller_cloud_, bool + ): + raise Exception( + "Expected is_controller_cloud_ to be a bool, received: {}".format( + type(is_controller_cloud_) + ) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if region_ is not None and not isinstance(region_, (bytes, str)): - raise Exception("Expected region_ to be a str, received: {}".format(type(region_))) + raise Exception( + "Expected region_ to be a str, received: {}".format(type(region_)) + ) if skip_tls_verify_ is not None and not isinstance(skip_tls_verify_, bool): - raise Exception("Expected skip_tls_verify_ to be a bool, received: {}".format(type(skip_tls_verify_))) - - if storage_endpoint_ is not None and not isinstance(storage_endpoint_, (bytes, str)): - raise Exception("Expected storage_endpoint_ to be a str, received: {}".format(type(storage_endpoint_))) + raise Exception( + "Expected skip_tls_verify_ to be a bool, received: {}".format( + type(skip_tls_verify_) + ) + ) + + if storage_endpoint_ is not None and not isinstance( + storage_endpoint_, (bytes, str) + ): + raise Exception( + "Expected storage_endpoint_ to be a str, received: {}".format( + type(storage_endpoint_) + ) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) self.cacertificates = cacertificates_ self.credential = credential_ @@ -4866,71 +7896,87 @@ def __init__(self, cacertificates=None, credential=None, endpoint=None, identity self.unknown_fields = unknown_fields - class CloudSpecResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : CloudSpec - ''' + """ error_ = Error.from_json(error) if error else None result_ = CloudSpec.from_json(result) if result else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if result_ is not None and not isinstance(result_, (dict, CloudSpec)): - raise Exception("Expected result_ to be a CloudSpec, received: {}".format(type(result_))) + raise Exception( + "Expected result_ to be a CloudSpec, received: {}".format(type(result_)) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class CloudSpecResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~CloudSpecResult] - ''' + """ results_ = [CloudSpecResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class CloudUserInfo(Type): - _toSchema = {'access': 'access', 'display_name': 'display-name', 'user': 'user'} - _toPy = {'access': 'access', 'display-name': 'display_name', 'user': 'user'} + _toSchema = {"access": "access", "display_name": "display-name", "user": "user"} + _toPy = {"access": "access", "display-name": "display_name", "user": "user"} + def __init__(self, access=None, display_name=None, user=None, **unknown_fields): - ''' + """ access : str display_name : str user : str - ''' + """ access_ = access display_name_ = display_name user_ = user # Validate arguments against known Juju API types. if access_ is not None and not isinstance(access_, (bytes, str)): - raise Exception("Expected access_ to be a str, received: {}".format(type(access_))) + raise Exception( + "Expected access_ to be a str, received: {}".format(type(access_)) + ) if display_name_ is not None and not isinstance(display_name_, (bytes, str)): - raise Exception("Expected display_name_ to be a str, received: {}".format(type(display_name_))) + raise Exception( + "Expected display_name_ to be a str, received: {}".format( + type(display_name_) + ) + ) if user_ is not None and not isinstance(user_, (bytes, str)): - raise Exception("Expected user_ to be a str, received: {}".format(type(user_))) + raise Exception( + "Expected user_ to be a str, received: {}".format(type(user_)) + ) self.access = access_ self.display_name = display_name_ @@ -4938,59 +7984,82 @@ def __init__(self, access=None, display_name=None, user=None, **unknown_fields): self.unknown_fields = unknown_fields - class CloudsResult(Type): - _toSchema = {'clouds': 'clouds'} - _toPy = {'clouds': 'clouds'} + _toSchema = {"clouds": "clouds"} + _toPy = {"clouds": "clouds"} + def __init__(self, clouds=None, **unknown_fields): - ''' + """ clouds : typing.Mapping[str, ~Cloud] - ''' + """ clouds_ = {k: Cloud.from_json(v) for k, v in (clouds or dict()).items()} # Validate arguments against known Juju API types. if clouds_ is not None and not isinstance(clouds_, dict): - raise Exception("Expected clouds_ to be a Mapping, received: {}".format(type(clouds_))) + raise Exception( + "Expected clouds_ to be a Mapping, received: {}".format(type(clouds_)) + ) self.clouds = clouds_ self.unknown_fields = unknown_fields - class ConfigResult(Type): - _toSchema = {'config': 'config', 'error': 'error'} - _toPy = {'config': 'config', 'error': 'error'} + _toSchema = {"config": "config", "error": "error"} + _toPy = {"config": "config", "error": "error"} + def __init__(self, config=None, error=None, **unknown_fields): - ''' + """ config : typing.Mapping[str, typing.Any] error : Error - ''' + """ config_ = config error_ = Error.from_json(error) if error else None # Validate arguments against known Juju API types. if config_ is not None and not isinstance(config_, dict): - raise Exception("Expected config_ to be a Mapping, received: {}".format(type(config_))) + raise Exception( + "Expected config_ to be a Mapping, received: {}".format(type(config_)) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) self.config = config_ self.error = error_ self.unknown_fields = unknown_fields - class ConfigSet(Type): - _toSchema = {'application': 'application', 'config': 'config', 'config_yaml': 'config-yaml', 'generation': 'generation'} - _toPy = {'application': 'application', 'config': 'config', 'config-yaml': 'config_yaml', 'generation': 'generation'} - def __init__(self, application=None, config=None, config_yaml=None, generation=None, **unknown_fields): - ''' + _toSchema = { + "application": "application", + "config": "config", + "config_yaml": "config-yaml", + "generation": "generation", + } + _toPy = { + "application": "application", + "config": "config", + "config-yaml": "config_yaml", + "generation": "generation", + } + + def __init__( + self, + application=None, + config=None, + config_yaml=None, + generation=None, + **unknown_fields, + ): + """ application : str config : typing.Mapping[str, str] config_yaml : str generation : str - ''' + """ application_ = application config_ = config config_yaml_ = config_yaml @@ -4998,16 +8067,30 @@ def __init__(self, application=None, config=None, config_yaml=None, generation=N # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): - raise Exception("Expected application_ to be a str, received: {}".format(type(application_))) + raise Exception( + "Expected application_ to be a str, received: {}".format( + type(application_) + ) + ) if config_ is not None and not isinstance(config_, dict): - raise Exception("Expected config_ to be a Mapping, received: {}".format(type(config_))) + raise Exception( + "Expected config_ to be a Mapping, received: {}".format(type(config_)) + ) if config_yaml_ is not None and not isinstance(config_yaml_, (bytes, str)): - raise Exception("Expected config_yaml_ to be a str, received: {}".format(type(config_yaml_))) + raise Exception( + "Expected config_yaml_ to be a str, received: {}".format( + type(config_yaml_) + ) + ) if generation_ is not None and not isinstance(generation_, (bytes, str)): - raise Exception("Expected generation_ to be a str, received: {}".format(type(generation_))) + raise Exception( + "Expected generation_ to be a str, received: {}".format( + type(generation_) + ) + ) self.application = application_ self.config = config_ @@ -5016,68 +8099,78 @@ def __init__(self, application=None, config=None, config_yaml=None, generation=N self.unknown_fields = unknown_fields - class ConfigSetArgs(Type): - _toSchema = {'args': 'Args'} - _toPy = {'Args': 'args'} + _toSchema = {"args": "Args"} + _toPy = {"Args": "args"} + def __init__(self, args=None, **unknown_fields): - ''' + """ args : typing.Sequence[~ConfigSet] - ''' + """ args_ = [ConfigSet.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception("Expected args_ to be a Sequence, received: {}".format(type(args_))) + raise Exception( + "Expected args_ to be a Sequence, received: {}".format(type(args_)) + ) self.args = args_ self.unknown_fields = unknown_fields - class ConfigValue(Type): - _toSchema = {'source': 'source', 'value': 'value'} - _toPy = {'source': 'source', 'value': 'value'} + _toSchema = {"source": "source", "value": "value"} + _toPy = {"source": "source", "value": "value"} + def __init__(self, source=None, value=None, **unknown_fields): - ''' + """ source : str value : Any - ''' + """ source_ = source value_ = value # Validate arguments against known Juju API types. if source_ is not None and not isinstance(source_, (bytes, str)): - raise Exception("Expected source_ to be a str, received: {}".format(type(source_))) + raise Exception( + "Expected source_ to be a str, received: {}".format(type(source_)) + ) self.source = source_ self.value = value_ self.unknown_fields = unknown_fields - class Constraints(Type): - _toSchema = {'count': 'Count', 'pool': 'Pool', 'size': 'Size'} - _toPy = {'Count': 'count', 'Pool': 'pool', 'Size': 'size'} + _toSchema = {"count": "Count", "pool": "Pool", "size": "Size"} + _toPy = {"Count": "count", "Pool": "pool", "Size": "size"} + def __init__(self, count=None, pool=None, size=None, **unknown_fields): - ''' + """ count : int pool : str size : int - ''' + """ count_ = count pool_ = pool size_ = size # Validate arguments against known Juju API types. if count_ is not None and not isinstance(count_, int): - raise Exception("Expected count_ to be a int, received: {}".format(type(count_))) + raise Exception( + "Expected count_ to be a int, received: {}".format(type(count_)) + ) if pool_ is not None and not isinstance(pool_, (bytes, str)): - raise Exception("Expected pool_ to be a str, received: {}".format(type(pool_))) + raise Exception( + "Expected pool_ to be a str, received: {}".format(type(pool_)) + ) if size_ is not None and not isinstance(size_, int): - raise Exception("Expected size_ to be a int, received: {}".format(type(size_))) + raise Exception( + "Expected size_ to be a int, received: {}".format(type(size_)) + ) self.count = count_ self.pool = pool_ @@ -5085,12 +8178,56 @@ def __init__(self, count=None, pool=None, size=None, **unknown_fields): self.unknown_fields = unknown_fields - class ConsumeApplicationArg(Type): - _toSchema = {'application_alias': 'application-alias', 'application_description': 'application-description', 'applicationofferdetails': 'ApplicationOfferDetails', 'bindings': 'bindings', 'endpoints': 'endpoints', 'external_controller': 'external-controller', 'macaroon': 'macaroon', 'offer_name': 'offer-name', 'offer_url': 'offer-url', 'offer_uuid': 'offer-uuid', 'source_model_tag': 'source-model-tag', 'spaces': 'spaces', 'users': 'users'} - _toPy = {'ApplicationOfferDetails': 'applicationofferdetails', 'application-alias': 'application_alias', 'application-description': 'application_description', 'bindings': 'bindings', 'endpoints': 'endpoints', 'external-controller': 'external_controller', 'macaroon': 'macaroon', 'offer-name': 'offer_name', 'offer-url': 'offer_url', 'offer-uuid': 'offer_uuid', 'source-model-tag': 'source_model_tag', 'spaces': 'spaces', 'users': 'users'} - def __init__(self, applicationofferdetails=None, application_alias=None, application_description=None, bindings=None, endpoints=None, external_controller=None, macaroon=None, offer_name=None, offer_url=None, offer_uuid=None, source_model_tag=None, spaces=None, users=None, **unknown_fields): - ''' + _toSchema = { + "application_alias": "application-alias", + "application_description": "application-description", + "applicationofferdetails": "ApplicationOfferDetails", + "bindings": "bindings", + "endpoints": "endpoints", + "external_controller": "external-controller", + "macaroon": "macaroon", + "offer_name": "offer-name", + "offer_url": "offer-url", + "offer_uuid": "offer-uuid", + "source_model_tag": "source-model-tag", + "spaces": "spaces", + "users": "users", + } + _toPy = { + "ApplicationOfferDetails": "applicationofferdetails", + "application-alias": "application_alias", + "application-description": "application_description", + "bindings": "bindings", + "endpoints": "endpoints", + "external-controller": "external_controller", + "macaroon": "macaroon", + "offer-name": "offer_name", + "offer-url": "offer_url", + "offer-uuid": "offer_uuid", + "source-model-tag": "source_model_tag", + "spaces": "spaces", + "users": "users", + } + + def __init__( + self, + applicationofferdetails=None, + application_alias=None, + application_description=None, + bindings=None, + endpoints=None, + external_controller=None, + macaroon=None, + offer_name=None, + offer_url=None, + offer_uuid=None, + source_model_tag=None, + spaces=None, + users=None, + **unknown_fields, + ): + """ applicationofferdetails : ApplicationOfferDetails application_alias : str application_description : str @@ -5104,13 +8241,21 @@ def __init__(self, applicationofferdetails=None, application_alias=None, applica source_model_tag : str spaces : typing.Sequence[~RemoteSpace] users : typing.Sequence[~OfferUserDetails] - ''' - applicationofferdetails_ = ApplicationOfferDetails.from_json(applicationofferdetails) if applicationofferdetails else None + """ + applicationofferdetails_ = ( + ApplicationOfferDetails.from_json(applicationofferdetails) + if applicationofferdetails + else None + ) application_alias_ = application_alias application_description_ = application_description bindings_ = bindings endpoints_ = [RemoteEndpoint.from_json(o) for o in endpoints or []] - external_controller_ = ExternalControllerInfo.from_json(external_controller) if external_controller else None + external_controller_ = ( + ExternalControllerInfo.from_json(external_controller) + if external_controller + else None + ) macaroon_ = Macaroon.from_json(macaroon) if macaroon else None offer_name_ = offer_name offer_url_ = offer_url @@ -5120,44 +8265,100 @@ def __init__(self, applicationofferdetails=None, application_alias=None, applica users_ = [OfferUserDetails.from_json(o) for o in users or []] # Validate arguments against known Juju API types. - if applicationofferdetails_ is not None and not isinstance(applicationofferdetails_, (dict, ApplicationOfferDetails)): - raise Exception("Expected applicationofferdetails_ to be a ApplicationOfferDetails, received: {}".format(type(applicationofferdetails_))) - - if application_alias_ is not None and not isinstance(application_alias_, (bytes, str)): - raise Exception("Expected application_alias_ to be a str, received: {}".format(type(application_alias_))) - - if application_description_ is not None and not isinstance(application_description_, (bytes, str)): - raise Exception("Expected application_description_ to be a str, received: {}".format(type(application_description_))) + if applicationofferdetails_ is not None and not isinstance( + applicationofferdetails_, (dict, ApplicationOfferDetails) + ): + raise Exception( + "Expected applicationofferdetails_ to be a ApplicationOfferDetails, received: {}".format( + type(applicationofferdetails_) + ) + ) + + if application_alias_ is not None and not isinstance( + application_alias_, (bytes, str) + ): + raise Exception( + "Expected application_alias_ to be a str, received: {}".format( + type(application_alias_) + ) + ) + + if application_description_ is not None and not isinstance( + application_description_, (bytes, str) + ): + raise Exception( + "Expected application_description_ to be a str, received: {}".format( + type(application_description_) + ) + ) if bindings_ is not None and not isinstance(bindings_, dict): - raise Exception("Expected bindings_ to be a Mapping, received: {}".format(type(bindings_))) + raise Exception( + "Expected bindings_ to be a Mapping, received: {}".format( + type(bindings_) + ) + ) if endpoints_ is not None and not isinstance(endpoints_, (bytes, str, list)): - raise Exception("Expected endpoints_ to be a Sequence, received: {}".format(type(endpoints_))) - - if external_controller_ is not None and not isinstance(external_controller_, (dict, ExternalControllerInfo)): - raise Exception("Expected external_controller_ to be a ExternalControllerInfo, received: {}".format(type(external_controller_))) + raise Exception( + "Expected endpoints_ to be a Sequence, received: {}".format( + type(endpoints_) + ) + ) + + if external_controller_ is not None and not isinstance( + external_controller_, (dict, ExternalControllerInfo) + ): + raise Exception( + "Expected external_controller_ to be a ExternalControllerInfo, received: {}".format( + type(external_controller_) + ) + ) if macaroon_ is not None and not isinstance(macaroon_, (dict, Macaroon)): - raise Exception("Expected macaroon_ to be a Macaroon, received: {}".format(type(macaroon_))) + raise Exception( + "Expected macaroon_ to be a Macaroon, received: {}".format( + type(macaroon_) + ) + ) if offer_name_ is not None and not isinstance(offer_name_, (bytes, str)): - raise Exception("Expected offer_name_ to be a str, received: {}".format(type(offer_name_))) + raise Exception( + "Expected offer_name_ to be a str, received: {}".format( + type(offer_name_) + ) + ) if offer_url_ is not None and not isinstance(offer_url_, (bytes, str)): - raise Exception("Expected offer_url_ to be a str, received: {}".format(type(offer_url_))) + raise Exception( + "Expected offer_url_ to be a str, received: {}".format(type(offer_url_)) + ) if offer_uuid_ is not None and not isinstance(offer_uuid_, (bytes, str)): - raise Exception("Expected offer_uuid_ to be a str, received: {}".format(type(offer_uuid_))) - - if source_model_tag_ is not None and not isinstance(source_model_tag_, (bytes, str)): - raise Exception("Expected source_model_tag_ to be a str, received: {}".format(type(source_model_tag_))) + raise Exception( + "Expected offer_uuid_ to be a str, received: {}".format( + type(offer_uuid_) + ) + ) + + if source_model_tag_ is not None and not isinstance( + source_model_tag_, (bytes, str) + ): + raise Exception( + "Expected source_model_tag_ to be a str, received: {}".format( + type(source_model_tag_) + ) + ) if spaces_ is not None and not isinstance(spaces_, (bytes, str, list)): - raise Exception("Expected spaces_ to be a Sequence, received: {}".format(type(spaces_))) + raise Exception( + "Expected spaces_ to be a Sequence, received: {}".format(type(spaces_)) + ) if users_ is not None and not isinstance(users_, (bytes, str, list)): - raise Exception("Expected users_ to be a Sequence, received: {}".format(type(users_))) + raise Exception( + "Expected users_ to be a Sequence, received: {}".format(type(users_)) + ) self.applicationofferdetails = applicationofferdetails_ self.application_alias = application_alias_ @@ -5175,12 +8376,50 @@ def __init__(self, applicationofferdetails=None, application_alias=None, applica self.unknown_fields = unknown_fields - class ConsumeApplicationArgV5(Type): - _toSchema = {'application_alias': 'application-alias', 'application_description': 'application-description', 'applicationofferdetailsv5': 'ApplicationOfferDetailsV5', 'endpoints': 'endpoints', 'external_controller': 'external-controller', 'macaroon': 'macaroon', 'offer_name': 'offer-name', 'offer_url': 'offer-url', 'offer_uuid': 'offer-uuid', 'source_model_tag': 'source-model-tag', 'users': 'users'} - _toPy = {'ApplicationOfferDetailsV5': 'applicationofferdetailsv5', 'application-alias': 'application_alias', 'application-description': 'application_description', 'endpoints': 'endpoints', 'external-controller': 'external_controller', 'macaroon': 'macaroon', 'offer-name': 'offer_name', 'offer-url': 'offer_url', 'offer-uuid': 'offer_uuid', 'source-model-tag': 'source_model_tag', 'users': 'users'} - def __init__(self, applicationofferdetailsv5=None, application_alias=None, application_description=None, endpoints=None, external_controller=None, macaroon=None, offer_name=None, offer_url=None, offer_uuid=None, source_model_tag=None, users=None, **unknown_fields): - ''' + _toSchema = { + "application_alias": "application-alias", + "application_description": "application-description", + "applicationofferdetailsv5": "ApplicationOfferDetailsV5", + "endpoints": "endpoints", + "external_controller": "external-controller", + "macaroon": "macaroon", + "offer_name": "offer-name", + "offer_url": "offer-url", + "offer_uuid": "offer-uuid", + "source_model_tag": "source-model-tag", + "users": "users", + } + _toPy = { + "ApplicationOfferDetailsV5": "applicationofferdetailsv5", + "application-alias": "application_alias", + "application-description": "application_description", + "endpoints": "endpoints", + "external-controller": "external_controller", + "macaroon": "macaroon", + "offer-name": "offer_name", + "offer-url": "offer_url", + "offer-uuid": "offer_uuid", + "source-model-tag": "source_model_tag", + "users": "users", + } + + def __init__( + self, + applicationofferdetailsv5=None, + application_alias=None, + application_description=None, + endpoints=None, + external_controller=None, + macaroon=None, + offer_name=None, + offer_url=None, + offer_uuid=None, + source_model_tag=None, + users=None, + **unknown_fields, + ): + """ applicationofferdetailsv5 : ApplicationOfferDetailsV5 application_alias : str application_description : str @@ -5192,12 +8431,20 @@ def __init__(self, applicationofferdetailsv5=None, application_alias=None, appli offer_uuid : str source_model_tag : str users : typing.Sequence[~OfferUserDetails] - ''' - applicationofferdetailsv5_ = ApplicationOfferDetailsV5.from_json(applicationofferdetailsv5) if applicationofferdetailsv5 else None + """ + applicationofferdetailsv5_ = ( + ApplicationOfferDetailsV5.from_json(applicationofferdetailsv5) + if applicationofferdetailsv5 + else None + ) application_alias_ = application_alias application_description_ = application_description endpoints_ = [RemoteEndpoint.from_json(o) for o in endpoints or []] - external_controller_ = ExternalControllerInfo.from_json(external_controller) if external_controller else None + external_controller_ = ( + ExternalControllerInfo.from_json(external_controller) + if external_controller + else None + ) macaroon_ = Macaroon.from_json(macaroon) if macaroon else None offer_name_ = offer_name offer_url_ = offer_url @@ -5206,38 +8453,88 @@ def __init__(self, applicationofferdetailsv5=None, application_alias=None, appli users_ = [OfferUserDetails.from_json(o) for o in users or []] # Validate arguments against known Juju API types. - if applicationofferdetailsv5_ is not None and not isinstance(applicationofferdetailsv5_, (dict, ApplicationOfferDetailsV5)): - raise Exception("Expected applicationofferdetailsv5_ to be a ApplicationOfferDetailsV5, received: {}".format(type(applicationofferdetailsv5_))) - - if application_alias_ is not None and not isinstance(application_alias_, (bytes, str)): - raise Exception("Expected application_alias_ to be a str, received: {}".format(type(application_alias_))) - - if application_description_ is not None and not isinstance(application_description_, (bytes, str)): - raise Exception("Expected application_description_ to be a str, received: {}".format(type(application_description_))) + if applicationofferdetailsv5_ is not None and not isinstance( + applicationofferdetailsv5_, (dict, ApplicationOfferDetailsV5) + ): + raise Exception( + "Expected applicationofferdetailsv5_ to be a ApplicationOfferDetailsV5, received: {}".format( + type(applicationofferdetailsv5_) + ) + ) + + if application_alias_ is not None and not isinstance( + application_alias_, (bytes, str) + ): + raise Exception( + "Expected application_alias_ to be a str, received: {}".format( + type(application_alias_) + ) + ) + + if application_description_ is not None and not isinstance( + application_description_, (bytes, str) + ): + raise Exception( + "Expected application_description_ to be a str, received: {}".format( + type(application_description_) + ) + ) if endpoints_ is not None and not isinstance(endpoints_, (bytes, str, list)): - raise Exception("Expected endpoints_ to be a Sequence, received: {}".format(type(endpoints_))) - - if external_controller_ is not None and not isinstance(external_controller_, (dict, ExternalControllerInfo)): - raise Exception("Expected external_controller_ to be a ExternalControllerInfo, received: {}".format(type(external_controller_))) + raise Exception( + "Expected endpoints_ to be a Sequence, received: {}".format( + type(endpoints_) + ) + ) + + if external_controller_ is not None and not isinstance( + external_controller_, (dict, ExternalControllerInfo) + ): + raise Exception( + "Expected external_controller_ to be a ExternalControllerInfo, received: {}".format( + type(external_controller_) + ) + ) if macaroon_ is not None and not isinstance(macaroon_, (dict, Macaroon)): - raise Exception("Expected macaroon_ to be a Macaroon, received: {}".format(type(macaroon_))) + raise Exception( + "Expected macaroon_ to be a Macaroon, received: {}".format( + type(macaroon_) + ) + ) if offer_name_ is not None and not isinstance(offer_name_, (bytes, str)): - raise Exception("Expected offer_name_ to be a str, received: {}".format(type(offer_name_))) + raise Exception( + "Expected offer_name_ to be a str, received: {}".format( + type(offer_name_) + ) + ) if offer_url_ is not None and not isinstance(offer_url_, (bytes, str)): - raise Exception("Expected offer_url_ to be a str, received: {}".format(type(offer_url_))) + raise Exception( + "Expected offer_url_ to be a str, received: {}".format(type(offer_url_)) + ) if offer_uuid_ is not None and not isinstance(offer_uuid_, (bytes, str)): - raise Exception("Expected offer_uuid_ to be a str, received: {}".format(type(offer_uuid_))) - - if source_model_tag_ is not None and not isinstance(source_model_tag_, (bytes, str)): - raise Exception("Expected source_model_tag_ to be a str, received: {}".format(type(source_model_tag_))) + raise Exception( + "Expected offer_uuid_ to be a str, received: {}".format( + type(offer_uuid_) + ) + ) + + if source_model_tag_ is not None and not isinstance( + source_model_tag_, (bytes, str) + ): + raise Exception( + "Expected source_model_tag_ to be a str, received: {}".format( + type(source_model_tag_) + ) + ) if users_ is not None and not isinstance(users_, (bytes, str, list)): - raise Exception("Expected users_ to be a Sequence, received: {}".format(type(users_))) + raise Exception( + "Expected users_ to be a Sequence, received: {}".format(type(users_)) + ) self.applicationofferdetailsv5 = applicationofferdetailsv5_ self.application_alias = application_alias_ @@ -5253,65 +8550,99 @@ def __init__(self, applicationofferdetailsv5=None, application_alias=None, appli self.unknown_fields = unknown_fields - class ConsumeApplicationArgs(Type): - _toSchema = {'args': 'args'} - _toPy = {'args': 'args'} + _toSchema = {"args": "args"} + _toPy = {"args": "args"} + def __init__(self, args=None, **unknown_fields): - ''' + """ args : typing.Sequence[~ConsumeApplicationArg] - ''' + """ args_ = [ConsumeApplicationArg.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception("Expected args_ to be a Sequence, received: {}".format(type(args_))) + raise Exception( + "Expected args_ to be a Sequence, received: {}".format(type(args_)) + ) self.args = args_ self.unknown_fields = unknown_fields - class ConsumeApplicationArgsV5(Type): - _toSchema = {'args': 'args'} - _toPy = {'args': 'args'} + _toSchema = {"args": "args"} + _toPy = {"args": "args"} + def __init__(self, args=None, **unknown_fields): - ''' + """ args : typing.Sequence[~ConsumeApplicationArgV5] - ''' + """ args_ = [ConsumeApplicationArgV5.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception("Expected args_ to be a Sequence, received: {}".format(type(args_))) + raise Exception( + "Expected args_ to be a Sequence, received: {}".format(type(args_)) + ) self.args = args_ self.unknown_fields = unknown_fields - class ConsumeOfferDetails(Type): - _toSchema = {'external_controller': 'external-controller', 'macaroon': 'macaroon', 'offer': 'offer'} - _toPy = {'external-controller': 'external_controller', 'macaroon': 'macaroon', 'offer': 'offer'} - def __init__(self, external_controller=None, macaroon=None, offer=None, **unknown_fields): - ''' + _toSchema = { + "external_controller": "external-controller", + "macaroon": "macaroon", + "offer": "offer", + } + _toPy = { + "external-controller": "external_controller", + "macaroon": "macaroon", + "offer": "offer", + } + + def __init__( + self, external_controller=None, macaroon=None, offer=None, **unknown_fields + ): + """ external_controller : ExternalControllerInfo macaroon : Macaroon offer : ApplicationOfferDetailsV5 - ''' - external_controller_ = ExternalControllerInfo.from_json(external_controller) if external_controller else None + """ + external_controller_ = ( + ExternalControllerInfo.from_json(external_controller) + if external_controller + else None + ) macaroon_ = Macaroon.from_json(macaroon) if macaroon else None offer_ = ApplicationOfferDetailsV5.from_json(offer) if offer else None # Validate arguments against known Juju API types. - if external_controller_ is not None and not isinstance(external_controller_, (dict, ExternalControllerInfo)): - raise Exception("Expected external_controller_ to be a ExternalControllerInfo, received: {}".format(type(external_controller_))) + if external_controller_ is not None and not isinstance( + external_controller_, (dict, ExternalControllerInfo) + ): + raise Exception( + "Expected external_controller_ to be a ExternalControllerInfo, received: {}".format( + type(external_controller_) + ) + ) if macaroon_ is not None and not isinstance(macaroon_, (dict, Macaroon)): - raise Exception("Expected macaroon_ to be a Macaroon, received: {}".format(type(macaroon_))) - - if offer_ is not None and not isinstance(offer_, (dict, ApplicationOfferDetailsV5)): - raise Exception("Expected offer_ to be a ApplicationOfferDetailsV5, received: {}".format(type(offer_))) + raise Exception( + "Expected macaroon_ to be a Macaroon, received: {}".format( + type(macaroon_) + ) + ) + + if offer_ is not None and not isinstance( + offer_, (dict, ApplicationOfferDetailsV5) + ): + raise Exception( + "Expected offer_ to be a ApplicationOfferDetailsV5, received: {}".format( + type(offer_) + ) + ) self.external_controller = external_controller_ self.macaroon = macaroon_ @@ -5319,63 +8650,121 @@ def __init__(self, external_controller=None, macaroon=None, offer=None, **unknow self.unknown_fields = unknown_fields - class ConsumeOfferDetailsArg(Type): - _toSchema = {'offer_urls': 'offer-urls', 'user_tag': 'user-tag'} - _toPy = {'offer-urls': 'offer_urls', 'user-tag': 'user_tag'} + _toSchema = {"offer_urls": "offer-urls", "user_tag": "user-tag"} + _toPy = {"offer-urls": "offer_urls", "user-tag": "user_tag"} + def __init__(self, offer_urls=None, user_tag=None, **unknown_fields): - ''' + """ offer_urls : OfferURLs user_tag : str - ''' + """ offer_urls_ = OfferURLs.from_json(offer_urls) if offer_urls else None user_tag_ = user_tag # Validate arguments against known Juju API types. if offer_urls_ is not None and not isinstance(offer_urls_, (dict, OfferURLs)): - raise Exception("Expected offer_urls_ to be a OfferURLs, received: {}".format(type(offer_urls_))) + raise Exception( + "Expected offer_urls_ to be a OfferURLs, received: {}".format( + type(offer_urls_) + ) + ) if user_tag_ is not None and not isinstance(user_tag_, (bytes, str)): - raise Exception("Expected user_tag_ to be a str, received: {}".format(type(user_tag_))) + raise Exception( + "Expected user_tag_ to be a str, received: {}".format(type(user_tag_)) + ) self.offer_urls = offer_urls_ self.user_tag = user_tag_ self.unknown_fields = unknown_fields - class ConsumeOfferDetailsResult(Type): - _toSchema = {'consumeofferdetails': 'ConsumeOfferDetails', 'error': 'error', 'external_controller': 'external-controller', 'macaroon': 'macaroon', 'offer': 'offer'} - _toPy = {'ConsumeOfferDetails': 'consumeofferdetails', 'error': 'error', 'external-controller': 'external_controller', 'macaroon': 'macaroon', 'offer': 'offer'} - def __init__(self, consumeofferdetails=None, error=None, external_controller=None, macaroon=None, offer=None, **unknown_fields): - ''' + _toSchema = { + "consumeofferdetails": "ConsumeOfferDetails", + "error": "error", + "external_controller": "external-controller", + "macaroon": "macaroon", + "offer": "offer", + } + _toPy = { + "ConsumeOfferDetails": "consumeofferdetails", + "error": "error", + "external-controller": "external_controller", + "macaroon": "macaroon", + "offer": "offer", + } + + def __init__( + self, + consumeofferdetails=None, + error=None, + external_controller=None, + macaroon=None, + offer=None, + **unknown_fields, + ): + """ consumeofferdetails : ConsumeOfferDetails error : Error external_controller : ExternalControllerInfo macaroon : Macaroon offer : ApplicationOfferDetailsV5 - ''' - consumeofferdetails_ = ConsumeOfferDetails.from_json(consumeofferdetails) if consumeofferdetails else None + """ + consumeofferdetails_ = ( + ConsumeOfferDetails.from_json(consumeofferdetails) + if consumeofferdetails + else None + ) error_ = Error.from_json(error) if error else None - external_controller_ = ExternalControllerInfo.from_json(external_controller) if external_controller else None + external_controller_ = ( + ExternalControllerInfo.from_json(external_controller) + if external_controller + else None + ) macaroon_ = Macaroon.from_json(macaroon) if macaroon else None offer_ = ApplicationOfferDetailsV5.from_json(offer) if offer else None # Validate arguments against known Juju API types. - if consumeofferdetails_ is not None and not isinstance(consumeofferdetails_, (dict, ConsumeOfferDetails)): - raise Exception("Expected consumeofferdetails_ to be a ConsumeOfferDetails, received: {}".format(type(consumeofferdetails_))) + if consumeofferdetails_ is not None and not isinstance( + consumeofferdetails_, (dict, ConsumeOfferDetails) + ): + raise Exception( + "Expected consumeofferdetails_ to be a ConsumeOfferDetails, received: {}".format( + type(consumeofferdetails_) + ) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) - - if external_controller_ is not None and not isinstance(external_controller_, (dict, ExternalControllerInfo)): - raise Exception("Expected external_controller_ to be a ExternalControllerInfo, received: {}".format(type(external_controller_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) + + if external_controller_ is not None and not isinstance( + external_controller_, (dict, ExternalControllerInfo) + ): + raise Exception( + "Expected external_controller_ to be a ExternalControllerInfo, received: {}".format( + type(external_controller_) + ) + ) if macaroon_ is not None and not isinstance(macaroon_, (dict, Macaroon)): - raise Exception("Expected macaroon_ to be a Macaroon, received: {}".format(type(macaroon_))) - - if offer_ is not None and not isinstance(offer_, (dict, ApplicationOfferDetailsV5)): - raise Exception("Expected offer_ to be a ApplicationOfferDetailsV5, received: {}".format(type(offer_))) + raise Exception( + "Expected macaroon_ to be a Macaroon, received: {}".format( + type(macaroon_) + ) + ) + + if offer_ is not None and not isinstance( + offer_, (dict, ApplicationOfferDetailsV5) + ): + raise Exception( + "Expected offer_ to be a ApplicationOfferDetailsV5, received: {}".format( + type(offer_) + ) + ) self.consumeofferdetails = consumeofferdetails_ self.error = error_ @@ -5385,47 +8774,59 @@ def __init__(self, consumeofferdetails=None, error=None, external_controller=Non self.unknown_fields = unknown_fields - class ConsumeOfferDetailsResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~ConsumeOfferDetailsResult] - ''' + """ results_ = [ConsumeOfferDetailsResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class ControllerAPIInfoResult(Type): - _toSchema = {'addresses': 'addresses', 'cacert': 'cacert', 'error': 'error'} - _toPy = {'addresses': 'addresses', 'cacert': 'cacert', 'error': 'error'} + _toSchema = {"addresses": "addresses", "cacert": "cacert", "error": "error"} + _toPy = {"addresses": "addresses", "cacert": "cacert", "error": "error"} + def __init__(self, addresses=None, cacert=None, error=None, **unknown_fields): - ''' + """ addresses : typing.Sequence[str] cacert : str error : Error - ''' + """ addresses_ = addresses cacert_ = cacert error_ = Error.from_json(error) if error else None # Validate arguments against known Juju API types. if addresses_ is not None and not isinstance(addresses_, (bytes, str, list)): - raise Exception("Expected addresses_ to be a Sequence, received: {}".format(type(addresses_))) + raise Exception( + "Expected addresses_ to be a Sequence, received: {}".format( + type(addresses_) + ) + ) if cacert_ is not None and not isinstance(cacert_, (bytes, str)): - raise Exception("Expected cacert_ to be a str, received: {}".format(type(cacert_))) + raise Exception( + "Expected cacert_ to be a str, received: {}".format(type(cacert_)) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) self.addresses = addresses_ self.cacert = cacert_ @@ -5433,161 +8834,208 @@ def __init__(self, addresses=None, cacert=None, error=None, **unknown_fields): self.unknown_fields = unknown_fields - class ControllerAPIInfoResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~ControllerAPIInfoResult] - ''' + """ results_ = [ControllerAPIInfoResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class ControllerConfigResult(Type): - _toSchema = {'config': 'config'} - _toPy = {'config': 'config'} + _toSchema = {"config": "config"} + _toPy = {"config": "config"} + def __init__(self, config=None, **unknown_fields): - ''' + """ config : typing.Mapping[str, typing.Any] - ''' + """ config_ = config # Validate arguments against known Juju API types. if config_ is not None and not isinstance(config_, dict): - raise Exception("Expected config_ to be a Mapping, received: {}".format(type(config_))) + raise Exception( + "Expected config_ to be a Mapping, received: {}".format(type(config_)) + ) self.config = config_ self.unknown_fields = unknown_fields - class ControllerConfigSet(Type): - _toSchema = {'config': 'config'} - _toPy = {'config': 'config'} + _toSchema = {"config": "config"} + _toPy = {"config": "config"} + def __init__(self, config=None, **unknown_fields): - ''' + """ config : typing.Mapping[str, typing.Any] - ''' + """ config_ = config # Validate arguments against known Juju API types. if config_ is not None and not isinstance(config_, dict): - raise Exception("Expected config_ to be a Mapping, received: {}".format(type(config_))) + raise Exception( + "Expected config_ to be a Mapping, received: {}".format(type(config_)) + ) self.config = config_ self.unknown_fields = unknown_fields - class ControllerCredentialInfo(Type): - _toSchema = {'content': 'content', 'models': 'models'} - _toPy = {'content': 'content', 'models': 'models'} + _toSchema = {"content": "content", "models": "models"} + _toPy = {"content": "content", "models": "models"} + def __init__(self, content=None, models=None, **unknown_fields): - ''' + """ content : CredentialContent models : typing.Sequence[~ModelAccess] - ''' + """ content_ = CredentialContent.from_json(content) if content else None models_ = [ModelAccess.from_json(o) for o in models or []] # Validate arguments against known Juju API types. if content_ is not None and not isinstance(content_, (dict, CredentialContent)): - raise Exception("Expected content_ to be a CredentialContent, received: {}".format(type(content_))) + raise Exception( + "Expected content_ to be a CredentialContent, received: {}".format( + type(content_) + ) + ) if models_ is not None and not isinstance(models_, (bytes, str, list)): - raise Exception("Expected models_ to be a Sequence, received: {}".format(type(models_))) + raise Exception( + "Expected models_ to be a Sequence, received: {}".format(type(models_)) + ) self.content = content_ self.models = models_ self.unknown_fields = unknown_fields - class ControllerVersionResults(Type): - _toSchema = {'git_commit': 'git-commit', 'version': 'version'} - _toPy = {'git-commit': 'git_commit', 'version': 'version'} + _toSchema = {"git_commit": "git-commit", "version": "version"} + _toPy = {"git-commit": "git_commit", "version": "version"} + def __init__(self, git_commit=None, version=None, **unknown_fields): - ''' + """ git_commit : str version : str - ''' + """ git_commit_ = git_commit version_ = version # Validate arguments against known Juju API types. if git_commit_ is not None and not isinstance(git_commit_, (bytes, str)): - raise Exception("Expected git_commit_ to be a str, received: {}".format(type(git_commit_))) + raise Exception( + "Expected git_commit_ to be a str, received: {}".format( + type(git_commit_) + ) + ) if version_ is not None and not isinstance(version_, (bytes, str)): - raise Exception("Expected version_ to be a str, received: {}".format(type(version_))) + raise Exception( + "Expected version_ to be a str, received: {}".format(type(version_)) + ) self.git_commit = git_commit_ self.version = version_ self.unknown_fields = unknown_fields - class ControllersChangeResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : ControllersChanges - ''' + """ error_ = Error.from_json(error) if error else None result_ = ControllersChanges.from_json(result) if result else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if result_ is not None and not isinstance(result_, (dict, ControllersChanges)): - raise Exception("Expected result_ to be a ControllersChanges, received: {}".format(type(result_))) + raise Exception( + "Expected result_ to be a ControllersChanges, received: {}".format( + type(result_) + ) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class ControllersChangeResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~ControllersChangeResult] - ''' + """ results_ = [ControllersChangeResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class ControllersChanges(Type): - _toSchema = {'added': 'added', 'converted': 'converted', 'maintained': 'maintained', 'removed': 'removed'} - _toPy = {'added': 'added', 'converted': 'converted', 'maintained': 'maintained', 'removed': 'removed'} - def __init__(self, added=None, converted=None, maintained=None, removed=None, **unknown_fields): - ''' + _toSchema = { + "added": "added", + "converted": "converted", + "maintained": "maintained", + "removed": "removed", + } + _toPy = { + "added": "added", + "converted": "converted", + "maintained": "maintained", + "removed": "removed", + } + + def __init__( + self, + added=None, + converted=None, + maintained=None, + removed=None, + **unknown_fields, + ): + """ added : typing.Sequence[str] converted : typing.Sequence[str] maintained : typing.Sequence[str] removed : typing.Sequence[str] - ''' + """ added_ = added converted_ = converted maintained_ = maintained @@ -5595,16 +9043,30 @@ def __init__(self, added=None, converted=None, maintained=None, removed=None, ** # Validate arguments against known Juju API types. if added_ is not None and not isinstance(added_, (bytes, str, list)): - raise Exception("Expected added_ to be a Sequence, received: {}".format(type(added_))) + raise Exception( + "Expected added_ to be a Sequence, received: {}".format(type(added_)) + ) if converted_ is not None and not isinstance(converted_, (bytes, str, list)): - raise Exception("Expected converted_ to be a Sequence, received: {}".format(type(converted_))) + raise Exception( + "Expected converted_ to be a Sequence, received: {}".format( + type(converted_) + ) + ) if maintained_ is not None and not isinstance(maintained_, (bytes, str, list)): - raise Exception("Expected maintained_ to be a Sequence, received: {}".format(type(maintained_))) + raise Exception( + "Expected maintained_ to be a Sequence, received: {}".format( + type(maintained_) + ) + ) if removed_ is not None and not isinstance(removed_, (bytes, str, list)): - raise Exception("Expected removed_ to be a Sequence, received: {}".format(type(removed_))) + raise Exception( + "Expected removed_ to be a Sequence, received: {}".format( + type(removed_) + ) + ) self.added = added_ self.converted = converted_ @@ -5613,29 +9075,51 @@ def __init__(self, added=None, converted=None, maintained=None, removed=None, ** self.unknown_fields = unknown_fields - class ControllersSpec(Type): - _toSchema = {'constraints': 'constraints', 'num_controllers': 'num-controllers', 'placement': 'placement'} - _toPy = {'constraints': 'constraints', 'num-controllers': 'num_controllers', 'placement': 'placement'} - def __init__(self, constraints=None, num_controllers=None, placement=None, **unknown_fields): - ''' + _toSchema = { + "constraints": "constraints", + "num_controllers": "num-controllers", + "placement": "placement", + } + _toPy = { + "constraints": "constraints", + "num-controllers": "num_controllers", + "placement": "placement", + } + + def __init__( + self, constraints=None, num_controllers=None, placement=None, **unknown_fields + ): + """ constraints : Value num_controllers : int placement : typing.Sequence[str] - ''' + """ constraints_ = Value.from_json(constraints) if constraints else None num_controllers_ = num_controllers placement_ = placement # Validate arguments against known Juju API types. if constraints_ is not None and not isinstance(constraints_, (dict, Value)): - raise Exception("Expected constraints_ to be a Value, received: {}".format(type(constraints_))) + raise Exception( + "Expected constraints_ to be a Value, received: {}".format( + type(constraints_) + ) + ) if num_controllers_ is not None and not isinstance(num_controllers_, int): - raise Exception("Expected num_controllers_ to be a int, received: {}".format(type(num_controllers_))) + raise Exception( + "Expected num_controllers_ to be a int, received: {}".format( + type(num_controllers_) + ) + ) if placement_ is not None and not isinstance(placement_, (bytes, str, list)): - raise Exception("Expected placement_ to be a Sequence, received: {}".format(type(placement_))) + raise Exception( + "Expected placement_ to be a Sequence, received: {}".format( + type(placement_) + ) + ) self.constraints = constraints_ self.num_controllers = num_controllers_ @@ -5643,30 +9127,64 @@ def __init__(self, constraints=None, num_controllers=None, placement=None, **unk self.unknown_fields = unknown_fields - class ControllersSpecs(Type): - _toSchema = {'specs': 'specs'} - _toPy = {'specs': 'specs'} + _toSchema = {"specs": "specs"} + _toPy = {"specs": "specs"} + def __init__(self, specs=None, **unknown_fields): - ''' + """ specs : typing.Sequence[~ControllersSpec] - ''' + """ specs_ = [ControllersSpec.from_json(o) for o in specs or []] # Validate arguments against known Juju API types. if specs_ is not None and not isinstance(specs_, (bytes, str, list)): - raise Exception("Expected specs_ to be a Sequence, received: {}".format(type(specs_))) + raise Exception( + "Expected specs_ to be a Sequence, received: {}".format(type(specs_)) + ) self.specs = specs_ self.unknown_fields = unknown_fields - class CreateSecretArg(Type): - _toSchema = {'content': 'content', 'description': 'description', 'expire_time': 'expire-time', 'label': 'label', 'owner_tag': 'owner-tag', 'params': 'params', 'rotate_policy': 'rotate-policy', 'upsertsecretarg': 'UpsertSecretArg', 'uri': 'uri'} - _toPy = {'UpsertSecretArg': 'upsertsecretarg', 'content': 'content', 'description': 'description', 'expire-time': 'expire_time', 'label': 'label', 'owner-tag': 'owner_tag', 'params': 'params', 'rotate-policy': 'rotate_policy', 'uri': 'uri'} - def __init__(self, upsertsecretarg=None, content=None, description=None, expire_time=None, label=None, owner_tag=None, params=None, rotate_policy=None, uri=None, **unknown_fields): - ''' + _toSchema = { + "content": "content", + "description": "description", + "expire_time": "expire-time", + "label": "label", + "owner_tag": "owner-tag", + "params": "params", + "rotate_policy": "rotate-policy", + "upsertsecretarg": "UpsertSecretArg", + "uri": "uri", + } + _toPy = { + "UpsertSecretArg": "upsertsecretarg", + "content": "content", + "description": "description", + "expire-time": "expire_time", + "label": "label", + "owner-tag": "owner_tag", + "params": "params", + "rotate-policy": "rotate_policy", + "uri": "uri", + } + + def __init__( + self, + upsertsecretarg=None, + content=None, + description=None, + expire_time=None, + label=None, + owner_tag=None, + params=None, + rotate_policy=None, + uri=None, + **unknown_fields, + ): + """ upsertsecretarg : UpsertSecretArg content : SecretContentParams description : str @@ -5676,8 +9194,10 @@ def __init__(self, upsertsecretarg=None, content=None, description=None, expire_ params : typing.Mapping[str, typing.Any] rotate_policy : str uri : str - ''' - upsertsecretarg_ = UpsertSecretArg.from_json(upsertsecretarg) if upsertsecretarg else None + """ + upsertsecretarg_ = ( + UpsertSecretArg.from_json(upsertsecretarg) if upsertsecretarg else None + ) content_ = SecretContentParams.from_json(content) if content else None description_ = description expire_time_ = expire_time @@ -5688,32 +9208,64 @@ def __init__(self, upsertsecretarg=None, content=None, description=None, expire_ uri_ = uri # Validate arguments against known Juju API types. - if upsertsecretarg_ is not None and not isinstance(upsertsecretarg_, (dict, UpsertSecretArg)): - raise Exception("Expected upsertsecretarg_ to be a UpsertSecretArg, received: {}".format(type(upsertsecretarg_))) - - if content_ is not None and not isinstance(content_, (dict, SecretContentParams)): - raise Exception("Expected content_ to be a SecretContentParams, received: {}".format(type(content_))) + if upsertsecretarg_ is not None and not isinstance( + upsertsecretarg_, (dict, UpsertSecretArg) + ): + raise Exception( + "Expected upsertsecretarg_ to be a UpsertSecretArg, received: {}".format( + type(upsertsecretarg_) + ) + ) + + if content_ is not None and not isinstance( + content_, (dict, SecretContentParams) + ): + raise Exception( + "Expected content_ to be a SecretContentParams, received: {}".format( + type(content_) + ) + ) if description_ is not None and not isinstance(description_, (bytes, str)): - raise Exception("Expected description_ to be a str, received: {}".format(type(description_))) + raise Exception( + "Expected description_ to be a str, received: {}".format( + type(description_) + ) + ) if expire_time_ is not None and not isinstance(expire_time_, (bytes, str)): - raise Exception("Expected expire_time_ to be a str, received: {}".format(type(expire_time_))) + raise Exception( + "Expected expire_time_ to be a str, received: {}".format( + type(expire_time_) + ) + ) if label_ is not None and not isinstance(label_, (bytes, str)): - raise Exception("Expected label_ to be a str, received: {}".format(type(label_))) + raise Exception( + "Expected label_ to be a str, received: {}".format(type(label_)) + ) if owner_tag_ is not None and not isinstance(owner_tag_, (bytes, str)): - raise Exception("Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_))) + raise Exception( + "Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_)) + ) if params_ is not None and not isinstance(params_, dict): - raise Exception("Expected params_ to be a Mapping, received: {}".format(type(params_))) + raise Exception( + "Expected params_ to be a Mapping, received: {}".format(type(params_)) + ) if rotate_policy_ is not None and not isinstance(rotate_policy_, (bytes, str)): - raise Exception("Expected rotate_policy_ to be a str, received: {}".format(type(rotate_policy_))) + raise Exception( + "Expected rotate_policy_ to be a str, received: {}".format( + type(rotate_policy_) + ) + ) if uri_ is not None and not isinstance(uri_, (bytes, str)): - raise Exception("Expected uri_ to be a str, received: {}".format(type(uri_))) + raise Exception( + "Expected uri_ to be a str, received: {}".format(type(uri_)) + ) self.upsertsecretarg = upsertsecretarg_ self.content = content_ @@ -5727,35 +9279,54 @@ def __init__(self, upsertsecretarg=None, content=None, description=None, expire_ self.unknown_fields = unknown_fields - class CreateSecretArgs(Type): - _toSchema = {'args': 'args'} - _toPy = {'args': 'args'} + _toSchema = {"args": "args"} + _toPy = {"args": "args"} + def __init__(self, args=None, **unknown_fields): - ''' + """ args : typing.Sequence[~CreateSecretArg] - ''' + """ args_ = [CreateSecretArg.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception("Expected args_ to be a Sequence, received: {}".format(type(args_))) + raise Exception( + "Expected args_ to be a Sequence, received: {}".format(type(args_)) + ) self.args = args_ self.unknown_fields = unknown_fields - class CreateSpaceParams(Type): - _toSchema = {'cidrs': 'cidrs', 'provider_id': 'provider-id', 'public': 'public', 'space_tag': 'space-tag'} - _toPy = {'cidrs': 'cidrs', 'provider-id': 'provider_id', 'public': 'public', 'space-tag': 'space_tag'} - def __init__(self, cidrs=None, provider_id=None, public=None, space_tag=None, **unknown_fields): - ''' + _toSchema = { + "cidrs": "cidrs", + "provider_id": "provider-id", + "public": "public", + "space_tag": "space-tag", + } + _toPy = { + "cidrs": "cidrs", + "provider-id": "provider_id", + "public": "public", + "space-tag": "space_tag", + } + + def __init__( + self, + cidrs=None, + provider_id=None, + public=None, + space_tag=None, + **unknown_fields, + ): + """ cidrs : typing.Sequence[str] provider_id : str public : bool space_tag : str - ''' + """ cidrs_ = cidrs provider_id_ = provider_id public_ = public @@ -5763,16 +9334,26 @@ def __init__(self, cidrs=None, provider_id=None, public=None, space_tag=None, ** # Validate arguments against known Juju API types. if cidrs_ is not None and not isinstance(cidrs_, (bytes, str, list)): - raise Exception("Expected cidrs_ to be a Sequence, received: {}".format(type(cidrs_))) + raise Exception( + "Expected cidrs_ to be a Sequence, received: {}".format(type(cidrs_)) + ) if provider_id_ is not None and not isinstance(provider_id_, (bytes, str)): - raise Exception("Expected provider_id_ to be a str, received: {}".format(type(provider_id_))) + raise Exception( + "Expected provider_id_ to be a str, received: {}".format( + type(provider_id_) + ) + ) if public_ is not None and not isinstance(public_, bool): - raise Exception("Expected public_ to be a bool, received: {}".format(type(public_))) + raise Exception( + "Expected public_ to be a bool, received: {}".format(type(public_)) + ) if space_tag_ is not None and not isinstance(space_tag_, (bytes, str)): - raise Exception("Expected space_tag_ to be a str, received: {}".format(type(space_tag_))) + raise Exception( + "Expected space_tag_ to be a str, received: {}".format(type(space_tag_)) + ) self.cidrs = cidrs_ self.provider_id = provider_id_ @@ -5781,36 +9362,58 @@ def __init__(self, cidrs=None, provider_id=None, public=None, space_tag=None, ** self.unknown_fields = unknown_fields - class CreateSpacesParams(Type): - _toSchema = {'spaces': 'spaces'} - _toPy = {'spaces': 'spaces'} + _toSchema = {"spaces": "spaces"} + _toPy = {"spaces": "spaces"} + def __init__(self, spaces=None, **unknown_fields): - ''' + """ spaces : typing.Sequence[~CreateSpaceParams] - ''' + """ spaces_ = [CreateSpaceParams.from_json(o) for o in spaces or []] # Validate arguments against known Juju API types. if spaces_ is not None and not isinstance(spaces_, (bytes, str, list)): - raise Exception("Expected spaces_ to be a Sequence, received: {}".format(type(spaces_))) + raise Exception( + "Expected spaces_ to be a Sequence, received: {}".format(type(spaces_)) + ) self.spaces = spaces_ self.unknown_fields = unknown_fields - class CredentialContent(Type): - _toSchema = {'attrs': 'attrs', 'auth_type': 'auth-type', 'cloud': 'cloud', 'name': 'name', 'valid': 'valid'} - _toPy = {'attrs': 'attrs', 'auth-type': 'auth_type', 'cloud': 'cloud', 'name': 'name', 'valid': 'valid'} - def __init__(self, attrs=None, auth_type=None, cloud=None, name=None, valid=None, **unknown_fields): - ''' + _toSchema = { + "attrs": "attrs", + "auth_type": "auth-type", + "cloud": "cloud", + "name": "name", + "valid": "valid", + } + _toPy = { + "attrs": "attrs", + "auth-type": "auth_type", + "cloud": "cloud", + "name": "name", + "valid": "valid", + } + + def __init__( + self, + attrs=None, + auth_type=None, + cloud=None, + name=None, + valid=None, + **unknown_fields, + ): + """ attrs : typing.Mapping[str, str] auth_type : str cloud : str name : str valid : bool - ''' + """ attrs_ = attrs auth_type_ = auth_type cloud_ = cloud @@ -5819,19 +9422,29 @@ def __init__(self, attrs=None, auth_type=None, cloud=None, name=None, valid=None # Validate arguments against known Juju API types. if attrs_ is not None and not isinstance(attrs_, dict): - raise Exception("Expected attrs_ to be a Mapping, received: {}".format(type(attrs_))) + raise Exception( + "Expected attrs_ to be a Mapping, received: {}".format(type(attrs_)) + ) if auth_type_ is not None and not isinstance(auth_type_, (bytes, str)): - raise Exception("Expected auth_type_ to be a str, received: {}".format(type(auth_type_))) + raise Exception( + "Expected auth_type_ to be a str, received: {}".format(type(auth_type_)) + ) if cloud_ is not None and not isinstance(cloud_, (bytes, str)): - raise Exception("Expected cloud_ to be a str, received: {}".format(type(cloud_))) + raise Exception( + "Expected cloud_ to be a str, received: {}".format(type(cloud_)) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if valid_ is not None and not isinstance(valid_, bool): - raise Exception("Expected valid_ to be a bool, received: {}".format(type(valid_))) + raise Exception( + "Expected valid_ to be a bool, received: {}".format(type(valid_)) + ) self.attrs = attrs_ self.auth_type = auth_type_ @@ -5841,71 +9454,113 @@ def __init__(self, attrs=None, auth_type=None, cloud=None, name=None, valid=None self.unknown_fields = unknown_fields - class CredentialContentResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : ControllerCredentialInfo - ''' + """ error_ = Error.from_json(error) if error else None result_ = ControllerCredentialInfo.from_json(result) if result else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) - - if result_ is not None and not isinstance(result_, (dict, ControllerCredentialInfo)): - raise Exception("Expected result_ to be a ControllerCredentialInfo, received: {}".format(type(result_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) + + if result_ is not None and not isinstance( + result_, (dict, ControllerCredentialInfo) + ): + raise Exception( + "Expected result_ to be a ControllerCredentialInfo, received: {}".format( + type(result_) + ) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class CredentialContentResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~CredentialContentResult] - ''' + """ results_ = [CredentialContentResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class DashboardConnectionInfo(Type): - _toSchema = {'error': 'error', 'proxy_connection': 'proxy-connection', 'ssh_connection': 'ssh-connection'} - _toPy = {'error': 'error', 'proxy-connection': 'proxy_connection', 'ssh-connection': 'ssh_connection'} - def __init__(self, error=None, proxy_connection=None, ssh_connection=None, **unknown_fields): - ''' + _toSchema = { + "error": "error", + "proxy_connection": "proxy-connection", + "ssh_connection": "ssh-connection", + } + _toPy = { + "error": "error", + "proxy-connection": "proxy_connection", + "ssh-connection": "ssh_connection", + } + + def __init__( + self, error=None, proxy_connection=None, ssh_connection=None, **unknown_fields + ): + """ error : Error proxy_connection : Proxy ssh_connection : DashboardConnectionSSHTunnel - ''' + """ error_ = Error.from_json(error) if error else None - proxy_connection_ = Proxy.from_json(proxy_connection) if proxy_connection else None - ssh_connection_ = DashboardConnectionSSHTunnel.from_json(ssh_connection) if ssh_connection else None + proxy_connection_ = ( + Proxy.from_json(proxy_connection) if proxy_connection else None + ) + ssh_connection_ = ( + DashboardConnectionSSHTunnel.from_json(ssh_connection) + if ssh_connection + else None + ) # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) - - if proxy_connection_ is not None and not isinstance(proxy_connection_, (dict, Proxy)): - raise Exception("Expected proxy_connection_ to be a Proxy, received: {}".format(type(proxy_connection_))) - - if ssh_connection_ is not None and not isinstance(ssh_connection_, (dict, DashboardConnectionSSHTunnel)): - raise Exception("Expected ssh_connection_ to be a DashboardConnectionSSHTunnel, received: {}".format(type(ssh_connection_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) + + if proxy_connection_ is not None and not isinstance( + proxy_connection_, (dict, Proxy) + ): + raise Exception( + "Expected proxy_connection_ to be a Proxy, received: {}".format( + type(proxy_connection_) + ) + ) + + if ssh_connection_ is not None and not isinstance( + ssh_connection_, (dict, DashboardConnectionSSHTunnel) + ): + raise Exception( + "Expected ssh_connection_ to be a DashboardConnectionSSHTunnel, received: {}".format( + type(ssh_connection_) + ) + ) self.error = error_ self.proxy_connection = proxy_connection_ @@ -5913,17 +9568,17 @@ def __init__(self, error=None, proxy_connection=None, ssh_connection=None, **unk self.unknown_fields = unknown_fields - class DashboardConnectionSSHTunnel(Type): - _toSchema = {'entity': 'entity', 'host': 'host', 'model': 'model', 'port': 'port'} - _toPy = {'entity': 'entity', 'host': 'host', 'model': 'model', 'port': 'port'} + _toSchema = {"entity": "entity", "host": "host", "model": "model", "port": "port"} + _toPy = {"entity": "entity", "host": "host", "model": "model", "port": "port"} + def __init__(self, entity=None, host=None, model=None, port=None, **unknown_fields): - ''' + """ entity : str host : str model : str port : str - ''' + """ entity_ = entity host_ = host model_ = model @@ -5931,16 +9586,24 @@ def __init__(self, entity=None, host=None, model=None, port=None, **unknown_fiel # Validate arguments against known Juju API types. if entity_ is not None and not isinstance(entity_, (bytes, str)): - raise Exception("Expected entity_ to be a str, received: {}".format(type(entity_))) + raise Exception( + "Expected entity_ to be a str, received: {}".format(type(entity_)) + ) if host_ is not None and not isinstance(host_, (bytes, str)): - raise Exception("Expected host_ to be a str, received: {}".format(type(host_))) + raise Exception( + "Expected host_ to be a str, received: {}".format(type(host_)) + ) if model_ is not None and not isinstance(model_, (bytes, str)): - raise Exception("Expected model_ to be a str, received: {}".format(type(model_))) + raise Exception( + "Expected model_ to be a str, received: {}".format(type(model_)) + ) if port_ is not None and not isinstance(port_, (bytes, str)): - raise Exception("Expected port_ to be a str, received: {}".format(type(port_))) + raise Exception( + "Expected port_ to be a str, received: {}".format(type(port_)) + ) self.entity = entity_ self.host = host_ @@ -5949,29 +9612,37 @@ def __init__(self, entity=None, host=None, model=None, port=None, **unknown_fiel self.unknown_fields = unknown_fields - class DeleteSecretArg(Type): - _toSchema = {'label': 'label', 'revisions': 'revisions', 'uri': 'uri'} - _toPy = {'label': 'label', 'revisions': 'revisions', 'uri': 'uri'} + _toSchema = {"label": "label", "revisions": "revisions", "uri": "uri"} + _toPy = {"label": "label", "revisions": "revisions", "uri": "uri"} + def __init__(self, label=None, revisions=None, uri=None, **unknown_fields): - ''' + """ label : str revisions : typing.Sequence[int] uri : str - ''' + """ label_ = label revisions_ = revisions uri_ = uri # Validate arguments against known Juju API types. if label_ is not None and not isinstance(label_, (bytes, str)): - raise Exception("Expected label_ to be a str, received: {}".format(type(label_))) + raise Exception( + "Expected label_ to be a str, received: {}".format(type(label_)) + ) if revisions_ is not None and not isinstance(revisions_, (bytes, str, list)): - raise Exception("Expected revisions_ to be a Sequence, received: {}".format(type(revisions_))) + raise Exception( + "Expected revisions_ to be a Sequence, received: {}".format( + type(revisions_) + ) + ) if uri_ is not None and not isinstance(uri_, (bytes, str)): - raise Exception("Expected uri_ to be a str, received: {}".format(type(uri_))) + raise Exception( + "Expected uri_ to be a str, received: {}".format(type(uri_)) + ) self.label = label_ self.revisions = revisions_ @@ -5979,51 +9650,111 @@ def __init__(self, label=None, revisions=None, uri=None, **unknown_fields): self.unknown_fields = unknown_fields - class DeleteSecretArgs(Type): - _toSchema = {'args': 'args'} - _toPy = {'args': 'args'} + _toSchema = {"args": "args"} + _toPy = {"args": "args"} + def __init__(self, args=None, **unknown_fields): - ''' + """ args : typing.Sequence[~DeleteSecretArg] - ''' + """ args_ = [DeleteSecretArg.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception("Expected args_ to be a Sequence, received: {}".format(type(args_))) + raise Exception( + "Expected args_ to be a Sequence, received: {}".format(type(args_)) + ) self.args = args_ self.unknown_fields = unknown_fields - class Delta(Type): - _toSchema = {'entity': 'entity', 'removed': 'removed'} - _toPy = {'entity': 'entity', 'removed': 'removed'} + _toSchema = {"entity": "entity", "removed": "removed"} + _toPy = {"entity": "entity", "removed": "removed"} + def __init__(self, entity=None, removed=None, **unknown_fields): - ''' + """ entity : Any removed : bool - ''' + """ entity_ = entity removed_ = removed # Validate arguments against known Juju API types. if removed_ is not None and not isinstance(removed_, bool): - raise Exception("Expected removed_ to be a bool, received: {}".format(type(removed_))) + raise Exception( + "Expected removed_ to be a bool, received: {}".format(type(removed_)) + ) self.entity = entity_ self.removed = removed_ self.unknown_fields = unknown_fields - class DeployFromRepositoryArg(Type): - _toSchema = {'applicationname': 'ApplicationName', 'attachstorage': 'AttachStorage', 'base': 'base', 'channel': 'channel', 'charmname': 'CharmName', 'configyaml': 'ConfigYAML', 'cons': 'Cons', 'devices': 'Devices', 'dryrun': 'DryRun', 'endpoint_bindings': 'endpoint-bindings', 'force': 'force', 'num_units': 'num-units', 'placement': 'Placement', 'resources': 'resources', 'revision': 'revision', 'storage': 'Storage', 'trust': 'Trust'} - _toPy = {'ApplicationName': 'applicationname', 'AttachStorage': 'attachstorage', 'CharmName': 'charmname', 'ConfigYAML': 'configyaml', 'Cons': 'cons', 'Devices': 'devices', 'DryRun': 'dryrun', 'Placement': 'placement', 'Storage': 'storage', 'Trust': 'trust', 'base': 'base', 'channel': 'channel', 'endpoint-bindings': 'endpoint_bindings', 'force': 'force', 'num-units': 'num_units', 'resources': 'resources', 'revision': 'revision'} - def __init__(self, applicationname=None, attachstorage=None, charmname=None, configyaml=None, cons=None, devices=None, dryrun=None, placement=None, storage=None, trust=None, base=None, channel=None, endpoint_bindings=None, force=None, num_units=None, resources=None, revision=None, **unknown_fields): - ''' + _toSchema = { + "applicationname": "ApplicationName", + "attachstorage": "AttachStorage", + "base": "base", + "channel": "channel", + "charmname": "CharmName", + "configyaml": "ConfigYAML", + "cons": "Cons", + "devices": "Devices", + "dryrun": "DryRun", + "endpoint_bindings": "endpoint-bindings", + "force": "force", + "num_units": "num-units", + "placement": "Placement", + "resources": "resources", + "revision": "revision", + "storage": "Storage", + "trust": "Trust", + } + _toPy = { + "ApplicationName": "applicationname", + "AttachStorage": "attachstorage", + "CharmName": "charmname", + "ConfigYAML": "configyaml", + "Cons": "cons", + "Devices": "devices", + "DryRun": "dryrun", + "Placement": "placement", + "Storage": "storage", + "Trust": "trust", + "base": "base", + "channel": "channel", + "endpoint-bindings": "endpoint_bindings", + "force": "force", + "num-units": "num_units", + "resources": "resources", + "revision": "revision", + } + + def __init__( + self, + applicationname=None, + attachstorage=None, + charmname=None, + configyaml=None, + cons=None, + devices=None, + dryrun=None, + placement=None, + storage=None, + trust=None, + base=None, + channel=None, + endpoint_bindings=None, + force=None, + num_units=None, + resources=None, + revision=None, + **unknown_fields, + ): + """ applicationname : str attachstorage : typing.Sequence[str] charmname : str @@ -6041,7 +9772,7 @@ def __init__(self, applicationname=None, attachstorage=None, charmname=None, con num_units : int resources : typing.Mapping[str, str] revision : int - ''' + """ applicationname_ = applicationname attachstorage_ = attachstorage charmname_ = charmname @@ -6061,56 +9792,106 @@ def __init__(self, applicationname=None, attachstorage=None, charmname=None, con revision_ = revision # Validate arguments against known Juju API types. - if applicationname_ is not None and not isinstance(applicationname_, (bytes, str)): - raise Exception("Expected applicationname_ to be a str, received: {}".format(type(applicationname_))) - - if attachstorage_ is not None and not isinstance(attachstorage_, (bytes, str, list)): - raise Exception("Expected attachstorage_ to be a Sequence, received: {}".format(type(attachstorage_))) + if applicationname_ is not None and not isinstance( + applicationname_, (bytes, str) + ): + raise Exception( + "Expected applicationname_ to be a str, received: {}".format( + type(applicationname_) + ) + ) + + if attachstorage_ is not None and not isinstance( + attachstorage_, (bytes, str, list) + ): + raise Exception( + "Expected attachstorage_ to be a Sequence, received: {}".format( + type(attachstorage_) + ) + ) if charmname_ is not None and not isinstance(charmname_, (bytes, str)): - raise Exception("Expected charmname_ to be a str, received: {}".format(type(charmname_))) + raise Exception( + "Expected charmname_ to be a str, received: {}".format(type(charmname_)) + ) if configyaml_ is not None and not isinstance(configyaml_, (bytes, str)): - raise Exception("Expected configyaml_ to be a str, received: {}".format(type(configyaml_))) + raise Exception( + "Expected configyaml_ to be a str, received: {}".format( + type(configyaml_) + ) + ) if cons_ is not None and not isinstance(cons_, (dict, Value)): - raise Exception("Expected cons_ to be a Value, received: {}".format(type(cons_))) + raise Exception( + "Expected cons_ to be a Value, received: {}".format(type(cons_)) + ) if devices_ is not None and not isinstance(devices_, dict): - raise Exception("Expected devices_ to be a Mapping, received: {}".format(type(devices_))) + raise Exception( + "Expected devices_ to be a Mapping, received: {}".format(type(devices_)) + ) if dryrun_ is not None and not isinstance(dryrun_, bool): - raise Exception("Expected dryrun_ to be a bool, received: {}".format(type(dryrun_))) + raise Exception( + "Expected dryrun_ to be a bool, received: {}".format(type(dryrun_)) + ) if placement_ is not None and not isinstance(placement_, (bytes, str, list)): - raise Exception("Expected placement_ to be a Sequence, received: {}".format(type(placement_))) + raise Exception( + "Expected placement_ to be a Sequence, received: {}".format( + type(placement_) + ) + ) if storage_ is not None and not isinstance(storage_, dict): - raise Exception("Expected storage_ to be a Mapping, received: {}".format(type(storage_))) + raise Exception( + "Expected storage_ to be a Mapping, received: {}".format(type(storage_)) + ) if trust_ is not None and not isinstance(trust_, bool): - raise Exception("Expected trust_ to be a bool, received: {}".format(type(trust_))) + raise Exception( + "Expected trust_ to be a bool, received: {}".format(type(trust_)) + ) if base_ is not None and not isinstance(base_, (dict, Base)): - raise Exception("Expected base_ to be a Base, received: {}".format(type(base_))) + raise Exception( + "Expected base_ to be a Base, received: {}".format(type(base_)) + ) if channel_ is not None and not isinstance(channel_, (bytes, str)): - raise Exception("Expected channel_ to be a str, received: {}".format(type(channel_))) + raise Exception( + "Expected channel_ to be a str, received: {}".format(type(channel_)) + ) if endpoint_bindings_ is not None and not isinstance(endpoint_bindings_, dict): - raise Exception("Expected endpoint_bindings_ to be a Mapping, received: {}".format(type(endpoint_bindings_))) + raise Exception( + "Expected endpoint_bindings_ to be a Mapping, received: {}".format( + type(endpoint_bindings_) + ) + ) if force_ is not None and not isinstance(force_, bool): - raise Exception("Expected force_ to be a bool, received: {}".format(type(force_))) + raise Exception( + "Expected force_ to be a bool, received: {}".format(type(force_)) + ) if num_units_ is not None and not isinstance(num_units_, int): - raise Exception("Expected num_units_ to be a int, received: {}".format(type(num_units_))) + raise Exception( + "Expected num_units_ to be a int, received: {}".format(type(num_units_)) + ) if resources_ is not None and not isinstance(resources_, dict): - raise Exception("Expected resources_ to be a Mapping, received: {}".format(type(resources_))) + raise Exception( + "Expected resources_ to be a Mapping, received: {}".format( + type(resources_) + ) + ) if revision_ is not None and not isinstance(revision_, int): - raise Exception("Expected revision_ to be a int, received: {}".format(type(revision_))) + raise Exception( + "Expected revision_ to be a int, received: {}".format(type(revision_)) + ) self.applicationname = applicationname_ self.attachstorage = attachstorage_ @@ -6132,37 +9913,62 @@ def __init__(self, applicationname=None, attachstorage=None, charmname=None, con self.unknown_fields = unknown_fields - class DeployFromRepositoryArgs(Type): - _toSchema = {'args': 'Args'} - _toPy = {'Args': 'args'} + _toSchema = {"args": "Args"} + _toPy = {"Args": "args"} + def __init__(self, args=None, **unknown_fields): - ''' + """ args : typing.Sequence[~DeployFromRepositoryArg] - ''' + """ args_ = [DeployFromRepositoryArg.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception("Expected args_ to be a Sequence, received: {}".format(type(args_))) + raise Exception( + "Expected args_ to be a Sequence, received: {}".format(type(args_)) + ) self.args = args_ self.unknown_fields = unknown_fields - class DeployFromRepositoryInfo(Type): - _toSchema = {'architecture': 'architecture', 'base': 'base', 'channel': 'channel', 'effective_channel': 'effective-channel', 'name': 'name', 'revision': 'revision'} - _toPy = {'architecture': 'architecture', 'base': 'base', 'channel': 'channel', 'effective-channel': 'effective_channel', 'name': 'name', 'revision': 'revision'} - def __init__(self, architecture=None, base=None, channel=None, effective_channel=None, name=None, revision=None, **unknown_fields): - ''' + _toSchema = { + "architecture": "architecture", + "base": "base", + "channel": "channel", + "effective_channel": "effective-channel", + "name": "name", + "revision": "revision", + } + _toPy = { + "architecture": "architecture", + "base": "base", + "channel": "channel", + "effective-channel": "effective_channel", + "name": "name", + "revision": "revision", + } + + def __init__( + self, + architecture=None, + base=None, + channel=None, + effective_channel=None, + name=None, + revision=None, + **unknown_fields, + ): + """ architecture : str base : Base channel : str effective_channel : str name : str revision : int - ''' + """ architecture_ = architecture base_ = Base.from_json(base) if base else None channel_ = channel @@ -6172,22 +9978,40 @@ def __init__(self, architecture=None, base=None, channel=None, effective_channel # Validate arguments against known Juju API types. if architecture_ is not None and not isinstance(architecture_, (bytes, str)): - raise Exception("Expected architecture_ to be a str, received: {}".format(type(architecture_))) + raise Exception( + "Expected architecture_ to be a str, received: {}".format( + type(architecture_) + ) + ) if base_ is not None and not isinstance(base_, (dict, Base)): - raise Exception("Expected base_ to be a Base, received: {}".format(type(base_))) + raise Exception( + "Expected base_ to be a Base, received: {}".format(type(base_)) + ) if channel_ is not None and not isinstance(channel_, (bytes, str)): - raise Exception("Expected channel_ to be a str, received: {}".format(type(channel_))) - - if effective_channel_ is not None and not isinstance(effective_channel_, (bytes, str)): - raise Exception("Expected effective_channel_ to be a str, received: {}".format(type(effective_channel_))) + raise Exception( + "Expected channel_ to be a str, received: {}".format(type(channel_)) + ) + + if effective_channel_ is not None and not isinstance( + effective_channel_, (bytes, str) + ): + raise Exception( + "Expected effective_channel_ to be a str, received: {}".format( + type(effective_channel_) + ) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if revision_ is not None and not isinstance(revision_, int): - raise Exception("Expected revision_ to be a int, received: {}".format(type(revision_))) + raise Exception( + "Expected revision_ to be a int, received: {}".format(type(revision_)) + ) self.architecture = architecture_ self.base = base_ @@ -6198,29 +10022,55 @@ def __init__(self, architecture=None, base=None, channel=None, effective_channel self.unknown_fields = unknown_fields - class DeployFromRepositoryResult(Type): - _toSchema = {'errors': 'Errors', 'info': 'Info', 'pendingresourceuploads': 'PendingResourceUploads'} - _toPy = {'Errors': 'errors', 'Info': 'info', 'PendingResourceUploads': 'pendingresourceuploads'} - def __init__(self, errors=None, info=None, pendingresourceuploads=None, **unknown_fields): - ''' + _toSchema = { + "errors": "Errors", + "info": "Info", + "pendingresourceuploads": "PendingResourceUploads", + } + _toPy = { + "Errors": "errors", + "Info": "info", + "PendingResourceUploads": "pendingresourceuploads", + } + + def __init__( + self, errors=None, info=None, pendingresourceuploads=None, **unknown_fields + ): + """ errors : typing.Sequence[~Error] info : DeployFromRepositoryInfo pendingresourceuploads : typing.Sequence[~PendingResourceUpload] - ''' + """ errors_ = [Error.from_json(o) for o in errors or []] info_ = DeployFromRepositoryInfo.from_json(info) if info else None - pendingresourceuploads_ = [PendingResourceUpload.from_json(o) for o in pendingresourceuploads or []] + pendingresourceuploads_ = [ + PendingResourceUpload.from_json(o) for o in pendingresourceuploads or [] + ] # Validate arguments against known Juju API types. if errors_ is not None and not isinstance(errors_, (bytes, str, list)): - raise Exception("Expected errors_ to be a Sequence, received: {}".format(type(errors_))) - - if info_ is not None and not isinstance(info_, (dict, DeployFromRepositoryInfo)): - raise Exception("Expected info_ to be a DeployFromRepositoryInfo, received: {}".format(type(info_))) - - if pendingresourceuploads_ is not None and not isinstance(pendingresourceuploads_, (bytes, str, list)): - raise Exception("Expected pendingresourceuploads_ to be a Sequence, received: {}".format(type(pendingresourceuploads_))) + raise Exception( + "Expected errors_ to be a Sequence, received: {}".format(type(errors_)) + ) + + if info_ is not None and not isinstance( + info_, (dict, DeployFromRepositoryInfo) + ): + raise Exception( + "Expected info_ to be a DeployFromRepositoryInfo, received: {}".format( + type(info_) + ) + ) + + if pendingresourceuploads_ is not None and not isinstance( + pendingresourceuploads_, (bytes, str, list) + ): + raise Exception( + "Expected pendingresourceuploads_ to be a Sequence, received: {}".format( + type(pendingresourceuploads_) + ) + ) self.errors = errors_ self.info = info_ @@ -6228,47 +10078,83 @@ def __init__(self, errors=None, info=None, pendingresourceuploads=None, **unknow self.unknown_fields = unknown_fields - class DeployFromRepositoryResults(Type): - _toSchema = {'results': 'Results'} - _toPy = {'Results': 'results'} + _toSchema = {"results": "Results"} + _toPy = {"Results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~DeployFromRepositoryResult] - ''' + """ results_ = [DeployFromRepositoryResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class DestroyApplicationInfo(Type): - _toSchema = {'destroyed_storage': 'destroyed-storage', 'destroyed_units': 'destroyed-units', 'detached_storage': 'detached-storage'} - _toPy = {'destroyed-storage': 'destroyed_storage', 'destroyed-units': 'destroyed_units', 'detached-storage': 'detached_storage'} - def __init__(self, destroyed_storage=None, destroyed_units=None, detached_storage=None, **unknown_fields): - ''' + _toSchema = { + "destroyed_storage": "destroyed-storage", + "destroyed_units": "destroyed-units", + "detached_storage": "detached-storage", + } + _toPy = { + "destroyed-storage": "destroyed_storage", + "destroyed-units": "destroyed_units", + "detached-storage": "detached_storage", + } + + def __init__( + self, + destroyed_storage=None, + destroyed_units=None, + detached_storage=None, + **unknown_fields, + ): + """ destroyed_storage : typing.Sequence[~Entity] destroyed_units : typing.Sequence[~Entity] detached_storage : typing.Sequence[~Entity] - ''' + """ destroyed_storage_ = [Entity.from_json(o) for o in destroyed_storage or []] destroyed_units_ = [Entity.from_json(o) for o in destroyed_units or []] detached_storage_ = [Entity.from_json(o) for o in detached_storage or []] # Validate arguments against known Juju API types. - if destroyed_storage_ is not None and not isinstance(destroyed_storage_, (bytes, str, list)): - raise Exception("Expected destroyed_storage_ to be a Sequence, received: {}".format(type(destroyed_storage_))) - - if destroyed_units_ is not None and not isinstance(destroyed_units_, (bytes, str, list)): - raise Exception("Expected destroyed_units_ to be a Sequence, received: {}".format(type(destroyed_units_))) - - if detached_storage_ is not None and not isinstance(detached_storage_, (bytes, str, list)): - raise Exception("Expected detached_storage_ to be a Sequence, received: {}".format(type(detached_storage_))) + if destroyed_storage_ is not None and not isinstance( + destroyed_storage_, (bytes, str, list) + ): + raise Exception( + "Expected destroyed_storage_ to be a Sequence, received: {}".format( + type(destroyed_storage_) + ) + ) + + if destroyed_units_ is not None and not isinstance( + destroyed_units_, (bytes, str, list) + ): + raise Exception( + "Expected destroyed_units_ to be a Sequence, received: {}".format( + type(destroyed_units_) + ) + ) + + if detached_storage_ is not None and not isinstance( + detached_storage_, (bytes, str, list) + ): + raise Exception( + "Expected detached_storage_ to be a Sequence, received: {}".format( + type(detached_storage_) + ) + ) self.destroyed_storage = destroyed_storage_ self.destroyed_units = destroyed_units_ @@ -6276,42 +10162,68 @@ def __init__(self, destroyed_storage=None, destroyed_units=None, detached_storag self.unknown_fields = unknown_fields - class DestroyApplicationOffers(Type): - _toSchema = {'force': 'force', 'offer_urls': 'offer-urls'} - _toPy = {'force': 'force', 'offer-urls': 'offer_urls'} + _toSchema = {"force": "force", "offer_urls": "offer-urls"} + _toPy = {"force": "force", "offer-urls": "offer_urls"} + def __init__(self, force=None, offer_urls=None, **unknown_fields): - ''' + """ force : bool offer_urls : typing.Sequence[str] - ''' + """ force_ = force offer_urls_ = offer_urls # Validate arguments against known Juju API types. if force_ is not None and not isinstance(force_, bool): - raise Exception("Expected force_ to be a bool, received: {}".format(type(force_))) + raise Exception( + "Expected force_ to be a bool, received: {}".format(type(force_)) + ) if offer_urls_ is not None and not isinstance(offer_urls_, (bytes, str, list)): - raise Exception("Expected offer_urls_ to be a Sequence, received: {}".format(type(offer_urls_))) + raise Exception( + "Expected offer_urls_ to be a Sequence, received: {}".format( + type(offer_urls_) + ) + ) self.force = force_ self.offer_urls = offer_urls_ self.unknown_fields = unknown_fields - class DestroyApplicationParams(Type): - _toSchema = {'application_tag': 'application-tag', 'destroy_storage': 'destroy-storage', 'dry_run': 'dry-run', 'force': 'force', 'max_wait': 'max-wait'} - _toPy = {'application-tag': 'application_tag', 'destroy-storage': 'destroy_storage', 'dry-run': 'dry_run', 'force': 'force', 'max-wait': 'max_wait'} - def __init__(self, application_tag=None, destroy_storage=None, dry_run=None, force=None, max_wait=None, **unknown_fields): - ''' + _toSchema = { + "application_tag": "application-tag", + "destroy_storage": "destroy-storage", + "dry_run": "dry-run", + "force": "force", + "max_wait": "max-wait", + } + _toPy = { + "application-tag": "application_tag", + "destroy-storage": "destroy_storage", + "dry-run": "dry_run", + "force": "force", + "max-wait": "max_wait", + } + + def __init__( + self, + application_tag=None, + destroy_storage=None, + dry_run=None, + force=None, + max_wait=None, + **unknown_fields, + ): + """ application_tag : str destroy_storage : bool dry_run : bool force : bool max_wait : int - ''' + """ application_tag_ = application_tag destroy_storage_ = destroy_storage dry_run_ = dry_run @@ -6319,20 +10231,36 @@ def __init__(self, application_tag=None, destroy_storage=None, dry_run=None, for max_wait_ = max_wait # Validate arguments against known Juju API types. - if application_tag_ is not None and not isinstance(application_tag_, (bytes, str)): - raise Exception("Expected application_tag_ to be a str, received: {}".format(type(application_tag_))) + if application_tag_ is not None and not isinstance( + application_tag_, (bytes, str) + ): + raise Exception( + "Expected application_tag_ to be a str, received: {}".format( + type(application_tag_) + ) + ) if destroy_storage_ is not None and not isinstance(destroy_storage_, bool): - raise Exception("Expected destroy_storage_ to be a bool, received: {}".format(type(destroy_storage_))) + raise Exception( + "Expected destroy_storage_ to be a bool, received: {}".format( + type(destroy_storage_) + ) + ) if dry_run_ is not None and not isinstance(dry_run_, bool): - raise Exception("Expected dry_run_ to be a bool, received: {}".format(type(dry_run_))) + raise Exception( + "Expected dry_run_ to be a bool, received: {}".format(type(dry_run_)) + ) if force_ is not None and not isinstance(force_, bool): - raise Exception("Expected force_ to be a bool, received: {}".format(type(force_))) + raise Exception( + "Expected force_ to be a bool, received: {}".format(type(force_)) + ) if max_wait_ is not None and not isinstance(max_wait_, int): - raise Exception("Expected max_wait_ to be a int, received: {}".format(type(max_wait_))) + raise Exception( + "Expected max_wait_ to be a int, received: {}".format(type(max_wait_)) + ) self.application_tag = application_tag_ self.destroy_storage = destroy_storage_ @@ -6342,89 +10270,127 @@ def __init__(self, application_tag=None, destroy_storage=None, dry_run=None, for self.unknown_fields = unknown_fields - class DestroyApplicationResult(Type): - _toSchema = {'error': 'error', 'info': 'info'} - _toPy = {'error': 'error', 'info': 'info'} + _toSchema = {"error": "error", "info": "info"} + _toPy = {"error": "error", "info": "info"} + def __init__(self, error=None, info=None, **unknown_fields): - ''' + """ error : Error info : DestroyApplicationInfo - ''' + """ error_ = Error.from_json(error) if error else None info_ = DestroyApplicationInfo.from_json(info) if info else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if info_ is not None and not isinstance(info_, (dict, DestroyApplicationInfo)): - raise Exception("Expected info_ to be a DestroyApplicationInfo, received: {}".format(type(info_))) + raise Exception( + "Expected info_ to be a DestroyApplicationInfo, received: {}".format( + type(info_) + ) + ) self.error = error_ self.info = info_ self.unknown_fields = unknown_fields - class DestroyApplicationResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~DestroyApplicationResult] - ''' + """ results_ = [DestroyApplicationResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class DestroyApplicationsParams(Type): - _toSchema = {'applications': 'applications'} - _toPy = {'applications': 'applications'} + _toSchema = {"applications": "applications"} + _toPy = {"applications": "applications"} + def __init__(self, applications=None, **unknown_fields): - ''' + """ applications : typing.Sequence[~DestroyApplicationParams] - ''' - applications_ = [DestroyApplicationParams.from_json(o) for o in applications or []] + """ + applications_ = [ + DestroyApplicationParams.from_json(o) for o in applications or [] + ] # Validate arguments against known Juju API types. - if applications_ is not None and not isinstance(applications_, (bytes, str, list)): - raise Exception("Expected applications_ to be a Sequence, received: {}".format(type(applications_))) + if applications_ is not None and not isinstance( + applications_, (bytes, str, list) + ): + raise Exception( + "Expected applications_ to be a Sequence, received: {}".format( + type(applications_) + ) + ) self.applications = applications_ self.unknown_fields = unknown_fields - class DestroyConsumedApplicationParams(Type): - _toSchema = {'application_tag': 'application-tag', 'force': 'force', 'max_wait': 'max-wait'} - _toPy = {'application-tag': 'application_tag', 'force': 'force', 'max-wait': 'max_wait'} - def __init__(self, application_tag=None, force=None, max_wait=None, **unknown_fields): - ''' + _toSchema = { + "application_tag": "application-tag", + "force": "force", + "max_wait": "max-wait", + } + _toPy = { + "application-tag": "application_tag", + "force": "force", + "max-wait": "max_wait", + } + + def __init__( + self, application_tag=None, force=None, max_wait=None, **unknown_fields + ): + """ application_tag : str force : bool max_wait : int - ''' + """ application_tag_ = application_tag force_ = force max_wait_ = max_wait # Validate arguments against known Juju API types. - if application_tag_ is not None and not isinstance(application_tag_, (bytes, str)): - raise Exception("Expected application_tag_ to be a str, received: {}".format(type(application_tag_))) + if application_tag_ is not None and not isinstance( + application_tag_, (bytes, str) + ): + raise Exception( + "Expected application_tag_ to be a str, received: {}".format( + type(application_tag_) + ) + ) if force_ is not None and not isinstance(force_, bool): - raise Exception("Expected force_ to be a bool, received: {}".format(type(force_))) + raise Exception( + "Expected force_ to be a bool, received: {}".format(type(force_)) + ) if max_wait_ is not None and not isinstance(max_wait_, int): - raise Exception("Expected max_wait_ to be a int, received: {}".format(type(max_wait_))) + raise Exception( + "Expected max_wait_ to be a int, received: {}".format(type(max_wait_)) + ) self.application_tag = application_tag_ self.force = force_ @@ -6432,36 +10398,64 @@ def __init__(self, application_tag=None, force=None, max_wait=None, **unknown_fi self.unknown_fields = unknown_fields - class DestroyConsumedApplicationsParams(Type): - _toSchema = {'applications': 'applications'} - _toPy = {'applications': 'applications'} + _toSchema = {"applications": "applications"} + _toPy = {"applications": "applications"} + def __init__(self, applications=None, **unknown_fields): - ''' + """ applications : typing.Sequence[~DestroyConsumedApplicationParams] - ''' - applications_ = [DestroyConsumedApplicationParams.from_json(o) for o in applications or []] + """ + applications_ = [ + DestroyConsumedApplicationParams.from_json(o) for o in applications or [] + ] # Validate arguments against known Juju API types. - if applications_ is not None and not isinstance(applications_, (bytes, str, list)): - raise Exception("Expected applications_ to be a Sequence, received: {}".format(type(applications_))) + if applications_ is not None and not isinstance( + applications_, (bytes, str, list) + ): + raise Exception( + "Expected applications_ to be a Sequence, received: {}".format( + type(applications_) + ) + ) self.applications = applications_ self.unknown_fields = unknown_fields - class DestroyControllerArgs(Type): - _toSchema = {'destroy_models': 'destroy-models', 'destroy_storage': 'destroy-storage', 'force': 'force', 'max_wait': 'max-wait', 'model_timeout': 'model-timeout'} - _toPy = {'destroy-models': 'destroy_models', 'destroy-storage': 'destroy_storage', 'force': 'force', 'max-wait': 'max_wait', 'model-timeout': 'model_timeout'} - def __init__(self, destroy_models=None, destroy_storage=None, force=None, max_wait=None, model_timeout=None, **unknown_fields): - ''' + _toSchema = { + "destroy_models": "destroy-models", + "destroy_storage": "destroy-storage", + "force": "force", + "max_wait": "max-wait", + "model_timeout": "model-timeout", + } + _toPy = { + "destroy-models": "destroy_models", + "destroy-storage": "destroy_storage", + "force": "force", + "max-wait": "max_wait", + "model-timeout": "model_timeout", + } + + def __init__( + self, + destroy_models=None, + destroy_storage=None, + force=None, + max_wait=None, + model_timeout=None, + **unknown_fields, + ): + """ destroy_models : bool destroy_storage : bool force : bool max_wait : int model_timeout : int - ''' + """ destroy_models_ = destroy_models destroy_storage_ = destroy_storage force_ = force @@ -6470,19 +10464,35 @@ def __init__(self, destroy_models=None, destroy_storage=None, force=None, max_wa # Validate arguments against known Juju API types. if destroy_models_ is not None and not isinstance(destroy_models_, bool): - raise Exception("Expected destroy_models_ to be a bool, received: {}".format(type(destroy_models_))) + raise Exception( + "Expected destroy_models_ to be a bool, received: {}".format( + type(destroy_models_) + ) + ) if destroy_storage_ is not None and not isinstance(destroy_storage_, bool): - raise Exception("Expected destroy_storage_ to be a bool, received: {}".format(type(destroy_storage_))) + raise Exception( + "Expected destroy_storage_ to be a bool, received: {}".format( + type(destroy_storage_) + ) + ) if force_ is not None and not isinstance(force_, bool): - raise Exception("Expected force_ to be a bool, received: {}".format(type(force_))) + raise Exception( + "Expected force_ to be a bool, received: {}".format(type(force_)) + ) if max_wait_ is not None and not isinstance(max_wait_, int): - raise Exception("Expected max_wait_ to be a int, received: {}".format(type(max_wait_))) + raise Exception( + "Expected max_wait_ to be a int, received: {}".format(type(max_wait_)) + ) if model_timeout_ is not None and not isinstance(model_timeout_, int): - raise Exception("Expected model_timeout_ to be a int, received: {}".format(type(model_timeout_))) + raise Exception( + "Expected model_timeout_ to be a int, received: {}".format( + type(model_timeout_) + ) + ) self.destroy_models = destroy_models_ self.destroy_storage = destroy_storage_ @@ -6492,39 +10502,89 @@ def __init__(self, destroy_models=None, destroy_storage=None, force=None, max_wa self.unknown_fields = unknown_fields - class DestroyMachineInfo(Type): - _toSchema = {'destroyed_containers': 'destroyed-containers', 'destroyed_storage': 'destroyed-storage', 'destroyed_units': 'destroyed-units', 'detached_storage': 'detached-storage', 'machine_id': 'machine-id'} - _toPy = {'destroyed-containers': 'destroyed_containers', 'destroyed-storage': 'destroyed_storage', 'destroyed-units': 'destroyed_units', 'detached-storage': 'detached_storage', 'machine-id': 'machine_id'} - def __init__(self, destroyed_containers=None, destroyed_storage=None, destroyed_units=None, detached_storage=None, machine_id=None, **unknown_fields): - ''' + _toSchema = { + "destroyed_containers": "destroyed-containers", + "destroyed_storage": "destroyed-storage", + "destroyed_units": "destroyed-units", + "detached_storage": "detached-storage", + "machine_id": "machine-id", + } + _toPy = { + "destroyed-containers": "destroyed_containers", + "destroyed-storage": "destroyed_storage", + "destroyed-units": "destroyed_units", + "detached-storage": "detached_storage", + "machine-id": "machine_id", + } + + def __init__( + self, + destroyed_containers=None, + destroyed_storage=None, + destroyed_units=None, + detached_storage=None, + machine_id=None, + **unknown_fields, + ): + """ destroyed_containers : typing.Sequence[~DestroyMachineResult] destroyed_storage : typing.Sequence[~Entity] destroyed_units : typing.Sequence[~Entity] detached_storage : typing.Sequence[~Entity] machine_id : str - ''' - destroyed_containers_ = [DestroyMachineResult.from_json(o) for o in destroyed_containers or []] + """ + destroyed_containers_ = [ + DestroyMachineResult.from_json(o) for o in destroyed_containers or [] + ] destroyed_storage_ = [Entity.from_json(o) for o in destroyed_storage or []] destroyed_units_ = [Entity.from_json(o) for o in destroyed_units or []] detached_storage_ = [Entity.from_json(o) for o in detached_storage or []] machine_id_ = machine_id # Validate arguments against known Juju API types. - if destroyed_containers_ is not None and not isinstance(destroyed_containers_, (bytes, str, list)): - raise Exception("Expected destroyed_containers_ to be a Sequence, received: {}".format(type(destroyed_containers_))) - - if destroyed_storage_ is not None and not isinstance(destroyed_storage_, (bytes, str, list)): - raise Exception("Expected destroyed_storage_ to be a Sequence, received: {}".format(type(destroyed_storage_))) - - if destroyed_units_ is not None and not isinstance(destroyed_units_, (bytes, str, list)): - raise Exception("Expected destroyed_units_ to be a Sequence, received: {}".format(type(destroyed_units_))) - - if detached_storage_ is not None and not isinstance(detached_storage_, (bytes, str, list)): - raise Exception("Expected detached_storage_ to be a Sequence, received: {}".format(type(detached_storage_))) + if destroyed_containers_ is not None and not isinstance( + destroyed_containers_, (bytes, str, list) + ): + raise Exception( + "Expected destroyed_containers_ to be a Sequence, received: {}".format( + type(destroyed_containers_) + ) + ) + + if destroyed_storage_ is not None and not isinstance( + destroyed_storage_, (bytes, str, list) + ): + raise Exception( + "Expected destroyed_storage_ to be a Sequence, received: {}".format( + type(destroyed_storage_) + ) + ) + + if destroyed_units_ is not None and not isinstance( + destroyed_units_, (bytes, str, list) + ): + raise Exception( + "Expected destroyed_units_ to be a Sequence, received: {}".format( + type(destroyed_units_) + ) + ) + + if detached_storage_ is not None and not isinstance( + detached_storage_, (bytes, str, list) + ): + raise Exception( + "Expected detached_storage_ to be a Sequence, received: {}".format( + type(detached_storage_) + ) + ) if machine_id_ is not None and not isinstance(machine_id_, (bytes, str)): - raise Exception("Expected machine_id_ to be a str, received: {}".format(type(machine_id_))) + raise Exception( + "Expected machine_id_ to be a str, received: {}".format( + type(machine_id_) + ) + ) self.destroyed_containers = destroyed_containers_ self.destroyed_storage = destroyed_storage_ @@ -6534,60 +10594,90 @@ def __init__(self, destroyed_containers=None, destroyed_storage=None, destroyed_ self.unknown_fields = unknown_fields - class DestroyMachineResult(Type): - _toSchema = {'error': 'error', 'info': 'info'} - _toPy = {'error': 'error', 'info': 'info'} + _toSchema = {"error": "error", "info": "info"} + _toPy = {"error": "error", "info": "info"} + def __init__(self, error=None, info=None, **unknown_fields): - ''' + """ error : Error info : DestroyMachineInfo - ''' + """ error_ = Error.from_json(error) if error else None info_ = DestroyMachineInfo.from_json(info) if info else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if info_ is not None and not isinstance(info_, (dict, DestroyMachineInfo)): - raise Exception("Expected info_ to be a DestroyMachineInfo, received: {}".format(type(info_))) + raise Exception( + "Expected info_ to be a DestroyMachineInfo, received: {}".format( + type(info_) + ) + ) self.error = error_ self.info = info_ self.unknown_fields = unknown_fields - class DestroyMachineResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~DestroyMachineResult] - ''' + """ results_ = [DestroyMachineResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class DestroyMachinesParams(Type): - _toSchema = {'dry_run': 'dry-run', 'force': 'force', 'keep': 'keep', 'machine_tags': 'machine-tags', 'max_wait': 'max-wait'} - _toPy = {'dry-run': 'dry_run', 'force': 'force', 'keep': 'keep', 'machine-tags': 'machine_tags', 'max-wait': 'max_wait'} - def __init__(self, dry_run=None, force=None, keep=None, machine_tags=None, max_wait=None, **unknown_fields): - ''' + _toSchema = { + "dry_run": "dry-run", + "force": "force", + "keep": "keep", + "machine_tags": "machine-tags", + "max_wait": "max-wait", + } + _toPy = { + "dry-run": "dry_run", + "force": "force", + "keep": "keep", + "machine-tags": "machine_tags", + "max-wait": "max_wait", + } + + def __init__( + self, + dry_run=None, + force=None, + keep=None, + machine_tags=None, + max_wait=None, + **unknown_fields, + ): + """ dry_run : bool force : bool keep : bool machine_tags : typing.Sequence[str] max_wait : int - ''' + """ dry_run_ = dry_run force_ = force keep_ = keep @@ -6596,19 +10686,33 @@ def __init__(self, dry_run=None, force=None, keep=None, machine_tags=None, max_w # Validate arguments against known Juju API types. if dry_run_ is not None and not isinstance(dry_run_, bool): - raise Exception("Expected dry_run_ to be a bool, received: {}".format(type(dry_run_))) + raise Exception( + "Expected dry_run_ to be a bool, received: {}".format(type(dry_run_)) + ) if force_ is not None and not isinstance(force_, bool): - raise Exception("Expected force_ to be a bool, received: {}".format(type(force_))) + raise Exception( + "Expected force_ to be a bool, received: {}".format(type(force_)) + ) if keep_ is not None and not isinstance(keep_, bool): - raise Exception("Expected keep_ to be a bool, received: {}".format(type(keep_))) - - if machine_tags_ is not None and not isinstance(machine_tags_, (bytes, str, list)): - raise Exception("Expected machine_tags_ to be a Sequence, received: {}".format(type(machine_tags_))) + raise Exception( + "Expected keep_ to be a bool, received: {}".format(type(keep_)) + ) + + if machine_tags_ is not None and not isinstance( + machine_tags_, (bytes, str, list) + ): + raise Exception( + "Expected machine_tags_ to be a Sequence, received: {}".format( + type(machine_tags_) + ) + ) if max_wait_ is not None and not isinstance(max_wait_, int): - raise Exception("Expected max_wait_ to be a int, received: {}".format(type(max_wait_))) + raise Exception( + "Expected max_wait_ to be a int, received: {}".format(type(max_wait_)) + ) self.dry_run = dry_run_ self.force = force_ @@ -6618,18 +10722,38 @@ def __init__(self, dry_run=None, force=None, keep=None, machine_tags=None, max_w self.unknown_fields = unknown_fields - class DestroyModelParams(Type): - _toSchema = {'destroy_storage': 'destroy-storage', 'force': 'force', 'max_wait': 'max-wait', 'model_tag': 'model-tag', 'timeout': 'timeout'} - _toPy = {'destroy-storage': 'destroy_storage', 'force': 'force', 'max-wait': 'max_wait', 'model-tag': 'model_tag', 'timeout': 'timeout'} - def __init__(self, destroy_storage=None, force=None, max_wait=None, model_tag=None, timeout=None, **unknown_fields): - ''' + _toSchema = { + "destroy_storage": "destroy-storage", + "force": "force", + "max_wait": "max-wait", + "model_tag": "model-tag", + "timeout": "timeout", + } + _toPy = { + "destroy-storage": "destroy_storage", + "force": "force", + "max-wait": "max_wait", + "model-tag": "model_tag", + "timeout": "timeout", + } + + def __init__( + self, + destroy_storage=None, + force=None, + max_wait=None, + model_tag=None, + timeout=None, + **unknown_fields, + ): + """ destroy_storage : bool force : bool max_wait : int model_tag : str timeout : int - ''' + """ destroy_storage_ = destroy_storage force_ = force max_wait_ = max_wait @@ -6638,19 +10762,31 @@ def __init__(self, destroy_storage=None, force=None, max_wait=None, model_tag=No # Validate arguments against known Juju API types. if destroy_storage_ is not None and not isinstance(destroy_storage_, bool): - raise Exception("Expected destroy_storage_ to be a bool, received: {}".format(type(destroy_storage_))) + raise Exception( + "Expected destroy_storage_ to be a bool, received: {}".format( + type(destroy_storage_) + ) + ) if force_ is not None and not isinstance(force_, bool): - raise Exception("Expected force_ to be a bool, received: {}".format(type(force_))) + raise Exception( + "Expected force_ to be a bool, received: {}".format(type(force_)) + ) if max_wait_ is not None and not isinstance(max_wait_, int): - raise Exception("Expected max_wait_ to be a int, received: {}".format(type(max_wait_))) + raise Exception( + "Expected max_wait_ to be a int, received: {}".format(type(max_wait_)) + ) if model_tag_ is not None and not isinstance(model_tag_, (bytes, str)): - raise Exception("Expected model_tag_ to be a str, received: {}".format(type(model_tag_))) + raise Exception( + "Expected model_tag_ to be a str, received: {}".format(type(model_tag_)) + ) if timeout_ is not None and not isinstance(timeout_, int): - raise Exception("Expected timeout_ to be a int, received: {}".format(type(timeout_))) + raise Exception( + "Expected timeout_ to be a int, received: {}".format(type(timeout_)) + ) self.destroy_storage = destroy_storage_ self.force = force_ @@ -6660,35 +10796,54 @@ def __init__(self, destroy_storage=None, force=None, max_wait=None, model_tag=No self.unknown_fields = unknown_fields - class DestroyModelsParams(Type): - _toSchema = {'models': 'models'} - _toPy = {'models': 'models'} + _toSchema = {"models": "models"} + _toPy = {"models": "models"} + def __init__(self, models=None, **unknown_fields): - ''' + """ models : typing.Sequence[~DestroyModelParams] - ''' + """ models_ = [DestroyModelParams.from_json(o) for o in models or []] # Validate arguments against known Juju API types. if models_ is not None and not isinstance(models_, (bytes, str, list)): - raise Exception("Expected models_ to be a Sequence, received: {}".format(type(models_))) + raise Exception( + "Expected models_ to be a Sequence, received: {}".format(type(models_)) + ) self.models = models_ self.unknown_fields = unknown_fields - class DestroyRelation(Type): - _toSchema = {'endpoints': 'endpoints', 'force': 'force', 'max_wait': 'max-wait', 'relation_id': 'relation-id'} - _toPy = {'endpoints': 'endpoints', 'force': 'force', 'max-wait': 'max_wait', 'relation-id': 'relation_id'} - def __init__(self, endpoints=None, force=None, max_wait=None, relation_id=None, **unknown_fields): - ''' + _toSchema = { + "endpoints": "endpoints", + "force": "force", + "max_wait": "max-wait", + "relation_id": "relation-id", + } + _toPy = { + "endpoints": "endpoints", + "force": "force", + "max-wait": "max_wait", + "relation-id": "relation_id", + } + + def __init__( + self, + endpoints=None, + force=None, + max_wait=None, + relation_id=None, + **unknown_fields, + ): + """ endpoints : typing.Sequence[str] force : bool max_wait : int relation_id : int - ''' + """ endpoints_ = endpoints force_ = force max_wait_ = max_wait @@ -6696,16 +10851,28 @@ def __init__(self, endpoints=None, force=None, max_wait=None, relation_id=None, # Validate arguments against known Juju API types. if endpoints_ is not None and not isinstance(endpoints_, (bytes, str, list)): - raise Exception("Expected endpoints_ to be a Sequence, received: {}".format(type(endpoints_))) + raise Exception( + "Expected endpoints_ to be a Sequence, received: {}".format( + type(endpoints_) + ) + ) if force_ is not None and not isinstance(force_, bool): - raise Exception("Expected force_ to be a bool, received: {}".format(type(force_))) + raise Exception( + "Expected force_ to be a bool, received: {}".format(type(force_)) + ) if max_wait_ is not None and not isinstance(max_wait_, int): - raise Exception("Expected max_wait_ to be a int, received: {}".format(type(max_wait_))) + raise Exception( + "Expected max_wait_ to be a int, received: {}".format(type(max_wait_)) + ) if relation_id_ is not None and not isinstance(relation_id_, int): - raise Exception("Expected relation_id_ to be a int, received: {}".format(type(relation_id_))) + raise Exception( + "Expected relation_id_ to be a int, received: {}".format( + type(relation_id_) + ) + ) self.endpoints = endpoints_ self.force = force_ @@ -6714,42 +10881,80 @@ def __init__(self, endpoints=None, force=None, max_wait=None, relation_id=None, self.unknown_fields = unknown_fields - class DestroyUnitInfo(Type): - _toSchema = {'destroyed_storage': 'destroyed-storage', 'detached_storage': 'detached-storage'} - _toPy = {'destroyed-storage': 'destroyed_storage', 'detached-storage': 'detached_storage'} + _toSchema = { + "destroyed_storage": "destroyed-storage", + "detached_storage": "detached-storage", + } + _toPy = { + "destroyed-storage": "destroyed_storage", + "detached-storage": "detached_storage", + } + def __init__(self, destroyed_storage=None, detached_storage=None, **unknown_fields): - ''' + """ destroyed_storage : typing.Sequence[~Entity] detached_storage : typing.Sequence[~Entity] - ''' + """ destroyed_storage_ = [Entity.from_json(o) for o in destroyed_storage or []] detached_storage_ = [Entity.from_json(o) for o in detached_storage or []] # Validate arguments against known Juju API types. - if destroyed_storage_ is not None and not isinstance(destroyed_storage_, (bytes, str, list)): - raise Exception("Expected destroyed_storage_ to be a Sequence, received: {}".format(type(destroyed_storage_))) - - if detached_storage_ is not None and not isinstance(detached_storage_, (bytes, str, list)): - raise Exception("Expected detached_storage_ to be a Sequence, received: {}".format(type(detached_storage_))) + if destroyed_storage_ is not None and not isinstance( + destroyed_storage_, (bytes, str, list) + ): + raise Exception( + "Expected destroyed_storage_ to be a Sequence, received: {}".format( + type(destroyed_storage_) + ) + ) + + if detached_storage_ is not None and not isinstance( + detached_storage_, (bytes, str, list) + ): + raise Exception( + "Expected detached_storage_ to be a Sequence, received: {}".format( + type(detached_storage_) + ) + ) self.destroyed_storage = destroyed_storage_ self.detached_storage = detached_storage_ self.unknown_fields = unknown_fields - class DestroyUnitParams(Type): - _toSchema = {'destroy_storage': 'destroy-storage', 'dry_run': 'dry-run', 'force': 'force', 'max_wait': 'max-wait', 'unit_tag': 'unit-tag'} - _toPy = {'destroy-storage': 'destroy_storage', 'dry-run': 'dry_run', 'force': 'force', 'max-wait': 'max_wait', 'unit-tag': 'unit_tag'} - def __init__(self, destroy_storage=None, dry_run=None, force=None, max_wait=None, unit_tag=None, **unknown_fields): - ''' + _toSchema = { + "destroy_storage": "destroy-storage", + "dry_run": "dry-run", + "force": "force", + "max_wait": "max-wait", + "unit_tag": "unit-tag", + } + _toPy = { + "destroy-storage": "destroy_storage", + "dry-run": "dry_run", + "force": "force", + "max-wait": "max_wait", + "unit-tag": "unit_tag", + } + + def __init__( + self, + destroy_storage=None, + dry_run=None, + force=None, + max_wait=None, + unit_tag=None, + **unknown_fields, + ): + """ destroy_storage : bool dry_run : bool force : bool max_wait : int unit_tag : str - ''' + """ destroy_storage_ = destroy_storage dry_run_ = dry_run force_ = force @@ -6758,19 +10963,31 @@ def __init__(self, destroy_storage=None, dry_run=None, force=None, max_wait=None # Validate arguments against known Juju API types. if destroy_storage_ is not None and not isinstance(destroy_storage_, bool): - raise Exception("Expected destroy_storage_ to be a bool, received: {}".format(type(destroy_storage_))) + raise Exception( + "Expected destroy_storage_ to be a bool, received: {}".format( + type(destroy_storage_) + ) + ) if dry_run_ is not None and not isinstance(dry_run_, bool): - raise Exception("Expected dry_run_ to be a bool, received: {}".format(type(dry_run_))) + raise Exception( + "Expected dry_run_ to be a bool, received: {}".format(type(dry_run_)) + ) if force_ is not None and not isinstance(force_, bool): - raise Exception("Expected force_ to be a bool, received: {}".format(type(force_))) + raise Exception( + "Expected force_ to be a bool, received: {}".format(type(force_)) + ) if max_wait_ is not None and not isinstance(max_wait_, int): - raise Exception("Expected max_wait_ to be a int, received: {}".format(type(max_wait_))) + raise Exception( + "Expected max_wait_ to be a int, received: {}".format(type(max_wait_)) + ) if unit_tag_ is not None and not isinstance(unit_tag_, (bytes, str)): - raise Exception("Expected unit_tag_ to be a str, received: {}".format(type(unit_tag_))) + raise Exception( + "Expected unit_tag_ to be a str, received: {}".format(type(unit_tag_)) + ) self.destroy_storage = destroy_storage_ self.dry_run = dry_run_ @@ -6780,72 +10997,113 @@ def __init__(self, destroy_storage=None, dry_run=None, force=None, max_wait=None self.unknown_fields = unknown_fields - class DestroyUnitResult(Type): - _toSchema = {'error': 'error', 'info': 'info'} - _toPy = {'error': 'error', 'info': 'info'} + _toSchema = {"error": "error", "info": "info"} + _toPy = {"error": "error", "info": "info"} + def __init__(self, error=None, info=None, **unknown_fields): - ''' + """ error : Error info : DestroyUnitInfo - ''' + """ error_ = Error.from_json(error) if error else None info_ = DestroyUnitInfo.from_json(info) if info else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if info_ is not None and not isinstance(info_, (dict, DestroyUnitInfo)): - raise Exception("Expected info_ to be a DestroyUnitInfo, received: {}".format(type(info_))) + raise Exception( + "Expected info_ to be a DestroyUnitInfo, received: {}".format( + type(info_) + ) + ) self.error = error_ self.info = info_ self.unknown_fields = unknown_fields - class DestroyUnitResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~DestroyUnitResult] - ''' + """ results_ = [DestroyUnitResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class DestroyUnitsParams(Type): - _toSchema = {'units': 'units'} - _toPy = {'units': 'units'} + _toSchema = {"units": "units"} + _toPy = {"units": "units"} + def __init__(self, units=None, **unknown_fields): - ''' + """ units : typing.Sequence[~DestroyUnitParams] - ''' + """ units_ = [DestroyUnitParams.from_json(o) for o in units or []] # Validate arguments against known Juju API types. if units_ is not None and not isinstance(units_, (bytes, str, list)): - raise Exception("Expected units_ to be a Sequence, received: {}".format(type(units_))) + raise Exception( + "Expected units_ to be a Sequence, received: {}".format(type(units_)) + ) self.units = units_ self.unknown_fields = unknown_fields - class DetailedStatus(Type): - _toSchema = {'data': 'data', 'err': 'err', 'info': 'info', 'kind': 'kind', 'life': 'life', 'since': 'since', 'status': 'status', 'version': 'version'} - _toPy = {'data': 'data', 'err': 'err', 'info': 'info', 'kind': 'kind', 'life': 'life', 'since': 'since', 'status': 'status', 'version': 'version'} - def __init__(self, data=None, err=None, info=None, kind=None, life=None, since=None, status=None, version=None, **unknown_fields): - ''' + _toSchema = { + "data": "data", + "err": "err", + "info": "info", + "kind": "kind", + "life": "life", + "since": "since", + "status": "status", + "version": "version", + } + _toPy = { + "data": "data", + "err": "err", + "info": "info", + "kind": "kind", + "life": "life", + "since": "since", + "status": "status", + "version": "version", + } + + def __init__( + self, + data=None, + err=None, + info=None, + kind=None, + life=None, + since=None, + status=None, + version=None, + **unknown_fields, + ): + """ data : typing.Mapping[str, typing.Any] err : Error info : str @@ -6854,7 +11112,7 @@ def __init__(self, data=None, err=None, info=None, kind=None, life=None, since=N since : str status : str version : str - ''' + """ data_ = data err_ = Error.from_json(err) if err else None info_ = info @@ -6866,28 +11124,44 @@ def __init__(self, data=None, err=None, info=None, kind=None, life=None, since=N # Validate arguments against known Juju API types. if data_ is not None and not isinstance(data_, dict): - raise Exception("Expected data_ to be a Mapping, received: {}".format(type(data_))) + raise Exception( + "Expected data_ to be a Mapping, received: {}".format(type(data_)) + ) if err_ is not None and not isinstance(err_, (dict, Error)): - raise Exception("Expected err_ to be a Error, received: {}".format(type(err_))) + raise Exception( + "Expected err_ to be a Error, received: {}".format(type(err_)) + ) if info_ is not None and not isinstance(info_, (bytes, str)): - raise Exception("Expected info_ to be a str, received: {}".format(type(info_))) + raise Exception( + "Expected info_ to be a str, received: {}".format(type(info_)) + ) if kind_ is not None and not isinstance(kind_, (bytes, str)): - raise Exception("Expected kind_ to be a str, received: {}".format(type(kind_))) + raise Exception( + "Expected kind_ to be a str, received: {}".format(type(kind_)) + ) if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception("Expected life_ to be a str, received: {}".format(type(life_))) + raise Exception( + "Expected life_ to be a str, received: {}".format(type(life_)) + ) if since_ is not None and not isinstance(since_, (bytes, str)): - raise Exception("Expected since_ to be a str, received: {}".format(type(since_))) + raise Exception( + "Expected since_ to be a str, received: {}".format(type(since_)) + ) if status_ is not None and not isinstance(status_, (bytes, str)): - raise Exception("Expected status_ to be a str, received: {}".format(type(status_))) + raise Exception( + "Expected status_ to be a str, received: {}".format(type(status_)) + ) if version_ is not None and not isinstance(version_, (bytes, str)): - raise Exception("Expected version_ to be a str, received: {}".format(type(version_))) + raise Exception( + "Expected version_ to be a str, received: {}".format(type(version_)) + ) self.data = data_ self.err = err_ @@ -6900,95 +11174,121 @@ def __init__(self, data=None, err=None, info=None, kind=None, life=None, since=N self.unknown_fields = unknown_fields - class DownloadInfoResult(Type): - _toSchema = {'charm_origin': 'charm-origin', 'url': 'url'} - _toPy = {'charm-origin': 'charm_origin', 'url': 'url'} + _toSchema = {"charm_origin": "charm-origin", "url": "url"} + _toPy = {"charm-origin": "charm_origin", "url": "url"} + def __init__(self, charm_origin=None, url=None, **unknown_fields): - ''' + """ charm_origin : CharmOrigin url : str - ''' + """ charm_origin_ = CharmOrigin.from_json(charm_origin) if charm_origin else None url_ = url # Validate arguments against known Juju API types. - if charm_origin_ is not None and not isinstance(charm_origin_, (dict, CharmOrigin)): - raise Exception("Expected charm_origin_ to be a CharmOrigin, received: {}".format(type(charm_origin_))) + if charm_origin_ is not None and not isinstance( + charm_origin_, (dict, CharmOrigin) + ): + raise Exception( + "Expected charm_origin_ to be a CharmOrigin, received: {}".format( + type(charm_origin_) + ) + ) if url_ is not None and not isinstance(url_, (bytes, str)): - raise Exception("Expected url_ to be a str, received: {}".format(type(url_))) + raise Exception( + "Expected url_ to be a str, received: {}".format(type(url_)) + ) self.charm_origin = charm_origin_ self.url = url_ self.unknown_fields = unknown_fields - class DownloadInfoResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~DownloadInfoResult] - ''' + """ results_ = [DownloadInfoResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class DumpModelRequest(Type): - _toSchema = {'entities': 'entities', 'simplified': 'simplified'} - _toPy = {'entities': 'entities', 'simplified': 'simplified'} + _toSchema = {"entities": "entities", "simplified": "simplified"} + _toPy = {"entities": "entities", "simplified": "simplified"} + def __init__(self, entities=None, simplified=None, **unknown_fields): - ''' + """ entities : typing.Sequence[~Entity] simplified : bool - ''' + """ entities_ = [Entity.from_json(o) for o in entities or []] simplified_ = simplified # Validate arguments against known Juju API types. if entities_ is not None and not isinstance(entities_, (bytes, str, list)): - raise Exception("Expected entities_ to be a Sequence, received: {}".format(type(entities_))) + raise Exception( + "Expected entities_ to be a Sequence, received: {}".format( + type(entities_) + ) + ) if simplified_ is not None and not isinstance(simplified_, bool): - raise Exception("Expected simplified_ to be a bool, received: {}".format(type(simplified_))) + raise Exception( + "Expected simplified_ to be a bool, received: {}".format( + type(simplified_) + ) + ) self.entities = entities_ self.simplified = simplified_ self.unknown_fields = unknown_fields - class EndpointFilterAttributes(Type): - _toSchema = {'interface': 'interface', 'name': 'name', 'role': 'role'} - _toPy = {'interface': 'interface', 'name': 'name', 'role': 'role'} + _toSchema = {"interface": "interface", "name": "name", "role": "role"} + _toPy = {"interface": "interface", "name": "name", "role": "role"} + def __init__(self, interface=None, name=None, role=None, **unknown_fields): - ''' + """ interface : str name : str role : str - ''' + """ interface_ = interface name_ = name role_ = role # Validate arguments against known Juju API types. if interface_ is not None and not isinstance(interface_, (bytes, str)): - raise Exception("Expected interface_ to be a str, received: {}".format(type(interface_))) + raise Exception( + "Expected interface_ to be a str, received: {}".format(type(interface_)) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if role_ is not None and not isinstance(role_, (bytes, str)): - raise Exception("Expected role_ to be a str, received: {}".format(type(role_))) + raise Exception( + "Expected role_ to be a str, received: {}".format(type(role_)) + ) self.interface = interface_ self.name = name_ @@ -6996,44 +11296,96 @@ def __init__(self, interface=None, name=None, role=None, **unknown_fields): self.unknown_fields = unknown_fields - class EndpointRelationData(Type): - _toSchema = {'applicationdata': 'ApplicationData', 'cross_model': 'cross-model', 'endpoint': 'endpoint', 'related_endpoint': 'related-endpoint', 'relation_id': 'relation-id', 'unit_relation_data': 'unit-relation-data'} - _toPy = {'ApplicationData': 'applicationdata', 'cross-model': 'cross_model', 'endpoint': 'endpoint', 'related-endpoint': 'related_endpoint', 'relation-id': 'relation_id', 'unit-relation-data': 'unit_relation_data'} - def __init__(self, applicationdata=None, cross_model=None, endpoint=None, related_endpoint=None, relation_id=None, unit_relation_data=None, **unknown_fields): - ''' + _toSchema = { + "applicationdata": "ApplicationData", + "cross_model": "cross-model", + "endpoint": "endpoint", + "related_endpoint": "related-endpoint", + "relation_id": "relation-id", + "unit_relation_data": "unit-relation-data", + } + _toPy = { + "ApplicationData": "applicationdata", + "cross-model": "cross_model", + "endpoint": "endpoint", + "related-endpoint": "related_endpoint", + "relation-id": "relation_id", + "unit-relation-data": "unit_relation_data", + } + + def __init__( + self, + applicationdata=None, + cross_model=None, + endpoint=None, + related_endpoint=None, + relation_id=None, + unit_relation_data=None, + **unknown_fields, + ): + """ applicationdata : typing.Mapping[str, typing.Any] cross_model : bool endpoint : str related_endpoint : str relation_id : int unit_relation_data : typing.Mapping[str, ~RelationData] - ''' + """ applicationdata_ = applicationdata cross_model_ = cross_model endpoint_ = endpoint related_endpoint_ = related_endpoint relation_id_ = relation_id - unit_relation_data_ = {k: RelationData.from_json(v) for k, v in (unit_relation_data or dict()).items()} + unit_relation_data_ = { + k: RelationData.from_json(v) + for k, v in (unit_relation_data or dict()).items() + } # Validate arguments against known Juju API types. if applicationdata_ is not None and not isinstance(applicationdata_, dict): - raise Exception("Expected applicationdata_ to be a Mapping, received: {}".format(type(applicationdata_))) + raise Exception( + "Expected applicationdata_ to be a Mapping, received: {}".format( + type(applicationdata_) + ) + ) if cross_model_ is not None and not isinstance(cross_model_, bool): - raise Exception("Expected cross_model_ to be a bool, received: {}".format(type(cross_model_))) + raise Exception( + "Expected cross_model_ to be a bool, received: {}".format( + type(cross_model_) + ) + ) if endpoint_ is not None and not isinstance(endpoint_, (bytes, str)): - raise Exception("Expected endpoint_ to be a str, received: {}".format(type(endpoint_))) - - if related_endpoint_ is not None and not isinstance(related_endpoint_, (bytes, str)): - raise Exception("Expected related_endpoint_ to be a str, received: {}".format(type(related_endpoint_))) + raise Exception( + "Expected endpoint_ to be a str, received: {}".format(type(endpoint_)) + ) + + if related_endpoint_ is not None and not isinstance( + related_endpoint_, (bytes, str) + ): + raise Exception( + "Expected related_endpoint_ to be a str, received: {}".format( + type(related_endpoint_) + ) + ) if relation_id_ is not None and not isinstance(relation_id_, int): - raise Exception("Expected relation_id_ to be a int, received: {}".format(type(relation_id_))) - - if unit_relation_data_ is not None and not isinstance(unit_relation_data_, dict): - raise Exception("Expected unit_relation_data_ to be a Mapping, received: {}".format(type(unit_relation_data_))) + raise Exception( + "Expected relation_id_ to be a int, received: {}".format( + type(relation_id_) + ) + ) + + if unit_relation_data_ is not None and not isinstance( + unit_relation_data_, dict + ): + raise Exception( + "Expected unit_relation_data_ to be a Mapping, received: {}".format( + type(unit_relation_data_) + ) + ) self.applicationdata = applicationdata_ self.cross_model = cross_model_ @@ -7044,17 +11396,29 @@ def __init__(self, applicationdata=None, cross_model=None, endpoint=None, relate self.unknown_fields = unknown_fields - class EndpointStatus(Type): - _toSchema = {'application': 'application', 'name': 'name', 'role': 'role', 'subordinate': 'subordinate'} - _toPy = {'application': 'application', 'name': 'name', 'role': 'role', 'subordinate': 'subordinate'} - def __init__(self, application=None, name=None, role=None, subordinate=None, **unknown_fields): - ''' + _toSchema = { + "application": "application", + "name": "name", + "role": "role", + "subordinate": "subordinate", + } + _toPy = { + "application": "application", + "name": "name", + "role": "role", + "subordinate": "subordinate", + } + + def __init__( + self, application=None, name=None, role=None, subordinate=None, **unknown_fields + ): + """ application : str name : str role : str subordinate : bool - ''' + """ application_ = application name_ = name role_ = role @@ -7062,16 +11426,28 @@ def __init__(self, application=None, name=None, role=None, subordinate=None, **u # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): - raise Exception("Expected application_ to be a str, received: {}".format(type(application_))) + raise Exception( + "Expected application_ to be a str, received: {}".format( + type(application_) + ) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if role_ is not None and not isinstance(role_, (bytes, str)): - raise Exception("Expected role_ to be a str, received: {}".format(type(role_))) + raise Exception( + "Expected role_ to be a str, received: {}".format(type(role_)) + ) if subordinate_ is not None and not isinstance(subordinate_, bool): - raise Exception("Expected subordinate_ to be a bool, received: {}".format(type(subordinate_))) + raise Exception( + "Expected subordinate_ to be a bool, received: {}".format( + type(subordinate_) + ) + ) self.application = application_ self.name = name_ @@ -7080,167 +11456,199 @@ def __init__(self, application=None, name=None, role=None, subordinate=None, **u self.unknown_fields = unknown_fields - class EnqueuedActions(Type): - _toSchema = {'actions': 'actions', 'operation': 'operation'} - _toPy = {'actions': 'actions', 'operation': 'operation'} + _toSchema = {"actions": "actions", "operation": "operation"} + _toPy = {"actions": "actions", "operation": "operation"} + def __init__(self, actions=None, operation=None, **unknown_fields): - ''' + """ actions : typing.Sequence[~ActionResult] operation : str - ''' + """ actions_ = [ActionResult.from_json(o) for o in actions or []] operation_ = operation # Validate arguments against known Juju API types. if actions_ is not None and not isinstance(actions_, (bytes, str, list)): - raise Exception("Expected actions_ to be a Sequence, received: {}".format(type(actions_))) + raise Exception( + "Expected actions_ to be a Sequence, received: {}".format( + type(actions_) + ) + ) if operation_ is not None and not isinstance(operation_, (bytes, str)): - raise Exception("Expected operation_ to be a str, received: {}".format(type(operation_))) + raise Exception( + "Expected operation_ to be a str, received: {}".format(type(operation_)) + ) self.actions = actions_ self.operation = operation_ self.unknown_fields = unknown_fields - class Entities(Type): - _toSchema = {'entities': 'entities'} - _toPy = {'entities': 'entities'} + _toSchema = {"entities": "entities"} + _toPy = {"entities": "entities"} + def __init__(self, entities=None, **unknown_fields): - ''' + """ entities : typing.Sequence[~Entity] - ''' + """ entities_ = [Entity.from_json(o) for o in entities or []] # Validate arguments against known Juju API types. if entities_ is not None and not isinstance(entities_, (bytes, str, list)): - raise Exception("Expected entities_ to be a Sequence, received: {}".format(type(entities_))) + raise Exception( + "Expected entities_ to be a Sequence, received: {}".format( + type(entities_) + ) + ) self.entities = entities_ self.unknown_fields = unknown_fields - class Entity(Type): - _toSchema = {'tag': 'tag'} - _toPy = {'tag': 'tag'} + _toSchema = {"tag": "tag"} + _toPy = {"tag": "tag"} + def __init__(self, tag=None, **unknown_fields): - ''' + """ tag : str - ''' + """ tag_ = tag # Validate arguments against known Juju API types. if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception("Expected tag_ to be a str, received: {}".format(type(tag_))) + raise Exception( + "Expected tag_ to be a str, received: {}".format(type(tag_)) + ) self.tag = tag_ self.unknown_fields = unknown_fields - class EntityAnnotations(Type): - _toSchema = {'annotations': 'annotations', 'entity': 'entity'} - _toPy = {'annotations': 'annotations', 'entity': 'entity'} + _toSchema = {"annotations": "annotations", "entity": "entity"} + _toPy = {"annotations": "annotations", "entity": "entity"} + def __init__(self, annotations=None, entity=None, **unknown_fields): - ''' + """ annotations : typing.Mapping[str, str] entity : str - ''' + """ annotations_ = annotations entity_ = entity # Validate arguments against known Juju API types. if annotations_ is not None and not isinstance(annotations_, dict): - raise Exception("Expected annotations_ to be a Mapping, received: {}".format(type(annotations_))) + raise Exception( + "Expected annotations_ to be a Mapping, received: {}".format( + type(annotations_) + ) + ) if entity_ is not None and not isinstance(entity_, (bytes, str)): - raise Exception("Expected entity_ to be a str, received: {}".format(type(entity_))) + raise Exception( + "Expected entity_ to be a str, received: {}".format(type(entity_)) + ) self.annotations = annotations_ self.entity = entity_ self.unknown_fields = unknown_fields - class EntityMetrics(Type): - _toSchema = {'error': 'error', 'metrics': 'metrics'} - _toPy = {'error': 'error', 'metrics': 'metrics'} + _toSchema = {"error": "error", "metrics": "metrics"} + _toPy = {"error": "error", "metrics": "metrics"} + def __init__(self, error=None, metrics=None, **unknown_fields): - ''' + """ error : Error metrics : typing.Sequence[~MetricResult] - ''' + """ error_ = Error.from_json(error) if error else None metrics_ = [MetricResult.from_json(o) for o in metrics or []] # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if metrics_ is not None and not isinstance(metrics_, (bytes, str, list)): - raise Exception("Expected metrics_ to be a Sequence, received: {}".format(type(metrics_))) + raise Exception( + "Expected metrics_ to be a Sequence, received: {}".format( + type(metrics_) + ) + ) self.error = error_ self.metrics = metrics_ self.unknown_fields = unknown_fields - class EntityPassword(Type): - _toSchema = {'password': 'password', 'tag': 'tag'} - _toPy = {'password': 'password', 'tag': 'tag'} + _toSchema = {"password": "password", "tag": "tag"} + _toPy = {"password": "password", "tag": "tag"} + def __init__(self, password=None, tag=None, **unknown_fields): - ''' + """ password : str tag : str - ''' + """ password_ = password tag_ = tag # Validate arguments against known Juju API types. if password_ is not None and not isinstance(password_, (bytes, str)): - raise Exception("Expected password_ to be a str, received: {}".format(type(password_))) + raise Exception( + "Expected password_ to be a str, received: {}".format(type(password_)) + ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception("Expected tag_ to be a str, received: {}".format(type(tag_))) + raise Exception( + "Expected tag_ to be a str, received: {}".format(type(tag_)) + ) self.password = password_ self.tag = tag_ self.unknown_fields = unknown_fields - class EntityPasswords(Type): - _toSchema = {'changes': 'changes'} - _toPy = {'changes': 'changes'} + _toSchema = {"changes": "changes"} + _toPy = {"changes": "changes"} + def __init__(self, changes=None, **unknown_fields): - ''' + """ changes : typing.Sequence[~EntityPassword] - ''' + """ changes_ = [EntityPassword.from_json(o) for o in changes or []] # Validate arguments against known Juju API types. if changes_ is not None and not isinstance(changes_, (bytes, str, list)): - raise Exception("Expected changes_ to be a Sequence, received: {}".format(type(changes_))) + raise Exception( + "Expected changes_ to be a Sequence, received: {}".format( + type(changes_) + ) + ) self.changes = changes_ self.unknown_fields = unknown_fields - class EntityStatus(Type): - _toSchema = {'data': 'data', 'info': 'info', 'since': 'since', 'status': 'status'} - _toPy = {'data': 'data', 'info': 'info', 'since': 'since', 'status': 'status'} + _toSchema = {"data": "data", "info": "info", "since": "since", "status": "status"} + _toPy = {"data": "data", "info": "info", "since": "since", "status": "status"} + def __init__(self, data=None, info=None, since=None, status=None, **unknown_fields): - ''' + """ data : typing.Mapping[str, typing.Any] info : str since : str status : str - ''' + """ data_ = data info_ = info since_ = since @@ -7248,16 +11656,24 @@ def __init__(self, data=None, info=None, since=None, status=None, **unknown_fiel # Validate arguments against known Juju API types. if data_ is not None and not isinstance(data_, dict): - raise Exception("Expected data_ to be a Mapping, received: {}".format(type(data_))) + raise Exception( + "Expected data_ to be a Mapping, received: {}".format(type(data_)) + ) if info_ is not None and not isinstance(info_, (bytes, str)): - raise Exception("Expected info_ to be a str, received: {}".format(type(info_))) + raise Exception( + "Expected info_ to be a str, received: {}".format(type(info_)) + ) if since_ is not None and not isinstance(since_, (bytes, str)): - raise Exception("Expected since_ to be a str, received: {}".format(type(since_))) + raise Exception( + "Expected since_ to be a str, received: {}".format(type(since_)) + ) if status_ is not None and not isinstance(status_, (bytes, str)): - raise Exception("Expected status_ to be a str, received: {}".format(type(status_))) + raise Exception( + "Expected status_ to be a str, received: {}".format(type(status_)) + ) self.data = data_ self.info = info_ @@ -7266,29 +11682,35 @@ def __init__(self, data=None, info=None, since=None, status=None, **unknown_fiel self.unknown_fields = unknown_fields - class Error(Type): - _toSchema = {'code': 'code', 'info': 'info', 'message': 'message'} - _toPy = {'code': 'code', 'info': 'info', 'message': 'message'} + _toSchema = {"code": "code", "info": "info", "message": "message"} + _toPy = {"code": "code", "info": "info", "message": "message"} + def __init__(self, code=None, info=None, message=None, **unknown_fields): - ''' + """ code : str info : typing.Mapping[str, typing.Any] message : str - ''' + """ code_ = code info_ = info message_ = message # Validate arguments against known Juju API types. if code_ is not None and not isinstance(code_, (bytes, str)): - raise Exception("Expected code_ to be a str, received: {}".format(type(code_))) + raise Exception( + "Expected code_ to be a str, received: {}".format(type(code_)) + ) if info_ is not None and not isinstance(info_, dict): - raise Exception("Expected info_ to be a Mapping, received: {}".format(type(info_))) + raise Exception( + "Expected info_ to be a Mapping, received: {}".format(type(info_)) + ) if message_ is not None and not isinstance(message_, (bytes, str)): - raise Exception("Expected message_ to be a str, received: {}".format(type(message_))) + raise Exception( + "Expected message_ to be a str, received: {}".format(type(message_)) + ) self.code = code_ self.info = info_ @@ -7296,98 +11718,140 @@ def __init__(self, code=None, info=None, message=None, **unknown_fields): self.unknown_fields = unknown_fields - class ErrorResult(Type): - _toSchema = {'error': 'error'} - _toPy = {'error': 'error'} + _toSchema = {"error": "error"} + _toPy = {"error": "error"} + def __init__(self, error=None, **unknown_fields): - ''' + """ error : Error - ''' + """ error_ = Error.from_json(error) if error else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) self.error = error_ self.unknown_fields = unknown_fields - class ErrorResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~ErrorResult] - ''' + """ results_ = [ErrorResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class ExportBundleParams(Type): - _toSchema = {'include_charm_defaults': 'include-charm-defaults', 'include_series': 'include-series'} - _toPy = {'include-charm-defaults': 'include_charm_defaults', 'include-series': 'include_series'} - def __init__(self, include_charm_defaults=None, include_series=None, **unknown_fields): - ''' + _toSchema = { + "include_charm_defaults": "include-charm-defaults", + "include_series": "include-series", + } + _toPy = { + "include-charm-defaults": "include_charm_defaults", + "include-series": "include_series", + } + + def __init__( + self, include_charm_defaults=None, include_series=None, **unknown_fields + ): + """ include_charm_defaults : bool include_series : bool - ''' + """ include_charm_defaults_ = include_charm_defaults include_series_ = include_series # Validate arguments against known Juju API types. - if include_charm_defaults_ is not None and not isinstance(include_charm_defaults_, bool): - raise Exception("Expected include_charm_defaults_ to be a bool, received: {}".format(type(include_charm_defaults_))) + if include_charm_defaults_ is not None and not isinstance( + include_charm_defaults_, bool + ): + raise Exception( + "Expected include_charm_defaults_ to be a bool, received: {}".format( + type(include_charm_defaults_) + ) + ) if include_series_ is not None and not isinstance(include_series_, bool): - raise Exception("Expected include_series_ to be a bool, received: {}".format(type(include_series_))) + raise Exception( + "Expected include_series_ to be a bool, received: {}".format( + type(include_series_) + ) + ) self.include_charm_defaults = include_charm_defaults_ self.include_series = include_series_ self.unknown_fields = unknown_fields - class ExposedEndpoint(Type): - _toSchema = {'expose_to_cidrs': 'expose-to-cidrs', 'expose_to_spaces': 'expose-to-spaces'} - _toPy = {'expose-to-cidrs': 'expose_to_cidrs', 'expose-to-spaces': 'expose_to_spaces'} + _toSchema = { + "expose_to_cidrs": "expose-to-cidrs", + "expose_to_spaces": "expose-to-spaces", + } + _toPy = { + "expose-to-cidrs": "expose_to_cidrs", + "expose-to-spaces": "expose_to_spaces", + } + def __init__(self, expose_to_cidrs=None, expose_to_spaces=None, **unknown_fields): - ''' + """ expose_to_cidrs : typing.Sequence[str] expose_to_spaces : typing.Sequence[str] - ''' + """ expose_to_cidrs_ = expose_to_cidrs expose_to_spaces_ = expose_to_spaces # Validate arguments against known Juju API types. - if expose_to_cidrs_ is not None and not isinstance(expose_to_cidrs_, (bytes, str, list)): - raise Exception("Expected expose_to_cidrs_ to be a Sequence, received: {}".format(type(expose_to_cidrs_))) - - if expose_to_spaces_ is not None and not isinstance(expose_to_spaces_, (bytes, str, list)): - raise Exception("Expected expose_to_spaces_ to be a Sequence, received: {}".format(type(expose_to_spaces_))) + if expose_to_cidrs_ is not None and not isinstance( + expose_to_cidrs_, (bytes, str, list) + ): + raise Exception( + "Expected expose_to_cidrs_ to be a Sequence, received: {}".format( + type(expose_to_cidrs_) + ) + ) + + if expose_to_spaces_ is not None and not isinstance( + expose_to_spaces_, (bytes, str, list) + ): + raise Exception( + "Expected expose_to_spaces_ to be a Sequence, received: {}".format( + type(expose_to_spaces_) + ) + ) self.expose_to_cidrs = expose_to_cidrs_ self.expose_to_spaces = expose_to_spaces_ self.unknown_fields = unknown_fields - class ExpressionTree(Type): - _toSchema = {'expression': 'Expression'} - _toPy = {'Expression': 'expression'} + _toSchema = {"expression": "Expression"} + _toPy = {"Expression": "expression"} + def __init__(self, expression=None, **unknown_fields): - ''' + """ expression : Any - ''' + """ expression_ = expression # Validate arguments against known Juju API types. @@ -7395,17 +11859,34 @@ def __init__(self, expression=None, **unknown_fields): self.unknown_fields = unknown_fields - class ExternalControllerInfo(Type): - _toSchema = {'addrs': 'addrs', 'ca_cert': 'ca-cert', 'controller_alias': 'controller-alias', 'controller_tag': 'controller-tag'} - _toPy = {'addrs': 'addrs', 'ca-cert': 'ca_cert', 'controller-alias': 'controller_alias', 'controller-tag': 'controller_tag'} - def __init__(self, addrs=None, ca_cert=None, controller_alias=None, controller_tag=None, **unknown_fields): - ''' + _toSchema = { + "addrs": "addrs", + "ca_cert": "ca-cert", + "controller_alias": "controller-alias", + "controller_tag": "controller-tag", + } + _toPy = { + "addrs": "addrs", + "ca-cert": "ca_cert", + "controller-alias": "controller_alias", + "controller-tag": "controller_tag", + } + + def __init__( + self, + addrs=None, + ca_cert=None, + controller_alias=None, + controller_tag=None, + **unknown_fields, + ): + """ addrs : typing.Sequence[str] ca_cert : str controller_alias : str controller_tag : str - ''' + """ addrs_ = addrs ca_cert_ = ca_cert controller_alias_ = controller_alias @@ -7413,16 +11894,32 @@ def __init__(self, addrs=None, ca_cert=None, controller_alias=None, controller_t # Validate arguments against known Juju API types. if addrs_ is not None and not isinstance(addrs_, (bytes, str, list)): - raise Exception("Expected addrs_ to be a Sequence, received: {}".format(type(addrs_))) + raise Exception( + "Expected addrs_ to be a Sequence, received: {}".format(type(addrs_)) + ) if ca_cert_ is not None and not isinstance(ca_cert_, (bytes, str)): - raise Exception("Expected ca_cert_ to be a str, received: {}".format(type(ca_cert_))) - - if controller_alias_ is not None and not isinstance(controller_alias_, (bytes, str)): - raise Exception("Expected controller_alias_ to be a str, received: {}".format(type(controller_alias_))) - - if controller_tag_ is not None and not isinstance(controller_tag_, (bytes, str)): - raise Exception("Expected controller_tag_ to be a str, received: {}".format(type(controller_tag_))) + raise Exception( + "Expected ca_cert_ to be a str, received: {}".format(type(ca_cert_)) + ) + + if controller_alias_ is not None and not isinstance( + controller_alias_, (bytes, str) + ): + raise Exception( + "Expected controller_alias_ to be a str, received: {}".format( + type(controller_alias_) + ) + ) + + if controller_tag_ is not None and not isinstance( + controller_tag_, (bytes, str) + ): + raise Exception( + "Expected controller_tag_ to be a str, received: {}".format( + type(controller_tag_) + ) + ) self.addrs = addrs_ self.ca_cert = ca_cert_ @@ -7431,34 +11928,71 @@ def __init__(self, addrs=None, ca_cert=None, controller_alias=None, controller_t self.unknown_fields = unknown_fields - class FilesystemAttachmentDetails(Type): - _toSchema = {'filesystemattachmentinfo': 'FilesystemAttachmentInfo', 'life': 'life', 'mount_point': 'mount-point', 'read_only': 'read-only'} - _toPy = {'FilesystemAttachmentInfo': 'filesystemattachmentinfo', 'life': 'life', 'mount-point': 'mount_point', 'read-only': 'read_only'} - def __init__(self, filesystemattachmentinfo=None, life=None, mount_point=None, read_only=None, **unknown_fields): - ''' + _toSchema = { + "filesystemattachmentinfo": "FilesystemAttachmentInfo", + "life": "life", + "mount_point": "mount-point", + "read_only": "read-only", + } + _toPy = { + "FilesystemAttachmentInfo": "filesystemattachmentinfo", + "life": "life", + "mount-point": "mount_point", + "read-only": "read_only", + } + + def __init__( + self, + filesystemattachmentinfo=None, + life=None, + mount_point=None, + read_only=None, + **unknown_fields, + ): + """ filesystemattachmentinfo : FilesystemAttachmentInfo life : str mount_point : str read_only : bool - ''' - filesystemattachmentinfo_ = FilesystemAttachmentInfo.from_json(filesystemattachmentinfo) if filesystemattachmentinfo else None + """ + filesystemattachmentinfo_ = ( + FilesystemAttachmentInfo.from_json(filesystemattachmentinfo) + if filesystemattachmentinfo + else None + ) life_ = life mount_point_ = mount_point read_only_ = read_only # Validate arguments against known Juju API types. - if filesystemattachmentinfo_ is not None and not isinstance(filesystemattachmentinfo_, (dict, FilesystemAttachmentInfo)): - raise Exception("Expected filesystemattachmentinfo_ to be a FilesystemAttachmentInfo, received: {}".format(type(filesystemattachmentinfo_))) + if filesystemattachmentinfo_ is not None and not isinstance( + filesystemattachmentinfo_, (dict, FilesystemAttachmentInfo) + ): + raise Exception( + "Expected filesystemattachmentinfo_ to be a FilesystemAttachmentInfo, received: {}".format( + type(filesystemattachmentinfo_) + ) + ) if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception("Expected life_ to be a str, received: {}".format(type(life_))) + raise Exception( + "Expected life_ to be a str, received: {}".format(type(life_)) + ) if mount_point_ is not None and not isinstance(mount_point_, (bytes, str)): - raise Exception("Expected mount_point_ to be a str, received: {}".format(type(mount_point_))) + raise Exception( + "Expected mount_point_ to be a str, received: {}".format( + type(mount_point_) + ) + ) if read_only_ is not None and not isinstance(read_only_, bool): - raise Exception("Expected read_only_ to be a bool, received: {}".format(type(read_only_))) + raise Exception( + "Expected read_only_ to be a bool, received: {}".format( + type(read_only_) + ) + ) self.filesystemattachmentinfo = filesystemattachmentinfo_ self.life = life_ @@ -7467,36 +12001,73 @@ def __init__(self, filesystemattachmentinfo=None, life=None, mount_point=None, r self.unknown_fields = unknown_fields - class FilesystemAttachmentInfo(Type): - _toSchema = {'mount_point': 'mount-point', 'read_only': 'read-only'} - _toPy = {'mount-point': 'mount_point', 'read-only': 'read_only'} + _toSchema = {"mount_point": "mount-point", "read_only": "read-only"} + _toPy = {"mount-point": "mount_point", "read-only": "read_only"} + def __init__(self, mount_point=None, read_only=None, **unknown_fields): - ''' + """ mount_point : str read_only : bool - ''' + """ mount_point_ = mount_point read_only_ = read_only # Validate arguments against known Juju API types. if mount_point_ is not None and not isinstance(mount_point_, (bytes, str)): - raise Exception("Expected mount_point_ to be a str, received: {}".format(type(mount_point_))) + raise Exception( + "Expected mount_point_ to be a str, received: {}".format( + type(mount_point_) + ) + ) if read_only_ is not None and not isinstance(read_only_, bool): - raise Exception("Expected read_only_ to be a bool, received: {}".format(type(read_only_))) + raise Exception( + "Expected read_only_ to be a bool, received: {}".format( + type(read_only_) + ) + ) self.mount_point = mount_point_ self.read_only = read_only_ self.unknown_fields = unknown_fields - class FilesystemDetails(Type): - _toSchema = {'filesystem_tag': 'filesystem-tag', 'info': 'info', 'life': 'life', 'machine_attachments': 'machine-attachments', 'status': 'status', 'storage': 'storage', 'unit_attachments': 'unit-attachments', 'volume_tag': 'volume-tag'} - _toPy = {'filesystem-tag': 'filesystem_tag', 'info': 'info', 'life': 'life', 'machine-attachments': 'machine_attachments', 'status': 'status', 'storage': 'storage', 'unit-attachments': 'unit_attachments', 'volume-tag': 'volume_tag'} - def __init__(self, filesystem_tag=None, info=None, life=None, machine_attachments=None, status=None, storage=None, unit_attachments=None, volume_tag=None, **unknown_fields): - ''' + _toSchema = { + "filesystem_tag": "filesystem-tag", + "info": "info", + "life": "life", + "machine_attachments": "machine-attachments", + "status": "status", + "storage": "storage", + "unit_attachments": "unit-attachments", + "volume_tag": "volume-tag", + } + _toPy = { + "filesystem-tag": "filesystem_tag", + "info": "info", + "life": "life", + "machine-attachments": "machine_attachments", + "status": "status", + "storage": "storage", + "unit-attachments": "unit_attachments", + "volume-tag": "volume_tag", + } + + def __init__( + self, + filesystem_tag=None, + info=None, + life=None, + machine_attachments=None, + status=None, + storage=None, + unit_attachments=None, + volume_tag=None, + **unknown_fields, + ): + """ filesystem_tag : str info : FilesystemInfo life : str @@ -7505,40 +12076,80 @@ def __init__(self, filesystem_tag=None, info=None, life=None, machine_attachment storage : StorageDetails unit_attachments : typing.Mapping[str, ~FilesystemAttachmentDetails] volume_tag : str - ''' + """ filesystem_tag_ = filesystem_tag info_ = FilesystemInfo.from_json(info) if info else None life_ = life - machine_attachments_ = {k: FilesystemAttachmentDetails.from_json(v) for k, v in (machine_attachments or dict()).items()} + machine_attachments_ = { + k: FilesystemAttachmentDetails.from_json(v) + for k, v in (machine_attachments or dict()).items() + } status_ = EntityStatus.from_json(status) if status else None storage_ = StorageDetails.from_json(storage) if storage else None - unit_attachments_ = {k: FilesystemAttachmentDetails.from_json(v) for k, v in (unit_attachments or dict()).items()} + unit_attachments_ = { + k: FilesystemAttachmentDetails.from_json(v) + for k, v in (unit_attachments or dict()).items() + } volume_tag_ = volume_tag # Validate arguments against known Juju API types. - if filesystem_tag_ is not None and not isinstance(filesystem_tag_, (bytes, str)): - raise Exception("Expected filesystem_tag_ to be a str, received: {}".format(type(filesystem_tag_))) + if filesystem_tag_ is not None and not isinstance( + filesystem_tag_, (bytes, str) + ): + raise Exception( + "Expected filesystem_tag_ to be a str, received: {}".format( + type(filesystem_tag_) + ) + ) if info_ is not None and not isinstance(info_, (dict, FilesystemInfo)): - raise Exception("Expected info_ to be a FilesystemInfo, received: {}".format(type(info_))) + raise Exception( + "Expected info_ to be a FilesystemInfo, received: {}".format( + type(info_) + ) + ) if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception("Expected life_ to be a str, received: {}".format(type(life_))) - - if machine_attachments_ is not None and not isinstance(machine_attachments_, dict): - raise Exception("Expected machine_attachments_ to be a Mapping, received: {}".format(type(machine_attachments_))) + raise Exception( + "Expected life_ to be a str, received: {}".format(type(life_)) + ) + + if machine_attachments_ is not None and not isinstance( + machine_attachments_, dict + ): + raise Exception( + "Expected machine_attachments_ to be a Mapping, received: {}".format( + type(machine_attachments_) + ) + ) if status_ is not None and not isinstance(status_, (dict, EntityStatus)): - raise Exception("Expected status_ to be a EntityStatus, received: {}".format(type(status_))) + raise Exception( + "Expected status_ to be a EntityStatus, received: {}".format( + type(status_) + ) + ) if storage_ is not None and not isinstance(storage_, (dict, StorageDetails)): - raise Exception("Expected storage_ to be a StorageDetails, received: {}".format(type(storage_))) + raise Exception( + "Expected storage_ to be a StorageDetails, received: {}".format( + type(storage_) + ) + ) if unit_attachments_ is not None and not isinstance(unit_attachments_, dict): - raise Exception("Expected unit_attachments_ to be a Mapping, received: {}".format(type(unit_attachments_))) + raise Exception( + "Expected unit_attachments_ to be a Mapping, received: {}".format( + type(unit_attachments_) + ) + ) if volume_tag_ is not None and not isinstance(volume_tag_, (bytes, str)): - raise Exception("Expected volume_tag_ to be a str, received: {}".format(type(volume_tag_))) + raise Exception( + "Expected volume_tag_ to be a str, received: {}".format( + type(volume_tag_) + ) + ) self.filesystem_tag = filesystem_tag_ self.info = info_ @@ -7551,107 +12162,131 @@ def __init__(self, filesystem_tag=None, info=None, life=None, machine_attachment self.unknown_fields = unknown_fields - class FilesystemDetailsListResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : typing.Sequence[~FilesystemDetails] - ''' + """ error_ = Error.from_json(error) if error else None result_ = [FilesystemDetails.from_json(o) for o in result or []] # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if result_ is not None and not isinstance(result_, (bytes, str, list)): - raise Exception("Expected result_ to be a Sequence, received: {}".format(type(result_))) + raise Exception( + "Expected result_ to be a Sequence, received: {}".format(type(result_)) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class FilesystemDetailsListResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~FilesystemDetailsListResult] - ''' + """ results_ = [FilesystemDetailsListResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class FilesystemFilter(Type): - _toSchema = {'machines': 'machines'} - _toPy = {'machines': 'machines'} + _toSchema = {"machines": "machines"} + _toPy = {"machines": "machines"} + def __init__(self, machines=None, **unknown_fields): - ''' + """ machines : typing.Sequence[str] - ''' + """ machines_ = machines # Validate arguments against known Juju API types. if machines_ is not None and not isinstance(machines_, (bytes, str, list)): - raise Exception("Expected machines_ to be a Sequence, received: {}".format(type(machines_))) + raise Exception( + "Expected machines_ to be a Sequence, received: {}".format( + type(machines_) + ) + ) self.machines = machines_ self.unknown_fields = unknown_fields - class FilesystemFilters(Type): - _toSchema = {'filters': 'filters'} - _toPy = {'filters': 'filters'} + _toSchema = {"filters": "filters"} + _toPy = {"filters": "filters"} + def __init__(self, filters=None, **unknown_fields): - ''' + """ filters : typing.Sequence[~FilesystemFilter] - ''' + """ filters_ = [FilesystemFilter.from_json(o) for o in filters or []] # Validate arguments against known Juju API types. if filters_ is not None and not isinstance(filters_, (bytes, str, list)): - raise Exception("Expected filters_ to be a Sequence, received: {}".format(type(filters_))) + raise Exception( + "Expected filters_ to be a Sequence, received: {}".format( + type(filters_) + ) + ) self.filters = filters_ self.unknown_fields = unknown_fields - class FilesystemInfo(Type): - _toSchema = {'filesystem_id': 'filesystem-id', 'pool': 'pool', 'size': 'size'} - _toPy = {'filesystem-id': 'filesystem_id', 'pool': 'pool', 'size': 'size'} + _toSchema = {"filesystem_id": "filesystem-id", "pool": "pool", "size": "size"} + _toPy = {"filesystem-id": "filesystem_id", "pool": "pool", "size": "size"} + def __init__(self, filesystem_id=None, pool=None, size=None, **unknown_fields): - ''' + """ filesystem_id : str pool : str size : int - ''' + """ filesystem_id_ = filesystem_id pool_ = pool size_ = size # Validate arguments against known Juju API types. if filesystem_id_ is not None and not isinstance(filesystem_id_, (bytes, str)): - raise Exception("Expected filesystem_id_ to be a str, received: {}".format(type(filesystem_id_))) + raise Exception( + "Expected filesystem_id_ to be a str, received: {}".format( + type(filesystem_id_) + ) + ) if pool_ is not None and not isinstance(pool_, (bytes, str)): - raise Exception("Expected pool_ to be a str, received: {}".format(type(pool_))) + raise Exception( + "Expected pool_ to be a str, received: {}".format(type(pool_)) + ) if size_ is not None and not isinstance(size_, int): - raise Exception("Expected size_ to be a int, received: {}".format(type(size_))) + raise Exception( + "Expected size_ to be a int, received: {}".format(type(size_)) + ) self.filesystem_id = filesystem_id_ self.pool = pool_ @@ -7659,18 +12294,38 @@ def __init__(self, filesystem_id=None, pool=None, size=None, **unknown_fields): self.unknown_fields = unknown_fields - class FindToolsParams(Type): - _toSchema = {'agentstream': 'agentstream', 'arch': 'arch', 'major': 'major', 'number': 'number', 'os_type': 'os-type'} - _toPy = {'agentstream': 'agentstream', 'arch': 'arch', 'major': 'major', 'number': 'number', 'os-type': 'os_type'} - def __init__(self, agentstream=None, arch=None, major=None, number=None, os_type=None, **unknown_fields): - ''' + _toSchema = { + "agentstream": "agentstream", + "arch": "arch", + "major": "major", + "number": "number", + "os_type": "os-type", + } + _toPy = { + "agentstream": "agentstream", + "arch": "arch", + "major": "major", + "number": "number", + "os-type": "os_type", + } + + def __init__( + self, + agentstream=None, + arch=None, + major=None, + number=None, + os_type=None, + **unknown_fields, + ): + """ agentstream : str arch : str major : int number : Number os_type : str - ''' + """ agentstream_ = agentstream arch_ = arch major_ = major @@ -7679,19 +12334,31 @@ def __init__(self, agentstream=None, arch=None, major=None, number=None, os_type # Validate arguments against known Juju API types. if agentstream_ is not None and not isinstance(agentstream_, (bytes, str)): - raise Exception("Expected agentstream_ to be a str, received: {}".format(type(agentstream_))) + raise Exception( + "Expected agentstream_ to be a str, received: {}".format( + type(agentstream_) + ) + ) if arch_ is not None and not isinstance(arch_, (bytes, str)): - raise Exception("Expected arch_ to be a str, received: {}".format(type(arch_))) + raise Exception( + "Expected arch_ to be a str, received: {}".format(type(arch_)) + ) if major_ is not None and not isinstance(major_, int): - raise Exception("Expected major_ to be a int, received: {}".format(type(major_))) + raise Exception( + "Expected major_ to be a int, received: {}".format(type(major_)) + ) if number_ is not None and not isinstance(number_, (dict, Number)): - raise Exception("Expected number_ to be a Number, received: {}".format(type(number_))) + raise Exception( + "Expected number_ to be a Number, received: {}".format(type(number_)) + ) if os_type_ is not None and not isinstance(os_type_, (bytes, str)): - raise Exception("Expected os_type_ to be a str, received: {}".format(type(os_type_))) + raise Exception( + "Expected os_type_ to be a str, received: {}".format(type(os_type_)) + ) self.agentstream = agentstream_ self.arch = arch_ @@ -7701,78 +12368,132 @@ def __init__(self, agentstream=None, arch=None, major=None, number=None, os_type self.unknown_fields = unknown_fields - class FindToolsResult(Type): - _toSchema = {'error': 'error', 'list_': 'list'} - _toPy = {'error': 'error', 'list': 'list_'} + _toSchema = {"error": "error", "list_": "list"} + _toPy = {"error": "error", "list": "list_"} + def __init__(self, error=None, list_=None, **unknown_fields): - ''' + """ error : Error list_ : typing.Sequence[~Tools] - ''' + """ error_ = Error.from_json(error) if error else None list__ = [Tools.from_json(o) for o in list_ or []] # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if list__ is not None and not isinstance(list__, (bytes, str, list)): - raise Exception("Expected list__ to be a Sequence, received: {}".format(type(list__))) + raise Exception( + "Expected list__ to be a Sequence, received: {}".format(type(list__)) + ) self.error = error_ self.list_ = list__ self.unknown_fields = unknown_fields - class FirewallRule(Type): - _toSchema = {'known_service': 'known-service', 'whitelist_cidrs': 'whitelist-cidrs'} - _toPy = {'known-service': 'known_service', 'whitelist-cidrs': 'whitelist_cidrs'} + _toSchema = {"known_service": "known-service", "whitelist_cidrs": "whitelist-cidrs"} + _toPy = {"known-service": "known_service", "whitelist-cidrs": "whitelist_cidrs"} + def __init__(self, known_service=None, whitelist_cidrs=None, **unknown_fields): - ''' + """ known_service : str whitelist_cidrs : typing.Sequence[str] - ''' + """ known_service_ = known_service whitelist_cidrs_ = whitelist_cidrs # Validate arguments against known Juju API types. if known_service_ is not None and not isinstance(known_service_, (bytes, str)): - raise Exception("Expected known_service_ to be a str, received: {}".format(type(known_service_))) - - if whitelist_cidrs_ is not None and not isinstance(whitelist_cidrs_, (bytes, str, list)): - raise Exception("Expected whitelist_cidrs_ to be a Sequence, received: {}".format(type(whitelist_cidrs_))) + raise Exception( + "Expected known_service_ to be a str, received: {}".format( + type(known_service_) + ) + ) + + if whitelist_cidrs_ is not None and not isinstance( + whitelist_cidrs_, (bytes, str, list) + ): + raise Exception( + "Expected whitelist_cidrs_ to be a Sequence, received: {}".format( + type(whitelist_cidrs_) + ) + ) self.known_service = known_service_ self.whitelist_cidrs = whitelist_cidrs_ self.unknown_fields = unknown_fields - class FirewallRuleArgs(Type): - _toSchema = {'args': 'args'} - _toPy = {'args': 'args'} + _toSchema = {"args": "args"} + _toPy = {"args": "args"} + def __init__(self, args=None, **unknown_fields): - ''' + """ args : typing.Sequence[~FirewallRule] - ''' + """ args_ = [FirewallRule.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception("Expected args_ to be a Sequence, received: {}".format(type(args_))) + raise Exception( + "Expected args_ to be a Sequence, received: {}".format(type(args_)) + ) self.args = args_ self.unknown_fields = unknown_fields - class FullStatus(Type): - _toSchema = {'applications': 'applications', 'branches': 'branches', 'controller_timestamp': 'controller-timestamp', 'filesystems': 'filesystems', 'machines': 'machines', 'model': 'model', 'offers': 'offers', 'relations': 'relations', 'remote_applications': 'remote-applications', 'storage': 'storage', 'volumes': 'volumes'} - _toPy = {'applications': 'applications', 'branches': 'branches', 'controller-timestamp': 'controller_timestamp', 'filesystems': 'filesystems', 'machines': 'machines', 'model': 'model', 'offers': 'offers', 'relations': 'relations', 'remote-applications': 'remote_applications', 'storage': 'storage', 'volumes': 'volumes'} - def __init__(self, applications=None, branches=None, controller_timestamp=None, filesystems=None, machines=None, model=None, offers=None, relations=None, remote_applications=None, storage=None, volumes=None, **unknown_fields): - ''' + _toSchema = { + "applications": "applications", + "branches": "branches", + "controller_timestamp": "controller-timestamp", + "filesystems": "filesystems", + "machines": "machines", + "model": "model", + "offers": "offers", + "relations": "relations", + "remote_applications": "remote-applications", + "storage": "storage", + "volumes": "volumes", + } + _toPy = { + "applications": "applications", + "branches": "branches", + "controller-timestamp": "controller_timestamp", + "filesystems": "filesystems", + "machines": "machines", + "model": "model", + "offers": "offers", + "relations": "relations", + "remote-applications": "remote_applications", + "storage": "storage", + "volumes": "volumes", + } + + def __init__( + self, + applications=None, + branches=None, + controller_timestamp=None, + filesystems=None, + machines=None, + model=None, + offers=None, + relations=None, + remote_applications=None, + storage=None, + volumes=None, + **unknown_fields, + ): + """ applications : typing.Mapping[str, ~ApplicationStatus] branches : typing.Mapping[str, ~BranchStatus] controller_timestamp : str @@ -7784,52 +12505,113 @@ def __init__(self, applications=None, branches=None, controller_timestamp=None, remote_applications : typing.Mapping[str, ~RemoteApplicationStatus] storage : typing.Sequence[~StorageDetails] volumes : typing.Sequence[~VolumeDetails] - ''' - applications_ = {k: ApplicationStatus.from_json(v) for k, v in (applications or dict()).items()} - branches_ = {k: BranchStatus.from_json(v) for k, v in (branches or dict()).items()} + """ + applications_ = { + k: ApplicationStatus.from_json(v) + for k, v in (applications or dict()).items() + } + branches_ = { + k: BranchStatus.from_json(v) for k, v in (branches or dict()).items() + } controller_timestamp_ = controller_timestamp filesystems_ = [FilesystemDetails.from_json(o) for o in filesystems or []] - machines_ = {k: MachineStatus.from_json(v) for k, v in (machines or dict()).items()} + machines_ = { + k: MachineStatus.from_json(v) for k, v in (machines or dict()).items() + } model_ = ModelStatusInfo.from_json(model) if model else None - offers_ = {k: ApplicationOfferStatus.from_json(v) for k, v in (offers or dict()).items()} + offers_ = { + k: ApplicationOfferStatus.from_json(v) + for k, v in (offers or dict()).items() + } relations_ = [RelationStatus.from_json(o) for o in relations or []] - remote_applications_ = {k: RemoteApplicationStatus.from_json(v) for k, v in (remote_applications or dict()).items()} + remote_applications_ = { + k: RemoteApplicationStatus.from_json(v) + for k, v in (remote_applications or dict()).items() + } storage_ = [StorageDetails.from_json(o) for o in storage or []] volumes_ = [VolumeDetails.from_json(o) for o in volumes or []] # Validate arguments against known Juju API types. if applications_ is not None and not isinstance(applications_, dict): - raise Exception("Expected applications_ to be a Mapping, received: {}".format(type(applications_))) + raise Exception( + "Expected applications_ to be a Mapping, received: {}".format( + type(applications_) + ) + ) if branches_ is not None and not isinstance(branches_, dict): - raise Exception("Expected branches_ to be a Mapping, received: {}".format(type(branches_))) - - if controller_timestamp_ is not None and not isinstance(controller_timestamp_, (bytes, str)): - raise Exception("Expected controller_timestamp_ to be a str, received: {}".format(type(controller_timestamp_))) - - if filesystems_ is not None and not isinstance(filesystems_, (bytes, str, list)): - raise Exception("Expected filesystems_ to be a Sequence, received: {}".format(type(filesystems_))) + raise Exception( + "Expected branches_ to be a Mapping, received: {}".format( + type(branches_) + ) + ) + + if controller_timestamp_ is not None and not isinstance( + controller_timestamp_, (bytes, str) + ): + raise Exception( + "Expected controller_timestamp_ to be a str, received: {}".format( + type(controller_timestamp_) + ) + ) + + if filesystems_ is not None and not isinstance( + filesystems_, (bytes, str, list) + ): + raise Exception( + "Expected filesystems_ to be a Sequence, received: {}".format( + type(filesystems_) + ) + ) if machines_ is not None and not isinstance(machines_, dict): - raise Exception("Expected machines_ to be a Mapping, received: {}".format(type(machines_))) + raise Exception( + "Expected machines_ to be a Mapping, received: {}".format( + type(machines_) + ) + ) if model_ is not None and not isinstance(model_, (dict, ModelStatusInfo)): - raise Exception("Expected model_ to be a ModelStatusInfo, received: {}".format(type(model_))) + raise Exception( + "Expected model_ to be a ModelStatusInfo, received: {}".format( + type(model_) + ) + ) if offers_ is not None and not isinstance(offers_, dict): - raise Exception("Expected offers_ to be a Mapping, received: {}".format(type(offers_))) + raise Exception( + "Expected offers_ to be a Mapping, received: {}".format(type(offers_)) + ) if relations_ is not None and not isinstance(relations_, (bytes, str, list)): - raise Exception("Expected relations_ to be a Sequence, received: {}".format(type(relations_))) - - if remote_applications_ is not None and not isinstance(remote_applications_, dict): - raise Exception("Expected remote_applications_ to be a Mapping, received: {}".format(type(remote_applications_))) + raise Exception( + "Expected relations_ to be a Sequence, received: {}".format( + type(relations_) + ) + ) + + if remote_applications_ is not None and not isinstance( + remote_applications_, dict + ): + raise Exception( + "Expected remote_applications_ to be a Mapping, received: {}".format( + type(remote_applications_) + ) + ) if storage_ is not None and not isinstance(storage_, (bytes, str, list)): - raise Exception("Expected storage_ to be a Sequence, received: {}".format(type(storage_))) + raise Exception( + "Expected storage_ to be a Sequence, received: {}".format( + type(storage_) + ) + ) if volumes_ is not None and not isinstance(volumes_, (bytes, str, list)): - raise Exception("Expected volumes_ to be a Sequence, received: {}".format(type(volumes_))) + raise Exception( + "Expected volumes_ to be a Sequence, received: {}".format( + type(volumes_) + ) + ) self.applications = applications_ self.branches = branches_ @@ -7845,12 +12627,38 @@ def __init__(self, applications=None, branches=None, controller_timestamp=None, self.unknown_fields = unknown_fields - class Generation(Type): - _toSchema = {'applications': 'applications', 'branch': 'branch', 'completed': 'completed', 'completed_by': 'completed-by', 'created': 'created', 'created_by': 'created-by', 'generation_id': 'generation-id'} - _toPy = {'applications': 'applications', 'branch': 'branch', 'completed': 'completed', 'completed-by': 'completed_by', 'created': 'created', 'created-by': 'created_by', 'generation-id': 'generation_id'} - def __init__(self, applications=None, branch=None, completed=None, completed_by=None, created=None, created_by=None, generation_id=None, **unknown_fields): - ''' + _toSchema = { + "applications": "applications", + "branch": "branch", + "completed": "completed", + "completed_by": "completed-by", + "created": "created", + "created_by": "created-by", + "generation_id": "generation-id", + } + _toPy = { + "applications": "applications", + "branch": "branch", + "completed": "completed", + "completed-by": "completed_by", + "created": "created", + "created-by": "created_by", + "generation-id": "generation_id", + } + + def __init__( + self, + applications=None, + branch=None, + completed=None, + completed_by=None, + created=None, + created_by=None, + generation_id=None, + **unknown_fields, + ): + """ applications : typing.Sequence[~GenerationApplication] branch : str completed : int @@ -7858,7 +12666,7 @@ def __init__(self, applications=None, branch=None, completed=None, completed_by= created : int created_by : str generation_id : int - ''' + """ applications_ = [GenerationApplication.from_json(o) for o in applications or []] branch_ = branch completed_ = completed @@ -7868,26 +12676,50 @@ def __init__(self, applications=None, branch=None, completed=None, completed_by= generation_id_ = generation_id # Validate arguments against known Juju API types. - if applications_ is not None and not isinstance(applications_, (bytes, str, list)): - raise Exception("Expected applications_ to be a Sequence, received: {}".format(type(applications_))) + if applications_ is not None and not isinstance( + applications_, (bytes, str, list) + ): + raise Exception( + "Expected applications_ to be a Sequence, received: {}".format( + type(applications_) + ) + ) if branch_ is not None and not isinstance(branch_, (bytes, str)): - raise Exception("Expected branch_ to be a str, received: {}".format(type(branch_))) + raise Exception( + "Expected branch_ to be a str, received: {}".format(type(branch_)) + ) if completed_ is not None and not isinstance(completed_, int): - raise Exception("Expected completed_ to be a int, received: {}".format(type(completed_))) + raise Exception( + "Expected completed_ to be a int, received: {}".format(type(completed_)) + ) if completed_by_ is not None and not isinstance(completed_by_, (bytes, str)): - raise Exception("Expected completed_by_ to be a str, received: {}".format(type(completed_by_))) + raise Exception( + "Expected completed_by_ to be a str, received: {}".format( + type(completed_by_) + ) + ) if created_ is not None and not isinstance(created_, int): - raise Exception("Expected created_ to be a int, received: {}".format(type(created_))) + raise Exception( + "Expected created_ to be a int, received: {}".format(type(created_)) + ) if created_by_ is not None and not isinstance(created_by_, (bytes, str)): - raise Exception("Expected created_by_ to be a str, received: {}".format(type(created_by_))) + raise Exception( + "Expected created_by_ to be a str, received: {}".format( + type(created_by_) + ) + ) if generation_id_ is not None and not isinstance(generation_id_, int): - raise Exception("Expected generation_id_ to be a int, received: {}".format(type(generation_id_))) + raise Exception( + "Expected generation_id_ to be a int, received: {}".format( + type(generation_id_) + ) + ) self.applications = applications_ self.branch = branch_ @@ -7899,18 +12731,38 @@ def __init__(self, applications=None, branch=None, completed=None, completed_by= self.unknown_fields = unknown_fields - class GenerationApplication(Type): - _toSchema = {'application': 'application', 'config': 'config', 'pending': 'pending', 'progress': 'progress', 'tracking': 'tracking'} - _toPy = {'application': 'application', 'config': 'config', 'pending': 'pending', 'progress': 'progress', 'tracking': 'tracking'} - def __init__(self, application=None, config=None, pending=None, progress=None, tracking=None, **unknown_fields): - ''' + _toSchema = { + "application": "application", + "config": "config", + "pending": "pending", + "progress": "progress", + "tracking": "tracking", + } + _toPy = { + "application": "application", + "config": "config", + "pending": "pending", + "progress": "progress", + "tracking": "tracking", + } + + def __init__( + self, + application=None, + config=None, + pending=None, + progress=None, + tracking=None, + **unknown_fields, + ): + """ application : str config : typing.Mapping[str, typing.Any] pending : typing.Sequence[str] progress : str tracking : typing.Sequence[str] - ''' + """ application_ = application config_ = config pending_ = pending @@ -7919,19 +12771,35 @@ def __init__(self, application=None, config=None, pending=None, progress=None, t # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): - raise Exception("Expected application_ to be a str, received: {}".format(type(application_))) + raise Exception( + "Expected application_ to be a str, received: {}".format( + type(application_) + ) + ) if config_ is not None and not isinstance(config_, dict): - raise Exception("Expected config_ to be a Mapping, received: {}".format(type(config_))) + raise Exception( + "Expected config_ to be a Mapping, received: {}".format(type(config_)) + ) if pending_ is not None and not isinstance(pending_, (bytes, str, list)): - raise Exception("Expected pending_ to be a Sequence, received: {}".format(type(pending_))) + raise Exception( + "Expected pending_ to be a Sequence, received: {}".format( + type(pending_) + ) + ) if progress_ is not None and not isinstance(progress_, (bytes, str)): - raise Exception("Expected progress_ to be a str, received: {}".format(type(progress_))) + raise Exception( + "Expected progress_ to be a str, received: {}".format(type(progress_)) + ) if tracking_ is not None and not isinstance(tracking_, (bytes, str, list)): - raise Exception("Expected tracking_ to be a Sequence, received: {}".format(type(tracking_))) + raise Exception( + "Expected tracking_ to be a Sequence, received: {}".format( + type(tracking_) + ) + ) self.application = application_ self.config = config_ @@ -7941,89 +12809,113 @@ def __init__(self, application=None, config=None, pending=None, progress=None, t self.unknown_fields = unknown_fields - class GenerationId(Type): - _toSchema = {'generation_id': 'generation-id'} - _toPy = {'generation-id': 'generation_id'} + _toSchema = {"generation_id": "generation-id"} + _toPy = {"generation-id": "generation_id"} + def __init__(self, generation_id=None, **unknown_fields): - ''' + """ generation_id : int - ''' + """ generation_id_ = generation_id # Validate arguments against known Juju API types. if generation_id_ is not None and not isinstance(generation_id_, int): - raise Exception("Expected generation_id_ to be a int, received: {}".format(type(generation_id_))) + raise Exception( + "Expected generation_id_ to be a int, received: {}".format( + type(generation_id_) + ) + ) self.generation_id = generation_id_ self.unknown_fields = unknown_fields - class GenerationResult(Type): - _toSchema = {'error': 'error', 'generation': 'generation'} - _toPy = {'error': 'error', 'generation': 'generation'} + _toSchema = {"error": "error", "generation": "generation"} + _toPy = {"error": "error", "generation": "generation"} + def __init__(self, error=None, generation=None, **unknown_fields): - ''' + """ error : Error generation : Generation - ''' + """ error_ = Error.from_json(error) if error else None generation_ = Generation.from_json(generation) if generation else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if generation_ is not None and not isinstance(generation_, (dict, Generation)): - raise Exception("Expected generation_ to be a Generation, received: {}".format(type(generation_))) + raise Exception( + "Expected generation_ to be a Generation, received: {}".format( + type(generation_) + ) + ) self.error = error_ self.generation = generation_ self.unknown_fields = unknown_fields - class GetConstraintsResults(Type): - _toSchema = {'constraints': 'constraints'} - _toPy = {'constraints': 'constraints'} + _toSchema = {"constraints": "constraints"} + _toPy = {"constraints": "constraints"} + def __init__(self, constraints=None, **unknown_fields): - ''' + """ constraints : Value - ''' + """ constraints_ = Value.from_json(constraints) if constraints else None # Validate arguments against known Juju API types. if constraints_ is not None and not isinstance(constraints_, (dict, Value)): - raise Exception("Expected constraints_ to be a Value, received: {}".format(type(constraints_))) + raise Exception( + "Expected constraints_ to be a Value, received: {}".format( + type(constraints_) + ) + ) self.constraints = constraints_ self.unknown_fields = unknown_fields - class GrantRevokeUserSecretArg(Type): - _toSchema = {'applications': 'applications', 'label': 'label', 'uri': 'uri'} - _toPy = {'applications': 'applications', 'label': 'label', 'uri': 'uri'} + _toSchema = {"applications": "applications", "label": "label", "uri": "uri"} + _toPy = {"applications": "applications", "label": "label", "uri": "uri"} + def __init__(self, applications=None, label=None, uri=None, **unknown_fields): - ''' + """ applications : typing.Sequence[str] label : str uri : str - ''' + """ applications_ = applications label_ = label uri_ = uri # Validate arguments against known Juju API types. - if applications_ is not None and not isinstance(applications_, (bytes, str, list)): - raise Exception("Expected applications_ to be a Sequence, received: {}".format(type(applications_))) + if applications_ is not None and not isinstance( + applications_, (bytes, str, list) + ): + raise Exception( + "Expected applications_ to be a Sequence, received: {}".format( + type(applications_) + ) + ) if label_ is not None and not isinstance(label_, (bytes, str)): - raise Exception("Expected label_ to be a str, received: {}".format(type(label_))) + raise Exception( + "Expected label_ to be a str, received: {}".format(type(label_)) + ) if uri_ is not None and not isinstance(uri_, (bytes, str)): - raise Exception("Expected uri_ to be a str, received: {}".format(type(uri_))) + raise Exception( + "Expected uri_ to be a str, received: {}".format(type(uri_)) + ) self.applications = applications_ self.label = label_ @@ -8031,12 +12923,44 @@ def __init__(self, applications=None, label=None, uri=None, **unknown_fields): self.unknown_fields = unknown_fields - class HardwareCharacteristics(Type): - _toSchema = {'arch': 'arch', 'availability_zone': 'availability-zone', 'cpu_cores': 'cpu-cores', 'cpu_power': 'cpu-power', 'mem': 'mem', 'root_disk': 'root-disk', 'root_disk_source': 'root-disk-source', 'tags': 'tags', 'virt_type': 'virt-type'} - _toPy = {'arch': 'arch', 'availability-zone': 'availability_zone', 'cpu-cores': 'cpu_cores', 'cpu-power': 'cpu_power', 'mem': 'mem', 'root-disk': 'root_disk', 'root-disk-source': 'root_disk_source', 'tags': 'tags', 'virt-type': 'virt_type'} - def __init__(self, arch=None, availability_zone=None, cpu_cores=None, cpu_power=None, mem=None, root_disk=None, root_disk_source=None, tags=None, virt_type=None, **unknown_fields): - ''' + _toSchema = { + "arch": "arch", + "availability_zone": "availability-zone", + "cpu_cores": "cpu-cores", + "cpu_power": "cpu-power", + "mem": "mem", + "root_disk": "root-disk", + "root_disk_source": "root-disk-source", + "tags": "tags", + "virt_type": "virt-type", + } + _toPy = { + "arch": "arch", + "availability-zone": "availability_zone", + "cpu-cores": "cpu_cores", + "cpu-power": "cpu_power", + "mem": "mem", + "root-disk": "root_disk", + "root-disk-source": "root_disk_source", + "tags": "tags", + "virt-type": "virt_type", + } + + def __init__( + self, + arch=None, + availability_zone=None, + cpu_cores=None, + cpu_power=None, + mem=None, + root_disk=None, + root_disk_source=None, + tags=None, + virt_type=None, + **unknown_fields, + ): + """ arch : str availability_zone : str cpu_cores : int @@ -8046,7 +12970,7 @@ def __init__(self, arch=None, availability_zone=None, cpu_cores=None, cpu_power= root_disk_source : str tags : typing.Sequence[str] virt_type : str - ''' + """ arch_ = arch availability_zone_ = availability_zone cpu_cores_ = cpu_cores @@ -8059,31 +12983,57 @@ def __init__(self, arch=None, availability_zone=None, cpu_cores=None, cpu_power= # Validate arguments against known Juju API types. if arch_ is not None and not isinstance(arch_, (bytes, str)): - raise Exception("Expected arch_ to be a str, received: {}".format(type(arch_))) - - if availability_zone_ is not None and not isinstance(availability_zone_, (bytes, str)): - raise Exception("Expected availability_zone_ to be a str, received: {}".format(type(availability_zone_))) + raise Exception( + "Expected arch_ to be a str, received: {}".format(type(arch_)) + ) + + if availability_zone_ is not None and not isinstance( + availability_zone_, (bytes, str) + ): + raise Exception( + "Expected availability_zone_ to be a str, received: {}".format( + type(availability_zone_) + ) + ) if cpu_cores_ is not None and not isinstance(cpu_cores_, int): - raise Exception("Expected cpu_cores_ to be a int, received: {}".format(type(cpu_cores_))) + raise Exception( + "Expected cpu_cores_ to be a int, received: {}".format(type(cpu_cores_)) + ) if cpu_power_ is not None and not isinstance(cpu_power_, int): - raise Exception("Expected cpu_power_ to be a int, received: {}".format(type(cpu_power_))) + raise Exception( + "Expected cpu_power_ to be a int, received: {}".format(type(cpu_power_)) + ) if mem_ is not None and not isinstance(mem_, int): - raise Exception("Expected mem_ to be a int, received: {}".format(type(mem_))) + raise Exception( + "Expected mem_ to be a int, received: {}".format(type(mem_)) + ) if root_disk_ is not None and not isinstance(root_disk_, int): - raise Exception("Expected root_disk_ to be a int, received: {}".format(type(root_disk_))) - - if root_disk_source_ is not None and not isinstance(root_disk_source_, (bytes, str)): - raise Exception("Expected root_disk_source_ to be a str, received: {}".format(type(root_disk_source_))) + raise Exception( + "Expected root_disk_ to be a int, received: {}".format(type(root_disk_)) + ) + + if root_disk_source_ is not None and not isinstance( + root_disk_source_, (bytes, str) + ): + raise Exception( + "Expected root_disk_source_ to be a str, received: {}".format( + type(root_disk_source_) + ) + ) if tags_ is not None and not isinstance(tags_, (bytes, str, list)): - raise Exception("Expected tags_ to be a Sequence, received: {}".format(type(tags_))) + raise Exception( + "Expected tags_ to be a Sequence, received: {}".format(type(tags_)) + ) if virt_type_ is not None and not isinstance(virt_type_, (bytes, str)): - raise Exception("Expected virt_type_ to be a str, received: {}".format(type(virt_type_))) + raise Exception( + "Expected virt_type_ to be a str, received: {}".format(type(virt_type_)) + ) self.arch = arch_ self.availability_zone = availability_zone_ @@ -8097,36 +13047,77 @@ def __init__(self, arch=None, availability_zone=None, cpu_cores=None, cpu_power= self.unknown_fields = unknown_fields - class History(Type): - _toSchema = {'error': 'error', 'statuses': 'statuses'} - _toPy = {'error': 'error', 'statuses': 'statuses'} + _toSchema = {"error": "error", "statuses": "statuses"} + _toPy = {"error": "error", "statuses": "statuses"} + def __init__(self, error=None, statuses=None, **unknown_fields): - ''' + """ error : Error statuses : typing.Sequence[~DetailedStatus] - ''' + """ error_ = Error.from_json(error) if error else None statuses_ = [DetailedStatus.from_json(o) for o in statuses or []] # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if statuses_ is not None and not isinstance(statuses_, (bytes, str, list)): - raise Exception("Expected statuses_ to be a Sequence, received: {}".format(type(statuses_))) + raise Exception( + "Expected statuses_ to be a Sequence, received: {}".format( + type(statuses_) + ) + ) self.error = error_ self.statuses = statuses_ self.unknown_fields = unknown_fields - class HostPort(Type): - _toSchema = {'address': 'Address', 'cidr': 'cidr', 'config_type': 'config-type', 'is_secondary': 'is-secondary', 'port': 'port', 'scope': 'scope', 'space_id': 'space-id', 'space_name': 'space-name', 'type_': 'type', 'value': 'value'} - _toPy = {'Address': 'address', 'cidr': 'cidr', 'config-type': 'config_type', 'is-secondary': 'is_secondary', 'port': 'port', 'scope': 'scope', 'space-id': 'space_id', 'space-name': 'space_name', 'type': 'type_', 'value': 'value'} - def __init__(self, address=None, cidr=None, config_type=None, is_secondary=None, port=None, scope=None, space_id=None, space_name=None, type_=None, value=None, **unknown_fields): - ''' + _toSchema = { + "address": "Address", + "cidr": "cidr", + "config_type": "config-type", + "is_secondary": "is-secondary", + "port": "port", + "scope": "scope", + "space_id": "space-id", + "space_name": "space-name", + "type_": "type", + "value": "value", + } + _toPy = { + "Address": "address", + "cidr": "cidr", + "config-type": "config_type", + "is-secondary": "is_secondary", + "port": "port", + "scope": "scope", + "space-id": "space_id", + "space-name": "space_name", + "type": "type_", + "value": "value", + } + + def __init__( + self, + address=None, + cidr=None, + config_type=None, + is_secondary=None, + port=None, + scope=None, + space_id=None, + space_name=None, + type_=None, + value=None, + **unknown_fields, + ): + """ address : Address cidr : str config_type : str @@ -8137,7 +13128,7 @@ def __init__(self, address=None, cidr=None, config_type=None, is_secondary=None, space_name : str type_ : str value : str - ''' + """ address_ = Address.from_json(address) if address else None cidr_ = cidr config_type_ = config_type @@ -8151,34 +13142,60 @@ def __init__(self, address=None, cidr=None, config_type=None, is_secondary=None, # Validate arguments against known Juju API types. if address_ is not None and not isinstance(address_, (dict, Address)): - raise Exception("Expected address_ to be a Address, received: {}".format(type(address_))) + raise Exception( + "Expected address_ to be a Address, received: {}".format(type(address_)) + ) if cidr_ is not None and not isinstance(cidr_, (bytes, str)): - raise Exception("Expected cidr_ to be a str, received: {}".format(type(cidr_))) + raise Exception( + "Expected cidr_ to be a str, received: {}".format(type(cidr_)) + ) if config_type_ is not None and not isinstance(config_type_, (bytes, str)): - raise Exception("Expected config_type_ to be a str, received: {}".format(type(config_type_))) + raise Exception( + "Expected config_type_ to be a str, received: {}".format( + type(config_type_) + ) + ) if is_secondary_ is not None and not isinstance(is_secondary_, bool): - raise Exception("Expected is_secondary_ to be a bool, received: {}".format(type(is_secondary_))) + raise Exception( + "Expected is_secondary_ to be a bool, received: {}".format( + type(is_secondary_) + ) + ) if port_ is not None and not isinstance(port_, int): - raise Exception("Expected port_ to be a int, received: {}".format(type(port_))) + raise Exception( + "Expected port_ to be a int, received: {}".format(type(port_)) + ) if scope_ is not None and not isinstance(scope_, (bytes, str)): - raise Exception("Expected scope_ to be a str, received: {}".format(type(scope_))) + raise Exception( + "Expected scope_ to be a str, received: {}".format(type(scope_)) + ) if space_id_ is not None and not isinstance(space_id_, (bytes, str)): - raise Exception("Expected space_id_ to be a str, received: {}".format(type(space_id_))) + raise Exception( + "Expected space_id_ to be a str, received: {}".format(type(space_id_)) + ) if space_name_ is not None and not isinstance(space_name_, (bytes, str)): - raise Exception("Expected space_name_ to be a str, received: {}".format(type(space_name_))) + raise Exception( + "Expected space_name_ to be a str, received: {}".format( + type(space_name_) + ) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) if value_ is not None and not isinstance(value_, (bytes, str)): - raise Exception("Expected value_ to be a str, received: {}".format(type(value_))) + raise Exception( + "Expected value_ to be a str, received: {}".format(type(value_)) + ) self.address = address_ self.cidr = cidr_ @@ -8193,18 +13210,38 @@ def __init__(self, address=None, cidr=None, config_type=None, is_secondary=None, self.unknown_fields = unknown_fields - class HostedModelConfig(Type): - _toSchema = {'cloud_spec': 'cloud-spec', 'config': 'config', 'error': 'error', 'name': 'name', 'owner': 'owner'} - _toPy = {'cloud-spec': 'cloud_spec', 'config': 'config', 'error': 'error', 'name': 'name', 'owner': 'owner'} - def __init__(self, cloud_spec=None, config=None, error=None, name=None, owner=None, **unknown_fields): - ''' + _toSchema = { + "cloud_spec": "cloud-spec", + "config": "config", + "error": "error", + "name": "name", + "owner": "owner", + } + _toPy = { + "cloud-spec": "cloud_spec", + "config": "config", + "error": "error", + "name": "name", + "owner": "owner", + } + + def __init__( + self, + cloud_spec=None, + config=None, + error=None, + name=None, + owner=None, + **unknown_fields, + ): + """ cloud_spec : CloudSpec config : typing.Mapping[str, typing.Any] error : Error name : str owner : str - ''' + """ cloud_spec_ = CloudSpec.from_json(cloud_spec) if cloud_spec else None config_ = config error_ = Error.from_json(error) if error else None @@ -8213,19 +13250,31 @@ def __init__(self, cloud_spec=None, config=None, error=None, name=None, owner=No # Validate arguments against known Juju API types. if cloud_spec_ is not None and not isinstance(cloud_spec_, (dict, CloudSpec)): - raise Exception("Expected cloud_spec_ to be a CloudSpec, received: {}".format(type(cloud_spec_))) + raise Exception( + "Expected cloud_spec_ to be a CloudSpec, received: {}".format( + type(cloud_spec_) + ) + ) if config_ is not None and not isinstance(config_, dict): - raise Exception("Expected config_ to be a Mapping, received: {}".format(type(config_))) + raise Exception( + "Expected config_ to be a Mapping, received: {}".format(type(config_)) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if owner_ is not None and not isinstance(owner_, (bytes, str)): - raise Exception("Expected owner_ to be a str, received: {}".format(type(owner_))) + raise Exception( + "Expected owner_ to be a str, received: {}".format(type(owner_)) + ) self.cloud_spec = cloud_spec_ self.config = config_ @@ -8235,37 +13284,62 @@ def __init__(self, cloud_spec=None, config=None, error=None, name=None, owner=No self.unknown_fields = unknown_fields - class HostedModelConfigsResults(Type): - _toSchema = {'models': 'models'} - _toPy = {'models': 'models'} + _toSchema = {"models": "models"} + _toPy = {"models": "models"} + def __init__(self, models=None, **unknown_fields): - ''' + """ models : typing.Sequence[~HostedModelConfig] - ''' + """ models_ = [HostedModelConfig.from_json(o) for o in models or []] # Validate arguments against known Juju API types. if models_ is not None and not isinstance(models_, (bytes, str, list)): - raise Exception("Expected models_ to be a Sequence, received: {}".format(type(models_))) + raise Exception( + "Expected models_ to be a Sequence, received: {}".format(type(models_)) + ) self.models = models_ self.unknown_fields = unknown_fields - class ImageMetadataFilter(Type): - _toSchema = {'arches': 'arches', 'region': 'region', 'root_storage_type': 'root-storage-type', 'stream': 'stream', 'versions': 'versions', 'virt_type': 'virt-type'} - _toPy = {'arches': 'arches', 'region': 'region', 'root-storage-type': 'root_storage_type', 'stream': 'stream', 'versions': 'versions', 'virt-type': 'virt_type'} - def __init__(self, arches=None, region=None, root_storage_type=None, stream=None, versions=None, virt_type=None, **unknown_fields): - ''' + _toSchema = { + "arches": "arches", + "region": "region", + "root_storage_type": "root-storage-type", + "stream": "stream", + "versions": "versions", + "virt_type": "virt-type", + } + _toPy = { + "arches": "arches", + "region": "region", + "root-storage-type": "root_storage_type", + "stream": "stream", + "versions": "versions", + "virt-type": "virt_type", + } + + def __init__( + self, + arches=None, + region=None, + root_storage_type=None, + stream=None, + versions=None, + virt_type=None, + **unknown_fields, + ): + """ arches : typing.Sequence[str] region : str root_storage_type : str stream : str versions : typing.Sequence[str] virt_type : str - ''' + """ arches_ = arches region_ = region root_storage_type_ = root_storage_type @@ -8275,22 +13349,40 @@ def __init__(self, arches=None, region=None, root_storage_type=None, stream=None # Validate arguments against known Juju API types. if arches_ is not None and not isinstance(arches_, (bytes, str, list)): - raise Exception("Expected arches_ to be a Sequence, received: {}".format(type(arches_))) + raise Exception( + "Expected arches_ to be a Sequence, received: {}".format(type(arches_)) + ) if region_ is not None and not isinstance(region_, (bytes, str)): - raise Exception("Expected region_ to be a str, received: {}".format(type(region_))) - - if root_storage_type_ is not None and not isinstance(root_storage_type_, (bytes, str)): - raise Exception("Expected root_storage_type_ to be a str, received: {}".format(type(root_storage_type_))) + raise Exception( + "Expected region_ to be a str, received: {}".format(type(region_)) + ) + + if root_storage_type_ is not None and not isinstance( + root_storage_type_, (bytes, str) + ): + raise Exception( + "Expected root_storage_type_ to be a str, received: {}".format( + type(root_storage_type_) + ) + ) if stream_ is not None and not isinstance(stream_, (bytes, str)): - raise Exception("Expected stream_ to be a str, received: {}".format(type(stream_))) + raise Exception( + "Expected stream_ to be a str, received: {}".format(type(stream_)) + ) if versions_ is not None and not isinstance(versions_, (bytes, str, list)): - raise Exception("Expected versions_ to be a Sequence, received: {}".format(type(versions_))) + raise Exception( + "Expected versions_ to be a Sequence, received: {}".format( + type(versions_) + ) + ) if virt_type_ is not None and not isinstance(virt_type_, (bytes, str)): - raise Exception("Expected virt_type_ to be a str, received: {}".format(type(virt_type_))) + raise Exception( + "Expected virt_type_ to be a str, received: {}".format(type(virt_type_)) + ) self.arches = arches_ self.region = region_ @@ -8301,35 +13393,56 @@ def __init__(self, arches=None, region=None, root_storage_type=None, stream=None self.unknown_fields = unknown_fields - class ImportStorageDetails(Type): - _toSchema = {'storage_tag': 'storage-tag'} - _toPy = {'storage-tag': 'storage_tag'} + _toSchema = {"storage_tag": "storage-tag"} + _toPy = {"storage-tag": "storage_tag"} + def __init__(self, storage_tag=None, **unknown_fields): - ''' + """ storage_tag : str - ''' + """ storage_tag_ = storage_tag # Validate arguments against known Juju API types. if storage_tag_ is not None and not isinstance(storage_tag_, (bytes, str)): - raise Exception("Expected storage_tag_ to be a str, received: {}".format(type(storage_tag_))) + raise Exception( + "Expected storage_tag_ to be a str, received: {}".format( + type(storage_tag_) + ) + ) self.storage_tag = storage_tag_ self.unknown_fields = unknown_fields - class ImportStorageParams(Type): - _toSchema = {'kind': 'kind', 'pool': 'pool', 'provider_id': 'provider-id', 'storage_name': 'storage-name'} - _toPy = {'kind': 'kind', 'pool': 'pool', 'provider-id': 'provider_id', 'storage-name': 'storage_name'} - def __init__(self, kind=None, pool=None, provider_id=None, storage_name=None, **unknown_fields): - ''' + _toSchema = { + "kind": "kind", + "pool": "pool", + "provider_id": "provider-id", + "storage_name": "storage-name", + } + _toPy = { + "kind": "kind", + "pool": "pool", + "provider-id": "provider_id", + "storage-name": "storage_name", + } + + def __init__( + self, + kind=None, + pool=None, + provider_id=None, + storage_name=None, + **unknown_fields, + ): + """ kind : int pool : str provider_id : str storage_name : str - ''' + """ kind_ = kind pool_ = pool provider_id_ = provider_id @@ -8337,16 +13450,28 @@ def __init__(self, kind=None, pool=None, provider_id=None, storage_name=None, ** # Validate arguments against known Juju API types. if kind_ is not None and not isinstance(kind_, int): - raise Exception("Expected kind_ to be a int, received: {}".format(type(kind_))) + raise Exception( + "Expected kind_ to be a int, received: {}".format(type(kind_)) + ) if pool_ is not None and not isinstance(pool_, (bytes, str)): - raise Exception("Expected pool_ to be a str, received: {}".format(type(pool_))) + raise Exception( + "Expected pool_ to be a str, received: {}".format(type(pool_)) + ) if provider_id_ is not None and not isinstance(provider_id_, (bytes, str)): - raise Exception("Expected provider_id_ to be a str, received: {}".format(type(provider_id_))) + raise Exception( + "Expected provider_id_ to be a str, received: {}".format( + type(provider_id_) + ) + ) if storage_name_ is not None and not isinstance(storage_name_, (bytes, str)): - raise Exception("Expected storage_name_ to be a str, received: {}".format(type(storage_name_))) + raise Exception( + "Expected storage_name_ to be a str, received: {}".format( + type(storage_name_) + ) + ) self.kind = kind_ self.pool = pool_ @@ -8355,89 +13480,115 @@ def __init__(self, kind=None, pool=None, provider_id=None, storage_name=None, ** self.unknown_fields = unknown_fields - class ImportStorageResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : ImportStorageDetails - ''' + """ error_ = Error.from_json(error) if error else None result_ = ImportStorageDetails.from_json(result) if result else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) - - if result_ is not None and not isinstance(result_, (dict, ImportStorageDetails)): - raise Exception("Expected result_ to be a ImportStorageDetails, received: {}".format(type(result_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) + + if result_ is not None and not isinstance( + result_, (dict, ImportStorageDetails) + ): + raise Exception( + "Expected result_ to be a ImportStorageDetails, received: {}".format( + type(result_) + ) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class ImportStorageResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~ImportStorageResult] - ''' + """ results_ = [ImportStorageResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class InitiateMigrationArgs(Type): - _toSchema = {'specs': 'specs'} - _toPy = {'specs': 'specs'} + _toSchema = {"specs": "specs"} + _toPy = {"specs": "specs"} + def __init__(self, specs=None, **unknown_fields): - ''' + """ specs : typing.Sequence[~MigrationSpec] - ''' + """ specs_ = [MigrationSpec.from_json(o) for o in specs or []] # Validate arguments against known Juju API types. if specs_ is not None and not isinstance(specs_, (bytes, str, list)): - raise Exception("Expected specs_ to be a Sequence, received: {}".format(type(specs_))) + raise Exception( + "Expected specs_ to be a Sequence, received: {}".format(type(specs_)) + ) self.specs = specs_ self.unknown_fields = unknown_fields - class InitiateMigrationResult(Type): - _toSchema = {'error': 'error', 'migration_id': 'migration-id', 'model_tag': 'model-tag'} - _toPy = {'error': 'error', 'migration-id': 'migration_id', 'model-tag': 'model_tag'} + _toSchema = { + "error": "error", + "migration_id": "migration-id", + "model_tag": "model-tag", + } + _toPy = {"error": "error", "migration-id": "migration_id", "model-tag": "model_tag"} + def __init__(self, error=None, migration_id=None, model_tag=None, **unknown_fields): - ''' + """ error : Error migration_id : str model_tag : str - ''' + """ error_ = Error.from_json(error) if error else None migration_id_ = migration_id model_tag_ = model_tag # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if migration_id_ is not None and not isinstance(migration_id_, (bytes, str)): - raise Exception("Expected migration_id_ to be a str, received: {}".format(type(migration_id_))) + raise Exception( + "Expected migration_id_ to be a str, received: {}".format( + type(migration_id_) + ) + ) if model_tag_ is not None and not isinstance(model_tag_, (bytes, str)): - raise Exception("Expected model_tag_ to be a str, received: {}".format(type(model_tag_))) + raise Exception( + "Expected model_tag_ to be a str, received: {}".format(type(model_tag_)) + ) self.error = error_ self.migration_id = migration_id_ @@ -8445,30 +13596,60 @@ def __init__(self, error=None, migration_id=None, model_tag=None, **unknown_fiel self.unknown_fields = unknown_fields - class InitiateMigrationResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~InitiateMigrationResult] - ''' + """ results_ = [InitiateMigrationResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class InstanceType(Type): - _toSchema = {'arches': 'arches', 'cost': 'cost', 'cpu_cores': 'cpu-cores', 'memory': 'memory', 'name': 'name', 'root_disk': 'root-disk', 'virt_type': 'virt-type'} - _toPy = {'arches': 'arches', 'cost': 'cost', 'cpu-cores': 'cpu_cores', 'memory': 'memory', 'name': 'name', 'root-disk': 'root_disk', 'virt-type': 'virt_type'} - def __init__(self, arches=None, cost=None, cpu_cores=None, memory=None, name=None, root_disk=None, virt_type=None, **unknown_fields): - ''' + _toSchema = { + "arches": "arches", + "cost": "cost", + "cpu_cores": "cpu-cores", + "memory": "memory", + "name": "name", + "root_disk": "root-disk", + "virt_type": "virt-type", + } + _toPy = { + "arches": "arches", + "cost": "cost", + "cpu-cores": "cpu_cores", + "memory": "memory", + "name": "name", + "root-disk": "root_disk", + "virt-type": "virt_type", + } + + def __init__( + self, + arches=None, + cost=None, + cpu_cores=None, + memory=None, + name=None, + root_disk=None, + virt_type=None, + **unknown_fields, + ): + """ arches : typing.Sequence[str] cost : int cpu_cores : int @@ -8476,7 +13657,7 @@ def __init__(self, arches=None, cost=None, cpu_cores=None, memory=None, name=Non name : str root_disk : int virt_type : str - ''' + """ arches_ = arches cost_ = cost cpu_cores_ = cpu_cores @@ -8487,25 +13668,39 @@ def __init__(self, arches=None, cost=None, cpu_cores=None, memory=None, name=Non # Validate arguments against known Juju API types. if arches_ is not None and not isinstance(arches_, (bytes, str, list)): - raise Exception("Expected arches_ to be a Sequence, received: {}".format(type(arches_))) + raise Exception( + "Expected arches_ to be a Sequence, received: {}".format(type(arches_)) + ) if cost_ is not None and not isinstance(cost_, int): - raise Exception("Expected cost_ to be a int, received: {}".format(type(cost_))) + raise Exception( + "Expected cost_ to be a int, received: {}".format(type(cost_)) + ) if cpu_cores_ is not None and not isinstance(cpu_cores_, int): - raise Exception("Expected cpu_cores_ to be a int, received: {}".format(type(cpu_cores_))) + raise Exception( + "Expected cpu_cores_ to be a int, received: {}".format(type(cpu_cores_)) + ) if memory_ is not None and not isinstance(memory_, int): - raise Exception("Expected memory_ to be a int, received: {}".format(type(memory_))) + raise Exception( + "Expected memory_ to be a int, received: {}".format(type(memory_)) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if root_disk_ is not None and not isinstance(root_disk_, int): - raise Exception("Expected root_disk_ to be a int, received: {}".format(type(root_disk_))) + raise Exception( + "Expected root_disk_ to be a int, received: {}".format(type(root_disk_)) + ) if virt_type_ is not None and not isinstance(virt_type_, (bytes, str)): - raise Exception("Expected virt_type_ to be a str, received: {}".format(type(virt_type_))) + raise Exception( + "Expected virt_type_ to be a str, received: {}".format(type(virt_type_)) + ) self.arches = arches_ self.cost = cost_ @@ -8517,18 +13712,38 @@ def __init__(self, arches=None, cost=None, cpu_cores=None, memory=None, name=Non self.unknown_fields = unknown_fields - class InstanceTypesResult(Type): - _toSchema = {'cost_currency': 'cost-currency', 'cost_divisor': 'cost-divisor', 'cost_unit': 'cost-unit', 'error': 'error', 'instance_types': 'instance-types'} - _toPy = {'cost-currency': 'cost_currency', 'cost-divisor': 'cost_divisor', 'cost-unit': 'cost_unit', 'error': 'error', 'instance-types': 'instance_types'} - def __init__(self, cost_currency=None, cost_divisor=None, cost_unit=None, error=None, instance_types=None, **unknown_fields): - ''' + _toSchema = { + "cost_currency": "cost-currency", + "cost_divisor": "cost-divisor", + "cost_unit": "cost-unit", + "error": "error", + "instance_types": "instance-types", + } + _toPy = { + "cost-currency": "cost_currency", + "cost-divisor": "cost_divisor", + "cost-unit": "cost_unit", + "error": "error", + "instance-types": "instance_types", + } + + def __init__( + self, + cost_currency=None, + cost_divisor=None, + cost_unit=None, + error=None, + instance_types=None, + **unknown_fields, + ): + """ cost_currency : str cost_divisor : int cost_unit : str error : Error instance_types : typing.Sequence[~InstanceType] - ''' + """ cost_currency_ = cost_currency cost_divisor_ = cost_divisor cost_unit_ = cost_unit @@ -8537,19 +13752,37 @@ def __init__(self, cost_currency=None, cost_divisor=None, cost_unit=None, error= # Validate arguments against known Juju API types. if cost_currency_ is not None and not isinstance(cost_currency_, (bytes, str)): - raise Exception("Expected cost_currency_ to be a str, received: {}".format(type(cost_currency_))) + raise Exception( + "Expected cost_currency_ to be a str, received: {}".format( + type(cost_currency_) + ) + ) if cost_divisor_ is not None and not isinstance(cost_divisor_, int): - raise Exception("Expected cost_divisor_ to be a int, received: {}".format(type(cost_divisor_))) + raise Exception( + "Expected cost_divisor_ to be a int, received: {}".format( + type(cost_divisor_) + ) + ) if cost_unit_ is not None and not isinstance(cost_unit_, (bytes, str)): - raise Exception("Expected cost_unit_ to be a str, received: {}".format(type(cost_unit_))) + raise Exception( + "Expected cost_unit_ to be a str, received: {}".format(type(cost_unit_)) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) - - if instance_types_ is not None and not isinstance(instance_types_, (bytes, str, list)): - raise Exception("Expected instance_types_ to be a Sequence, received: {}".format(type(instance_types_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) + + if instance_types_ is not None and not isinstance( + instance_types_, (bytes, str, list) + ): + raise Exception( + "Expected instance_types_ to be a Sequence, received: {}".format( + type(instance_types_) + ) + ) self.cost_currency = cost_currency_ self.cost_divisor = cost_divisor_ @@ -8559,107 +13792,127 @@ def __init__(self, cost_currency=None, cost_divisor=None, cost_unit=None, error= self.unknown_fields = unknown_fields - class InstanceTypesResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~InstanceTypesResult] - ''' + """ results_ = [InstanceTypesResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class IntResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : int - ''' + """ error_ = Error.from_json(error) if error else None result_ = result # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if result_ is not None and not isinstance(result_, int): - raise Exception("Expected result_ to be a int, received: {}".format(type(result_))) + raise Exception( + "Expected result_ to be a int, received: {}".format(type(result_)) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class InvalidateCredentialArg(Type): - _toSchema = {'reason': 'reason'} - _toPy = {'reason': 'reason'} + _toSchema = {"reason": "reason"} + _toPy = {"reason": "reason"} + def __init__(self, reason=None, **unknown_fields): - ''' + """ reason : str - ''' + """ reason_ = reason # Validate arguments against known Juju API types. if reason_ is not None and not isinstance(reason_, (bytes, str)): - raise Exception("Expected reason_ to be a str, received: {}".format(type(reason_))) + raise Exception( + "Expected reason_ to be a str, received: {}".format(type(reason_)) + ) self.reason = reason_ self.unknown_fields = unknown_fields - class IsMeteredResult(Type): - _toSchema = {'metered': 'metered'} - _toPy = {'metered': 'metered'} + _toSchema = {"metered": "metered"} + _toPy = {"metered": "metered"} + def __init__(self, metered=None, **unknown_fields): - ''' + """ metered : bool - ''' + """ metered_ = metered # Validate arguments against known Juju API types. if metered_ is not None and not isinstance(metered_, bool): - raise Exception("Expected metered_ to be a bool, received: {}".format(type(metered_))) + raise Exception( + "Expected metered_ to be a bool, received: {}".format(type(metered_)) + ) self.metered = metered_ self.unknown_fields = unknown_fields - class LXDProfile(Type): - _toSchema = {'config': 'config', 'description': 'description', 'devices': 'devices'} - _toPy = {'config': 'config', 'description': 'description', 'devices': 'devices'} + _toSchema = {"config": "config", "description": "description", "devices": "devices"} + _toPy = {"config": "config", "description": "description", "devices": "devices"} + def __init__(self, config=None, description=None, devices=None, **unknown_fields): - ''' + """ config : typing.Mapping[str, str] description : str devices : typing.Mapping[str, typing.Any] - ''' + """ config_ = config description_ = description devices_ = devices # Validate arguments against known Juju API types. if config_ is not None and not isinstance(config_, dict): - raise Exception("Expected config_ to be a Mapping, received: {}".format(type(config_))) + raise Exception( + "Expected config_ to be a Mapping, received: {}".format(type(config_)) + ) if description_ is not None and not isinstance(description_, (bytes, str)): - raise Exception("Expected description_ to be a str, received: {}".format(type(description_))) + raise Exception( + "Expected description_ to be a str, received: {}".format( + type(description_) + ) + ) if devices_ is not None and not isinstance(devices_, dict): - raise Exception("Expected devices_ to be a Mapping, received: {}".format(type(devices_))) + raise Exception( + "Expected devices_ to be a Mapping, received: {}".format(type(devices_)) + ) self.config = config_ self.description = description_ @@ -8667,222 +13920,318 @@ def __init__(self, config=None, description=None, devices=None, **unknown_fields self.unknown_fields = unknown_fields - class ListCloudImageMetadataResult(Type): - _toSchema = {'result': 'result'} - _toPy = {'result': 'result'} + _toSchema = {"result": "result"} + _toPy = {"result": "result"} + def __init__(self, result=None, **unknown_fields): - ''' + """ result : typing.Sequence[~CloudImageMetadata] - ''' + """ result_ = [CloudImageMetadata.from_json(o) for o in result or []] # Validate arguments against known Juju API types. if result_ is not None and not isinstance(result_, (bytes, str, list)): - raise Exception("Expected result_ to be a Sequence, received: {}".format(type(result_))) + raise Exception( + "Expected result_ to be a Sequence, received: {}".format(type(result_)) + ) self.result = result_ self.unknown_fields = unknown_fields - class ListCloudInfo(Type): - _toSchema = {'clouddetails': 'CloudDetails', 'user_access': 'user-access'} - _toPy = {'CloudDetails': 'clouddetails', 'user-access': 'user_access'} + _toSchema = {"clouddetails": "CloudDetails", "user_access": "user-access"} + _toPy = {"CloudDetails": "clouddetails", "user-access": "user_access"} + def __init__(self, clouddetails=None, user_access=None, **unknown_fields): - ''' + """ clouddetails : CloudDetails user_access : str - ''' + """ clouddetails_ = CloudDetails.from_json(clouddetails) if clouddetails else None user_access_ = user_access # Validate arguments against known Juju API types. - if clouddetails_ is not None and not isinstance(clouddetails_, (dict, CloudDetails)): - raise Exception("Expected clouddetails_ to be a CloudDetails, received: {}".format(type(clouddetails_))) + if clouddetails_ is not None and not isinstance( + clouddetails_, (dict, CloudDetails) + ): + raise Exception( + "Expected clouddetails_ to be a CloudDetails, received: {}".format( + type(clouddetails_) + ) + ) if user_access_ is not None and not isinstance(user_access_, (bytes, str)): - raise Exception("Expected user_access_ to be a str, received: {}".format(type(user_access_))) + raise Exception( + "Expected user_access_ to be a str, received: {}".format( + type(user_access_) + ) + ) self.clouddetails = clouddetails_ self.user_access = user_access_ self.unknown_fields = unknown_fields - class ListCloudInfoResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : ListCloudInfo - ''' + """ error_ = Error.from_json(error) if error else None result_ = ListCloudInfo.from_json(result) if result else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if result_ is not None and not isinstance(result_, (dict, ListCloudInfo)): - raise Exception("Expected result_ to be a ListCloudInfo, received: {}".format(type(result_))) + raise Exception( + "Expected result_ to be a ListCloudInfo, received: {}".format( + type(result_) + ) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class ListCloudInfoResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~ListCloudInfoResult] - ''' + """ results_ = [ListCloudInfoResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class ListCloudsRequest(Type): - _toSchema = {'all_': 'all', 'user_tag': 'user-tag'} - _toPy = {'all': 'all_', 'user-tag': 'user_tag'} + _toSchema = {"all_": "all", "user_tag": "user-tag"} + _toPy = {"all": "all_", "user-tag": "user_tag"} + def __init__(self, all_=None, user_tag=None, **unknown_fields): - ''' + """ all_ : bool user_tag : str - ''' + """ all__ = all_ user_tag_ = user_tag # Validate arguments against known Juju API types. if all__ is not None and not isinstance(all__, bool): - raise Exception("Expected all__ to be a bool, received: {}".format(type(all__))) + raise Exception( + "Expected all__ to be a bool, received: {}".format(type(all__)) + ) if user_tag_ is not None and not isinstance(user_tag_, (bytes, str)): - raise Exception("Expected user_tag_ to be a str, received: {}".format(type(user_tag_))) + raise Exception( + "Expected user_tag_ to be a str, received: {}".format(type(user_tag_)) + ) self.all_ = all__ self.user_tag = user_tag_ self.unknown_fields = unknown_fields - class ListFirewallRulesResults(Type): - _toSchema = {'rules': 'Rules'} - _toPy = {'Rules': 'rules'} + _toSchema = {"rules": "Rules"} + _toPy = {"Rules": "rules"} + def __init__(self, rules=None, **unknown_fields): - ''' + """ rules : typing.Sequence[~FirewallRule] - ''' + """ rules_ = [FirewallRule.from_json(o) for o in rules or []] # Validate arguments against known Juju API types. if rules_ is not None and not isinstance(rules_, (bytes, str, list)): - raise Exception("Expected rules_ to be a Sequence, received: {}".format(type(rules_))) + raise Exception( + "Expected rules_ to be a Sequence, received: {}".format(type(rules_)) + ) self.rules = rules_ self.unknown_fields = unknown_fields - class ListResourcesArgs(Type): - _toSchema = {'entities': 'entities'} - _toPy = {'entities': 'entities'} + _toSchema = {"entities": "entities"} + _toPy = {"entities": "entities"} + def __init__(self, entities=None, **unknown_fields): - ''' + """ entities : typing.Sequence[~Entity] - ''' + """ entities_ = [Entity.from_json(o) for o in entities or []] # Validate arguments against known Juju API types. if entities_ is not None and not isinstance(entities_, (bytes, str, list)): - raise Exception("Expected entities_ to be a Sequence, received: {}".format(type(entities_))) + raise Exception( + "Expected entities_ to be a Sequence, received: {}".format( + type(entities_) + ) + ) self.entities = entities_ self.unknown_fields = unknown_fields - class ListSSHKeys(Type): - _toSchema = {'entities': 'entities', 'mode': 'mode'} - _toPy = {'entities': 'entities', 'mode': 'mode'} + _toSchema = {"entities": "entities", "mode": "mode"} + _toPy = {"entities": "entities", "mode": "mode"} + def __init__(self, entities=None, mode=None, **unknown_fields): - ''' + """ entities : Entities mode : bool - ''' + """ entities_ = Entities.from_json(entities) if entities else None mode_ = mode # Validate arguments against known Juju API types. if entities_ is not None and not isinstance(entities_, (dict, Entities)): - raise Exception("Expected entities_ to be a Entities, received: {}".format(type(entities_))) + raise Exception( + "Expected entities_ to be a Entities, received: {}".format( + type(entities_) + ) + ) if mode_ is not None and not isinstance(mode_, bool): - raise Exception("Expected mode_ to be a bool, received: {}".format(type(mode_))) + raise Exception( + "Expected mode_ to be a bool, received: {}".format(type(mode_)) + ) self.entities = entities_ self.mode = mode_ self.unknown_fields = unknown_fields - class ListSecretBackendsArgs(Type): - _toSchema = {'names': 'names', 'reveal': 'reveal'} - _toPy = {'names': 'names', 'reveal': 'reveal'} + _toSchema = {"names": "names", "reveal": "reveal"} + _toPy = {"names": "names", "reveal": "reveal"} + def __init__(self, names=None, reveal=None, **unknown_fields): - ''' + """ names : typing.Sequence[str] reveal : bool - ''' + """ names_ = names reveal_ = reveal # Validate arguments against known Juju API types. if names_ is not None and not isinstance(names_, (bytes, str, list)): - raise Exception("Expected names_ to be a Sequence, received: {}".format(type(names_))) + raise Exception( + "Expected names_ to be a Sequence, received: {}".format(type(names_)) + ) if reveal_ is not None and not isinstance(reveal_, bool): - raise Exception("Expected reveal_ to be a bool, received: {}".format(type(reveal_))) + raise Exception( + "Expected reveal_ to be a bool, received: {}".format(type(reveal_)) + ) self.names = names_ self.reveal = reveal_ self.unknown_fields = unknown_fields - class ListSecretBackendsResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~SecretBackendResult] - ''' + """ results_ = [SecretBackendResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class ListSecretResult(Type): - _toSchema = {'access': 'access', 'create_time': 'create-time', 'description': 'description', 'label': 'label', 'latest_expire_time': 'latest-expire-time', 'latest_revision': 'latest-revision', 'latest_revision_checksum': 'latest-revision-checksum', 'next_rotate_time': 'next-rotate-time', 'owner_tag': 'owner-tag', 'revisions': 'revisions', 'rotate_policy': 'rotate-policy', 'update_time': 'update-time', 'uri': 'uri', 'value': 'value', 'version': 'version'} - _toPy = {'access': 'access', 'create-time': 'create_time', 'description': 'description', 'label': 'label', 'latest-expire-time': 'latest_expire_time', 'latest-revision': 'latest_revision', 'latest-revision-checksum': 'latest_revision_checksum', 'next-rotate-time': 'next_rotate_time', 'owner-tag': 'owner_tag', 'revisions': 'revisions', 'rotate-policy': 'rotate_policy', 'update-time': 'update_time', 'uri': 'uri', 'value': 'value', 'version': 'version'} - def __init__(self, access=None, create_time=None, description=None, label=None, latest_expire_time=None, latest_revision=None, latest_revision_checksum=None, next_rotate_time=None, owner_tag=None, revisions=None, rotate_policy=None, update_time=None, uri=None, value=None, version=None, **unknown_fields): - ''' + _toSchema = { + "access": "access", + "create_time": "create-time", + "description": "description", + "label": "label", + "latest_expire_time": "latest-expire-time", + "latest_revision": "latest-revision", + "latest_revision_checksum": "latest-revision-checksum", + "next_rotate_time": "next-rotate-time", + "owner_tag": "owner-tag", + "revisions": "revisions", + "rotate_policy": "rotate-policy", + "update_time": "update-time", + "uri": "uri", + "value": "value", + "version": "version", + } + _toPy = { + "access": "access", + "create-time": "create_time", + "description": "description", + "label": "label", + "latest-expire-time": "latest_expire_time", + "latest-revision": "latest_revision", + "latest-revision-checksum": "latest_revision_checksum", + "next-rotate-time": "next_rotate_time", + "owner-tag": "owner_tag", + "revisions": "revisions", + "rotate-policy": "rotate_policy", + "update-time": "update_time", + "uri": "uri", + "value": "value", + "version": "version", + } + + def __init__( + self, + access=None, + create_time=None, + description=None, + label=None, + latest_expire_time=None, + latest_revision=None, + latest_revision_checksum=None, + next_rotate_time=None, + owner_tag=None, + revisions=None, + rotate_policy=None, + update_time=None, + uri=None, + value=None, + version=None, + **unknown_fields, + ): + """ access : typing.Sequence[~AccessInfo] create_time : str description : str @@ -8898,7 +14247,7 @@ def __init__(self, access=None, create_time=None, description=None, label=None, uri : str value : SecretValueResult version : int - ''' + """ access_ = [AccessInfo.from_json(o) for o in access or []] create_time_ = create_time description_ = description @@ -8917,49 +14266,105 @@ def __init__(self, access=None, create_time=None, description=None, label=None, # Validate arguments against known Juju API types. if access_ is not None and not isinstance(access_, (bytes, str, list)): - raise Exception("Expected access_ to be a Sequence, received: {}".format(type(access_))) + raise Exception( + "Expected access_ to be a Sequence, received: {}".format(type(access_)) + ) if create_time_ is not None and not isinstance(create_time_, (bytes, str)): - raise Exception("Expected create_time_ to be a str, received: {}".format(type(create_time_))) + raise Exception( + "Expected create_time_ to be a str, received: {}".format( + type(create_time_) + ) + ) if description_ is not None and not isinstance(description_, (bytes, str)): - raise Exception("Expected description_ to be a str, received: {}".format(type(description_))) + raise Exception( + "Expected description_ to be a str, received: {}".format( + type(description_) + ) + ) if label_ is not None and not isinstance(label_, (bytes, str)): - raise Exception("Expected label_ to be a str, received: {}".format(type(label_))) - - if latest_expire_time_ is not None and not isinstance(latest_expire_time_, (bytes, str)): - raise Exception("Expected latest_expire_time_ to be a str, received: {}".format(type(latest_expire_time_))) + raise Exception( + "Expected label_ to be a str, received: {}".format(type(label_)) + ) + + if latest_expire_time_ is not None and not isinstance( + latest_expire_time_, (bytes, str) + ): + raise Exception( + "Expected latest_expire_time_ to be a str, received: {}".format( + type(latest_expire_time_) + ) + ) if latest_revision_ is not None and not isinstance(latest_revision_, int): - raise Exception("Expected latest_revision_ to be a int, received: {}".format(type(latest_revision_))) - - if latest_revision_checksum_ is not None and not isinstance(latest_revision_checksum_, (bytes, str)): - raise Exception("Expected latest_revision_checksum_ to be a str, received: {}".format(type(latest_revision_checksum_))) - - if next_rotate_time_ is not None and not isinstance(next_rotate_time_, (bytes, str)): - raise Exception("Expected next_rotate_time_ to be a str, received: {}".format(type(next_rotate_time_))) + raise Exception( + "Expected latest_revision_ to be a int, received: {}".format( + type(latest_revision_) + ) + ) + + if latest_revision_checksum_ is not None and not isinstance( + latest_revision_checksum_, (bytes, str) + ): + raise Exception( + "Expected latest_revision_checksum_ to be a str, received: {}".format( + type(latest_revision_checksum_) + ) + ) + + if next_rotate_time_ is not None and not isinstance( + next_rotate_time_, (bytes, str) + ): + raise Exception( + "Expected next_rotate_time_ to be a str, received: {}".format( + type(next_rotate_time_) + ) + ) if owner_tag_ is not None and not isinstance(owner_tag_, (bytes, str)): - raise Exception("Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_))) + raise Exception( + "Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_)) + ) if revisions_ is not None and not isinstance(revisions_, (bytes, str, list)): - raise Exception("Expected revisions_ to be a Sequence, received: {}".format(type(revisions_))) + raise Exception( + "Expected revisions_ to be a Sequence, received: {}".format( + type(revisions_) + ) + ) if rotate_policy_ is not None and not isinstance(rotate_policy_, (bytes, str)): - raise Exception("Expected rotate_policy_ to be a str, received: {}".format(type(rotate_policy_))) + raise Exception( + "Expected rotate_policy_ to be a str, received: {}".format( + type(rotate_policy_) + ) + ) if update_time_ is not None and not isinstance(update_time_, (bytes, str)): - raise Exception("Expected update_time_ to be a str, received: {}".format(type(update_time_))) + raise Exception( + "Expected update_time_ to be a str, received: {}".format( + type(update_time_) + ) + ) if uri_ is not None and not isinstance(uri_, (bytes, str)): - raise Exception("Expected uri_ to be a str, received: {}".format(type(uri_))) + raise Exception( + "Expected uri_ to be a str, received: {}".format(type(uri_)) + ) if value_ is not None and not isinstance(value_, (dict, SecretValueResult)): - raise Exception("Expected value_ to be a SecretValueResult, received: {}".format(type(value_))) + raise Exception( + "Expected value_ to be a SecretValueResult, received: {}".format( + type(value_) + ) + ) if version_ is not None and not isinstance(version_, int): - raise Exception("Expected version_ to be a int, received: {}".format(type(version_))) + raise Exception( + "Expected version_ to be a int, received: {}".format(type(version_)) + ) self.access = access_ self.create_time = create_time_ @@ -8979,90 +14384,142 @@ def __init__(self, access=None, create_time=None, description=None, label=None, self.unknown_fields = unknown_fields - class ListSecretResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~ListSecretResult] - ''' + """ results_ = [ListSecretResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class ListSecretsArgs(Type): - _toSchema = {'filter_': 'filter', 'show_secrets': 'show-secrets'} - _toPy = {'filter': 'filter_', 'show-secrets': 'show_secrets'} + _toSchema = {"filter_": "filter", "show_secrets": "show-secrets"} + _toPy = {"filter": "filter_", "show-secrets": "show_secrets"} + def __init__(self, filter_=None, show_secrets=None, **unknown_fields): - ''' + """ filter_ : SecretsFilter show_secrets : bool - ''' + """ filter__ = SecretsFilter.from_json(filter_) if filter_ else None show_secrets_ = show_secrets # Validate arguments against known Juju API types. if filter__ is not None and not isinstance(filter__, (dict, SecretsFilter)): - raise Exception("Expected filter__ to be a SecretsFilter, received: {}".format(type(filter__))) + raise Exception( + "Expected filter__ to be a SecretsFilter, received: {}".format( + type(filter__) + ) + ) if show_secrets_ is not None and not isinstance(show_secrets_, bool): - raise Exception("Expected show_secrets_ to be a bool, received: {}".format(type(show_secrets_))) + raise Exception( + "Expected show_secrets_ to be a bool, received: {}".format( + type(show_secrets_) + ) + ) self.filter_ = filter__ self.show_secrets = show_secrets_ self.unknown_fields = unknown_fields - class ListSpacesResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~Space] - ''' + """ results_ = [Space.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class ListSubnetsResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~Subnet] - ''' + """ results_ = [Subnet.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class LoginRequest(Type): - _toSchema = {'auth_tag': 'auth-tag', 'bakery_version': 'bakery-version', 'cli_args': 'cli-args', 'client_version': 'client-version', 'credentials': 'credentials', 'macaroons': 'macaroons', 'nonce': 'nonce', 'token': 'token', 'user_data': 'user-data'} - _toPy = {'auth-tag': 'auth_tag', 'bakery-version': 'bakery_version', 'cli-args': 'cli_args', 'client-version': 'client_version', 'credentials': 'credentials', 'macaroons': 'macaroons', 'nonce': 'nonce', 'token': 'token', 'user-data': 'user_data'} - def __init__(self, auth_tag=None, bakery_version=None, cli_args=None, client_version=None, credentials=None, macaroons=None, nonce=None, token=None, user_data=None, **unknown_fields): - ''' + _toSchema = { + "auth_tag": "auth-tag", + "bakery_version": "bakery-version", + "cli_args": "cli-args", + "client_version": "client-version", + "credentials": "credentials", + "macaroons": "macaroons", + "nonce": "nonce", + "token": "token", + "user_data": "user-data", + } + _toPy = { + "auth-tag": "auth_tag", + "bakery-version": "bakery_version", + "cli-args": "cli_args", + "client-version": "client_version", + "credentials": "credentials", + "macaroons": "macaroons", + "nonce": "nonce", + "token": "token", + "user-data": "user_data", + } + + def __init__( + self, + auth_tag=None, + bakery_version=None, + cli_args=None, + client_version=None, + credentials=None, + macaroons=None, + nonce=None, + token=None, + user_data=None, + **unknown_fields, + ): + """ auth_tag : str bakery_version : int cli_args : str @@ -9072,7 +14529,7 @@ def __init__(self, auth_tag=None, bakery_version=None, cli_args=None, client_ver nonce : str token : str user_data : str - ''' + """ auth_tag_ = auth_tag bakery_version_ = bakery_version cli_args_ = cli_args @@ -9085,31 +14542,59 @@ def __init__(self, auth_tag=None, bakery_version=None, cli_args=None, client_ver # Validate arguments against known Juju API types. if auth_tag_ is not None and not isinstance(auth_tag_, (bytes, str)): - raise Exception("Expected auth_tag_ to be a str, received: {}".format(type(auth_tag_))) + raise Exception( + "Expected auth_tag_ to be a str, received: {}".format(type(auth_tag_)) + ) if bakery_version_ is not None and not isinstance(bakery_version_, int): - raise Exception("Expected bakery_version_ to be a int, received: {}".format(type(bakery_version_))) + raise Exception( + "Expected bakery_version_ to be a int, received: {}".format( + type(bakery_version_) + ) + ) if cli_args_ is not None and not isinstance(cli_args_, (bytes, str)): - raise Exception("Expected cli_args_ to be a str, received: {}".format(type(cli_args_))) - - if client_version_ is not None and not isinstance(client_version_, (bytes, str)): - raise Exception("Expected client_version_ to be a str, received: {}".format(type(client_version_))) + raise Exception( + "Expected cli_args_ to be a str, received: {}".format(type(cli_args_)) + ) + + if client_version_ is not None and not isinstance( + client_version_, (bytes, str) + ): + raise Exception( + "Expected client_version_ to be a str, received: {}".format( + type(client_version_) + ) + ) if credentials_ is not None and not isinstance(credentials_, (bytes, str)): - raise Exception("Expected credentials_ to be a str, received: {}".format(type(credentials_))) + raise Exception( + "Expected credentials_ to be a str, received: {}".format( + type(credentials_) + ) + ) if macaroons_ is not None and not isinstance(macaroons_, (bytes, str, list)): - raise Exception("Expected macaroons_ to be a Sequence, received: {}".format(type(macaroons_))) + raise Exception( + "Expected macaroons_ to be a Sequence, received: {}".format( + type(macaroons_) + ) + ) if nonce_ is not None and not isinstance(nonce_, (bytes, str)): - raise Exception("Expected nonce_ to be a str, received: {}".format(type(nonce_))) + raise Exception( + "Expected nonce_ to be a str, received: {}".format(type(nonce_)) + ) if token_ is not None and not isinstance(token_, (bytes, str)): - raise Exception("Expected token_ to be a str, received: {}".format(type(token_))) + raise Exception( + "Expected token_ to be a str, received: {}".format(type(token_)) + ) if user_data_ is not None and not isinstance(user_data_, (bytes, str)): - raise Exception("Expected user_data_ to be a str, received: {}".format(type(user_data_))) + raise Exception( + "Expected user_data_ to be a str, received: {}".format(type(user_data_)) + ) self.auth_tag = auth_tag_ self.bakery_version = bakery_version_ @@ -9123,12 +14608,47 @@ def __init__(self, auth_tag=None, bakery_version=None, cli_args=None, client_ver self.unknown_fields = unknown_fields - class LoginResult(Type): - _toSchema = {'bakery_discharge_required': 'bakery-discharge-required', 'controller_tag': 'controller-tag', 'discharge_required': 'discharge-required', 'discharge_required_error': 'discharge-required-error', 'facades': 'facades', 'model_tag': 'model-tag', 'public_dns_name': 'public-dns-name', 'server_version': 'server-version', 'servers': 'servers', 'user_info': 'user-info'} - _toPy = {'bakery-discharge-required': 'bakery_discharge_required', 'controller-tag': 'controller_tag', 'discharge-required': 'discharge_required', 'discharge-required-error': 'discharge_required_error', 'facades': 'facades', 'model-tag': 'model_tag', 'public-dns-name': 'public_dns_name', 'server-version': 'server_version', 'servers': 'servers', 'user-info': 'user_info'} - def __init__(self, bakery_discharge_required=None, controller_tag=None, discharge_required=None, discharge_required_error=None, facades=None, model_tag=None, public_dns_name=None, server_version=None, servers=None, user_info=None, **unknown_fields): - ''' + _toSchema = { + "bakery_discharge_required": "bakery-discharge-required", + "controller_tag": "controller-tag", + "discharge_required": "discharge-required", + "discharge_required_error": "discharge-required-error", + "facades": "facades", + "model_tag": "model-tag", + "public_dns_name": "public-dns-name", + "server_version": "server-version", + "servers": "servers", + "user_info": "user-info", + } + _toPy = { + "bakery-discharge-required": "bakery_discharge_required", + "controller-tag": "controller_tag", + "discharge-required": "discharge_required", + "discharge-required-error": "discharge_required_error", + "facades": "facades", + "model-tag": "model_tag", + "public-dns-name": "public_dns_name", + "server-version": "server_version", + "servers": "servers", + "user-info": "user_info", + } + + def __init__( + self, + bakery_discharge_required=None, + controller_tag=None, + discharge_required=None, + discharge_required_error=None, + facades=None, + model_tag=None, + public_dns_name=None, + server_version=None, + servers=None, + user_info=None, + **unknown_fields, + ): + """ bakery_discharge_required : Macaroon controller_tag : str discharge_required : Macaroon @@ -9139,10 +14659,16 @@ def __init__(self, bakery_discharge_required=None, controller_tag=None, discharg server_version : str servers : typing.Sequence[~HostPort] user_info : AuthUserInfo - ''' - bakery_discharge_required_ = Macaroon.from_json(bakery_discharge_required) if bakery_discharge_required else None + """ + bakery_discharge_required_ = ( + Macaroon.from_json(bakery_discharge_required) + if bakery_discharge_required + else None + ) controller_tag_ = controller_tag - discharge_required_ = Macaroon.from_json(discharge_required) if discharge_required else None + discharge_required_ = ( + Macaroon.from_json(discharge_required) if discharge_required else None + ) discharge_required_error_ = discharge_required_error facades_ = [FacadeVersions.from_json(o) for o in facades or []] model_tag_ = model_tag @@ -9152,35 +14678,85 @@ def __init__(self, bakery_discharge_required=None, controller_tag=None, discharg user_info_ = AuthUserInfo.from_json(user_info) if user_info else None # Validate arguments against known Juju API types. - if bakery_discharge_required_ is not None and not isinstance(bakery_discharge_required_, (dict, Macaroon)): - raise Exception("Expected bakery_discharge_required_ to be a Macaroon, received: {}".format(type(bakery_discharge_required_))) - - if controller_tag_ is not None and not isinstance(controller_tag_, (bytes, str)): - raise Exception("Expected controller_tag_ to be a str, received: {}".format(type(controller_tag_))) - - if discharge_required_ is not None and not isinstance(discharge_required_, (dict, Macaroon)): - raise Exception("Expected discharge_required_ to be a Macaroon, received: {}".format(type(discharge_required_))) - - if discharge_required_error_ is not None and not isinstance(discharge_required_error_, (bytes, str)): - raise Exception("Expected discharge_required_error_ to be a str, received: {}".format(type(discharge_required_error_))) + if bakery_discharge_required_ is not None and not isinstance( + bakery_discharge_required_, (dict, Macaroon) + ): + raise Exception( + "Expected bakery_discharge_required_ to be a Macaroon, received: {}".format( + type(bakery_discharge_required_) + ) + ) + + if controller_tag_ is not None and not isinstance( + controller_tag_, (bytes, str) + ): + raise Exception( + "Expected controller_tag_ to be a str, received: {}".format( + type(controller_tag_) + ) + ) + + if discharge_required_ is not None and not isinstance( + discharge_required_, (dict, Macaroon) + ): + raise Exception( + "Expected discharge_required_ to be a Macaroon, received: {}".format( + type(discharge_required_) + ) + ) + + if discharge_required_error_ is not None and not isinstance( + discharge_required_error_, (bytes, str) + ): + raise Exception( + "Expected discharge_required_error_ to be a str, received: {}".format( + type(discharge_required_error_) + ) + ) if facades_ is not None and not isinstance(facades_, (bytes, str, list)): - raise Exception("Expected facades_ to be a Sequence, received: {}".format(type(facades_))) + raise Exception( + "Expected facades_ to be a Sequence, received: {}".format( + type(facades_) + ) + ) if model_tag_ is not None and not isinstance(model_tag_, (bytes, str)): - raise Exception("Expected model_tag_ to be a str, received: {}".format(type(model_tag_))) - - if public_dns_name_ is not None and not isinstance(public_dns_name_, (bytes, str)): - raise Exception("Expected public_dns_name_ to be a str, received: {}".format(type(public_dns_name_))) - - if server_version_ is not None and not isinstance(server_version_, (bytes, str)): - raise Exception("Expected server_version_ to be a str, received: {}".format(type(server_version_))) + raise Exception( + "Expected model_tag_ to be a str, received: {}".format(type(model_tag_)) + ) + + if public_dns_name_ is not None and not isinstance( + public_dns_name_, (bytes, str) + ): + raise Exception( + "Expected public_dns_name_ to be a str, received: {}".format( + type(public_dns_name_) + ) + ) + + if server_version_ is not None and not isinstance( + server_version_, (bytes, str) + ): + raise Exception( + "Expected server_version_ to be a str, received: {}".format( + type(server_version_) + ) + ) if servers_ is not None and not isinstance(servers_, (bytes, str, list)): - raise Exception("Expected servers_ to be a Sequence, received: {}".format(type(servers_))) + raise Exception( + "Expected servers_ to be a Sequence, received: {}".format( + type(servers_) + ) + ) if user_info_ is not None and not isinstance(user_info_, (dict, AuthUserInfo)): - raise Exception("Expected user_info_ to be a AuthUserInfo, received: {}".format(type(user_info_))) + raise Exception( + "Expected user_info_ to be a AuthUserInfo, received: {}".format( + type(user_info_) + ) + ) self.bakery_discharge_required = bakery_discharge_required_ self.controller_tag = controller_tag_ @@ -9195,23 +14771,50 @@ def __init__(self, bakery_discharge_required=None, controller_tag=None, discharg self.unknown_fields = unknown_fields - class Macaroon(Type): _toSchema = {} _toPy = {} - def __init__(self, **unknown_fields): - ''' - ''' + def __init__(self, **unknown_fields): + """ """ self.unknown_fields = unknown_fields - class MachineHardware(Type): - _toSchema = {'arch': 'arch', 'availability_zone': 'availability-zone', 'cores': 'cores', 'cpu_power': 'cpu-power', 'mem': 'mem', 'root_disk': 'root-disk', 'tags': 'tags', 'virt_type': 'virt-type'} - _toPy = {'arch': 'arch', 'availability-zone': 'availability_zone', 'cores': 'cores', 'cpu-power': 'cpu_power', 'mem': 'mem', 'root-disk': 'root_disk', 'tags': 'tags', 'virt-type': 'virt_type'} - def __init__(self, arch=None, availability_zone=None, cores=None, cpu_power=None, mem=None, root_disk=None, tags=None, virt_type=None, **unknown_fields): - ''' + _toSchema = { + "arch": "arch", + "availability_zone": "availability-zone", + "cores": "cores", + "cpu_power": "cpu-power", + "mem": "mem", + "root_disk": "root-disk", + "tags": "tags", + "virt_type": "virt-type", + } + _toPy = { + "arch": "arch", + "availability-zone": "availability_zone", + "cores": "cores", + "cpu-power": "cpu_power", + "mem": "mem", + "root-disk": "root_disk", + "tags": "tags", + "virt-type": "virt_type", + } + + def __init__( + self, + arch=None, + availability_zone=None, + cores=None, + cpu_power=None, + mem=None, + root_disk=None, + tags=None, + virt_type=None, + **unknown_fields, + ): + """ arch : str availability_zone : str cores : int @@ -9220,7 +14823,7 @@ def __init__(self, arch=None, availability_zone=None, cores=None, cpu_power=None root_disk : int tags : typing.Sequence[str] virt_type : str - ''' + """ arch_ = arch availability_zone_ = availability_zone cores_ = cores @@ -9232,28 +14835,48 @@ def __init__(self, arch=None, availability_zone=None, cores=None, cpu_power=None # Validate arguments against known Juju API types. if arch_ is not None and not isinstance(arch_, (bytes, str)): - raise Exception("Expected arch_ to be a str, received: {}".format(type(arch_))) - - if availability_zone_ is not None and not isinstance(availability_zone_, (bytes, str)): - raise Exception("Expected availability_zone_ to be a str, received: {}".format(type(availability_zone_))) + raise Exception( + "Expected arch_ to be a str, received: {}".format(type(arch_)) + ) + + if availability_zone_ is not None and not isinstance( + availability_zone_, (bytes, str) + ): + raise Exception( + "Expected availability_zone_ to be a str, received: {}".format( + type(availability_zone_) + ) + ) if cores_ is not None and not isinstance(cores_, int): - raise Exception("Expected cores_ to be a int, received: {}".format(type(cores_))) + raise Exception( + "Expected cores_ to be a int, received: {}".format(type(cores_)) + ) if cpu_power_ is not None and not isinstance(cpu_power_, int): - raise Exception("Expected cpu_power_ to be a int, received: {}".format(type(cpu_power_))) + raise Exception( + "Expected cpu_power_ to be a int, received: {}".format(type(cpu_power_)) + ) if mem_ is not None and not isinstance(mem_, int): - raise Exception("Expected mem_ to be a int, received: {}".format(type(mem_))) + raise Exception( + "Expected mem_ to be a int, received: {}".format(type(mem_)) + ) if root_disk_ is not None and not isinstance(root_disk_, int): - raise Exception("Expected root_disk_ to be a int, received: {}".format(type(root_disk_))) + raise Exception( + "Expected root_disk_ to be a int, received: {}".format(type(root_disk_)) + ) if tags_ is not None and not isinstance(tags_, (bytes, str, list)): - raise Exception("Expected tags_ to be a Sequence, received: {}".format(type(tags_))) + raise Exception( + "Expected tags_ to be a Sequence, received: {}".format(type(tags_)) + ) if virt_type_ is not None and not isinstance(virt_type_, (bytes, str)): - raise Exception("Expected virt_type_ to be a str, received: {}".format(type(virt_type_))) + raise Exception( + "Expected virt_type_ to be a str, received: {}".format(type(virt_type_)) + ) self.arch = arch_ self.availability_zone = availability_zone_ @@ -9266,12 +14889,74 @@ def __init__(self, arch=None, availability_zone=None, cores=None, cpu_power=None self.unknown_fields = unknown_fields - class MachineStatus(Type): - _toSchema = {'agent_status': 'agent-status', 'base': 'base', 'constraints': 'constraints', 'containers': 'containers', 'display_name': 'display-name', 'dns_name': 'dns-name', 'hardware': 'hardware', 'has_vote': 'has-vote', 'hostname': 'hostname', 'id_': 'id', 'instance_id': 'instance-id', 'instance_status': 'instance-status', 'ip_addresses': 'ip-addresses', 'jobs': 'jobs', 'lxd_profiles': 'lxd-profiles', 'modification_status': 'modification-status', 'network_interfaces': 'network-interfaces', 'primary_controller_machine': 'primary-controller-machine', 'wants_vote': 'wants-vote'} - _toPy = {'agent-status': 'agent_status', 'base': 'base', 'constraints': 'constraints', 'containers': 'containers', 'display-name': 'display_name', 'dns-name': 'dns_name', 'hardware': 'hardware', 'has-vote': 'has_vote', 'hostname': 'hostname', 'id': 'id_', 'instance-id': 'instance_id', 'instance-status': 'instance_status', 'ip-addresses': 'ip_addresses', 'jobs': 'jobs', 'lxd-profiles': 'lxd_profiles', 'modification-status': 'modification_status', 'network-interfaces': 'network_interfaces', 'primary-controller-machine': 'primary_controller_machine', 'wants-vote': 'wants_vote'} - def __init__(self, agent_status=None, base=None, constraints=None, containers=None, display_name=None, dns_name=None, hardware=None, has_vote=None, hostname=None, id_=None, instance_id=None, instance_status=None, ip_addresses=None, jobs=None, lxd_profiles=None, modification_status=None, network_interfaces=None, primary_controller_machine=None, wants_vote=None, **unknown_fields): - ''' + _toSchema = { + "agent_status": "agent-status", + "base": "base", + "constraints": "constraints", + "containers": "containers", + "display_name": "display-name", + "dns_name": "dns-name", + "hardware": "hardware", + "has_vote": "has-vote", + "hostname": "hostname", + "id_": "id", + "instance_id": "instance-id", + "instance_status": "instance-status", + "ip_addresses": "ip-addresses", + "jobs": "jobs", + "lxd_profiles": "lxd-profiles", + "modification_status": "modification-status", + "network_interfaces": "network-interfaces", + "primary_controller_machine": "primary-controller-machine", + "wants_vote": "wants-vote", + } + _toPy = { + "agent-status": "agent_status", + "base": "base", + "constraints": "constraints", + "containers": "containers", + "display-name": "display_name", + "dns-name": "dns_name", + "hardware": "hardware", + "has-vote": "has_vote", + "hostname": "hostname", + "id": "id_", + "instance-id": "instance_id", + "instance-status": "instance_status", + "ip-addresses": "ip_addresses", + "jobs": "jobs", + "lxd-profiles": "lxd_profiles", + "modification-status": "modification_status", + "network-interfaces": "network_interfaces", + "primary-controller-machine": "primary_controller_machine", + "wants-vote": "wants_vote", + } + + def __init__( + self, + agent_status=None, + base=None, + constraints=None, + containers=None, + display_name=None, + dns_name=None, + hardware=None, + has_vote=None, + hostname=None, + id_=None, + instance_id=None, + instance_status=None, + ip_addresses=None, + jobs=None, + lxd_profiles=None, + modification_status=None, + network_interfaces=None, + primary_controller_machine=None, + wants_vote=None, + **unknown_fields, + ): + """ agent_status : DetailedStatus base : Base constraints : str @@ -9291,11 +14976,13 @@ def __init__(self, agent_status=None, base=None, constraints=None, containers=No network_interfaces : typing.Mapping[str, ~NetworkInterface] primary_controller_machine : bool wants_vote : bool - ''' + """ agent_status_ = DetailedStatus.from_json(agent_status) if agent_status else None base_ = Base.from_json(base) if base else None constraints_ = constraints - containers_ = {k: MachineStatus.from_json(v) for k, v in (containers or dict()).items()} + containers_ = { + k: MachineStatus.from_json(v) for k, v in (containers or dict()).items() + } display_name_ = display_name dns_name_ = dns_name hardware_ = hardware @@ -9303,72 +14990,157 @@ def __init__(self, agent_status=None, base=None, constraints=None, containers=No hostname_ = hostname id__ = id_ instance_id_ = instance_id - instance_status_ = DetailedStatus.from_json(instance_status) if instance_status else None + instance_status_ = ( + DetailedStatus.from_json(instance_status) if instance_status else None + ) ip_addresses_ = ip_addresses jobs_ = jobs - lxd_profiles_ = {k: LXDProfile.from_json(v) for k, v in (lxd_profiles or dict()).items()} - modification_status_ = DetailedStatus.from_json(modification_status) if modification_status else None - network_interfaces_ = {k: NetworkInterface.from_json(v) for k, v in (network_interfaces or dict()).items()} + lxd_profiles_ = { + k: LXDProfile.from_json(v) for k, v in (lxd_profiles or dict()).items() + } + modification_status_ = ( + DetailedStatus.from_json(modification_status) + if modification_status + else None + ) + network_interfaces_ = { + k: NetworkInterface.from_json(v) + for k, v in (network_interfaces or dict()).items() + } primary_controller_machine_ = primary_controller_machine wants_vote_ = wants_vote # Validate arguments against known Juju API types. - if agent_status_ is not None and not isinstance(agent_status_, (dict, DetailedStatus)): - raise Exception("Expected agent_status_ to be a DetailedStatus, received: {}".format(type(agent_status_))) + if agent_status_ is not None and not isinstance( + agent_status_, (dict, DetailedStatus) + ): + raise Exception( + "Expected agent_status_ to be a DetailedStatus, received: {}".format( + type(agent_status_) + ) + ) if base_ is not None and not isinstance(base_, (dict, Base)): - raise Exception("Expected base_ to be a Base, received: {}".format(type(base_))) + raise Exception( + "Expected base_ to be a Base, received: {}".format(type(base_)) + ) if constraints_ is not None and not isinstance(constraints_, (bytes, str)): - raise Exception("Expected constraints_ to be a str, received: {}".format(type(constraints_))) + raise Exception( + "Expected constraints_ to be a str, received: {}".format( + type(constraints_) + ) + ) if containers_ is not None and not isinstance(containers_, dict): - raise Exception("Expected containers_ to be a Mapping, received: {}".format(type(containers_))) + raise Exception( + "Expected containers_ to be a Mapping, received: {}".format( + type(containers_) + ) + ) if display_name_ is not None and not isinstance(display_name_, (bytes, str)): - raise Exception("Expected display_name_ to be a str, received: {}".format(type(display_name_))) + raise Exception( + "Expected display_name_ to be a str, received: {}".format( + type(display_name_) + ) + ) if dns_name_ is not None and not isinstance(dns_name_, (bytes, str)): - raise Exception("Expected dns_name_ to be a str, received: {}".format(type(dns_name_))) + raise Exception( + "Expected dns_name_ to be a str, received: {}".format(type(dns_name_)) + ) if hardware_ is not None and not isinstance(hardware_, (bytes, str)): - raise Exception("Expected hardware_ to be a str, received: {}".format(type(hardware_))) + raise Exception( + "Expected hardware_ to be a str, received: {}".format(type(hardware_)) + ) if has_vote_ is not None and not isinstance(has_vote_, bool): - raise Exception("Expected has_vote_ to be a bool, received: {}".format(type(has_vote_))) + raise Exception( + "Expected has_vote_ to be a bool, received: {}".format(type(has_vote_)) + ) if hostname_ is not None and not isinstance(hostname_, (bytes, str)): - raise Exception("Expected hostname_ to be a str, received: {}".format(type(hostname_))) + raise Exception( + "Expected hostname_ to be a str, received: {}".format(type(hostname_)) + ) if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception("Expected id__ to be a str, received: {}".format(type(id__))) + raise Exception( + "Expected id__ to be a str, received: {}".format(type(id__)) + ) if instance_id_ is not None and not isinstance(instance_id_, (bytes, str)): - raise Exception("Expected instance_id_ to be a str, received: {}".format(type(instance_id_))) - - if instance_status_ is not None and not isinstance(instance_status_, (dict, DetailedStatus)): - raise Exception("Expected instance_status_ to be a DetailedStatus, received: {}".format(type(instance_status_))) - - if ip_addresses_ is not None and not isinstance(ip_addresses_, (bytes, str, list)): - raise Exception("Expected ip_addresses_ to be a Sequence, received: {}".format(type(ip_addresses_))) + raise Exception( + "Expected instance_id_ to be a str, received: {}".format( + type(instance_id_) + ) + ) + + if instance_status_ is not None and not isinstance( + instance_status_, (dict, DetailedStatus) + ): + raise Exception( + "Expected instance_status_ to be a DetailedStatus, received: {}".format( + type(instance_status_) + ) + ) + + if ip_addresses_ is not None and not isinstance( + ip_addresses_, (bytes, str, list) + ): + raise Exception( + "Expected ip_addresses_ to be a Sequence, received: {}".format( + type(ip_addresses_) + ) + ) if jobs_ is not None and not isinstance(jobs_, (bytes, str, list)): - raise Exception("Expected jobs_ to be a Sequence, received: {}".format(type(jobs_))) + raise Exception( + "Expected jobs_ to be a Sequence, received: {}".format(type(jobs_)) + ) if lxd_profiles_ is not None and not isinstance(lxd_profiles_, dict): - raise Exception("Expected lxd_profiles_ to be a Mapping, received: {}".format(type(lxd_profiles_))) - - if modification_status_ is not None and not isinstance(modification_status_, (dict, DetailedStatus)): - raise Exception("Expected modification_status_ to be a DetailedStatus, received: {}".format(type(modification_status_))) - - if network_interfaces_ is not None and not isinstance(network_interfaces_, dict): - raise Exception("Expected network_interfaces_ to be a Mapping, received: {}".format(type(network_interfaces_))) - - if primary_controller_machine_ is not None and not isinstance(primary_controller_machine_, bool): - raise Exception("Expected primary_controller_machine_ to be a bool, received: {}".format(type(primary_controller_machine_))) + raise Exception( + "Expected lxd_profiles_ to be a Mapping, received: {}".format( + type(lxd_profiles_) + ) + ) + + if modification_status_ is not None and not isinstance( + modification_status_, (dict, DetailedStatus) + ): + raise Exception( + "Expected modification_status_ to be a DetailedStatus, received: {}".format( + type(modification_status_) + ) + ) + + if network_interfaces_ is not None and not isinstance( + network_interfaces_, dict + ): + raise Exception( + "Expected network_interfaces_ to be a Mapping, received: {}".format( + type(network_interfaces_) + ) + ) + + if primary_controller_machine_ is not None and not isinstance( + primary_controller_machine_, bool + ): + raise Exception( + "Expected primary_controller_machine_ to be a bool, received: {}".format( + type(primary_controller_machine_) + ) + ) if wants_vote_ is not None and not isinstance(wants_vote_, bool): - raise Exception("Expected wants_vote_ to be a bool, received: {}".format(type(wants_vote_))) + raise Exception( + "Expected wants_vote_ to be a bool, received: {}".format( + type(wants_vote_) + ) + ) self.agent_status = agent_status_ self.base = base_ @@ -9392,131 +15164,157 @@ def __init__(self, agent_status=None, base=None, constraints=None, containers=No self.unknown_fields = unknown_fields - class MapResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : typing.Mapping[str, typing.Any] - ''' + """ error_ = Error.from_json(error) if error else None result_ = result # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if result_ is not None and not isinstance(result_, dict): - raise Exception("Expected result_ to be a Mapping, received: {}".format(type(result_))) + raise Exception( + "Expected result_ to be a Mapping, received: {}".format(type(result_)) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class MapResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~MapResult] - ''' + """ results_ = [MapResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class MetadataImageIds(Type): - _toSchema = {'image_ids': 'image-ids'} - _toPy = {'image-ids': 'image_ids'} + _toSchema = {"image_ids": "image-ids"} + _toPy = {"image-ids": "image_ids"} + def __init__(self, image_ids=None, **unknown_fields): - ''' + """ image_ids : typing.Sequence[str] - ''' + """ image_ids_ = image_ids # Validate arguments against known Juju API types. if image_ids_ is not None and not isinstance(image_ids_, (bytes, str, list)): - raise Exception("Expected image_ids_ to be a Sequence, received: {}".format(type(image_ids_))) + raise Exception( + "Expected image_ids_ to be a Sequence, received: {}".format( + type(image_ids_) + ) + ) self.image_ids = image_ids_ self.unknown_fields = unknown_fields - class MetadataSaveParams(Type): - _toSchema = {'metadata': 'metadata'} - _toPy = {'metadata': 'metadata'} + _toSchema = {"metadata": "metadata"} + _toPy = {"metadata": "metadata"} + def __init__(self, metadata=None, **unknown_fields): - ''' + """ metadata : typing.Sequence[~CloudImageMetadataList] - ''' + """ metadata_ = [CloudImageMetadataList.from_json(o) for o in metadata or []] # Validate arguments against known Juju API types. if metadata_ is not None and not isinstance(metadata_, (bytes, str, list)): - raise Exception("Expected metadata_ to be a Sequence, received: {}".format(type(metadata_))) + raise Exception( + "Expected metadata_ to be a Sequence, received: {}".format( + type(metadata_) + ) + ) self.metadata = metadata_ self.unknown_fields = unknown_fields - class MeterStatus(Type): - _toSchema = {'color': 'color', 'message': 'message'} - _toPy = {'color': 'color', 'message': 'message'} + _toSchema = {"color": "color", "message": "message"} + _toPy = {"color": "color", "message": "message"} + def __init__(self, color=None, message=None, **unknown_fields): - ''' + """ color : str message : str - ''' + """ color_ = color message_ = message # Validate arguments against known Juju API types. if color_ is not None and not isinstance(color_, (bytes, str)): - raise Exception("Expected color_ to be a str, received: {}".format(type(color_))) + raise Exception( + "Expected color_ to be a str, received: {}".format(type(color_)) + ) if message_ is not None and not isinstance(message_, (bytes, str)): - raise Exception("Expected message_ to be a str, received: {}".format(type(message_))) + raise Exception( + "Expected message_ to be a str, received: {}".format(type(message_)) + ) self.color = color_ self.message = message_ self.unknown_fields = unknown_fields - class MeterStatusParam(Type): - _toSchema = {'code': 'code', 'info': 'info', 'tag': 'tag'} - _toPy = {'code': 'code', 'info': 'info', 'tag': 'tag'} + _toSchema = {"code": "code", "info": "info", "tag": "tag"} + _toPy = {"code": "code", "info": "info", "tag": "tag"} + def __init__(self, code=None, info=None, tag=None, **unknown_fields): - ''' + """ code : str info : str tag : str - ''' + """ code_ = code info_ = info tag_ = tag # Validate arguments against known Juju API types. if code_ is not None and not isinstance(code_, (bytes, str)): - raise Exception("Expected code_ to be a str, received: {}".format(type(code_))) + raise Exception( + "Expected code_ to be a str, received: {}".format(type(code_)) + ) if info_ is not None and not isinstance(info_, (bytes, str)): - raise Exception("Expected info_ to be a str, received: {}".format(type(info_))) + raise Exception( + "Expected info_ to be a str, received: {}".format(type(info_)) + ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception("Expected tag_ to be a str, received: {}".format(type(tag_))) + raise Exception( + "Expected tag_ to be a str, received: {}".format(type(tag_)) + ) self.code = code_ self.info = info_ @@ -9524,36 +15322,54 @@ def __init__(self, code=None, info=None, tag=None, **unknown_fields): self.unknown_fields = unknown_fields - class MeterStatusParams(Type): - _toSchema = {'statues': 'statues'} - _toPy = {'statues': 'statues'} + _toSchema = {"statues": "statues"} + _toPy = {"statues": "statues"} + def __init__(self, statues=None, **unknown_fields): - ''' + """ statues : typing.Sequence[~MeterStatusParam] - ''' + """ statues_ = [MeterStatusParam.from_json(o) for o in statues or []] # Validate arguments against known Juju API types. if statues_ is not None and not isinstance(statues_, (bytes, str, list)): - raise Exception("Expected statues_ to be a Sequence, received: {}".format(type(statues_))) + raise Exception( + "Expected statues_ to be a Sequence, received: {}".format( + type(statues_) + ) + ) self.statues = statues_ self.unknown_fields = unknown_fields - class MetricResult(Type): - _toSchema = {'key': 'key', 'labels': 'labels', 'time': 'time', 'unit': 'unit', 'value': 'value'} - _toPy = {'key': 'key', 'labels': 'labels', 'time': 'time', 'unit': 'unit', 'value': 'value'} - def __init__(self, key=None, labels=None, time=None, unit=None, value=None, **unknown_fields): - ''' + _toSchema = { + "key": "key", + "labels": "labels", + "time": "time", + "unit": "unit", + "value": "value", + } + _toPy = { + "key": "key", + "labels": "labels", + "time": "time", + "unit": "unit", + "value": "value", + } + + def __init__( + self, key=None, labels=None, time=None, unit=None, value=None, **unknown_fields + ): + """ key : str labels : typing.Mapping[str, str] time : str unit : str value : str - ''' + """ key_ = key labels_ = labels time_ = time @@ -9562,19 +15378,29 @@ def __init__(self, key=None, labels=None, time=None, unit=None, value=None, **un # Validate arguments against known Juju API types. if key_ is not None and not isinstance(key_, (bytes, str)): - raise Exception("Expected key_ to be a str, received: {}".format(type(key_))) + raise Exception( + "Expected key_ to be a str, received: {}".format(type(key_)) + ) if labels_ is not None and not isinstance(labels_, dict): - raise Exception("Expected labels_ to be a Mapping, received: {}".format(type(labels_))) + raise Exception( + "Expected labels_ to be a Mapping, received: {}".format(type(labels_)) + ) if time_ is not None and not isinstance(time_, (bytes, str)): - raise Exception("Expected time_ to be a str, received: {}".format(type(time_))) + raise Exception( + "Expected time_ to be a str, received: {}".format(type(time_)) + ) if unit_ is not None and not isinstance(unit_, (bytes, str)): - raise Exception("Expected unit_ to be a str, received: {}".format(type(unit_))) + raise Exception( + "Expected unit_ to be a str, received: {}".format(type(unit_)) + ) if value_ is not None and not isinstance(value_, (bytes, str)): - raise Exception("Expected value_ to be a str, received: {}".format(type(value_))) + raise Exception( + "Expected value_ to be a str, received: {}".format(type(value_)) + ) self.key = key_ self.labels = labels_ @@ -9584,54 +15410,94 @@ def __init__(self, key=None, labels=None, time=None, unit=None, value=None, **un self.unknown_fields = unknown_fields - class MetricResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~EntityMetrics] - ''' + """ results_ = [EntityMetrics.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class MigrationSpec(Type): - _toSchema = {'model_tag': 'model-tag', 'target_info': 'target-info'} - _toPy = {'model-tag': 'model_tag', 'target-info': 'target_info'} + _toSchema = {"model_tag": "model-tag", "target_info": "target-info"} + _toPy = {"model-tag": "model_tag", "target-info": "target_info"} + def __init__(self, model_tag=None, target_info=None, **unknown_fields): - ''' + """ model_tag : str target_info : MigrationTargetInfo - ''' + """ model_tag_ = model_tag - target_info_ = MigrationTargetInfo.from_json(target_info) if target_info else None + target_info_ = ( + MigrationTargetInfo.from_json(target_info) if target_info else None + ) # Validate arguments against known Juju API types. if model_tag_ is not None and not isinstance(model_tag_, (bytes, str)): - raise Exception("Expected model_tag_ to be a str, received: {}".format(type(model_tag_))) - - if target_info_ is not None and not isinstance(target_info_, (dict, MigrationTargetInfo)): - raise Exception("Expected target_info_ to be a MigrationTargetInfo, received: {}".format(type(target_info_))) + raise Exception( + "Expected model_tag_ to be a str, received: {}".format(type(model_tag_)) + ) + + if target_info_ is not None and not isinstance( + target_info_, (dict, MigrationTargetInfo) + ): + raise Exception( + "Expected target_info_ to be a MigrationTargetInfo, received: {}".format( + type(target_info_) + ) + ) self.model_tag = model_tag_ self.target_info = target_info_ self.unknown_fields = unknown_fields - class MigrationTargetInfo(Type): - _toSchema = {'addrs': 'addrs', 'auth_tag': 'auth-tag', 'ca_cert': 'ca-cert', 'controller_alias': 'controller-alias', 'controller_tag': 'controller-tag', 'macaroons': 'macaroons', 'password': 'password'} - _toPy = {'addrs': 'addrs', 'auth-tag': 'auth_tag', 'ca-cert': 'ca_cert', 'controller-alias': 'controller_alias', 'controller-tag': 'controller_tag', 'macaroons': 'macaroons', 'password': 'password'} - def __init__(self, addrs=None, auth_tag=None, ca_cert=None, controller_alias=None, controller_tag=None, macaroons=None, password=None, **unknown_fields): - ''' + _toSchema = { + "addrs": "addrs", + "auth_tag": "auth-tag", + "ca_cert": "ca-cert", + "controller_alias": "controller-alias", + "controller_tag": "controller-tag", + "macaroons": "macaroons", + "password": "password", + } + _toPy = { + "addrs": "addrs", + "auth-tag": "auth_tag", + "ca-cert": "ca_cert", + "controller-alias": "controller_alias", + "controller-tag": "controller_tag", + "macaroons": "macaroons", + "password": "password", + } + + def __init__( + self, + addrs=None, + auth_tag=None, + ca_cert=None, + controller_alias=None, + controller_tag=None, + macaroons=None, + password=None, + **unknown_fields, + ): + """ addrs : typing.Sequence[str] auth_tag : str ca_cert : str @@ -9639,7 +15505,7 @@ def __init__(self, addrs=None, auth_tag=None, ca_cert=None, controller_alias=Non controller_tag : str macaroons : str password : str - ''' + """ addrs_ = addrs auth_tag_ = auth_tag ca_cert_ = ca_cert @@ -9650,25 +15516,47 @@ def __init__(self, addrs=None, auth_tag=None, ca_cert=None, controller_alias=Non # Validate arguments against known Juju API types. if addrs_ is not None and not isinstance(addrs_, (bytes, str, list)): - raise Exception("Expected addrs_ to be a Sequence, received: {}".format(type(addrs_))) + raise Exception( + "Expected addrs_ to be a Sequence, received: {}".format(type(addrs_)) + ) if auth_tag_ is not None and not isinstance(auth_tag_, (bytes, str)): - raise Exception("Expected auth_tag_ to be a str, received: {}".format(type(auth_tag_))) + raise Exception( + "Expected auth_tag_ to be a str, received: {}".format(type(auth_tag_)) + ) if ca_cert_ is not None and not isinstance(ca_cert_, (bytes, str)): - raise Exception("Expected ca_cert_ to be a str, received: {}".format(type(ca_cert_))) - - if controller_alias_ is not None and not isinstance(controller_alias_, (bytes, str)): - raise Exception("Expected controller_alias_ to be a str, received: {}".format(type(controller_alias_))) - - if controller_tag_ is not None and not isinstance(controller_tag_, (bytes, str)): - raise Exception("Expected controller_tag_ to be a str, received: {}".format(type(controller_tag_))) + raise Exception( + "Expected ca_cert_ to be a str, received: {}".format(type(ca_cert_)) + ) + + if controller_alias_ is not None and not isinstance( + controller_alias_, (bytes, str) + ): + raise Exception( + "Expected controller_alias_ to be a str, received: {}".format( + type(controller_alias_) + ) + ) + + if controller_tag_ is not None and not isinstance( + controller_tag_, (bytes, str) + ): + raise Exception( + "Expected controller_tag_ to be a str, received: {}".format( + type(controller_tag_) + ) + ) if macaroons_ is not None and not isinstance(macaroons_, (bytes, str)): - raise Exception("Expected macaroons_ to be a str, received: {}".format(type(macaroons_))) + raise Exception( + "Expected macaroons_ to be a str, received: {}".format(type(macaroons_)) + ) if password_ is not None and not isinstance(password_, (bytes, str)): - raise Exception("Expected password_ to be a str, received: {}".format(type(password_))) + raise Exception( + "Expected password_ to be a str, received: {}".format(type(password_)) + ) self.addrs = addrs_ self.auth_tag = auth_tag_ @@ -9680,17 +15568,24 @@ def __init__(self, addrs=None, auth_tag=None, ca_cert=None, controller_alias=Non self.unknown_fields = unknown_fields - class Model(Type): - _toSchema = {'name': 'name', 'owner_tag': 'owner-tag', 'type_': 'type', 'uuid': 'uuid'} - _toPy = {'name': 'name', 'owner-tag': 'owner_tag', 'type': 'type_', 'uuid': 'uuid'} - def __init__(self, name=None, owner_tag=None, type_=None, uuid=None, **unknown_fields): - ''' + _toSchema = { + "name": "name", + "owner_tag": "owner-tag", + "type_": "type", + "uuid": "uuid", + } + _toPy = {"name": "name", "owner-tag": "owner_tag", "type": "type_", "uuid": "uuid"} + + def __init__( + self, name=None, owner_tag=None, type_=None, uuid=None, **unknown_fields + ): + """ name : str owner_tag : str type_ : str uuid : str - ''' + """ name_ = name owner_tag_ = owner_tag type__ = type_ @@ -9698,16 +15593,24 @@ def __init__(self, name=None, owner_tag=None, type_=None, uuid=None, **unknown_f # Validate arguments against known Juju API types. if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if owner_tag_ is not None and not isinstance(owner_tag_, (bytes, str)): - raise Exception("Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_))) + raise Exception( + "Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_)) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) if uuid_ is not None and not isinstance(uuid_, (bytes, str)): - raise Exception("Expected uuid_ to be a str, received: {}".format(type(uuid_))) + raise Exception( + "Expected uuid_ to be a str, received: {}".format(type(uuid_)) + ) self.name = name_ self.owner_tag = owner_tag_ @@ -9716,59 +15619,77 @@ def __init__(self, name=None, owner_tag=None, type_=None, uuid=None, **unknown_f self.unknown_fields = unknown_fields - class ModelAccess(Type): - _toSchema = {'access': 'access', 'model': 'model'} - _toPy = {'access': 'access', 'model': 'model'} + _toSchema = {"access": "access", "model": "model"} + _toPy = {"access": "access", "model": "model"} + def __init__(self, access=None, model=None, **unknown_fields): - ''' + """ access : str model : str - ''' + """ access_ = access model_ = model # Validate arguments against known Juju API types. if access_ is not None and not isinstance(access_, (bytes, str)): - raise Exception("Expected access_ to be a str, received: {}".format(type(access_))) + raise Exception( + "Expected access_ to be a str, received: {}".format(type(access_)) + ) if model_ is not None and not isinstance(model_, (bytes, str)): - raise Exception("Expected model_ to be a str, received: {}".format(type(model_))) + raise Exception( + "Expected model_ to be a str, received: {}".format(type(model_)) + ) self.access = access_ self.model = model_ self.unknown_fields = unknown_fields - class ModelApplicationInfo(Type): - _toSchema = {'name': 'name'} - _toPy = {'name': 'name'} + _toSchema = {"name": "name"} + _toPy = {"name": "name"} + def __init__(self, name=None, **unknown_fields): - ''' + """ name : str - ''' + """ name_ = name # Validate arguments against known Juju API types. if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) self.name = name_ self.unknown_fields = unknown_fields - class ModelBlockInfo(Type): - _toSchema = {'blocks': 'blocks', 'model_uuid': 'model-uuid', 'name': 'name', 'owner_tag': 'owner-tag'} - _toPy = {'blocks': 'blocks', 'model-uuid': 'model_uuid', 'name': 'name', 'owner-tag': 'owner_tag'} - def __init__(self, blocks=None, model_uuid=None, name=None, owner_tag=None, **unknown_fields): - ''' + _toSchema = { + "blocks": "blocks", + "model_uuid": "model-uuid", + "name": "name", + "owner_tag": "owner-tag", + } + _toPy = { + "blocks": "blocks", + "model-uuid": "model_uuid", + "name": "name", + "owner-tag": "owner_tag", + } + + def __init__( + self, blocks=None, model_uuid=None, name=None, owner_tag=None, **unknown_fields + ): + """ blocks : typing.Sequence[str] model_uuid : str name : str owner_tag : str - ''' + """ blocks_ = blocks model_uuid_ = model_uuid name_ = name @@ -9776,16 +15697,26 @@ def __init__(self, blocks=None, model_uuid=None, name=None, owner_tag=None, **un # Validate arguments against known Juju API types. if blocks_ is not None and not isinstance(blocks_, (bytes, str, list)): - raise Exception("Expected blocks_ to be a Sequence, received: {}".format(type(blocks_))) + raise Exception( + "Expected blocks_ to be a Sequence, received: {}".format(type(blocks_)) + ) if model_uuid_ is not None and not isinstance(model_uuid_, (bytes, str)): - raise Exception("Expected model_uuid_ to be a str, received: {}".format(type(model_uuid_))) + raise Exception( + "Expected model_uuid_ to be a str, received: {}".format( + type(model_uuid_) + ) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if owner_tag_ is not None and not isinstance(owner_tag_, (bytes, str)): - raise Exception("Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_))) + raise Exception( + "Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_)) + ) self.blocks = blocks_ self.model_uuid = model_uuid_ @@ -9794,55 +15725,82 @@ def __init__(self, blocks=None, model_uuid=None, name=None, owner_tag=None, **un self.unknown_fields = unknown_fields - class ModelBlockInfoList(Type): - _toSchema = {'models': 'models'} - _toPy = {'models': 'models'} + _toSchema = {"models": "models"} + _toPy = {"models": "models"} + def __init__(self, models=None, **unknown_fields): - ''' + """ models : typing.Sequence[~ModelBlockInfo] - ''' + """ models_ = [ModelBlockInfo.from_json(o) for o in models or []] # Validate arguments against known Juju API types. if models_ is not None and not isinstance(models_, (bytes, str, list)): - raise Exception("Expected models_ to be a Sequence, received: {}".format(type(models_))) + raise Exception( + "Expected models_ to be a Sequence, received: {}".format(type(models_)) + ) self.models = models_ self.unknown_fields = unknown_fields - class ModelConfigResults(Type): - _toSchema = {'config': 'config'} - _toPy = {'config': 'config'} + _toSchema = {"config": "config"} + _toPy = {"config": "config"} + def __init__(self, config=None, **unknown_fields): - ''' + """ config : typing.Mapping[str, ~ConfigValue] - ''' + """ config_ = {k: ConfigValue.from_json(v) for k, v in (config or dict()).items()} # Validate arguments against known Juju API types. if config_ is not None and not isinstance(config_, dict): - raise Exception("Expected config_ to be a Mapping, received: {}".format(type(config_))) + raise Exception( + "Expected config_ to be a Mapping, received: {}".format(type(config_)) + ) self.config = config_ self.unknown_fields = unknown_fields - class ModelCreateArgs(Type): - _toSchema = {'cloud_tag': 'cloud-tag', 'config': 'config', 'credential': 'credential', 'name': 'name', 'owner_tag': 'owner-tag', 'region': 'region'} - _toPy = {'cloud-tag': 'cloud_tag', 'config': 'config', 'credential': 'credential', 'name': 'name', 'owner-tag': 'owner_tag', 'region': 'region'} - def __init__(self, cloud_tag=None, config=None, credential=None, name=None, owner_tag=None, region=None, **unknown_fields): - ''' + _toSchema = { + "cloud_tag": "cloud-tag", + "config": "config", + "credential": "credential", + "name": "name", + "owner_tag": "owner-tag", + "region": "region", + } + _toPy = { + "cloud-tag": "cloud_tag", + "config": "config", + "credential": "credential", + "name": "name", + "owner-tag": "owner_tag", + "region": "region", + } + + def __init__( + self, + cloud_tag=None, + config=None, + credential=None, + name=None, + owner_tag=None, + region=None, + **unknown_fields, + ): + """ cloud_tag : str config : typing.Mapping[str, typing.Any] credential : str name : str owner_tag : str region : str - ''' + """ cloud_tag_ = cloud_tag config_ = config credential_ = credential @@ -9852,22 +15810,36 @@ def __init__(self, cloud_tag=None, config=None, credential=None, name=None, owne # Validate arguments against known Juju API types. if cloud_tag_ is not None and not isinstance(cloud_tag_, (bytes, str)): - raise Exception("Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_))) + raise Exception( + "Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_)) + ) if config_ is not None and not isinstance(config_, dict): - raise Exception("Expected config_ to be a Mapping, received: {}".format(type(config_))) + raise Exception( + "Expected config_ to be a Mapping, received: {}".format(type(config_)) + ) if credential_ is not None and not isinstance(credential_, (bytes, str)): - raise Exception("Expected credential_ to be a str, received: {}".format(type(credential_))) + raise Exception( + "Expected credential_ to be a str, received: {}".format( + type(credential_) + ) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if owner_tag_ is not None and not isinstance(owner_tag_, (bytes, str)): - raise Exception("Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_))) + raise Exception( + "Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_)) + ) if region_ is not None and not isinstance(region_, (bytes, str)): - raise Exception("Expected region_ to be a str, received: {}".format(type(region_))) + raise Exception( + "Expected region_ to be a str, received: {}".format(type(region_)) + ) self.cloud_tag = cloud_tag_ self.config = config_ @@ -9878,29 +15850,47 @@ def __init__(self, cloud_tag=None, config=None, credential=None, name=None, owne self.unknown_fields = unknown_fields - class ModelDefaultValues(Type): - _toSchema = {'cloud_region': 'cloud-region', 'cloud_tag': 'cloud-tag', 'config': 'config'} - _toPy = {'cloud-region': 'cloud_region', 'cloud-tag': 'cloud_tag', 'config': 'config'} - def __init__(self, cloud_region=None, cloud_tag=None, config=None, **unknown_fields): - ''' + _toSchema = { + "cloud_region": "cloud-region", + "cloud_tag": "cloud-tag", + "config": "config", + } + _toPy = { + "cloud-region": "cloud_region", + "cloud-tag": "cloud_tag", + "config": "config", + } + + def __init__( + self, cloud_region=None, cloud_tag=None, config=None, **unknown_fields + ): + """ cloud_region : str cloud_tag : str config : typing.Mapping[str, typing.Any] - ''' + """ cloud_region_ = cloud_region cloud_tag_ = cloud_tag config_ = config # Validate arguments against known Juju API types. if cloud_region_ is not None and not isinstance(cloud_region_, (bytes, str)): - raise Exception("Expected cloud_region_ to be a str, received: {}".format(type(cloud_region_))) + raise Exception( + "Expected cloud_region_ to be a str, received: {}".format( + type(cloud_region_) + ) + ) if cloud_tag_ is not None and not isinstance(cloud_tag_, (bytes, str)): - raise Exception("Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_))) + raise Exception( + "Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_)) + ) if config_ is not None and not isinstance(config_, dict): - raise Exception("Expected config_ to be a Mapping, received: {}".format(type(config_))) + raise Exception( + "Expected config_ to be a Mapping, received: {}".format(type(config_)) + ) self.cloud_region = cloud_region_ self.cloud_tag = cloud_tag_ @@ -9908,23 +15898,27 @@ def __init__(self, cloud_region=None, cloud_tag=None, config=None, **unknown_fie self.unknown_fields = unknown_fields - class ModelDefaults(Type): - _toSchema = {'controller': 'controller', 'default': 'default', 'regions': 'regions'} - _toPy = {'controller': 'controller', 'default': 'default', 'regions': 'regions'} + _toSchema = {"controller": "controller", "default": "default", "regions": "regions"} + _toPy = {"controller": "controller", "default": "default", "regions": "regions"} + def __init__(self, controller=None, default=None, regions=None, **unknown_fields): - ''' + """ controller : Any default : Any regions : typing.Sequence[~RegionDefaults] - ''' + """ controller_ = controller default_ = default regions_ = [RegionDefaults.from_json(o) for o in regions or []] # Validate arguments against known Juju API types. if regions_ is not None and not isinstance(regions_, (bytes, str, list)): - raise Exception("Expected regions_ to be a Sequence, received: {}".format(type(regions_))) + raise Exception( + "Expected regions_ to be a Sequence, received: {}".format( + type(regions_) + ) + ) self.controller = controller_ self.default = default_ @@ -9932,84 +15926,116 @@ def __init__(self, controller=None, default=None, regions=None, **unknown_fields self.unknown_fields = unknown_fields - class ModelDefaultsResult(Type): - _toSchema = {'config': 'config', 'error': 'error'} - _toPy = {'config': 'config', 'error': 'error'} + _toSchema = {"config": "config", "error": "error"} + _toPy = {"config": "config", "error": "error"} + def __init__(self, config=None, error=None, **unknown_fields): - ''' + """ config : typing.Mapping[str, ~ModelDefaults] error : Error - ''' + """ config_ = {k: ModelDefaults.from_json(v) for k, v in (config or dict()).items()} error_ = Error.from_json(error) if error else None # Validate arguments against known Juju API types. if config_ is not None and not isinstance(config_, dict): - raise Exception("Expected config_ to be a Mapping, received: {}".format(type(config_))) + raise Exception( + "Expected config_ to be a Mapping, received: {}".format(type(config_)) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) self.config = config_ self.error = error_ self.unknown_fields = unknown_fields - class ModelDefaultsResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~ModelDefaultsResult] - ''' + """ results_ = [ModelDefaultsResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class ModelEntityCount(Type): - _toSchema = {'count': 'count', 'entity': 'entity'} - _toPy = {'count': 'count', 'entity': 'entity'} + _toSchema = {"count": "count", "entity": "entity"} + _toPy = {"count": "count", "entity": "entity"} + def __init__(self, count=None, entity=None, **unknown_fields): - ''' + """ count : int entity : str - ''' + """ count_ = count entity_ = entity # Validate arguments against known Juju API types. if count_ is not None and not isinstance(count_, int): - raise Exception("Expected count_ to be a int, received: {}".format(type(count_))) + raise Exception( + "Expected count_ to be a int, received: {}".format(type(count_)) + ) if entity_ is not None and not isinstance(entity_, (bytes, str)): - raise Exception("Expected entity_ to be a str, received: {}".format(type(entity_))) + raise Exception( + "Expected entity_ to be a str, received: {}".format(type(entity_)) + ) self.count = count_ self.entity = entity_ self.unknown_fields = unknown_fields - class ModelFilesystemInfo(Type): - _toSchema = {'detachable': 'detachable', 'id_': 'id', 'message': 'message', 'provider_id': 'provider-id', 'status': 'status'} - _toPy = {'detachable': 'detachable', 'id': 'id_', 'message': 'message', 'provider-id': 'provider_id', 'status': 'status'} - def __init__(self, detachable=None, id_=None, message=None, provider_id=None, status=None, **unknown_fields): - ''' + _toSchema = { + "detachable": "detachable", + "id_": "id", + "message": "message", + "provider_id": "provider-id", + "status": "status", + } + _toPy = { + "detachable": "detachable", + "id": "id_", + "message": "message", + "provider-id": "provider_id", + "status": "status", + } + + def __init__( + self, + detachable=None, + id_=None, + message=None, + provider_id=None, + status=None, + **unknown_fields, + ): + """ detachable : bool id_ : str message : str provider_id : str status : str - ''' + """ detachable_ = detachable id__ = id_ message_ = message @@ -10018,19 +16044,33 @@ def __init__(self, detachable=None, id_=None, message=None, provider_id=None, st # Validate arguments against known Juju API types. if detachable_ is not None and not isinstance(detachable_, bool): - raise Exception("Expected detachable_ to be a bool, received: {}".format(type(detachable_))) + raise Exception( + "Expected detachable_ to be a bool, received: {}".format( + type(detachable_) + ) + ) if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception("Expected id__ to be a str, received: {}".format(type(id__))) + raise Exception( + "Expected id__ to be a str, received: {}".format(type(id__)) + ) if message_ is not None and not isinstance(message_, (bytes, str)): - raise Exception("Expected message_ to be a str, received: {}".format(type(message_))) + raise Exception( + "Expected message_ to be a str, received: {}".format(type(message_)) + ) if provider_id_ is not None and not isinstance(provider_id_, (bytes, str)): - raise Exception("Expected provider_id_ to be a str, received: {}".format(type(provider_id_))) + raise Exception( + "Expected provider_id_ to be a str, received: {}".format( + type(provider_id_) + ) + ) if status_ is not None and not isinstance(status_, (bytes, str)): - raise Exception("Expected status_ to be a str, received: {}".format(type(status_))) + raise Exception( + "Expected status_ to be a str, received: {}".format(type(status_)) + ) self.detachable = detachable_ self.id_ = id__ @@ -10040,12 +16080,83 @@ def __init__(self, detachable=None, id_=None, message=None, provider_id=None, st self.unknown_fields = unknown_fields - class ModelInfo(Type): - _toSchema = {'agent_version': 'agent-version', 'cloud_credential_tag': 'cloud-credential-tag', 'cloud_credential_validity': 'cloud-credential-validity', 'cloud_region': 'cloud-region', 'cloud_tag': 'cloud-tag', 'controller_uuid': 'controller-uuid', 'default_base': 'default-base', 'default_series': 'default-series', 'is_controller': 'is-controller', 'life': 'life', 'machines': 'machines', 'migration': 'migration', 'name': 'name', 'owner_tag': 'owner-tag', 'provider_type': 'provider-type', 'secret_backends': 'secret-backends', 'sla': 'sla', 'status': 'status', 'supported_features': 'supported-features', 'type_': 'type', 'users': 'users', 'uuid': 'uuid'} - _toPy = {'agent-version': 'agent_version', 'cloud-credential-tag': 'cloud_credential_tag', 'cloud-credential-validity': 'cloud_credential_validity', 'cloud-region': 'cloud_region', 'cloud-tag': 'cloud_tag', 'controller-uuid': 'controller_uuid', 'default-base': 'default_base', 'default-series': 'default_series', 'is-controller': 'is_controller', 'life': 'life', 'machines': 'machines', 'migration': 'migration', 'name': 'name', 'owner-tag': 'owner_tag', 'provider-type': 'provider_type', 'secret-backends': 'secret_backends', 'sla': 'sla', 'status': 'status', 'supported-features': 'supported_features', 'type': 'type_', 'users': 'users', 'uuid': 'uuid'} - def __init__(self, agent_version=None, cloud_credential_tag=None, cloud_credential_validity=None, cloud_region=None, cloud_tag=None, controller_uuid=None, default_base=None, default_series=None, is_controller=None, life=None, machines=None, migration=None, name=None, owner_tag=None, provider_type=None, secret_backends=None, sla=None, status=None, supported_features=None, type_=None, users=None, uuid=None, **unknown_fields): - ''' + _toSchema = { + "agent_version": "agent-version", + "cloud_credential_tag": "cloud-credential-tag", + "cloud_credential_validity": "cloud-credential-validity", + "cloud_region": "cloud-region", + "cloud_tag": "cloud-tag", + "controller_uuid": "controller-uuid", + "default_base": "default-base", + "default_series": "default-series", + "is_controller": "is-controller", + "life": "life", + "machines": "machines", + "migration": "migration", + "name": "name", + "owner_tag": "owner-tag", + "provider_type": "provider-type", + "secret_backends": "secret-backends", + "sla": "sla", + "status": "status", + "supported_features": "supported-features", + "type_": "type", + "users": "users", + "uuid": "uuid", + } + _toPy = { + "agent-version": "agent_version", + "cloud-credential-tag": "cloud_credential_tag", + "cloud-credential-validity": "cloud_credential_validity", + "cloud-region": "cloud_region", + "cloud-tag": "cloud_tag", + "controller-uuid": "controller_uuid", + "default-base": "default_base", + "default-series": "default_series", + "is-controller": "is_controller", + "life": "life", + "machines": "machines", + "migration": "migration", + "name": "name", + "owner-tag": "owner_tag", + "provider-type": "provider_type", + "secret-backends": "secret_backends", + "sla": "sla", + "status": "status", + "supported-features": "supported_features", + "type": "type_", + "users": "users", + "uuid": "uuid", + } + + def __init__( + self, + agent_version=None, + cloud_credential_tag=None, + cloud_credential_validity=None, + cloud_region=None, + cloud_tag=None, + controller_uuid=None, + default_base=None, + default_series=None, + is_controller=None, + life=None, + machines=None, + migration=None, + name=None, + owner_tag=None, + provider_type=None, + secret_backends=None, + sla=None, + status=None, + supported_features=None, + type_=None, + users=None, + uuid=None, + **unknown_fields, + ): + """ agent_version : Number cloud_credential_tag : str cloud_credential_validity : bool @@ -10068,7 +16179,7 @@ def __init__(self, agent_version=None, cloud_credential_tag=None, cloud_credenti type_ : str users : typing.Sequence[~ModelUserInfo] uuid : str - ''' + """ agent_version_ = Number.from_json(agent_version) if agent_version else None cloud_credential_tag_ = cloud_credential_tag cloud_credential_validity_ = cloud_credential_validity @@ -10084,80 +16195,172 @@ def __init__(self, agent_version=None, cloud_credential_tag=None, cloud_credenti name_ = name owner_tag_ = owner_tag provider_type_ = provider_type - secret_backends_ = [SecretBackendResult.from_json(o) for o in secret_backends or []] + secret_backends_ = [ + SecretBackendResult.from_json(o) for o in secret_backends or [] + ] sla_ = ModelSLAInfo.from_json(sla) if sla else None status_ = EntityStatus.from_json(status) if status else None - supported_features_ = [SupportedFeature.from_json(o) for o in supported_features or []] + supported_features_ = [ + SupportedFeature.from_json(o) for o in supported_features or [] + ] type__ = type_ users_ = [ModelUserInfo.from_json(o) for o in users or []] uuid_ = uuid # Validate arguments against known Juju API types. - if agent_version_ is not None and not isinstance(agent_version_, (dict, Number)): - raise Exception("Expected agent_version_ to be a Number, received: {}".format(type(agent_version_))) - - if cloud_credential_tag_ is not None and not isinstance(cloud_credential_tag_, (bytes, str)): - raise Exception("Expected cloud_credential_tag_ to be a str, received: {}".format(type(cloud_credential_tag_))) - - if cloud_credential_validity_ is not None and not isinstance(cloud_credential_validity_, bool): - raise Exception("Expected cloud_credential_validity_ to be a bool, received: {}".format(type(cloud_credential_validity_))) + if agent_version_ is not None and not isinstance( + agent_version_, (dict, Number) + ): + raise Exception( + "Expected agent_version_ to be a Number, received: {}".format( + type(agent_version_) + ) + ) + + if cloud_credential_tag_ is not None and not isinstance( + cloud_credential_tag_, (bytes, str) + ): + raise Exception( + "Expected cloud_credential_tag_ to be a str, received: {}".format( + type(cloud_credential_tag_) + ) + ) + + if cloud_credential_validity_ is not None and not isinstance( + cloud_credential_validity_, bool + ): + raise Exception( + "Expected cloud_credential_validity_ to be a bool, received: {}".format( + type(cloud_credential_validity_) + ) + ) if cloud_region_ is not None and not isinstance(cloud_region_, (bytes, str)): - raise Exception("Expected cloud_region_ to be a str, received: {}".format(type(cloud_region_))) + raise Exception( + "Expected cloud_region_ to be a str, received: {}".format( + type(cloud_region_) + ) + ) if cloud_tag_ is not None and not isinstance(cloud_tag_, (bytes, str)): - raise Exception("Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_))) - - if controller_uuid_ is not None and not isinstance(controller_uuid_, (bytes, str)): - raise Exception("Expected controller_uuid_ to be a str, received: {}".format(type(controller_uuid_))) + raise Exception( + "Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_)) + ) + + if controller_uuid_ is not None and not isinstance( + controller_uuid_, (bytes, str) + ): + raise Exception( + "Expected controller_uuid_ to be a str, received: {}".format( + type(controller_uuid_) + ) + ) if default_base_ is not None and not isinstance(default_base_, (bytes, str)): - raise Exception("Expected default_base_ to be a str, received: {}".format(type(default_base_))) - - if default_series_ is not None and not isinstance(default_series_, (bytes, str)): - raise Exception("Expected default_series_ to be a str, received: {}".format(type(default_series_))) + raise Exception( + "Expected default_base_ to be a str, received: {}".format( + type(default_base_) + ) + ) + + if default_series_ is not None and not isinstance( + default_series_, (bytes, str) + ): + raise Exception( + "Expected default_series_ to be a str, received: {}".format( + type(default_series_) + ) + ) if is_controller_ is not None and not isinstance(is_controller_, bool): - raise Exception("Expected is_controller_ to be a bool, received: {}".format(type(is_controller_))) + raise Exception( + "Expected is_controller_ to be a bool, received: {}".format( + type(is_controller_) + ) + ) if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception("Expected life_ to be a str, received: {}".format(type(life_))) + raise Exception( + "Expected life_ to be a str, received: {}".format(type(life_)) + ) if machines_ is not None and not isinstance(machines_, (bytes, str, list)): - raise Exception("Expected machines_ to be a Sequence, received: {}".format(type(machines_))) - - if migration_ is not None and not isinstance(migration_, (dict, ModelMigrationStatus)): - raise Exception("Expected migration_ to be a ModelMigrationStatus, received: {}".format(type(migration_))) + raise Exception( + "Expected machines_ to be a Sequence, received: {}".format( + type(machines_) + ) + ) + + if migration_ is not None and not isinstance( + migration_, (dict, ModelMigrationStatus) + ): + raise Exception( + "Expected migration_ to be a ModelMigrationStatus, received: {}".format( + type(migration_) + ) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if owner_tag_ is not None and not isinstance(owner_tag_, (bytes, str)): - raise Exception("Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_))) + raise Exception( + "Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_)) + ) if provider_type_ is not None and not isinstance(provider_type_, (bytes, str)): - raise Exception("Expected provider_type_ to be a str, received: {}".format(type(provider_type_))) - - if secret_backends_ is not None and not isinstance(secret_backends_, (bytes, str, list)): - raise Exception("Expected secret_backends_ to be a Sequence, received: {}".format(type(secret_backends_))) + raise Exception( + "Expected provider_type_ to be a str, received: {}".format( + type(provider_type_) + ) + ) + + if secret_backends_ is not None and not isinstance( + secret_backends_, (bytes, str, list) + ): + raise Exception( + "Expected secret_backends_ to be a Sequence, received: {}".format( + type(secret_backends_) + ) + ) if sla_ is not None and not isinstance(sla_, (dict, ModelSLAInfo)): - raise Exception("Expected sla_ to be a ModelSLAInfo, received: {}".format(type(sla_))) + raise Exception( + "Expected sla_ to be a ModelSLAInfo, received: {}".format(type(sla_)) + ) if status_ is not None and not isinstance(status_, (dict, EntityStatus)): - raise Exception("Expected status_ to be a EntityStatus, received: {}".format(type(status_))) - - if supported_features_ is not None and not isinstance(supported_features_, (bytes, str, list)): - raise Exception("Expected supported_features_ to be a Sequence, received: {}".format(type(supported_features_))) + raise Exception( + "Expected status_ to be a EntityStatus, received: {}".format( + type(status_) + ) + ) + + if supported_features_ is not None and not isinstance( + supported_features_, (bytes, str, list) + ): + raise Exception( + "Expected supported_features_ to be a Sequence, received: {}".format( + type(supported_features_) + ) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) if users_ is not None and not isinstance(users_, (bytes, str, list)): - raise Exception("Expected users_ to be a Sequence, received: {}".format(type(users_))) + raise Exception( + "Expected users_ to be a Sequence, received: {}".format(type(users_)) + ) if uuid_ is not None and not isinstance(uuid_, (bytes, str)): - raise Exception("Expected uuid_ to be a str, received: {}".format(type(uuid_))) + raise Exception( + "Expected uuid_ to be a str, received: {}".format(type(uuid_)) + ) self.agent_version = agent_version_ self.cloud_credential_tag = cloud_credential_tag_ @@ -10184,90 +16387,140 @@ def __init__(self, agent_version=None, cloud_credential_tag=None, cloud_credenti self.unknown_fields = unknown_fields - class ModelInfoResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : ModelInfo - ''' + """ error_ = Error.from_json(error) if error else None result_ = ModelInfo.from_json(result) if result else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if result_ is not None and not isinstance(result_, (dict, ModelInfo)): - raise Exception("Expected result_ to be a ModelInfo, received: {}".format(type(result_))) + raise Exception( + "Expected result_ to be a ModelInfo, received: {}".format(type(result_)) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class ModelInfoResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~ModelInfoResult] - ''' + """ results_ = [ModelInfoResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class ModelInstanceTypesConstraint(Type): - _toSchema = {'value': 'value'} - _toPy = {'value': 'value'} + _toSchema = {"value": "value"} + _toPy = {"value": "value"} + def __init__(self, value=None, **unknown_fields): - ''' + """ value : Value - ''' + """ value_ = Value.from_json(value) if value else None # Validate arguments against known Juju API types. if value_ is not None and not isinstance(value_, (dict, Value)): - raise Exception("Expected value_ to be a Value, received: {}".format(type(value_))) + raise Exception( + "Expected value_ to be a Value, received: {}".format(type(value_)) + ) self.value = value_ self.unknown_fields = unknown_fields - class ModelInstanceTypesConstraints(Type): - _toSchema = {'constraints': 'constraints'} - _toPy = {'constraints': 'constraints'} + _toSchema = {"constraints": "constraints"} + _toPy = {"constraints": "constraints"} + def __init__(self, constraints=None, **unknown_fields): - ''' + """ constraints : typing.Sequence[~ModelInstanceTypesConstraint] - ''' - constraints_ = [ModelInstanceTypesConstraint.from_json(o) for o in constraints or []] + """ + constraints_ = [ + ModelInstanceTypesConstraint.from_json(o) for o in constraints or [] + ] # Validate arguments against known Juju API types. - if constraints_ is not None and not isinstance(constraints_, (bytes, str, list)): - raise Exception("Expected constraints_ to be a Sequence, received: {}".format(type(constraints_))) + if constraints_ is not None and not isinstance( + constraints_, (bytes, str, list) + ): + raise Exception( + "Expected constraints_ to be a Sequence, received: {}".format( + type(constraints_) + ) + ) self.constraints = constraints_ self.unknown_fields = unknown_fields - class ModelMachineInfo(Type): - _toSchema = {'display_name': 'display-name', 'ha_primary': 'ha-primary', 'hardware': 'hardware', 'has_vote': 'has-vote', 'id_': 'id', 'instance_id': 'instance-id', 'message': 'message', 'status': 'status', 'wants_vote': 'wants-vote'} - _toPy = {'display-name': 'display_name', 'ha-primary': 'ha_primary', 'hardware': 'hardware', 'has-vote': 'has_vote', 'id': 'id_', 'instance-id': 'instance_id', 'message': 'message', 'status': 'status', 'wants-vote': 'wants_vote'} - def __init__(self, display_name=None, ha_primary=None, hardware=None, has_vote=None, id_=None, instance_id=None, message=None, status=None, wants_vote=None, **unknown_fields): - ''' + _toSchema = { + "display_name": "display-name", + "ha_primary": "ha-primary", + "hardware": "hardware", + "has_vote": "has-vote", + "id_": "id", + "instance_id": "instance-id", + "message": "message", + "status": "status", + "wants_vote": "wants-vote", + } + _toPy = { + "display-name": "display_name", + "ha-primary": "ha_primary", + "hardware": "hardware", + "has-vote": "has_vote", + "id": "id_", + "instance-id": "instance_id", + "message": "message", + "status": "status", + "wants-vote": "wants_vote", + } + + def __init__( + self, + display_name=None, + ha_primary=None, + hardware=None, + has_vote=None, + id_=None, + instance_id=None, + message=None, + status=None, + wants_vote=None, + **unknown_fields, + ): + """ display_name : str ha_primary : bool hardware : MachineHardware @@ -10277,7 +16530,7 @@ def __init__(self, display_name=None, ha_primary=None, hardware=None, has_vote=N message : str status : str wants_vote : bool - ''' + """ display_name_ = display_name ha_primary_ = ha_primary hardware_ = MachineHardware.from_json(hardware) if hardware else None @@ -10290,31 +16543,59 @@ def __init__(self, display_name=None, ha_primary=None, hardware=None, has_vote=N # Validate arguments against known Juju API types. if display_name_ is not None and not isinstance(display_name_, (bytes, str)): - raise Exception("Expected display_name_ to be a str, received: {}".format(type(display_name_))) + raise Exception( + "Expected display_name_ to be a str, received: {}".format( + type(display_name_) + ) + ) if ha_primary_ is not None and not isinstance(ha_primary_, bool): - raise Exception("Expected ha_primary_ to be a bool, received: {}".format(type(ha_primary_))) + raise Exception( + "Expected ha_primary_ to be a bool, received: {}".format( + type(ha_primary_) + ) + ) if hardware_ is not None and not isinstance(hardware_, (dict, MachineHardware)): - raise Exception("Expected hardware_ to be a MachineHardware, received: {}".format(type(hardware_))) + raise Exception( + "Expected hardware_ to be a MachineHardware, received: {}".format( + type(hardware_) + ) + ) if has_vote_ is not None and not isinstance(has_vote_, bool): - raise Exception("Expected has_vote_ to be a bool, received: {}".format(type(has_vote_))) + raise Exception( + "Expected has_vote_ to be a bool, received: {}".format(type(has_vote_)) + ) if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception("Expected id__ to be a str, received: {}".format(type(id__))) + raise Exception( + "Expected id__ to be a str, received: {}".format(type(id__)) + ) if instance_id_ is not None and not isinstance(instance_id_, (bytes, str)): - raise Exception("Expected instance_id_ to be a str, received: {}".format(type(instance_id_))) + raise Exception( + "Expected instance_id_ to be a str, received: {}".format( + type(instance_id_) + ) + ) if message_ is not None and not isinstance(message_, (bytes, str)): - raise Exception("Expected message_ to be a str, received: {}".format(type(message_))) + raise Exception( + "Expected message_ to be a str, received: {}".format(type(message_)) + ) if status_ is not None and not isinstance(status_, (bytes, str)): - raise Exception("Expected status_ to be a str, received: {}".format(type(status_))) + raise Exception( + "Expected status_ to be a str, received: {}".format(type(status_)) + ) if wants_vote_ is not None and not isinstance(wants_vote_, bool): - raise Exception("Expected wants_vote_ to be a bool, received: {}".format(type(wants_vote_))) + raise Exception( + "Expected wants_vote_ to be a bool, received: {}".format( + type(wants_vote_) + ) + ) self.display_name = display_name_ self.ha_primary = ha_primary_ @@ -10328,29 +16609,35 @@ def __init__(self, display_name=None, ha_primary=None, hardware=None, has_vote=N self.unknown_fields = unknown_fields - class ModelMigrationStatus(Type): - _toSchema = {'end': 'end', 'start': 'start', 'status': 'status'} - _toPy = {'end': 'end', 'start': 'start', 'status': 'status'} + _toSchema = {"end": "end", "start": "start", "status": "status"} + _toPy = {"end": "end", "start": "start", "status": "status"} + def __init__(self, end=None, start=None, status=None, **unknown_fields): - ''' + """ end : str start : str status : str - ''' + """ end_ = end start_ = start status_ = status # Validate arguments against known Juju API types. if end_ is not None and not isinstance(end_, (bytes, str)): - raise Exception("Expected end_ to be a str, received: {}".format(type(end_))) + raise Exception( + "Expected end_ to be a str, received: {}".format(type(end_)) + ) if start_ is not None and not isinstance(start_, (bytes, str)): - raise Exception("Expected start_ to be a str, received: {}".format(type(start_))) + raise Exception( + "Expected start_ to be a str, received: {}".format(type(start_)) + ) if status_ is not None and not isinstance(status_, (bytes, str)): - raise Exception("Expected status_ to be a str, received: {}".format(type(status_))) + raise Exception( + "Expected status_ to be a str, received: {}".format(type(status_)) + ) self.end = end_ self.start = start_ @@ -10358,52 +16645,78 @@ def __init__(self, end=None, start=None, status=None, **unknown_fields): self.unknown_fields = unknown_fields - class ModelParam(Type): - _toSchema = {'model_tag': 'model-tag'} - _toPy = {'model-tag': 'model_tag'} + _toSchema = {"model_tag": "model-tag"} + _toPy = {"model-tag": "model_tag"} + def __init__(self, model_tag=None, **unknown_fields): - ''' + """ model_tag : str - ''' + """ model_tag_ = model_tag # Validate arguments against known Juju API types. if model_tag_ is not None and not isinstance(model_tag_, (bytes, str)): - raise Exception("Expected model_tag_ to be a str, received: {}".format(type(model_tag_))) + raise Exception( + "Expected model_tag_ to be a str, received: {}".format(type(model_tag_)) + ) self.model_tag = model_tag_ self.unknown_fields = unknown_fields - class ModelSLA(Type): - _toSchema = {'creds': 'creds', 'level': 'level', 'modelslainfo': 'ModelSLAInfo', 'owner': 'owner'} - _toPy = {'ModelSLAInfo': 'modelslainfo', 'creds': 'creds', 'level': 'level', 'owner': 'owner'} - def __init__(self, modelslainfo=None, creds=None, level=None, owner=None, **unknown_fields): - ''' + _toSchema = { + "creds": "creds", + "level": "level", + "modelslainfo": "ModelSLAInfo", + "owner": "owner", + } + _toPy = { + "ModelSLAInfo": "modelslainfo", + "creds": "creds", + "level": "level", + "owner": "owner", + } + + def __init__( + self, modelslainfo=None, creds=None, level=None, owner=None, **unknown_fields + ): + """ modelslainfo : ModelSLAInfo creds : typing.Sequence[int] level : str owner : str - ''' + """ modelslainfo_ = ModelSLAInfo.from_json(modelslainfo) if modelslainfo else None creds_ = creds level_ = level owner_ = owner # Validate arguments against known Juju API types. - if modelslainfo_ is not None and not isinstance(modelslainfo_, (dict, ModelSLAInfo)): - raise Exception("Expected modelslainfo_ to be a ModelSLAInfo, received: {}".format(type(modelslainfo_))) + if modelslainfo_ is not None and not isinstance( + modelslainfo_, (dict, ModelSLAInfo) + ): + raise Exception( + "Expected modelslainfo_ to be a ModelSLAInfo, received: {}".format( + type(modelslainfo_) + ) + ) if creds_ is not None and not isinstance(creds_, (bytes, str, list)): - raise Exception("Expected creds_ to be a Sequence, received: {}".format(type(creds_))) + raise Exception( + "Expected creds_ to be a Sequence, received: {}".format(type(creds_)) + ) if level_ is not None and not isinstance(level_, (bytes, str)): - raise Exception("Expected level_ to be a str, received: {}".format(type(level_))) + raise Exception( + "Expected level_ to be a str, received: {}".format(type(level_)) + ) if owner_ is not None and not isinstance(owner_, (bytes, str)): - raise Exception("Expected owner_ to be a str, received: {}".format(type(owner_))) + raise Exception( + "Expected owner_ to be a str, received: {}".format(type(owner_)) + ) self.modelslainfo = modelslainfo_ self.creds = creds_ @@ -10412,72 +16725,123 @@ def __init__(self, modelslainfo=None, creds=None, level=None, owner=None, **unkn self.unknown_fields = unknown_fields - class ModelSLAInfo(Type): - _toSchema = {'level': 'level', 'owner': 'owner'} - _toPy = {'level': 'level', 'owner': 'owner'} + _toSchema = {"level": "level", "owner": "owner"} + _toPy = {"level": "level", "owner": "owner"} + def __init__(self, level=None, owner=None, **unknown_fields): - ''' + """ level : str owner : str - ''' + """ level_ = level owner_ = owner # Validate arguments against known Juju API types. if level_ is not None and not isinstance(level_, (bytes, str)): - raise Exception("Expected level_ to be a str, received: {}".format(type(level_))) + raise Exception( + "Expected level_ to be a str, received: {}".format(type(level_)) + ) if owner_ is not None and not isinstance(owner_, (bytes, str)): - raise Exception("Expected owner_ to be a str, received: {}".format(type(owner_))) + raise Exception( + "Expected owner_ to be a str, received: {}".format(type(owner_)) + ) self.level = level_ self.owner = owner_ self.unknown_fields = unknown_fields - class ModelSequencesResult(Type): - _toSchema = {'sequences': 'sequences'} - _toPy = {'sequences': 'sequences'} + _toSchema = {"sequences": "sequences"} + _toPy = {"sequences": "sequences"} + def __init__(self, sequences=None, **unknown_fields): - ''' + """ sequences : typing.Mapping[str, int] - ''' + """ sequences_ = sequences # Validate arguments against known Juju API types. if sequences_ is not None and not isinstance(sequences_, dict): - raise Exception("Expected sequences_ to be a Mapping, received: {}".format(type(sequences_))) + raise Exception( + "Expected sequences_ to be a Mapping, received: {}".format( + type(sequences_) + ) + ) self.sequences = sequences_ self.unknown_fields = unknown_fields - class ModelSet(Type): - _toSchema = {'config': 'config'} - _toPy = {'config': 'config'} + _toSchema = {"config": "config"} + _toPy = {"config": "config"} + def __init__(self, config=None, **unknown_fields): - ''' + """ config : typing.Mapping[str, typing.Any] - ''' + """ config_ = config # Validate arguments against known Juju API types. if config_ is not None and not isinstance(config_, dict): - raise Exception("Expected config_ to be a Mapping, received: {}".format(type(config_))) + raise Exception( + "Expected config_ to be a Mapping, received: {}".format(type(config_)) + ) self.config = config_ self.unknown_fields = unknown_fields - class ModelStatus(Type): - _toSchema = {'application_count': 'application-count', 'applications': 'applications', 'error': 'error', 'filesystems': 'filesystems', 'hosted_machine_count': 'hosted-machine-count', 'life': 'life', 'machines': 'machines', 'model_tag': 'model-tag', 'owner_tag': 'owner-tag', 'type_': 'type', 'unit_count': 'unit-count', 'volumes': 'volumes'} - _toPy = {'application-count': 'application_count', 'applications': 'applications', 'error': 'error', 'filesystems': 'filesystems', 'hosted-machine-count': 'hosted_machine_count', 'life': 'life', 'machines': 'machines', 'model-tag': 'model_tag', 'owner-tag': 'owner_tag', 'type': 'type_', 'unit-count': 'unit_count', 'volumes': 'volumes'} - def __init__(self, application_count=None, applications=None, error=None, filesystems=None, hosted_machine_count=None, life=None, machines=None, model_tag=None, owner_tag=None, type_=None, unit_count=None, volumes=None, **unknown_fields): - ''' + _toSchema = { + "application_count": "application-count", + "applications": "applications", + "error": "error", + "filesystems": "filesystems", + "hosted_machine_count": "hosted-machine-count", + "life": "life", + "machines": "machines", + "model_tag": "model-tag", + "owner_tag": "owner-tag", + "type_": "type", + "unit_count": "unit-count", + "volumes": "volumes", + } + _toPy = { + "application-count": "application_count", + "applications": "applications", + "error": "error", + "filesystems": "filesystems", + "hosted-machine-count": "hosted_machine_count", + "life": "life", + "machines": "machines", + "model-tag": "model_tag", + "owner-tag": "owner_tag", + "type": "type_", + "unit-count": "unit_count", + "volumes": "volumes", + } + + def __init__( + self, + application_count=None, + applications=None, + error=None, + filesystems=None, + hosted_machine_count=None, + life=None, + machines=None, + model_tag=None, + owner_tag=None, + type_=None, + unit_count=None, + volumes=None, + **unknown_fields, + ): + """ application_count : int applications : typing.Sequence[~ModelApplicationInfo] error : Error @@ -10490,7 +16854,7 @@ def __init__(self, application_count=None, applications=None, error=None, filesy type_ : str unit_count : int volumes : typing.Sequence[~ModelVolumeInfo] - ''' + """ application_count_ = application_count applications_ = [ModelApplicationInfo.from_json(o) for o in applications or []] error_ = Error.from_json(error) if error else None @@ -10506,40 +16870,84 @@ def __init__(self, application_count=None, applications=None, error=None, filesy # Validate arguments against known Juju API types. if application_count_ is not None and not isinstance(application_count_, int): - raise Exception("Expected application_count_ to be a int, received: {}".format(type(application_count_))) - - if applications_ is not None and not isinstance(applications_, (bytes, str, list)): - raise Exception("Expected applications_ to be a Sequence, received: {}".format(type(applications_))) + raise Exception( + "Expected application_count_ to be a int, received: {}".format( + type(application_count_) + ) + ) + + if applications_ is not None and not isinstance( + applications_, (bytes, str, list) + ): + raise Exception( + "Expected applications_ to be a Sequence, received: {}".format( + type(applications_) + ) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) - - if filesystems_ is not None and not isinstance(filesystems_, (bytes, str, list)): - raise Exception("Expected filesystems_ to be a Sequence, received: {}".format(type(filesystems_))) - - if hosted_machine_count_ is not None and not isinstance(hosted_machine_count_, int): - raise Exception("Expected hosted_machine_count_ to be a int, received: {}".format(type(hosted_machine_count_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) + + if filesystems_ is not None and not isinstance( + filesystems_, (bytes, str, list) + ): + raise Exception( + "Expected filesystems_ to be a Sequence, received: {}".format( + type(filesystems_) + ) + ) + + if hosted_machine_count_ is not None and not isinstance( + hosted_machine_count_, int + ): + raise Exception( + "Expected hosted_machine_count_ to be a int, received: {}".format( + type(hosted_machine_count_) + ) + ) if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception("Expected life_ to be a str, received: {}".format(type(life_))) + raise Exception( + "Expected life_ to be a str, received: {}".format(type(life_)) + ) if machines_ is not None and not isinstance(machines_, (bytes, str, list)): - raise Exception("Expected machines_ to be a Sequence, received: {}".format(type(machines_))) + raise Exception( + "Expected machines_ to be a Sequence, received: {}".format( + type(machines_) + ) + ) if model_tag_ is not None and not isinstance(model_tag_, (bytes, str)): - raise Exception("Expected model_tag_ to be a str, received: {}".format(type(model_tag_))) + raise Exception( + "Expected model_tag_ to be a str, received: {}".format(type(model_tag_)) + ) if owner_tag_ is not None and not isinstance(owner_tag_, (bytes, str)): - raise Exception("Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_))) + raise Exception( + "Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_)) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) if unit_count_ is not None and not isinstance(unit_count_, int): - raise Exception("Expected unit_count_ to be a int, received: {}".format(type(unit_count_))) + raise Exception( + "Expected unit_count_ to be a int, received: {}".format( + type(unit_count_) + ) + ) if volumes_ is not None and not isinstance(volumes_, (bytes, str, list)): - raise Exception("Expected volumes_ to be a Sequence, received: {}".format(type(volumes_))) + raise Exception( + "Expected volumes_ to be a Sequence, received: {}".format( + type(volumes_) + ) + ) self.application_count = application_count_ self.applications = applications_ @@ -10556,12 +16964,44 @@ def __init__(self, application_count=None, applications=None, error=None, filesy self.unknown_fields = unknown_fields - class ModelStatusInfo(Type): - _toSchema = {'available_version': 'available-version', 'cloud_tag': 'cloud-tag', 'meter_status': 'meter-status', 'model_status': 'model-status', 'name': 'name', 'region': 'region', 'sla': 'sla', 'type_': 'type', 'version': 'version'} - _toPy = {'available-version': 'available_version', 'cloud-tag': 'cloud_tag', 'meter-status': 'meter_status', 'model-status': 'model_status', 'name': 'name', 'region': 'region', 'sla': 'sla', 'type': 'type_', 'version': 'version'} - def __init__(self, available_version=None, cloud_tag=None, meter_status=None, model_status=None, name=None, region=None, sla=None, type_=None, version=None, **unknown_fields): - ''' + _toSchema = { + "available_version": "available-version", + "cloud_tag": "cloud-tag", + "meter_status": "meter-status", + "model_status": "model-status", + "name": "name", + "region": "region", + "sla": "sla", + "type_": "type", + "version": "version", + } + _toPy = { + "available-version": "available_version", + "cloud-tag": "cloud_tag", + "meter-status": "meter_status", + "model-status": "model_status", + "name": "name", + "region": "region", + "sla": "sla", + "type": "type_", + "version": "version", + } + + def __init__( + self, + available_version=None, + cloud_tag=None, + meter_status=None, + model_status=None, + name=None, + region=None, + sla=None, + type_=None, + version=None, + **unknown_fields, + ): + """ available_version : str cloud_tag : str meter_status : MeterStatus @@ -10571,7 +17011,7 @@ def __init__(self, available_version=None, cloud_tag=None, meter_status=None, mo sla : str type_ : str version : str - ''' + """ available_version_ = available_version cloud_tag_ = cloud_tag meter_status_ = MeterStatus.from_json(meter_status) if meter_status else None @@ -10583,32 +17023,62 @@ def __init__(self, available_version=None, cloud_tag=None, meter_status=None, mo version_ = version # Validate arguments against known Juju API types. - if available_version_ is not None and not isinstance(available_version_, (bytes, str)): - raise Exception("Expected available_version_ to be a str, received: {}".format(type(available_version_))) + if available_version_ is not None and not isinstance( + available_version_, (bytes, str) + ): + raise Exception( + "Expected available_version_ to be a str, received: {}".format( + type(available_version_) + ) + ) if cloud_tag_ is not None and not isinstance(cloud_tag_, (bytes, str)): - raise Exception("Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_))) - - if meter_status_ is not None and not isinstance(meter_status_, (dict, MeterStatus)): - raise Exception("Expected meter_status_ to be a MeterStatus, received: {}".format(type(meter_status_))) - - if model_status_ is not None and not isinstance(model_status_, (dict, DetailedStatus)): - raise Exception("Expected model_status_ to be a DetailedStatus, received: {}".format(type(model_status_))) + raise Exception( + "Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_)) + ) + + if meter_status_ is not None and not isinstance( + meter_status_, (dict, MeterStatus) + ): + raise Exception( + "Expected meter_status_ to be a MeterStatus, received: {}".format( + type(meter_status_) + ) + ) + + if model_status_ is not None and not isinstance( + model_status_, (dict, DetailedStatus) + ): + raise Exception( + "Expected model_status_ to be a DetailedStatus, received: {}".format( + type(model_status_) + ) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if region_ is not None and not isinstance(region_, (bytes, str)): - raise Exception("Expected region_ to be a str, received: {}".format(type(region_))) + raise Exception( + "Expected region_ to be a str, received: {}".format(type(region_)) + ) if sla_ is not None and not isinstance(sla_, (bytes, str)): - raise Exception("Expected sla_ to be a str, received: {}".format(type(sla_))) + raise Exception( + "Expected sla_ to be a str, received: {}".format(type(sla_)) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) if version_ is not None and not isinstance(version_, (bytes, str)): - raise Exception("Expected version_ to be a str, received: {}".format(type(version_))) + raise Exception( + "Expected version_ to be a str, received: {}".format(type(version_)) + ) self.available_version = available_version_ self.cloud_tag = cloud_tag_ @@ -10622,54 +17092,122 @@ def __init__(self, available_version=None, cloud_tag=None, meter_status=None, mo self.unknown_fields = unknown_fields - class ModelStatusResults(Type): - _toSchema = {'models': 'models'} - _toPy = {'models': 'models'} + _toSchema = {"models": "models"} + _toPy = {"models": "models"} + def __init__(self, models=None, **unknown_fields): - ''' + """ models : typing.Sequence[~ModelStatus] - ''' + """ models_ = [ModelStatus.from_json(o) for o in models or []] # Validate arguments against known Juju API types. if models_ is not None and not isinstance(models_, (bytes, str, list)): - raise Exception("Expected models_ to be a Sequence, received: {}".format(type(models_))) + raise Exception( + "Expected models_ to be a Sequence, received: {}".format(type(models_)) + ) self.models = models_ self.unknown_fields = unknown_fields - class ModelSummariesRequest(Type): - _toSchema = {'all_': 'all', 'user_tag': 'user-tag'} - _toPy = {'all': 'all_', 'user-tag': 'user_tag'} + _toSchema = {"all_": "all", "user_tag": "user-tag"} + _toPy = {"all": "all_", "user-tag": "user_tag"} + def __init__(self, all_=None, user_tag=None, **unknown_fields): - ''' + """ all_ : bool user_tag : str - ''' + """ all__ = all_ user_tag_ = user_tag # Validate arguments against known Juju API types. if all__ is not None and not isinstance(all__, bool): - raise Exception("Expected all__ to be a bool, received: {}".format(type(all__))) + raise Exception( + "Expected all__ to be a bool, received: {}".format(type(all__)) + ) if user_tag_ is not None and not isinstance(user_tag_, (bytes, str)): - raise Exception("Expected user_tag_ to be a str, received: {}".format(type(user_tag_))) + raise Exception( + "Expected user_tag_ to be a str, received: {}".format(type(user_tag_)) + ) self.all_ = all__ self.user_tag = user_tag_ self.unknown_fields = unknown_fields - class ModelSummary(Type): - _toSchema = {'agent_version': 'agent-version', 'cloud_credential_tag': 'cloud-credential-tag', 'cloud_region': 'cloud-region', 'cloud_tag': 'cloud-tag', 'controller_uuid': 'controller-uuid', 'counts': 'counts', 'default_series': 'default-series', 'is_controller': 'is-controller', 'last_connection': 'last-connection', 'life': 'life', 'migration': 'migration', 'name': 'name', 'owner_tag': 'owner-tag', 'provider_type': 'provider-type', 'sla': 'sla', 'status': 'status', 'type_': 'type', 'user_access': 'user-access', 'uuid': 'uuid'} - _toPy = {'agent-version': 'agent_version', 'cloud-credential-tag': 'cloud_credential_tag', 'cloud-region': 'cloud_region', 'cloud-tag': 'cloud_tag', 'controller-uuid': 'controller_uuid', 'counts': 'counts', 'default-series': 'default_series', 'is-controller': 'is_controller', 'last-connection': 'last_connection', 'life': 'life', 'migration': 'migration', 'name': 'name', 'owner-tag': 'owner_tag', 'provider-type': 'provider_type', 'sla': 'sla', 'status': 'status', 'type': 'type_', 'user-access': 'user_access', 'uuid': 'uuid'} - def __init__(self, agent_version=None, cloud_credential_tag=None, cloud_region=None, cloud_tag=None, controller_uuid=None, counts=None, default_series=None, is_controller=None, last_connection=None, life=None, migration=None, name=None, owner_tag=None, provider_type=None, sla=None, status=None, type_=None, user_access=None, uuid=None, **unknown_fields): - ''' + _toSchema = { + "agent_version": "agent-version", + "cloud_credential_tag": "cloud-credential-tag", + "cloud_region": "cloud-region", + "cloud_tag": "cloud-tag", + "controller_uuid": "controller-uuid", + "counts": "counts", + "default_series": "default-series", + "is_controller": "is-controller", + "last_connection": "last-connection", + "life": "life", + "migration": "migration", + "name": "name", + "owner_tag": "owner-tag", + "provider_type": "provider-type", + "sla": "sla", + "status": "status", + "type_": "type", + "user_access": "user-access", + "uuid": "uuid", + } + _toPy = { + "agent-version": "agent_version", + "cloud-credential-tag": "cloud_credential_tag", + "cloud-region": "cloud_region", + "cloud-tag": "cloud_tag", + "controller-uuid": "controller_uuid", + "counts": "counts", + "default-series": "default_series", + "is-controller": "is_controller", + "last-connection": "last_connection", + "life": "life", + "migration": "migration", + "name": "name", + "owner-tag": "owner_tag", + "provider-type": "provider_type", + "sla": "sla", + "status": "status", + "type": "type_", + "user-access": "user_access", + "uuid": "uuid", + } + + def __init__( + self, + agent_version=None, + cloud_credential_tag=None, + cloud_region=None, + cloud_tag=None, + controller_uuid=None, + counts=None, + default_series=None, + is_controller=None, + last_connection=None, + life=None, + migration=None, + name=None, + owner_tag=None, + provider_type=None, + sla=None, + status=None, + type_=None, + user_access=None, + uuid=None, + **unknown_fields, + ): + """ agent_version : Number cloud_credential_tag : str cloud_region : str @@ -10689,7 +17227,7 @@ def __init__(self, agent_version=None, cloud_credential_tag=None, cloud_region=N type_ : str user_access : str uuid : str - ''' + """ agent_version_ = Number.from_json(agent_version) if agent_version else None cloud_credential_tag_ = cloud_credential_tag cloud_region_ = cloud_region @@ -10711,62 +17249,134 @@ def __init__(self, agent_version=None, cloud_credential_tag=None, cloud_region=N uuid_ = uuid # Validate arguments against known Juju API types. - if agent_version_ is not None and not isinstance(agent_version_, (dict, Number)): - raise Exception("Expected agent_version_ to be a Number, received: {}".format(type(agent_version_))) - - if cloud_credential_tag_ is not None and not isinstance(cloud_credential_tag_, (bytes, str)): - raise Exception("Expected cloud_credential_tag_ to be a str, received: {}".format(type(cloud_credential_tag_))) + if agent_version_ is not None and not isinstance( + agent_version_, (dict, Number) + ): + raise Exception( + "Expected agent_version_ to be a Number, received: {}".format( + type(agent_version_) + ) + ) + + if cloud_credential_tag_ is not None and not isinstance( + cloud_credential_tag_, (bytes, str) + ): + raise Exception( + "Expected cloud_credential_tag_ to be a str, received: {}".format( + type(cloud_credential_tag_) + ) + ) if cloud_region_ is not None and not isinstance(cloud_region_, (bytes, str)): - raise Exception("Expected cloud_region_ to be a str, received: {}".format(type(cloud_region_))) + raise Exception( + "Expected cloud_region_ to be a str, received: {}".format( + type(cloud_region_) + ) + ) if cloud_tag_ is not None and not isinstance(cloud_tag_, (bytes, str)): - raise Exception("Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_))) - - if controller_uuid_ is not None and not isinstance(controller_uuid_, (bytes, str)): - raise Exception("Expected controller_uuid_ to be a str, received: {}".format(type(controller_uuid_))) + raise Exception( + "Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_)) + ) + + if controller_uuid_ is not None and not isinstance( + controller_uuid_, (bytes, str) + ): + raise Exception( + "Expected controller_uuid_ to be a str, received: {}".format( + type(controller_uuid_) + ) + ) if counts_ is not None and not isinstance(counts_, (bytes, str, list)): - raise Exception("Expected counts_ to be a Sequence, received: {}".format(type(counts_))) - - if default_series_ is not None and not isinstance(default_series_, (bytes, str)): - raise Exception("Expected default_series_ to be a str, received: {}".format(type(default_series_))) + raise Exception( + "Expected counts_ to be a Sequence, received: {}".format(type(counts_)) + ) + + if default_series_ is not None and not isinstance( + default_series_, (bytes, str) + ): + raise Exception( + "Expected default_series_ to be a str, received: {}".format( + type(default_series_) + ) + ) if is_controller_ is not None and not isinstance(is_controller_, bool): - raise Exception("Expected is_controller_ to be a bool, received: {}".format(type(is_controller_))) - - if last_connection_ is not None and not isinstance(last_connection_, (bytes, str)): - raise Exception("Expected last_connection_ to be a str, received: {}".format(type(last_connection_))) + raise Exception( + "Expected is_controller_ to be a bool, received: {}".format( + type(is_controller_) + ) + ) + + if last_connection_ is not None and not isinstance( + last_connection_, (bytes, str) + ): + raise Exception( + "Expected last_connection_ to be a str, received: {}".format( + type(last_connection_) + ) + ) if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception("Expected life_ to be a str, received: {}".format(type(life_))) - - if migration_ is not None and not isinstance(migration_, (dict, ModelMigrationStatus)): - raise Exception("Expected migration_ to be a ModelMigrationStatus, received: {}".format(type(migration_))) + raise Exception( + "Expected life_ to be a str, received: {}".format(type(life_)) + ) + + if migration_ is not None and not isinstance( + migration_, (dict, ModelMigrationStatus) + ): + raise Exception( + "Expected migration_ to be a ModelMigrationStatus, received: {}".format( + type(migration_) + ) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if owner_tag_ is not None and not isinstance(owner_tag_, (bytes, str)): - raise Exception("Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_))) + raise Exception( + "Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_)) + ) if provider_type_ is not None and not isinstance(provider_type_, (bytes, str)): - raise Exception("Expected provider_type_ to be a str, received: {}".format(type(provider_type_))) + raise Exception( + "Expected provider_type_ to be a str, received: {}".format( + type(provider_type_) + ) + ) if sla_ is not None and not isinstance(sla_, (dict, ModelSLAInfo)): - raise Exception("Expected sla_ to be a ModelSLAInfo, received: {}".format(type(sla_))) + raise Exception( + "Expected sla_ to be a ModelSLAInfo, received: {}".format(type(sla_)) + ) if status_ is not None and not isinstance(status_, (dict, EntityStatus)): - raise Exception("Expected status_ to be a EntityStatus, received: {}".format(type(status_))) + raise Exception( + "Expected status_ to be a EntityStatus, received: {}".format( + type(status_) + ) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) if user_access_ is not None and not isinstance(user_access_, (bytes, str)): - raise Exception("Expected user_access_ to be a str, received: {}".format(type(user_access_))) + raise Exception( + "Expected user_access_ to be a str, received: {}".format( + type(user_access_) + ) + ) if uuid_ is not None and not isinstance(uuid_, (bytes, str)): - raise Exception("Expected uuid_ to be a str, received: {}".format(type(uuid_))) + raise Exception( + "Expected uuid_ to be a str, received: {}".format(type(uuid_)) + ) self.agent_version = agent_version_ self.cloud_credential_tag = cloud_credential_tag_ @@ -10790,100 +17400,122 @@ def __init__(self, agent_version=None, cloud_credential_tag=None, cloud_region=N self.unknown_fields = unknown_fields - class ModelSummaryResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : ModelSummary - ''' + """ error_ = Error.from_json(error) if error else None result_ = ModelSummary.from_json(result) if result else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if result_ is not None and not isinstance(result_, (dict, ModelSummary)): - raise Exception("Expected result_ to be a ModelSummary, received: {}".format(type(result_))) + raise Exception( + "Expected result_ to be a ModelSummary, received: {}".format( + type(result_) + ) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class ModelSummaryResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~ModelSummaryResult] - ''' + """ results_ = [ModelSummaryResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class ModelTag(Type): _toSchema = {} _toPy = {} - def __init__(self, **unknown_fields): - ''' - ''' + def __init__(self, **unknown_fields): + """ """ self.unknown_fields = unknown_fields - class ModelUnset(Type): - _toSchema = {'keys': 'keys'} - _toPy = {'keys': 'keys'} + _toSchema = {"keys": "keys"} + _toPy = {"keys": "keys"} + def __init__(self, keys=None, **unknown_fields): - ''' + """ keys : typing.Sequence[str] - ''' + """ keys_ = keys # Validate arguments against known Juju API types. if keys_ is not None and not isinstance(keys_, (bytes, str, list)): - raise Exception("Expected keys_ to be a Sequence, received: {}".format(type(keys_))) + raise Exception( + "Expected keys_ to be a Sequence, received: {}".format(type(keys_)) + ) self.keys = keys_ self.unknown_fields = unknown_fields - class ModelUnsetKeys(Type): - _toSchema = {'cloud_region': 'cloud-region', 'cloud_tag': 'cloud-tag', 'keys': 'keys'} - _toPy = {'cloud-region': 'cloud_region', 'cloud-tag': 'cloud_tag', 'keys': 'keys'} + _toSchema = { + "cloud_region": "cloud-region", + "cloud_tag": "cloud-tag", + "keys": "keys", + } + _toPy = {"cloud-region": "cloud_region", "cloud-tag": "cloud_tag", "keys": "keys"} + def __init__(self, cloud_region=None, cloud_tag=None, keys=None, **unknown_fields): - ''' + """ cloud_region : str cloud_tag : str keys : typing.Sequence[str] - ''' + """ cloud_region_ = cloud_region cloud_tag_ = cloud_tag keys_ = keys # Validate arguments against known Juju API types. if cloud_region_ is not None and not isinstance(cloud_region_, (bytes, str)): - raise Exception("Expected cloud_region_ to be a str, received: {}".format(type(cloud_region_))) + raise Exception( + "Expected cloud_region_ to be a str, received: {}".format( + type(cloud_region_) + ) + ) if cloud_tag_ is not None and not isinstance(cloud_tag_, (bytes, str)): - raise Exception("Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_))) + raise Exception( + "Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_)) + ) if keys_ is not None and not isinstance(keys_, (bytes, str, list)): - raise Exception("Expected keys_ to be a Sequence, received: {}".format(type(keys_))) + raise Exception( + "Expected keys_ to be a Sequence, received: {}".format(type(keys_)) + ) self.cloud_region = cloud_region_ self.cloud_tag = cloud_tag_ @@ -10891,18 +17523,38 @@ def __init__(self, cloud_region=None, cloud_tag=None, keys=None, **unknown_field self.unknown_fields = unknown_fields - class ModelUserInfo(Type): - _toSchema = {'access': 'access', 'display_name': 'display-name', 'last_connection': 'last-connection', 'model_tag': 'model-tag', 'user': 'user'} - _toPy = {'access': 'access', 'display-name': 'display_name', 'last-connection': 'last_connection', 'model-tag': 'model_tag', 'user': 'user'} - def __init__(self, access=None, display_name=None, last_connection=None, model_tag=None, user=None, **unknown_fields): - ''' + _toSchema = { + "access": "access", + "display_name": "display-name", + "last_connection": "last-connection", + "model_tag": "model-tag", + "user": "user", + } + _toPy = { + "access": "access", + "display-name": "display_name", + "last-connection": "last_connection", + "model-tag": "model_tag", + "user": "user", + } + + def __init__( + self, + access=None, + display_name=None, + last_connection=None, + model_tag=None, + user=None, + **unknown_fields, + ): + """ access : str display_name : str last_connection : str model_tag : str user : str - ''' + """ access_ = access display_name_ = display_name last_connection_ = last_connection @@ -10911,19 +17563,35 @@ def __init__(self, access=None, display_name=None, last_connection=None, model_t # Validate arguments against known Juju API types. if access_ is not None and not isinstance(access_, (bytes, str)): - raise Exception("Expected access_ to be a str, received: {}".format(type(access_))) + raise Exception( + "Expected access_ to be a str, received: {}".format(type(access_)) + ) if display_name_ is not None and not isinstance(display_name_, (bytes, str)): - raise Exception("Expected display_name_ to be a str, received: {}".format(type(display_name_))) - - if last_connection_ is not None and not isinstance(last_connection_, (bytes, str)): - raise Exception("Expected last_connection_ to be a str, received: {}".format(type(last_connection_))) + raise Exception( + "Expected display_name_ to be a str, received: {}".format( + type(display_name_) + ) + ) + + if last_connection_ is not None and not isinstance( + last_connection_, (bytes, str) + ): + raise Exception( + "Expected last_connection_ to be a str, received: {}".format( + type(last_connection_) + ) + ) if model_tag_ is not None and not isinstance(model_tag_, (bytes, str)): - raise Exception("Expected model_tag_ to be a str, received: {}".format(type(model_tag_))) + raise Exception( + "Expected model_tag_ to be a str, received: {}".format(type(model_tag_)) + ) if user_ is not None and not isinstance(user_, (bytes, str)): - raise Exception("Expected user_ to be a str, received: {}".format(type(user_))) + raise Exception( + "Expected user_ to be a str, received: {}".format(type(user_)) + ) self.access = access_ self.display_name = display_name_ @@ -10933,60 +17601,90 @@ def __init__(self, access=None, display_name=None, last_connection=None, model_t self.unknown_fields = unknown_fields - class ModelUserInfoResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : ModelUserInfo - ''' + """ error_ = Error.from_json(error) if error else None result_ = ModelUserInfo.from_json(result) if result else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if result_ is not None and not isinstance(result_, (dict, ModelUserInfo)): - raise Exception("Expected result_ to be a ModelUserInfo, received: {}".format(type(result_))) + raise Exception( + "Expected result_ to be a ModelUserInfo, received: {}".format( + type(result_) + ) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class ModelUserInfoResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~ModelUserInfoResult] - ''' + """ results_ = [ModelUserInfoResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class ModelVolumeInfo(Type): - _toSchema = {'detachable': 'detachable', 'id_': 'id', 'message': 'message', 'provider_id': 'provider-id', 'status': 'status'} - _toPy = {'detachable': 'detachable', 'id': 'id_', 'message': 'message', 'provider-id': 'provider_id', 'status': 'status'} - def __init__(self, detachable=None, id_=None, message=None, provider_id=None, status=None, **unknown_fields): - ''' + _toSchema = { + "detachable": "detachable", + "id_": "id", + "message": "message", + "provider_id": "provider-id", + "status": "status", + } + _toPy = { + "detachable": "detachable", + "id": "id_", + "message": "message", + "provider-id": "provider_id", + "status": "status", + } + + def __init__( + self, + detachable=None, + id_=None, + message=None, + provider_id=None, + status=None, + **unknown_fields, + ): + """ detachable : bool id_ : str message : str provider_id : str status : str - ''' + """ detachable_ = detachable id__ = id_ message_ = message @@ -10995,19 +17693,33 @@ def __init__(self, detachable=None, id_=None, message=None, provider_id=None, st # Validate arguments against known Juju API types. if detachable_ is not None and not isinstance(detachable_, bool): - raise Exception("Expected detachable_ to be a bool, received: {}".format(type(detachable_))) + raise Exception( + "Expected detachable_ to be a bool, received: {}".format( + type(detachable_) + ) + ) if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception("Expected id__ to be a str, received: {}".format(type(id__))) + raise Exception( + "Expected id__ to be a str, received: {}".format(type(id__)) + ) if message_ is not None and not isinstance(message_, (bytes, str)): - raise Exception("Expected message_ to be a str, received: {}".format(type(message_))) + raise Exception( + "Expected message_ to be a str, received: {}".format(type(message_)) + ) if provider_id_ is not None and not isinstance(provider_id_, (bytes, str)): - raise Exception("Expected provider_id_ to be a str, received: {}".format(type(provider_id_))) + raise Exception( + "Expected provider_id_ to be a str, received: {}".format( + type(provider_id_) + ) + ) if status_ is not None and not isinstance(status_, (bytes, str)): - raise Exception("Expected status_ to be a str, received: {}".format(type(status_))) + raise Exception( + "Expected status_ to be a str, received: {}".format(type(status_)) + ) self.detachable = detachable_ self.id_ = id__ @@ -11017,17 +17729,29 @@ def __init__(self, detachable=None, id_=None, message=None, provider_id=None, st self.unknown_fields = unknown_fields - class ModifyCloudAccess(Type): - _toSchema = {'access': 'access', 'action': 'action', 'cloud_tag': 'cloud-tag', 'user_tag': 'user-tag'} - _toPy = {'access': 'access', 'action': 'action', 'cloud-tag': 'cloud_tag', 'user-tag': 'user_tag'} - def __init__(self, access=None, action=None, cloud_tag=None, user_tag=None, **unknown_fields): - ''' + _toSchema = { + "access": "access", + "action": "action", + "cloud_tag": "cloud-tag", + "user_tag": "user-tag", + } + _toPy = { + "access": "access", + "action": "action", + "cloud-tag": "cloud_tag", + "user-tag": "user_tag", + } + + def __init__( + self, access=None, action=None, cloud_tag=None, user_tag=None, **unknown_fields + ): + """ access : str action : str cloud_tag : str user_tag : str - ''' + """ access_ = access action_ = action cloud_tag_ = cloud_tag @@ -11035,16 +17759,24 @@ def __init__(self, access=None, action=None, cloud_tag=None, user_tag=None, **un # Validate arguments against known Juju API types. if access_ is not None and not isinstance(access_, (bytes, str)): - raise Exception("Expected access_ to be a str, received: {}".format(type(access_))) + raise Exception( + "Expected access_ to be a str, received: {}".format(type(access_)) + ) if action_ is not None and not isinstance(action_, (bytes, str)): - raise Exception("Expected action_ to be a str, received: {}".format(type(action_))) + raise Exception( + "Expected action_ to be a str, received: {}".format(type(action_)) + ) if cloud_tag_ is not None and not isinstance(cloud_tag_, (bytes, str)): - raise Exception("Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_))) + raise Exception( + "Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_)) + ) if user_tag_ is not None and not isinstance(user_tag_, (bytes, str)): - raise Exception("Expected user_tag_ to be a str, received: {}".format(type(user_tag_))) + raise Exception( + "Expected user_tag_ to be a str, received: {}".format(type(user_tag_)) + ) self.access = access_ self.action = action_ @@ -11053,47 +17785,57 @@ def __init__(self, access=None, action=None, cloud_tag=None, user_tag=None, **un self.unknown_fields = unknown_fields - class ModifyCloudAccessRequest(Type): - _toSchema = {'changes': 'changes'} - _toPy = {'changes': 'changes'} + _toSchema = {"changes": "changes"} + _toPy = {"changes": "changes"} + def __init__(self, changes=None, **unknown_fields): - ''' + """ changes : typing.Sequence[~ModifyCloudAccess] - ''' + """ changes_ = [ModifyCloudAccess.from_json(o) for o in changes or []] # Validate arguments against known Juju API types. if changes_ is not None and not isinstance(changes_, (bytes, str, list)): - raise Exception("Expected changes_ to be a Sequence, received: {}".format(type(changes_))) + raise Exception( + "Expected changes_ to be a Sequence, received: {}".format( + type(changes_) + ) + ) self.changes = changes_ self.unknown_fields = unknown_fields - class ModifyControllerAccess(Type): - _toSchema = {'access': 'access', 'action': 'action', 'user_tag': 'user-tag'} - _toPy = {'access': 'access', 'action': 'action', 'user-tag': 'user_tag'} + _toSchema = {"access": "access", "action": "action", "user_tag": "user-tag"} + _toPy = {"access": "access", "action": "action", "user-tag": "user_tag"} + def __init__(self, access=None, action=None, user_tag=None, **unknown_fields): - ''' + """ access : str action : str user_tag : str - ''' + """ access_ = access action_ = action user_tag_ = user_tag # Validate arguments against known Juju API types. if access_ is not None and not isinstance(access_, (bytes, str)): - raise Exception("Expected access_ to be a str, received: {}".format(type(access_))) + raise Exception( + "Expected access_ to be a str, received: {}".format(type(access_)) + ) if action_ is not None and not isinstance(action_, (bytes, str)): - raise Exception("Expected action_ to be a str, received: {}".format(type(action_))) + raise Exception( + "Expected action_ to be a str, received: {}".format(type(action_)) + ) if user_tag_ is not None and not isinstance(user_tag_, (bytes, str)): - raise Exception("Expected user_tag_ to be a str, received: {}".format(type(user_tag_))) + raise Exception( + "Expected user_tag_ to be a str, received: {}".format(type(user_tag_)) + ) self.access = access_ self.action = action_ @@ -11101,35 +17843,51 @@ def __init__(self, access=None, action=None, user_tag=None, **unknown_fields): self.unknown_fields = unknown_fields - class ModifyControllerAccessRequest(Type): - _toSchema = {'changes': 'changes'} - _toPy = {'changes': 'changes'} + _toSchema = {"changes": "changes"} + _toPy = {"changes": "changes"} + def __init__(self, changes=None, **unknown_fields): - ''' + """ changes : typing.Sequence[~ModifyControllerAccess] - ''' + """ changes_ = [ModifyControllerAccess.from_json(o) for o in changes or []] # Validate arguments against known Juju API types. if changes_ is not None and not isinstance(changes_, (bytes, str, list)): - raise Exception("Expected changes_ to be a Sequence, received: {}".format(type(changes_))) + raise Exception( + "Expected changes_ to be a Sequence, received: {}".format( + type(changes_) + ) + ) self.changes = changes_ self.unknown_fields = unknown_fields - class ModifyModelAccess(Type): - _toSchema = {'access': 'access', 'action': 'action', 'model_tag': 'model-tag', 'user_tag': 'user-tag'} - _toPy = {'access': 'access', 'action': 'action', 'model-tag': 'model_tag', 'user-tag': 'user_tag'} - def __init__(self, access=None, action=None, model_tag=None, user_tag=None, **unknown_fields): - ''' + _toSchema = { + "access": "access", + "action": "action", + "model_tag": "model-tag", + "user_tag": "user-tag", + } + _toPy = { + "access": "access", + "action": "action", + "model-tag": "model_tag", + "user-tag": "user_tag", + } + + def __init__( + self, access=None, action=None, model_tag=None, user_tag=None, **unknown_fields + ): + """ access : str action : str model_tag : str user_tag : str - ''' + """ access_ = access action_ = action model_tag_ = model_tag @@ -11137,16 +17895,24 @@ def __init__(self, access=None, action=None, model_tag=None, user_tag=None, **un # Validate arguments against known Juju API types. if access_ is not None and not isinstance(access_, (bytes, str)): - raise Exception("Expected access_ to be a str, received: {}".format(type(access_))) + raise Exception( + "Expected access_ to be a str, received: {}".format(type(access_)) + ) if action_ is not None and not isinstance(action_, (bytes, str)): - raise Exception("Expected action_ to be a str, received: {}".format(type(action_))) + raise Exception( + "Expected action_ to be a str, received: {}".format(type(action_)) + ) if model_tag_ is not None and not isinstance(model_tag_, (bytes, str)): - raise Exception("Expected model_tag_ to be a str, received: {}".format(type(model_tag_))) + raise Exception( + "Expected model_tag_ to be a str, received: {}".format(type(model_tag_)) + ) if user_tag_ is not None and not isinstance(user_tag_, (bytes, str)): - raise Exception("Expected user_tag_ to be a str, received: {}".format(type(user_tag_))) + raise Exception( + "Expected user_tag_ to be a str, received: {}".format(type(user_tag_)) + ) self.access = access_ self.action = action_ @@ -11155,35 +17921,51 @@ def __init__(self, access=None, action=None, model_tag=None, user_tag=None, **un self.unknown_fields = unknown_fields - class ModifyModelAccessRequest(Type): - _toSchema = {'changes': 'changes'} - _toPy = {'changes': 'changes'} + _toSchema = {"changes": "changes"} + _toPy = {"changes": "changes"} + def __init__(self, changes=None, **unknown_fields): - ''' + """ changes : typing.Sequence[~ModifyModelAccess] - ''' + """ changes_ = [ModifyModelAccess.from_json(o) for o in changes or []] # Validate arguments against known Juju API types. if changes_ is not None and not isinstance(changes_, (bytes, str, list)): - raise Exception("Expected changes_ to be a Sequence, received: {}".format(type(changes_))) + raise Exception( + "Expected changes_ to be a Sequence, received: {}".format( + type(changes_) + ) + ) self.changes = changes_ self.unknown_fields = unknown_fields - class ModifyOfferAccess(Type): - _toSchema = {'access': 'access', 'action': 'action', 'offer_url': 'offer-url', 'user_tag': 'user-tag'} - _toPy = {'access': 'access', 'action': 'action', 'offer-url': 'offer_url', 'user-tag': 'user_tag'} - def __init__(self, access=None, action=None, offer_url=None, user_tag=None, **unknown_fields): - ''' + _toSchema = { + "access": "access", + "action": "action", + "offer_url": "offer-url", + "user_tag": "user-tag", + } + _toPy = { + "access": "access", + "action": "action", + "offer-url": "offer_url", + "user-tag": "user_tag", + } + + def __init__( + self, access=None, action=None, offer_url=None, user_tag=None, **unknown_fields + ): + """ access : str action : str offer_url : str user_tag : str - ''' + """ access_ = access action_ = action offer_url_ = offer_url @@ -11191,16 +17973,24 @@ def __init__(self, access=None, action=None, offer_url=None, user_tag=None, **un # Validate arguments against known Juju API types. if access_ is not None and not isinstance(access_, (bytes, str)): - raise Exception("Expected access_ to be a str, received: {}".format(type(access_))) + raise Exception( + "Expected access_ to be a str, received: {}".format(type(access_)) + ) if action_ is not None and not isinstance(action_, (bytes, str)): - raise Exception("Expected action_ to be a str, received: {}".format(type(action_))) + raise Exception( + "Expected action_ to be a str, received: {}".format(type(action_)) + ) if offer_url_ is not None and not isinstance(offer_url_, (bytes, str)): - raise Exception("Expected offer_url_ to be a str, received: {}".format(type(offer_url_))) + raise Exception( + "Expected offer_url_ to be a str, received: {}".format(type(offer_url_)) + ) if user_tag_ is not None and not isinstance(user_tag_, (bytes, str)): - raise Exception("Expected user_tag_ to be a str, received: {}".format(type(user_tag_))) + raise Exception( + "Expected user_tag_ to be a str, received: {}".format(type(user_tag_)) + ) self.access = access_ self.action = action_ @@ -11209,71 +17999,89 @@ def __init__(self, access=None, action=None, offer_url=None, user_tag=None, **un self.unknown_fields = unknown_fields - class ModifyOfferAccessRequest(Type): - _toSchema = {'changes': 'changes'} - _toPy = {'changes': 'changes'} + _toSchema = {"changes": "changes"} + _toPy = {"changes": "changes"} + def __init__(self, changes=None, **unknown_fields): - ''' + """ changes : typing.Sequence[~ModifyOfferAccess] - ''' + """ changes_ = [ModifyOfferAccess.from_json(o) for o in changes or []] # Validate arguments against known Juju API types. if changes_ is not None and not isinstance(changes_, (bytes, str, list)): - raise Exception("Expected changes_ to be a Sequence, received: {}".format(type(changes_))) + raise Exception( + "Expected changes_ to be a Sequence, received: {}".format( + type(changes_) + ) + ) self.changes = changes_ self.unknown_fields = unknown_fields - class ModifyUserSSHKeys(Type): - _toSchema = {'ssh_keys': 'ssh-keys', 'user': 'user'} - _toPy = {'ssh-keys': 'ssh_keys', 'user': 'user'} + _toSchema = {"ssh_keys": "ssh-keys", "user": "user"} + _toPy = {"ssh-keys": "ssh_keys", "user": "user"} + def __init__(self, ssh_keys=None, user=None, **unknown_fields): - ''' + """ ssh_keys : typing.Sequence[str] user : str - ''' + """ ssh_keys_ = ssh_keys user_ = user # Validate arguments against known Juju API types. if ssh_keys_ is not None and not isinstance(ssh_keys_, (bytes, str, list)): - raise Exception("Expected ssh_keys_ to be a Sequence, received: {}".format(type(ssh_keys_))) + raise Exception( + "Expected ssh_keys_ to be a Sequence, received: {}".format( + type(ssh_keys_) + ) + ) if user_ is not None and not isinstance(user_, (bytes, str)): - raise Exception("Expected user_ to be a str, received: {}".format(type(user_))) + raise Exception( + "Expected user_ to be a str, received: {}".format(type(user_)) + ) self.ssh_keys = ssh_keys_ self.user = user_ self.unknown_fields = unknown_fields - class MoveSubnetsParam(Type): - _toSchema = {'force': 'force', 'space_tag': 'space-tag', 'subnets': 'subnets'} - _toPy = {'force': 'force', 'space-tag': 'space_tag', 'subnets': 'subnets'} + _toSchema = {"force": "force", "space_tag": "space-tag", "subnets": "subnets"} + _toPy = {"force": "force", "space-tag": "space_tag", "subnets": "subnets"} + def __init__(self, force=None, space_tag=None, subnets=None, **unknown_fields): - ''' + """ force : bool space_tag : str subnets : typing.Sequence[str] - ''' + """ force_ = force space_tag_ = space_tag subnets_ = subnets # Validate arguments against known Juju API types. if force_ is not None and not isinstance(force_, bool): - raise Exception("Expected force_ to be a bool, received: {}".format(type(force_))) + raise Exception( + "Expected force_ to be a bool, received: {}".format(type(force_)) + ) if space_tag_ is not None and not isinstance(space_tag_, (bytes, str)): - raise Exception("Expected space_tag_ to be a str, received: {}".format(type(space_tag_))) + raise Exception( + "Expected space_tag_ to be a str, received: {}".format(type(space_tag_)) + ) if subnets_ is not None and not isinstance(subnets_, (bytes, str, list)): - raise Exception("Expected subnets_ to be a Sequence, received: {}".format(type(subnets_))) + raise Exception( + "Expected subnets_ to be a Sequence, received: {}".format( + type(subnets_) + ) + ) self.force = force_ self.space_tag = space_tag_ @@ -11281,47 +18089,69 @@ def __init__(self, force=None, space_tag=None, subnets=None, **unknown_fields): self.unknown_fields = unknown_fields - class MoveSubnetsParams(Type): - _toSchema = {'args': 'args'} - _toPy = {'args': 'args'} + _toSchema = {"args": "args"} + _toPy = {"args": "args"} + def __init__(self, args=None, **unknown_fields): - ''' + """ args : typing.Sequence[~MoveSubnetsParam] - ''' + """ args_ = [MoveSubnetsParam.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception("Expected args_ to be a Sequence, received: {}".format(type(args_))) + raise Exception( + "Expected args_ to be a Sequence, received: {}".format(type(args_)) + ) self.args = args_ self.unknown_fields = unknown_fields - class MoveSubnetsResult(Type): - _toSchema = {'error': 'error', 'moved_subnets': 'moved-subnets', 'new_space': 'new-space'} - _toPy = {'error': 'error', 'moved-subnets': 'moved_subnets', 'new-space': 'new_space'} - def __init__(self, error=None, moved_subnets=None, new_space=None, **unknown_fields): - ''' + _toSchema = { + "error": "error", + "moved_subnets": "moved-subnets", + "new_space": "new-space", + } + _toPy = { + "error": "error", + "moved-subnets": "moved_subnets", + "new-space": "new_space", + } + + def __init__( + self, error=None, moved_subnets=None, new_space=None, **unknown_fields + ): + """ error : Error moved_subnets : typing.Sequence[~MovedSubnet] new_space : str - ''' + """ error_ = Error.from_json(error) if error else None moved_subnets_ = [MovedSubnet.from_json(o) for o in moved_subnets or []] new_space_ = new_space # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) - - if moved_subnets_ is not None and not isinstance(moved_subnets_, (bytes, str, list)): - raise Exception("Expected moved_subnets_ to be a Sequence, received: {}".format(type(moved_subnets_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) + + if moved_subnets_ is not None and not isinstance( + moved_subnets_, (bytes, str, list) + ): + raise Exception( + "Expected moved_subnets_ to be a Sequence, received: {}".format( + type(moved_subnets_) + ) + ) if new_space_ is not None and not isinstance(new_space_, (bytes, str)): - raise Exception("Expected new_space_ to be a str, received: {}".format(type(new_space_))) + raise Exception( + "Expected new_space_ to be a str, received: {}".format(type(new_space_)) + ) self.error = error_ self.moved_subnets = moved_subnets_ @@ -11329,47 +18159,57 @@ def __init__(self, error=None, moved_subnets=None, new_space=None, **unknown_fie self.unknown_fields = unknown_fields - class MoveSubnetsResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~MoveSubnetsResult] - ''' + """ results_ = [MoveSubnetsResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class MovedSubnet(Type): - _toSchema = {'cidr': 'cidr', 'old_space': 'old-space', 'subnet': 'subnet'} - _toPy = {'cidr': 'cidr', 'old-space': 'old_space', 'subnet': 'subnet'} + _toSchema = {"cidr": "cidr", "old_space": "old-space", "subnet": "subnet"} + _toPy = {"cidr": "cidr", "old-space": "old_space", "subnet": "subnet"} + def __init__(self, cidr=None, old_space=None, subnet=None, **unknown_fields): - ''' + """ cidr : str old_space : str subnet : str - ''' + """ cidr_ = cidr old_space_ = old_space subnet_ = subnet # Validate arguments against known Juju API types. if cidr_ is not None and not isinstance(cidr_, (bytes, str)): - raise Exception("Expected cidr_ to be a str, received: {}".format(type(cidr_))) + raise Exception( + "Expected cidr_ to be a str, received: {}".format(type(cidr_)) + ) if old_space_ is not None and not isinstance(old_space_, (bytes, str)): - raise Exception("Expected old_space_ to be a str, received: {}".format(type(old_space_))) + raise Exception( + "Expected old_space_ to be a str, received: {}".format(type(old_space_)) + ) if subnet_ is not None and not isinstance(subnet_, (bytes, str)): - raise Exception("Expected subnet_ to be a str, received: {}".format(type(subnet_))) + raise Exception( + "Expected subnet_ to be a str, received: {}".format(type(subnet_)) + ) self.cidr = cidr_ self.old_space = old_space_ @@ -11377,19 +18217,42 @@ def __init__(self, cidr=None, old_space=None, subnet=None, **unknown_fields): self.unknown_fields = unknown_fields - class NetworkInterface(Type): - _toSchema = {'dns_nameservers': 'dns-nameservers', 'gateway': 'gateway', 'ip_addresses': 'ip-addresses', 'is_up': 'is-up', 'mac_address': 'mac-address', 'space': 'space'} - _toPy = {'dns-nameservers': 'dns_nameservers', 'gateway': 'gateway', 'ip-addresses': 'ip_addresses', 'is-up': 'is_up', 'mac-address': 'mac_address', 'space': 'space'} - def __init__(self, dns_nameservers=None, gateway=None, ip_addresses=None, is_up=None, mac_address=None, space=None, **unknown_fields): - ''' + _toSchema = { + "dns_nameservers": "dns-nameservers", + "gateway": "gateway", + "ip_addresses": "ip-addresses", + "is_up": "is-up", + "mac_address": "mac-address", + "space": "space", + } + _toPy = { + "dns-nameservers": "dns_nameservers", + "gateway": "gateway", + "ip-addresses": "ip_addresses", + "is-up": "is_up", + "mac-address": "mac_address", + "space": "space", + } + + def __init__( + self, + dns_nameservers=None, + gateway=None, + ip_addresses=None, + is_up=None, + mac_address=None, + space=None, + **unknown_fields, + ): + """ dns_nameservers : typing.Sequence[str] gateway : str ip_addresses : typing.Sequence[str] is_up : bool mac_address : str space : str - ''' + """ dns_nameservers_ = dns_nameservers gateway_ = gateway ip_addresses_ = ip_addresses @@ -11398,23 +18261,45 @@ def __init__(self, dns_nameservers=None, gateway=None, ip_addresses=None, is_up= space_ = space # Validate arguments against known Juju API types. - if dns_nameservers_ is not None and not isinstance(dns_nameservers_, (bytes, str, list)): - raise Exception("Expected dns_nameservers_ to be a Sequence, received: {}".format(type(dns_nameservers_))) + if dns_nameservers_ is not None and not isinstance( + dns_nameservers_, (bytes, str, list) + ): + raise Exception( + "Expected dns_nameservers_ to be a Sequence, received: {}".format( + type(dns_nameservers_) + ) + ) if gateway_ is not None and not isinstance(gateway_, (bytes, str)): - raise Exception("Expected gateway_ to be a str, received: {}".format(type(gateway_))) - - if ip_addresses_ is not None and not isinstance(ip_addresses_, (bytes, str, list)): - raise Exception("Expected ip_addresses_ to be a Sequence, received: {}".format(type(ip_addresses_))) + raise Exception( + "Expected gateway_ to be a str, received: {}".format(type(gateway_)) + ) + + if ip_addresses_ is not None and not isinstance( + ip_addresses_, (bytes, str, list) + ): + raise Exception( + "Expected ip_addresses_ to be a Sequence, received: {}".format( + type(ip_addresses_) + ) + ) if is_up_ is not None and not isinstance(is_up_, bool): - raise Exception("Expected is_up_ to be a bool, received: {}".format(type(is_up_))) + raise Exception( + "Expected is_up_ to be a bool, received: {}".format(type(is_up_)) + ) if mac_address_ is not None and not isinstance(mac_address_, (bytes, str)): - raise Exception("Expected mac_address_ to be a str, received: {}".format(type(mac_address_))) + raise Exception( + "Expected mac_address_ to be a str, received: {}".format( + type(mac_address_) + ) + ) if space_ is not None and not isinstance(space_, (bytes, str)): - raise Exception("Expected space_ to be a str, received: {}".format(type(space_))) + raise Exception( + "Expected space_ to be a str, received: {}".format(type(space_)) + ) self.dns_nameservers = dns_nameservers_ self.gateway = gateway_ @@ -11425,60 +18310,86 @@ def __init__(self, dns_nameservers=None, gateway=None, ip_addresses=None, is_up= self.unknown_fields = unknown_fields - class NotifyWatchResult(Type): - _toSchema = {'error': 'error', 'notifywatcherid': 'NotifyWatcherId'} - _toPy = {'NotifyWatcherId': 'notifywatcherid', 'error': 'error'} + _toSchema = {"error": "error", "notifywatcherid": "NotifyWatcherId"} + _toPy = {"NotifyWatcherId": "notifywatcherid", "error": "error"} + def __init__(self, notifywatcherid=None, error=None, **unknown_fields): - ''' + """ notifywatcherid : str error : Error - ''' + """ notifywatcherid_ = notifywatcherid error_ = Error.from_json(error) if error else None # Validate arguments against known Juju API types. - if notifywatcherid_ is not None and not isinstance(notifywatcherid_, (bytes, str)): - raise Exception("Expected notifywatcherid_ to be a str, received: {}".format(type(notifywatcherid_))) + if notifywatcherid_ is not None and not isinstance( + notifywatcherid_, (bytes, str) + ): + raise Exception( + "Expected notifywatcherid_ to be a str, received: {}".format( + type(notifywatcherid_) + ) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) self.notifywatcherid = notifywatcherid_ self.error = error_ self.unknown_fields = unknown_fields - class NotifyWatchResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~NotifyWatchResult] - ''' + """ results_ = [NotifyWatchResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class Number(Type): - _toSchema = {'build': 'Build', 'major': 'Major', 'minor': 'Minor', 'patch': 'Patch', 'tag': 'Tag'} - _toPy = {'Build': 'build', 'Major': 'major', 'Minor': 'minor', 'Patch': 'patch', 'Tag': 'tag'} - def __init__(self, build=None, major=None, minor=None, patch=None, tag=None, **unknown_fields): - ''' + _toSchema = { + "build": "Build", + "major": "Major", + "minor": "Minor", + "patch": "Patch", + "tag": "Tag", + } + _toPy = { + "Build": "build", + "Major": "major", + "Minor": "minor", + "Patch": "patch", + "Tag": "tag", + } + + def __init__( + self, build=None, major=None, minor=None, patch=None, tag=None, **unknown_fields + ): + """ build : int major : int minor : int patch : int tag : str - ''' + """ build_ = build major_ = major minor_ = minor @@ -11487,19 +18398,29 @@ def __init__(self, build=None, major=None, minor=None, patch=None, tag=None, **u # Validate arguments against known Juju API types. if build_ is not None and not isinstance(build_, int): - raise Exception("Expected build_ to be a int, received: {}".format(type(build_))) + raise Exception( + "Expected build_ to be a int, received: {}".format(type(build_)) + ) if major_ is not None and not isinstance(major_, int): - raise Exception("Expected major_ to be a int, received: {}".format(type(major_))) + raise Exception( + "Expected major_ to be a int, received: {}".format(type(major_)) + ) if minor_ is not None and not isinstance(minor_, int): - raise Exception("Expected minor_ to be a int, received: {}".format(type(minor_))) + raise Exception( + "Expected minor_ to be a int, received: {}".format(type(minor_)) + ) if patch_ is not None and not isinstance(patch_, int): - raise Exception("Expected patch_ to be a int, received: {}".format(type(patch_))) + raise Exception( + "Expected patch_ to be a int, received: {}".format(type(patch_)) + ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception("Expected tag_ to be a str, received: {}".format(type(tag_))) + raise Exception( + "Expected tag_ to be a str, received: {}".format(type(tag_)) + ) self.build = build_ self.major = major_ @@ -11509,19 +18430,42 @@ def __init__(self, build=None, major=None, minor=None, patch=None, tag=None, **u self.unknown_fields = unknown_fields - class OfferConnection(Type): - _toSchema = {'endpoint': 'endpoint', 'ingress_subnets': 'ingress-subnets', 'relation_id': 'relation-id', 'source_model_tag': 'source-model-tag', 'status': 'status', 'username': 'username'} - _toPy = {'endpoint': 'endpoint', 'ingress-subnets': 'ingress_subnets', 'relation-id': 'relation_id', 'source-model-tag': 'source_model_tag', 'status': 'status', 'username': 'username'} - def __init__(self, endpoint=None, ingress_subnets=None, relation_id=None, source_model_tag=None, status=None, username=None, **unknown_fields): - ''' + _toSchema = { + "endpoint": "endpoint", + "ingress_subnets": "ingress-subnets", + "relation_id": "relation-id", + "source_model_tag": "source-model-tag", + "status": "status", + "username": "username", + } + _toPy = { + "endpoint": "endpoint", + "ingress-subnets": "ingress_subnets", + "relation-id": "relation_id", + "source-model-tag": "source_model_tag", + "status": "status", + "username": "username", + } + + def __init__( + self, + endpoint=None, + ingress_subnets=None, + relation_id=None, + source_model_tag=None, + status=None, + username=None, + **unknown_fields, + ): + """ endpoint : str ingress_subnets : typing.Sequence[str] relation_id : int source_model_tag : str status : EntityStatus username : str - ''' + """ endpoint_ = endpoint ingress_subnets_ = ingress_subnets relation_id_ = relation_id @@ -11531,22 +18475,46 @@ def __init__(self, endpoint=None, ingress_subnets=None, relation_id=None, source # Validate arguments against known Juju API types. if endpoint_ is not None and not isinstance(endpoint_, (bytes, str)): - raise Exception("Expected endpoint_ to be a str, received: {}".format(type(endpoint_))) - - if ingress_subnets_ is not None and not isinstance(ingress_subnets_, (bytes, str, list)): - raise Exception("Expected ingress_subnets_ to be a Sequence, received: {}".format(type(ingress_subnets_))) + raise Exception( + "Expected endpoint_ to be a str, received: {}".format(type(endpoint_)) + ) + + if ingress_subnets_ is not None and not isinstance( + ingress_subnets_, (bytes, str, list) + ): + raise Exception( + "Expected ingress_subnets_ to be a Sequence, received: {}".format( + type(ingress_subnets_) + ) + ) if relation_id_ is not None and not isinstance(relation_id_, int): - raise Exception("Expected relation_id_ to be a int, received: {}".format(type(relation_id_))) - - if source_model_tag_ is not None and not isinstance(source_model_tag_, (bytes, str)): - raise Exception("Expected source_model_tag_ to be a str, received: {}".format(type(source_model_tag_))) + raise Exception( + "Expected relation_id_ to be a int, received: {}".format( + type(relation_id_) + ) + ) + + if source_model_tag_ is not None and not isinstance( + source_model_tag_, (bytes, str) + ): + raise Exception( + "Expected source_model_tag_ to be a str, received: {}".format( + type(source_model_tag_) + ) + ) if status_ is not None and not isinstance(status_, (dict, EntityStatus)): - raise Exception("Expected status_ to be a EntityStatus, received: {}".format(type(status_))) + raise Exception( + "Expected status_ to be a EntityStatus, received: {}".format( + type(status_) + ) + ) if username_ is not None and not isinstance(username_, (bytes, str)): - raise Exception("Expected username_ to be a str, received: {}".format(type(username_))) + raise Exception( + "Expected username_ to be a str, received: {}".format(type(username_)) + ) self.endpoint = endpoint_ self.ingress_subnets = ingress_subnets_ @@ -11557,12 +18525,44 @@ def __init__(self, endpoint=None, ingress_subnets=None, relation_id=None, source self.unknown_fields = unknown_fields - class OfferFilter(Type): - _toSchema = {'allowed_users': 'allowed-users', 'application_description': 'application-description', 'application_name': 'application-name', 'application_user': 'application-user', 'connected_users': 'connected-users', 'endpoints': 'endpoints', 'model_name': 'model-name', 'offer_name': 'offer-name', 'owner_name': 'owner-name'} - _toPy = {'allowed-users': 'allowed_users', 'application-description': 'application_description', 'application-name': 'application_name', 'application-user': 'application_user', 'connected-users': 'connected_users', 'endpoints': 'endpoints', 'model-name': 'model_name', 'offer-name': 'offer_name', 'owner-name': 'owner_name'} - def __init__(self, allowed_users=None, application_description=None, application_name=None, application_user=None, connected_users=None, endpoints=None, model_name=None, offer_name=None, owner_name=None, **unknown_fields): - ''' + _toSchema = { + "allowed_users": "allowed-users", + "application_description": "application-description", + "application_name": "application-name", + "application_user": "application-user", + "connected_users": "connected-users", + "endpoints": "endpoints", + "model_name": "model-name", + "offer_name": "offer-name", + "owner_name": "owner-name", + } + _toPy = { + "allowed-users": "allowed_users", + "application-description": "application_description", + "application-name": "application_name", + "application-user": "application_user", + "connected-users": "connected_users", + "endpoints": "endpoints", + "model-name": "model_name", + "offer-name": "offer_name", + "owner-name": "owner_name", + } + + def __init__( + self, + allowed_users=None, + application_description=None, + application_name=None, + application_user=None, + connected_users=None, + endpoints=None, + model_name=None, + offer_name=None, + owner_name=None, + **unknown_fields, + ): + """ allowed_users : typing.Sequence[str] application_description : str application_name : str @@ -11572,7 +18572,7 @@ def __init__(self, allowed_users=None, application_description=None, application model_name : str offer_name : str owner_name : str - ''' + """ allowed_users_ = allowed_users application_description_ = application_description application_name_ = application_name @@ -11584,32 +18584,78 @@ def __init__(self, allowed_users=None, application_description=None, application owner_name_ = owner_name # Validate arguments against known Juju API types. - if allowed_users_ is not None and not isinstance(allowed_users_, (bytes, str, list)): - raise Exception("Expected allowed_users_ to be a Sequence, received: {}".format(type(allowed_users_))) - - if application_description_ is not None and not isinstance(application_description_, (bytes, str)): - raise Exception("Expected application_description_ to be a str, received: {}".format(type(application_description_))) - - if application_name_ is not None and not isinstance(application_name_, (bytes, str)): - raise Exception("Expected application_name_ to be a str, received: {}".format(type(application_name_))) - - if application_user_ is not None and not isinstance(application_user_, (bytes, str)): - raise Exception("Expected application_user_ to be a str, received: {}".format(type(application_user_))) - - if connected_users_ is not None and not isinstance(connected_users_, (bytes, str, list)): - raise Exception("Expected connected_users_ to be a Sequence, received: {}".format(type(connected_users_))) + if allowed_users_ is not None and not isinstance( + allowed_users_, (bytes, str, list) + ): + raise Exception( + "Expected allowed_users_ to be a Sequence, received: {}".format( + type(allowed_users_) + ) + ) + + if application_description_ is not None and not isinstance( + application_description_, (bytes, str) + ): + raise Exception( + "Expected application_description_ to be a str, received: {}".format( + type(application_description_) + ) + ) + + if application_name_ is not None and not isinstance( + application_name_, (bytes, str) + ): + raise Exception( + "Expected application_name_ to be a str, received: {}".format( + type(application_name_) + ) + ) + + if application_user_ is not None and not isinstance( + application_user_, (bytes, str) + ): + raise Exception( + "Expected application_user_ to be a str, received: {}".format( + type(application_user_) + ) + ) + + if connected_users_ is not None and not isinstance( + connected_users_, (bytes, str, list) + ): + raise Exception( + "Expected connected_users_ to be a Sequence, received: {}".format( + type(connected_users_) + ) + ) if endpoints_ is not None and not isinstance(endpoints_, (bytes, str, list)): - raise Exception("Expected endpoints_ to be a Sequence, received: {}".format(type(endpoints_))) + raise Exception( + "Expected endpoints_ to be a Sequence, received: {}".format( + type(endpoints_) + ) + ) if model_name_ is not None and not isinstance(model_name_, (bytes, str)): - raise Exception("Expected model_name_ to be a str, received: {}".format(type(model_name_))) + raise Exception( + "Expected model_name_ to be a str, received: {}".format( + type(model_name_) + ) + ) if offer_name_ is not None and not isinstance(offer_name_, (bytes, str)): - raise Exception("Expected offer_name_ to be a str, received: {}".format(type(offer_name_))) + raise Exception( + "Expected offer_name_ to be a str, received: {}".format( + type(offer_name_) + ) + ) if owner_name_ is not None and not isinstance(owner_name_, (bytes, str)): - raise Exception("Expected owner_name_ to be a str, received: {}".format(type(owner_name_))) + raise Exception( + "Expected owner_name_ to be a str, received: {}".format( + type(owner_name_) + ) + ) self.allowed_users = allowed_users_ self.application_description = application_description_ @@ -11623,71 +18669,91 @@ def __init__(self, allowed_users=None, application_description=None, application self.unknown_fields = unknown_fields - class OfferFilters(Type): - _toSchema = {'filters': 'Filters'} - _toPy = {'Filters': 'filters'} + _toSchema = {"filters": "Filters"} + _toPy = {"Filters": "filters"} + def __init__(self, filters=None, **unknown_fields): - ''' + """ filters : typing.Sequence[~OfferFilter] - ''' + """ filters_ = [OfferFilter.from_json(o) for o in filters or []] # Validate arguments against known Juju API types. if filters_ is not None and not isinstance(filters_, (bytes, str, list)): - raise Exception("Expected filters_ to be a Sequence, received: {}".format(type(filters_))) + raise Exception( + "Expected filters_ to be a Sequence, received: {}".format( + type(filters_) + ) + ) self.filters = filters_ self.unknown_fields = unknown_fields - class OfferURLs(Type): - _toSchema = {'bakery_version': 'bakery-version', 'offer_urls': 'offer-urls'} - _toPy = {'bakery-version': 'bakery_version', 'offer-urls': 'offer_urls'} + _toSchema = {"bakery_version": "bakery-version", "offer_urls": "offer-urls"} + _toPy = {"bakery-version": "bakery_version", "offer-urls": "offer_urls"} + def __init__(self, bakery_version=None, offer_urls=None, **unknown_fields): - ''' + """ bakery_version : int offer_urls : typing.Sequence[str] - ''' + """ bakery_version_ = bakery_version offer_urls_ = offer_urls # Validate arguments against known Juju API types. if bakery_version_ is not None and not isinstance(bakery_version_, int): - raise Exception("Expected bakery_version_ to be a int, received: {}".format(type(bakery_version_))) + raise Exception( + "Expected bakery_version_ to be a int, received: {}".format( + type(bakery_version_) + ) + ) if offer_urls_ is not None and not isinstance(offer_urls_, (bytes, str, list)): - raise Exception("Expected offer_urls_ to be a Sequence, received: {}".format(type(offer_urls_))) + raise Exception( + "Expected offer_urls_ to be a Sequence, received: {}".format( + type(offer_urls_) + ) + ) self.bakery_version = bakery_version_ self.offer_urls = offer_urls_ self.unknown_fields = unknown_fields - class OfferUserDetails(Type): - _toSchema = {'access': 'access', 'display_name': 'display-name', 'user': 'user'} - _toPy = {'access': 'access', 'display-name': 'display_name', 'user': 'user'} + _toSchema = {"access": "access", "display_name": "display-name", "user": "user"} + _toPy = {"access": "access", "display-name": "display_name", "user": "user"} + def __init__(self, access=None, display_name=None, user=None, **unknown_fields): - ''' + """ access : str display_name : str user : str - ''' + """ access_ = access display_name_ = display_name user_ = user # Validate arguments against known Juju API types. if access_ is not None and not isinstance(access_, (bytes, str)): - raise Exception("Expected access_ to be a str, received: {}".format(type(access_))) + raise Exception( + "Expected access_ to be a str, received: {}".format(type(access_)) + ) if display_name_ is not None and not isinstance(display_name_, (bytes, str)): - raise Exception("Expected display_name_ to be a str, received: {}".format(type(display_name_))) + raise Exception( + "Expected display_name_ to be a str, received: {}".format( + type(display_name_) + ) + ) if user_ is not None and not isinstance(user_, (bytes, str)): - raise Exception("Expected user_ to be a str, received: {}".format(type(user_))) + raise Exception( + "Expected user_ to be a str, received: {}".format(type(user_)) + ) self.access = access_ self.display_name = display_name_ @@ -11695,12 +18761,38 @@ def __init__(self, access=None, display_name=None, user=None, **unknown_fields): self.unknown_fields = unknown_fields - class OperationQueryArgs(Type): - _toSchema = {'actions': 'actions', 'applications': 'applications', 'limit': 'limit', 'machines': 'machines', 'offset': 'offset', 'status': 'status', 'units': 'units'} - _toPy = {'actions': 'actions', 'applications': 'applications', 'limit': 'limit', 'machines': 'machines', 'offset': 'offset', 'status': 'status', 'units': 'units'} - def __init__(self, actions=None, applications=None, limit=None, machines=None, offset=None, status=None, units=None, **unknown_fields): - ''' + _toSchema = { + "actions": "actions", + "applications": "applications", + "limit": "limit", + "machines": "machines", + "offset": "offset", + "status": "status", + "units": "units", + } + _toPy = { + "actions": "actions", + "applications": "applications", + "limit": "limit", + "machines": "machines", + "offset": "offset", + "status": "status", + "units": "units", + } + + def __init__( + self, + actions=None, + applications=None, + limit=None, + machines=None, + offset=None, + status=None, + units=None, + **unknown_fields, + ): + """ actions : typing.Sequence[str] applications : typing.Sequence[str] limit : int @@ -11708,7 +18800,7 @@ def __init__(self, actions=None, applications=None, limit=None, machines=None, o offset : int status : typing.Sequence[str] units : typing.Sequence[str] - ''' + """ actions_ = actions applications_ = applications limit_ = limit @@ -11719,25 +18811,47 @@ def __init__(self, actions=None, applications=None, limit=None, machines=None, o # Validate arguments against known Juju API types. if actions_ is not None and not isinstance(actions_, (bytes, str, list)): - raise Exception("Expected actions_ to be a Sequence, received: {}".format(type(actions_))) - - if applications_ is not None and not isinstance(applications_, (bytes, str, list)): - raise Exception("Expected applications_ to be a Sequence, received: {}".format(type(applications_))) + raise Exception( + "Expected actions_ to be a Sequence, received: {}".format( + type(actions_) + ) + ) + + if applications_ is not None and not isinstance( + applications_, (bytes, str, list) + ): + raise Exception( + "Expected applications_ to be a Sequence, received: {}".format( + type(applications_) + ) + ) if limit_ is not None and not isinstance(limit_, int): - raise Exception("Expected limit_ to be a int, received: {}".format(type(limit_))) + raise Exception( + "Expected limit_ to be a int, received: {}".format(type(limit_)) + ) if machines_ is not None and not isinstance(machines_, (bytes, str, list)): - raise Exception("Expected machines_ to be a Sequence, received: {}".format(type(machines_))) + raise Exception( + "Expected machines_ to be a Sequence, received: {}".format( + type(machines_) + ) + ) if offset_ is not None and not isinstance(offset_, int): - raise Exception("Expected offset_ to be a int, received: {}".format(type(offset_))) + raise Exception( + "Expected offset_ to be a int, received: {}".format(type(offset_)) + ) if status_ is not None and not isinstance(status_, (bytes, str, list)): - raise Exception("Expected status_ to be a Sequence, received: {}".format(type(status_))) + raise Exception( + "Expected status_ to be a Sequence, received: {}".format(type(status_)) + ) if units_ is not None and not isinstance(units_, (bytes, str, list)): - raise Exception("Expected units_ to be a Sequence, received: {}".format(type(units_))) + raise Exception( + "Expected units_ to be a Sequence, received: {}".format(type(units_)) + ) self.actions = actions_ self.applications = applications_ @@ -11749,12 +18863,44 @@ def __init__(self, actions=None, applications=None, limit=None, machines=None, o self.unknown_fields = unknown_fields - class OperationResult(Type): - _toSchema = {'actions': 'actions', 'completed': 'completed', 'enqueued': 'enqueued', 'error': 'error', 'fail': 'fail', 'operation': 'operation', 'started': 'started', 'status': 'status', 'summary': 'summary'} - _toPy = {'actions': 'actions', 'completed': 'completed', 'enqueued': 'enqueued', 'error': 'error', 'fail': 'fail', 'operation': 'operation', 'started': 'started', 'status': 'status', 'summary': 'summary'} - def __init__(self, actions=None, completed=None, enqueued=None, error=None, fail=None, operation=None, started=None, status=None, summary=None, **unknown_fields): - ''' + _toSchema = { + "actions": "actions", + "completed": "completed", + "enqueued": "enqueued", + "error": "error", + "fail": "fail", + "operation": "operation", + "started": "started", + "status": "status", + "summary": "summary", + } + _toPy = { + "actions": "actions", + "completed": "completed", + "enqueued": "enqueued", + "error": "error", + "fail": "fail", + "operation": "operation", + "started": "started", + "status": "status", + "summary": "summary", + } + + def __init__( + self, + actions=None, + completed=None, + enqueued=None, + error=None, + fail=None, + operation=None, + started=None, + status=None, + summary=None, + **unknown_fields, + ): + """ actions : typing.Sequence[~ActionResult] completed : str enqueued : str @@ -11764,7 +18910,7 @@ def __init__(self, actions=None, completed=None, enqueued=None, error=None, fail started : str status : str summary : str - ''' + """ actions_ = [ActionResult.from_json(o) for o in actions or []] completed_ = completed enqueued_ = enqueued @@ -11777,31 +18923,51 @@ def __init__(self, actions=None, completed=None, enqueued=None, error=None, fail # Validate arguments against known Juju API types. if actions_ is not None and not isinstance(actions_, (bytes, str, list)): - raise Exception("Expected actions_ to be a Sequence, received: {}".format(type(actions_))) + raise Exception( + "Expected actions_ to be a Sequence, received: {}".format( + type(actions_) + ) + ) if completed_ is not None and not isinstance(completed_, (bytes, str)): - raise Exception("Expected completed_ to be a str, received: {}".format(type(completed_))) + raise Exception( + "Expected completed_ to be a str, received: {}".format(type(completed_)) + ) if enqueued_ is not None and not isinstance(enqueued_, (bytes, str)): - raise Exception("Expected enqueued_ to be a str, received: {}".format(type(enqueued_))) + raise Exception( + "Expected enqueued_ to be a str, received: {}".format(type(enqueued_)) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if fail_ is not None and not isinstance(fail_, (bytes, str)): - raise Exception("Expected fail_ to be a str, received: {}".format(type(fail_))) + raise Exception( + "Expected fail_ to be a str, received: {}".format(type(fail_)) + ) if operation_ is not None and not isinstance(operation_, (bytes, str)): - raise Exception("Expected operation_ to be a str, received: {}".format(type(operation_))) + raise Exception( + "Expected operation_ to be a str, received: {}".format(type(operation_)) + ) if started_ is not None and not isinstance(started_, (bytes, str)): - raise Exception("Expected started_ to be a str, received: {}".format(type(started_))) + raise Exception( + "Expected started_ to be a str, received: {}".format(type(started_)) + ) if status_ is not None and not isinstance(status_, (bytes, str)): - raise Exception("Expected status_ to be a str, received: {}".format(type(status_))) + raise Exception( + "Expected status_ to be a str, received: {}".format(type(status_)) + ) if summary_ is not None and not isinstance(summary_, (bytes, str)): - raise Exception("Expected summary_ to be a str, received: {}".format(type(summary_))) + raise Exception( + "Expected summary_ to be a str, received: {}".format(type(summary_)) + ) self.actions = actions_ self.completed = completed_ @@ -11815,36 +18981,70 @@ def __init__(self, actions=None, completed=None, enqueued=None, error=None, fail self.unknown_fields = unknown_fields - class OperationResults(Type): - _toSchema = {'results': 'results', 'truncated': 'truncated'} - _toPy = {'results': 'results', 'truncated': 'truncated'} + _toSchema = {"results": "results", "truncated": "truncated"} + _toPy = {"results": "results", "truncated": "truncated"} + def __init__(self, results=None, truncated=None, **unknown_fields): - ''' + """ results : typing.Sequence[~OperationResult] truncated : bool - ''' + """ results_ = [OperationResult.from_json(o) for o in results or []] truncated_ = truncated # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) if truncated_ is not None and not isinstance(truncated_, bool): - raise Exception("Expected truncated_ to be a bool, received: {}".format(type(truncated_))) + raise Exception( + "Expected truncated_ to be a bool, received: {}".format( + type(truncated_) + ) + ) self.results = results_ self.truncated = truncated_ self.unknown_fields = unknown_fields - class Payload(Type): - _toSchema = {'class_': 'class', 'id_': 'id', 'labels': 'labels', 'machine': 'machine', 'status': 'status', 'type_': 'type', 'unit': 'unit'} - _toPy = {'class': 'class_', 'id': 'id_', 'labels': 'labels', 'machine': 'machine', 'status': 'status', 'type': 'type_', 'unit': 'unit'} - def __init__(self, class_=None, id_=None, labels=None, machine=None, status=None, type_=None, unit=None, **unknown_fields): - ''' + _toSchema = { + "class_": "class", + "id_": "id", + "labels": "labels", + "machine": "machine", + "status": "status", + "type_": "type", + "unit": "unit", + } + _toPy = { + "class": "class_", + "id": "id_", + "labels": "labels", + "machine": "machine", + "status": "status", + "type": "type_", + "unit": "unit", + } + + def __init__( + self, + class_=None, + id_=None, + labels=None, + machine=None, + status=None, + type_=None, + unit=None, + **unknown_fields, + ): + """ class_ : str id_ : str labels : typing.Sequence[str] @@ -11852,7 +19052,7 @@ def __init__(self, class_=None, id_=None, labels=None, machine=None, status=None status : str type_ : str unit : str - ''' + """ class__ = class_ id__ = id_ labels_ = labels @@ -11863,25 +19063,39 @@ def __init__(self, class_=None, id_=None, labels=None, machine=None, status=None # Validate arguments against known Juju API types. if class__ is not None and not isinstance(class__, (bytes, str)): - raise Exception("Expected class__ to be a str, received: {}".format(type(class__))) + raise Exception( + "Expected class__ to be a str, received: {}".format(type(class__)) + ) if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception("Expected id__ to be a str, received: {}".format(type(id__))) + raise Exception( + "Expected id__ to be a str, received: {}".format(type(id__)) + ) if labels_ is not None and not isinstance(labels_, (bytes, str, list)): - raise Exception("Expected labels_ to be a Sequence, received: {}".format(type(labels_))) + raise Exception( + "Expected labels_ to be a Sequence, received: {}".format(type(labels_)) + ) if machine_ is not None and not isinstance(machine_, (bytes, str)): - raise Exception("Expected machine_ to be a str, received: {}".format(type(machine_))) + raise Exception( + "Expected machine_ to be a str, received: {}".format(type(machine_)) + ) if status_ is not None and not isinstance(status_, (bytes, str)): - raise Exception("Expected status_ to be a str, received: {}".format(type(status_))) + raise Exception( + "Expected status_ to be a str, received: {}".format(type(status_)) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) if unit_ is not None and not isinstance(unit_, (bytes, str)): - raise Exception("Expected unit_ to be a str, received: {}".format(type(unit_))) + raise Exception( + "Expected unit_ to be a str, received: {}".format(type(unit_)) + ) self.class_ = class__ self.id_ = id__ @@ -11893,65 +19107,79 @@ def __init__(self, class_=None, id_=None, labels=None, machine=None, status=None self.unknown_fields = unknown_fields - class PayloadListArgs(Type): - _toSchema = {'patterns': 'patterns'} - _toPy = {'patterns': 'patterns'} + _toSchema = {"patterns": "patterns"} + _toPy = {"patterns": "patterns"} + def __init__(self, patterns=None, **unknown_fields): - ''' + """ patterns : typing.Sequence[str] - ''' + """ patterns_ = patterns # Validate arguments against known Juju API types. if patterns_ is not None and not isinstance(patterns_, (bytes, str, list)): - raise Exception("Expected patterns_ to be a Sequence, received: {}".format(type(patterns_))) + raise Exception( + "Expected patterns_ to be a Sequence, received: {}".format( + type(patterns_) + ) + ) self.patterns = patterns_ self.unknown_fields = unknown_fields - class PayloadListResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~Payload] - ''' + """ results_ = [Payload.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class PendingResourceUpload(Type): - _toSchema = {'filename': 'Filename', 'name': 'Name', 'type_': 'Type'} - _toPy = {'Filename': 'filename', 'Name': 'name', 'Type': 'type_'} + _toSchema = {"filename": "Filename", "name": "Name", "type_": "Type"} + _toPy = {"Filename": "filename", "Name": "name", "Type": "type_"} + def __init__(self, filename=None, name=None, type_=None, **unknown_fields): - ''' + """ filename : str name : str type_ : str - ''' + """ filename_ = filename name_ = name type__ = type_ # Validate arguments against known Juju API types. if filename_ is not None and not isinstance(filename_, (bytes, str)): - raise Exception("Expected filename_ to be a str, received: {}".format(type(filename_))) + raise Exception( + "Expected filename_ to be a str, received: {}".format(type(filename_)) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) self.filename = filename_ self.name = name_ @@ -11959,41 +19187,62 @@ def __init__(self, filename=None, name=None, type_=None, **unknown_fields): self.unknown_fields = unknown_fields - class Placement(Type): - _toSchema = {'directive': 'directive', 'scope': 'scope'} - _toPy = {'directive': 'directive', 'scope': 'scope'} + _toSchema = {"directive": "directive", "scope": "scope"} + _toPy = {"directive": "directive", "scope": "scope"} + def __init__(self, directive=None, scope=None, **unknown_fields): - ''' + """ directive : str scope : str - ''' + """ directive_ = directive scope_ = scope # Validate arguments against known Juju API types. if directive_ is not None and not isinstance(directive_, (bytes, str)): - raise Exception("Expected directive_ to be a str, received: {}".format(type(directive_))) + raise Exception( + "Expected directive_ to be a str, received: {}".format(type(directive_)) + ) if scope_ is not None and not isinstance(scope_, (bytes, str)): - raise Exception("Expected scope_ to be a str, received: {}".format(type(scope_))) + raise Exception( + "Expected scope_ to be a str, received: {}".format(type(scope_)) + ) self.directive = directive_ self.scope = scope_ self.unknown_fields = unknown_fields - class ProvisioningScriptParams(Type): - _toSchema = {'data_dir': 'data-dir', 'disable_package_commands': 'disable-package-commands', 'machine_id': 'machine-id', 'nonce': 'nonce'} - _toPy = {'data-dir': 'data_dir', 'disable-package-commands': 'disable_package_commands', 'machine-id': 'machine_id', 'nonce': 'nonce'} - def __init__(self, data_dir=None, disable_package_commands=None, machine_id=None, nonce=None, **unknown_fields): - ''' + _toSchema = { + "data_dir": "data-dir", + "disable_package_commands": "disable-package-commands", + "machine_id": "machine-id", + "nonce": "nonce", + } + _toPy = { + "data-dir": "data_dir", + "disable-package-commands": "disable_package_commands", + "machine-id": "machine_id", + "nonce": "nonce", + } + + def __init__( + self, + data_dir=None, + disable_package_commands=None, + machine_id=None, + nonce=None, + **unknown_fields, + ): + """ data_dir : str disable_package_commands : bool machine_id : str nonce : str - ''' + """ data_dir_ = data_dir disable_package_commands_ = disable_package_commands machine_id_ = machine_id @@ -12001,16 +19250,30 @@ def __init__(self, data_dir=None, disable_package_commands=None, machine_id=None # Validate arguments against known Juju API types. if data_dir_ is not None and not isinstance(data_dir_, (bytes, str)): - raise Exception("Expected data_dir_ to be a str, received: {}".format(type(data_dir_))) - - if disable_package_commands_ is not None and not isinstance(disable_package_commands_, bool): - raise Exception("Expected disable_package_commands_ to be a bool, received: {}".format(type(disable_package_commands_))) + raise Exception( + "Expected data_dir_ to be a str, received: {}".format(type(data_dir_)) + ) + + if disable_package_commands_ is not None and not isinstance( + disable_package_commands_, bool + ): + raise Exception( + "Expected disable_package_commands_ to be a bool, received: {}".format( + type(disable_package_commands_) + ) + ) if machine_id_ is not None and not isinstance(machine_id_, (bytes, str)): - raise Exception("Expected machine_id_ to be a str, received: {}".format(type(machine_id_))) + raise Exception( + "Expected machine_id_ to be a str, received: {}".format( + type(machine_id_) + ) + ) if nonce_ is not None and not isinstance(nonce_, (bytes, str)): - raise Exception("Expected nonce_ to be a str, received: {}".format(type(nonce_))) + raise Exception( + "Expected nonce_ to be a str, received: {}".format(type(nonce_)) + ) self.data_dir = data_dir_ self.disable_package_commands = disable_package_commands_ @@ -12019,166 +19282,219 @@ def __init__(self, data_dir=None, disable_package_commands=None, machine_id=None self.unknown_fields = unknown_fields - class ProvisioningScriptResult(Type): - _toSchema = {'script': 'script'} - _toPy = {'script': 'script'} + _toSchema = {"script": "script"} + _toPy = {"script": "script"} + def __init__(self, script=None, **unknown_fields): - ''' + """ script : str - ''' + """ script_ = script # Validate arguments against known Juju API types. if script_ is not None and not isinstance(script_, (bytes, str)): - raise Exception("Expected script_ to be a str, received: {}".format(type(script_))) + raise Exception( + "Expected script_ to be a str, received: {}".format(type(script_)) + ) self.script = script_ self.unknown_fields = unknown_fields - class Proxy(Type): - _toSchema = {'config': 'config', 'type_': 'type'} - _toPy = {'config': 'config', 'type': 'type_'} + _toSchema = {"config": "config", "type_": "type"} + _toPy = {"config": "config", "type": "type_"} + def __init__(self, config=None, type_=None, **unknown_fields): - ''' + """ config : typing.Mapping[str, typing.Any] type_ : str - ''' + """ config_ = config type__ = type_ # Validate arguments against known Juju API types. if config_ is not None and not isinstance(config_, dict): - raise Exception("Expected config_ to be a Mapping, received: {}".format(type(config_))) + raise Exception( + "Expected config_ to be a Mapping, received: {}".format(type(config_)) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) self.config = config_ self.type_ = type__ self.unknown_fields = unknown_fields - class QueryApplicationOffersResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~ApplicationOfferAdminDetails] - ''' + """ results_ = [ApplicationOfferAdminDetails.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class QueryApplicationOffersResultsV5(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~ApplicationOfferAdminDetailsV5] - ''' + """ results_ = [ApplicationOfferAdminDetailsV5.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class RedirectInfoResult(Type): - _toSchema = {'ca_cert': 'ca-cert', 'servers': 'servers'} - _toPy = {'ca-cert': 'ca_cert', 'servers': 'servers'} + _toSchema = {"ca_cert": "ca-cert", "servers": "servers"} + _toPy = {"ca-cert": "ca_cert", "servers": "servers"} + def __init__(self, ca_cert=None, servers=None, **unknown_fields): - ''' + """ ca_cert : str servers : typing.Sequence[~HostPort] - ''' + """ ca_cert_ = ca_cert servers_ = [HostPort.from_json(o) for o in servers or []] # Validate arguments against known Juju API types. if ca_cert_ is not None and not isinstance(ca_cert_, (bytes, str)): - raise Exception("Expected ca_cert_ to be a str, received: {}".format(type(ca_cert_))) + raise Exception( + "Expected ca_cert_ to be a str, received: {}".format(type(ca_cert_)) + ) if servers_ is not None and not isinstance(servers_, (bytes, str, list)): - raise Exception("Expected servers_ to be a Sequence, received: {}".format(type(servers_))) + raise Exception( + "Expected servers_ to be a Sequence, received: {}".format( + type(servers_) + ) + ) self.ca_cert = ca_cert_ self.servers = servers_ self.unknown_fields = unknown_fields - class RegionDefaults(Type): - _toSchema = {'region_name': 'region-name', 'value': 'value'} - _toPy = {'region-name': 'region_name', 'value': 'value'} + _toSchema = {"region_name": "region-name", "value": "value"} + _toPy = {"region-name": "region_name", "value": "value"} + def __init__(self, region_name=None, value=None, **unknown_fields): - ''' + """ region_name : str value : Any - ''' + """ region_name_ = region_name value_ = value # Validate arguments against known Juju API types. if region_name_ is not None and not isinstance(region_name_, (bytes, str)): - raise Exception("Expected region_name_ to be a str, received: {}".format(type(region_name_))) + raise Exception( + "Expected region_name_ to be a str, received: {}".format( + type(region_name_) + ) + ) self.region_name = region_name_ self.value = value_ self.unknown_fields = unknown_fields - class RelationData(Type): - _toSchema = {'inscope': 'InScope', 'unitdata': 'UnitData'} - _toPy = {'InScope': 'inscope', 'UnitData': 'unitdata'} + _toSchema = {"inscope": "InScope", "unitdata": "UnitData"} + _toPy = {"InScope": "inscope", "UnitData": "unitdata"} + def __init__(self, inscope=None, unitdata=None, **unknown_fields): - ''' + """ inscope : bool unitdata : typing.Mapping[str, typing.Any] - ''' + """ inscope_ = inscope unitdata_ = unitdata # Validate arguments against known Juju API types. if inscope_ is not None and not isinstance(inscope_, bool): - raise Exception("Expected inscope_ to be a bool, received: {}".format(type(inscope_))) + raise Exception( + "Expected inscope_ to be a bool, received: {}".format(type(inscope_)) + ) if unitdata_ is not None and not isinstance(unitdata_, dict): - raise Exception("Expected unitdata_ to be a Mapping, received: {}".format(type(unitdata_))) + raise Exception( + "Expected unitdata_ to be a Mapping, received: {}".format( + type(unitdata_) + ) + ) self.inscope = inscope_ self.unitdata = unitdata_ self.unknown_fields = unknown_fields - class RelationStatus(Type): - _toSchema = {'endpoints': 'endpoints', 'id_': 'id', 'interface': 'interface', 'key': 'key', 'scope': 'scope', 'status': 'status'} - _toPy = {'endpoints': 'endpoints', 'id': 'id_', 'interface': 'interface', 'key': 'key', 'scope': 'scope', 'status': 'status'} - def __init__(self, endpoints=None, id_=None, interface=None, key=None, scope=None, status=None, **unknown_fields): - ''' + _toSchema = { + "endpoints": "endpoints", + "id_": "id", + "interface": "interface", + "key": "key", + "scope": "scope", + "status": "status", + } + _toPy = { + "endpoints": "endpoints", + "id": "id_", + "interface": "interface", + "key": "key", + "scope": "scope", + "status": "status", + } + + def __init__( + self, + endpoints=None, + id_=None, + interface=None, + key=None, + scope=None, + status=None, + **unknown_fields, + ): + """ endpoints : typing.Sequence[~EndpointStatus] id_ : int interface : str key : str scope : str status : DetailedStatus - ''' + """ endpoints_ = [EndpointStatus.from_json(o) for o in endpoints or []] id__ = id_ interface_ = interface @@ -12188,22 +19504,38 @@ def __init__(self, endpoints=None, id_=None, interface=None, key=None, scope=Non # Validate arguments against known Juju API types. if endpoints_ is not None and not isinstance(endpoints_, (bytes, str, list)): - raise Exception("Expected endpoints_ to be a Sequence, received: {}".format(type(endpoints_))) + raise Exception( + "Expected endpoints_ to be a Sequence, received: {}".format( + type(endpoints_) + ) + ) if id__ is not None and not isinstance(id__, int): - raise Exception("Expected id__ to be a int, received: {}".format(type(id__))) + raise Exception( + "Expected id__ to be a int, received: {}".format(type(id__)) + ) if interface_ is not None and not isinstance(interface_, (bytes, str)): - raise Exception("Expected interface_ to be a str, received: {}".format(type(interface_))) + raise Exception( + "Expected interface_ to be a str, received: {}".format(type(interface_)) + ) if key_ is not None and not isinstance(key_, (bytes, str)): - raise Exception("Expected key_ to be a str, received: {}".format(type(key_))) + raise Exception( + "Expected key_ to be a str, received: {}".format(type(key_)) + ) if scope_ is not None and not isinstance(scope_, (bytes, str)): - raise Exception("Expected scope_ to be a str, received: {}".format(type(scope_))) + raise Exception( + "Expected scope_ to be a str, received: {}".format(type(scope_)) + ) if status_ is not None and not isinstance(status_, (dict, DetailedStatus)): - raise Exception("Expected status_ to be a DetailedStatus, received: {}".format(type(status_))) + raise Exception( + "Expected status_ to be a DetailedStatus, received: {}".format( + type(status_) + ) + ) self.endpoints = endpoints_ self.id_ = id__ @@ -12214,29 +19546,49 @@ def __init__(self, endpoints=None, id_=None, interface=None, key=None, scope=Non self.unknown_fields = unknown_fields - class RelationSuspendedArg(Type): - _toSchema = {'message': 'message', 'relation_id': 'relation-id', 'suspended': 'suspended'} - _toPy = {'message': 'message', 'relation-id': 'relation_id', 'suspended': 'suspended'} - def __init__(self, message=None, relation_id=None, suspended=None, **unknown_fields): - ''' + _toSchema = { + "message": "message", + "relation_id": "relation-id", + "suspended": "suspended", + } + _toPy = { + "message": "message", + "relation-id": "relation_id", + "suspended": "suspended", + } + + def __init__( + self, message=None, relation_id=None, suspended=None, **unknown_fields + ): + """ message : str relation_id : int suspended : bool - ''' + """ message_ = message relation_id_ = relation_id suspended_ = suspended # Validate arguments against known Juju API types. if message_ is not None and not isinstance(message_, (bytes, str)): - raise Exception("Expected message_ to be a str, received: {}".format(type(message_))) + raise Exception( + "Expected message_ to be a str, received: {}".format(type(message_)) + ) if relation_id_ is not None and not isinstance(relation_id_, int): - raise Exception("Expected relation_id_ to be a int, received: {}".format(type(relation_id_))) + raise Exception( + "Expected relation_id_ to be a int, received: {}".format( + type(relation_id_) + ) + ) if suspended_ is not None and not isinstance(suspended_, bool): - raise Exception("Expected suspended_ to be a bool, received: {}".format(type(suspended_))) + raise Exception( + "Expected suspended_ to be a bool, received: {}".format( + type(suspended_) + ) + ) self.message = message_ self.relation_id = relation_id_ @@ -12244,30 +19596,58 @@ def __init__(self, message=None, relation_id=None, suspended=None, **unknown_fie self.unknown_fields = unknown_fields - class RelationSuspendedArgs(Type): - _toSchema = {'args': 'args'} - _toPy = {'args': 'args'} + _toSchema = {"args": "args"} + _toPy = {"args": "args"} + def __init__(self, args=None, **unknown_fields): - ''' + """ args : typing.Sequence[~RelationSuspendedArg] - ''' + """ args_ = [RelationSuspendedArg.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception("Expected args_ to be a Sequence, received: {}".format(type(args_))) + raise Exception( + "Expected args_ to be a Sequence, received: {}".format(type(args_)) + ) self.args = args_ self.unknown_fields = unknown_fields - class RemoteApplicationInfo(Type): - _toSchema = {'description': 'description', 'endpoints': 'endpoints', 'icon_url_path': 'icon-url-path', 'model_tag': 'model-tag', 'name': 'name', 'offer_url': 'offer-url', 'source_model_label': 'source-model-label'} - _toPy = {'description': 'description', 'endpoints': 'endpoints', 'icon-url-path': 'icon_url_path', 'model-tag': 'model_tag', 'name': 'name', 'offer-url': 'offer_url', 'source-model-label': 'source_model_label'} - def __init__(self, description=None, endpoints=None, icon_url_path=None, model_tag=None, name=None, offer_url=None, source_model_label=None, **unknown_fields): - ''' + _toSchema = { + "description": "description", + "endpoints": "endpoints", + "icon_url_path": "icon-url-path", + "model_tag": "model-tag", + "name": "name", + "offer_url": "offer-url", + "source_model_label": "source-model-label", + } + _toPy = { + "description": "description", + "endpoints": "endpoints", + "icon-url-path": "icon_url_path", + "model-tag": "model_tag", + "name": "name", + "offer-url": "offer_url", + "source-model-label": "source_model_label", + } + + def __init__( + self, + description=None, + endpoints=None, + icon_url_path=None, + model_tag=None, + name=None, + offer_url=None, + source_model_label=None, + **unknown_fields, + ): + """ description : str endpoints : typing.Sequence[~RemoteEndpoint] icon_url_path : str @@ -12275,7 +19655,7 @@ def __init__(self, description=None, endpoints=None, icon_url_path=None, model_t name : str offer_url : str source_model_label : str - ''' + """ description_ = description endpoints_ = [RemoteEndpoint.from_json(o) for o in endpoints or []] icon_url_path_ = icon_url_path @@ -12286,25 +19666,49 @@ def __init__(self, description=None, endpoints=None, icon_url_path=None, model_t # Validate arguments against known Juju API types. if description_ is not None and not isinstance(description_, (bytes, str)): - raise Exception("Expected description_ to be a str, received: {}".format(type(description_))) + raise Exception( + "Expected description_ to be a str, received: {}".format( + type(description_) + ) + ) if endpoints_ is not None and not isinstance(endpoints_, (bytes, str, list)): - raise Exception("Expected endpoints_ to be a Sequence, received: {}".format(type(endpoints_))) + raise Exception( + "Expected endpoints_ to be a Sequence, received: {}".format( + type(endpoints_) + ) + ) if icon_url_path_ is not None and not isinstance(icon_url_path_, (bytes, str)): - raise Exception("Expected icon_url_path_ to be a str, received: {}".format(type(icon_url_path_))) + raise Exception( + "Expected icon_url_path_ to be a str, received: {}".format( + type(icon_url_path_) + ) + ) if model_tag_ is not None and not isinstance(model_tag_, (bytes, str)): - raise Exception("Expected model_tag_ to be a str, received: {}".format(type(model_tag_))) + raise Exception( + "Expected model_tag_ to be a str, received: {}".format(type(model_tag_)) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if offer_url_ is not None and not isinstance(offer_url_, (bytes, str)): - raise Exception("Expected offer_url_ to be a str, received: {}".format(type(offer_url_))) - - if source_model_label_ is not None and not isinstance(source_model_label_, (bytes, str)): - raise Exception("Expected source_model_label_ to be a str, received: {}".format(type(source_model_label_))) + raise Exception( + "Expected offer_url_ to be a str, received: {}".format(type(offer_url_)) + ) + + if source_model_label_ is not None and not isinstance( + source_model_label_, (bytes, str) + ): + raise Exception( + "Expected source_model_label_ to be a str, received: {}".format( + type(source_model_label_) + ) + ) self.description = description_ self.endpoints = endpoints_ @@ -12316,54 +19720,92 @@ def __init__(self, description=None, endpoints=None, icon_url_path=None, model_t self.unknown_fields = unknown_fields - class RemoteApplicationInfoResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : RemoteApplicationInfo - ''' + """ error_ = Error.from_json(error) if error else None result_ = RemoteApplicationInfo.from_json(result) if result else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) - - if result_ is not None and not isinstance(result_, (dict, RemoteApplicationInfo)): - raise Exception("Expected result_ to be a RemoteApplicationInfo, received: {}".format(type(result_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) + + if result_ is not None and not isinstance( + result_, (dict, RemoteApplicationInfo) + ): + raise Exception( + "Expected result_ to be a RemoteApplicationInfo, received: {}".format( + type(result_) + ) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class RemoteApplicationInfoResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~RemoteApplicationInfoResult] - ''' + """ results_ = [RemoteApplicationInfoResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class RemoteApplicationStatus(Type): - _toSchema = {'endpoints': 'endpoints', 'err': 'err', 'life': 'life', 'offer_name': 'offer-name', 'offer_url': 'offer-url', 'relations': 'relations', 'status': 'status'} - _toPy = {'endpoints': 'endpoints', 'err': 'err', 'life': 'life', 'offer-name': 'offer_name', 'offer-url': 'offer_url', 'relations': 'relations', 'status': 'status'} - def __init__(self, endpoints=None, err=None, life=None, offer_name=None, offer_url=None, relations=None, status=None, **unknown_fields): - ''' + _toSchema = { + "endpoints": "endpoints", + "err": "err", + "life": "life", + "offer_name": "offer-name", + "offer_url": "offer-url", + "relations": "relations", + "status": "status", + } + _toPy = { + "endpoints": "endpoints", + "err": "err", + "life": "life", + "offer-name": "offer_name", + "offer-url": "offer_url", + "relations": "relations", + "status": "status", + } + + def __init__( + self, + endpoints=None, + err=None, + life=None, + offer_name=None, + offer_url=None, + relations=None, + status=None, + **unknown_fields, + ): + """ endpoints : typing.Sequence[~RemoteEndpoint] err : Error life : str @@ -12371,7 +19813,7 @@ def __init__(self, endpoints=None, err=None, life=None, offer_name=None, offer_u offer_url : str relations : typing.Mapping[str, typing.Sequence[str]] status : DetailedStatus - ''' + """ endpoints_ = [RemoteEndpoint.from_json(o) for o in endpoints or []] err_ = Error.from_json(err) if err else None life_ = life @@ -12382,25 +19824,47 @@ def __init__(self, endpoints=None, err=None, life=None, offer_name=None, offer_u # Validate arguments against known Juju API types. if endpoints_ is not None and not isinstance(endpoints_, (bytes, str, list)): - raise Exception("Expected endpoints_ to be a Sequence, received: {}".format(type(endpoints_))) + raise Exception( + "Expected endpoints_ to be a Sequence, received: {}".format( + type(endpoints_) + ) + ) if err_ is not None and not isinstance(err_, (dict, Error)): - raise Exception("Expected err_ to be a Error, received: {}".format(type(err_))) + raise Exception( + "Expected err_ to be a Error, received: {}".format(type(err_)) + ) if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception("Expected life_ to be a str, received: {}".format(type(life_))) + raise Exception( + "Expected life_ to be a str, received: {}".format(type(life_)) + ) if offer_name_ is not None and not isinstance(offer_name_, (bytes, str)): - raise Exception("Expected offer_name_ to be a str, received: {}".format(type(offer_name_))) + raise Exception( + "Expected offer_name_ to be a str, received: {}".format( + type(offer_name_) + ) + ) if offer_url_ is not None and not isinstance(offer_url_, (bytes, str)): - raise Exception("Expected offer_url_ to be a str, received: {}".format(type(offer_url_))) + raise Exception( + "Expected offer_url_ to be a str, received: {}".format(type(offer_url_)) + ) if relations_ is not None and not isinstance(relations_, dict): - raise Exception("Expected relations_ to be a Mapping, received: {}".format(type(relations_))) + raise Exception( + "Expected relations_ to be a Mapping, received: {}".format( + type(relations_) + ) + ) if status_ is not None and not isinstance(status_, (dict, DetailedStatus)): - raise Exception("Expected status_ to be a DetailedStatus, received: {}".format(type(status_))) + raise Exception( + "Expected status_ to be a DetailedStatus, received: {}".format( + type(status_) + ) + ) self.endpoints = endpoints_ self.err = err_ @@ -12412,17 +19876,24 @@ def __init__(self, endpoints=None, err=None, life=None, offer_name=None, offer_u self.unknown_fields = unknown_fields - class RemoteEndpoint(Type): - _toSchema = {'interface': 'interface', 'limit': 'limit', 'name': 'name', 'role': 'role'} - _toPy = {'interface': 'interface', 'limit': 'limit', 'name': 'name', 'role': 'role'} - def __init__(self, interface=None, limit=None, name=None, role=None, **unknown_fields): - ''' + _toSchema = { + "interface": "interface", + "limit": "limit", + "name": "name", + "role": "role", + } + _toPy = {"interface": "interface", "limit": "limit", "name": "name", "role": "role"} + + def __init__( + self, interface=None, limit=None, name=None, role=None, **unknown_fields + ): + """ interface : str limit : int name : str role : str - ''' + """ interface_ = interface limit_ = limit name_ = name @@ -12430,16 +19901,24 @@ def __init__(self, interface=None, limit=None, name=None, role=None, **unknown_f # Validate arguments against known Juju API types. if interface_ is not None and not isinstance(interface_, (bytes, str)): - raise Exception("Expected interface_ to be a str, received: {}".format(type(interface_))) + raise Exception( + "Expected interface_ to be a str, received: {}".format(type(interface_)) + ) if limit_ is not None and not isinstance(limit_, int): - raise Exception("Expected limit_ to be a int, received: {}".format(type(limit_))) + raise Exception( + "Expected limit_ to be a int, received: {}".format(type(limit_)) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if role_ is not None and not isinstance(role_, (bytes, str)): - raise Exception("Expected role_ to be a str, received: {}".format(type(role_))) + raise Exception( + "Expected role_ to be a str, received: {}".format(type(role_)) + ) self.interface = interface_ self.limit = limit_ @@ -12448,18 +19927,38 @@ def __init__(self, interface=None, limit=None, name=None, role=None, **unknown_f self.unknown_fields = unknown_fields - class RemoteSpace(Type): - _toSchema = {'cloud_type': 'cloud-type', 'name': 'name', 'provider_attributes': 'provider-attributes', 'provider_id': 'provider-id', 'subnets': 'subnets'} - _toPy = {'cloud-type': 'cloud_type', 'name': 'name', 'provider-attributes': 'provider_attributes', 'provider-id': 'provider_id', 'subnets': 'subnets'} - def __init__(self, cloud_type=None, name=None, provider_attributes=None, provider_id=None, subnets=None, **unknown_fields): - ''' + _toSchema = { + "cloud_type": "cloud-type", + "name": "name", + "provider_attributes": "provider-attributes", + "provider_id": "provider-id", + "subnets": "subnets", + } + _toPy = { + "cloud-type": "cloud_type", + "name": "name", + "provider-attributes": "provider_attributes", + "provider-id": "provider_id", + "subnets": "subnets", + } + + def __init__( + self, + cloud_type=None, + name=None, + provider_attributes=None, + provider_id=None, + subnets=None, + **unknown_fields, + ): + """ cloud_type : str name : str provider_attributes : typing.Mapping[str, typing.Any] provider_id : str subnets : typing.Sequence[~Subnet] - ''' + """ cloud_type_ = cloud_type name_ = name provider_attributes_ = provider_attributes @@ -12468,19 +19967,39 @@ def __init__(self, cloud_type=None, name=None, provider_attributes=None, provide # Validate arguments against known Juju API types. if cloud_type_ is not None and not isinstance(cloud_type_, (bytes, str)): - raise Exception("Expected cloud_type_ to be a str, received: {}".format(type(cloud_type_))) + raise Exception( + "Expected cloud_type_ to be a str, received: {}".format( + type(cloud_type_) + ) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) - - if provider_attributes_ is not None and not isinstance(provider_attributes_, dict): - raise Exception("Expected provider_attributes_ to be a Mapping, received: {}".format(type(provider_attributes_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) + + if provider_attributes_ is not None and not isinstance( + provider_attributes_, dict + ): + raise Exception( + "Expected provider_attributes_ to be a Mapping, received: {}".format( + type(provider_attributes_) + ) + ) if provider_id_ is not None and not isinstance(provider_id_, (bytes, str)): - raise Exception("Expected provider_id_ to be a str, received: {}".format(type(provider_id_))) + raise Exception( + "Expected provider_id_ to be a str, received: {}".format( + type(provider_id_) + ) + ) if subnets_ is not None and not isinstance(subnets_, (bytes, str, list)): - raise Exception("Expected subnets_ to be a Sequence, received: {}".format(type(subnets_))) + raise Exception( + "Expected subnets_ to be a Sequence, received: {}".format( + type(subnets_) + ) + ) self.cloud_type = cloud_type_ self.name = name_ @@ -12490,89 +20009,103 @@ def __init__(self, cloud_type=None, name=None, provider_attributes=None, provide self.unknown_fields = unknown_fields - class RemoveBlocksArgs(Type): - _toSchema = {'all_': 'all'} - _toPy = {'all': 'all_'} + _toSchema = {"all_": "all"} + _toPy = {"all": "all_"} + def __init__(self, all_=None, **unknown_fields): - ''' + """ all_ : bool - ''' + """ all__ = all_ # Validate arguments against known Juju API types. if all__ is not None and not isinstance(all__, bool): - raise Exception("Expected all__ to be a bool, received: {}".format(type(all__))) + raise Exception( + "Expected all__ to be a bool, received: {}".format(type(all__)) + ) self.all_ = all__ self.unknown_fields = unknown_fields - class RemoveSecretBackendArg(Type): - _toSchema = {'force': 'force', 'name': 'name'} - _toPy = {'force': 'force', 'name': 'name'} + _toSchema = {"force": "force", "name": "name"} + _toPy = {"force": "force", "name": "name"} + def __init__(self, force=None, name=None, **unknown_fields): - ''' + """ force : bool name : str - ''' + """ force_ = force name_ = name # Validate arguments against known Juju API types. if force_ is not None and not isinstance(force_, bool): - raise Exception("Expected force_ to be a bool, received: {}".format(type(force_))) + raise Exception( + "Expected force_ to be a bool, received: {}".format(type(force_)) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) self.force = force_ self.name = name_ self.unknown_fields = unknown_fields - class RemoveSecretBackendArgs(Type): - _toSchema = {'args': 'args'} - _toPy = {'args': 'args'} + _toSchema = {"args": "args"} + _toPy = {"args": "args"} + def __init__(self, args=None, **unknown_fields): - ''' + """ args : typing.Sequence[~RemoveSecretBackendArg] - ''' + """ args_ = [RemoveSecretBackendArg.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception("Expected args_ to be a Sequence, received: {}".format(type(args_))) + raise Exception( + "Expected args_ to be a Sequence, received: {}".format(type(args_)) + ) self.args = args_ self.unknown_fields = unknown_fields - class RemoveSpaceParam(Type): - _toSchema = {'dry_run': 'dry-run', 'force': 'force', 'space': 'space'} - _toPy = {'dry-run': 'dry_run', 'force': 'force', 'space': 'space'} + _toSchema = {"dry_run": "dry-run", "force": "force", "space": "space"} + _toPy = {"dry-run": "dry_run", "force": "force", "space": "space"} + def __init__(self, dry_run=None, force=None, space=None, **unknown_fields): - ''' + """ dry_run : bool force : bool space : Entity - ''' + """ dry_run_ = dry_run force_ = force space_ = Entity.from_json(space) if space else None # Validate arguments against known Juju API types. if dry_run_ is not None and not isinstance(dry_run_, bool): - raise Exception("Expected dry_run_ to be a bool, received: {}".format(type(dry_run_))) + raise Exception( + "Expected dry_run_ to be a bool, received: {}".format(type(dry_run_)) + ) if force_ is not None and not isinstance(force_, bool): - raise Exception("Expected force_ to be a bool, received: {}".format(type(force_))) + raise Exception( + "Expected force_ to be a bool, received: {}".format(type(force_)) + ) if space_ is not None and not isinstance(space_, (dict, Entity)): - raise Exception("Expected space_ to be a Entity, received: {}".format(type(space_))) + raise Exception( + "Expected space_ to be a Entity, received: {}".format(type(space_)) + ) self.dry_run = dry_run_ self.force = force_ @@ -12580,35 +20113,58 @@ def __init__(self, dry_run=None, force=None, space=None, **unknown_fields): self.unknown_fields = unknown_fields - class RemoveSpaceParams(Type): - _toSchema = {'space_param': 'space-param'} - _toPy = {'space-param': 'space_param'} + _toSchema = {"space_param": "space-param"} + _toPy = {"space-param": "space_param"} + def __init__(self, space_param=None, **unknown_fields): - ''' + """ space_param : typing.Sequence[~RemoveSpaceParam] - ''' + """ space_param_ = [RemoveSpaceParam.from_json(o) for o in space_param or []] # Validate arguments against known Juju API types. - if space_param_ is not None and not isinstance(space_param_, (bytes, str, list)): - raise Exception("Expected space_param_ to be a Sequence, received: {}".format(type(space_param_))) + if space_param_ is not None and not isinstance( + space_param_, (bytes, str, list) + ): + raise Exception( + "Expected space_param_ to be a Sequence, received: {}".format( + type(space_param_) + ) + ) self.space_param = space_param_ self.unknown_fields = unknown_fields - class RemoveSpaceResult(Type): - _toSchema = {'bindings': 'bindings', 'constraints': 'constraints', 'controller_settings': 'controller-settings', 'error': 'error'} - _toPy = {'bindings': 'bindings', 'constraints': 'constraints', 'controller-settings': 'controller_settings', 'error': 'error'} - def __init__(self, bindings=None, constraints=None, controller_settings=None, error=None, **unknown_fields): - ''' + _toSchema = { + "bindings": "bindings", + "constraints": "constraints", + "controller_settings": "controller-settings", + "error": "error", + } + _toPy = { + "bindings": "bindings", + "constraints": "constraints", + "controller-settings": "controller_settings", + "error": "error", + } + + def __init__( + self, + bindings=None, + constraints=None, + controller_settings=None, + error=None, + **unknown_fields, + ): + """ bindings : typing.Sequence[~Entity] constraints : typing.Sequence[~Entity] controller_settings : typing.Sequence[str] error : Error - ''' + """ bindings_ = [Entity.from_json(o) for o in bindings or []] constraints_ = [Entity.from_json(o) for o in constraints or []] controller_settings_ = controller_settings @@ -12616,16 +20172,34 @@ def __init__(self, bindings=None, constraints=None, controller_settings=None, er # Validate arguments against known Juju API types. if bindings_ is not None and not isinstance(bindings_, (bytes, str, list)): - raise Exception("Expected bindings_ to be a Sequence, received: {}".format(type(bindings_))) - - if constraints_ is not None and not isinstance(constraints_, (bytes, str, list)): - raise Exception("Expected constraints_ to be a Sequence, received: {}".format(type(constraints_))) - - if controller_settings_ is not None and not isinstance(controller_settings_, (bytes, str, list)): - raise Exception("Expected controller_settings_ to be a Sequence, received: {}".format(type(controller_settings_))) + raise Exception( + "Expected bindings_ to be a Sequence, received: {}".format( + type(bindings_) + ) + ) + + if constraints_ is not None and not isinstance( + constraints_, (bytes, str, list) + ): + raise Exception( + "Expected constraints_ to be a Sequence, received: {}".format( + type(constraints_) + ) + ) + + if controller_settings_ is not None and not isinstance( + controller_settings_, (bytes, str, list) + ): + raise Exception( + "Expected controller_settings_ to be a Sequence, received: {}".format( + type(controller_settings_) + ) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) self.bindings = bindings_ self.constraints = constraints_ @@ -12634,54 +20208,82 @@ def __init__(self, bindings=None, constraints=None, controller_settings=None, er self.unknown_fields = unknown_fields - class RemoveSpaceResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~RemoveSpaceResult] - ''' + """ results_ = [RemoveSpaceResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class RemoveStorage(Type): - _toSchema = {'storage': 'storage'} - _toPy = {'storage': 'storage'} + _toSchema = {"storage": "storage"} + _toPy = {"storage": "storage"} + def __init__(self, storage=None, **unknown_fields): - ''' + """ storage : typing.Sequence[~RemoveStorageInstance] - ''' + """ storage_ = [RemoveStorageInstance.from_json(o) for o in storage or []] # Validate arguments against known Juju API types. if storage_ is not None and not isinstance(storage_, (bytes, str, list)): - raise Exception("Expected storage_ to be a Sequence, received: {}".format(type(storage_))) + raise Exception( + "Expected storage_ to be a Sequence, received: {}".format( + type(storage_) + ) + ) self.storage = storage_ self.unknown_fields = unknown_fields - class RemoveStorageInstance(Type): - _toSchema = {'destroy_attachments': 'destroy-attachments', 'destroy_storage': 'destroy-storage', 'force': 'force', 'max_wait': 'max-wait', 'tag': 'tag'} - _toPy = {'destroy-attachments': 'destroy_attachments', 'destroy-storage': 'destroy_storage', 'force': 'force', 'max-wait': 'max_wait', 'tag': 'tag'} - def __init__(self, destroy_attachments=None, destroy_storage=None, force=None, max_wait=None, tag=None, **unknown_fields): - ''' + _toSchema = { + "destroy_attachments": "destroy-attachments", + "destroy_storage": "destroy-storage", + "force": "force", + "max_wait": "max-wait", + "tag": "tag", + } + _toPy = { + "destroy-attachments": "destroy_attachments", + "destroy-storage": "destroy_storage", + "force": "force", + "max-wait": "max_wait", + "tag": "tag", + } + + def __init__( + self, + destroy_attachments=None, + destroy_storage=None, + force=None, + max_wait=None, + tag=None, + **unknown_fields, + ): + """ destroy_attachments : bool destroy_storage : bool force : bool max_wait : int tag : str - ''' + """ destroy_attachments_ = destroy_attachments destroy_storage_ = destroy_storage force_ = force @@ -12689,20 +20291,36 @@ def __init__(self, destroy_attachments=None, destroy_storage=None, force=None, m tag_ = tag # Validate arguments against known Juju API types. - if destroy_attachments_ is not None and not isinstance(destroy_attachments_, bool): - raise Exception("Expected destroy_attachments_ to be a bool, received: {}".format(type(destroy_attachments_))) + if destroy_attachments_ is not None and not isinstance( + destroy_attachments_, bool + ): + raise Exception( + "Expected destroy_attachments_ to be a bool, received: {}".format( + type(destroy_attachments_) + ) + ) if destroy_storage_ is not None and not isinstance(destroy_storage_, bool): - raise Exception("Expected destroy_storage_ to be a bool, received: {}".format(type(destroy_storage_))) + raise Exception( + "Expected destroy_storage_ to be a bool, received: {}".format( + type(destroy_storage_) + ) + ) if force_ is not None and not isinstance(force_, bool): - raise Exception("Expected force_ to be a bool, received: {}".format(type(force_))) + raise Exception( + "Expected force_ to be a bool, received: {}".format(type(force_)) + ) if max_wait_ is not None and not isinstance(max_wait_, int): - raise Exception("Expected max_wait_ to be a int, received: {}".format(type(max_wait_))) + raise Exception( + "Expected max_wait_ to be a int, received: {}".format(type(max_wait_)) + ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception("Expected tag_ to be a str, received: {}".format(type(tag_))) + raise Exception( + "Expected tag_ to be a str, received: {}".format(type(tag_)) + ) self.destroy_attachments = destroy_attachments_ self.destroy_storage = destroy_storage_ @@ -12712,71 +20330,107 @@ def __init__(self, destroy_attachments=None, destroy_storage=None, force=None, m self.unknown_fields = unknown_fields - class RenameSpaceParams(Type): - _toSchema = {'from_space_tag': 'from-space-tag', 'to_space_tag': 'to-space-tag'} - _toPy = {'from-space-tag': 'from_space_tag', 'to-space-tag': 'to_space_tag'} + _toSchema = {"from_space_tag": "from-space-tag", "to_space_tag": "to-space-tag"} + _toPy = {"from-space-tag": "from_space_tag", "to-space-tag": "to_space_tag"} + def __init__(self, from_space_tag=None, to_space_tag=None, **unknown_fields): - ''' + """ from_space_tag : str to_space_tag : str - ''' + """ from_space_tag_ = from_space_tag to_space_tag_ = to_space_tag # Validate arguments against known Juju API types. - if from_space_tag_ is not None and not isinstance(from_space_tag_, (bytes, str)): - raise Exception("Expected from_space_tag_ to be a str, received: {}".format(type(from_space_tag_))) + if from_space_tag_ is not None and not isinstance( + from_space_tag_, (bytes, str) + ): + raise Exception( + "Expected from_space_tag_ to be a str, received: {}".format( + type(from_space_tag_) + ) + ) if to_space_tag_ is not None and not isinstance(to_space_tag_, (bytes, str)): - raise Exception("Expected to_space_tag_ to be a str, received: {}".format(type(to_space_tag_))) + raise Exception( + "Expected to_space_tag_ to be a str, received: {}".format( + type(to_space_tag_) + ) + ) self.from_space_tag = from_space_tag_ self.to_space_tag = to_space_tag_ self.unknown_fields = unknown_fields - class RenameSpacesParams(Type): - _toSchema = {'changes': 'changes'} - _toPy = {'changes': 'changes'} + _toSchema = {"changes": "changes"} + _toPy = {"changes": "changes"} + def __init__(self, changes=None, **unknown_fields): - ''' + """ changes : typing.Sequence[~RenameSpaceParams] - ''' + """ changes_ = [RenameSpaceParams.from_json(o) for o in changes or []] # Validate arguments against known Juju API types. if changes_ is not None and not isinstance(changes_, (bytes, str, list)): - raise Exception("Expected changes_ to be a Sequence, received: {}".format(type(changes_))) + raise Exception( + "Expected changes_ to be a Sequence, received: {}".format( + type(changes_) + ) + ) self.changes = changes_ self.unknown_fields = unknown_fields - class ResolveCharmWithChannel(Type): - _toSchema = {'charm_origin': 'charm-origin', 'reference': 'reference', 'switch_charm': 'switch-charm'} - _toPy = {'charm-origin': 'charm_origin', 'reference': 'reference', 'switch-charm': 'switch_charm'} - def __init__(self, charm_origin=None, reference=None, switch_charm=None, **unknown_fields): - ''' + _toSchema = { + "charm_origin": "charm-origin", + "reference": "reference", + "switch_charm": "switch-charm", + } + _toPy = { + "charm-origin": "charm_origin", + "reference": "reference", + "switch-charm": "switch_charm", + } + + def __init__( + self, charm_origin=None, reference=None, switch_charm=None, **unknown_fields + ): + """ charm_origin : CharmOrigin reference : str switch_charm : bool - ''' + """ charm_origin_ = CharmOrigin.from_json(charm_origin) if charm_origin else None reference_ = reference switch_charm_ = switch_charm # Validate arguments against known Juju API types. - if charm_origin_ is not None and not isinstance(charm_origin_, (dict, CharmOrigin)): - raise Exception("Expected charm_origin_ to be a CharmOrigin, received: {}".format(type(charm_origin_))) + if charm_origin_ is not None and not isinstance( + charm_origin_, (dict, CharmOrigin) + ): + raise Exception( + "Expected charm_origin_ to be a CharmOrigin, received: {}".format( + type(charm_origin_) + ) + ) if reference_ is not None and not isinstance(reference_, (bytes, str)): - raise Exception("Expected reference_ to be a str, received: {}".format(type(reference_))) + raise Exception( + "Expected reference_ to be a str, received: {}".format(type(reference_)) + ) if switch_charm_ is not None and not isinstance(switch_charm_, bool): - raise Exception("Expected switch_charm_ to be a bool, received: {}".format(type(switch_charm_))) + raise Exception( + "Expected switch_charm_ to be a bool, received: {}".format( + type(switch_charm_) + ) + ) self.charm_origin = charm_origin_ self.reference = reference_ @@ -12784,34 +20438,67 @@ def __init__(self, charm_origin=None, reference=None, switch_charm=None, **unkno self.unknown_fields = unknown_fields - class ResolveCharmWithChannelResult(Type): - _toSchema = {'charm_origin': 'charm-origin', 'error': 'error', 'supported_bases': 'supported-bases', 'url': 'url'} - _toPy = {'charm-origin': 'charm_origin', 'error': 'error', 'supported-bases': 'supported_bases', 'url': 'url'} - def __init__(self, charm_origin=None, error=None, supported_bases=None, url=None, **unknown_fields): - ''' + _toSchema = { + "charm_origin": "charm-origin", + "error": "error", + "supported_bases": "supported-bases", + "url": "url", + } + _toPy = { + "charm-origin": "charm_origin", + "error": "error", + "supported-bases": "supported_bases", + "url": "url", + } + + def __init__( + self, + charm_origin=None, + error=None, + supported_bases=None, + url=None, + **unknown_fields, + ): + """ charm_origin : CharmOrigin error : Error supported_bases : typing.Sequence[~Base] url : str - ''' + """ charm_origin_ = CharmOrigin.from_json(charm_origin) if charm_origin else None error_ = Error.from_json(error) if error else None supported_bases_ = [Base.from_json(o) for o in supported_bases or []] url_ = url # Validate arguments against known Juju API types. - if charm_origin_ is not None and not isinstance(charm_origin_, (dict, CharmOrigin)): - raise Exception("Expected charm_origin_ to be a CharmOrigin, received: {}".format(type(charm_origin_))) + if charm_origin_ is not None and not isinstance( + charm_origin_, (dict, CharmOrigin) + ): + raise Exception( + "Expected charm_origin_ to be a CharmOrigin, received: {}".format( + type(charm_origin_) + ) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) - - if supported_bases_ is not None and not isinstance(supported_bases_, (bytes, str, list)): - raise Exception("Expected supported_bases_ to be a Sequence, received: {}".format(type(supported_bases_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) + + if supported_bases_ is not None and not isinstance( + supported_bases_, (bytes, str, list) + ): + raise Exception( + "Expected supported_bases_ to be a Sequence, received: {}".format( + type(supported_bases_) + ) + ) if url_ is not None and not isinstance(url_, (bytes, str)): - raise Exception("Expected url_ to be a str, received: {}".format(type(url_))) + raise Exception( + "Expected url_ to be a str, received: {}".format(type(url_)) + ) self.charm_origin = charm_origin_ self.error = error_ @@ -12820,54 +20507,113 @@ def __init__(self, charm_origin=None, error=None, supported_bases=None, url=None self.unknown_fields = unknown_fields - class ResolveCharmWithChannelResults(Type): - _toSchema = {'results': 'Results'} - _toPy = {'Results': 'results'} + _toSchema = {"results": "Results"} + _toPy = {"Results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~ResolveCharmWithChannelResult] - ''' + """ results_ = [ResolveCharmWithChannelResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class ResolveCharmsWithChannel(Type): - _toSchema = {'macaroon': 'macaroon', 'resolve': 'resolve'} - _toPy = {'macaroon': 'macaroon', 'resolve': 'resolve'} + _toSchema = {"macaroon": "macaroon", "resolve": "resolve"} + _toPy = {"macaroon": "macaroon", "resolve": "resolve"} + def __init__(self, macaroon=None, resolve=None, **unknown_fields): - ''' + """ macaroon : Macaroon resolve : typing.Sequence[~ResolveCharmWithChannel] - ''' + """ macaroon_ = Macaroon.from_json(macaroon) if macaroon else None resolve_ = [ResolveCharmWithChannel.from_json(o) for o in resolve or []] # Validate arguments against known Juju API types. if macaroon_ is not None and not isinstance(macaroon_, (dict, Macaroon)): - raise Exception("Expected macaroon_ to be a Macaroon, received: {}".format(type(macaroon_))) + raise Exception( + "Expected macaroon_ to be a Macaroon, received: {}".format( + type(macaroon_) + ) + ) if resolve_ is not None and not isinstance(resolve_, (bytes, str, list)): - raise Exception("Expected resolve_ to be a Sequence, received: {}".format(type(resolve_))) + raise Exception( + "Expected resolve_ to be a Sequence, received: {}".format( + type(resolve_) + ) + ) self.macaroon = macaroon_ self.resolve = resolve_ self.unknown_fields = unknown_fields - class Resource(Type): - _toSchema = {'application': 'application', 'charmresource': 'CharmResource', 'description': 'description', 'fingerprint': 'fingerprint', 'id_': 'id', 'name': 'name', 'origin': 'origin', 'path': 'path', 'pending_id': 'pending-id', 'revision': 'revision', 'size': 'size', 'timestamp': 'timestamp', 'type_': 'type', 'username': 'username'} - _toPy = {'CharmResource': 'charmresource', 'application': 'application', 'description': 'description', 'fingerprint': 'fingerprint', 'id': 'id_', 'name': 'name', 'origin': 'origin', 'path': 'path', 'pending-id': 'pending_id', 'revision': 'revision', 'size': 'size', 'timestamp': 'timestamp', 'type': 'type_', 'username': 'username'} - def __init__(self, charmresource=None, application=None, description=None, fingerprint=None, id_=None, name=None, origin=None, path=None, pending_id=None, revision=None, size=None, timestamp=None, type_=None, username=None, **unknown_fields): - ''' + _toSchema = { + "application": "application", + "charmresource": "CharmResource", + "description": "description", + "fingerprint": "fingerprint", + "id_": "id", + "name": "name", + "origin": "origin", + "path": "path", + "pending_id": "pending-id", + "revision": "revision", + "size": "size", + "timestamp": "timestamp", + "type_": "type", + "username": "username", + } + _toPy = { + "CharmResource": "charmresource", + "application": "application", + "description": "description", + "fingerprint": "fingerprint", + "id": "id_", + "name": "name", + "origin": "origin", + "path": "path", + "pending-id": "pending_id", + "revision": "revision", + "size": "size", + "timestamp": "timestamp", + "type": "type_", + "username": "username", + } + + def __init__( + self, + charmresource=None, + application=None, + description=None, + fingerprint=None, + id_=None, + name=None, + origin=None, + path=None, + pending_id=None, + revision=None, + size=None, + timestamp=None, + type_=None, + username=None, + **unknown_fields, + ): + """ charmresource : CharmResource application : str description : str @@ -12882,8 +20628,10 @@ def __init__(self, charmresource=None, application=None, description=None, finge timestamp : str type_ : str username : str - ''' - charmresource_ = CharmResource.from_json(charmresource) if charmresource else None + """ + charmresource_ = ( + CharmResource.from_json(charmresource) if charmresource else None + ) application_ = application description_ = description fingerprint_ = fingerprint @@ -12899,47 +20647,89 @@ def __init__(self, charmresource=None, application=None, description=None, finge username_ = username # Validate arguments against known Juju API types. - if charmresource_ is not None and not isinstance(charmresource_, (dict, CharmResource)): - raise Exception("Expected charmresource_ to be a CharmResource, received: {}".format(type(charmresource_))) + if charmresource_ is not None and not isinstance( + charmresource_, (dict, CharmResource) + ): + raise Exception( + "Expected charmresource_ to be a CharmResource, received: {}".format( + type(charmresource_) + ) + ) if application_ is not None and not isinstance(application_, (bytes, str)): - raise Exception("Expected application_ to be a str, received: {}".format(type(application_))) + raise Exception( + "Expected application_ to be a str, received: {}".format( + type(application_) + ) + ) if description_ is not None and not isinstance(description_, (bytes, str)): - raise Exception("Expected description_ to be a str, received: {}".format(type(description_))) - - if fingerprint_ is not None and not isinstance(fingerprint_, (bytes, str, list)): - raise Exception("Expected fingerprint_ to be a Sequence, received: {}".format(type(fingerprint_))) + raise Exception( + "Expected description_ to be a str, received: {}".format( + type(description_) + ) + ) + + if fingerprint_ is not None and not isinstance( + fingerprint_, (bytes, str, list) + ): + raise Exception( + "Expected fingerprint_ to be a Sequence, received: {}".format( + type(fingerprint_) + ) + ) if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception("Expected id__ to be a str, received: {}".format(type(id__))) + raise Exception( + "Expected id__ to be a str, received: {}".format(type(id__)) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if origin_ is not None and not isinstance(origin_, (bytes, str)): - raise Exception("Expected origin_ to be a str, received: {}".format(type(origin_))) + raise Exception( + "Expected origin_ to be a str, received: {}".format(type(origin_)) + ) if path_ is not None and not isinstance(path_, (bytes, str)): - raise Exception("Expected path_ to be a str, received: {}".format(type(path_))) + raise Exception( + "Expected path_ to be a str, received: {}".format(type(path_)) + ) if pending_id_ is not None and not isinstance(pending_id_, (bytes, str)): - raise Exception("Expected pending_id_ to be a str, received: {}".format(type(pending_id_))) + raise Exception( + "Expected pending_id_ to be a str, received: {}".format( + type(pending_id_) + ) + ) if revision_ is not None and not isinstance(revision_, int): - raise Exception("Expected revision_ to be a int, received: {}".format(type(revision_))) + raise Exception( + "Expected revision_ to be a int, received: {}".format(type(revision_)) + ) if size_ is not None and not isinstance(size_, int): - raise Exception("Expected size_ to be a int, received: {}".format(type(size_))) + raise Exception( + "Expected size_ to be a int, received: {}".format(type(size_)) + ) if timestamp_ is not None and not isinstance(timestamp_, (bytes, str)): - raise Exception("Expected timestamp_ to be a str, received: {}".format(type(timestamp_))) + raise Exception( + "Expected timestamp_ to be a str, received: {}".format(type(timestamp_)) + ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception("Expected type__ to be a str, received: {}".format(type(type__))) + raise Exception( + "Expected type__ to be a str, received: {}".format(type(type__)) + ) if username_ is not None and not isinstance(username_, (bytes, str)): - raise Exception("Expected username_ to be a str, received: {}".format(type(username_))) + raise Exception( + "Expected username_ to be a str, received: {}".format(type(username_)) + ) self.charmresource = charmresource_ self.application = application_ @@ -12958,39 +20748,85 @@ def __init__(self, charmresource=None, application=None, description=None, finge self.unknown_fields = unknown_fields - class ResourcesResult(Type): - _toSchema = {'charm_store_resources': 'charm-store-resources', 'error': 'error', 'errorresult': 'ErrorResult', 'resources': 'resources', 'unit_resources': 'unit-resources'} - _toPy = {'ErrorResult': 'errorresult', 'charm-store-resources': 'charm_store_resources', 'error': 'error', 'resources': 'resources', 'unit-resources': 'unit_resources'} - def __init__(self, errorresult=None, charm_store_resources=None, error=None, resources=None, unit_resources=None, **unknown_fields): - ''' + _toSchema = { + "charm_store_resources": "charm-store-resources", + "error": "error", + "errorresult": "ErrorResult", + "resources": "resources", + "unit_resources": "unit-resources", + } + _toPy = { + "ErrorResult": "errorresult", + "charm-store-resources": "charm_store_resources", + "error": "error", + "resources": "resources", + "unit-resources": "unit_resources", + } + + def __init__( + self, + errorresult=None, + charm_store_resources=None, + error=None, + resources=None, + unit_resources=None, + **unknown_fields, + ): + """ errorresult : ErrorResult charm_store_resources : typing.Sequence[~CharmResource] error : Error resources : typing.Sequence[~Resource] unit_resources : typing.Sequence[~UnitResources] - ''' + """ errorresult_ = ErrorResult.from_json(errorresult) if errorresult else None - charm_store_resources_ = [CharmResource.from_json(o) for o in charm_store_resources or []] + charm_store_resources_ = [ + CharmResource.from_json(o) for o in charm_store_resources or [] + ] error_ = Error.from_json(error) if error else None resources_ = [Resource.from_json(o) for o in resources or []] unit_resources_ = [UnitResources.from_json(o) for o in unit_resources or []] # Validate arguments against known Juju API types. - if errorresult_ is not None and not isinstance(errorresult_, (dict, ErrorResult)): - raise Exception("Expected errorresult_ to be a ErrorResult, received: {}".format(type(errorresult_))) - - if charm_store_resources_ is not None and not isinstance(charm_store_resources_, (bytes, str, list)): - raise Exception("Expected charm_store_resources_ to be a Sequence, received: {}".format(type(charm_store_resources_))) + if errorresult_ is not None and not isinstance( + errorresult_, (dict, ErrorResult) + ): + raise Exception( + "Expected errorresult_ to be a ErrorResult, received: {}".format( + type(errorresult_) + ) + ) + + if charm_store_resources_ is not None and not isinstance( + charm_store_resources_, (bytes, str, list) + ): + raise Exception( + "Expected charm_store_resources_ to be a Sequence, received: {}".format( + type(charm_store_resources_) + ) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if resources_ is not None and not isinstance(resources_, (bytes, str, list)): - raise Exception("Expected resources_ to be a Sequence, received: {}".format(type(resources_))) - - if unit_resources_ is not None and not isinstance(unit_resources_, (bytes, str, list)): - raise Exception("Expected unit_resources_ to be a Sequence, received: {}".format(type(unit_resources_))) + raise Exception( + "Expected resources_ to be a Sequence, received: {}".format( + type(resources_) + ) + ) + + if unit_resources_ is not None and not isinstance( + unit_resources_, (bytes, str, list) + ): + raise Exception( + "Expected unit_resources_ to be a Sequence, received: {}".format( + type(unit_resources_) + ) + ) self.errorresult = errorresult_ self.charm_store_resources = charm_store_resources_ @@ -13000,96 +20836,145 @@ def __init__(self, errorresult=None, charm_store_resources=None, error=None, res self.unknown_fields = unknown_fields - class ResourcesResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~ResourcesResult] - ''' + """ results_ = [ResourcesResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class RetryProvisioningArgs(Type): - _toSchema = {'all_': 'all', 'machines': 'machines'} - _toPy = {'all': 'all_', 'machines': 'machines'} + _toSchema = {"all_": "all", "machines": "machines"} + _toPy = {"all": "all_", "machines": "machines"} + def __init__(self, all_=None, machines=None, **unknown_fields): - ''' + """ all_ : bool machines : typing.Sequence[str] - ''' + """ all__ = all_ machines_ = machines # Validate arguments against known Juju API types. if all__ is not None and not isinstance(all__, bool): - raise Exception("Expected all__ to be a bool, received: {}".format(type(all__))) + raise Exception( + "Expected all__ to be a bool, received: {}".format(type(all__)) + ) if machines_ is not None and not isinstance(machines_, (bytes, str, list)): - raise Exception("Expected machines_ to be a Sequence, received: {}".format(type(machines_))) + raise Exception( + "Expected machines_ to be a Sequence, received: {}".format( + type(machines_) + ) + ) self.all_ = all__ self.machines = machines_ self.unknown_fields = unknown_fields - class RevokeCredentialArg(Type): - _toSchema = {'force': 'force', 'tag': 'tag'} - _toPy = {'force': 'force', 'tag': 'tag'} + _toSchema = {"force": "force", "tag": "tag"} + _toPy = {"force": "force", "tag": "tag"} + def __init__(self, force=None, tag=None, **unknown_fields): - ''' + """ force : bool tag : str - ''' + """ force_ = force tag_ = tag # Validate arguments against known Juju API types. if force_ is not None and not isinstance(force_, bool): - raise Exception("Expected force_ to be a bool, received: {}".format(type(force_))) + raise Exception( + "Expected force_ to be a bool, received: {}".format(type(force_)) + ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception("Expected tag_ to be a str, received: {}".format(type(tag_))) + raise Exception( + "Expected tag_ to be a str, received: {}".format(type(tag_)) + ) self.force = force_ self.tag = tag_ self.unknown_fields = unknown_fields - class RevokeCredentialArgs(Type): - _toSchema = {'credentials': 'credentials'} - _toPy = {'credentials': 'credentials'} + _toSchema = {"credentials": "credentials"} + _toPy = {"credentials": "credentials"} + def __init__(self, credentials=None, **unknown_fields): - ''' + """ credentials : typing.Sequence[~RevokeCredentialArg] - ''' + """ credentials_ = [RevokeCredentialArg.from_json(o) for o in credentials or []] # Validate arguments against known Juju API types. - if credentials_ is not None and not isinstance(credentials_, (bytes, str, list)): - raise Exception("Expected credentials_ to be a Sequence, received: {}".format(type(credentials_))) + if credentials_ is not None and not isinstance( + credentials_, (bytes, str, list) + ): + raise Exception( + "Expected credentials_ to be a Sequence, received: {}".format( + type(credentials_) + ) + ) self.credentials = credentials_ self.unknown_fields = unknown_fields - class RunParams(Type): - _toSchema = {'applications': 'applications', 'commands': 'commands', 'execution_group': 'execution-group', 'machines': 'machines', 'parallel': 'parallel', 'timeout': 'timeout', 'units': 'units', 'workload_context': 'workload-context'} - _toPy = {'applications': 'applications', 'commands': 'commands', 'execution-group': 'execution_group', 'machines': 'machines', 'parallel': 'parallel', 'timeout': 'timeout', 'units': 'units', 'workload-context': 'workload_context'} - def __init__(self, applications=None, commands=None, execution_group=None, machines=None, parallel=None, timeout=None, units=None, workload_context=None, **unknown_fields): - ''' + _toSchema = { + "applications": "applications", + "commands": "commands", + "execution_group": "execution-group", + "machines": "machines", + "parallel": "parallel", + "timeout": "timeout", + "units": "units", + "workload_context": "workload-context", + } + _toPy = { + "applications": "applications", + "commands": "commands", + "execution-group": "execution_group", + "machines": "machines", + "parallel": "parallel", + "timeout": "timeout", + "units": "units", + "workload-context": "workload_context", + } + + def __init__( + self, + applications=None, + commands=None, + execution_group=None, + machines=None, + parallel=None, + timeout=None, + units=None, + workload_context=None, + **unknown_fields, + ): + """ applications : typing.Sequence[str] commands : str execution_group : str @@ -13098,7 +20983,7 @@ def __init__(self, applications=None, commands=None, execution_group=None, machi timeout : int units : typing.Sequence[str] workload_context : bool - ''' + """ applications_ = applications commands_ = commands execution_group_ = execution_group @@ -13109,29 +20994,57 @@ def __init__(self, applications=None, commands=None, execution_group=None, machi workload_context_ = workload_context # Validate arguments against known Juju API types. - if applications_ is not None and not isinstance(applications_, (bytes, str, list)): - raise Exception("Expected applications_ to be a Sequence, received: {}".format(type(applications_))) + if applications_ is not None and not isinstance( + applications_, (bytes, str, list) + ): + raise Exception( + "Expected applications_ to be a Sequence, received: {}".format( + type(applications_) + ) + ) if commands_ is not None and not isinstance(commands_, (bytes, str)): - raise Exception("Expected commands_ to be a str, received: {}".format(type(commands_))) - - if execution_group_ is not None and not isinstance(execution_group_, (bytes, str)): - raise Exception("Expected execution_group_ to be a str, received: {}".format(type(execution_group_))) + raise Exception( + "Expected commands_ to be a str, received: {}".format(type(commands_)) + ) + + if execution_group_ is not None and not isinstance( + execution_group_, (bytes, str) + ): + raise Exception( + "Expected execution_group_ to be a str, received: {}".format( + type(execution_group_) + ) + ) if machines_ is not None and not isinstance(machines_, (bytes, str, list)): - raise Exception("Expected machines_ to be a Sequence, received: {}".format(type(machines_))) + raise Exception( + "Expected machines_ to be a Sequence, received: {}".format( + type(machines_) + ) + ) if parallel_ is not None and not isinstance(parallel_, bool): - raise Exception("Expected parallel_ to be a bool, received: {}".format(type(parallel_))) + raise Exception( + "Expected parallel_ to be a bool, received: {}".format(type(parallel_)) + ) if timeout_ is not None and not isinstance(timeout_, int): - raise Exception("Expected timeout_ to be a int, received: {}".format(type(timeout_))) + raise Exception( + "Expected timeout_ to be a int, received: {}".format(type(timeout_)) + ) if units_ is not None and not isinstance(units_, (bytes, str, list)): - raise Exception("Expected units_ to be a Sequence, received: {}".format(type(units_))) + raise Exception( + "Expected units_ to be a Sequence, received: {}".format(type(units_)) + ) if workload_context_ is not None and not isinstance(workload_context_, bool): - raise Exception("Expected workload_context_ to be a bool, received: {}".format(type(workload_context_))) + raise Exception( + "Expected workload_context_ to be a bool, received: {}".format( + type(workload_context_) + ) + ) self.applications = applications_ self.commands = commands_ @@ -13144,196 +21057,263 @@ def __init__(self, applications=None, commands=None, execution_group=None, machi self.unknown_fields = unknown_fields - class SSHAddressResult(Type): - _toSchema = {'address': 'address', 'error': 'error'} - _toPy = {'address': 'address', 'error': 'error'} + _toSchema = {"address": "address", "error": "error"} + _toPy = {"address": "address", "error": "error"} + def __init__(self, address=None, error=None, **unknown_fields): - ''' + """ address : str error : Error - ''' + """ address_ = address error_ = Error.from_json(error) if error else None # Validate arguments against known Juju API types. if address_ is not None and not isinstance(address_, (bytes, str)): - raise Exception("Expected address_ to be a str, received: {}".format(type(address_))) + raise Exception( + "Expected address_ to be a str, received: {}".format(type(address_)) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) self.address = address_ self.error = error_ self.unknown_fields = unknown_fields - class SSHAddressResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~SSHAddressResult] - ''' + """ results_ = [SSHAddressResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class SSHAddressesResult(Type): - _toSchema = {'addresses': 'addresses', 'error': 'error'} - _toPy = {'addresses': 'addresses', 'error': 'error'} + _toSchema = {"addresses": "addresses", "error": "error"} + _toPy = {"addresses": "addresses", "error": "error"} + def __init__(self, addresses=None, error=None, **unknown_fields): - ''' + """ addresses : typing.Sequence[str] error : Error - ''' + """ addresses_ = addresses error_ = Error.from_json(error) if error else None # Validate arguments against known Juju API types. if addresses_ is not None and not isinstance(addresses_, (bytes, str, list)): - raise Exception("Expected addresses_ to be a Sequence, received: {}".format(type(addresses_))) + raise Exception( + "Expected addresses_ to be a Sequence, received: {}".format( + type(addresses_) + ) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) self.addresses = addresses_ self.error = error_ self.unknown_fields = unknown_fields - class SSHAddressesResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~SSHAddressesResult] - ''' + """ results_ = [SSHAddressesResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class SSHProxyResult(Type): - _toSchema = {'use_proxy': 'use-proxy'} - _toPy = {'use-proxy': 'use_proxy'} + _toSchema = {"use_proxy": "use-proxy"} + _toPy = {"use-proxy": "use_proxy"} + def __init__(self, use_proxy=None, **unknown_fields): - ''' + """ use_proxy : bool - ''' + """ use_proxy_ = use_proxy # Validate arguments against known Juju API types. if use_proxy_ is not None and not isinstance(use_proxy_, bool): - raise Exception("Expected use_proxy_ to be a bool, received: {}".format(type(use_proxy_))) + raise Exception( + "Expected use_proxy_ to be a bool, received: {}".format( + type(use_proxy_) + ) + ) self.use_proxy = use_proxy_ self.unknown_fields = unknown_fields - class SSHPublicKeysResult(Type): - _toSchema = {'error': 'error', 'public_keys': 'public-keys'} - _toPy = {'error': 'error', 'public-keys': 'public_keys'} + _toSchema = {"error": "error", "public_keys": "public-keys"} + _toPy = {"error": "error", "public-keys": "public_keys"} + def __init__(self, error=None, public_keys=None, **unknown_fields): - ''' + """ error : Error public_keys : typing.Sequence[str] - ''' + """ error_ = Error.from_json(error) if error else None public_keys_ = public_keys # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) - - if public_keys_ is not None and not isinstance(public_keys_, (bytes, str, list)): - raise Exception("Expected public_keys_ to be a Sequence, received: {}".format(type(public_keys_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) + + if public_keys_ is not None and not isinstance( + public_keys_, (bytes, str, list) + ): + raise Exception( + "Expected public_keys_ to be a Sequence, received: {}".format( + type(public_keys_) + ) + ) self.error = error_ self.public_keys = public_keys_ self.unknown_fields = unknown_fields - class SSHPublicKeysResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~SSHPublicKeysResult] - ''' + """ results_ = [SSHPublicKeysResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class ScaleApplicationInfo(Type): - _toSchema = {'num_units': 'num-units'} - _toPy = {'num-units': 'num_units'} + _toSchema = {"num_units": "num-units"} + _toPy = {"num-units": "num_units"} + def __init__(self, num_units=None, **unknown_fields): - ''' + """ num_units : int - ''' + """ num_units_ = num_units # Validate arguments against known Juju API types. if num_units_ is not None and not isinstance(num_units_, int): - raise Exception("Expected num_units_ to be a int, received: {}".format(type(num_units_))) + raise Exception( + "Expected num_units_ to be a int, received: {}".format(type(num_units_)) + ) self.num_units = num_units_ self.unknown_fields = unknown_fields - class ScaleApplicationParams(Type): - _toSchema = {'application_tag': 'application-tag', 'force': 'force', 'scale': 'scale', 'scale_change': 'scale-change'} - _toPy = {'application-tag': 'application_tag', 'force': 'force', 'scale': 'scale', 'scale-change': 'scale_change'} - def __init__(self, application_tag=None, force=None, scale=None, scale_change=None, **unknown_fields): - ''' + _toSchema = { + "application_tag": "application-tag", + "force": "force", + "scale": "scale", + "scale_change": "scale-change", + } + _toPy = { + "application-tag": "application_tag", + "force": "force", + "scale": "scale", + "scale-change": "scale_change", + } + + def __init__( + self, + application_tag=None, + force=None, + scale=None, + scale_change=None, + **unknown_fields, + ): + """ application_tag : str force : bool scale : int scale_change : int - ''' + """ application_tag_ = application_tag force_ = force scale_ = scale scale_change_ = scale_change # Validate arguments against known Juju API types. - if application_tag_ is not None and not isinstance(application_tag_, (bytes, str)): - raise Exception("Expected application_tag_ to be a str, received: {}".format(type(application_tag_))) + if application_tag_ is not None and not isinstance( + application_tag_, (bytes, str) + ): + raise Exception( + "Expected application_tag_ to be a str, received: {}".format( + type(application_tag_) + ) + ) if force_ is not None and not isinstance(force_, bool): - raise Exception("Expected force_ to be a bool, received: {}".format(type(force_))) + raise Exception( + "Expected force_ to be a bool, received: {}".format(type(force_)) + ) if scale_ is not None and not isinstance(scale_, int): - raise Exception("Expected scale_ to be a int, received: {}".format(type(scale_))) + raise Exception( + "Expected scale_ to be a int, received: {}".format(type(scale_)) + ) if scale_change_ is not None and not isinstance(scale_change_, int): - raise Exception("Expected scale_change_ to be a int, received: {}".format(type(scale_change_))) + raise Exception( + "Expected scale_change_ to be a int, received: {}".format( + type(scale_change_) + ) + ) self.application_tag = application_tag_ self.force = force_ @@ -13342,77 +21322,112 @@ def __init__(self, application_tag=None, force=None, scale=None, scale_change=No self.unknown_fields = unknown_fields - class ScaleApplicationResult(Type): - _toSchema = {'error': 'error', 'info': 'info'} - _toPy = {'error': 'error', 'info': 'info'} + _toSchema = {"error": "error", "info": "info"} + _toPy = {"error": "error", "info": "info"} + def __init__(self, error=None, info=None, **unknown_fields): - ''' + """ error : Error info : ScaleApplicationInfo - ''' + """ error_ = Error.from_json(error) if error else None info_ = ScaleApplicationInfo.from_json(info) if info else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if info_ is not None and not isinstance(info_, (dict, ScaleApplicationInfo)): - raise Exception("Expected info_ to be a ScaleApplicationInfo, received: {}".format(type(info_))) + raise Exception( + "Expected info_ to be a ScaleApplicationInfo, received: {}".format( + type(info_) + ) + ) self.error = error_ self.info = info_ self.unknown_fields = unknown_fields - class ScaleApplicationResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~ScaleApplicationResult] - ''' + """ results_ = [ScaleApplicationResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class ScaleApplicationsParams(Type): - _toSchema = {'applications': 'applications'} - _toPy = {'applications': 'applications'} + _toSchema = {"applications": "applications"} + _toPy = {"applications": "applications"} + def __init__(self, applications=None, **unknown_fields): - ''' + """ applications : typing.Sequence[~ScaleApplicationParams] - ''' - applications_ = [ScaleApplicationParams.from_json(o) for o in applications or []] + """ + applications_ = [ + ScaleApplicationParams.from_json(o) for o in applications or [] + ] # Validate arguments against known Juju API types. - if applications_ is not None and not isinstance(applications_, (bytes, str, list)): - raise Exception("Expected applications_ to be a Sequence, received: {}".format(type(applications_))) + if applications_ is not None and not isinstance( + applications_, (bytes, str, list) + ): + raise Exception( + "Expected applications_ to be a Sequence, received: {}".format( + type(applications_) + ) + ) self.applications = applications_ self.unknown_fields = unknown_fields - class SecretBackend(Type): - _toSchema = {'backend_type': 'backend-type', 'config': 'config', 'name': 'name', 'token_rotate_interval': 'token-rotate-interval'} - _toPy = {'backend-type': 'backend_type', 'config': 'config', 'name': 'name', 'token-rotate-interval': 'token_rotate_interval'} - def __init__(self, backend_type=None, config=None, name=None, token_rotate_interval=None, **unknown_fields): - ''' + _toSchema = { + "backend_type": "backend-type", + "config": "config", + "name": "name", + "token_rotate_interval": "token-rotate-interval", + } + _toPy = { + "backend-type": "backend_type", + "config": "config", + "name": "name", + "token-rotate-interval": "token_rotate_interval", + } + + def __init__( + self, + backend_type=None, + config=None, + name=None, + token_rotate_interval=None, + **unknown_fields, + ): + """ backend_type : str config : typing.Mapping[str, typing.Any] name : str token_rotate_interval : int - ''' + """ backend_type_ = backend_type config_ = config name_ = name @@ -13420,16 +21435,30 @@ def __init__(self, backend_type=None, config=None, name=None, token_rotate_inter # Validate arguments against known Juju API types. if backend_type_ is not None and not isinstance(backend_type_, (bytes, str)): - raise Exception("Expected backend_type_ to be a str, received: {}".format(type(backend_type_))) + raise Exception( + "Expected backend_type_ to be a str, received: {}".format( + type(backend_type_) + ) + ) if config_ is not None and not isinstance(config_, dict): - raise Exception("Expected config_ to be a Mapping, received: {}".format(type(config_))) + raise Exception( + "Expected config_ to be a Mapping, received: {}".format(type(config_)) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) - - if token_rotate_interval_ is not None and not isinstance(token_rotate_interval_, int): - raise Exception("Expected token_rotate_interval_ to be a int, received: {}".format(type(token_rotate_interval_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) + + if token_rotate_interval_ is not None and not isinstance( + token_rotate_interval_, int + ): + raise Exception( + "Expected token_rotate_interval_ to be a int, received: {}".format( + type(token_rotate_interval_) + ) + ) self.backend_type = backend_type_ self.config = config_ @@ -13438,19 +21467,42 @@ def __init__(self, backend_type=None, config=None, name=None, token_rotate_inter self.unknown_fields = unknown_fields - class SecretBackendResult(Type): - _toSchema = {'error': 'error', 'id_': 'id', 'message': 'message', 'num_secrets': 'num-secrets', 'result': 'result', 'status': 'status'} - _toPy = {'error': 'error', 'id': 'id_', 'message': 'message', 'num-secrets': 'num_secrets', 'result': 'result', 'status': 'status'} - def __init__(self, error=None, id_=None, message=None, num_secrets=None, result=None, status=None, **unknown_fields): - ''' + _toSchema = { + "error": "error", + "id_": "id", + "message": "message", + "num_secrets": "num-secrets", + "result": "result", + "status": "status", + } + _toPy = { + "error": "error", + "id": "id_", + "message": "message", + "num-secrets": "num_secrets", + "result": "result", + "status": "status", + } + + def __init__( + self, + error=None, + id_=None, + message=None, + num_secrets=None, + result=None, + status=None, + **unknown_fields, + ): + """ error : Error id_ : str message : str num_secrets : int result : SecretBackend status : str - ''' + """ error_ = Error.from_json(error) if error else None id__ = id_ message_ = message @@ -13460,22 +21512,38 @@ def __init__(self, error=None, id_=None, message=None, num_secrets=None, result= # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception("Expected id__ to be a str, received: {}".format(type(id__))) + raise Exception( + "Expected id__ to be a str, received: {}".format(type(id__)) + ) if message_ is not None and not isinstance(message_, (bytes, str)): - raise Exception("Expected message_ to be a str, received: {}".format(type(message_))) + raise Exception( + "Expected message_ to be a str, received: {}".format(type(message_)) + ) if num_secrets_ is not None and not isinstance(num_secrets_, int): - raise Exception("Expected num_secrets_ to be a int, received: {}".format(type(num_secrets_))) + raise Exception( + "Expected num_secrets_ to be a int, received: {}".format( + type(num_secrets_) + ) + ) if result_ is not None and not isinstance(result_, (dict, SecretBackend)): - raise Exception("Expected result_ to be a SecretBackend, received: {}".format(type(result_))) + raise Exception( + "Expected result_ to be a SecretBackend, received: {}".format( + type(result_) + ) + ) if status_ is not None and not isinstance(status_, (bytes, str)): - raise Exception("Expected status_ to be a str, received: {}".format(type(status_))) + raise Exception( + "Expected status_ to be a str, received: {}".format(type(status_)) + ) self.error = error_ self.id_ = id__ @@ -13486,29 +21554,39 @@ def __init__(self, error=None, id_=None, message=None, num_secrets=None, result= self.unknown_fields = unknown_fields - class SecretContentParams(Type): - _toSchema = {'checksum': 'checksum', 'data': 'data', 'value_ref': 'value-ref'} - _toPy = {'checksum': 'checksum', 'data': 'data', 'value-ref': 'value_ref'} + _toSchema = {"checksum": "checksum", "data": "data", "value_ref": "value-ref"} + _toPy = {"checksum": "checksum", "data": "data", "value-ref": "value_ref"} + def __init__(self, checksum=None, data=None, value_ref=None, **unknown_fields): - ''' + """ checksum : str data : typing.Mapping[str, str] value_ref : SecretValueRef - ''' + """ checksum_ = checksum data_ = data value_ref_ = SecretValueRef.from_json(value_ref) if value_ref else None # Validate arguments against known Juju API types. if checksum_ is not None and not isinstance(checksum_, (bytes, str)): - raise Exception("Expected checksum_ to be a str, received: {}".format(type(checksum_))) + raise Exception( + "Expected checksum_ to be a str, received: {}".format(type(checksum_)) + ) if data_ is not None and not isinstance(data_, dict): - raise Exception("Expected data_ to be a Mapping, received: {}".format(type(data_))) - - if value_ref_ is not None and not isinstance(value_ref_, (dict, SecretValueRef)): - raise Exception("Expected value_ref_ to be a SecretValueRef, received: {}".format(type(value_ref_))) + raise Exception( + "Expected data_ to be a Mapping, received: {}".format(type(data_)) + ) + + if value_ref_ is not None and not isinstance( + value_ref_, (dict, SecretValueRef) + ): + raise Exception( + "Expected value_ref_ to be a SecretValueRef, received: {}".format( + type(value_ref_) + ) + ) self.checksum = checksum_ self.data = data_ @@ -13516,19 +21594,42 @@ def __init__(self, checksum=None, data=None, value_ref=None, **unknown_fields): self.unknown_fields = unknown_fields - class SecretRevision(Type): - _toSchema = {'backend_name': 'backend-name', 'create_time': 'create-time', 'expire_time': 'expire-time', 'revision': 'revision', 'update_time': 'update-time', 'value_ref': 'value-ref'} - _toPy = {'backend-name': 'backend_name', 'create-time': 'create_time', 'expire-time': 'expire_time', 'revision': 'revision', 'update-time': 'update_time', 'value-ref': 'value_ref'} - def __init__(self, backend_name=None, create_time=None, expire_time=None, revision=None, update_time=None, value_ref=None, **unknown_fields): - ''' + _toSchema = { + "backend_name": "backend-name", + "create_time": "create-time", + "expire_time": "expire-time", + "revision": "revision", + "update_time": "update-time", + "value_ref": "value-ref", + } + _toPy = { + "backend-name": "backend_name", + "create-time": "create_time", + "expire-time": "expire_time", + "revision": "revision", + "update-time": "update_time", + "value-ref": "value_ref", + } + + def __init__( + self, + backend_name=None, + create_time=None, + expire_time=None, + revision=None, + update_time=None, + value_ref=None, + **unknown_fields, + ): + """ backend_name : str create_time : str expire_time : str revision : int update_time : str value_ref : SecretValueRef - ''' + """ backend_name_ = backend_name create_time_ = create_time expire_time_ = expire_time @@ -13538,22 +21639,46 @@ def __init__(self, backend_name=None, create_time=None, expire_time=None, revisi # Validate arguments against known Juju API types. if backend_name_ is not None and not isinstance(backend_name_, (bytes, str)): - raise Exception("Expected backend_name_ to be a str, received: {}".format(type(backend_name_))) + raise Exception( + "Expected backend_name_ to be a str, received: {}".format( + type(backend_name_) + ) + ) if create_time_ is not None and not isinstance(create_time_, (bytes, str)): - raise Exception("Expected create_time_ to be a str, received: {}".format(type(create_time_))) + raise Exception( + "Expected create_time_ to be a str, received: {}".format( + type(create_time_) + ) + ) if expire_time_ is not None and not isinstance(expire_time_, (bytes, str)): - raise Exception("Expected expire_time_ to be a str, received: {}".format(type(expire_time_))) + raise Exception( + "Expected expire_time_ to be a str, received: {}".format( + type(expire_time_) + ) + ) if revision_ is not None and not isinstance(revision_, int): - raise Exception("Expected revision_ to be a int, received: {}".format(type(revision_))) + raise Exception( + "Expected revision_ to be a int, received: {}".format(type(revision_)) + ) if update_time_ is not None and not isinstance(update_time_, (bytes, str)): - raise Exception("Expected update_time_ to be a str, received: {}".format(type(update_time_))) - - if value_ref_ is not None and not isinstance(value_ref_, (dict, SecretValueRef)): - raise Exception("Expected value_ref_ to be a SecretValueRef, received: {}".format(type(value_ref_))) + raise Exception( + "Expected update_time_ to be a str, received: {}".format( + type(update_time_) + ) + ) + + if value_ref_ is not None and not isinstance( + value_ref_, (dict, SecretValueRef) + ): + raise Exception( + "Expected value_ref_ to be a SecretValueRef, received: {}".format( + type(value_ref_) + ) + ) self.backend_name = backend_name_ self.create_time = create_time_ @@ -13564,65 +21689,89 @@ def __init__(self, backend_name=None, create_time=None, expire_time=None, revisi self.unknown_fields = unknown_fields - class SecretValueRef(Type): - _toSchema = {'backend_id': 'backend-id', 'revision_id': 'revision-id'} - _toPy = {'backend-id': 'backend_id', 'revision-id': 'revision_id'} + _toSchema = {"backend_id": "backend-id", "revision_id": "revision-id"} + _toPy = {"backend-id": "backend_id", "revision-id": "revision_id"} + def __init__(self, backend_id=None, revision_id=None, **unknown_fields): - ''' + """ backend_id : str revision_id : str - ''' + """ backend_id_ = backend_id revision_id_ = revision_id # Validate arguments against known Juju API types. if backend_id_ is not None and not isinstance(backend_id_, (bytes, str)): - raise Exception("Expected backend_id_ to be a str, received: {}".format(type(backend_id_))) + raise Exception( + "Expected backend_id_ to be a str, received: {}".format( + type(backend_id_) + ) + ) if revision_id_ is not None and not isinstance(revision_id_, (bytes, str)): - raise Exception("Expected revision_id_ to be a str, received: {}".format(type(revision_id_))) + raise Exception( + "Expected revision_id_ to be a str, received: {}".format( + type(revision_id_) + ) + ) self.backend_id = backend_id_ self.revision_id = revision_id_ self.unknown_fields = unknown_fields - class SecretValueResult(Type): - _toSchema = {'data': 'data', 'error': 'error'} - _toPy = {'data': 'data', 'error': 'error'} + _toSchema = {"data": "data", "error": "error"} + _toPy = {"data": "data", "error": "error"} + def __init__(self, data=None, error=None, **unknown_fields): - ''' + """ data : typing.Mapping[str, str] error : Error - ''' + """ data_ = data error_ = Error.from_json(error) if error else None # Validate arguments against known Juju API types. if data_ is not None and not isinstance(data_, dict): - raise Exception("Expected data_ to be a Mapping, received: {}".format(type(data_))) + raise Exception( + "Expected data_ to be a Mapping, received: {}".format(type(data_)) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) self.data = data_ self.error = error_ self.unknown_fields = unknown_fields - class SecretsFilter(Type): - _toSchema = {'label': 'label', 'owner_tag': 'owner-tag', 'revision': 'revision', 'uri': 'uri'} - _toPy = {'label': 'label', 'owner-tag': 'owner_tag', 'revision': 'revision', 'uri': 'uri'} - def __init__(self, label=None, owner_tag=None, revision=None, uri=None, **unknown_fields): - ''' + _toSchema = { + "label": "label", + "owner_tag": "owner-tag", + "revision": "revision", + "uri": "uri", + } + _toPy = { + "label": "label", + "owner-tag": "owner_tag", + "revision": "revision", + "uri": "uri", + } + + def __init__( + self, label=None, owner_tag=None, revision=None, uri=None, **unknown_fields + ): + """ label : str owner_tag : str revision : int uri : str - ''' + """ label_ = label owner_tag_ = owner_tag revision_ = revision @@ -13630,16 +21779,24 @@ def __init__(self, label=None, owner_tag=None, revision=None, uri=None, **unknow # Validate arguments against known Juju API types. if label_ is not None and not isinstance(label_, (bytes, str)): - raise Exception("Expected label_ to be a str, received: {}".format(type(label_))) + raise Exception( + "Expected label_ to be a str, received: {}".format(type(label_)) + ) if owner_tag_ is not None and not isinstance(owner_tag_, (bytes, str)): - raise Exception("Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_))) + raise Exception( + "Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_)) + ) if revision_ is not None and not isinstance(revision_, int): - raise Exception("Expected revision_ to be a int, received: {}".format(type(revision_))) + raise Exception( + "Expected revision_ to be a int, received: {}".format(type(revision_)) + ) if uri_ is not None and not isinstance(uri_, (bytes, str)): - raise Exception("Expected uri_ to be a str, received: {}".format(type(uri_))) + raise Exception( + "Expected uri_ to be a str, received: {}".format(type(uri_)) + ) self.label = label_ self.owner_tag = owner_tag_ @@ -13648,76 +21805,117 @@ def __init__(self, label=None, owner_tag=None, revision=None, uri=None, **unknow self.unknown_fields = unknown_fields - class SetConstraints(Type): - _toSchema = {'application': 'application', 'constraints': 'constraints'} - _toPy = {'application': 'application', 'constraints': 'constraints'} + _toSchema = {"application": "application", "constraints": "constraints"} + _toPy = {"application": "application", "constraints": "constraints"} + def __init__(self, application=None, constraints=None, **unknown_fields): - ''' + """ application : str constraints : Value - ''' + """ application_ = application constraints_ = Value.from_json(constraints) if constraints else None # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): - raise Exception("Expected application_ to be a str, received: {}".format(type(application_))) + raise Exception( + "Expected application_ to be a str, received: {}".format( + type(application_) + ) + ) if constraints_ is not None and not isinstance(constraints_, (dict, Value)): - raise Exception("Expected constraints_ to be a Value, received: {}".format(type(constraints_))) + raise Exception( + "Expected constraints_ to be a Value, received: {}".format( + type(constraints_) + ) + ) self.application = application_ self.constraints = constraints_ self.unknown_fields = unknown_fields - class SetModelDefaults(Type): - _toSchema = {'config': 'config'} - _toPy = {'config': 'config'} + _toSchema = {"config": "config"} + _toPy = {"config": "config"} + def __init__(self, config=None, **unknown_fields): - ''' + """ config : typing.Sequence[~ModelDefaultValues] - ''' + """ config_ = [ModelDefaultValues.from_json(o) for o in config or []] # Validate arguments against known Juju API types. if config_ is not None and not isinstance(config_, (bytes, str, list)): - raise Exception("Expected config_ to be a Sequence, received: {}".format(type(config_))) + raise Exception( + "Expected config_ to be a Sequence, received: {}".format(type(config_)) + ) self.config = config_ self.unknown_fields = unknown_fields - class ShowSpaceResult(Type): - _toSchema = {'applications': 'applications', 'error': 'error', 'machine_count': 'machine-count', 'space': 'space'} - _toPy = {'applications': 'applications', 'error': 'error', 'machine-count': 'machine_count', 'space': 'space'} - def __init__(self, applications=None, error=None, machine_count=None, space=None, **unknown_fields): - ''' + _toSchema = { + "applications": "applications", + "error": "error", + "machine_count": "machine-count", + "space": "space", + } + _toPy = { + "applications": "applications", + "error": "error", + "machine-count": "machine_count", + "space": "space", + } + + def __init__( + self, + applications=None, + error=None, + machine_count=None, + space=None, + **unknown_fields, + ): + """ applications : typing.Sequence[str] error : Error machine_count : int space : Space - ''' + """ applications_ = applications error_ = Error.from_json(error) if error else None machine_count_ = machine_count space_ = Space.from_json(space) if space else None # Validate arguments against known Juju API types. - if applications_ is not None and not isinstance(applications_, (bytes, str, list)): - raise Exception("Expected applications_ to be a Sequence, received: {}".format(type(applications_))) + if applications_ is not None and not isinstance( + applications_, (bytes, str, list) + ): + raise Exception( + "Expected applications_ to be a Sequence, received: {}".format( + type(applications_) + ) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if machine_count_ is not None and not isinstance(machine_count_, int): - raise Exception("Expected machine_count_ to be a int, received: {}".format(type(machine_count_))) + raise Exception( + "Expected machine_count_ to be a int, received: {}".format( + type(machine_count_) + ) + ) if space_ is not None and not isinstance(space_, (dict, Space)): - raise Exception("Expected space_ to be a Space, received: {}".format(type(space_))) + raise Exception( + "Expected space_ to be a Space, received: {}".format(type(space_)) + ) self.applications = applications_ self.error = error_ @@ -13726,35 +21924,39 @@ def __init__(self, applications=None, error=None, machine_count=None, space=None self.unknown_fields = unknown_fields - class ShowSpaceResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~ShowSpaceResult] - ''' + """ results_ = [ShowSpaceResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class Space(Type): - _toSchema = {'error': 'error', 'id_': 'id', 'name': 'name', 'subnets': 'subnets'} - _toPy = {'error': 'error', 'id': 'id_', 'name': 'name', 'subnets': 'subnets'} + _toSchema = {"error": "error", "id_": "id", "name": "name", "subnets": "subnets"} + _toPy = {"error": "error", "id": "id_", "name": "name", "subnets": "subnets"} + def __init__(self, error=None, id_=None, name=None, subnets=None, **unknown_fields): - ''' + """ error : Error id_ : str name : str subnets : typing.Sequence[~Subnet] - ''' + """ error_ = Error.from_json(error) if error else None id__ = id_ name_ = name @@ -13762,16 +21964,26 @@ def __init__(self, error=None, id_=None, name=None, subnets=None, **unknown_fiel # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception("Expected id__ to be a str, received: {}".format(type(id__))) + raise Exception( + "Expected id__ to be a str, received: {}".format(type(id__)) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if subnets_ is not None and not isinstance(subnets_, (bytes, str, list)): - raise Exception("Expected subnets_ to be a Sequence, received: {}".format(type(subnets_))) + raise Exception( + "Expected subnets_ to be a Sequence, received: {}".format( + type(subnets_) + ) + ) self.error = error_ self.id_ = id__ @@ -13780,17 +21992,19 @@ def __init__(self, error=None, id_=None, name=None, subnets=None, **unknown_fiel self.unknown_fields = unknown_fields - class StatusHistoryFilter(Type): - _toSchema = {'date': 'date', 'delta': 'delta', 'exclude': 'exclude', 'size': 'size'} - _toPy = {'date': 'date', 'delta': 'delta', 'exclude': 'exclude', 'size': 'size'} - def __init__(self, date=None, delta=None, exclude=None, size=None, **unknown_fields): - ''' + _toSchema = {"date": "date", "delta": "delta", "exclude": "exclude", "size": "size"} + _toPy = {"date": "date", "delta": "delta", "exclude": "exclude", "size": "size"} + + def __init__( + self, date=None, delta=None, exclude=None, size=None, **unknown_fields + ): + """ date : str delta : int exclude : typing.Sequence[str] size : int - ''' + """ date_ = date delta_ = delta exclude_ = exclude @@ -13798,16 +22012,26 @@ def __init__(self, date=None, delta=None, exclude=None, size=None, **unknown_fie # Validate arguments against known Juju API types. if date_ is not None and not isinstance(date_, (bytes, str)): - raise Exception("Expected date_ to be a str, received: {}".format(type(date_))) + raise Exception( + "Expected date_ to be a str, received: {}".format(type(date_)) + ) if delta_ is not None and not isinstance(delta_, int): - raise Exception("Expected delta_ to be a int, received: {}".format(type(delta_))) + raise Exception( + "Expected delta_ to be a int, received: {}".format(type(delta_)) + ) if exclude_ is not None and not isinstance(exclude_, (bytes, str, list)): - raise Exception("Expected exclude_ to be a Sequence, received: {}".format(type(exclude_))) + raise Exception( + "Expected exclude_ to be a Sequence, received: {}".format( + type(exclude_) + ) + ) if size_ is not None and not isinstance(size_, int): - raise Exception("Expected size_ to be a int, received: {}".format(type(size_))) + raise Exception( + "Expected size_ to be a int, received: {}".format(type(size_)) + ) self.date = date_ self.delta = delta_ @@ -13816,34 +22040,60 @@ def __init__(self, date=None, delta=None, exclude=None, size=None, **unknown_fie self.unknown_fields = unknown_fields - class StatusHistoryRequest(Type): - _toSchema = {'filter_': 'filter', 'historykind': 'historyKind', 'size': 'size', 'tag': 'tag'} - _toPy = {'filter': 'filter_', 'historyKind': 'historykind', 'size': 'size', 'tag': 'tag'} - def __init__(self, filter_=None, historykind=None, size=None, tag=None, **unknown_fields): - ''' + _toSchema = { + "filter_": "filter", + "historykind": "historyKind", + "size": "size", + "tag": "tag", + } + _toPy = { + "filter": "filter_", + "historyKind": "historykind", + "size": "size", + "tag": "tag", + } + + def __init__( + self, filter_=None, historykind=None, size=None, tag=None, **unknown_fields + ): + """ filter_ : StatusHistoryFilter historykind : str size : int tag : str - ''' + """ filter__ = StatusHistoryFilter.from_json(filter_) if filter_ else None historykind_ = historykind size_ = size tag_ = tag # Validate arguments against known Juju API types. - if filter__ is not None and not isinstance(filter__, (dict, StatusHistoryFilter)): - raise Exception("Expected filter__ to be a StatusHistoryFilter, received: {}".format(type(filter__))) + if filter__ is not None and not isinstance( + filter__, (dict, StatusHistoryFilter) + ): + raise Exception( + "Expected filter__ to be a StatusHistoryFilter, received: {}".format( + type(filter__) + ) + ) if historykind_ is not None and not isinstance(historykind_, (bytes, str)): - raise Exception("Expected historykind_ to be a str, received: {}".format(type(historykind_))) + raise Exception( + "Expected historykind_ to be a str, received: {}".format( + type(historykind_) + ) + ) if size_ is not None and not isinstance(size_, int): - raise Exception("Expected size_ to be a int, received: {}".format(type(size_))) + raise Exception( + "Expected size_ to be a int, received: {}".format(type(size_)) + ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception("Expected tag_ to be a str, received: {}".format(type(tag_))) + raise Exception( + "Expected tag_ to be a str, received: {}".format(type(tag_)) + ) self.filter_ = filter__ self.historykind = historykind_ @@ -13852,113 +22102,143 @@ def __init__(self, filter_=None, historykind=None, size=None, tag=None, **unknow self.unknown_fields = unknown_fields - class StatusHistoryRequests(Type): - _toSchema = {'requests': 'requests'} - _toPy = {'requests': 'requests'} + _toSchema = {"requests": "requests"} + _toPy = {"requests": "requests"} + def __init__(self, requests=None, **unknown_fields): - ''' + """ requests : typing.Sequence[~StatusHistoryRequest] - ''' + """ requests_ = [StatusHistoryRequest.from_json(o) for o in requests or []] # Validate arguments against known Juju API types. if requests_ is not None and not isinstance(requests_, (bytes, str, list)): - raise Exception("Expected requests_ to be a Sequence, received: {}".format(type(requests_))) + raise Exception( + "Expected requests_ to be a Sequence, received: {}".format( + type(requests_) + ) + ) self.requests = requests_ self.unknown_fields = unknown_fields - class StatusHistoryResult(Type): - _toSchema = {'error': 'error', 'history': 'history'} - _toPy = {'error': 'error', 'history': 'history'} + _toSchema = {"error": "error", "history": "history"} + _toPy = {"error": "error", "history": "history"} + def __init__(self, error=None, history=None, **unknown_fields): - ''' + """ error : Error history : History - ''' + """ error_ = Error.from_json(error) if error else None history_ = History.from_json(history) if history else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if history_ is not None and not isinstance(history_, (dict, History)): - raise Exception("Expected history_ to be a History, received: {}".format(type(history_))) + raise Exception( + "Expected history_ to be a History, received: {}".format(type(history_)) + ) self.error = error_ self.history = history_ self.unknown_fields = unknown_fields - class StatusHistoryResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~StatusHistoryResult] - ''' + """ results_ = [StatusHistoryResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class StatusParams(Type): - _toSchema = {'include_storage': 'include-storage', 'patterns': 'patterns'} - _toPy = {'include-storage': 'include_storage', 'patterns': 'patterns'} + _toSchema = {"include_storage": "include-storage", "patterns": "patterns"} + _toPy = {"include-storage": "include_storage", "patterns": "patterns"} + def __init__(self, include_storage=None, patterns=None, **unknown_fields): - ''' + """ include_storage : bool patterns : typing.Sequence[str] - ''' + """ include_storage_ = include_storage patterns_ = patterns # Validate arguments against known Juju API types. if include_storage_ is not None and not isinstance(include_storage_, bool): - raise Exception("Expected include_storage_ to be a bool, received: {}".format(type(include_storage_))) + raise Exception( + "Expected include_storage_ to be a bool, received: {}".format( + type(include_storage_) + ) + ) if patterns_ is not None and not isinstance(patterns_, (bytes, str, list)): - raise Exception("Expected patterns_ to be a Sequence, received: {}".format(type(patterns_))) + raise Exception( + "Expected patterns_ to be a Sequence, received: {}".format( + type(patterns_) + ) + ) self.include_storage = include_storage_ self.patterns = patterns_ self.unknown_fields = unknown_fields - class StorageAddParams(Type): - _toSchema = {'name': 'name', 'storage': 'storage', 'unit': 'unit'} - _toPy = {'name': 'name', 'storage': 'storage', 'unit': 'unit'} + _toSchema = {"name": "name", "storage": "storage", "unit": "unit"} + _toPy = {"name": "name", "storage": "storage", "unit": "unit"} + def __init__(self, name=None, storage=None, unit=None, **unknown_fields): - ''' + """ name : str storage : StorageConstraints unit : str - ''' + """ name_ = name storage_ = StorageConstraints.from_json(storage) if storage else None unit_ = unit # Validate arguments against known Juju API types. if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) - - if storage_ is not None and not isinstance(storage_, (dict, StorageConstraints)): - raise Exception("Expected storage_ to be a StorageConstraints, received: {}".format(type(storage_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) + + if storage_ is not None and not isinstance( + storage_, (dict, StorageConstraints) + ): + raise Exception( + "Expected storage_ to be a StorageConstraints, received: {}".format( + type(storage_) + ) + ) if unit_ is not None and not isinstance(unit_, (bytes, str)): - raise Exception("Expected unit_ to be a str, received: {}".format(type(unit_))) + raise Exception( + "Expected unit_ to be a str, received: {}".format(type(unit_)) + ) self.name = name_ self.storage = storage_ @@ -13966,18 +22246,38 @@ def __init__(self, name=None, storage=None, unit=None, **unknown_fields): self.unknown_fields = unknown_fields - class StorageAttachmentDetails(Type): - _toSchema = {'life': 'life', 'location': 'location', 'machine_tag': 'machine-tag', 'storage_tag': 'storage-tag', 'unit_tag': 'unit-tag'} - _toPy = {'life': 'life', 'location': 'location', 'machine-tag': 'machine_tag', 'storage-tag': 'storage_tag', 'unit-tag': 'unit_tag'} - def __init__(self, life=None, location=None, machine_tag=None, storage_tag=None, unit_tag=None, **unknown_fields): - ''' + _toSchema = { + "life": "life", + "location": "location", + "machine_tag": "machine-tag", + "storage_tag": "storage-tag", + "unit_tag": "unit-tag", + } + _toPy = { + "life": "life", + "location": "location", + "machine-tag": "machine_tag", + "storage-tag": "storage_tag", + "unit-tag": "unit_tag", + } + + def __init__( + self, + life=None, + location=None, + machine_tag=None, + storage_tag=None, + unit_tag=None, + **unknown_fields, + ): + """ life : str location : str machine_tag : str storage_tag : str unit_tag : str - ''' + """ life_ = life location_ = location machine_tag_ = machine_tag @@ -13986,19 +22286,33 @@ def __init__(self, life=None, location=None, machine_tag=None, storage_tag=None, # Validate arguments against known Juju API types. if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception("Expected life_ to be a str, received: {}".format(type(life_))) + raise Exception( + "Expected life_ to be a str, received: {}".format(type(life_)) + ) if location_ is not None and not isinstance(location_, (bytes, str)): - raise Exception("Expected location_ to be a str, received: {}".format(type(location_))) + raise Exception( + "Expected location_ to be a str, received: {}".format(type(location_)) + ) if machine_tag_ is not None and not isinstance(machine_tag_, (bytes, str)): - raise Exception("Expected machine_tag_ to be a str, received: {}".format(type(machine_tag_))) + raise Exception( + "Expected machine_tag_ to be a str, received: {}".format( + type(machine_tag_) + ) + ) if storage_tag_ is not None and not isinstance(storage_tag_, (bytes, str)): - raise Exception("Expected storage_tag_ to be a str, received: {}".format(type(storage_tag_))) + raise Exception( + "Expected storage_tag_ to be a str, received: {}".format( + type(storage_tag_) + ) + ) if unit_tag_ is not None and not isinstance(unit_tag_, (bytes, str)): - raise Exception("Expected unit_tag_ to be a str, received: {}".format(type(unit_tag_))) + raise Exception( + "Expected unit_tag_ to be a str, received: {}".format(type(unit_tag_)) + ) self.life = life_ self.location = location_ @@ -14008,71 +22322,85 @@ def __init__(self, life=None, location=None, machine_tag=None, storage_tag=None, self.unknown_fields = unknown_fields - class StorageAttachmentId(Type): - _toSchema = {'storage_tag': 'storage-tag', 'unit_tag': 'unit-tag'} - _toPy = {'storage-tag': 'storage_tag', 'unit-tag': 'unit_tag'} + _toSchema = {"storage_tag": "storage-tag", "unit_tag": "unit-tag"} + _toPy = {"storage-tag": "storage_tag", "unit-tag": "unit_tag"} + def __init__(self, storage_tag=None, unit_tag=None, **unknown_fields): - ''' + """ storage_tag : str unit_tag : str - ''' + """ storage_tag_ = storage_tag unit_tag_ = unit_tag # Validate arguments against known Juju API types. if storage_tag_ is not None and not isinstance(storage_tag_, (bytes, str)): - raise Exception("Expected storage_tag_ to be a str, received: {}".format(type(storage_tag_))) + raise Exception( + "Expected storage_tag_ to be a str, received: {}".format( + type(storage_tag_) + ) + ) if unit_tag_ is not None and not isinstance(unit_tag_, (bytes, str)): - raise Exception("Expected unit_tag_ to be a str, received: {}".format(type(unit_tag_))) + raise Exception( + "Expected unit_tag_ to be a str, received: {}".format(type(unit_tag_)) + ) self.storage_tag = storage_tag_ self.unit_tag = unit_tag_ self.unknown_fields = unknown_fields - class StorageAttachmentIds(Type): - _toSchema = {'ids': 'ids'} - _toPy = {'ids': 'ids'} + _toSchema = {"ids": "ids"} + _toPy = {"ids": "ids"} + def __init__(self, ids=None, **unknown_fields): - ''' + """ ids : typing.Sequence[~StorageAttachmentId] - ''' + """ ids_ = [StorageAttachmentId.from_json(o) for o in ids or []] # Validate arguments against known Juju API types. if ids_ is not None and not isinstance(ids_, (bytes, str, list)): - raise Exception("Expected ids_ to be a Sequence, received: {}".format(type(ids_))) + raise Exception( + "Expected ids_ to be a Sequence, received: {}".format(type(ids_)) + ) self.ids = ids_ self.unknown_fields = unknown_fields - class StorageConstraints(Type): - _toSchema = {'count': 'count', 'pool': 'pool', 'size': 'size'} - _toPy = {'count': 'count', 'pool': 'pool', 'size': 'size'} + _toSchema = {"count": "count", "pool": "pool", "size": "size"} + _toPy = {"count": "count", "pool": "pool", "size": "size"} + def __init__(self, count=None, pool=None, size=None, **unknown_fields): - ''' + """ count : int pool : str size : int - ''' + """ count_ = count pool_ = pool size_ = size # Validate arguments against known Juju API types. if count_ is not None and not isinstance(count_, int): - raise Exception("Expected count_ to be a int, received: {}".format(type(count_))) + raise Exception( + "Expected count_ to be a int, received: {}".format(type(count_)) + ) if pool_ is not None and not isinstance(pool_, (bytes, str)): - raise Exception("Expected pool_ to be a str, received: {}".format(type(pool_))) + raise Exception( + "Expected pool_ to be a str, received: {}".format(type(pool_)) + ) if size_ is not None and not isinstance(size_, int): - raise Exception("Expected size_ to be a int, received: {}".format(type(size_))) + raise Exception( + "Expected size_ to be a int, received: {}".format(type(size_)) + ) self.count = count_ self.pool = pool_ @@ -14080,29 +22408,37 @@ def __init__(self, count=None, pool=None, size=None, **unknown_fields): self.unknown_fields = unknown_fields - class StorageDetachmentParams(Type): - _toSchema = {'force': 'force', 'ids': 'ids', 'max_wait': 'max-wait'} - _toPy = {'force': 'force', 'ids': 'ids', 'max-wait': 'max_wait'} + _toSchema = {"force": "force", "ids": "ids", "max_wait": "max-wait"} + _toPy = {"force": "force", "ids": "ids", "max-wait": "max_wait"} + def __init__(self, force=None, ids=None, max_wait=None, **unknown_fields): - ''' + """ force : bool ids : StorageAttachmentIds max_wait : int - ''' + """ force_ = force ids_ = StorageAttachmentIds.from_json(ids) if ids else None max_wait_ = max_wait # Validate arguments against known Juju API types. if force_ is not None and not isinstance(force_, bool): - raise Exception("Expected force_ to be a bool, received: {}".format(type(force_))) + raise Exception( + "Expected force_ to be a bool, received: {}".format(type(force_)) + ) if ids_ is not None and not isinstance(ids_, (dict, StorageAttachmentIds)): - raise Exception("Expected ids_ to be a StorageAttachmentIds, received: {}".format(type(ids_))) + raise Exception( + "Expected ids_ to be a StorageAttachmentIds, received: {}".format( + type(ids_) + ) + ) if max_wait_ is not None and not isinstance(max_wait_, int): - raise Exception("Expected max_wait_ to be a int, received: {}".format(type(max_wait_))) + raise Exception( + "Expected max_wait_ to be a int, received: {}".format(type(max_wait_)) + ) self.force = force_ self.ids = ids_ @@ -14110,12 +22446,38 @@ def __init__(self, force=None, ids=None, max_wait=None, **unknown_fields): self.unknown_fields = unknown_fields - class StorageDetails(Type): - _toSchema = {'attachments': 'attachments', 'kind': 'kind', 'life': 'life', 'owner_tag': 'owner-tag', 'persistent': 'persistent', 'status': 'status', 'storage_tag': 'storage-tag'} - _toPy = {'attachments': 'attachments', 'kind': 'kind', 'life': 'life', 'owner-tag': 'owner_tag', 'persistent': 'persistent', 'status': 'status', 'storage-tag': 'storage_tag'} - def __init__(self, attachments=None, kind=None, life=None, owner_tag=None, persistent=None, status=None, storage_tag=None, **unknown_fields): - ''' + _toSchema = { + "attachments": "attachments", + "kind": "kind", + "life": "life", + "owner_tag": "owner-tag", + "persistent": "persistent", + "status": "status", + "storage_tag": "storage-tag", + } + _toPy = { + "attachments": "attachments", + "kind": "kind", + "life": "life", + "owner-tag": "owner_tag", + "persistent": "persistent", + "status": "status", + "storage-tag": "storage_tag", + } + + def __init__( + self, + attachments=None, + kind=None, + life=None, + owner_tag=None, + persistent=None, + status=None, + storage_tag=None, + **unknown_fields, + ): + """ attachments : typing.Mapping[str, ~StorageAttachmentDetails] kind : int life : str @@ -14123,8 +22485,11 @@ def __init__(self, attachments=None, kind=None, life=None, owner_tag=None, persi persistent : bool status : EntityStatus storage_tag : str - ''' - attachments_ = {k: StorageAttachmentDetails.from_json(v) for k, v in (attachments or dict()).items()} + """ + attachments_ = { + k: StorageAttachmentDetails.from_json(v) + for k, v in (attachments or dict()).items() + } kind_ = kind life_ = life owner_tag_ = owner_tag @@ -14134,25 +22499,47 @@ def __init__(self, attachments=None, kind=None, life=None, owner_tag=None, persi # Validate arguments against known Juju API types. if attachments_ is not None and not isinstance(attachments_, dict): - raise Exception("Expected attachments_ to be a Mapping, received: {}".format(type(attachments_))) + raise Exception( + "Expected attachments_ to be a Mapping, received: {}".format( + type(attachments_) + ) + ) if kind_ is not None and not isinstance(kind_, int): - raise Exception("Expected kind_ to be a int, received: {}".format(type(kind_))) + raise Exception( + "Expected kind_ to be a int, received: {}".format(type(kind_)) + ) if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception("Expected life_ to be a str, received: {}".format(type(life_))) + raise Exception( + "Expected life_ to be a str, received: {}".format(type(life_)) + ) if owner_tag_ is not None and not isinstance(owner_tag_, (bytes, str)): - raise Exception("Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_))) + raise Exception( + "Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_)) + ) if persistent_ is not None and not isinstance(persistent_, bool): - raise Exception("Expected persistent_ to be a bool, received: {}".format(type(persistent_))) + raise Exception( + "Expected persistent_ to be a bool, received: {}".format( + type(persistent_) + ) + ) if status_ is not None and not isinstance(status_, (dict, EntityStatus)): - raise Exception("Expected status_ to be a EntityStatus, received: {}".format(type(status_))) + raise Exception( + "Expected status_ to be a EntityStatus, received: {}".format( + type(status_) + ) + ) if storage_tag_ is not None and not isinstance(storage_tag_, (bytes, str)): - raise Exception("Expected storage_tag_ to be a str, received: {}".format(type(storage_tag_))) + raise Exception( + "Expected storage_tag_ to be a str, received: {}".format( + type(storage_tag_) + ) + ) self.attachments = attachments_ self.kind = kind_ @@ -14164,142 +22551,168 @@ def __init__(self, attachments=None, kind=None, life=None, owner_tag=None, persi self.unknown_fields = unknown_fields - class StorageDetailsListResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : typing.Sequence[~StorageDetails] - ''' + """ error_ = Error.from_json(error) if error else None result_ = [StorageDetails.from_json(o) for o in result or []] # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if result_ is not None and not isinstance(result_, (bytes, str, list)): - raise Exception("Expected result_ to be a Sequence, received: {}".format(type(result_))) + raise Exception( + "Expected result_ to be a Sequence, received: {}".format(type(result_)) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class StorageDetailsListResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~StorageDetailsListResult] - ''' + """ results_ = [StorageDetailsListResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class StorageDetailsResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : StorageDetails - ''' + """ error_ = Error.from_json(error) if error else None result_ = StorageDetails.from_json(result) if result else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if result_ is not None and not isinstance(result_, (dict, StorageDetails)): - raise Exception("Expected result_ to be a StorageDetails, received: {}".format(type(result_))) + raise Exception( + "Expected result_ to be a StorageDetails, received: {}".format( + type(result_) + ) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class StorageDetailsResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~StorageDetailsResult] - ''' + """ results_ = [StorageDetailsResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class StorageFilter(Type): _toSchema = {} _toPy = {} - def __init__(self, **unknown_fields): - ''' - ''' + def __init__(self, **unknown_fields): + """ """ self.unknown_fields = unknown_fields - class StorageFilters(Type): - _toSchema = {'filters': 'filters'} - _toPy = {'filters': 'filters'} + _toSchema = {"filters": "filters"} + _toPy = {"filters": "filters"} + def __init__(self, filters=None, **unknown_fields): - ''' + """ filters : typing.Sequence[~StorageFilter] - ''' + """ filters_ = [StorageFilter.from_json(o) for o in filters or []] # Validate arguments against known Juju API types. if filters_ is not None and not isinstance(filters_, (bytes, str, list)): - raise Exception("Expected filters_ to be a Sequence, received: {}".format(type(filters_))) + raise Exception( + "Expected filters_ to be a Sequence, received: {}".format( + type(filters_) + ) + ) self.filters = filters_ self.unknown_fields = unknown_fields - class StoragePool(Type): - _toSchema = {'attrs': 'attrs', 'name': 'name', 'provider': 'provider'} - _toPy = {'attrs': 'attrs', 'name': 'name', 'provider': 'provider'} + _toSchema = {"attrs": "attrs", "name": "name", "provider": "provider"} + _toPy = {"attrs": "attrs", "name": "name", "provider": "provider"} + def __init__(self, attrs=None, name=None, provider=None, **unknown_fields): - ''' + """ attrs : typing.Mapping[str, typing.Any] name : str provider : str - ''' + """ attrs_ = attrs name_ = name provider_ = provider # Validate arguments against known Juju API types. if attrs_ is not None and not isinstance(attrs_, dict): - raise Exception("Expected attrs_ to be a Mapping, received: {}".format(type(attrs_))) + raise Exception( + "Expected attrs_ to be a Mapping, received: {}".format(type(attrs_)) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if provider_ is not None and not isinstance(provider_, (bytes, str)): - raise Exception("Expected provider_ to be a str, received: {}".format(type(provider_))) + raise Exception( + "Expected provider_ to be a str, received: {}".format(type(provider_)) + ) self.attrs = attrs_ self.name = name_ @@ -14307,269 +22720,327 @@ def __init__(self, attrs=None, name=None, provider=None, **unknown_fields): self.unknown_fields = unknown_fields - class StoragePoolArgs(Type): - _toSchema = {'pools': 'pools'} - _toPy = {'pools': 'pools'} + _toSchema = {"pools": "pools"} + _toPy = {"pools": "pools"} + def __init__(self, pools=None, **unknown_fields): - ''' + """ pools : typing.Sequence[~StoragePool] - ''' + """ pools_ = [StoragePool.from_json(o) for o in pools or []] # Validate arguments against known Juju API types. if pools_ is not None and not isinstance(pools_, (bytes, str, list)): - raise Exception("Expected pools_ to be a Sequence, received: {}".format(type(pools_))) + raise Exception( + "Expected pools_ to be a Sequence, received: {}".format(type(pools_)) + ) self.pools = pools_ self.unknown_fields = unknown_fields - class StoragePoolDeleteArg(Type): - _toSchema = {'name': 'name'} - _toPy = {'name': 'name'} + _toSchema = {"name": "name"} + _toPy = {"name": "name"} + def __init__(self, name=None, **unknown_fields): - ''' + """ name : str - ''' + """ name_ = name # Validate arguments against known Juju API types. if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) self.name = name_ self.unknown_fields = unknown_fields - class StoragePoolDeleteArgs(Type): - _toSchema = {'pools': 'pools'} - _toPy = {'pools': 'pools'} + _toSchema = {"pools": "pools"} + _toPy = {"pools": "pools"} + def __init__(self, pools=None, **unknown_fields): - ''' + """ pools : typing.Sequence[~StoragePoolDeleteArg] - ''' + """ pools_ = [StoragePoolDeleteArg.from_json(o) for o in pools or []] # Validate arguments against known Juju API types. if pools_ is not None and not isinstance(pools_, (bytes, str, list)): - raise Exception("Expected pools_ to be a Sequence, received: {}".format(type(pools_))) + raise Exception( + "Expected pools_ to be a Sequence, received: {}".format(type(pools_)) + ) self.pools = pools_ self.unknown_fields = unknown_fields - class StoragePoolFilter(Type): - _toSchema = {'names': 'names', 'providers': 'providers'} - _toPy = {'names': 'names', 'providers': 'providers'} + _toSchema = {"names": "names", "providers": "providers"} + _toPy = {"names": "names", "providers": "providers"} + def __init__(self, names=None, providers=None, **unknown_fields): - ''' + """ names : typing.Sequence[str] providers : typing.Sequence[str] - ''' + """ names_ = names providers_ = providers # Validate arguments against known Juju API types. if names_ is not None and not isinstance(names_, (bytes, str, list)): - raise Exception("Expected names_ to be a Sequence, received: {}".format(type(names_))) + raise Exception( + "Expected names_ to be a Sequence, received: {}".format(type(names_)) + ) if providers_ is not None and not isinstance(providers_, (bytes, str, list)): - raise Exception("Expected providers_ to be a Sequence, received: {}".format(type(providers_))) + raise Exception( + "Expected providers_ to be a Sequence, received: {}".format( + type(providers_) + ) + ) self.names = names_ self.providers = providers_ self.unknown_fields = unknown_fields - class StoragePoolFilters(Type): - _toSchema = {'filters': 'filters'} - _toPy = {'filters': 'filters'} + _toSchema = {"filters": "filters"} + _toPy = {"filters": "filters"} + def __init__(self, filters=None, **unknown_fields): - ''' + """ filters : typing.Sequence[~StoragePoolFilter] - ''' + """ filters_ = [StoragePoolFilter.from_json(o) for o in filters or []] # Validate arguments against known Juju API types. if filters_ is not None and not isinstance(filters_, (bytes, str, list)): - raise Exception("Expected filters_ to be a Sequence, received: {}".format(type(filters_))) + raise Exception( + "Expected filters_ to be a Sequence, received: {}".format( + type(filters_) + ) + ) self.filters = filters_ self.unknown_fields = unknown_fields - class StoragePoolsResult(Type): - _toSchema = {'error': 'error', 'storage_pools': 'storage-pools'} - _toPy = {'error': 'error', 'storage-pools': 'storage_pools'} + _toSchema = {"error": "error", "storage_pools": "storage-pools"} + _toPy = {"error": "error", "storage-pools": "storage_pools"} + def __init__(self, error=None, storage_pools=None, **unknown_fields): - ''' + """ error : Error storage_pools : typing.Sequence[~StoragePool] - ''' + """ error_ = Error.from_json(error) if error else None storage_pools_ = [StoragePool.from_json(o) for o in storage_pools or []] # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) - - if storage_pools_ is not None and not isinstance(storage_pools_, (bytes, str, list)): - raise Exception("Expected storage_pools_ to be a Sequence, received: {}".format(type(storage_pools_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) + + if storage_pools_ is not None and not isinstance( + storage_pools_, (bytes, str, list) + ): + raise Exception( + "Expected storage_pools_ to be a Sequence, received: {}".format( + type(storage_pools_) + ) + ) self.error = error_ self.storage_pools = storage_pools_ self.unknown_fields = unknown_fields - class StoragePoolsResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~StoragePoolsResult] - ''' + """ results_ = [StoragePoolsResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class StoragesAddParams(Type): - _toSchema = {'storages': 'storages'} - _toPy = {'storages': 'storages'} + _toSchema = {"storages": "storages"} + _toPy = {"storages": "storages"} + def __init__(self, storages=None, **unknown_fields): - ''' + """ storages : typing.Sequence[~StorageAddParams] - ''' + """ storages_ = [StorageAddParams.from_json(o) for o in storages or []] # Validate arguments against known Juju API types. if storages_ is not None and not isinstance(storages_, (bytes, str, list)): - raise Exception("Expected storages_ to be a Sequence, received: {}".format(type(storages_))) + raise Exception( + "Expected storages_ to be a Sequence, received: {}".format( + type(storages_) + ) + ) self.storages = storages_ self.unknown_fields = unknown_fields - class StringResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : str - ''' + """ error_ = Error.from_json(error) if error else None result_ = result # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if result_ is not None and not isinstance(result_, (bytes, str)): - raise Exception("Expected result_ to be a str, received: {}".format(type(result_))) + raise Exception( + "Expected result_ to be a str, received: {}".format(type(result_)) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class StringResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~StringResult] - ''' + """ results_ = [StringResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class StringsResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : typing.Sequence[str] - ''' + """ error_ = Error.from_json(error) if error else None result_ = result # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if result_ is not None and not isinstance(result_, (bytes, str, list)): - raise Exception("Expected result_ to be a Sequence, received: {}".format(type(result_))) + raise Exception( + "Expected result_ to be a Sequence, received: {}".format(type(result_)) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class StringsResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~StringsResult] - ''' + """ results_ = [StringsResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class StringsWatchResult(Type): - _toSchema = {'changes': 'changes', 'error': 'error', 'watcher_id': 'watcher-id'} - _toPy = {'changes': 'changes', 'error': 'error', 'watcher-id': 'watcher_id'} + _toSchema = {"changes": "changes", "error": "error", "watcher_id": "watcher-id"} + _toPy = {"changes": "changes", "error": "error", "watcher-id": "watcher_id"} + def __init__(self, changes=None, error=None, watcher_id=None, **unknown_fields): - ''' + """ changes : typing.Sequence[str] error : Error watcher_id : str - ''' + """ changes_ = changes error_ = Error.from_json(error) if error else None watcher_id_ = watcher_id # Validate arguments against known Juju API types. if changes_ is not None and not isinstance(changes_, (bytes, str, list)): - raise Exception("Expected changes_ to be a Sequence, received: {}".format(type(changes_))) + raise Exception( + "Expected changes_ to be a Sequence, received: {}".format( + type(changes_) + ) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if watcher_id_ is not None and not isinstance(watcher_id_, (bytes, str)): - raise Exception("Expected watcher_id_ to be a str, received: {}".format(type(watcher_id_))) + raise Exception( + "Expected watcher_id_ to be a str, received: {}".format( + type(watcher_id_) + ) + ) self.changes = changes_ self.error = error_ @@ -14577,30 +23048,66 @@ def __init__(self, changes=None, error=None, watcher_id=None, **unknown_fields): self.unknown_fields = unknown_fields - class StringsWatchResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~StringsWatchResult] - ''' + """ results_ = [StringsWatchResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class Subnet(Type): - _toSchema = {'cidr': 'cidr', 'life': 'life', 'provider_id': 'provider-id', 'provider_network_id': 'provider-network-id', 'provider_space_id': 'provider-space-id', 'space_tag': 'space-tag', 'status': 'status', 'vlan_tag': 'vlan-tag', 'zones': 'zones'} - _toPy = {'cidr': 'cidr', 'life': 'life', 'provider-id': 'provider_id', 'provider-network-id': 'provider_network_id', 'provider-space-id': 'provider_space_id', 'space-tag': 'space_tag', 'status': 'status', 'vlan-tag': 'vlan_tag', 'zones': 'zones'} - def __init__(self, cidr=None, life=None, provider_id=None, provider_network_id=None, provider_space_id=None, space_tag=None, status=None, vlan_tag=None, zones=None, **unknown_fields): - ''' + _toSchema = { + "cidr": "cidr", + "life": "life", + "provider_id": "provider-id", + "provider_network_id": "provider-network-id", + "provider_space_id": "provider-space-id", + "space_tag": "space-tag", + "status": "status", + "vlan_tag": "vlan-tag", + "zones": "zones", + } + _toPy = { + "cidr": "cidr", + "life": "life", + "provider-id": "provider_id", + "provider-network-id": "provider_network_id", + "provider-space-id": "provider_space_id", + "space-tag": "space_tag", + "status": "status", + "vlan-tag": "vlan_tag", + "zones": "zones", + } + + def __init__( + self, + cidr=None, + life=None, + provider_id=None, + provider_network_id=None, + provider_space_id=None, + space_tag=None, + status=None, + vlan_tag=None, + zones=None, + **unknown_fields, + ): + """ cidr : str life : str provider_id : str @@ -14610,7 +23117,7 @@ def __init__(self, cidr=None, life=None, provider_id=None, provider_network_id=N status : str vlan_tag : int zones : typing.Sequence[str] - ''' + """ cidr_ = cidr life_ = life provider_id_ = provider_id @@ -14623,31 +23130,59 @@ def __init__(self, cidr=None, life=None, provider_id=None, provider_network_id=N # Validate arguments against known Juju API types. if cidr_ is not None and not isinstance(cidr_, (bytes, str)): - raise Exception("Expected cidr_ to be a str, received: {}".format(type(cidr_))) + raise Exception( + "Expected cidr_ to be a str, received: {}".format(type(cidr_)) + ) if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception("Expected life_ to be a str, received: {}".format(type(life_))) + raise Exception( + "Expected life_ to be a str, received: {}".format(type(life_)) + ) if provider_id_ is not None and not isinstance(provider_id_, (bytes, str)): - raise Exception("Expected provider_id_ to be a str, received: {}".format(type(provider_id_))) - - if provider_network_id_ is not None and not isinstance(provider_network_id_, (bytes, str)): - raise Exception("Expected provider_network_id_ to be a str, received: {}".format(type(provider_network_id_))) - - if provider_space_id_ is not None and not isinstance(provider_space_id_, (bytes, str)): - raise Exception("Expected provider_space_id_ to be a str, received: {}".format(type(provider_space_id_))) + raise Exception( + "Expected provider_id_ to be a str, received: {}".format( + type(provider_id_) + ) + ) + + if provider_network_id_ is not None and not isinstance( + provider_network_id_, (bytes, str) + ): + raise Exception( + "Expected provider_network_id_ to be a str, received: {}".format( + type(provider_network_id_) + ) + ) + + if provider_space_id_ is not None and not isinstance( + provider_space_id_, (bytes, str) + ): + raise Exception( + "Expected provider_space_id_ to be a str, received: {}".format( + type(provider_space_id_) + ) + ) if space_tag_ is not None and not isinstance(space_tag_, (bytes, str)): - raise Exception("Expected space_tag_ to be a str, received: {}".format(type(space_tag_))) + raise Exception( + "Expected space_tag_ to be a str, received: {}".format(type(space_tag_)) + ) if status_ is not None and not isinstance(status_, (bytes, str)): - raise Exception("Expected status_ to be a str, received: {}".format(type(status_))) + raise Exception( + "Expected status_ to be a str, received: {}".format(type(status_)) + ) if vlan_tag_ is not None and not isinstance(vlan_tag_, int): - raise Exception("Expected vlan_tag_ to be a int, received: {}".format(type(vlan_tag_))) + raise Exception( + "Expected vlan_tag_ to be a int, received: {}".format(type(vlan_tag_)) + ) if zones_ is not None and not isinstance(zones_, (bytes, str, list)): - raise Exception("Expected zones_ to be a Sequence, received: {}".format(type(zones_))) + raise Exception( + "Expected zones_ to be a Sequence, received: {}".format(type(zones_)) + ) self.cidr = cidr_ self.life = life_ @@ -14661,12 +23196,50 @@ def __init__(self, cidr=None, life=None, provider_id=None, provider_network_id=N self.unknown_fields = unknown_fields - class SubnetV2(Type): - _toSchema = {'cidr': 'cidr', 'id_': 'id', 'life': 'life', 'provider_id': 'provider-id', 'provider_network_id': 'provider-network-id', 'provider_space_id': 'provider-space-id', 'space_tag': 'space-tag', 'status': 'status', 'subnet': 'Subnet', 'vlan_tag': 'vlan-tag', 'zones': 'zones'} - _toPy = {'Subnet': 'subnet', 'cidr': 'cidr', 'id': 'id_', 'life': 'life', 'provider-id': 'provider_id', 'provider-network-id': 'provider_network_id', 'provider-space-id': 'provider_space_id', 'space-tag': 'space_tag', 'status': 'status', 'vlan-tag': 'vlan_tag', 'zones': 'zones'} - def __init__(self, subnet=None, cidr=None, id_=None, life=None, provider_id=None, provider_network_id=None, provider_space_id=None, space_tag=None, status=None, vlan_tag=None, zones=None, **unknown_fields): - ''' + _toSchema = { + "cidr": "cidr", + "id_": "id", + "life": "life", + "provider_id": "provider-id", + "provider_network_id": "provider-network-id", + "provider_space_id": "provider-space-id", + "space_tag": "space-tag", + "status": "status", + "subnet": "Subnet", + "vlan_tag": "vlan-tag", + "zones": "zones", + } + _toPy = { + "Subnet": "subnet", + "cidr": "cidr", + "id": "id_", + "life": "life", + "provider-id": "provider_id", + "provider-network-id": "provider_network_id", + "provider-space-id": "provider_space_id", + "space-tag": "space_tag", + "status": "status", + "vlan-tag": "vlan_tag", + "zones": "zones", + } + + def __init__( + self, + subnet=None, + cidr=None, + id_=None, + life=None, + provider_id=None, + provider_network_id=None, + provider_space_id=None, + space_tag=None, + status=None, + vlan_tag=None, + zones=None, + **unknown_fields, + ): + """ subnet : Subnet cidr : str id_ : str @@ -14678,7 +23251,7 @@ def __init__(self, subnet=None, cidr=None, id_=None, life=None, provider_id=None status : str vlan_tag : int zones : typing.Sequence[str] - ''' + """ subnet_ = Subnet.from_json(subnet) if subnet else None cidr_ = cidr id__ = id_ @@ -14693,37 +23266,69 @@ def __init__(self, subnet=None, cidr=None, id_=None, life=None, provider_id=None # Validate arguments against known Juju API types. if subnet_ is not None and not isinstance(subnet_, (dict, Subnet)): - raise Exception("Expected subnet_ to be a Subnet, received: {}".format(type(subnet_))) + raise Exception( + "Expected subnet_ to be a Subnet, received: {}".format(type(subnet_)) + ) if cidr_ is not None and not isinstance(cidr_, (bytes, str)): - raise Exception("Expected cidr_ to be a str, received: {}".format(type(cidr_))) + raise Exception( + "Expected cidr_ to be a str, received: {}".format(type(cidr_)) + ) if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception("Expected id__ to be a str, received: {}".format(type(id__))) + raise Exception( + "Expected id__ to be a str, received: {}".format(type(id__)) + ) if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception("Expected life_ to be a str, received: {}".format(type(life_))) + raise Exception( + "Expected life_ to be a str, received: {}".format(type(life_)) + ) if provider_id_ is not None and not isinstance(provider_id_, (bytes, str)): - raise Exception("Expected provider_id_ to be a str, received: {}".format(type(provider_id_))) - - if provider_network_id_ is not None and not isinstance(provider_network_id_, (bytes, str)): - raise Exception("Expected provider_network_id_ to be a str, received: {}".format(type(provider_network_id_))) - - if provider_space_id_ is not None and not isinstance(provider_space_id_, (bytes, str)): - raise Exception("Expected provider_space_id_ to be a str, received: {}".format(type(provider_space_id_))) + raise Exception( + "Expected provider_id_ to be a str, received: {}".format( + type(provider_id_) + ) + ) + + if provider_network_id_ is not None and not isinstance( + provider_network_id_, (bytes, str) + ): + raise Exception( + "Expected provider_network_id_ to be a str, received: {}".format( + type(provider_network_id_) + ) + ) + + if provider_space_id_ is not None and not isinstance( + provider_space_id_, (bytes, str) + ): + raise Exception( + "Expected provider_space_id_ to be a str, received: {}".format( + type(provider_space_id_) + ) + ) if space_tag_ is not None and not isinstance(space_tag_, (bytes, str)): - raise Exception("Expected space_tag_ to be a str, received: {}".format(type(space_tag_))) + raise Exception( + "Expected space_tag_ to be a str, received: {}".format(type(space_tag_)) + ) if status_ is not None and not isinstance(status_, (bytes, str)): - raise Exception("Expected status_ to be a str, received: {}".format(type(status_))) + raise Exception( + "Expected status_ to be a str, received: {}".format(type(status_)) + ) if vlan_tag_ is not None and not isinstance(vlan_tag_, int): - raise Exception("Expected vlan_tag_ to be a int, received: {}".format(type(vlan_tag_))) + raise Exception( + "Expected vlan_tag_ to be a int, received: {}".format(type(vlan_tag_)) + ) if zones_ is not None and not isinstance(zones_, (bytes, str, list)): - raise Exception("Expected zones_ to be a Sequence, received: {}".format(type(zones_))) + raise Exception( + "Expected zones_ to be a Sequence, received: {}".format(type(zones_)) + ) self.subnet = subnet_ self.cidr = cidr_ @@ -14739,113 +23344,139 @@ def __init__(self, subnet=None, cidr=None, id_=None, life=None, provider_id=None self.unknown_fields = unknown_fields - class SubnetsFilters(Type): - _toSchema = {'space_tag': 'space-tag', 'zone': 'zone'} - _toPy = {'space-tag': 'space_tag', 'zone': 'zone'} + _toSchema = {"space_tag": "space-tag", "zone": "zone"} + _toPy = {"space-tag": "space_tag", "zone": "zone"} + def __init__(self, space_tag=None, zone=None, **unknown_fields): - ''' + """ space_tag : str zone : str - ''' + """ space_tag_ = space_tag zone_ = zone # Validate arguments against known Juju API types. if space_tag_ is not None and not isinstance(space_tag_, (bytes, str)): - raise Exception("Expected space_tag_ to be a str, received: {}".format(type(space_tag_))) + raise Exception( + "Expected space_tag_ to be a str, received: {}".format(type(space_tag_)) + ) if zone_ is not None and not isinstance(zone_, (bytes, str)): - raise Exception("Expected zone_ to be a str, received: {}".format(type(zone_))) + raise Exception( + "Expected zone_ to be a str, received: {}".format(type(zone_)) + ) self.space_tag = space_tag_ self.zone = zone_ self.unknown_fields = unknown_fields - class SubnetsResult(Type): - _toSchema = {'error': 'error', 'subnets': 'subnets'} - _toPy = {'error': 'error', 'subnets': 'subnets'} + _toSchema = {"error": "error", "subnets": "subnets"} + _toPy = {"error": "error", "subnets": "subnets"} + def __init__(self, error=None, subnets=None, **unknown_fields): - ''' + """ error : Error subnets : typing.Sequence[~SubnetV2] - ''' + """ error_ = Error.from_json(error) if error else None subnets_ = [SubnetV2.from_json(o) for o in subnets or []] # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if subnets_ is not None and not isinstance(subnets_, (bytes, str, list)): - raise Exception("Expected subnets_ to be a Sequence, received: {}".format(type(subnets_))) + raise Exception( + "Expected subnets_ to be a Sequence, received: {}".format( + type(subnets_) + ) + ) self.error = error_ self.subnets = subnets_ self.unknown_fields = unknown_fields - class SubnetsResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~SubnetsResult] - ''' + """ results_ = [SubnetsResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class SummaryWatcherID(Type): - _toSchema = {'watcher_id': 'watcher-id'} - _toPy = {'watcher-id': 'watcher_id'} + _toSchema = {"watcher_id": "watcher-id"} + _toPy = {"watcher-id": "watcher_id"} + def __init__(self, watcher_id=None, **unknown_fields): - ''' + """ watcher_id : str - ''' + """ watcher_id_ = watcher_id # Validate arguments against known Juju API types. if watcher_id_ is not None and not isinstance(watcher_id_, (bytes, str)): - raise Exception("Expected watcher_id_ to be a str, received: {}".format(type(watcher_id_))) + raise Exception( + "Expected watcher_id_ to be a str, received: {}".format( + type(watcher_id_) + ) + ) self.watcher_id = watcher_id_ self.unknown_fields = unknown_fields - class SupportedFeature(Type): - _toSchema = {'description': 'description', 'name': 'name', 'version': 'version'} - _toPy = {'description': 'description', 'name': 'name', 'version': 'version'} + _toSchema = {"description": "description", "name": "name", "version": "version"} + _toPy = {"description": "description", "name": "name", "version": "version"} + def __init__(self, description=None, name=None, version=None, **unknown_fields): - ''' + """ description : str name : str version : str - ''' + """ description_ = description name_ = name version_ = version # Validate arguments against known Juju API types. if description_ is not None and not isinstance(description_, (bytes, str)): - raise Exception("Expected description_ to be a str, received: {}".format(type(description_))) + raise Exception( + "Expected description_ to be a str, received: {}".format( + type(description_) + ) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if version_ is not None and not isinstance(version_, (bytes, str)): - raise Exception("Expected version_ to be a str, received: {}".format(type(version_))) + raise Exception( + "Expected version_ to be a str, received: {}".format(type(version_)) + ) self.description = description_ self.name = name_ @@ -14853,59 +23484,75 @@ def __init__(self, description=None, name=None, version=None, **unknown_fields): self.unknown_fields = unknown_fields - class TaggedCredential(Type): - _toSchema = {'credential': 'credential', 'tag': 'tag'} - _toPy = {'credential': 'credential', 'tag': 'tag'} + _toSchema = {"credential": "credential", "tag": "tag"} + _toPy = {"credential": "credential", "tag": "tag"} + def __init__(self, credential=None, tag=None, **unknown_fields): - ''' + """ credential : CloudCredential tag : str - ''' + """ credential_ = CloudCredential.from_json(credential) if credential else None tag_ = tag # Validate arguments against known Juju API types. - if credential_ is not None and not isinstance(credential_, (dict, CloudCredential)): - raise Exception("Expected credential_ to be a CloudCredential, received: {}".format(type(credential_))) + if credential_ is not None and not isinstance( + credential_, (dict, CloudCredential) + ): + raise Exception( + "Expected credential_ to be a CloudCredential, received: {}".format( + type(credential_) + ) + ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception("Expected tag_ to be a str, received: {}".format(type(tag_))) + raise Exception( + "Expected tag_ to be a str, received: {}".format(type(tag_)) + ) self.credential = credential_ self.tag = tag_ self.unknown_fields = unknown_fields - class TaggedCredentials(Type): - _toSchema = {'credentials': 'credentials'} - _toPy = {'credentials': 'credentials'} + _toSchema = {"credentials": "credentials"} + _toPy = {"credentials": "credentials"} + def __init__(self, credentials=None, **unknown_fields): - ''' + """ credentials : typing.Sequence[~TaggedCredential] - ''' + """ credentials_ = [TaggedCredential.from_json(o) for o in credentials or []] # Validate arguments against known Juju API types. - if credentials_ is not None and not isinstance(credentials_, (bytes, str, list)): - raise Exception("Expected credentials_ to be a Sequence, received: {}".format(type(credentials_))) + if credentials_ is not None and not isinstance( + credentials_, (bytes, str, list) + ): + raise Exception( + "Expected credentials_ to be a Sequence, received: {}".format( + type(credentials_) + ) + ) self.credentials = credentials_ self.unknown_fields = unknown_fields - class Tools(Type): - _toSchema = {'sha256': 'sha256', 'size': 'size', 'url': 'url', 'version': 'version'} - _toPy = {'sha256': 'sha256', 'size': 'size', 'url': 'url', 'version': 'version'} - def __init__(self, sha256=None, size=None, url=None, version=None, **unknown_fields): - ''' + _toSchema = {"sha256": "sha256", "size": "size", "url": "url", "version": "version"} + _toPy = {"sha256": "sha256", "size": "size", "url": "url", "version": "version"} + + def __init__( + self, sha256=None, size=None, url=None, version=None, **unknown_fields + ): + """ sha256 : str size : int url : str version : Binary - ''' + """ sha256_ = sha256 size_ = size url_ = url @@ -14913,16 +23560,24 @@ def __init__(self, sha256=None, size=None, url=None, version=None, **unknown_fie # Validate arguments against known Juju API types. if sha256_ is not None and not isinstance(sha256_, (bytes, str)): - raise Exception("Expected sha256_ to be a str, received: {}".format(type(sha256_))) + raise Exception( + "Expected sha256_ to be a str, received: {}".format(type(sha256_)) + ) if size_ is not None and not isinstance(size_, int): - raise Exception("Expected size_ to be a int, received: {}".format(type(size_))) + raise Exception( + "Expected size_ to be a int, received: {}".format(type(size_)) + ) if url_ is not None and not isinstance(url_, (bytes, str)): - raise Exception("Expected url_ to be a str, received: {}".format(type(url_))) + raise Exception( + "Expected url_ to be a str, received: {}".format(type(url_)) + ) if version_ is not None and not isinstance(version_, (dict, Binary)): - raise Exception("Expected version_ to be a Binary, received: {}".format(type(version_))) + raise Exception( + "Expected version_ to be a Binary, received: {}".format(type(version_)) + ) self.sha256 = sha256_ self.size = size_ @@ -14931,59 +23586,86 @@ def __init__(self, sha256=None, size=None, url=None, version=None, **unknown_fie self.unknown_fields = unknown_fields - class UnitInfoResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : UnitResult - ''' + """ error_ = Error.from_json(error) if error else None result_ = UnitResult.from_json(result) if result else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if result_ is not None and not isinstance(result_, (dict, UnitResult)): - raise Exception("Expected result_ to be a UnitResult, received: {}".format(type(result_))) + raise Exception( + "Expected result_ to be a UnitResult, received: {}".format( + type(result_) + ) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class UnitInfoResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~UnitInfoResult] - ''' + """ results_ = [UnitInfoResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class UnitResources(Type): - _toSchema = {'download_progress': 'download-progress', 'entity': 'Entity', 'resources': 'resources', 'tag': 'tag'} - _toPy = {'Entity': 'entity', 'download-progress': 'download_progress', 'resources': 'resources', 'tag': 'tag'} - def __init__(self, entity=None, download_progress=None, resources=None, tag=None, **unknown_fields): - ''' + _toSchema = { + "download_progress": "download-progress", + "entity": "Entity", + "resources": "resources", + "tag": "tag", + } + _toPy = { + "Entity": "entity", + "download-progress": "download_progress", + "resources": "resources", + "tag": "tag", + } + + def __init__( + self, + entity=None, + download_progress=None, + resources=None, + tag=None, + **unknown_fields, + ): + """ entity : Entity download_progress : typing.Mapping[str, int] resources : typing.Sequence[~Resource] tag : str - ''' + """ entity_ = Entity.from_json(entity) if entity else None download_progress_ = download_progress resources_ = [Resource.from_json(o) for o in resources or []] @@ -14991,16 +23673,28 @@ def __init__(self, entity=None, download_progress=None, resources=None, tag=None # Validate arguments against known Juju API types. if entity_ is not None and not isinstance(entity_, (dict, Entity)): - raise Exception("Expected entity_ to be a Entity, received: {}".format(type(entity_))) + raise Exception( + "Expected entity_ to be a Entity, received: {}".format(type(entity_)) + ) if download_progress_ is not None and not isinstance(download_progress_, dict): - raise Exception("Expected download_progress_ to be a Mapping, received: {}".format(type(download_progress_))) + raise Exception( + "Expected download_progress_ to be a Mapping, received: {}".format( + type(download_progress_) + ) + ) if resources_ is not None and not isinstance(resources_, (bytes, str, list)): - raise Exception("Expected resources_ to be a Sequence, received: {}".format(type(resources_))) + raise Exception( + "Expected resources_ to be a Sequence, received: {}".format( + type(resources_) + ) + ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception("Expected tag_ to be a str, received: {}".format(type(tag_))) + raise Exception( + "Expected tag_ to be a str, received: {}".format(type(tag_)) + ) self.entity = entity_ self.download_progress = download_progress_ @@ -15009,12 +23703,50 @@ def __init__(self, entity=None, download_progress=None, resources=None, tag=None self.unknown_fields = unknown_fields - class UnitResult(Type): - _toSchema = {'address': 'address', 'charm': 'charm', 'leader': 'leader', 'life': 'life', 'machine': 'machine', 'opened_ports': 'opened-ports', 'provider_id': 'provider-id', 'public_address': 'public-address', 'relation_data': 'relation-data', 'tag': 'tag', 'workload_version': 'workload-version'} - _toPy = {'address': 'address', 'charm': 'charm', 'leader': 'leader', 'life': 'life', 'machine': 'machine', 'opened-ports': 'opened_ports', 'provider-id': 'provider_id', 'public-address': 'public_address', 'relation-data': 'relation_data', 'tag': 'tag', 'workload-version': 'workload_version'} - def __init__(self, address=None, charm=None, leader=None, life=None, machine=None, opened_ports=None, provider_id=None, public_address=None, relation_data=None, tag=None, workload_version=None, **unknown_fields): - ''' + _toSchema = { + "address": "address", + "charm": "charm", + "leader": "leader", + "life": "life", + "machine": "machine", + "opened_ports": "opened-ports", + "provider_id": "provider-id", + "public_address": "public-address", + "relation_data": "relation-data", + "tag": "tag", + "workload_version": "workload-version", + } + _toPy = { + "address": "address", + "charm": "charm", + "leader": "leader", + "life": "life", + "machine": "machine", + "opened-ports": "opened_ports", + "provider-id": "provider_id", + "public-address": "public_address", + "relation-data": "relation_data", + "tag": "tag", + "workload-version": "workload_version", + } + + def __init__( + self, + address=None, + charm=None, + leader=None, + life=None, + machine=None, + opened_ports=None, + provider_id=None, + public_address=None, + relation_data=None, + tag=None, + workload_version=None, + **unknown_fields, + ): + """ address : str charm : str leader : bool @@ -15026,7 +23758,7 @@ def __init__(self, address=None, charm=None, leader=None, life=None, machine=Non relation_data : typing.Sequence[~EndpointRelationData] tag : str workload_version : str - ''' + """ address_ = address charm_ = charm leader_ = leader @@ -15035,43 +23767,85 @@ def __init__(self, address=None, charm=None, leader=None, life=None, machine=Non opened_ports_ = opened_ports provider_id_ = provider_id public_address_ = public_address - relation_data_ = [EndpointRelationData.from_json(o) for o in relation_data or []] + relation_data_ = [ + EndpointRelationData.from_json(o) for o in relation_data or [] + ] tag_ = tag workload_version_ = workload_version # Validate arguments against known Juju API types. if address_ is not None and not isinstance(address_, (bytes, str)): - raise Exception("Expected address_ to be a str, received: {}".format(type(address_))) + raise Exception( + "Expected address_ to be a str, received: {}".format(type(address_)) + ) if charm_ is not None and not isinstance(charm_, (bytes, str)): - raise Exception("Expected charm_ to be a str, received: {}".format(type(charm_))) + raise Exception( + "Expected charm_ to be a str, received: {}".format(type(charm_)) + ) if leader_ is not None and not isinstance(leader_, bool): - raise Exception("Expected leader_ to be a bool, received: {}".format(type(leader_))) + raise Exception( + "Expected leader_ to be a bool, received: {}".format(type(leader_)) + ) if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception("Expected life_ to be a str, received: {}".format(type(life_))) + raise Exception( + "Expected life_ to be a str, received: {}".format(type(life_)) + ) if machine_ is not None and not isinstance(machine_, (bytes, str)): - raise Exception("Expected machine_ to be a str, received: {}".format(type(machine_))) - - if opened_ports_ is not None and not isinstance(opened_ports_, (bytes, str, list)): - raise Exception("Expected opened_ports_ to be a Sequence, received: {}".format(type(opened_ports_))) + raise Exception( + "Expected machine_ to be a str, received: {}".format(type(machine_)) + ) + + if opened_ports_ is not None and not isinstance( + opened_ports_, (bytes, str, list) + ): + raise Exception( + "Expected opened_ports_ to be a Sequence, received: {}".format( + type(opened_ports_) + ) + ) if provider_id_ is not None and not isinstance(provider_id_, (bytes, str)): - raise Exception("Expected provider_id_ to be a str, received: {}".format(type(provider_id_))) - - if public_address_ is not None and not isinstance(public_address_, (bytes, str)): - raise Exception("Expected public_address_ to be a str, received: {}".format(type(public_address_))) - - if relation_data_ is not None and not isinstance(relation_data_, (bytes, str, list)): - raise Exception("Expected relation_data_ to be a Sequence, received: {}".format(type(relation_data_))) + raise Exception( + "Expected provider_id_ to be a str, received: {}".format( + type(provider_id_) + ) + ) + + if public_address_ is not None and not isinstance( + public_address_, (bytes, str) + ): + raise Exception( + "Expected public_address_ to be a str, received: {}".format( + type(public_address_) + ) + ) + + if relation_data_ is not None and not isinstance( + relation_data_, (bytes, str, list) + ): + raise Exception( + "Expected relation_data_ to be a Sequence, received: {}".format( + type(relation_data_) + ) + ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception("Expected tag_ to be a str, received: {}".format(type(tag_))) - - if workload_version_ is not None and not isinstance(workload_version_, (bytes, str)): - raise Exception("Expected workload_version_ to be a str, received: {}".format(type(workload_version_))) + raise Exception( + "Expected tag_ to be a str, received: {}".format(type(tag_)) + ) + + if workload_version_ is not None and not isinstance( + workload_version_, (bytes, str) + ): + raise Exception( + "Expected workload_version_ to be a str, received: {}".format( + type(workload_version_) + ) + ) self.address = address_ self.charm = charm_ @@ -15087,12 +23861,50 @@ def __init__(self, address=None, charm=None, leader=None, life=None, machine=Non self.unknown_fields = unknown_fields - class UnitStatus(Type): - _toSchema = {'address': 'address', 'agent_status': 'agent-status', 'charm': 'charm', 'leader': 'leader', 'machine': 'machine', 'opened_ports': 'opened-ports', 'provider_id': 'provider-id', 'public_address': 'public-address', 'subordinates': 'subordinates', 'workload_status': 'workload-status', 'workload_version': 'workload-version'} - _toPy = {'address': 'address', 'agent-status': 'agent_status', 'charm': 'charm', 'leader': 'leader', 'machine': 'machine', 'opened-ports': 'opened_ports', 'provider-id': 'provider_id', 'public-address': 'public_address', 'subordinates': 'subordinates', 'workload-status': 'workload_status', 'workload-version': 'workload_version'} - def __init__(self, address=None, agent_status=None, charm=None, leader=None, machine=None, opened_ports=None, provider_id=None, public_address=None, subordinates=None, workload_status=None, workload_version=None, **unknown_fields): - ''' + _toSchema = { + "address": "address", + "agent_status": "agent-status", + "charm": "charm", + "leader": "leader", + "machine": "machine", + "opened_ports": "opened-ports", + "provider_id": "provider-id", + "public_address": "public-address", + "subordinates": "subordinates", + "workload_status": "workload-status", + "workload_version": "workload-version", + } + _toPy = { + "address": "address", + "agent-status": "agent_status", + "charm": "charm", + "leader": "leader", + "machine": "machine", + "opened-ports": "opened_ports", + "provider-id": "provider_id", + "public-address": "public_address", + "subordinates": "subordinates", + "workload-status": "workload_status", + "workload-version": "workload_version", + } + + def __init__( + self, + address=None, + agent_status=None, + charm=None, + leader=None, + machine=None, + opened_ports=None, + provider_id=None, + public_address=None, + subordinates=None, + workload_status=None, + workload_version=None, + **unknown_fields, + ): + """ address : str agent_status : DetailedStatus charm : str @@ -15104,7 +23916,7 @@ def __init__(self, address=None, agent_status=None, charm=None, leader=None, mac subordinates : typing.Mapping[str, ~UnitStatus] workload_status : DetailedStatus workload_version : str - ''' + """ address_ = address agent_status_ = DetailedStatus.from_json(agent_status) if agent_status else None charm_ = charm @@ -15113,43 +23925,93 @@ def __init__(self, address=None, agent_status=None, charm=None, leader=None, mac opened_ports_ = opened_ports provider_id_ = provider_id public_address_ = public_address - subordinates_ = {k: UnitStatus.from_json(v) for k, v in (subordinates or dict()).items()} - workload_status_ = DetailedStatus.from_json(workload_status) if workload_status else None + subordinates_ = { + k: UnitStatus.from_json(v) for k, v in (subordinates or dict()).items() + } + workload_status_ = ( + DetailedStatus.from_json(workload_status) if workload_status else None + ) workload_version_ = workload_version # Validate arguments against known Juju API types. if address_ is not None and not isinstance(address_, (bytes, str)): - raise Exception("Expected address_ to be a str, received: {}".format(type(address_))) - - if agent_status_ is not None and not isinstance(agent_status_, (dict, DetailedStatus)): - raise Exception("Expected agent_status_ to be a DetailedStatus, received: {}".format(type(agent_status_))) + raise Exception( + "Expected address_ to be a str, received: {}".format(type(address_)) + ) + + if agent_status_ is not None and not isinstance( + agent_status_, (dict, DetailedStatus) + ): + raise Exception( + "Expected agent_status_ to be a DetailedStatus, received: {}".format( + type(agent_status_) + ) + ) if charm_ is not None and not isinstance(charm_, (bytes, str)): - raise Exception("Expected charm_ to be a str, received: {}".format(type(charm_))) + raise Exception( + "Expected charm_ to be a str, received: {}".format(type(charm_)) + ) if leader_ is not None and not isinstance(leader_, bool): - raise Exception("Expected leader_ to be a bool, received: {}".format(type(leader_))) + raise Exception( + "Expected leader_ to be a bool, received: {}".format(type(leader_)) + ) if machine_ is not None and not isinstance(machine_, (bytes, str)): - raise Exception("Expected machine_ to be a str, received: {}".format(type(machine_))) - - if opened_ports_ is not None and not isinstance(opened_ports_, (bytes, str, list)): - raise Exception("Expected opened_ports_ to be a Sequence, received: {}".format(type(opened_ports_))) + raise Exception( + "Expected machine_ to be a str, received: {}".format(type(machine_)) + ) + + if opened_ports_ is not None and not isinstance( + opened_ports_, (bytes, str, list) + ): + raise Exception( + "Expected opened_ports_ to be a Sequence, received: {}".format( + type(opened_ports_) + ) + ) if provider_id_ is not None and not isinstance(provider_id_, (bytes, str)): - raise Exception("Expected provider_id_ to be a str, received: {}".format(type(provider_id_))) - - if public_address_ is not None and not isinstance(public_address_, (bytes, str)): - raise Exception("Expected public_address_ to be a str, received: {}".format(type(public_address_))) + raise Exception( + "Expected provider_id_ to be a str, received: {}".format( + type(provider_id_) + ) + ) + + if public_address_ is not None and not isinstance( + public_address_, (bytes, str) + ): + raise Exception( + "Expected public_address_ to be a str, received: {}".format( + type(public_address_) + ) + ) if subordinates_ is not None and not isinstance(subordinates_, dict): - raise Exception("Expected subordinates_ to be a Mapping, received: {}".format(type(subordinates_))) - - if workload_status_ is not None and not isinstance(workload_status_, (dict, DetailedStatus)): - raise Exception("Expected workload_status_ to be a DetailedStatus, received: {}".format(type(workload_status_))) - - if workload_version_ is not None and not isinstance(workload_version_, (bytes, str)): - raise Exception("Expected workload_version_ to be a str, received: {}".format(type(workload_version_))) + raise Exception( + "Expected subordinates_ to be a Mapping, received: {}".format( + type(subordinates_) + ) + ) + + if workload_status_ is not None and not isinstance( + workload_status_, (dict, DetailedStatus) + ): + raise Exception( + "Expected workload_status_ to be a DetailedStatus, received: {}".format( + type(workload_status_) + ) + ) + + if workload_version_ is not None and not isinstance( + workload_version_, (bytes, str) + ): + raise Exception( + "Expected workload_version_ to be a str, received: {}".format( + type(workload_version_) + ) + ) self.address = address_ self.agent_status = agent_status_ @@ -15165,29 +24027,35 @@ def __init__(self, address=None, agent_status=None, charm=None, leader=None, mac self.unknown_fields = unknown_fields - class UnitsResolved(Type): - _toSchema = {'all_': 'all', 'retry': 'retry', 'tags': 'tags'} - _toPy = {'all': 'all_', 'retry': 'retry', 'tags': 'tags'} + _toSchema = {"all_": "all", "retry": "retry", "tags": "tags"} + _toPy = {"all": "all_", "retry": "retry", "tags": "tags"} + def __init__(self, all_=None, retry=None, tags=None, **unknown_fields): - ''' + """ all_ : bool retry : bool tags : Entities - ''' + """ all__ = all_ retry_ = retry tags_ = Entities.from_json(tags) if tags else None # Validate arguments against known Juju API types. if all__ is not None and not isinstance(all__, bool): - raise Exception("Expected all__ to be a bool, received: {}".format(type(all__))) + raise Exception( + "Expected all__ to be a bool, received: {}".format(type(all__)) + ) if retry_ is not None and not isinstance(retry_, bool): - raise Exception("Expected retry_ to be a bool, received: {}".format(type(retry_))) + raise Exception( + "Expected retry_ to be a bool, received: {}".format(type(retry_)) + ) if tags_ is not None and not isinstance(tags_, (dict, Entities)): - raise Exception("Expected tags_ to be a Entities, received: {}".format(type(tags_))) + raise Exception( + "Expected tags_ to be a Entities, received: {}".format(type(tags_)) + ) self.all_ = all__ self.retry = retry_ @@ -15195,47 +24063,55 @@ def __init__(self, all_=None, retry=None, tags=None, **unknown_fields): self.unknown_fields = unknown_fields - class UnsetModelDefaults(Type): - _toSchema = {'keys': 'keys'} - _toPy = {'keys': 'keys'} + _toSchema = {"keys": "keys"} + _toPy = {"keys": "keys"} + def __init__(self, keys=None, **unknown_fields): - ''' + """ keys : typing.Sequence[~ModelUnsetKeys] - ''' + """ keys_ = [ModelUnsetKeys.from_json(o) for o in keys or []] # Validate arguments against known Juju API types. if keys_ is not None and not isinstance(keys_, (bytes, str, list)): - raise Exception("Expected keys_ to be a Sequence, received: {}".format(type(keys_))) + raise Exception( + "Expected keys_ to be a Sequence, received: {}".format(type(keys_)) + ) self.keys = keys_ self.unknown_fields = unknown_fields - class UpdateChannelArg(Type): - _toSchema = {'channel': 'channel', 'force': 'force', 'tag': 'tag'} - _toPy = {'channel': 'channel', 'force': 'force', 'tag': 'tag'} + _toSchema = {"channel": "channel", "force": "force", "tag": "tag"} + _toPy = {"channel": "channel", "force": "force", "tag": "tag"} + def __init__(self, channel=None, force=None, tag=None, **unknown_fields): - ''' + """ channel : str force : bool tag : Entity - ''' + """ channel_ = channel force_ = force tag_ = Entity.from_json(tag) if tag else None # Validate arguments against known Juju API types. if channel_ is not None and not isinstance(channel_, (bytes, str)): - raise Exception("Expected channel_ to be a str, received: {}".format(type(channel_))) + raise Exception( + "Expected channel_ to be a str, received: {}".format(type(channel_)) + ) if force_ is not None and not isinstance(force_, bool): - raise Exception("Expected force_ to be a bool, received: {}".format(type(force_))) + raise Exception( + "Expected force_ to be a bool, received: {}".format(type(force_)) + ) if tag_ is not None and not isinstance(tag_, (dict, Entity)): - raise Exception("Expected tag_ to be a Entity, received: {}".format(type(tag_))) + raise Exception( + "Expected tag_ to be a Entity, received: {}".format(type(tag_)) + ) self.channel = channel_ self.force = force_ @@ -15243,89 +24119,107 @@ def __init__(self, channel=None, force=None, tag=None, **unknown_fields): self.unknown_fields = unknown_fields - class UpdateChannelArgs(Type): - _toSchema = {'args': 'args'} - _toPy = {'args': 'args'} + _toSchema = {"args": "args"} + _toPy = {"args": "args"} + def __init__(self, args=None, **unknown_fields): - ''' + """ args : typing.Sequence[~UpdateChannelArg] - ''' + """ args_ = [UpdateChannelArg.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception("Expected args_ to be a Sequence, received: {}".format(type(args_))) + raise Exception( + "Expected args_ to be a Sequence, received: {}".format(type(args_)) + ) self.args = args_ self.unknown_fields = unknown_fields - class UpdateCloudArgs(Type): - _toSchema = {'clouds': 'clouds'} - _toPy = {'clouds': 'clouds'} + _toSchema = {"clouds": "clouds"} + _toPy = {"clouds": "clouds"} + def __init__(self, clouds=None, **unknown_fields): - ''' + """ clouds : typing.Sequence[~AddCloudArgs] - ''' + """ clouds_ = [AddCloudArgs.from_json(o) for o in clouds or []] # Validate arguments against known Juju API types. if clouds_ is not None and not isinstance(clouds_, (bytes, str, list)): - raise Exception("Expected clouds_ to be a Sequence, received: {}".format(type(clouds_))) + raise Exception( + "Expected clouds_ to be a Sequence, received: {}".format(type(clouds_)) + ) self.clouds = clouds_ self.unknown_fields = unknown_fields - class UpdateCredentialArgs(Type): - _toSchema = {'credentials': 'credentials', 'force': 'force'} - _toPy = {'credentials': 'credentials', 'force': 'force'} + _toSchema = {"credentials": "credentials", "force": "force"} + _toPy = {"credentials": "credentials", "force": "force"} + def __init__(self, credentials=None, force=None, **unknown_fields): - ''' + """ credentials : typing.Sequence[~TaggedCredential] force : bool - ''' + """ credentials_ = [TaggedCredential.from_json(o) for o in credentials or []] force_ = force # Validate arguments against known Juju API types. - if credentials_ is not None and not isinstance(credentials_, (bytes, str, list)): - raise Exception("Expected credentials_ to be a Sequence, received: {}".format(type(credentials_))) + if credentials_ is not None and not isinstance( + credentials_, (bytes, str, list) + ): + raise Exception( + "Expected credentials_ to be a Sequence, received: {}".format( + type(credentials_) + ) + ) if force_ is not None and not isinstance(force_, bool): - raise Exception("Expected force_ to be a bool, received: {}".format(type(force_))) + raise Exception( + "Expected force_ to be a bool, received: {}".format(type(force_)) + ) self.credentials = credentials_ self.force = force_ self.unknown_fields = unknown_fields - class UpdateCredentialModelResult(Type): - _toSchema = {'errors': 'errors', 'name': 'name', 'uuid': 'uuid'} - _toPy = {'errors': 'errors', 'name': 'name', 'uuid': 'uuid'} + _toSchema = {"errors": "errors", "name": "name", "uuid": "uuid"} + _toPy = {"errors": "errors", "name": "name", "uuid": "uuid"} + def __init__(self, errors=None, name=None, uuid=None, **unknown_fields): - ''' + """ errors : typing.Sequence[~ErrorResult] name : str uuid : str - ''' + """ errors_ = [ErrorResult.from_json(o) for o in errors or []] name_ = name uuid_ = uuid # Validate arguments against known Juju API types. if errors_ is not None and not isinstance(errors_, (bytes, str, list)): - raise Exception("Expected errors_ to be a Sequence, received: {}".format(type(errors_))) + raise Exception( + "Expected errors_ to be a Sequence, received: {}".format(type(errors_)) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if uuid_ is not None and not isinstance(uuid_, (bytes, str)): - raise Exception("Expected uuid_ to be a str, received: {}".format(type(uuid_))) + raise Exception( + "Expected uuid_ to be a str, received: {}".format(type(uuid_)) + ) self.errors = errors_ self.name = name_ @@ -15333,29 +24227,35 @@ def __init__(self, errors=None, name=None, uuid=None, **unknown_fields): self.unknown_fields = unknown_fields - class UpdateCredentialResult(Type): - _toSchema = {'error': 'error', 'models': 'models', 'tag': 'tag'} - _toPy = {'error': 'error', 'models': 'models', 'tag': 'tag'} + _toSchema = {"error": "error", "models": "models", "tag": "tag"} + _toPy = {"error": "error", "models": "models", "tag": "tag"} + def __init__(self, error=None, models=None, tag=None, **unknown_fields): - ''' + """ error : Error models : typing.Sequence[~UpdateCredentialModelResult] tag : str - ''' + """ error_ = Error.from_json(error) if error else None models_ = [UpdateCredentialModelResult.from_json(o) for o in models or []] tag_ = tag # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if models_ is not None and not isinstance(models_, (bytes, str, list)): - raise Exception("Expected models_ to be a Sequence, received: {}".format(type(models_))) + raise Exception( + "Expected models_ to be a Sequence, received: {}".format(type(models_)) + ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception("Expected tag_ to be a str, received: {}".format(type(tag_))) + raise Exception( + "Expected tag_ to be a str, received: {}".format(type(tag_)) + ) self.error = error_ self.models = models_ @@ -15363,37 +24263,64 @@ def __init__(self, error=None, models=None, tag=None, **unknown_fields): self.unknown_fields = unknown_fields - class UpdateCredentialResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~UpdateCredentialResult] - ''' + """ results_ = [UpdateCredentialResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class UpdateSecretBackendArg(Type): - _toSchema = {'config': 'config', 'force': 'force', 'name': 'name', 'name_change': 'name-change', 'reset': 'reset', 'token_rotate_interval': 'token-rotate-interval'} - _toPy = {'config': 'config', 'force': 'force', 'name': 'name', 'name-change': 'name_change', 'reset': 'reset', 'token-rotate-interval': 'token_rotate_interval'} - def __init__(self, config=None, force=None, name=None, name_change=None, reset=None, token_rotate_interval=None, **unknown_fields): - ''' + _toSchema = { + "config": "config", + "force": "force", + "name": "name", + "name_change": "name-change", + "reset": "reset", + "token_rotate_interval": "token-rotate-interval", + } + _toPy = { + "config": "config", + "force": "force", + "name": "name", + "name-change": "name_change", + "reset": "reset", + "token-rotate-interval": "token_rotate_interval", + } + + def __init__( + self, + config=None, + force=None, + name=None, + name_change=None, + reset=None, + token_rotate_interval=None, + **unknown_fields, + ): + """ config : typing.Mapping[str, typing.Any] force : bool name : str name_change : str reset : typing.Sequence[str] token_rotate_interval : int - ''' + """ config_ = config force_ = force name_ = name @@ -15403,22 +24330,40 @@ def __init__(self, config=None, force=None, name=None, name_change=None, reset=N # Validate arguments against known Juju API types. if config_ is not None and not isinstance(config_, dict): - raise Exception("Expected config_ to be a Mapping, received: {}".format(type(config_))) + raise Exception( + "Expected config_ to be a Mapping, received: {}".format(type(config_)) + ) if force_ is not None and not isinstance(force_, bool): - raise Exception("Expected force_ to be a bool, received: {}".format(type(force_))) + raise Exception( + "Expected force_ to be a bool, received: {}".format(type(force_)) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) if name_change_ is not None and not isinstance(name_change_, (bytes, str)): - raise Exception("Expected name_change_ to be a str, received: {}".format(type(name_change_))) + raise Exception( + "Expected name_change_ to be a str, received: {}".format( + type(name_change_) + ) + ) if reset_ is not None and not isinstance(reset_, (bytes, str, list)): - raise Exception("Expected reset_ to be a Sequence, received: {}".format(type(reset_))) - - if token_rotate_interval_ is not None and not isinstance(token_rotate_interval_, int): - raise Exception("Expected token_rotate_interval_ to be a int, received: {}".format(type(token_rotate_interval_))) + raise Exception( + "Expected reset_ to be a Sequence, received: {}".format(type(reset_)) + ) + + if token_rotate_interval_ is not None and not isinstance( + token_rotate_interval_, int + ): + raise Exception( + "Expected token_rotate_interval_ to be a int, received: {}".format( + type(token_rotate_interval_) + ) + ) self.config = config_ self.force = force_ @@ -15429,30 +24374,67 @@ def __init__(self, config=None, force=None, name=None, name_change=None, reset=N self.unknown_fields = unknown_fields - class UpdateSecretBackendArgs(Type): - _toSchema = {'args': 'args'} - _toPy = {'args': 'args'} + _toSchema = {"args": "args"} + _toPy = {"args": "args"} + def __init__(self, args=None, **unknown_fields): - ''' + """ args : typing.Sequence[~UpdateSecretBackendArg] - ''' + """ args_ = [UpdateSecretBackendArg.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception("Expected args_ to be a Sequence, received: {}".format(type(args_))) + raise Exception( + "Expected args_ to be a Sequence, received: {}".format(type(args_)) + ) self.args = args_ self.unknown_fields = unknown_fields - class UpdateUserSecretArg(Type): - _toSchema = {'auto_prune': 'auto-prune', 'content': 'content', 'description': 'description', 'existing_label': 'existing-label', 'expire_time': 'expire-time', 'label': 'label', 'params': 'params', 'rotate_policy': 'rotate-policy', 'upsertsecretarg': 'UpsertSecretArg', 'uri': 'uri'} - _toPy = {'UpsertSecretArg': 'upsertsecretarg', 'auto-prune': 'auto_prune', 'content': 'content', 'description': 'description', 'existing-label': 'existing_label', 'expire-time': 'expire_time', 'label': 'label', 'params': 'params', 'rotate-policy': 'rotate_policy', 'uri': 'uri'} - def __init__(self, upsertsecretarg=None, auto_prune=None, content=None, description=None, existing_label=None, expire_time=None, label=None, params=None, rotate_policy=None, uri=None, **unknown_fields): - ''' + _toSchema = { + "auto_prune": "auto-prune", + "content": "content", + "description": "description", + "existing_label": "existing-label", + "expire_time": "expire-time", + "label": "label", + "params": "params", + "rotate_policy": "rotate-policy", + "upsertsecretarg": "UpsertSecretArg", + "uri": "uri", + } + _toPy = { + "UpsertSecretArg": "upsertsecretarg", + "auto-prune": "auto_prune", + "content": "content", + "description": "description", + "existing-label": "existing_label", + "expire-time": "expire_time", + "label": "label", + "params": "params", + "rotate-policy": "rotate_policy", + "uri": "uri", + } + + def __init__( + self, + upsertsecretarg=None, + auto_prune=None, + content=None, + description=None, + existing_label=None, + expire_time=None, + label=None, + params=None, + rotate_policy=None, + uri=None, + **unknown_fields, + ): + """ upsertsecretarg : UpsertSecretArg auto_prune : bool content : SecretContentParams @@ -15463,8 +24445,10 @@ def __init__(self, upsertsecretarg=None, auto_prune=None, content=None, descript params : typing.Mapping[str, typing.Any] rotate_policy : str uri : str - ''' - upsertsecretarg_ = UpsertSecretArg.from_json(upsertsecretarg) if upsertsecretarg else None + """ + upsertsecretarg_ = ( + UpsertSecretArg.from_json(upsertsecretarg) if upsertsecretarg else None + ) auto_prune_ = auto_prune content_ = SecretContentParams.from_json(content) if content else None description_ = description @@ -15476,35 +24460,75 @@ def __init__(self, upsertsecretarg=None, auto_prune=None, content=None, descript uri_ = uri # Validate arguments against known Juju API types. - if upsertsecretarg_ is not None and not isinstance(upsertsecretarg_, (dict, UpsertSecretArg)): - raise Exception("Expected upsertsecretarg_ to be a UpsertSecretArg, received: {}".format(type(upsertsecretarg_))) + if upsertsecretarg_ is not None and not isinstance( + upsertsecretarg_, (dict, UpsertSecretArg) + ): + raise Exception( + "Expected upsertsecretarg_ to be a UpsertSecretArg, received: {}".format( + type(upsertsecretarg_) + ) + ) if auto_prune_ is not None and not isinstance(auto_prune_, bool): - raise Exception("Expected auto_prune_ to be a bool, received: {}".format(type(auto_prune_))) - - if content_ is not None and not isinstance(content_, (dict, SecretContentParams)): - raise Exception("Expected content_ to be a SecretContentParams, received: {}".format(type(content_))) + raise Exception( + "Expected auto_prune_ to be a bool, received: {}".format( + type(auto_prune_) + ) + ) + + if content_ is not None and not isinstance( + content_, (dict, SecretContentParams) + ): + raise Exception( + "Expected content_ to be a SecretContentParams, received: {}".format( + type(content_) + ) + ) if description_ is not None and not isinstance(description_, (bytes, str)): - raise Exception("Expected description_ to be a str, received: {}".format(type(description_))) - - if existing_label_ is not None and not isinstance(existing_label_, (bytes, str)): - raise Exception("Expected existing_label_ to be a str, received: {}".format(type(existing_label_))) + raise Exception( + "Expected description_ to be a str, received: {}".format( + type(description_) + ) + ) + + if existing_label_ is not None and not isinstance( + existing_label_, (bytes, str) + ): + raise Exception( + "Expected existing_label_ to be a str, received: {}".format( + type(existing_label_) + ) + ) if expire_time_ is not None and not isinstance(expire_time_, (bytes, str)): - raise Exception("Expected expire_time_ to be a str, received: {}".format(type(expire_time_))) + raise Exception( + "Expected expire_time_ to be a str, received: {}".format( + type(expire_time_) + ) + ) if label_ is not None and not isinstance(label_, (bytes, str)): - raise Exception("Expected label_ to be a str, received: {}".format(type(label_))) + raise Exception( + "Expected label_ to be a str, received: {}".format(type(label_)) + ) if params_ is not None and not isinstance(params_, dict): - raise Exception("Expected params_ to be a Mapping, received: {}".format(type(params_))) + raise Exception( + "Expected params_ to be a Mapping, received: {}".format(type(params_)) + ) if rotate_policy_ is not None and not isinstance(rotate_policy_, (bytes, str)): - raise Exception("Expected rotate_policy_ to be a str, received: {}".format(type(rotate_policy_))) + raise Exception( + "Expected rotate_policy_ to be a str, received: {}".format( + type(rotate_policy_) + ) + ) if uri_ is not None and not isinstance(uri_, (bytes, str)): - raise Exception("Expected uri_ to be a str, received: {}".format(type(uri_))) + raise Exception( + "Expected uri_ to be a str, received: {}".format(type(uri_)) + ) self.upsertsecretarg = upsertsecretarg_ self.auto_prune = auto_prune_ @@ -15519,36 +24543,58 @@ def __init__(self, upsertsecretarg=None, auto_prune=None, content=None, descript self.unknown_fields = unknown_fields - class UpdateUserSecretArgs(Type): - _toSchema = {'args': 'args'} - _toPy = {'args': 'args'} + _toSchema = {"args": "args"} + _toPy = {"args": "args"} + def __init__(self, args=None, **unknown_fields): - ''' + """ args : typing.Sequence[~UpdateUserSecretArg] - ''' + """ args_ = [UpdateUserSecretArg.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception("Expected args_ to be a Sequence, received: {}".format(type(args_))) + raise Exception( + "Expected args_ to be a Sequence, received: {}".format(type(args_)) + ) self.args = args_ self.unknown_fields = unknown_fields - class UpgradeModelParams(Type): - _toSchema = {'agent_stream': 'agent-stream', 'dry_run': 'dry-run', 'ignore_agent_versions': 'ignore-agent-versions', 'model_tag': 'model-tag', 'target_version': 'target-version'} - _toPy = {'agent-stream': 'agent_stream', 'dry-run': 'dry_run', 'ignore-agent-versions': 'ignore_agent_versions', 'model-tag': 'model_tag', 'target-version': 'target_version'} - def __init__(self, agent_stream=None, dry_run=None, ignore_agent_versions=None, model_tag=None, target_version=None, **unknown_fields): - ''' + _toSchema = { + "agent_stream": "agent-stream", + "dry_run": "dry-run", + "ignore_agent_versions": "ignore-agent-versions", + "model_tag": "model-tag", + "target_version": "target-version", + } + _toPy = { + "agent-stream": "agent_stream", + "dry-run": "dry_run", + "ignore-agent-versions": "ignore_agent_versions", + "model-tag": "model_tag", + "target-version": "target_version", + } + + def __init__( + self, + agent_stream=None, + dry_run=None, + ignore_agent_versions=None, + model_tag=None, + target_version=None, + **unknown_fields, + ): + """ agent_stream : str dry_run : bool ignore_agent_versions : bool model_tag : str target_version : Number - ''' + """ agent_stream_ = agent_stream dry_run_ = dry_run ignore_agent_versions_ = ignore_agent_versions @@ -15557,19 +24603,39 @@ def __init__(self, agent_stream=None, dry_run=None, ignore_agent_versions=None, # Validate arguments against known Juju API types. if agent_stream_ is not None and not isinstance(agent_stream_, (bytes, str)): - raise Exception("Expected agent_stream_ to be a str, received: {}".format(type(agent_stream_))) + raise Exception( + "Expected agent_stream_ to be a str, received: {}".format( + type(agent_stream_) + ) + ) if dry_run_ is not None and not isinstance(dry_run_, bool): - raise Exception("Expected dry_run_ to be a bool, received: {}".format(type(dry_run_))) - - if ignore_agent_versions_ is not None and not isinstance(ignore_agent_versions_, bool): - raise Exception("Expected ignore_agent_versions_ to be a bool, received: {}".format(type(ignore_agent_versions_))) + raise Exception( + "Expected dry_run_ to be a bool, received: {}".format(type(dry_run_)) + ) + + if ignore_agent_versions_ is not None and not isinstance( + ignore_agent_versions_, bool + ): + raise Exception( + "Expected ignore_agent_versions_ to be a bool, received: {}".format( + type(ignore_agent_versions_) + ) + ) if model_tag_ is not None and not isinstance(model_tag_, (bytes, str)): - raise Exception("Expected model_tag_ to be a str, received: {}".format(type(model_tag_))) - - if target_version_ is not None and not isinstance(target_version_, (dict, Number)): - raise Exception("Expected target_version_ to be a Number, received: {}".format(type(target_version_))) + raise Exception( + "Expected model_tag_ to be a str, received: {}".format(type(model_tag_)) + ) + + if target_version_ is not None and not isinstance( + target_version_, (dict, Number) + ): + raise Exception( + "Expected target_version_ to be a Number, received: {}".format( + type(target_version_) + ) + ) self.agent_stream = agent_stream_ self.dry_run = dry_run_ @@ -15579,127 +24645,176 @@ def __init__(self, agent_stream=None, dry_run=None, ignore_agent_versions=None, self.unknown_fields = unknown_fields - class UpgradeModelResult(Type): - _toSchema = {'chosen_version': 'chosen-version', 'error': 'error'} - _toPy = {'chosen-version': 'chosen_version', 'error': 'error'} + _toSchema = {"chosen_version": "chosen-version", "error": "error"} + _toPy = {"chosen-version": "chosen_version", "error": "error"} + def __init__(self, chosen_version=None, error=None, **unknown_fields): - ''' + """ chosen_version : Number error : Error - ''' + """ chosen_version_ = Number.from_json(chosen_version) if chosen_version else None error_ = Error.from_json(error) if error else None # Validate arguments against known Juju API types. - if chosen_version_ is not None and not isinstance(chosen_version_, (dict, Number)): - raise Exception("Expected chosen_version_ to be a Number, received: {}".format(type(chosen_version_))) + if chosen_version_ is not None and not isinstance( + chosen_version_, (dict, Number) + ): + raise Exception( + "Expected chosen_version_ to be a Number, received: {}".format( + type(chosen_version_) + ) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) self.chosen_version = chosen_version_ self.error = error_ self.unknown_fields = unknown_fields - class UpgradeSeriesNotificationParam(Type): - _toSchema = {'entity': 'entity', 'watcher_id': 'watcher-id'} - _toPy = {'entity': 'entity', 'watcher-id': 'watcher_id'} + _toSchema = {"entity": "entity", "watcher_id": "watcher-id"} + _toPy = {"entity": "entity", "watcher-id": "watcher_id"} + def __init__(self, entity=None, watcher_id=None, **unknown_fields): - ''' + """ entity : Entity watcher_id : str - ''' + """ entity_ = Entity.from_json(entity) if entity else None watcher_id_ = watcher_id # Validate arguments against known Juju API types. if entity_ is not None and not isinstance(entity_, (dict, Entity)): - raise Exception("Expected entity_ to be a Entity, received: {}".format(type(entity_))) + raise Exception( + "Expected entity_ to be a Entity, received: {}".format(type(entity_)) + ) if watcher_id_ is not None and not isinstance(watcher_id_, (bytes, str)): - raise Exception("Expected watcher_id_ to be a str, received: {}".format(type(watcher_id_))) + raise Exception( + "Expected watcher_id_ to be a str, received: {}".format( + type(watcher_id_) + ) + ) self.entity = entity_ self.watcher_id = watcher_id_ self.unknown_fields = unknown_fields - class UpgradeSeriesNotificationParams(Type): - _toSchema = {'params': 'params'} - _toPy = {'params': 'params'} + _toSchema = {"params": "params"} + _toPy = {"params": "params"} + def __init__(self, params=None, **unknown_fields): - ''' + """ params : typing.Sequence[~UpgradeSeriesNotificationParam] - ''' + """ params_ = [UpgradeSeriesNotificationParam.from_json(o) for o in params or []] # Validate arguments against known Juju API types. if params_ is not None and not isinstance(params_, (bytes, str, list)): - raise Exception("Expected params_ to be a Sequence, received: {}".format(type(params_))) + raise Exception( + "Expected params_ to be a Sequence, received: {}".format(type(params_)) + ) self.params = params_ self.unknown_fields = unknown_fields - class UpgradeSeriesUnitsResult(Type): - _toSchema = {'error': 'error', 'unit_names': 'unit-names'} - _toPy = {'error': 'error', 'unit-names': 'unit_names'} + _toSchema = {"error": "error", "unit_names": "unit-names"} + _toPy = {"error": "error", "unit-names": "unit_names"} + def __init__(self, error=None, unit_names=None, **unknown_fields): - ''' + """ error : Error unit_names : typing.Sequence[str] - ''' + """ error_ = Error.from_json(error) if error else None unit_names_ = unit_names # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if unit_names_ is not None and not isinstance(unit_names_, (bytes, str, list)): - raise Exception("Expected unit_names_ to be a Sequence, received: {}".format(type(unit_names_))) + raise Exception( + "Expected unit_names_ to be a Sequence, received: {}".format( + type(unit_names_) + ) + ) self.error = error_ self.unit_names = unit_names_ self.unknown_fields = unknown_fields - class UpgradeSeriesUnitsResults(Type): - _toSchema = {'results': 'Results'} - _toPy = {'Results': 'results'} + _toSchema = {"results": "Results"} + _toPy = {"Results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~UpgradeSeriesUnitsResult] - ''' + """ results_ = [UpgradeSeriesUnitsResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class UpsertSecretArg(Type): - _toSchema = {'content': 'content', 'description': 'description', 'expire_time': 'expire-time', 'label': 'label', 'params': 'params', 'rotate_policy': 'rotate-policy'} - _toPy = {'content': 'content', 'description': 'description', 'expire-time': 'expire_time', 'label': 'label', 'params': 'params', 'rotate-policy': 'rotate_policy'} - def __init__(self, content=None, description=None, expire_time=None, label=None, params=None, rotate_policy=None, **unknown_fields): - ''' + _toSchema = { + "content": "content", + "description": "description", + "expire_time": "expire-time", + "label": "label", + "params": "params", + "rotate_policy": "rotate-policy", + } + _toPy = { + "content": "content", + "description": "description", + "expire-time": "expire_time", + "label": "label", + "params": "params", + "rotate-policy": "rotate_policy", + } + + def __init__( + self, + content=None, + description=None, + expire_time=None, + label=None, + params=None, + rotate_policy=None, + **unknown_fields, + ): + """ content : SecretContentParams description : str expire_time : str label : str params : typing.Mapping[str, typing.Any] rotate_policy : str - ''' + """ content_ = SecretContentParams.from_json(content) if content else None description_ = description expire_time_ = expire_time @@ -15708,23 +24823,45 @@ def __init__(self, content=None, description=None, expire_time=None, label=None, rotate_policy_ = rotate_policy # Validate arguments against known Juju API types. - if content_ is not None and not isinstance(content_, (dict, SecretContentParams)): - raise Exception("Expected content_ to be a SecretContentParams, received: {}".format(type(content_))) + if content_ is not None and not isinstance( + content_, (dict, SecretContentParams) + ): + raise Exception( + "Expected content_ to be a SecretContentParams, received: {}".format( + type(content_) + ) + ) if description_ is not None and not isinstance(description_, (bytes, str)): - raise Exception("Expected description_ to be a str, received: {}".format(type(description_))) + raise Exception( + "Expected description_ to be a str, received: {}".format( + type(description_) + ) + ) if expire_time_ is not None and not isinstance(expire_time_, (bytes, str)): - raise Exception("Expected expire_time_ to be a str, received: {}".format(type(expire_time_))) + raise Exception( + "Expected expire_time_ to be a str, received: {}".format( + type(expire_time_) + ) + ) if label_ is not None and not isinstance(label_, (bytes, str)): - raise Exception("Expected label_ to be a str, received: {}".format(type(label_))) + raise Exception( + "Expected label_ to be a str, received: {}".format(type(label_)) + ) if params_ is not None and not isinstance(params_, dict): - raise Exception("Expected params_ to be a Mapping, received: {}".format(type(params_))) + raise Exception( + "Expected params_ to be a Mapping, received: {}".format(type(params_)) + ) if rotate_policy_ is not None and not isinstance(rotate_policy_, (bytes, str)): - raise Exception("Expected rotate_policy_ to be a str, received: {}".format(type(rotate_policy_))) + raise Exception( + "Expected rotate_policy_ to be a str, received: {}".format( + type(rotate_policy_) + ) + ) self.content = content_ self.description = description_ @@ -15735,120 +24872,170 @@ def __init__(self, content=None, description=None, expire_time=None, label=None, self.unknown_fields = unknown_fields - class UserAccess(Type): - _toSchema = {'access': 'access', 'user_tag': 'user-tag'} - _toPy = {'access': 'access', 'user-tag': 'user_tag'} + _toSchema = {"access": "access", "user_tag": "user-tag"} + _toPy = {"access": "access", "user-tag": "user_tag"} + def __init__(self, access=None, user_tag=None, **unknown_fields): - ''' + """ access : str user_tag : str - ''' + """ access_ = access user_tag_ = user_tag # Validate arguments against known Juju API types. if access_ is not None and not isinstance(access_, (bytes, str)): - raise Exception("Expected access_ to be a str, received: {}".format(type(access_))) + raise Exception( + "Expected access_ to be a str, received: {}".format(type(access_)) + ) if user_tag_ is not None and not isinstance(user_tag_, (bytes, str)): - raise Exception("Expected user_tag_ to be a str, received: {}".format(type(user_tag_))) + raise Exception( + "Expected user_tag_ to be a str, received: {}".format(type(user_tag_)) + ) self.access = access_ self.user_tag = user_tag_ self.unknown_fields = unknown_fields - class UserAccessResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : UserAccess - ''' + """ error_ = Error.from_json(error) if error else None result_ = UserAccess.from_json(result) if result else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if result_ is not None and not isinstance(result_, (dict, UserAccess)): - raise Exception("Expected result_ to be a UserAccess, received: {}".format(type(result_))) + raise Exception( + "Expected result_ to be a UserAccess, received: {}".format( + type(result_) + ) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class UserAccessResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~UserAccessResult] - ''' + """ results_ = [UserAccessResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class UserCloud(Type): - _toSchema = {'cloud_tag': 'cloud-tag', 'user_tag': 'user-tag'} - _toPy = {'cloud-tag': 'cloud_tag', 'user-tag': 'user_tag'} + _toSchema = {"cloud_tag": "cloud-tag", "user_tag": "user-tag"} + _toPy = {"cloud-tag": "cloud_tag", "user-tag": "user_tag"} + def __init__(self, cloud_tag=None, user_tag=None, **unknown_fields): - ''' + """ cloud_tag : str user_tag : str - ''' + """ cloud_tag_ = cloud_tag user_tag_ = user_tag # Validate arguments against known Juju API types. if cloud_tag_ is not None and not isinstance(cloud_tag_, (bytes, str)): - raise Exception("Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_))) + raise Exception( + "Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_)) + ) if user_tag_ is not None and not isinstance(user_tag_, (bytes, str)): - raise Exception("Expected user_tag_ to be a str, received: {}".format(type(user_tag_))) + raise Exception( + "Expected user_tag_ to be a str, received: {}".format(type(user_tag_)) + ) self.cloud_tag = cloud_tag_ self.user_tag = user_tag_ self.unknown_fields = unknown_fields - class UserClouds(Type): - _toSchema = {'user_clouds': 'user-clouds'} - _toPy = {'user-clouds': 'user_clouds'} + _toSchema = {"user_clouds": "user-clouds"} + _toPy = {"user-clouds": "user_clouds"} + def __init__(self, user_clouds=None, **unknown_fields): - ''' + """ user_clouds : typing.Sequence[~UserCloud] - ''' + """ user_clouds_ = [UserCloud.from_json(o) for o in user_clouds or []] # Validate arguments against known Juju API types. - if user_clouds_ is not None and not isinstance(user_clouds_, (bytes, str, list)): - raise Exception("Expected user_clouds_ to be a Sequence, received: {}".format(type(user_clouds_))) + if user_clouds_ is not None and not isinstance( + user_clouds_, (bytes, str, list) + ): + raise Exception( + "Expected user_clouds_ to be a Sequence, received: {}".format( + type(user_clouds_) + ) + ) self.user_clouds = user_clouds_ self.unknown_fields = unknown_fields - class UserInfo(Type): - _toSchema = {'access': 'access', 'created_by': 'created-by', 'date_created': 'date-created', 'disabled': 'disabled', 'display_name': 'display-name', 'last_connection': 'last-connection', 'username': 'username'} - _toPy = {'access': 'access', 'created-by': 'created_by', 'date-created': 'date_created', 'disabled': 'disabled', 'display-name': 'display_name', 'last-connection': 'last_connection', 'username': 'username'} - def __init__(self, access=None, created_by=None, date_created=None, disabled=None, display_name=None, last_connection=None, username=None, **unknown_fields): - ''' + _toSchema = { + "access": "access", + "created_by": "created-by", + "date_created": "date-created", + "disabled": "disabled", + "display_name": "display-name", + "last_connection": "last-connection", + "username": "username", + } + _toPy = { + "access": "access", + "created-by": "created_by", + "date-created": "date_created", + "disabled": "disabled", + "display-name": "display_name", + "last-connection": "last_connection", + "username": "username", + } + + def __init__( + self, + access=None, + created_by=None, + date_created=None, + disabled=None, + display_name=None, + last_connection=None, + username=None, + **unknown_fields, + ): + """ access : str created_by : str date_created : str @@ -15856,7 +25043,7 @@ def __init__(self, access=None, created_by=None, date_created=None, disabled=Non display_name : str last_connection : str username : str - ''' + """ access_ = access created_by_ = created_by date_created_ = date_created @@ -15867,25 +25054,49 @@ def __init__(self, access=None, created_by=None, date_created=None, disabled=Non # Validate arguments against known Juju API types. if access_ is not None and not isinstance(access_, (bytes, str)): - raise Exception("Expected access_ to be a str, received: {}".format(type(access_))) + raise Exception( + "Expected access_ to be a str, received: {}".format(type(access_)) + ) if created_by_ is not None and not isinstance(created_by_, (bytes, str)): - raise Exception("Expected created_by_ to be a str, received: {}".format(type(created_by_))) + raise Exception( + "Expected created_by_ to be a str, received: {}".format( + type(created_by_) + ) + ) if date_created_ is not None and not isinstance(date_created_, (bytes, str)): - raise Exception("Expected date_created_ to be a str, received: {}".format(type(date_created_))) + raise Exception( + "Expected date_created_ to be a str, received: {}".format( + type(date_created_) + ) + ) if disabled_ is not None and not isinstance(disabled_, bool): - raise Exception("Expected disabled_ to be a bool, received: {}".format(type(disabled_))) + raise Exception( + "Expected disabled_ to be a bool, received: {}".format(type(disabled_)) + ) if display_name_ is not None and not isinstance(display_name_, (bytes, str)): - raise Exception("Expected display_name_ to be a str, received: {}".format(type(display_name_))) - - if last_connection_ is not None and not isinstance(last_connection_, (bytes, str)): - raise Exception("Expected last_connection_ to be a str, received: {}".format(type(last_connection_))) + raise Exception( + "Expected display_name_ to be a str, received: {}".format( + type(display_name_) + ) + ) + + if last_connection_ is not None and not isinstance( + last_connection_, (bytes, str) + ): + raise Exception( + "Expected last_connection_ to be a str, received: {}".format( + type(last_connection_) + ) + ) if username_ is not None and not isinstance(username_, (bytes, str)): - raise Exception("Expected username_ to be a str, received: {}".format(type(username_))) + raise Exception( + "Expected username_ to be a str, received: {}".format(type(username_)) + ) self.access = access_ self.created_by = created_by_ @@ -15897,120 +25108,200 @@ def __init__(self, access=None, created_by=None, date_created=None, disabled=Non self.unknown_fields = unknown_fields - class UserInfoRequest(Type): - _toSchema = {'entities': 'entities', 'include_disabled': 'include-disabled'} - _toPy = {'entities': 'entities', 'include-disabled': 'include_disabled'} + _toSchema = {"entities": "entities", "include_disabled": "include-disabled"} + _toPy = {"entities": "entities", "include-disabled": "include_disabled"} + def __init__(self, entities=None, include_disabled=None, **unknown_fields): - ''' + """ entities : typing.Sequence[~Entity] include_disabled : bool - ''' + """ entities_ = [Entity.from_json(o) for o in entities or []] include_disabled_ = include_disabled # Validate arguments against known Juju API types. if entities_ is not None and not isinstance(entities_, (bytes, str, list)): - raise Exception("Expected entities_ to be a Sequence, received: {}".format(type(entities_))) + raise Exception( + "Expected entities_ to be a Sequence, received: {}".format( + type(entities_) + ) + ) if include_disabled_ is not None and not isinstance(include_disabled_, bool): - raise Exception("Expected include_disabled_ to be a bool, received: {}".format(type(include_disabled_))) + raise Exception( + "Expected include_disabled_ to be a bool, received: {}".format( + type(include_disabled_) + ) + ) self.entities = entities_ self.include_disabled = include_disabled_ self.unknown_fields = unknown_fields - class UserInfoResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : UserInfo - ''' + """ error_ = Error.from_json(error) if error else None result_ = UserInfo.from_json(result) if result else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if result_ is not None and not isinstance(result_, (dict, UserInfo)): - raise Exception("Expected result_ to be a UserInfo, received: {}".format(type(result_))) + raise Exception( + "Expected result_ to be a UserInfo, received: {}".format(type(result_)) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class UserInfoResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~UserInfoResult] - ''' + """ results_ = [UserInfoResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class UserModel(Type): - _toSchema = {'last_connection': 'last-connection', 'model': 'model'} - _toPy = {'last-connection': 'last_connection', 'model': 'model'} + _toSchema = {"last_connection": "last-connection", "model": "model"} + _toPy = {"last-connection": "last_connection", "model": "model"} + def __init__(self, last_connection=None, model=None, **unknown_fields): - ''' + """ last_connection : str model : Model - ''' + """ last_connection_ = last_connection model_ = Model.from_json(model) if model else None # Validate arguments against known Juju API types. - if last_connection_ is not None and not isinstance(last_connection_, (bytes, str)): - raise Exception("Expected last_connection_ to be a str, received: {}".format(type(last_connection_))) + if last_connection_ is not None and not isinstance( + last_connection_, (bytes, str) + ): + raise Exception( + "Expected last_connection_ to be a str, received: {}".format( + type(last_connection_) + ) + ) if model_ is not None and not isinstance(model_, (dict, Model)): - raise Exception("Expected model_ to be a Model, received: {}".format(type(model_))) + raise Exception( + "Expected model_ to be a Model, received: {}".format(type(model_)) + ) self.last_connection = last_connection_ self.model = model_ self.unknown_fields = unknown_fields - class UserModelList(Type): - _toSchema = {'user_models': 'user-models'} - _toPy = {'user-models': 'user_models'} + _toSchema = {"user_models": "user-models"} + _toPy = {"user-models": "user_models"} + def __init__(self, user_models=None, **unknown_fields): - ''' + """ user_models : typing.Sequence[~UserModel] - ''' + """ user_models_ = [UserModel.from_json(o) for o in user_models or []] # Validate arguments against known Juju API types. - if user_models_ is not None and not isinstance(user_models_, (bytes, str, list)): - raise Exception("Expected user_models_ to be a Sequence, received: {}".format(type(user_models_))) + if user_models_ is not None and not isinstance( + user_models_, (bytes, str, list) + ): + raise Exception( + "Expected user_models_ to be a Sequence, received: {}".format( + type(user_models_) + ) + ) self.user_models = user_models_ self.unknown_fields = unknown_fields - class Value(Type): - _toSchema = {'allocate_public_ip': 'allocate-public-ip', 'arch': 'arch', 'container': 'container', 'cores': 'cores', 'cpu_power': 'cpu-power', 'image_id': 'image-id', 'instance_role': 'instance-role', 'instance_type': 'instance-type', 'mem': 'mem', 'root_disk': 'root-disk', 'root_disk_source': 'root-disk-source', 'spaces': 'spaces', 'tags': 'tags', 'virt_type': 'virt-type', 'zones': 'zones'} - _toPy = {'allocate-public-ip': 'allocate_public_ip', 'arch': 'arch', 'container': 'container', 'cores': 'cores', 'cpu-power': 'cpu_power', 'image-id': 'image_id', 'instance-role': 'instance_role', 'instance-type': 'instance_type', 'mem': 'mem', 'root-disk': 'root_disk', 'root-disk-source': 'root_disk_source', 'spaces': 'spaces', 'tags': 'tags', 'virt-type': 'virt_type', 'zones': 'zones'} - def __init__(self, allocate_public_ip=None, arch=None, container=None, cores=None, cpu_power=None, image_id=None, instance_role=None, instance_type=None, mem=None, root_disk=None, root_disk_source=None, spaces=None, tags=None, virt_type=None, zones=None, **unknown_fields): - ''' + _toSchema = { + "allocate_public_ip": "allocate-public-ip", + "arch": "arch", + "container": "container", + "cores": "cores", + "cpu_power": "cpu-power", + "image_id": "image-id", + "instance_role": "instance-role", + "instance_type": "instance-type", + "mem": "mem", + "root_disk": "root-disk", + "root_disk_source": "root-disk-source", + "spaces": "spaces", + "tags": "tags", + "virt_type": "virt-type", + "zones": "zones", + } + _toPy = { + "allocate-public-ip": "allocate_public_ip", + "arch": "arch", + "container": "container", + "cores": "cores", + "cpu-power": "cpu_power", + "image-id": "image_id", + "instance-role": "instance_role", + "instance-type": "instance_type", + "mem": "mem", + "root-disk": "root_disk", + "root-disk-source": "root_disk_source", + "spaces": "spaces", + "tags": "tags", + "virt-type": "virt_type", + "zones": "zones", + } + + def __init__( + self, + allocate_public_ip=None, + arch=None, + container=None, + cores=None, + cpu_power=None, + image_id=None, + instance_role=None, + instance_type=None, + mem=None, + root_disk=None, + root_disk_source=None, + spaces=None, + tags=None, + virt_type=None, + zones=None, + **unknown_fields, + ): + """ allocate_public_ip : bool arch : str container : str @@ -16026,7 +25317,7 @@ def __init__(self, allocate_public_ip=None, arch=None, container=None, cores=Non tags : typing.Sequence[str] virt_type : str zones : typing.Sequence[str] - ''' + """ allocate_public_ip_ = allocate_public_ip arch_ = arch container_ = container @@ -16044,50 +25335,92 @@ def __init__(self, allocate_public_ip=None, arch=None, container=None, cores=Non zones_ = zones # Validate arguments against known Juju API types. - if allocate_public_ip_ is not None and not isinstance(allocate_public_ip_, bool): - raise Exception("Expected allocate_public_ip_ to be a bool, received: {}".format(type(allocate_public_ip_))) + if allocate_public_ip_ is not None and not isinstance( + allocate_public_ip_, bool + ): + raise Exception( + "Expected allocate_public_ip_ to be a bool, received: {}".format( + type(allocate_public_ip_) + ) + ) if arch_ is not None and not isinstance(arch_, (bytes, str)): - raise Exception("Expected arch_ to be a str, received: {}".format(type(arch_))) + raise Exception( + "Expected arch_ to be a str, received: {}".format(type(arch_)) + ) if container_ is not None and not isinstance(container_, (bytes, str)): - raise Exception("Expected container_ to be a str, received: {}".format(type(container_))) + raise Exception( + "Expected container_ to be a str, received: {}".format(type(container_)) + ) if cores_ is not None and not isinstance(cores_, int): - raise Exception("Expected cores_ to be a int, received: {}".format(type(cores_))) + raise Exception( + "Expected cores_ to be a int, received: {}".format(type(cores_)) + ) if cpu_power_ is not None and not isinstance(cpu_power_, int): - raise Exception("Expected cpu_power_ to be a int, received: {}".format(type(cpu_power_))) + raise Exception( + "Expected cpu_power_ to be a int, received: {}".format(type(cpu_power_)) + ) if image_id_ is not None and not isinstance(image_id_, (bytes, str)): - raise Exception("Expected image_id_ to be a str, received: {}".format(type(image_id_))) + raise Exception( + "Expected image_id_ to be a str, received: {}".format(type(image_id_)) + ) if instance_role_ is not None and not isinstance(instance_role_, (bytes, str)): - raise Exception("Expected instance_role_ to be a str, received: {}".format(type(instance_role_))) + raise Exception( + "Expected instance_role_ to be a str, received: {}".format( + type(instance_role_) + ) + ) if instance_type_ is not None and not isinstance(instance_type_, (bytes, str)): - raise Exception("Expected instance_type_ to be a str, received: {}".format(type(instance_type_))) + raise Exception( + "Expected instance_type_ to be a str, received: {}".format( + type(instance_type_) + ) + ) if mem_ is not None and not isinstance(mem_, int): - raise Exception("Expected mem_ to be a int, received: {}".format(type(mem_))) + raise Exception( + "Expected mem_ to be a int, received: {}".format(type(mem_)) + ) if root_disk_ is not None and not isinstance(root_disk_, int): - raise Exception("Expected root_disk_ to be a int, received: {}".format(type(root_disk_))) - - if root_disk_source_ is not None and not isinstance(root_disk_source_, (bytes, str)): - raise Exception("Expected root_disk_source_ to be a str, received: {}".format(type(root_disk_source_))) + raise Exception( + "Expected root_disk_ to be a int, received: {}".format(type(root_disk_)) + ) + + if root_disk_source_ is not None and not isinstance( + root_disk_source_, (bytes, str) + ): + raise Exception( + "Expected root_disk_source_ to be a str, received: {}".format( + type(root_disk_source_) + ) + ) if spaces_ is not None and not isinstance(spaces_, (bytes, str, list)): - raise Exception("Expected spaces_ to be a Sequence, received: {}".format(type(spaces_))) + raise Exception( + "Expected spaces_ to be a Sequence, received: {}".format(type(spaces_)) + ) if tags_ is not None and not isinstance(tags_, (bytes, str, list)): - raise Exception("Expected tags_ to be a Sequence, received: {}".format(type(tags_))) + raise Exception( + "Expected tags_ to be a Sequence, received: {}".format(type(tags_)) + ) if virt_type_ is not None and not isinstance(virt_type_, (bytes, str)): - raise Exception("Expected virt_type_ to be a str, received: {}".format(type(virt_type_))) + raise Exception( + "Expected virt_type_ to be a str, received: {}".format(type(virt_type_)) + ) if zones_ is not None and not isinstance(zones_, (bytes, str, list)): - raise Exception("Expected zones_ to be a Sequence, received: {}".format(type(zones_))) + raise Exception( + "Expected zones_ to be a Sequence, received: {}".format(type(zones_)) + ) self.allocate_public_ip = allocate_public_ip_ self.arch = arch_ @@ -16107,12 +25440,38 @@ def __init__(self, allocate_public_ip=None, arch=None, container=None, cores=Non self.unknown_fields = unknown_fields - class VolumeAttachmentDetails(Type): - _toSchema = {'bus_address': 'bus-address', 'device_link': 'device-link', 'device_name': 'device-name', 'life': 'life', 'plan_info': 'plan-info', 'read_only': 'read-only', 'volumeattachmentinfo': 'VolumeAttachmentInfo'} - _toPy = {'VolumeAttachmentInfo': 'volumeattachmentinfo', 'bus-address': 'bus_address', 'device-link': 'device_link', 'device-name': 'device_name', 'life': 'life', 'plan-info': 'plan_info', 'read-only': 'read_only'} - def __init__(self, volumeattachmentinfo=None, bus_address=None, device_link=None, device_name=None, life=None, plan_info=None, read_only=None, **unknown_fields): - ''' + _toSchema = { + "bus_address": "bus-address", + "device_link": "device-link", + "device_name": "device-name", + "life": "life", + "plan_info": "plan-info", + "read_only": "read-only", + "volumeattachmentinfo": "VolumeAttachmentInfo", + } + _toPy = { + "VolumeAttachmentInfo": "volumeattachmentinfo", + "bus-address": "bus_address", + "device-link": "device_link", + "device-name": "device_name", + "life": "life", + "plan-info": "plan_info", + "read-only": "read_only", + } + + def __init__( + self, + volumeattachmentinfo=None, + bus_address=None, + device_link=None, + device_name=None, + life=None, + plan_info=None, + read_only=None, + **unknown_fields, + ): + """ volumeattachmentinfo : VolumeAttachmentInfo bus_address : str device_link : str @@ -16120,36 +25479,72 @@ def __init__(self, volumeattachmentinfo=None, bus_address=None, device_link=None life : str plan_info : VolumeAttachmentPlanInfo read_only : bool - ''' - volumeattachmentinfo_ = VolumeAttachmentInfo.from_json(volumeattachmentinfo) if volumeattachmentinfo else None + """ + volumeattachmentinfo_ = ( + VolumeAttachmentInfo.from_json(volumeattachmentinfo) + if volumeattachmentinfo + else None + ) bus_address_ = bus_address device_link_ = device_link device_name_ = device_name life_ = life - plan_info_ = VolumeAttachmentPlanInfo.from_json(plan_info) if plan_info else None + plan_info_ = ( + VolumeAttachmentPlanInfo.from_json(plan_info) if plan_info else None + ) read_only_ = read_only # Validate arguments against known Juju API types. - if volumeattachmentinfo_ is not None and not isinstance(volumeattachmentinfo_, (dict, VolumeAttachmentInfo)): - raise Exception("Expected volumeattachmentinfo_ to be a VolumeAttachmentInfo, received: {}".format(type(volumeattachmentinfo_))) + if volumeattachmentinfo_ is not None and not isinstance( + volumeattachmentinfo_, (dict, VolumeAttachmentInfo) + ): + raise Exception( + "Expected volumeattachmentinfo_ to be a VolumeAttachmentInfo, received: {}".format( + type(volumeattachmentinfo_) + ) + ) if bus_address_ is not None and not isinstance(bus_address_, (bytes, str)): - raise Exception("Expected bus_address_ to be a str, received: {}".format(type(bus_address_))) + raise Exception( + "Expected bus_address_ to be a str, received: {}".format( + type(bus_address_) + ) + ) if device_link_ is not None and not isinstance(device_link_, (bytes, str)): - raise Exception("Expected device_link_ to be a str, received: {}".format(type(device_link_))) + raise Exception( + "Expected device_link_ to be a str, received: {}".format( + type(device_link_) + ) + ) if device_name_ is not None and not isinstance(device_name_, (bytes, str)): - raise Exception("Expected device_name_ to be a str, received: {}".format(type(device_name_))) + raise Exception( + "Expected device_name_ to be a str, received: {}".format( + type(device_name_) + ) + ) if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception("Expected life_ to be a str, received: {}".format(type(life_))) - - if plan_info_ is not None and not isinstance(plan_info_, (dict, VolumeAttachmentPlanInfo)): - raise Exception("Expected plan_info_ to be a VolumeAttachmentPlanInfo, received: {}".format(type(plan_info_))) + raise Exception( + "Expected life_ to be a str, received: {}".format(type(life_)) + ) + + if plan_info_ is not None and not isinstance( + plan_info_, (dict, VolumeAttachmentPlanInfo) + ): + raise Exception( + "Expected plan_info_ to be a VolumeAttachmentPlanInfo, received: {}".format( + type(plan_info_) + ) + ) if read_only_ is not None and not isinstance(read_only_, bool): - raise Exception("Expected read_only_ to be a bool, received: {}".format(type(read_only_))) + raise Exception( + "Expected read_only_ to be a bool, received: {}".format( + type(read_only_) + ) + ) self.volumeattachmentinfo = volumeattachmentinfo_ self.bus_address = bus_address_ @@ -16161,39 +25556,83 @@ def __init__(self, volumeattachmentinfo=None, bus_address=None, device_link=None self.unknown_fields = unknown_fields - class VolumeAttachmentInfo(Type): - _toSchema = {'bus_address': 'bus-address', 'device_link': 'device-link', 'device_name': 'device-name', 'plan_info': 'plan-info', 'read_only': 'read-only'} - _toPy = {'bus-address': 'bus_address', 'device-link': 'device_link', 'device-name': 'device_name', 'plan-info': 'plan_info', 'read-only': 'read_only'} - def __init__(self, bus_address=None, device_link=None, device_name=None, plan_info=None, read_only=None, **unknown_fields): - ''' + _toSchema = { + "bus_address": "bus-address", + "device_link": "device-link", + "device_name": "device-name", + "plan_info": "plan-info", + "read_only": "read-only", + } + _toPy = { + "bus-address": "bus_address", + "device-link": "device_link", + "device-name": "device_name", + "plan-info": "plan_info", + "read-only": "read_only", + } + + def __init__( + self, + bus_address=None, + device_link=None, + device_name=None, + plan_info=None, + read_only=None, + **unknown_fields, + ): + """ bus_address : str device_link : str device_name : str plan_info : VolumeAttachmentPlanInfo read_only : bool - ''' + """ bus_address_ = bus_address device_link_ = device_link device_name_ = device_name - plan_info_ = VolumeAttachmentPlanInfo.from_json(plan_info) if plan_info else None + plan_info_ = ( + VolumeAttachmentPlanInfo.from_json(plan_info) if plan_info else None + ) read_only_ = read_only # Validate arguments against known Juju API types. if bus_address_ is not None and not isinstance(bus_address_, (bytes, str)): - raise Exception("Expected bus_address_ to be a str, received: {}".format(type(bus_address_))) + raise Exception( + "Expected bus_address_ to be a str, received: {}".format( + type(bus_address_) + ) + ) if device_link_ is not None and not isinstance(device_link_, (bytes, str)): - raise Exception("Expected device_link_ to be a str, received: {}".format(type(device_link_))) + raise Exception( + "Expected device_link_ to be a str, received: {}".format( + type(device_link_) + ) + ) if device_name_ is not None and not isinstance(device_name_, (bytes, str)): - raise Exception("Expected device_name_ to be a str, received: {}".format(type(device_name_))) - - if plan_info_ is not None and not isinstance(plan_info_, (dict, VolumeAttachmentPlanInfo)): - raise Exception("Expected plan_info_ to be a VolumeAttachmentPlanInfo, received: {}".format(type(plan_info_))) + raise Exception( + "Expected device_name_ to be a str, received: {}".format( + type(device_name_) + ) + ) + + if plan_info_ is not None and not isinstance( + plan_info_, (dict, VolumeAttachmentPlanInfo) + ): + raise Exception( + "Expected plan_info_ to be a VolumeAttachmentPlanInfo, received: {}".format( + type(plan_info_) + ) + ) if read_only_ is not None and not isinstance(read_only_, bool): - raise Exception("Expected read_only_ to be a bool, received: {}".format(type(read_only_))) + raise Exception( + "Expected read_only_ to be a bool, received: {}".format( + type(read_only_) + ) + ) self.bus_address = bus_address_ self.device_link = device_link_ @@ -16203,36 +25642,70 @@ def __init__(self, bus_address=None, device_link=None, device_name=None, plan_in self.unknown_fields = unknown_fields - class VolumeAttachmentPlanInfo(Type): - _toSchema = {'device_attributes': 'device-attributes', 'device_type': 'device-type'} - _toPy = {'device-attributes': 'device_attributes', 'device-type': 'device_type'} + _toSchema = {"device_attributes": "device-attributes", "device_type": "device-type"} + _toPy = {"device-attributes": "device_attributes", "device-type": "device_type"} + def __init__(self, device_attributes=None, device_type=None, **unknown_fields): - ''' + """ device_attributes : typing.Mapping[str, str] device_type : str - ''' + """ device_attributes_ = device_attributes device_type_ = device_type # Validate arguments against known Juju API types. if device_attributes_ is not None and not isinstance(device_attributes_, dict): - raise Exception("Expected device_attributes_ to be a Mapping, received: {}".format(type(device_attributes_))) + raise Exception( + "Expected device_attributes_ to be a Mapping, received: {}".format( + type(device_attributes_) + ) + ) if device_type_ is not None and not isinstance(device_type_, (bytes, str)): - raise Exception("Expected device_type_ to be a str, received: {}".format(type(device_type_))) + raise Exception( + "Expected device_type_ to be a str, received: {}".format( + type(device_type_) + ) + ) self.device_attributes = device_attributes_ self.device_type = device_type_ self.unknown_fields = unknown_fields - class VolumeDetails(Type): - _toSchema = {'info': 'info', 'life': 'life', 'machine_attachments': 'machine-attachments', 'status': 'status', 'storage': 'storage', 'unit_attachments': 'unit-attachments', 'volume_tag': 'volume-tag'} - _toPy = {'info': 'info', 'life': 'life', 'machine-attachments': 'machine_attachments', 'status': 'status', 'storage': 'storage', 'unit-attachments': 'unit_attachments', 'volume-tag': 'volume_tag'} - def __init__(self, info=None, life=None, machine_attachments=None, status=None, storage=None, unit_attachments=None, volume_tag=None, **unknown_fields): - ''' + _toSchema = { + "info": "info", + "life": "life", + "machine_attachments": "machine-attachments", + "status": "status", + "storage": "storage", + "unit_attachments": "unit-attachments", + "volume_tag": "volume-tag", + } + _toPy = { + "info": "info", + "life": "life", + "machine-attachments": "machine_attachments", + "status": "status", + "storage": "storage", + "unit-attachments": "unit_attachments", + "volume-tag": "volume_tag", + } + + def __init__( + self, + info=None, + life=None, + machine_attachments=None, + status=None, + storage=None, + unit_attachments=None, + volume_tag=None, + **unknown_fields, + ): + """ info : VolumeInfo life : str machine_attachments : typing.Mapping[str, ~VolumeAttachmentDetails] @@ -16240,36 +25713,68 @@ def __init__(self, info=None, life=None, machine_attachments=None, status=None, storage : StorageDetails unit_attachments : typing.Mapping[str, ~VolumeAttachmentDetails] volume_tag : str - ''' + """ info_ = VolumeInfo.from_json(info) if info else None life_ = life - machine_attachments_ = {k: VolumeAttachmentDetails.from_json(v) for k, v in (machine_attachments or dict()).items()} + machine_attachments_ = { + k: VolumeAttachmentDetails.from_json(v) + for k, v in (machine_attachments or dict()).items() + } status_ = EntityStatus.from_json(status) if status else None storage_ = StorageDetails.from_json(storage) if storage else None - unit_attachments_ = {k: VolumeAttachmentDetails.from_json(v) for k, v in (unit_attachments or dict()).items()} + unit_attachments_ = { + k: VolumeAttachmentDetails.from_json(v) + for k, v in (unit_attachments or dict()).items() + } volume_tag_ = volume_tag # Validate arguments against known Juju API types. if info_ is not None and not isinstance(info_, (dict, VolumeInfo)): - raise Exception("Expected info_ to be a VolumeInfo, received: {}".format(type(info_))) + raise Exception( + "Expected info_ to be a VolumeInfo, received: {}".format(type(info_)) + ) if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception("Expected life_ to be a str, received: {}".format(type(life_))) - - if machine_attachments_ is not None and not isinstance(machine_attachments_, dict): - raise Exception("Expected machine_attachments_ to be a Mapping, received: {}".format(type(machine_attachments_))) + raise Exception( + "Expected life_ to be a str, received: {}".format(type(life_)) + ) + + if machine_attachments_ is not None and not isinstance( + machine_attachments_, dict + ): + raise Exception( + "Expected machine_attachments_ to be a Mapping, received: {}".format( + type(machine_attachments_) + ) + ) if status_ is not None and not isinstance(status_, (dict, EntityStatus)): - raise Exception("Expected status_ to be a EntityStatus, received: {}".format(type(status_))) + raise Exception( + "Expected status_ to be a EntityStatus, received: {}".format( + type(status_) + ) + ) if storage_ is not None and not isinstance(storage_, (dict, StorageDetails)): - raise Exception("Expected storage_ to be a StorageDetails, received: {}".format(type(storage_))) + raise Exception( + "Expected storage_ to be a StorageDetails, received: {}".format( + type(storage_) + ) + ) if unit_attachments_ is not None and not isinstance(unit_attachments_, dict): - raise Exception("Expected unit_attachments_ to be a Mapping, received: {}".format(type(unit_attachments_))) + raise Exception( + "Expected unit_attachments_ to be a Mapping, received: {}".format( + type(unit_attachments_) + ) + ) if volume_tag_ is not None and not isinstance(volume_tag_, (bytes, str)): - raise Exception("Expected volume_tag_ to be a str, received: {}".format(type(volume_tag_))) + raise Exception( + "Expected volume_tag_ to be a str, received: {}".format( + type(volume_tag_) + ) + ) self.info = info_ self.life = life_ @@ -16281,97 +25786,136 @@ def __init__(self, info=None, life=None, machine_attachments=None, status=None, self.unknown_fields = unknown_fields - class VolumeDetailsListResult(Type): - _toSchema = {'error': 'error', 'result': 'result'} - _toPy = {'error': 'error', 'result': 'result'} + _toSchema = {"error": "error", "result": "result"} + _toPy = {"error": "error", "result": "result"} + def __init__(self, error=None, result=None, **unknown_fields): - ''' + """ error : Error result : typing.Sequence[~VolumeDetails] - ''' + """ error_ = Error.from_json(error) if error else None result_ = [VolumeDetails.from_json(o) for o in result or []] # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if result_ is not None and not isinstance(result_, (bytes, str, list)): - raise Exception("Expected result_ to be a Sequence, received: {}".format(type(result_))) + raise Exception( + "Expected result_ to be a Sequence, received: {}".format(type(result_)) + ) self.error = error_ self.result = result_ self.unknown_fields = unknown_fields - class VolumeDetailsListResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~VolumeDetailsListResult] - ''' + """ results_ = [VolumeDetailsListResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - class VolumeFilter(Type): - _toSchema = {'machines': 'machines'} - _toPy = {'machines': 'machines'} + _toSchema = {"machines": "machines"} + _toPy = {"machines": "machines"} + def __init__(self, machines=None, **unknown_fields): - ''' + """ machines : typing.Sequence[str] - ''' + """ machines_ = machines # Validate arguments against known Juju API types. if machines_ is not None and not isinstance(machines_, (bytes, str, list)): - raise Exception("Expected machines_ to be a Sequence, received: {}".format(type(machines_))) + raise Exception( + "Expected machines_ to be a Sequence, received: {}".format( + type(machines_) + ) + ) self.machines = machines_ self.unknown_fields = unknown_fields - class VolumeFilters(Type): - _toSchema = {'filters': 'filters'} - _toPy = {'filters': 'filters'} + _toSchema = {"filters": "filters"} + _toPy = {"filters": "filters"} + def __init__(self, filters=None, **unknown_fields): - ''' + """ filters : typing.Sequence[~VolumeFilter] - ''' + """ filters_ = [VolumeFilter.from_json(o) for o in filters or []] # Validate arguments against known Juju API types. if filters_ is not None and not isinstance(filters_, (bytes, str, list)): - raise Exception("Expected filters_ to be a Sequence, received: {}".format(type(filters_))) + raise Exception( + "Expected filters_ to be a Sequence, received: {}".format( + type(filters_) + ) + ) self.filters = filters_ self.unknown_fields = unknown_fields - class VolumeInfo(Type): - _toSchema = {'hardware_id': 'hardware-id', 'persistent': 'persistent', 'pool': 'pool', 'size': 'size', 'volume_id': 'volume-id', 'wwn': 'wwn'} - _toPy = {'hardware-id': 'hardware_id', 'persistent': 'persistent', 'pool': 'pool', 'size': 'size', 'volume-id': 'volume_id', 'wwn': 'wwn'} - def __init__(self, hardware_id=None, persistent=None, pool=None, size=None, volume_id=None, wwn=None, **unknown_fields): - ''' + _toSchema = { + "hardware_id": "hardware-id", + "persistent": "persistent", + "pool": "pool", + "size": "size", + "volume_id": "volume-id", + "wwn": "wwn", + } + _toPy = { + "hardware-id": "hardware_id", + "persistent": "persistent", + "pool": "pool", + "size": "size", + "volume-id": "volume_id", + "wwn": "wwn", + } + + def __init__( + self, + hardware_id=None, + persistent=None, + pool=None, + size=None, + volume_id=None, + wwn=None, + **unknown_fields, + ): + """ hardware_id : str persistent : bool pool : str size : int volume_id : str wwn : str - ''' + """ hardware_id_ = hardware_id persistent_ = persistent pool_ = pool @@ -16381,22 +25925,38 @@ def __init__(self, hardware_id=None, persistent=None, pool=None, size=None, volu # Validate arguments against known Juju API types. if hardware_id_ is not None and not isinstance(hardware_id_, (bytes, str)): - raise Exception("Expected hardware_id_ to be a str, received: {}".format(type(hardware_id_))) + raise Exception( + "Expected hardware_id_ to be a str, received: {}".format( + type(hardware_id_) + ) + ) if persistent_ is not None and not isinstance(persistent_, bool): - raise Exception("Expected persistent_ to be a bool, received: {}".format(type(persistent_))) + raise Exception( + "Expected persistent_ to be a bool, received: {}".format( + type(persistent_) + ) + ) if pool_ is not None and not isinstance(pool_, (bytes, str)): - raise Exception("Expected pool_ to be a str, received: {}".format(type(pool_))) + raise Exception( + "Expected pool_ to be a str, received: {}".format(type(pool_)) + ) if size_ is not None and not isinstance(size_, int): - raise Exception("Expected size_ to be a int, received: {}".format(type(size_))) + raise Exception( + "Expected size_ to be a int, received: {}".format(type(size_)) + ) if volume_id_ is not None and not isinstance(volume_id_, (bytes, str)): - raise Exception("Expected volume_id_ to be a str, received: {}".format(type(volume_id_))) + raise Exception( + "Expected volume_id_ to be a str, received: {}".format(type(volume_id_)) + ) if wwn_ is not None and not isinstance(wwn_, (bytes, str)): - raise Exception("Expected wwn_ to be a str, received: {}".format(type(wwn_))) + raise Exception( + "Expected wwn_ to be a str, received: {}".format(type(wwn_)) + ) self.hardware_id = hardware_id_ self.persistent = persistent_ @@ -16407,29 +25967,37 @@ def __init__(self, hardware_id=None, persistent=None, pool=None, size=None, volu self.unknown_fields = unknown_fields - class ZoneResult(Type): - _toSchema = {'available': 'available', 'error': 'error', 'name': 'name'} - _toPy = {'available': 'available', 'error': 'error', 'name': 'name'} + _toSchema = {"available": "available", "error": "error", "name": "name"} + _toPy = {"available": "available", "error": "error", "name": "name"} + def __init__(self, available=None, error=None, name=None, **unknown_fields): - ''' + """ available : bool error : Error name : str - ''' + """ available_ = available error_ = Error.from_json(error) if error else None name_ = name # Validate arguments against known Juju API types. if available_ is not None and not isinstance(available_, bool): - raise Exception("Expected available_ to be a bool, received: {}".format(type(available_))) + raise Exception( + "Expected available_ to be a bool, received: {}".format( + type(available_) + ) + ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception("Expected error_ to be a Error, received: {}".format(type(error_))) + raise Exception( + "Expected error_ to be a Error, received: {}".format(type(error_)) + ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception("Expected name_ to be a str, received: {}".format(type(name_))) + raise Exception( + "Expected name_ to be a str, received: {}".format(type(name_)) + ) self.available = available_ self.error = error_ @@ -16437,21 +26005,23 @@ def __init__(self, available=None, error=None, name=None, **unknown_fields): self.unknown_fields = unknown_fields - class ZoneResults(Type): - _toSchema = {'results': 'results'} - _toPy = {'results': 'results'} + _toSchema = {"results": "results"} + _toPy = {"results": "results"} + def __init__(self, results=None, **unknown_fields): - ''' + """ results : typing.Sequence[~ZoneResult] - ''' + """ results_ = [ZoneResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): - raise Exception("Expected results_ to be a Sequence, received: {}".format(type(results_))) + raise Exception( + "Expected results_ to be a Sequence, received: {}".format( + type(results_) + ) + ) self.results = results_ self.unknown_fields = unknown_fields - - diff --git a/juju/client/client.py b/juju/client/client.py index e68601ac7..a06ecb846 100644 --- a/juju/client/client.py +++ b/juju/client/client.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -'''Replace auto-generated classes with our own, where necessary. -''' +"""Replace auto-generated classes with our own, where necessary.""" from . import _client, _definitions, overrides # isort:skip @@ -16,8 +15,8 @@ # We shouldn't be overriding Facades! else: raise ValueError( - "Cannot override a versioned Facade class -- you must patch " - "it instead.") + "Cannot override a versioned Facade class -- you must patch it instead." + ) for o in overrides.__patches__: # Patch a versioned Facade. @@ -30,7 +29,7 @@ continue o_type = getattr(overrides, o) for a in dir(o_type): - if not a.startswith('_'): + if not a.startswith("_"): setattr(c_type, a, getattr(o_type, a)) from ._client import * # noqa, isort:skip diff --git a/juju/client/codegen.py b/juju/client/codegen.py index 137d4ecf8..ef97acf43 100644 --- a/juju/client/codegen.py +++ b/juju/client/codegen.py @@ -12,6 +12,7 @@ class CodeWriter(StringIO): holding the source code for a Python class and associated methods. """ + INDENT = " " CLASS = 0 diff --git a/juju/client/connection.py b/juju/client/connection.py index f0d10597d..82f52662b 100644 --- a/juju/client/connection.py +++ b/juju/client/connection.py @@ -21,7 +21,7 @@ from juju.version import CLIENT_VERSION from .facade_versions import client_facade_versions, known_unsupported_facades -log = logging.getLogger('juju.client.connection') +log = logging.getLogger("juju.client.connection") def facade_versions(name, versions): @@ -31,10 +31,10 @@ def facade_versions(name, versions): :param name: name of the facade :param versions: versions to support by the facade """ - if name.endswith('Facade'): - name = name[:-len('Facade')] + if name.endswith("Facade"): + name = name[: -len("Facade")] return { - name: {'versions': versions}, + name: {"versions": versions}, } @@ -52,10 +52,11 @@ class Monitor: network issues or other unexpected circumstances. """ - ERROR = 'error' - CONNECTED = 'connected' - DISCONNECTING = 'disconnecting' - DISCONNECTED = 'disconnected' + + ERROR = "error" + CONNECTED = "connected" + DISCONNECTING = "disconnecting" + DISCONNECTED = "disconnected" def __init__(self, connection): self.connection = weakref.ref(connection) @@ -93,7 +94,10 @@ def status(self): if connection.is_debug_log_connection: stopped = connection._debug_log_task.cancelled() else: - stopped = connection._receiver_task is not None and connection._receiver_task.cancelled() + stopped = ( + connection._receiver_task is not None + and connection._receiver_task.cancelled() + ) if stopped or not connection._ws.open: return self.ERROR @@ -119,20 +123,22 @@ class Connection: @classmethod async def connect( - cls, - endpoint=None, - uuid=None, - username=None, - password=None, - cacert=None, - bakery_client=None, - max_frame_size=None, - retries=3, - retry_backoff=10, - specified_facades: Optional[Dict[str, Dict[Literal["versions"], Sequence[int]]]] = None, - proxy=None, - debug_log_conn=None, - debug_log_params={} + cls, + endpoint=None, + uuid=None, + username=None, + password=None, + cacert=None, + bakery_client=None, + max_frame_size=None, + retries=3, + retry_backoff=10, + specified_facades: Optional[ + Dict[str, Dict[Literal["versions"], Sequence[int]]] + ] = None, + proxy=None, + debug_log_conn=None, + debug_log_params={}, ): """Connect to the websocket. @@ -164,19 +170,20 @@ async def connect( """ self = cls() if endpoint is None: - raise ValueError('no endpoint provided') + raise ValueError("no endpoint provided") if not isinstance(endpoint, str) and not isinstance(endpoint, list): raise TypeError("Endpoint should be either str or list") self.uuid = uuid if bakery_client is None: bakery_client = httpbakery.Client() self.bakery_client = bakery_client - if username and '@' in username and not username.endswith('@local'): + if username and "@" in username and not username.endswith("@local"): # We're trying to log in as an external user - we need to use # macaroon authentication with no username or password. if password is not None: - raise errors.JujuAuthError('cannot log in as external ' - 'user with a password') + raise errors.JujuAuthError( + "cannot log in as external user with a password" + ) username = None self.usertag = tag.user(username) self.password = password @@ -230,7 +237,11 @@ async def connect( if self.proxy is not None: self.proxy.connect() - _endpoints = [(endpoint, cacert)] if isinstance(endpoint, str) else [(e, cacert) for e in endpoint] + _endpoints = ( + [(endpoint, cacert)] + if isinstance(endpoint, str) + else [(e, cacert) for e in endpoint] + ) lastError = None for _ep in _endpoints: try: @@ -245,8 +256,7 @@ async def connect( lastError = e continue except OSError as e: - logging.debug( - "Cannot access endpoint {}: {}".format(_ep, e.strerror)) + logging.debug("Cannot access endpoint {}: {}".format(_ep, e.strerror)) lastError = e continue if lastError is not None: @@ -255,20 +265,22 @@ async def connect( @property def ws(self): - log.warning('Direct access to the websocket object may cause disruptions in asyncio event handling.') + log.warning( + "Direct access to the websocket object may cause disruptions in asyncio event handling." + ) return self._ws @property def username(self): if not self.usertag: return None - return self.usertag[len('user-'):] + return self.usertag[len("user-") :] @property def is_using_old_client(self): if self.info is None: raise errors.JujuError("Not connected yet.") - return self.info['server-version'].startswith('2.') + return self.info["server-version"].startswith("2.") @property def is_open(self): @@ -276,7 +288,8 @@ def is_open(self): def _get_ssl(self, cert=None): context = ssl.create_default_context( - purpose=ssl.Purpose.SERVER_AUTH, cadata=cert) + purpose=ssl.Purpose.SERVER_AUTH, cadata=cert + ) if cert: # Disable hostname checking if and only if we have an explicit cert # to validate against, because the cert doesn't contain the IP addr @@ -288,11 +301,11 @@ def _get_ssl(self, cert=None): return context async def _open(self, endpoint, cacert): - if self.is_debug_log_connection: assert self.uuid url = "wss://user-{}:{}@{}/model/{}/log".format( - self.username, self.password, endpoint, self.uuid) + self.username, self.password, endpoint, self.uuid + ) elif self.uuid: url = "wss://{}/model/{}/api".format(endpoint, self.uuid) else: @@ -311,13 +324,20 @@ def _exit_tasks(): for task in jasyncio.all_tasks(): task.cancel() - return (await websockets.connect( + return ( + ( + await websockets.connect( + url, + ssl=self._get_ssl(cacert), + max_size=self.max_frame_size, + server_hostname=server_hostname, + sock=sock, + ) + ), url, - ssl=self._get_ssl(cacert), - max_size=self.max_frame_size, - server_hostname=server_hostname, - sock=sock, - )), url, endpoint, cacert + endpoint, + cacert, + ) async def close(self, to_reconnect=False): if not self._ws: @@ -341,7 +361,7 @@ async def close(self, to_reconnect=False): if not to_reconnect: try: - log.debug('Gathering all tasks for connection close') + log.debug("Gathering all tasks for connection close") await jasyncio.gather(*tasks_need_to_be_gathered) except jasyncio.CancelledError: pass @@ -358,51 +378,63 @@ async def close(self, to_reconnect=False): async def _recv(self, request_id): if not self.is_open: raise websockets.exceptions.ConnectionClosed( - websockets.frames.Close(websockets.frames.CloseCode.NORMAL_CLOSURE, - 'websocket closed')) + websockets.frames.Close( + websockets.frames.CloseCode.NORMAL_CLOSURE, "websocket closed" + ) + ) try: return await self.messages.get(request_id) except GeneratorExit: return {} def debug_log_filter_write(self, result): - write_or_not = True - entity = result['tag'] - msg_lev = result['sev'] - mod = result['mod'] - msg = result['msg'] - - excluded_entities = self.debug_log_params['exclude'] - excluded_modules = self.debug_log_params['exclude_module'] - write_or_not = write_or_not and \ - (mod not in excluded_modules) and \ - (entity not in excluded_entities) + entity = result["tag"] + msg_lev = result["sev"] + mod = result["mod"] + msg = result["msg"] + + excluded_entities = self.debug_log_params["exclude"] + excluded_modules = self.debug_log_params["exclude_module"] + write_or_not = ( + write_or_not + and (mod not in excluded_modules) + and (entity not in excluded_entities) + ) - included_entities = self.debug_log_params['include'] - only_these_modules = self.debug_log_params['include_module'] - write_or_not = write_or_not and \ - (only_these_modules == [] or mod in only_these_modules) and \ - (included_entities == [] or entity in included_entities) + included_entities = self.debug_log_params["include"] + only_these_modules = self.debug_log_params["include_module"] + write_or_not = ( + write_or_not + and (only_these_modules == [] or mod in only_these_modules) + and (included_entities == [] or entity in included_entities) + ) - LEVELS = ['TRACE', 'DEBUG', 'INFO', 'WARNING', 'ERROR'] - log_level = self.debug_log_params['level'] + LEVELS = ["TRACE", "DEBUG", "INFO", "WARNING", "ERROR"] + log_level = self.debug_log_params["level"] if log_level != "" and log_level not in LEVELS: - log.warning("Debug Logger: level should be one of %s, given %s" % (LEVELS, log_level)) + log.warning( + "Debug Logger: level should be one of %s, given %s" + % (LEVELS, log_level) + ) else: - write_or_not = write_or_not and \ - (log_level == "" or (LEVELS.index(msg_lev) >= LEVELS.index(log_level))) + write_or_not = write_or_not and ( + log_level == "" or (LEVELS.index(msg_lev) >= LEVELS.index(log_level)) + ) # TODO # lines = self.debug_log_params['lines'] # no_tail = self.debug_log_params['no_tail'] if write_or_not: - ts = parse(result['ts']) + ts = parse(result["ts"]) - self.debug_log_target.write("%s %02d:%02d:%02d %s %s %s\n" % (entity, ts.hour, ts.minute, ts.second, msg_lev, mod, msg)) + self.debug_log_target.write( + "%s %02d:%02d:%02d %s %s %s\n" + % (entity, ts.hour, ts.minute, ts.second, msg_lev, mod, msg) + ) return 1 else: return 0 @@ -411,31 +443,30 @@ async def _debug_logger(self): try: while self.is_open: result = await utils.run_with_interrupt( - self._ws.recv(), - self.monitor.close_called, - log=log) + self._ws.recv(), self.monitor.close_called, log=log + ) if self.monitor.close_called.is_set(): break - if result is not None and result != '{}\n': + if result is not None and result != "{}\n": result = json.loads(result) number_of_lines_written = self.debug_log_filter_write(result) self.debug_log_shown_lines += number_of_lines_written - if self.debug_log_shown_lines >= self.debug_log_params['limit']: + if self.debug_log_shown_lines >= self.debug_log_params["limit"]: jasyncio.create_task(self.close(), name="Task_Close") return except KeyError as e: - log.exception('Unexpected debug line -- %s' % e) + log.exception("Unexpected debug line -- %s" % e) jasyncio.create_task(self.close(), name="Task_Close") raise except jasyncio.CancelledError: jasyncio.create_task(self.close(), name="Task_Close") raise except websockets.exceptions.ConnectionClosed: - log.warning('Debug Logger: Connection closed, reconnecting') + log.warning("Debug Logger: Connection closed, reconnecting") # the reconnect has to be done as a task because the receiver will # be cancelled by the reconnect and we don't want the reconnect # to be aborted half-way through @@ -450,19 +481,18 @@ async def _receiver(self): try: while self.is_open: result = await utils.run_with_interrupt( - self._ws.recv(), - self.monitor.close_called, - log=log) + self._ws.recv(), self.monitor.close_called, log=log + ) if self.monitor.close_called.is_set(): break if result is not None: result = json.loads(result) - await self.messages.put(result['request-id'], result) + await self.messages.put(result["request-id"], result) except jasyncio.CancelledError: - log.debug('Receiver: Cancelled') + log.debug("Receiver: Cancelled") pass except websockets.exceptions.ConnectionClosed as e: - log.warning('Receiver: Connection closed, reconnecting') + log.warning("Receiver: Connection closed, reconnecting") await self.messages.put_all(e) # the reconnect has to be done as a task because the receiver will # be cancelled by the reconnect and we don't want the reconnect @@ -476,16 +506,17 @@ async def _receiver(self): raise async def _pinger(self): - ''' + """ A Controller can time us out if we are silent for too long. This is especially true in JaaS, which has a fairly strict timeout. To prevent timing out, we send a ping every ten seconds. - ''' + """ + async def _do_ping(): try: - log.debug(f'Pinger {self._pinger_task}: pinging') + log.debug(f"Pinger {self._pinger_task}: pinging") await pinger_facade.Ping() except jasyncio.CancelledError: raise @@ -494,51 +525,52 @@ async def _do_ping(): try: while True: await utils.run_with_interrupt( - _do_ping(), - self.monitor.close_called, - log=log) + _do_ping(), self.monitor.close_called, log=log + ) if self.monitor.close_called.is_set(): break await jasyncio.sleep(10) except jasyncio.CancelledError: - log.debug('Pinger: Cancelled') + log.debug("Pinger: Cancelled") pass except websockets.exceptions.ConnectionClosed: # The connection has closed - we can't do anything # more until the connection is restarted. - log.debug('ping failed because of closed connection') + log.debug("ping failed because of closed connection") pass async def rpc(self, msg, encoder=None): - '''Make an RPC to the API. The message is encoded as JSON + """Make an RPC to the API. The message is encoded as JSON using the given encoder if any. :param msg: Parameters for the call (will be encoded as JSON). :param encoder: Encoder to be used when encoding the message. :return: The result of the call. :raises JujuAPIError: When there's an error returned. :raises JujuError: - ''' + """ self.__request_id__ += 1 - msg['request-id'] = self.__request_id__ - if 'params' not in msg: - msg['params'] = {} + msg["request-id"] = self.__request_id__ + if "params" not in msg: + msg["params"] = {} if "version" not in msg: - msg['version'] = self.facades[msg['type']] + msg["version"] = self.facades[msg["type"]] outgoing = json.dumps(msg, indent=2, cls=encoder) - log.debug('connection id: {} ---> {}'.format(id(self), outgoing)) + log.debug("connection id: {} ---> {}".format(id(self), outgoing)) for attempt in range(3): if self.monitor.status == Monitor.DISCONNECTED: # closed cleanly; shouldn't try to reconnect raise websockets.exceptions.ConnectionClosed( - websockets.frames.Close(websockets.frames.CloseCode.NORMAL_CLOSURE, - 'websocket closed')) + websockets.frames.Close( + websockets.frames.CloseCode.NORMAL_CLOSURE, "websocket closed" + ) + ) try: await self._ws.send(outgoing) break except websockets.ConnectionClosed: if attempt == 2: raise - log.warning('RPC: Connection closed, reconnecting') + log.warning("RPC: Connection closed, reconnecting") # the reconnect has to be done in a separate task because, # if it is triggered by the pinger, then this RPC call will # be cancelled when the pinger is cancelled by the reconnect, @@ -546,37 +578,37 @@ async def rpc(self, msg, encoder=None): await jasyncio.wait([jasyncio.create_task(self.reconnect())]) if self.monitor.status != Monitor.CONNECTED: # reconnect failed; abort and shutdown - log.error('RPC: Automatic reconnect failed') + log.error("RPC: Automatic reconnect failed") raise - result = await self._recv(msg['request-id']) - log.debug('connection id : {} <--- {}'.format(id(self), result)) + result = await self._recv(msg["request-id"]) + log.debug("connection id : {} <--- {}".format(id(self), result)) if not result: return result - if 'error' in result: + if "error" in result: # API Error Response raise errors.JujuAPIError(result) - if 'response' not in result: + if "response" not in result: # This may never happen return result - if 'results' in result['response']: + if "results" in result["response"]: # Check for errors in a result list. # TODO This loses the results that might have succeeded. # Perhaps JujuError should return all the results including # errors, or perhaps a keyword parameter to the rpc method # could be added to trigger this behaviour. err_results = [] - for res in result['response']['results'] or []: - if res.get('error', {}).get('message'): - err_results.append(res['error']['message']) + for res in result["response"]["results"] or []: + if res.get("error", {}).get("message"): + err_results.append(res["error"]["message"]) if err_results: raise errors.JujuError(err_results) - elif result['response'].get('error', {}).get('message'): - raise errors.JujuError(result['response']['error']['message']) + elif result["response"].get("error", {}).get("message"): + raise errors.JujuError(result["response"]["error"]["message"]) return result @@ -590,14 +622,9 @@ def _http_headers(self): if not self.usertag: return {} - creds = u'{}:{}'.format( - self.usertag, - self.password or '' - ) + creds = "{}:{}".format(self.usertag, self.password or "") token = base64.b64encode(creds.encode()) - return { - 'Authorization': 'Basic {}'.format(token.decode()) - } + return {"Authorization": "Basic {}".format(token.decode())} def https_connection(self): """Return an https connection to this Connection's endpoint. @@ -611,21 +638,19 @@ def https_connection(self): """ endpoint = self.endpoint # Support IPv6 by right splitting on : and removing [] around IP address for host - host, remainder = endpoint.rsplit(':', 1) + host, remainder = endpoint.rsplit(":", 1) host = host.strip("[]") port = remainder - if '/' in remainder: - port, _ = remainder.split('/', 1) + if "/" in remainder: + port, _ = remainder.split("/", 1) conn = HTTPSConnection( - host, int(port), + host, + int(port), context=self._get_ssl(self.cacert), ) - path = ( - "/model/{}".format(self.uuid) - if self.uuid else "" - ) + path = "/model/{}".format(self.uuid) if self.uuid else "" return conn, self._http_headers(), path async def clone(self): @@ -641,19 +666,18 @@ def connect_params(self): to the same controller (and model if specified). """ return { - 'endpoint': self.endpoint, - 'uuid': self.uuid, - 'username': self.username, - 'password': self.password, - 'cacert': self.cacert, - 'bakery_client': self.bakery_client, - 'max_frame_size': self.max_frame_size, - 'proxy': self.proxy, + "endpoint": self.endpoint, + "uuid": self.uuid, + "username": self.username, + "password": self.password, + "cacert": self.cacert, + "bakery_client": self.bakery_client, + "max_frame_size": self.max_frame_size, + "proxy": self.proxy, } async def controller(self): - """Return a Connection to the controller at self.endpoint - """ + """Return a Connection to the controller at self.endpoint""" return await Connection.connect( self.endpoint, username=self.username, @@ -664,28 +688,31 @@ async def controller(self): ) async def reconnect(self): - """ Force a reconnection. - """ + """Force a reconnection.""" monitor = self.monitor if monitor.reconnecting.locked() or monitor.close_called.is_set(): return async with monitor.reconnecting: await self.close(to_reconnect=True) - connector = self._connect if self.is_debug_log_connection else self._connect_with_login + connector = ( + self._connect + if self.is_debug_log_connection + else self._connect_with_login + ) res = await connector( - [(self.endpoint, self.cacert)] - if not self.endpoints else - self.endpoints + [(self.endpoint, self.cacert)] if not self.endpoints else self.endpoints ) if not self.is_debug_log_connection: - self._build_facades(res.get('facades', {})) + self._build_facades(res.get("facades", {})) if not self._pinger_task: - log.debug('reconnect: scheduling a pinger task') - self._pinger_task = jasyncio.create_task(self._pinger(), name="Task_Pinger") + log.debug("reconnect: scheduling a pinger task") + self._pinger_task = jasyncio.create_task( + self._pinger(), name="Task_Pinger" + ) async def _connect(self, endpoints): if len(endpoints) == 0: - raise errors.JujuConnectionError('no endpoints to connect to') + raise errors.JujuConnectionError("no endpoints to connect to") async def _try_endpoint(endpoint, cacert, delay): if delay: @@ -695,9 +722,10 @@ async def _try_endpoint(endpoint, cacert, delay): # Try all endpoints in parallel, with slight increasing delay (+100ms # for each subsequent endpoint); the delay allows us to prefer the # earlier endpoints over the latter. Use first successful connection. - tasks = [jasyncio.ensure_future(_try_endpoint(endpoint, cacert, - 0.1 * i)) - for i, (endpoint, cacert) in enumerate(endpoints)] + tasks = [ + jasyncio.ensure_future(_try_endpoint(endpoint, cacert, 0.1 * i)) + for i, (endpoint, cacert) in enumerate(endpoints) + ] for attempt in range(self._retries + 1): for task in jasyncio.as_completed(tasks): try: @@ -706,19 +734,19 @@ async def _try_endpoint(endpoint, cacert, delay): except ConnectionError: continue # ignore; try another endpoint else: - _endpoints_str = ', '.join([endpoint - for endpoint, cacert in endpoints]) + _endpoints_str = ", ".join([endpoint for endpoint, cacert in endpoints]) if attempt < self._retries: - log.debug('Retrying connection to endpoints: {}; ' - 'attempt {} of {}'.format(_endpoints_str, - attempt + 1, - self._retries + 1)) + log.debug( + "Retrying connection to endpoints: {}; attempt {} of {}".format( + _endpoints_str, attempt + 1, self._retries + 1 + ) + ) await jasyncio.sleep((attempt + 1) * self._retry_backoff) continue else: raise errors.JujuConnectionError( - 'Unable to connect to any endpoint: ' - '{}'.format(_endpoints_str)) + "Unable to connect to any endpoint: {}".format(_endpoints_str) + ) # only executed if inner loop's else did not continue # (i.e., inner loop did break due to successful connection) break @@ -732,13 +760,17 @@ async def _try_endpoint(endpoint, cacert, delay): # If this is a debug-log connection, and the _debug_log_task # is not created yet, then go ahead and schedule it if self.is_debug_log_connection and not self._debug_log_task: - self._debug_log_task = jasyncio.create_task(self._debug_logger(), name="Task_Debug_Log") + self._debug_log_task = jasyncio.create_task( + self._debug_logger(), name="Task_Debug_Log" + ) # If this is regular connection, and we dont have a # receiver_task yet, then schedule a _receiver_task elif not self.is_debug_log_connection and not self._receiver_task: - log.debug('_connect: scheduling a receiver task') - self._receiver_task = jasyncio.create_task(self._receiver(), name="Task_Receiver") + log.debug("_connect: scheduling a receiver task") + self._receiver_task = jasyncio.create_task( + self._receiver(), name="Task_Receiver" + ) log.debug("Driver connected to juju %s", self.addr) self.monitor.close_called.clear() @@ -757,8 +789,8 @@ async def _connect_with_login(self, endpoints): # corresponding to different levels of authentication, so retry # a few times. for i in range(0, 2): - result = (await self.login())['response'] - macaroonJSON = result.get('discharge-required') + result = (await self.login())["response"] + macaroonJSON = result.get("discharge-required") if macaroonJSON is None: self.info = result success = True @@ -767,18 +799,17 @@ async def _connect_with_login(self, endpoints): self.bakery_client.handle_error( httpbakery.Error( code=httpbakery.ERR_DISCHARGE_REQUIRED, - message=result.get('discharge-required-error'), + message=result.get("discharge-required-error"), version=macaroon.version, info=httpbakery.ErrorInfo( macaroon=macaroon, - macaroon_path=result.get('macaroon-path'), + macaroon_path=result.get("macaroon-path"), ), ), # note: remove the port number. - 'https://' + self.endpoint + '/', + "https://" + self.endpoint + "/", ) - raise errors.JujuAuthError('failed to authenticate ' - 'after several attempts') + raise errors.JujuAuthError("failed to authenticate after several attempts") finally: if not success: await self.close() @@ -791,9 +822,9 @@ async def _connect_with_redirect(self, endpoints): if e.follow_redirect is False: raise login_result = await self._connect_with_login(e.endpoints) - self._build_facades(login_result.get('facades', {})) + self._build_facades(login_result.get("facades", {})) if not self._pinger_task: - log.debug('_connect_with_redirect: scheduling a pinger task') + log.debug("_connect_with_redirect: scheduling a pinger task") self._pinger_task = jasyncio.create_task(self._pinger(), name="Task_Pinger") # _build_facades takes the facade list that comes from the connection with the controller, @@ -803,7 +834,7 @@ async def _connect_with_redirect(self, endpoints): def _build_facades(self, facades_from_connection): self.facades.clear() for facade in facades_from_connection: - name = facade['name'] + name = facade["name"] if name in self._specified_facades: client_versions = self._specified_facades[name] elif name in client_facade_versions: @@ -811,30 +842,32 @@ def _build_facades(self, facades_from_connection): elif name in known_unsupported_facades: continue else: - log.warning(f'unexpected facade {name} received from the controller') + log.warning(f"unexpected facade {name} received from the controller") continue - controller_versions = facade['versions'] + controller_versions = facade["versions"] candidates = set(client_versions) & set(controller_versions) if not candidates: - log.warning(f'unknown common facade version for {name},\n' - f'versions known to client : {client_versions}\n' - f'versions known to controller : {controller_versions}') + log.warning( + f"unknown common facade version for {name},\n" + f"versions known to client : {client_versions}\n" + f"versions known to controller : {controller_versions}" + ) continue self.facades[name] = max(candidates) async def login(self): params = {} # Set the client version - params['client-version'] = CLIENT_VERSION - params['auth-tag'] = self.usertag + params["client-version"] = CLIENT_VERSION + params["auth-tag"] = self.usertag if self.password: - params['credentials'] = self.password + params["credentials"] = self.password else: - macaroons = _macaroons_for_domain(self.bakery_client.cookies, - self.endpoint) - params['macaroons'] = [[bakery.macaroon_to_dict(m) for m in ms] - for ms in macaroons] + macaroons = _macaroons_for_domain(self.bakery_client.cookies, self.endpoint) + params["macaroons"] = [ + [bakery.macaroon_to_dict(m) for m in ms] for ms in macaroons + ] try: return await self.rpc({ @@ -844,9 +877,9 @@ async def login(self): "params": params, }) except errors.JujuAPIError as e: - if e.error_code != 'redirection required': + if e.error_code != "redirection required": raise - log.info('Controller requested redirect') + log.info("Controller requested redirect") # Check if the redirect error provides a payload with embedded # redirection info (juju 2.6+ controller). In this case, return a # redirect exception which the library should not automatically @@ -859,17 +892,19 @@ async def login(self): # Fetch additional redirection information now so that # we can safely close the connection after login # fails. - redirect_info = (await self.rpc({ - "type": "Admin", - "request": "RedirectInfo", - "version": 3, - }))['response'] + redirect_info = ( + await self.rpc({ + "type": "Admin", + "request": "RedirectInfo", + "version": 3, + }) + )["response"] raise errors.JujuRedirectException(redirect_info, True) from e def _macaroons_for_domain(cookies, domain): - '''Return any macaroons from the given cookie jar that - apply to the given domain name.''' - req = urllib.request.Request('https://' + domain + '/') + """Return any macaroons from the given cookie jar that + apply to the given domain name.""" + req = urllib.request.Request("https://" + domain + "/") cookies.add_cookie_header(req) return httpbakery.extract_macaroons(req) diff --git a/juju/client/connector.py b/juju/client/connector.py index 3a901c7d0..9c366bfc4 100644 --- a/juju/client/connector.py +++ b/juju/client/connector.py @@ -86,17 +86,19 @@ async def connect(self, **kwargs): if self._connection: await self._connection.close() - account = kwargs.pop('account', {}) + account = kwargs.pop("account", {}) # Prioritize the username and password that user provided # If not enough, try to patch it with info from accounts.yaml - if 'username' not in kwargs and account.get('user'): - kwargs.update(username=account.get('user')) - if 'password' not in kwargs and account.get('password'): - kwargs.update(password=account.get('password')) - - if not ({'username', 'password'}.issubset(kwargs)): - required = {'username', 'password'}.difference(kwargs) - raise ValueError(f'Some authentication parameters are required : {",".join(required)}') + if "username" not in kwargs and account.get("user"): + kwargs.update(username=account.get("user")) + if "password" not in kwargs and account.get("password"): + kwargs.update(password=account.get("password")) + + if not ({"username", "password"}.issubset(kwargs)): + required = {"username", "password"}.difference(kwargs) + raise ValueError( + f"Some authentication parameters are required : {','.join(required)}" + ) self._connection = await Connection.connect(**kwargs) # Check if we support the target controller @@ -106,9 +108,9 @@ async def connect(self, **kwargs): except version.InvalidVersion as err: # We're only interested in the major version, so # we attempt to clean up versions such as 3.4-rc1.2 as just 3.4 - if '-' not in server_version: + if "-" not in server_version: raise JujuUnknownVersion(err) - juju_server_version = version.parse(server_version.split('-')[0]) + juju_server_version = version.parse(server_version.split("-")[0]) # CLIENT_VERSION statically comes from the VERSION file in the repo client_version = version.parse(CLIENT_VERSION) @@ -129,7 +131,9 @@ async def disconnect(self, entity): await self._log_connection.close() self._log_connection = None - async def connect_controller(self, controller_name=None, specified_facades=None, **kwargs): + async def connect_controller( + self, controller_name=None, specified_facades=None, **kwargs + ): """Connect to a controller by name. If the name is empty, it connect to the current controller. """ @@ -142,14 +146,15 @@ async def connect_controller(self, controller_name=None, specified_facades=None, proxy = proxy_from_config(controller.get("proxy-config", None)) - kwargs.update(endpoint=endpoints, - uuid=None, - account=accounts, - cacert=controller.get('ca-cert'), - bakery_client=self.bakery_client_for_controller(controller_name), - specified_facades=specified_facades, - proxy=proxy, - ) + kwargs.update( + endpoint=endpoints, + uuid=None, + account=accounts, + cacert=controller.get("ca-cert"), + bakery_client=self.bakery_client_for_controller(controller_name), + specified_facades=specified_facades, + proxy=proxy, + ) await self.connect(**kwargs) self.controller_name = controller_name self.controller_uuid = controller["uuid"] @@ -196,12 +201,14 @@ async def connect_model(self, _model_name=None, **kwargs): # TODO remove the need for base.CleanModel to subclass # JujuData. - kwargs.update(endpoint=endpoints, - uuid=model_uuid, - account=account, - cacert=controller.get('ca-cert'), - bakery_client=self.bakery_client_for_controller(controller_name), - proxy=proxy) + kwargs.update( + endpoint=endpoints, + uuid=model_uuid, + account=account, + cacert=controller.get("ca-cert"), + bakery_client=self.bakery_client_for_controller(controller_name), + proxy=proxy, + ) await self.connect(**kwargs) # TODO this might be a good spot to trigger refreshing the # local cache (the connection to the model might help) diff --git a/juju/client/facade.py b/juju/client/facade.py index 00e7f5310..920c49850 100644 --- a/juju/client/facade.py +++ b/juju/client/facade.py @@ -22,19 +22,19 @@ _marker = object() -JUJU_VERSION = re.compile(r'[0-9]+\.[0-9-]+[\.\-][0-9a-z]+(\.[0-9]+)?') +JUJU_VERSION = re.compile(r"[0-9]+\.[0-9-]+[\.\-][0-9a-z]+(\.[0-9]+)?") # Workaround for https://bugs.launchpad.net/juju/+bug/1683906 -NAUGHTY_CLASSES = ['ClientFacade', 'Client', 'ModelStatusInfo'] +NAUGHTY_CLASSES = ["ClientFacade", "Client", "ModelStatusInfo"] # Map basic types to Python's typing with a callable SCHEMA_TO_PYTHON = { - 'string': str, - 'integer': int, - 'float': float, - 'number': float, - 'boolean': bool, - 'object': Any, + "string": str, + "integer": int, + "float": float, + "number": float, + "boolean": bool, + "object": Any, } @@ -110,20 +110,21 @@ def best_facade_version(cls, connection): ''' -CLIENT_TABLE = ''' +CLIENT_TABLE = """ CLIENTS = {{ {clients} }} -''' +""" class KindRegistry(dict): - def register(self, name, version, obj): - self[name] = {version: { - "object": obj, - }} + self[name] = { + version: { + "object": obj, + } + } def lookup(self, name, version=None): """If version is omitted, max version is used""" @@ -143,7 +144,6 @@ def getObj(self, name, version=None): class TypeRegistry(dict): - def __init__(self, schema): self.schema = schema @@ -161,7 +161,7 @@ def getRefType(self, ref): return self.get(ref) def objType(self, obj): - kind = obj.get('type') + kind = obj.get("type") if not kind: raise ValueError("%s has no type" % obj) result = SCHEMA_TO_PYTHON.get(kind) @@ -188,10 +188,10 @@ def booler(v): type_mapping = { - 'str': '(bytes, str)', - 'Sequence': '(bytes, str, list)', - 'Union': 'dict', - 'Mapping': 'dict', + "str": "(bytes, str)", + "Sequence": "(bytes, str, list)", + "Union": "dict", + "Mapping": "dict", } @@ -204,12 +204,12 @@ def name_to_py(name): def var_type_to_py(kind): - return 'None' + return "None" def kind_to_py(kind): if kind is None or kind is typing.Any: - return 'None', '', False + return "None", "", False name = "" if typing_inspect.is_generic_type(kind): @@ -218,9 +218,9 @@ def kind_to_py(kind): else: name = kind.__name__ - if (kind in basic_types or type(kind) in basic_types): + if kind in basic_types or type(kind) in basic_types: return name, type_mapping.get(name) or name, True - if (name in type_mapping): + if name in type_mapping: return name, type_mapping[name], True suffix = name.lstrip("~") @@ -228,13 +228,12 @@ def kind_to_py(kind): def strcast(kind, keep_builtins=False): - if (kind in basic_types or - type(kind) in basic_types) and keep_builtins is False: + if (kind in basic_types or type(kind) in basic_types) and keep_builtins is False: return kind.__name__ - if str(kind).startswith('~'): + if str(kind).startswith("~"): return str(kind)[1:] if kind is typing.Any: - return 'Any' + return "Any" try: if issubclass(kind, typing.GenericMeta): return str(kind)[1:] @@ -244,7 +243,6 @@ def strcast(kind, keep_builtins=False): class Args(list): - def __init__(self, schema, defs): self.schema = schema self.defs = defs @@ -263,9 +261,13 @@ def do_explode(self, kind): return False if kind in basic_types or type(kind) is typing.TypeVar: return False - if typing_inspect.is_generic_type(kind) and issubclass(typing_inspect.get_origin(kind), Sequence): + if typing_inspect.is_generic_type(kind) and issubclass( + typing_inspect.get_origin(kind), Sequence + ): return False - if typing_inspect.is_generic_type(kind) and issubclass(typing_inspect.get_origin(kind), Mapping): + if typing_inspect.is_generic_type(kind) and issubclass( + typing_inspect.get_origin(kind), Mapping + ): return False self.clear() self.extend(Args(self.schema, kind)) @@ -285,10 +287,7 @@ def SchemaToPyMapping(self): def _format(self, name, rtype, typed=True): if typed: - return "{} : {}".format( - name_to_py(name), - strcast(rtype) - ) + return "{} : {}".format(name_to_py(name), strcast(rtype)) else: return name_to_py(name) @@ -300,7 +299,7 @@ def _get_arg_str(self, typed=False, joined=", "): if joined: return joined.join(parts) return parts - return '' + return "" def as_kwargs(self): if self: @@ -308,9 +307,9 @@ def as_kwargs(self): for item in self: var_name = name_to_py(item[0]) var_type = var_type_to_py(item[1]) - parts.append('{}={}'.format(var_name, var_type)) - return ', '.join(parts) - return '' + parts.append("{}={}".format(var_name, var_type)) + return ", ".join(parts) + return "" def as_validation(self): """ @@ -323,7 +322,7 @@ def as_validation(self): var_type, var_sub_type, ok = kind_to_py(item[1]) if ok: parts.append(buildValidation(var_name, var_type, var_sub_type)) - return '\n'.join(parts) + return "\n".join(parts) def typed(self): return self._get_arg_str(True) @@ -339,17 +338,20 @@ def buildValidation(name, instance_type, instance_sub_type, ident=None): INDENT = ident or " " source = """{ident}if {name} is not None and not isinstance({name}, {instance_sub_type}): {ident} raise Exception("Expected {name} to be a {instance_type}, received: {{}}".format(type({name}))) -""".format(ident=INDENT, - name=name, - instance_type=instance_type, - instance_sub_type=instance_sub_type) +""".format( + ident=INDENT, + name=name, + instance_type=instance_type, + instance_sub_type=instance_sub_type, + ) return source def buildTypes(schema, capture): INDENT = " " - for kind in sorted((k for k in schema.types if not isinstance(k, str)), - key=lambda x: str(x)): + for kind in sorted( + (k for k in schema.types if not isinstance(k, str)), key=lambda x: str(x) + ): name = schema.types[kind] if not name: # when running on juju 3.1.0 client-only schemas, we get a seemingly empty entry with no name @@ -363,7 +365,8 @@ def buildTypes(schema, capture): # Write Factory class for _client.py make_factory(name) # Write actual class - source = [""" + source = [ + """ class {}(Type): _toSchema = {} _toPy = {} @@ -371,13 +374,15 @@ def __init__(self{}{}, **unknown_fields): ''' {} '''""".format( - name, - # pprint these to get stable ordering across regens - pprint.pformat(args.PyToSchemaMapping(), width=999), - pprint.pformat(args.SchemaToPyMapping(), width=999), - ", " if args else "", - args.as_kwargs(), - textwrap.indent(args.get_doc(), INDENT * 2))] + name, + # pprint these to get stable ordering across regens + pprint.pformat(args.PyToSchemaMapping(), width=999), + pprint.pformat(args.SchemaToPyMapping(), width=999), + ", " if args else "", + args.as_kwargs(), + textwrap.indent(args.get_doc(), INDENT * 2), + ) + ] if not args: source.append("{}self.unknown_fields = unknown_fields".format(INDENT * 2)) @@ -388,71 +393,67 @@ def __init__(self{}{}, **unknown_fields): arg_type = arg[1] arg_type_name = strcast(arg_type) if arg_type in basic_types or arg_type is typing.Any: - source.append("{}{}_ = {}".format(INDENT * 2, - arg_name, - arg_name)) + source.append("{}{}_ = {}".format(INDENT * 2, arg_name, arg_name)) elif type(arg_type) is typing.TypeVar: - source.append("{}{}_ = {}.from_json({}) " - "if {} else None".format(INDENT * 2, - arg_name, - arg_type_name, - arg_name, - arg_name)) - elif typing_inspect.is_generic_type(arg_type) and issubclass(typing_inspect.get_origin(arg_type), Sequence): - parameters = typing_inspect.get_parameters(arg_type) - value_type = ( - parameters[0] - if len(parameters) - else None + source.append( + "{}{}_ = {}.from_json({}) if {} else None".format( + INDENT * 2, arg_name, arg_type_name, arg_name, arg_name + ) ) + elif typing_inspect.is_generic_type(arg_type) and issubclass( + typing_inspect.get_origin(arg_type), Sequence + ): + parameters = typing_inspect.get_parameters(arg_type) + value_type = parameters[0] if len(parameters) else None if type(value_type) is typing.TypeVar: source.append( - "{}{}_ = [{}.from_json(o) " - "for o in {} or []]".format(INDENT * 2, - arg_name, - strcast(value_type), - arg_name)) + "{}{}_ = [{}.from_json(o) for o in {} or []]".format( + INDENT * 2, arg_name, strcast(value_type), arg_name + ) + ) else: - source.append("{}{}_ = {}".format(INDENT * 2, - arg_name, - arg_name)) - elif typing_inspect.is_generic_type(arg_type) and issubclass(typing_inspect.get_origin(arg_type), Mapping): + source.append( + "{}{}_ = {}".format(INDENT * 2, arg_name, arg_name) + ) + elif typing_inspect.is_generic_type(arg_type) and issubclass( + typing_inspect.get_origin(arg_type), Mapping + ): parameters = typing_inspect.get_parameters(arg_type) - value_type = ( - parameters[0] - if len(parameters) - else None - ) + value_type = parameters[0] if len(parameters) else None if type(value_type) is typing.TypeVar: source.append( "{}{}_ = {{k: {}.from_json(v) " "for k, v in ({} or dict()).items()}}".format( - INDENT * 2, - arg_name, - strcast(value_type), - arg_name)) + INDENT * 2, arg_name, strcast(value_type), arg_name + ) + ) else: - source.append("{}{}_ = {}".format(INDENT * 2, - arg_name, - arg_name)) + source.append( + "{}{}_ = {}".format(INDENT * 2, arg_name, arg_name) + ) else: - source.append("{}{}_ = {}".format(INDENT * 2, - arg_name, - arg_name)) + source.append("{}{}_ = {}".format(INDENT * 2, arg_name, arg_name)) if len(args) > 0: - source.append('\n{}# Validate arguments against known Juju API types.'.format(INDENT * 2)) + source.append( + "\n{}# Validate arguments against known Juju API types.".format( + INDENT * 2 + ) + ) for arg in args: arg_name = "{}_".format(name_to_py(arg[0])) arg_type, arg_sub_type, ok = kind_to_py(arg[1]) if ok: - source.append('{}'.format(buildValidation(arg_name, - arg_type, - arg_sub_type, - ident=INDENT * 2))) + source.append( + "{}".format( + buildValidation( + arg_name, arg_type, arg_sub_type, ident=INDENT * 2 + ) + ) + ) for arg in args: arg_name = name_to_py(arg[0]) - source.append('{}self.{} = {}_'.format(INDENT * 2, arg_name, arg_name)) + source.append("{}self.{} = {}_".format(INDENT * 2, arg_name, arg_name)) # Ensure that we take the kwargs (unknown_fields) and put it on the # Results/Params so we can inspect it. source.append("{}self.unknown_fields = unknown_fields".format(INDENT * 2)) @@ -493,9 +494,11 @@ async def wrapper(*args, **kwargs): reply = await f(*args, **kwargs) if cls is None: return reply - if 'error' in reply: - cls = CLASSES['Error'] - if typing_inspect.is_generic_type(cls) and issubclass(typing_inspect.get_origin(cls), Sequence): + if "error" in reply: + cls = CLASSES["Error"] + if typing_inspect.is_generic_type(cls) and issubclass( + typing_inspect.get_origin(cls), Sequence + ): parameters = typing_inspect.get_parameters(cls) result = [] item_cls = parameters[0] @@ -509,10 +512,12 @@ async def wrapper(*args, **kwargs): result.append(cls.from_json(item)) """ else: - result = cls.from_json(reply['response']) + result = cls.from_json(reply["response"]) return result + return wrapper + return decorator @@ -522,9 +527,7 @@ def makeFunc(cls, name, description, params, result, _async=True): assignments = [] toschema = args.PyToSchemaMapping() for arg in args._get_arg_str(False, False): - assignments.append("{}_params[\'{}\'] = {}".format(INDENT, - toschema[arg], - arg)) + assignments.append("{}_params['{}'] = {}".format(INDENT, toschema[arg], arg)) assignments = "\n".join(assignments) res = retspec(cls.schema, result) source = """ @@ -551,17 +554,19 @@ def makeFunc(cls, name, description, params, result, _async=True): if description != "": description = "{}\n\n".format(description) doc_string = "{}{}".format(description, args.get_doc()) - fsource = source.format(_async="async " if _async else "", - name=name, - argsep=", " if args else "", - args=args.as_kwargs(), - res=res, - validation=args.as_validation(), - rettype=result.__name__ if result else None, - docstring=textwrap.indent(doc_string, INDENT), - cls=cls, - assignments=assignments, - _await="await " if _async else "") + fsource = source.format( + _async="async " if _async else "", + name=name, + argsep=", " if args else "", + args=args.as_kwargs(), + res=res, + validation=args.as_validation(), + rettype=result.__name__ if result else None, + docstring=textwrap.indent(doc_string, INDENT), + cls=cls, + assignments=assignments, + _await="await " if _async else "", + ) ns = _getns(cls.schema) exec(fsource, ns) func = ns[name] @@ -591,7 +596,7 @@ async def rpc(self, msg): def buildMethods(cls, capture): - properties = cls.schema['properties'] + properties = cls.schema["properties"] for methodname in sorted(properties): method, source = _buildMethod(cls, methodname) setattr(cls, methodname, method) @@ -601,26 +606,26 @@ def buildMethods(cls, capture): def _buildMethod(cls, name): params = None result = None - method = cls.schema['properties'][name] + method = cls.schema["properties"][name] description = "" - if 'description' in method: - description = method['description'] - if 'properties' in method: - prop = method['properties'] - spec = prop.get('Params') + if "description" in method: + description = method["description"] + if "properties" in method: + prop = method["properties"] + spec = prop.get("Params") if spec: - params = cls.schema.types.get(spec['$ref']) - spec = prop.get('Result') + params = cls.schema.types.get(spec["$ref"]) + spec = prop.get("Result") if spec: - if '$ref' in spec: - result = cls.schema.types.get(spec['$ref']) + if "$ref" in spec: + result = cls.schema.types.get(spec["$ref"]) else: - result = SCHEMA_TO_PYTHON[spec['type']] + result = SCHEMA_TO_PYTHON[spec["type"]] return makeFunc(cls, name, description, params, result) def buildWatcherRPCMethods(cls, capture): - properties = cls.schema['properties'] + properties = cls.schema["properties"] if "Next" in properties and "Stop" in properties: method, source = makeRPCFunc(cls) setattr(cls, "rpc", method) @@ -628,17 +633,21 @@ def buildWatcherRPCMethods(cls, capture): def buildFacade(schema): - cls = type(schema.name, (Type,), dict(name=schema.name, - version=schema.version, - schema=schema)) + cls = type( + schema.name, + (Type,), + dict(name=schema.name, version=schema.version, schema=schema), + ) source = """ class {name}Facade(Type): name = '{name}' version = {version} schema = {schema} - """.format(name=schema.name, - version=schema.version, - schema=textwrap.indent(pprint.pformat(schema), " ")) + """.format( + name=schema.name, + version=schema.version, + schema=textwrap.indent(pprint.pformat(schema), " "), + ) return cls, source @@ -670,15 +679,15 @@ async def rpc(self, msg): def from_json(cls, data): def _parse_nested_list_entry(expr, result_dict): if isinstance(expr, str): - if '>' in expr or '>=' in expr: + if ">" in expr or ">=" in expr: # something like juju >= 2.9.31 - i = expr.index('>') + i = expr.index(">") _key = expr[:i].strip() _value = expr[i:].strip() result_dict[_key] = _value else: # this is a simple entry - result_dict[expr] = '' + result_dict[expr] = "" elif isinstance(expr, dict): for _, v in expr.items(): _parse_nested_list_entry(v, result_dict) @@ -686,7 +695,9 @@ def _parse_nested_list_entry(expr, result_dict): for v in expr: _parse_nested_list_entry(v, result_dict) else: - raise TypeError(f"Unexpected type of entry in assumes expression: {expr}") + raise TypeError( + f"Unexpected type of entry in assumes expression: {expr}" + ) if isinstance(data, cls): return data @@ -743,9 +754,9 @@ def get(self, key, default=None): class Schema(dict): def __init__(self, schema): - self.name = schema['Name'] - self.version = schema['Version'] - self.update(schema['Schema']) + self.name = schema["Name"] + self.version = schema["Version"] + self.update(schema["Schema"]) self.registry = KindRegistry() self.types = TypeRegistry(self) @@ -761,7 +772,7 @@ def buildDefinitions(self): # but these may contain references themselves # so we dfs to the bottom and build upwards # when a types is already in the registry - defs = self.get('definitions') + defs = self.get("definitions") if not defs: return definitions = {} @@ -793,7 +804,7 @@ def buildObject(self, node, name=None): if "$ref" in prop: add((p, self.types.refType(prop))) else: - kind = prop['type'] + kind = prop["type"] if kind == "array": add((p, self.buildArray(prop))) elif kind == "object": @@ -803,8 +814,8 @@ def buildObject(self, node, name=None): if pprops: if ".*" not in pprops: raise ValueError( - "Cannot handle actual pattern in patternProperties %s" % - pprops) + "Cannot handle actual pattern in patternProperties %s" % pprops + ) pprop = pprops[".*"] if "$ref" in pprop: add((name, Mapping[str, self.types.refType(pprop)])) @@ -815,8 +826,8 @@ def buildObject(self, node, name=None): else: add((name, Mapping[str, SCHEMA_TO_PYTHON[ppkind]])) - if not struct and node.get('additionalProperties', False): - add((name, SCHEMA_TO_PYTHON.get('object'))) + if not struct and node.get("additionalProperties", False): + add((name, SCHEMA_TO_PYTHON.get("object"))) return struct @@ -827,17 +838,14 @@ def buildArray(self, obj): else: kind = obj.get("type") if kind and kind == "array": - items = obj['items'] + items = obj["items"] return self.buildArray(items) else: return Sequence[self.types.objType(obj)] def _getns(schema): - ns = {'Type': Type, - 'typing': typing, - 'ReturnMapping': ReturnMapping - } + ns = {"Type": Type, "typing": typing, "ReturnMapping": ReturnMapping} # Copy our types into the globals of the method for facade in schema.registry: ns[facade] = schema.registry.getObj(facade) @@ -861,8 +869,7 @@ def write_facades(captures, options): f.write(HEADER) f.write("from juju.client.facade import Type, ReturnMapping\n") f.write("from juju.client._definitions import *\n\n") - for key in sorted( - [k for k in captures[version].keys() if "Facade" in k]): + for key in sorted([k for k in captures[version].keys() if "Facade" in k]): print(captures[version][key], file=f) # Return the last (most recent) version for use in other routines. @@ -871,8 +878,8 @@ def write_facades(captures, options): def write_definitions(captures, options): """ - Write auxillary (non versioned) classes to - _definitions.py The auxillary classes currently get + Write auxiliary (non versioned) classes to + _definitions.py The auxiliary classes currently get written redudantly into each capture object, so we can look in one of them -- we just use the last one from the loop above. @@ -880,8 +887,7 @@ def write_definitions(captures, options): with open("{}/_definitions.py".format(options.output_dir), "w") as f: f.write(HEADER) f.write("from juju.client.facade import Type, ReturnMapping\n\n") - for key in sorted( - [k for k in captures.keys() if "Facade" not in k]): + for key in sorted([k for k in captures.keys() if "Facade" not in k]): print(captures[key], file=f) @@ -899,8 +905,13 @@ def write_client(captures, options): # from juju.client import _client2, _client1, _client3 ... f.write("\nfrom juju.client import " + clients + "\n\n") # CLIENTS = { .... - f.write(CLIENT_TABLE.format(clients=",\n ".join( - ['"{}": _client{}'.format(v, v) for v in captures]))) + f.write( + CLIENT_TABLE.format( + clients=",\n ".join([ + '"{}": _client{}'.format(v, v) for v in captures + ]) + ) + ) f.write(LOOKUP_FACADE) f.write(TYPE_FACTORY) @@ -909,7 +920,7 @@ def write_client(captures, options): def generate_definitions(schemas): - # Build all of the auxillary (unversioned) classes + # Build all of the auxiliary (unversioned) classes # TODO: get rid of some of the excess trips through loops in the # called functions. definitions = codegen.Capture() @@ -927,7 +938,9 @@ def generate_definitions(schemas): return definitions -def generate_facades(schemas: Dict[str, List[Schema]]) -> Dict[str, Dict[int, codegen.Capture]]: +def generate_facades( + schemas: Dict[str, List[Schema]], +) -> Dict[str, Dict[int, codegen.Capture]]: captures = defaultdict(codegen.Capture) # Build the Facade classes @@ -989,5 +1002,5 @@ def main(): write_client(captures, options) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/juju/client/facade_versions.py b/juju/client/facade_versions.py index f5c273c2e..8b8268c48 100644 --- a/juju/client/facade_versions.py +++ b/juju/client/facade_versions.py @@ -1,141 +1,140 @@ # Copyright 2024 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -"""Constants for facade version negotation.""" +"""Constants for facade version negotiation.""" + from typing import Dict, Sequence # Please keep in alphabetical order # in future this will likely be generated automatically (perhaps at runtime) client_facade_versions = { - 'Action': (7, ), - 'Admin': (3, ), - 'AllModelWatcher': (4, ), - 'AllWatcher': (3, ), - 'Annotations': (2, ), - 'Application': (17, 19, 20), - 'ApplicationOffers': (4, 5), - 'Backups': (3, ), - 'Block': (2, ), - 'Bundle': (6, ), - 'Charms': (6, ), - 'Client': (6, 7, 8), - 'Cloud': (7, ), - 'Controller': (11, 12), - 'CredentialManager': (1, ), - 'FirewallRules': (1, ), - 'HighAvailability': (2, ), - 'ImageMetadataManager': (1, ), - 'KeyManager': (1, ), - 'MachineManager': (10, ), - 'MetricsDebug': (2, ), - 'ModelConfig': (3, ), - 'ModelGeneration': (4, ), - 'ModelManager': (9, 10), - 'ModelUpgrader': (1, ), - 'Payloads': (1, ), - 'Pinger': (1, ), - 'Resources': (3, ), - 'SSHClient': (4, ), - 'SecretBackends': (1, ), - 'Secrets': (1, 2), - 'Spaces': (6, ), - 'Storage': (6, ), - 'Subnets': (5, ), - 'UserManager': (3, ), + "Action": (7,), + "Admin": (3,), + "AllModelWatcher": (4,), + "AllWatcher": (3,), + "Annotations": (2,), + "Application": (17, 19, 20), + "ApplicationOffers": (4, 5), + "Backups": (3,), + "Block": (2,), + "Bundle": (6,), + "Charms": (6,), + "Client": (6, 7, 8), + "Cloud": (7,), + "Controller": (11, 12), + "CredentialManager": (1,), + "FirewallRules": (1,), + "HighAvailability": (2,), + "ImageMetadataManager": (1,), + "KeyManager": (1,), + "MachineManager": (10,), + "MetricsDebug": (2,), + "ModelConfig": (3,), + "ModelGeneration": (4,), + "ModelManager": (9, 10), + "ModelUpgrader": (1,), + "Payloads": (1,), + "Pinger": (1,), + "Resources": (3,), + "SSHClient": (4,), + "SecretBackends": (1,), + "Secrets": (1, 2), + "Spaces": (6,), + "Storage": (6,), + "Subnets": (5,), + "UserManager": (3,), } # Manual list of facades present in schemas + codegen which python-libjuju does not yet support -excluded_facade_versions: Dict[str, Sequence[int]] = { - 'Charms': (7, ) -} +excluded_facade_versions: Dict[str, Sequence[int]] = {"Charms": (7,)} # We don't generate code for these, as we can never use them. # The controller happily lists them though, don't warn about these. known_unsupported_facades = ( - 'ActionPruner', - 'Agent', - 'AgentLifeFlag', - 'AgentTools', - 'ApplicationScaler', - 'CAASAdmission', - 'CAASAgent', - 'CAASApplication', - 'CAASApplicationProvisioner', - 'CAASFirewaller', - 'CAASFirewallerSidecar', - 'CAASModelConfigManager', - 'CAASModelOperator', - 'CAASOperator', - 'CAASOperatorProvisioner', - 'CAASOperatorUpgrader', - 'CAASUnitProvisioner', - 'CharmDownloader', - 'CharmRevisionUpdater', - 'Cleaner', - 'CredentialValidator', - 'CrossController', - 'CrossModelRelations', - 'CrossModelSecrets', - 'Deployer', - 'DiskManager', - 'EntityWatcher', - 'EnvironUpgrader', - 'ExternalControllerUpdater', - 'FanConfigurer', - 'FilesystemAttachmentsWatcher', - 'Firewaller', - 'HostKeyReporter', - 'ImageMetadata', - 'InstanceMutater', - 'InstancePoller', - 'KeyUpdater', - 'LeadershipService', - 'LifeFlag', - 'LogForwarding', - 'Logger', - 'MachineActions', - 'MachineUndertaker', - 'Machiner', - 'MeterStatus', - 'MetricsAdder', - 'MetricsManager', - 'MigrationFlag', - 'MigrationMaster', - 'MigrationMinion', - 'MigrationStatusWatcher', - 'MigrationTarget', - 'ModelSummaryWatcher', - 'NotifyWatcher', - 'OfferStatusWatcher', - 'PayloadsHookContext', - 'Provisioner', - 'ProxyUpdater', - 'Reboot', - 'RelationStatusWatcher', - 'RelationUnitsWatcher', - 'RemoteRelationWatcher', - 'RemoteRelations', - 'ResourcesHookContext', - 'RetryStrategy', - 'SecretBackendsManager', - 'SecretBackendsRotateWatcher', - 'SecretsDrain', - 'SecretsManager', - 'SecretsRevisionWatcher', - 'SecretsTriggerWatcher', - 'Singular', - 'StatusHistory', - 'StorageProvisioner', - 'StringsWatcher', - 'Undertaker', - 'UnitAssigner', - 'Uniter', - 'UpgradeSeries', - 'UpgradeSteps', - 'Upgrader', - 'UserSecretsDrain', - 'UserSecretsManager', - 'VolumeAttachmentPlansWatcher', - 'VolumeAttachmentsWatcher' + "ActionPruner", + "Agent", + "AgentLifeFlag", + "AgentTools", + "ApplicationScaler", + "CAASAdmission", + "CAASAgent", + "CAASApplication", + "CAASApplicationProvisioner", + "CAASFirewaller", + "CAASFirewallerSidecar", + "CAASModelConfigManager", + "CAASModelOperator", + "CAASOperator", + "CAASOperatorProvisioner", + "CAASOperatorUpgrader", + "CAASUnitProvisioner", + "CharmDownloader", + "CharmRevisionUpdater", + "Cleaner", + "CredentialValidator", + "CrossController", + "CrossModelRelations", + "CrossModelSecrets", + "Deployer", + "DiskManager", + "EntityWatcher", + "EnvironUpgrader", + "ExternalControllerUpdater", + "FanConfigurer", + "FilesystemAttachmentsWatcher", + "Firewaller", + "HostKeyReporter", + "ImageMetadata", + "InstanceMutater", + "InstancePoller", + "KeyUpdater", + "LeadershipService", + "LifeFlag", + "LogForwarding", + "Logger", + "MachineActions", + "MachineUndertaker", + "Machiner", + "MeterStatus", + "MetricsAdder", + "MetricsManager", + "MigrationFlag", + "MigrationMaster", + "MigrationMinion", + "MigrationStatusWatcher", + "MigrationTarget", + "ModelSummaryWatcher", + "NotifyWatcher", + "OfferStatusWatcher", + "PayloadsHookContext", + "Provisioner", + "ProxyUpdater", + "Reboot", + "RelationStatusWatcher", + "RelationUnitsWatcher", + "RemoteRelationWatcher", + "RemoteRelations", + "ResourcesHookContext", + "RetryStrategy", + "SecretBackendsManager", + "SecretBackendsRotateWatcher", + "SecretsDrain", + "SecretsManager", + "SecretsRevisionWatcher", + "SecretsTriggerWatcher", + "Singular", + "StatusHistory", + "StorageProvisioner", + "StringsWatcher", + "Undertaker", + "UnitAssigner", + "Uniter", + "UpgradeSeries", + "UpgradeSteps", + "Upgrader", + "UserSecretsDrain", + "UserSecretsManager", + "VolumeAttachmentPlansWatcher", + "VolumeAttachmentsWatcher", ) diff --git a/juju/client/gocookies.py b/juju/client/gocookies.py index e53ccde9e..d568cc8fd 100644 --- a/juju/client/gocookies.py +++ b/juju/client/gocookies.py @@ -10,12 +10,13 @@ class GoCookieJar(cookiejar.FileCookieJar): - '''A CookieJar implementation that reads and writes cookies + """A CookieJar implementation that reads and writes cookies to the cookiejar format as understood by the Go package - github.com/juju/persistent-cookiejar.''' + github.com/juju/persistent-cookiejar.""" + def _really_load(self, f, filename, ignore_discard, ignore_expires): - '''Implement the _really_load method called by FileCookieJar - to implement the actual cookie loading''' + """Implement the _really_load method called by FileCookieJar + to implement the actual cookie loading""" data = json.load(f) or [] now = time.time() for cookie in map(go_to_py_cookie, data): @@ -24,7 +25,7 @@ def _really_load(self, f, filename, ignore_discard, ignore_expires): self.set_cookie(cookie) def save(self, filename=None, ignore_discard=False, ignore_expires=False): - '''Implement the FileCookieJar abstract method.''' + """Implement the FileCookieJar abstract method.""" if filename is None: if self.filename is not None: filename = self.filename @@ -46,15 +47,15 @@ def save(self, filename=None, ignore_discard=False, ignore_expires=False): def go_to_py_cookie(go_cookie): - '''Convert a Go-style JSON-unmarshaled cookie into a Python cookie''' + """Convert a Go-style JSON-unmarshaled cookie into a Python cookie""" expires = None - if go_cookie.get('Expires') is not None: - t = pyrfc3339.parse(go_cookie['Expires']) + if go_cookie.get("Expires") is not None: + t = pyrfc3339.parse(go_cookie["Expires"]) expires = t.timestamp() return cookiejar.Cookie( version=0, - name=go_cookie['Name'], - value=go_cookie['Value'], + name=go_cookie["Name"], + value=go_cookie["Value"], port=None, port_specified=False, # Unfortunately Python cookies don't record the original @@ -63,12 +64,12 @@ def go_to_py_cookie(go_cookie): # even though it probably was not. This means that # we won't correctly record the CanonicalHost entry # when writing the cookie file after reading it. - domain=go_cookie['Domain'], - domain_specified=not go_cookie['HostOnly'], + domain=go_cookie["Domain"], + domain_specified=not go_cookie["HostOnly"], domain_initial_dot=False, - path=go_cookie['Path'], + path=go_cookie["Path"], path_specified=True, - secure=go_cookie['Secure'], + secure=go_cookie["Secure"], expires=expires, discard=False, comment=None, @@ -79,7 +80,7 @@ def go_to_py_cookie(go_cookie): def py_to_go_cookie(py_cookie): - '''Convert a python cookie to the JSON-marshalable Go-style cookie form.''' + """Convert a python cookie to the JSON-marshalable Go-style cookie form.""" # TODO (perhaps): # HttpOnly # Creation @@ -87,19 +88,19 @@ def py_to_go_cookie(py_cookie): # Updated # not done properly: CanonicalHost. go_cookie = { - 'Name': py_cookie.name, - 'Value': py_cookie.value, - 'Domain': py_cookie.domain, - 'HostOnly': not py_cookie.domain_specified, - 'Persistent': not py_cookie.discard, - 'Secure': py_cookie.secure, - 'CanonicalHost': py_cookie.domain, + "Name": py_cookie.name, + "Value": py_cookie.value, + "Domain": py_cookie.domain, + "HostOnly": not py_cookie.domain_specified, + "Persistent": not py_cookie.discard, + "Secure": py_cookie.secure, + "CanonicalHost": py_cookie.domain, } if py_cookie.path_specified: - go_cookie['Path'] = py_cookie.path + go_cookie["Path"] = py_cookie.path if py_cookie.expires is not None: unix_time = datetime.datetime.fromtimestamp(py_cookie.expires) # Note: fromtimestamp bizarrely produces a time without # a time zone, so we need to use accept_naive. - go_cookie['Expires'] = pyrfc3339.generate(unix_time, accept_naive=True) + go_cookie["Expires"] = pyrfc3339.generate(unix_time, accept_naive=True) return go_cookie diff --git a/juju/client/jujudata.py b/juju/client/jujudata.py index f48858b3d..c38d8a306 100644 --- a/juju/client/jujudata.py +++ b/juju/client/jujudata.py @@ -11,11 +11,14 @@ from juju import tag from juju.client import client as jujuclient from juju.client.gocookies import GoCookieJar -from juju.errors import (JujuControllerNotFoundError, JujuError, - PylibjujuProgrammingError) +from juju.errors import ( + JujuControllerNotFoundError, + JujuError, + PylibjujuProgrammingError, +) from juju.utils import juju_config_dir -API_ENDPOINTS_KEY = 'api-endpoints' +API_ENDPOINTS_KEY = "api-endpoints" class NoModelException(Exception): @@ -35,9 +38,9 @@ def parse_model(self, model): :return (str, str): The controller and model names. """ # TODO if model is empty, use $JUJU_MODEL environment variable. - if model and ':' in model: + if model and ":" in model: # explicit controller given - controller_name, model_name = model.split(':') + controller_name, model_name = model.split(":") else: # use the current controller if one isn't explicitly given controller_name = self.current_controller() @@ -47,25 +50,30 @@ def parse_model(self, model): if not model_name: model_name = self.current_model(controller_name, model_only=True) if not model_name: - raise NoModelException('no current model') + raise NoModelException("no current model") - if '/' not in model_name: + if "/" not in model_name: # model name doesn't include a user prefix, so add one # by using the current user for the controller. accounts = self.accounts().get(controller_name) if accounts is None: - raise JujuError('No account found for controller {} '.format(controller_name)) - username = accounts.get('user') + raise JujuError( + "No account found for controller {} ".format(controller_name) + ) + username = accounts.get("user") if username is None: - raise JujuError('No username found for controller {}'.format(controller_name)) + raise JujuError( + "No username found for controller {}".format(controller_name) + ) model_name = username + "/" + model_name return controller_name, model_name class FileJujuData(JujuData): - '''Provide access to the Juju client configuration files. - Any configuration file is read once and then cached.''' + """Provide access to the Juju client configuration files. + Any configuration file is read once and then cached.""" + def __init__(self): self.path = juju_config_dir() # _loaded keeps track of the loaded YAML from @@ -74,35 +82,37 @@ def __init__(self): self._loaded = {} def refresh(self): - '''Forget the cache of configuration file data''' + """Forget the cache of configuration file data""" self._loaded = {} def current_controller(self): - '''Return the current controller name''' + """Return the current controller name""" try: - return self._load_yaml('controllers.yaml', 'current-controller') + return self._load_yaml("controllers.yaml", "current-controller") except FileNotFoundError: - raise JujuControllerNotFoundError('No controllers.yaml file found. python-libjuju requires a bootstrapped Juju controller.') + raise JujuControllerNotFoundError( + "No controllers.yaml file found. python-libjuju requires a bootstrapped Juju controller." + ) def current_model(self, controller_name=None, model_only=False): - '''Return the current model, qualified by its controller name. + """Return the current model, qualified by its controller name. If controller_name is specified, the current model for that controller will be returned. If model_only is true, only the model name, not qualified by its controller name, will be returned. - ''' + """ # TODO respect JUJU_MODEL environment variable. if not controller_name: controller_name = self.current_controller() if not controller_name: - raise JujuError('No current controller') + raise JujuError("No current controller") models = self.models()[controller_name] - if 'current-model' not in models: + if "current-model" not in models: return None if model_only: - return models['current-model'] - return controller_name + ':' + models['current-model'] + return models["current-model"] + return controller_name + ":" + models["current-model"] def load_credential(self, cloud, name=None): """Load a local credential. @@ -113,19 +123,19 @@ def load_credential(self, cloud, name=None): :return: A CloudCredential instance, or None. """ try: - cloud = tag.untag('cloud-', cloud) + cloud = tag.untag("cloud-", cloud) creds_data = self.credentials()[cloud] if not name: - default_credential = creds_data.pop('default-credential', None) - default_region = creds_data.pop('default-region', None) # noqa + default_credential = creds_data.pop("default-credential", None) + default_region = creds_data.pop("default-region", None) # noqa if default_credential: - name = creds_data['default-credential'] + name = creds_data["default-credential"] elif len(creds_data) == 1: name = list(creds_data)[0] else: return None, None cred_data = creds_data[name] - auth_type = cred_data.pop('auth-type') + auth_type = cred_data.pop("auth-type") return name, jujuclient.CloudCredential( auth_type=auth_type, attrs=cred_data, @@ -148,19 +158,19 @@ def controller_name_by_endpoint(self, endpoint): return controller_name else: raise PylibjujuProgrammingError() - raise JujuError(f'Unable to find controller with endpoint {endpoint}') + raise JujuError(f"Unable to find controller with endpoint {endpoint}") def controllers(self): - return self._load_yaml('controllers.yaml', 'controllers') + return self._load_yaml("controllers.yaml", "controllers") def models(self): - return self._load_yaml('models.yaml', 'controllers') + return self._load_yaml("models.yaml", "controllers") def accounts(self): - return self._load_yaml('accounts.yaml', 'controllers') + return self._load_yaml("accounts.yaml", "controllers") def credentials(self): - return self._load_yaml('credentials.yaml', 'credentials') + return self._load_yaml("credentials.yaml", "credentials") def _load_yaml(self, filename, key): if filename in self._loaded: @@ -168,15 +178,15 @@ def _load_yaml(self, filename, key): return self._loaded[filename].get(key) # TODO use the file lock like Juju does. filepath = os.path.join(self.path, filename) - with io.open(filepath, 'rt') as f: + with io.open(filepath, "rt") as f: data = yaml.safe_load(f) self._loaded[filename] = data return data.get(key) def cookies_for_controller(self, controller_name): - f = pathlib.Path(self.path) / 'cookies' / (controller_name + '.json') + f = pathlib.Path(self.path) / "cookies" / (controller_name + ".json") if not f.exists(): - f = pathlib.Path('~/.go-cookies').expanduser() + f = pathlib.Path("~/.go-cookies").expanduser() # TODO if neither cookie file exists, where should # we create the cookies? jar = GoCookieJar(str(f)) diff --git a/juju/client/overrides.py b/juju/client/overrides.py index be3f2440d..fdead912c 100644 --- a/juju/client/overrides.py +++ b/juju/client/overrides.py @@ -8,17 +8,17 @@ from .facade import ReturnMapping, Type, TypeEncoder __all__ = [ - 'Delta', - 'Number', - 'Binary', - 'ConfigValue', - 'Resource', + "Delta", + "Number", + "Binary", + "ConfigValue", + "Resource", ] __patches__ = [ - 'ResourcesFacade', - 'AllWatcherFacade', - 'ActionFacade', + "ResourcesFacade", + "AllWatcherFacade", + "ActionFacade", ] @@ -38,8 +38,9 @@ class Delta(Type): Sphinx bug: https://github.com/sphinx-doc/sphinx/issues/2549 """ - _toSchema = {'deltas': 'deltas'} - _toPy = {'deltas': 'deltas'} + + _toSchema = {"deltas": "deltas"} + _toPy = {"deltas": "deltas"} def __init__(self, deltas=None): """ @@ -48,7 +49,7 @@ def __init__(self, deltas=None): """ self.deltas = deltas - Change = namedtuple('Change', 'entity type data') + Change = namedtuple("Change", "entity type data") change = Change(*self.deltas) self.entity = change.entity @@ -61,15 +62,12 @@ def from_json(cls, data): class ResourcesFacade(Type): - """Patch parts of ResourcesFacade to make it work. - """ + """Patch parts of ResourcesFacade to make it work.""" @ReturnMapping(_client.AddPendingResourcesResult) - async def AddPendingResources(self, - application_tag="", - charm_url="", - charm_origin=None, - resources=None): + async def AddPendingResources( + self, application_tag="", charm_url="", charm_origin=None, resources=None + ): """Fix the calling signature of AddPendingResources. The ResourcesFacade doesn't conform to the standard facade pattern in @@ -86,14 +84,16 @@ async def AddPendingResources(self, version = _client.ResourcesFacade.best_facade_version(self.connection) # map input types to rpc msg _params = dict() - msg = dict(type='Resources', - request='AddPendingResources', - version=version, - params=_params) - _params['tag'] = application_tag - _params['url'] = charm_url - _params['resources'] = resources - _params['charm-origin'] = charm_origin + msg = dict( + type="Resources", + request="AddPendingResources", + version=version, + params=_params, + ) + _params["tag"] = application_tag + _params["url"] = charm_url + _params["resources"] = resources + _params["charm-origin"] = charm_origin reply = await self.rpc(msg) return reply @@ -103,50 +103,48 @@ class AllWatcherFacade(Type): Patch rpc method of allwatcher to add in 'id' stuff. """ + async def rpc(self, msg): - if not hasattr(self, 'Id'): + if not hasattr(self, "Id"): client = _client.ClientFacade.from_connection(self.connection) result = await client.WatchAll() self.Id = result.watcher_id - msg['Id'] = self.Id + msg["Id"] = self.Id result = await self.connection.rpc(msg, encoder=TypeEncoder) return result class ActionFacade(Type): - class _FindTagsResults(Type): - _toSchema = {'matches': 'matches'} - _toPy = {'matches': 'matches'} + _toSchema = {"matches": "matches"} + _toPy = {"matches": "matches"} def __init__(self, matches=None, **unknown_fields): - ''' + """ FindTagsResults wraps the mapping between the requested prefix and the matching tags for each requested prefix. Matches map[string][]Entity `json:"matches"` - ''' + """ self.matches = {} matches = matches or {} for prefix, tags in matches.items(): - self.matches[prefix] = [_definitions.Entity.from_json(r) - for r in tags] + self.matches[prefix] = [_definitions.Entity.from_json(r) for r in tags] @ReturnMapping(_FindTagsResults) async def FindActionTagsByPrefix(self, prefixes): - ''' + """ prefixes : typing.Sequence[str] Returns -> typing.Sequence[~Entity] - ''' + """ # map input types to rpc msg _params = dict() - msg = dict(type='Action', - request='FindActionTagsByPrefix', - version=2, - params=_params) - _params['prefixes'] = prefixes + msg = dict( + type="Action", request="FindActionTagsByPrefix", version=2, params=_params + ) + _params["prefixes"] = prefixes reply = await self.rpc(msg) return reply @@ -160,26 +158,31 @@ class Number(_definitions.Number): See https://github.com/juju/version for more info. """ - numberPat = re.compile(r'^(\d{1,9})\.(\d{1,9})(?:\.|-([a-z]+))(\d{1,9})(\.\d{1,9})?$') # noqa - def __init__(self, major=None, minor=None, patch=None, tag=None, - build=None, **unknown_fields): - ''' + numberPat = re.compile( + r"^(\d{1,9})\.(\d{1,9})(?:\.|-([a-z]+))(\d{1,9})(\.\d{1,9})?$" + ) # noqa + + def __init__( + self, major=None, minor=None, patch=None, tag=None, build=None, **unknown_fields + ): + """ major : int minor : int patch : int tag : str build : int - ''' - self.major = int(major or '0') - self.minor = int(minor or '0') - self.patch = int(patch or '0') - self.tag = tag or '' - self.build = int(build or '0') + """ + self.major = int(major or "0") + self.minor = int(minor or "0") + self.patch = int(patch or "0") + self.tag = tag or "" + self.build = int(build or "0") def __repr__(self): - return ''.format( - self.major, self.minor, self.patch, self.tag, self.build) + return "".format( + self.major, self.minor, self.patch, self.tag, self.build + ) def __str__(self): return self.serialize() @@ -216,16 +219,14 @@ def from_json(cls, data): match = cls.numberPat.match(data) if match: parsed = { - 'major': match.group(1), - 'minor': match.group(2), - 'tag': match.group(3), - 'patch': match.group(4), - 'build': (match.group(5)[1:] if match.group(5) - else 0), + "major": match.group(1), + "minor": match.group(2), + "tag": match.group(3), + "patch": match.group(4), + "build": (match.group(5)[1:] if match.group(5) else 0), } if not parsed: - raise TypeError('Unable to parse Number version string: ' - '{}'.format(data)) + raise TypeError("Unable to parse Number version string: {}".format(data)) d = {} for k, v in parsed.items(): d[cls._toPy.get(k, k)] = v @@ -237,8 +238,7 @@ def serialize(self): if not self.tag: s = "{}.{}.{}".format(self.major, self.minor, self.patch) else: - s = "{}.{}-{}{}".format(self.major, self.minor, self.tag, - self.patch) + s = "{}.{}-{}{}".format(self.major, self.minor, self.tag, self.patch) if self.build: s = "{}.{}".format(s, self.build) return s @@ -256,31 +256,36 @@ class Binary(_definitions.Binary): See https://github.com/juju/version for more info. """ - binaryPat = re.compile(r'^(\d{1,9})\.(\d{1,9})(?:\.|-([a-z]+))(\d{1,9})(\.\d{1,9})?-([^-]+)-([^-]+)$') # noqa + + binaryPat = re.compile( + r"^(\d{1,9})\.(\d{1,9})(?:\.|-([a-z]+))(\d{1,9})(\.\d{1,9})?-([^-]+)-([^-]+)$" + ) # noqa def __init__(self, number=None, series=None, arch=None, **unknown_fields): - ''' + """ number : Number series : str arch : str - ''' + """ self.number = Number.from_json(number) self.series = series self.arch = arch def __repr__(self): - return ''.format( - self.number, self.series, self.arch) + return "".format( + self.number, self.series, self.arch + ) def __str__(self): return self.serialize() def __eq__(self, other): return ( - isinstance(other, type(self)) and - other.number == self.number and - other.series == self.series and - other.arch == self.arch) + isinstance(other, type(self)) + and other.number == self.number + and other.series == self.series + and other.arch == self.arch + ) @classmethod def from_json(cls, data): @@ -295,20 +300,18 @@ def from_json(cls, data): match = cls.binaryPat.match(data) if match: parsed = { - 'number': { - 'major': match.group(1), - 'minor': match.group(2), - 'tag': match.group(3), - 'patch': match.group(4), - 'build': (match.group(5)[1:] if match.group(5) - else 0), + "number": { + "major": match.group(1), + "minor": match.group(2), + "tag": match.group(3), + "patch": match.group(4), + "build": (match.group(5)[1:] if match.group(5) else 0), }, - 'series': match.group(6), - 'arch': match.group(7), + "series": match.group(6), + "arch": match.group(7), } if parsed is None: - raise TypeError('Unable to parse Binary version string: ' - '{}'.format(data)) + raise TypeError("Unable to parse Binary version string: {}".format(data)) d = {} for k, v in parsed.items(): d[cls._toPy.get(k, k)] = v @@ -316,8 +319,7 @@ def from_json(cls, data): return cls(**d) def serialize(self): - return "{}-{}-{}".format(self.number.serialize(), - self.series, self.arch) + return "{}-{}-{}".format(self.number.serialize(), self.series, self.arch) def to_json(self): return self.serialize() @@ -325,33 +327,46 @@ def to_json(self): class ConfigValue(_definitions.ConfigValue): def __repr__(self): - return '<{} source={} value={}>'.format(type(self).__name__, - repr(self.source), - repr(self.value)) + return "<{} source={} value={}>".format( + type(self).__name__, repr(self.source), repr(self.value) + ) class Resource(Type): - _toSchema = {'application': 'application', - 'charmresource': 'CharmResource', - 'id_': 'id', - 'pending_id': 'pending-id', - 'timestamp': 'timestamp', - 'username': 'username', - 'name': 'name', - 'origin': 'origin'} - _toPy = {'CharmResource': 'charmresource', - 'application': 'application', - 'id': 'id_', - 'pending-id': 'pending_id', - 'timestamp': 'timestamp', - 'username': 'username', - 'name': 'name', - 'origin': 'origin'} - - def __init__(self, charmresource=None, application=None, id_=None, - pending_id=None, timestamp=None, username=None, name=None, - origin=None, **unknown_fields): - ''' + _toSchema = { + "application": "application", + "charmresource": "CharmResource", + "id_": "id", + "pending_id": "pending-id", + "timestamp": "timestamp", + "username": "username", + "name": "name", + "origin": "origin", + } + _toPy = { + "CharmResource": "charmresource", + "application": "application", + "id": "id_", + "pending-id": "pending_id", + "timestamp": "timestamp", + "username": "username", + "name": "name", + "origin": "origin", + } + + def __init__( + self, + charmresource=None, + application=None, + id_=None, + pending_id=None, + timestamp=None, + username=None, + name=None, + origin=None, + **unknown_fields, + ): + """ charmresource : CharmResource application : str id_ : str @@ -360,7 +375,7 @@ def __init__(self, charmresource=None, application=None, id_=None, username : str name: str origin : str - ''' + """ if charmresource: self.charmresource = _client.CharmResource.from_json(charmresource) else: @@ -376,22 +391,28 @@ def __init__(self, charmresource=None, application=None, id_=None, class Macaroon(Type): - _toSchema = {'signature': 'signature', - 'caveats': 'caveats', - 'location': 'location', - 'identifier': 'identifier'} - _toPy = {'signature': 'signature', - 'caveats': 'caveats', - 'location': 'location', - 'identifier': 'identifier'} - - def __init__(self, signature="", caveats=None, location=None, identifier="", **unknown_fields): - ''' + _toSchema = { + "signature": "signature", + "caveats": "caveats", + "location": "location", + "identifier": "identifier", + } + _toPy = { + "signature": "signature", + "caveats": "caveats", + "location": "location", + "identifier": "identifier", + } + + def __init__( + self, signature="", caveats=None, location=None, identifier="", **unknown_fields + ): + """ signature : str caveats : typing.Sequence<+T_co>[~RemoteSpace]<~RemoteSpace> location : str identifier : str - ''' + """ self.signature = signature self.caveats = caveats self.location = location @@ -400,12 +421,12 @@ def __init__(self, signature="", caveats=None, location=None, identifier="", **u class Caveat(Type): - _toSchema = {'cid': 'cid'} - _toPy = {'cid': 'cid'} + _toSchema = {"cid": "cid"} + _toPy = {"cid": "cid"} def __init__(self, cid="", **unknown_fields): - ''' + """ cid : str - ''' + """ self.cid = cid self.unknown_fields = unknown_fields diff --git a/juju/client/proxy/factory.py b/juju/client/proxy/factory.py index 725d7dc59..24f760816 100644 --- a/juju/client/proxy/factory.py +++ b/juju/client/proxy/factory.py @@ -8,22 +8,22 @@ def proxy_from_config(conf): if conf is None: return None - if 'type' not in conf: + if "type" not in conf: return None - proxy_type = conf['type'] - if proxy_type != 'kubernetes-port-forward': - raise ValueError('unknown proxy type %s' % proxy_type) + proxy_type = conf["type"] + if proxy_type != "kubernetes-port-forward": + raise ValueError("unknown proxy type %s" % proxy_type) - return _construct_kube_proxy(conf['config']) + return _construct_kube_proxy(conf["config"]) def _construct_kube_proxy(config): return KubernetesProxy( - config.get('api-host', ''), - config.get('namespace', ''), - config.get('remote-port', ''), - config.get('service', ''), - config.get('service-account-token', ''), - config.get('ca-cert', None), + config.get("api-host", ""), + config.get("namespace", ""), + config.get("remote-port", ""), + config.get("service", ""), + config.get("service-account-token", ""), + config.get("ca-cert", None), ) diff --git a/juju/client/proxy/kubernetes/proxy.py b/juju/client/proxy/kubernetes/proxy.py index 3eb53c5c0..22adf7fcd 100644 --- a/juju/client/proxy/kubernetes/proxy.py +++ b/juju/client/proxy/kubernetes/proxy.py @@ -8,18 +8,18 @@ from kubernetes import client from kubernetes.stream import portforward -log = logging.getLogger('juju.client.connection') +log = logging.getLogger("juju.client.connection") class KubernetesProxy(Proxy): def __init__( - self, - api_host, - namespace, - remote_port, - service, - service_account_token, - ca_cert=None, + self, + api_host, + namespace, + remote_port, + service, + service_account_token, + ca_cert=None, ): config = client.Configuration() config.host = api_host @@ -37,7 +37,7 @@ def __init__( if ca_cert: self.temp_ca_file = tempfile.NamedTemporaryFile(delete=False) - self.temp_ca_file.write(bytes(ca_cert, 'utf-8')) + self.temp_ca_file.write(bytes(ca_cert, "utf-8")) self.temp_ca_file.flush() config.ssl_ca_cert = self.temp_ca_file.name @@ -47,7 +47,7 @@ def connect(self): corev1 = client.CoreV1Api(self.api_client) service = corev1.read_namespaced_service(self.service, self.namespace) - label_selector = ','.join(k + '=' + v for k, v in service.spec.selector.items()) + label_selector = ",".join(k + "=" + v for k, v in service.spec.selector.items()) pods = corev1.list_namespaced_pod( namespace=self.namespace, diff --git a/juju/client/proxy/proxy.py b/juju/client/proxy/proxy.py index 5105c5f6c..4cc55d7cd 100644 --- a/juju/client/proxy/proxy.py +++ b/juju/client/proxy/proxy.py @@ -10,7 +10,7 @@ class ProxyNotConnectedError(Exception): pass -class Proxy(): +class Proxy: """ Abstract class to represent a generic controller connection proxy """ diff --git a/juju/client/runner.py b/juju/client/runner.py index 9401718ff..87518b2cd 100644 --- a/juju/client/runner.py +++ b/juju/client/runner.py @@ -10,6 +10,7 @@ async def __call__(self, facade_method, *args, **kwargs): class ThreadedRunner: pass + # Methods are descriptors?? # get is called with params # set gets called with the result? diff --git a/juju/client/schemas-juju-3.1.0.json b/juju/client/schemas-juju-3.1.0.json index b33d9e459..5f6f003f3 100644 --- a/juju/client/schemas-juju-3.1.0.json +++ b/juju/client/schemas-juju-3.1.0.json @@ -17429,4 +17429,4 @@ } } } -] \ No newline at end of file +] diff --git a/juju/client/schemas-juju-3.1.10.json b/juju/client/schemas-juju-3.1.10.json index bd18742b3..fb47c9d77 100644 --- a/juju/client/schemas-juju-3.1.10.json +++ b/juju/client/schemas-juju-3.1.10.json @@ -17403,4 +17403,4 @@ } } } -] \ No newline at end of file +] diff --git a/juju/client/schemas-juju-3.1.5.json b/juju/client/schemas-juju-3.1.5.json index 302cf2074..37c1d514f 100644 --- a/juju/client/schemas-juju-3.1.5.json +++ b/juju/client/schemas-juju-3.1.5.json @@ -17409,4 +17409,4 @@ } } } -] \ No newline at end of file +] diff --git a/juju/client/schemas-juju-3.3.0.json b/juju/client/schemas-juju-3.3.0.json index 6cc880648..0da05ac0c 100644 --- a/juju/client/schemas-juju-3.3.0.json +++ b/juju/client/schemas-juju-3.3.0.json @@ -18201,4 +18201,4 @@ } } } -] \ No newline at end of file +] diff --git a/juju/client/schemas-juju-3.3.7.json b/juju/client/schemas-juju-3.3.7.json index 88e8102d4..9fd15a94c 100644 --- a/juju/client/schemas-juju-3.3.7.json +++ b/juju/client/schemas-juju-3.3.7.json @@ -18227,4 +18227,4 @@ } } } -] \ No newline at end of file +] diff --git a/juju/client/schemas-juju-3.4.6.json b/juju/client/schemas-juju-3.4.6.json index 88e8102d4..9fd15a94c 100644 --- a/juju/client/schemas-juju-3.4.6.json +++ b/juju/client/schemas-juju-3.4.6.json @@ -18227,4 +18227,4 @@ } } } -] \ No newline at end of file +] diff --git a/juju/client/schemas-juju-3.5.4.json b/juju/client/schemas-juju-3.5.4.json index e9c69b086..06c042866 100644 --- a/juju/client/schemas-juju-3.5.4.json +++ b/juju/client/schemas-juju-3.5.4.json @@ -18020,4 +18020,4 @@ } } } -] \ No newline at end of file +] diff --git a/juju/client/schemas-juju-3.6-rc1.json b/juju/client/schemas-juju-3.6-rc1.json index 9aa310a17..8c46189b0 100644 --- a/juju/client/schemas-juju-3.6-rc1.json +++ b/juju/client/schemas-juju-3.6-rc1.json @@ -17832,4 +17832,4 @@ } } } -] \ No newline at end of file +] diff --git a/juju/constraints.py b/juju/constraints.py index 44ee5fbe1..c9b3ab710 100644 --- a/juju/constraints.py +++ b/juju/constraints.py @@ -24,18 +24,18 @@ # Matches on a string specifying memory size -MEM = re.compile('^[1-9][0-9]*[MGTP]$') +MEM = re.compile("^[1-9][0-9]*[MGTP]$") # Multiplication factors to get Megabytes # https://github.com/juju/juju/blob/master/constraints/constraints.go#L666 FACTORS = { - "M": 1024 ** 0, - "G": 1024 ** 1, - "T": 1024 ** 2, - "P": 1024 ** 3, - "E": 1024 ** 4, - "Z": 1024 ** 5, - "Y": 1024 ** 6 + "M": 1024**0, + "G": 1024**1, + "T": 1024**2, + "P": 1024**3, + "E": 1024**4, + "Z": 1024**5, + "Y": 1024**6, } # List of supported constraint keys, see @@ -58,10 +58,10 @@ "allocate_public_ip", ] -LIST_KEYS = {'tags', 'spaces', 'zones'} +LIST_KEYS = {"tags", "spaces", "zones"} -SNAKE1 = re.compile(r'(.)([A-Z][a-z]+)') -SNAKE2 = re.compile('([a-z0-9])([A-Z])') +SNAKE1 = re.compile(r"(.)([A-Z][a-z]+)") +SNAKE2 = re.compile("([a-z0-9])([A-Z])") ParsedValue = Union[int, bool, str] @@ -95,7 +95,7 @@ def parse(constraints: Union[str, ConstraintsDict]) -> Optional[ConstraintsDict] return None if isinstance(constraints, dict): - # Fowards compatibilty: already parsed + # Forwards compatibility: already parsed return constraints normalized_constraints: ConstraintsDict = {} @@ -105,9 +105,7 @@ def parse(constraints: Union[str, ConstraintsDict]) -> Optional[ConstraintsDict] k, v = s.split("=") normalized_constraints[normalize_key(k)] = ( - normalize_list_value(v) - if k in LIST_KEYS - else normalize_value(v) + normalize_list_value(v) if k in LIST_KEYS else normalize_value(v) ) return normalized_constraints @@ -119,8 +117,8 @@ def normalize_key(orig_key: str) -> str: key = key.replace("-", "_") # Our _client lib wants "_" in place of "-" # Convert camelCase to snake_case - key = SNAKE1.sub(r'\1_\2', key) - key = SNAKE2.sub(r'\1_\2', key).lower() + key = SNAKE1.sub(r"\1_\2", key) + key = SNAKE2.sub(r"\1_\2", key).lower() if key not in SUPPORTED_KEYS: raise ValueError("unknown constraint in %s" % orig_key) @@ -137,16 +135,16 @@ def normalize_value(value: str) -> Union[int, bool, str]: if value.isdigit(): return int(value) - if value.lower() == 'true': + if value.lower() == "true": return True - if value.lower() == 'false': + if value.lower() == "false": return False return value def normalize_list_value(value: str) -> List[ParsedValue]: - values = value.strip().split(',') + values = value.strip().split(",") return [normalize_value(value) for value in values] @@ -154,18 +152,18 @@ def normalize_list_value(value: str) -> List[ParsedValue]: # original regex: # '(?:(?:^|(?<=,))(?:|(?P[a-zA-Z]+[-?a-zA-Z0-9]*)|(?P-?[0-9]+)|(?:(?P-?[0-9]+(?:\\.[0-9]+)?)(?P[MGTPEZY])(?:i?B)?))(?:$|,))' # with formatting and explanation -- note that this regex is used with re.finditer: - '(?:' - '(?:^|(?<=,))' # start of string or previous match ends with ',' - '(?:' # match one of the following: - '|(?P[a-zA-Z]+[-?a-zA-Z0-9]*)' # * pool: a sequence starting with a letter, ending with a letter or number, - # ------- and including letters, numbers and hyphens (no more than one in a row) - '|(?P-?[0-9]+)' # * count: an optional minus sign followed by one or more digits - '|(?:' # * size (number) and size_exp (units): - '(?P-?[0-9]+(?:\\.[0-9]+)?)' # -- * an optional minus sign followed by one or more digits, optionally with decimal point and more digits - '(?P[MGTPEZY])(?:i?B)?)' # -- * one of MGTPEZY, optionally followed by iB or B, for example 1M or 2.0MB or -3.3MiB - ')' - '(?:$|,)' # end of string or ',' - ')' + "(?:" + "(?:^|(?<=,))" # start of string or previous match ends with ',' + "(?:" # match one of the following: + "|(?P[a-zA-Z]+[-?a-zA-Z0-9]*)" # * pool: a sequence starting with a letter, ending with a letter or number, + # ------- and including letters, numbers and hyphens (no more than one in a row) + "|(?P-?[0-9]+)" # * count: an optional minus sign followed by one or more digits + "|(?:" # * size (number) and size_exp (units): + "(?P-?[0-9]+(?:\\.[0-9]+)?)" # -- * an optional minus sign followed by one or more digits, optionally with decimal point and more digits + "(?P[MGTPEZY])(?:i?B)?)" # -- * one of MGTPEZY, optionally followed by iB or B, for example 1M or 2.0MB or -3.3MiB + ")" + "(?:$|,)" # end of string or ',' + ")" ) @@ -176,20 +174,20 @@ class StorageConstraintDict(TypedDict): def parse_storage_constraint(constraint: str) -> StorageConstraintDict: - storage: StorageConstraintDict = {'count': 1} + storage: StorageConstraintDict = {"count": 1} for m in STORAGE.finditer(constraint): - pool = m.group('pool') + pool = m.group("pool") if pool: - if 'pool' in storage: + if "pool" in storage: raise ValueError("pool already specified") - storage['pool'] = pool - count = m.group('count') + storage["pool"] = pool + count = m.group("count") if count: count = int(count) - storage['count'] = count if count > 0 else 1 - size = m.group('size') + storage["count"] = count if count > 0 else 1 + size = m.group("size") if size: - storage['size'] = int(float(size) * FACTORS[m.group('size_exp')]) + storage["size"] = int(float(size) * FACTORS[m.group("size_exp")]) return storage @@ -197,19 +195,19 @@ def parse_storage_constraint(constraint: str) -> StorageConstraintDict: # original regex: # '^(?P[0-9]+)?(?:^|,)(?P[^,]+)(?:$|,(?!$))(?P(?:[^=]+=[^;]+)+)*$' # with formatting and explanation -- note this regex is used with re.match: - '^' # start of string - '(?P[0-9]+)?' # count is 1+ digits, and is optional - '(?:^|,)' # match start of string or a comma - # -- so type can be at the start or comma separated from count - '(?P[^,]+)' # type is 1+ anything not a comma (including digits), and is required - '(?:$|,(?!$))' # match end of string | or a non-trailing comma - # -- so type can be at the end or followed by attrs - '(?P(?:[^=]+=[^;]+)+)*' # attrs is any number of semicolon separated key=value items - # -- value can have spare '=' inside, possible not intended - # -- attrs will be matched with ATTR.finditer afterwards in parse_device_constraint - '$' # end of string + "^" # start of string + "(?P[0-9]+)?" # count is 1+ digits, and is optional + "(?:^|,)" # match start of string or a comma + # -- so type can be at the start or comma separated from count + "(?P[^,]+)" # type is 1+ anything not a comma (including digits), and is required + "(?:$|,(?!$))" # match end of string | or a non-trailing comma + # -- so type can be at the end or followed by attrs + "(?P(?:[^=]+=[^;]+)+)*" # attrs is any number of semicolon separated key=value items + # -- value can have spare '=' inside, possible not intended + # -- attrs will be matched with ATTR.finditer afterwards in parse_device_constraint + "$" # end of string ) -ATTR = re.compile(';?(?P[^=]+)=(?P[^;]+)') +ATTR = re.compile(";?(?P[^=]+)=(?P[^;]+)") class DeviceConstraintDict(TypedDict): @@ -223,15 +221,16 @@ def parse_device_constraint(constraint: str) -> DeviceConstraintDict: if m is None: raise ValueError("device constraint does not match") device: DeviceConstraintDict = {} - count = m.group('count') + count = m.group("count") if count: count = int(count) - device['count'] = count if count > 0 else 1 + device["count"] = count if count > 0 else 1 else: - device['count'] = 1 - device['type'] = m.group('type') - attrs = m.group('attrs') + device["count"] = 1 + device["type"] = m.group("type") + attrs = m.group("attrs") if attrs: - device['attributes'] = {match.group('key'): match.group('value') - for match in ATTR.finditer(attrs)} + device["attributes"] = { + match.group("key"): match.group("value") for match in ATTR.finditer(attrs) + } return device diff --git a/juju/controller.py b/juju/controller.py index d2cb1f2c7..351f942e2 100644 --- a/juju/controller.py +++ b/juju/controller.py @@ -97,45 +97,49 @@ async def connect(self, *args, **kwargs): specified facades. """ await self.disconnect() - if 'endpoint' not in kwargs and len(args) < 2: - if args and 'model_name' in kwargs: - raise TypeError('connect() got multiple values for ' - 'controller_name') + if "endpoint" not in kwargs and len(args) < 2: + if args and "model_name" in kwargs: + raise TypeError("connect() got multiple values for controller_name") elif args: controller_name = args[0] else: - controller_name = kwargs.pop('controller_name', None) + controller_name = kwargs.pop("controller_name", None) await self._connector.connect_controller(controller_name, **kwargs) else: - if 'controller_name' in kwargs: - raise TypeError('connect() got values for both ' - 'controller_name and endpoint') - if args and 'endpoint' in kwargs: - raise TypeError('connect() got multiple values for endpoint') - has_userpass = (len(args) >= 3 or - {'username', 'password'}.issubset(kwargs)) - has_macaroons = (len(args) >= 5 or not - {'bakery_client', 'macaroons'}.isdisjoint(kwargs)) + if "controller_name" in kwargs: + raise TypeError( + "connect() got values for both controller_name and endpoint" + ) + if args and "endpoint" in kwargs: + raise TypeError("connect() got multiple values for endpoint") + has_userpass = len(args) >= 3 or {"username", "password"}.issubset(kwargs) + has_macaroons = len(args) >= 5 or not { + "bakery_client", + "macaroons", + }.isdisjoint(kwargs) if not (has_userpass or has_macaroons): - raise TypeError('connect() missing auth params') + raise TypeError("connect() missing auth params") arg_names = [ - 'endpoint', - 'username', - 'password', - 'cacert', - 'bakery_client', - 'macaroons', - 'max_frame_size', + "endpoint", + "username", + "password", + "cacert", + "bakery_client", + "macaroons", + "max_frame_size", ] for i, arg in enumerate(args): kwargs[arg_names[i]] = arg - if 'endpoint' not in kwargs: - raise ValueError('endpoint is required ' - 'if controller_name not given') - if not ({'username', 'password'}.issubset(kwargs) or - {'bakery_client', 'macaroons'}.intersection(kwargs)): - raise ValueError('Authentication parameters are required ' - 'if controller_name not given') + if "endpoint" not in kwargs: + raise ValueError("endpoint is required if controller_name not given") + if not ( + {"username", "password"}.issubset(kwargs) + or {"bakery_client", "macaroons"}.intersection(kwargs) + ): + raise ValueError( + "Authentication parameters are required " + "if controller_name not given" + ) await self._connector.connect(**kwargs) await self.update_endpoints() @@ -143,11 +147,12 @@ async def update_endpoints(self): try: info = await self.info() self._connector._connection.endpoints = [ - (e, info.results[0].cacert) - for e in info.results[0].addresses + (e, info.results[0].cacert) for e in info.results[0].addresses ] except errors.JujuPermissionError: - log.warning("This user doesn't have at least read access to the controller model, so endpoints are not updated after connection.") + log.warning( + "This user doesn't have at least read access to the controller model, so endpoints are not updated after connection." + ) pass async def connect_current(self): @@ -181,10 +186,15 @@ def connection(self): def controller_name(self): if not self._controller_name: try: - self._controller_name = self._connector.jujudata.controller_name_by_endpoint( - self._connector.connection().endpoint) + self._controller_name = ( + self._connector.jujudata.controller_name_by_endpoint( + self._connector.connection().endpoint + ) + ) except FileNotFoundError: - raise errors.PylibjujuError("Unable to determine controller name. controllers.yaml not found.") + raise errors.PylibjujuError( + "Unable to determine controller name. controllers.yaml not found." + ) return self._controller_name @property @@ -201,13 +211,12 @@ async def api_endpoints(self): return info.results[0].addresses async def disconnect(self): - """Shut down the watcher task and close websockets. + """Shut down the watcher task and close websockets.""" + await self._connector.disconnect(entity="controller") - """ - await self._connector.disconnect(entity='controller') - - async def add_credential(self, name=None, credential=None, cloud=None, - owner=None, force=False): + async def add_credential( + self, name=None, credential=None, cloud=None, owner=None, force=False + ): """Add or update a credential to the controller. :param str name: Name of new credential. If None, the default @@ -228,45 +237,45 @@ async def add_credential(self, name=None, credential=None, cloud=None, cloud = await self.get_cloud() if not owner: - owner = self.connection().info['user-info']['identity'] + owner = self.connection().info["user-info"]["identity"] if credential and not name: - raise errors.JujuError('Name must be provided for credential') + raise errors.JujuError("Name must be provided for credential") if not credential: - name, credential = self._connector.jujudata.load_credential(cloud, - name) + name, credential = self._connector.jujudata.load_credential(cloud, name) if credential is None: - raise errors.JujuError( - 'Unable to find credential: {}'.format(name)) + raise errors.JujuError("Unable to find credential: {}".format(name)) - if credential.auth_type == 'jsonfile' and 'file' in credential.attrs: + if credential.auth_type == "jsonfile" and "file" in credential.attrs: # file creds have to be loaded before being sent to the controller try: # it might already be JSON - json.loads(credential.attrs['file']) + json.loads(credential.attrs["file"]) except json.JSONDecodeError: # not valid JSON, so maybe it's a file - cred_path = Path(credential.attrs['file']) + cred_path = Path(credential.attrs["file"]) if cred_path.exists(): # make a copy cred_json = credential.to_json() credential = client.CloudCredential.from_json(cred_json) # inline the cred - credential.attrs['file'] = cred_path.read_text() + credential.attrs["file"] = cred_path.read_text() - log.debug('Uploading credential %s', name) + log.debug("Uploading credential %s", name) cloud_facade = client.CloudFacade.from_connection(self.connection()) tagged_credentials = [ client.TaggedCredential( - tag=tag.credential(cloud, tag.untag('user-', owner), name), + tag=tag.credential(cloud, tag.untag("user-", owner), name), credential=credential, - )] + ) + ] if cloud_facade.version >= 3: # UpdateCredentials was renamed to UpdateCredentialsCheckModels # in facade version 3. await cloud_facade.UpdateCredentialsCheckModels( - credentials=tagged_credentials, force=force, + credentials=tagged_credentials, + force=force, ) else: await cloud_facade.UpdateCredentials(credentials=tagged_credentials) @@ -279,7 +288,7 @@ async def add_cloud(self, name, cloud): :param Cloud cloud: Cloud configuration. :return Cloud: Cloud that was created. """ - log.debug('Adding cloud %s', name) + log.debug("Adding cloud %s", name) cloud_facade = client.CloudFacade.from_connection(self.connection()) await cloud_facade.AddCloud(cloud=cloud, name=name) result = await self.cloud(name=name) @@ -290,10 +299,10 @@ async def info(self): :return ControllerAPIInfoResult """ - log.debug('Getting information') + log.debug("Getting information") uuids = await self.model_uuids() - if 'controller' not in uuids: - raise errors.JujuPermissionError('Requires access to controller model.') + if "controller" not in uuids: + raise errors.JujuPermissionError("Requires access to controller model.") controller_facade = client.ControllerFacade.from_connection(self.connection()) params = [client.Entity(tag.model(uuids["controller"]))] return await controller_facade.ControllerAPIInfoForModels(entities=params) @@ -303,13 +312,19 @@ async def remove_cloud(self, name): :param str name: Name of the cloud to remove. """ - log.debug('Removing cloud %s', name) + log.debug("Removing cloud %s", name) cloud_facade = client.CloudFacade.from_connection(self.connection()) await cloud_facade.RemoveClouds(entities=[client.Entity(tag.cloud(name))]) async def add_model( - self, model_name, cloud_name=None, credential_name=None, - owner=None, config=None, region=None): + self, + model_name, + cloud_name=None, + credential_name=None, + owner=None, + config=None, + region=None, + ): """Add a model to this controller. :param str model_name: Name to give the new model. @@ -324,36 +339,32 @@ async def add_model( :param str region: Region in which to create the model. :return Model: A connection to the newly created model. """ - model_facade = client.ModelManagerFacade.from_connection( - self.connection()) + model_facade = client.ModelManagerFacade.from_connection(self.connection()) - owner = owner or self.connection().info['user-info']['identity'] + owner = owner or self.connection().info["user-info"]["identity"] cloud_name = cloud_name or await self.get_cloud() try: # attempt to add/update the credential from local data if available credential_name = await self.add_credential( - name=credential_name, - cloud=cloud_name, - owner=owner) + name=credential_name, cloud=cloud_name, owner=owner + ) except errors.JujuError: # if it's not available locally, assume it's on the controller pass if credential_name: credential = tag.credential( - cloud_name, - tag.untag('user-', owner), - credential_name + cloud_name, tag.untag("user-", owner), credential_name ) else: credential = None - log.debug('Creating model %s', model_name) + log.debug("Creating model %s", model_name) - if not config or 'authorized-keys' not in config: + if not config or "authorized-keys" not in config: config = config or {} - config['authorized-keys'] = await utils.read_ssh_key() + config["authorized-keys"] = await utils.read_ssh_key() model_info = await model_facade.CreateModel( cloud_tag=tag.cloud(cloud_name), @@ -361,18 +372,21 @@ async def add_model( credential=credential, name=model_name, owner_tag=owner, - region=region + region=region, ) from juju.model import Model + model = Model(jujudata=self._connector.jujudata) kwargs = self.connection().connect_params() - kwargs['uuid'] = model_info.uuid + kwargs["uuid"] = model_info.uuid model._info = model_info await model._connect_direct(**kwargs) return model - async def destroy_models(self, *models, destroy_storage=False, force=False, max_wait=None): + async def destroy_models( + self, *models, destroy_storage=False, force=False, max_wait=None + ): """Destroy one or more models. :param str *models: Names or UUIDs of models to destroy @@ -384,16 +398,12 @@ async def destroy_models(self, *models, destroy_storage=False, force=False, max_ """ uuids = await self.model_uuids() - models = [uuids[model] if model in uuids else model - for model in models] + models = [uuids[model] if model in uuids else model for model in models] - model_facade = client.ModelManagerFacade.from_connection( - self.connection()) + model_facade = client.ModelManagerFacade.from_connection(self.connection()) log.debug( - 'Destroying model%s %s', - '' if len(models) == 1 else 's', - ', '.join(models) + "Destroying model%s %s", "" if len(models) == 1 else "s", ", ".join(models) ) if model_facade.version >= 5: @@ -404,12 +414,14 @@ async def destroy_models(self, *models, destroy_storage=False, force=False, max_ force=force, max_wait=max_wait, ) - for model in models] + for model in models + ] await model_facade.DestroyModels(models=params) else: params = [client.Entity(tag.model(model)) for model in models] await model_facade.DestroyModels(entities=params) + destroy_model = destroy_models async def add_user(self, username, password=None, display_name=None): @@ -422,20 +434,19 @@ async def add_user(self, username, password=None, display_name=None): """ if not display_name: display_name = username - user_facade = client.UserManagerFacade.from_connection( - self.connection()) - users = [client.AddUser(display_name=display_name, - username=username, - password=password)] + user_facade = client.UserManagerFacade.from_connection(self.connection()) + users = [ + client.AddUser( + display_name=display_name, username=username, password=password + ) + ] results = await user_facade.AddUser(users=users) secret_key = results.results[0].secret_key return await self.get_user(username, secret_key=secret_key) async def remove_user(self, username): - """Remove a user from this controller. - """ - client_facade = client.UserManagerFacade.from_connection( - self.connection()) + """Remove a user from this controller.""" + client_facade = client.UserManagerFacade.from_connection(self.connection()) user = tag.user(username) await client_facade.RemoveUser(entities=[client.Entity(user)]) @@ -446,8 +457,7 @@ async def change_user_password(self, username, password): :param str password: New password """ - user_facade = client.UserManagerFacade.from_connection( - self.connection()) + user_facade = client.UserManagerFacade.from_connection(self.connection()) entity = client.EntityPassword(password=password, tag=tag.user(username)) return await user_facade.SetPassword(changes=[entity]) @@ -457,8 +467,7 @@ async def reset_user_password(self, username): :param str username: Username :returns: A :class:`~juju.user.User` instance """ - user_facade = client.UserManagerFacade.from_connection( - self.connection()) + user_facade = client.UserManagerFacade.from_connection(self.connection()) entity = client.Entity(tag.user(username)) results = await user_facade.ResetPassword(entities=[entity]) secret_key = results.results[0].secret_key @@ -469,12 +478,13 @@ async def destroy(self, destroy_all_models=False, destroy_storage=False): :param bool destroy_all_models: Destroy all hosted models in the controller. - :param bool destroy_storage: Destory all hosted storage in the + :param bool destroy_storage: Destroy all hosted storage in the controller. """ - controller_facade = client.ControllerFacade.from_connection( - self.connection()) - return await controller_facade.DestroyController(destroy_models=destroy_all_models, destroy_storage=destroy_storage) + controller_facade = client.ControllerFacade.from_connection(self.connection()) + return await controller_facade.DestroyController( + destroy_models=destroy_all_models, destroy_storage=destroy_storage + ) async def disable_user(self, username): """Disable a user. @@ -482,17 +492,13 @@ async def disable_user(self, username): :param str username: Username """ - user_facade = client.UserManagerFacade.from_connection( - self.connection()) + user_facade = client.UserManagerFacade.from_connection(self.connection()) entity = client.Entity(tag.user(username)) return await user_facade.DisableUser(entities=[entity]) async def enable_user(self, username): - """Re-enable a previously disabled user. - - """ - user_facade = client.UserManagerFacade.from_connection( - self.connection()) + """Re-enable a previously disabled user.""" + user_facade = client.UserManagerFacade.from_connection(self.connection()) entity = client.Entity(tag.user(username)) return await user_facade.EnableUser(entities=[entity]) @@ -510,7 +516,9 @@ async def get_model_info(self, model_name=None, model_uuid=None): """ if model_uuid is None and model_name is None: - raise errors.JujuError("get_model_info requires either a name or a uuid for a model") + raise errors.JujuError( + "get_model_info requires either a name or a uuid for a model" + ) facade = client.ModelManagerFacade.from_connection(self.connection()) if model_uuid is None: @@ -518,7 +526,11 @@ async def get_model_info(self, model_name=None, model_uuid=None): try: model_uuid = uuids[model_name] except KeyError: - raise errors.JujuError("{} is not among the models in the controller : {}".format(model_name, uuids)) + raise errors.JujuError( + "{} is not among the models in the controller : {}".format( + model_name, uuids + ) + ) entity = client.Entity(tag.model(model_uuid)) _model_info_results = await facade.ModelInfo(entities=[entity]) return _model_info_results.results[0].result @@ -559,7 +571,7 @@ async def get_cloud(self): result = await cloud_facade.Clouds() cloud = list(result.clouds.keys())[0] # only lives on one cloud - return tag.untag('cloud-', cloud) + return tag.untag("cloud-", cloud) async def get_models(self, all=False, username=None): """ @@ -579,14 +591,19 @@ async def model_uuids(self, username=None, all=False): :returns: {str name : str UUID} """ - model_manager_facade = client.ModelManagerFacade.from_connection(self.connection()) + model_manager_facade = client.ModelManagerFacade.from_connection( + self.connection() + ) u_name = username if username else self.get_current_username() user = tag.user(u_name) - user_model_list = await model_manager_facade.ListModelSummaries(user_tag=user, all_=all) + user_model_list = await model_manager_facade.ListModelSummaries( + user_tag=user, all_=all + ) model_summaries = [msr.result for msr in user_model_list.results] - return {model_summary.name: model_summary.uuid - for model_summary in model_summaries} + return { + model_summary.name: model_summary.uuid for model_summary in model_summaries + } async def list_models(self, username=None, all=False): """Return list of names of the available models on this controller. @@ -625,9 +642,10 @@ async def get_model(self, model): uuid = model from juju.model import Model + model = Model() kwargs = self.connection().connect_params() - kwargs['uuid'] = uuid + kwargs["uuid"] = uuid await model._connect_direct(**kwargs) return model @@ -639,14 +657,15 @@ async def get_user(self, username, secret_key=None): password :returns: A :class:`~juju.user.User` instance """ - client_facade = client.UserManagerFacade.from_connection( - self.connection()) + client_facade = client.UserManagerFacade.from_connection(self.connection()) user = tag.user(username) args = [client.Entity(user)] try: - response = await client_facade.UserInfo(entities=args, include_disabled=True) + response = await client_facade.UserInfo( + entities=args, include_disabled=True + ) except errors.JujuError as e: - if 'permission denied' in e.errors: + if "permission denied" in e.errors: # apparently, trying to get info for a nonexistent user returns # a "permission denied" error rather than an empty result set return None @@ -661,12 +680,13 @@ async def get_users(self, include_disabled=False): :param bool include_disabled: Include disabled users :returns: A list of :class:`~juju.user.User` instances """ - client_facade = client.UserManagerFacade.from_connection( - self.connection()) - response = await client_facade.UserInfo(entities=None, include_disabled=include_disabled) + client_facade = client.UserManagerFacade.from_connection(self.connection()) + response = await client_facade.UserInfo( + entities=None, include_disabled=include_disabled + ) return [User(self, r.result) for r in response.results] - async def grant(self, username, acl='login'): + async def grant(self, username, acl="login"): """Grant access level of the given user on the controller. Note that if the user already has higher permissions than the provided ACL, this will do nothing (see revoke for a way to @@ -676,20 +696,19 @@ async def grant(self, username, acl='login'): :returns: True if new access was granted, False if user already had requested access or greater. Raises JujuError if failed. """ - controller_facade = client.ControllerFacade.from_connection( - self.connection()) + controller_facade = client.ControllerFacade.from_connection(self.connection()) user = tag.user(username) - changes = client.ModifyControllerAccess(acl, 'grant', user) + changes = client.ModifyControllerAccess(acl, "grant", user) try: await controller_facade.ModifyControllerAccess(changes=[changes]) return True except errors.JujuError as e: - if 'user already has' in str(e): + if "user already has" in str(e): return False else: raise - async def revoke(self, username, acl='login'): + async def revoke(self, username, acl="login"): """Removes some or all access of a user to from a controller If 'login' access is revoked, the user will no longer have any permissions on the controller. Revoking a higher privilege from @@ -698,13 +717,12 @@ async def revoke(self, username, acl='login'): :param str username: username :param str acl: Access to remove ('login', 'add-model' or 'superuser') """ - controller_facade = client.ControllerFacade.from_connection( - self.connection()) + controller_facade = client.ControllerFacade.from_connection(self.connection()) user = tag.user(username) - changes = client.ModifyControllerAccess(acl, 'revoke', user) + changes = client.ModifyControllerAccess(acl, "revoke", user) return await controller_facade.ModifyControllerAccess(changes=[changes]) - async def grant_model(self, username, model_uuid, acl='read'): + async def grant_model(self, username, model_uuid, acl="read"): """Grant a user access to a model. Note that if the user already has higher permissions than the provided ACL, this will do nothing (see revoke_model for a way to remove @@ -714,14 +732,13 @@ async def grant_model(self, username, model_uuid, acl='read'): :param str model_uuid: The UUID of the model to change. :param str acl: Access control ('read, 'write' or 'admin') """ - model_facade = client.ModelManagerFacade.from_connection( - self.connection()) + model_facade = client.ModelManagerFacade.from_connection(self.connection()) user = tag.user(username) model = tag.model(model_uuid) - changes = client.ModifyModelAccess(acl, 'grant', model, user) + changes = client.ModifyModelAccess(acl, "grant", model, user) return await model_facade.ModifyModelAccess(changes=[changes]) - async def revoke_model(self, username, model_uuid, acl='read'): + async def revoke_model(self, username, model_uuid, acl="read"): """Revoke some or all of a user's access to a model. If 'read' access is revoked, the user will no longer have any permissions on the model. Revoking a higher privilege from @@ -731,14 +748,15 @@ async def revoke_model(self, username, model_uuid, acl='read'): :param str model_uuid: The UUID of the model to change. :param str acl: Access control ('read, 'write' or 'admin') """ - model_facade = client.ModelManagerFacade.from_connection( - self.connection()) + model_facade = client.ModelManagerFacade.from_connection(self.connection()) user = tag.user(username) model = tag.model(model_uuid) - changes = client.ModifyModelAccess(acl, 'revoke', model, user) + changes = client.ModifyModelAccess(acl, "revoke", model, user) return await model_facade.ModifyModelAccess(changes=[changes]) - async def create_offer(self, model_uuid, endpoint, offer_name=None, application_name=None): + async def create_offer( + self, model_uuid, endpoint, offer_name=None, application_name=None + ): """ Offer a deployed application using a series of endpoints for use by consumers. @@ -806,7 +824,9 @@ async def remove_offer(self, model_uuid, offer, force=False): if offer_source == "": offer_source = self.controller_name if not force: - raise RemoveError("removing offer will also remove relations, use force and try again.") + raise RemoveError( + "removing offer will also remove relations, use force and try again." + ) facade = client.ApplicationOffersFacade.from_connection(self.connection()) return await facade.DestroyOffers(force=force, offer_urls=[url.string()]) @@ -817,7 +837,9 @@ async def get_consume_details(self, endpoint): model to consume the specified offers represented by the urls. """ facade = client.ApplicationOffersFacade.from_connection(self.connection()) - offers = await facade.GetConsumeDetails(offer_urls=client.OfferURLs(offer_urls=[endpoint])) + offers = await facade.GetConsumeDetails( + offer_urls=client.OfferURLs(offer_urls=[endpoint]) + ) if len(offers.results) != 1: raise JujuAPIError("expected to find one result") result = offers.results[0] @@ -838,10 +860,10 @@ async def watch_model_summaries(self, callback, as_admin=False): async def _watcher(stop_event): try: - facade = client.ControllerFacade.from_connection( - self.connection()) + facade = client.ControllerFacade.from_connection(self.connection()) watcher = client.ModelSummaryWatcherFacade.from_connection( - self.connection()) + self.connection() + ) if as_admin: result = await facade.WatchAllModelSummaries() watcher.Id = result.watcher_id @@ -853,11 +875,10 @@ async def _watcher(stop_event): while True: try: results = await utils.run_with_interrupt( - watcher.Next(), - stop_event, - log=log) + watcher.Next(), stop_event, log=log + ) except JujuAPIError as e: - if 'watcher was stopped' not in str(e): + if "watcher was stopped" not in str(e): raise except websockets.ConnectionClosed: break @@ -872,10 +893,10 @@ async def _watcher(stop_event): except CancelledError: pass except Exception: - log.exception('Error in watcher') + log.exception("Error in watcher") raise - log.debug('Starting watcher task for model summaries') + log.debug("Starting watcher task for model summaries") jasyncio.ensure_future(_watcher(stop_event)) return stop_event @@ -899,13 +920,15 @@ async def add_secret_backends(self, id, name, backend_type, config): a list of errors if any """ facade = client.SecretBackendsFacade.from_connection(self.connection()) - return await facade.AddSecretBackends([{ - 'id': id, - 'backend-type': backend_type, - 'config': config, - 'name': name, - 'token-rotate-interval': config.get('token-rotate-interval', None), - }]) + return await facade.AddSecretBackends([ + { + "id": id, + "backend-type": backend_type, + "config": config, + "name": name, + "token-rotate-interval": config.get("token-rotate-interval", None), + } + ]) async def list_secret_backends(self, reveal=False): """ @@ -938,12 +961,16 @@ async def remove_secret_backends(self, name, force=False): error if any """ facade = client.SecretBackendsFacade.from_connection(self.connection()) - return await facade.RemoveSecretBackends([{ - 'name': name, - 'force': force - }]) + return await facade.RemoveSecretBackends([{"name": name, "force": force}]) - async def update_secret_backends(self, name, config=None, force=False, name_change=None, token_rotate_interval=None): + async def update_secret_backends( + self, + name, + config=None, + force=False, + name_change=None, + token_rotate_interval=None, + ): """ Update a backend. @@ -954,20 +981,22 @@ async def update_secret_backends(self, name, config=None, force=False, name_chan config : dict key value dict with configuration parameters force : boolean - true to force the upate process + true to force the update process name_change : string new name for the backend token_rotate_interval : int token rotation interval """ facade = client.SecretBackendsFacade.from_connection(self.connection()) - return await facade.UpdateSecretBackends([{ - 'name': name, - 'config': config, - 'force': force, - 'token-rotate-interval': token_rotate_interval, - 'name-change': name_change, - }]) + return await facade.UpdateSecretBackends([ + { + "name": name, + "config": config, + "force": force, + "token-rotate-interval": token_rotate_interval, + "name-change": name_change, + } + ]) class ConnectedController(Controller): @@ -981,12 +1010,13 @@ def __init__( super().__init__( max_frame_size=max_frame_size, bakery_client=bakery_client, - jujudata=jujudata) + jujudata=jujudata, + ) self._conn = connection async def __aenter__(self): kwargs = self._conn.connect_params() - kwargs.pop('uuid') + kwargs.pop("uuid") await self._connect_direct(**kwargs) return self diff --git a/juju/delta.py b/juju/delta.py index 6f65e4425..a2ac374fe 100644 --- a/juju/delta.py +++ b/juju/delta.py @@ -14,7 +14,7 @@ def get_entity_class(entity_type): class EntityDelta(client.Delta): def get_id(self): - return self.data['id'] + return self.data["id"] @classmethod def get_entity_class(self): @@ -25,36 +25,40 @@ class ActionDelta(EntityDelta): @classmethod def get_entity_class(self): from .action import Action + return Action class ApplicationDelta(EntityDelta): def get_id(self): - return self.data['name'] + return self.data["name"] @classmethod def get_entity_class(self): from .application import Application + return Application class AnnotationDelta(EntityDelta): def get_id(self): - return self.data['tag'] + return self.data["tag"] @classmethod def get_entity_class(self): from .annotation import Annotation + return Annotation class ModelDelta(EntityDelta): def get_id(self): - return self.data['model-uuid'] + return self.data["model-uuid"] @classmethod def get_entity_class(self): from .model import ModelInfo + return ModelInfo @@ -62,16 +66,18 @@ class MachineDelta(EntityDelta): @classmethod def get_entity_class(self): from .machine import Machine + return Machine class UnitDelta(EntityDelta): def get_id(self): - return self.data['name'] + return self.data["name"] @classmethod def get_entity_class(self): from .unit import Unit + return Unit @@ -79,48 +85,52 @@ class RelationDelta(EntityDelta): @classmethod def get_entity_class(self): from .relation import Relation + return Relation class RemoteApplicationDelta(EntityDelta): def get_id(self): - return self.data['name'] + return self.data["name"] @classmethod def get_entity_class(self): from .remoteapplication import RemoteApplication + return RemoteApplication class CharmDelta(EntityDelta): def get_id(self): - return self.data['charm-url'] + return self.data["charm-url"] @classmethod def get_entity_class(self): from .charm import Charm + return Charm class ApplicationOfferDelta(EntityDelta): def get_id(self): - return self.data['application-name'] + return self.data["application-name"] @classmethod def get_entity_class(self): from .remoteapplication import ApplicationOffer + return ApplicationOffer _delta_types = { - 'action': ActionDelta, - 'annotation': AnnotationDelta, - 'application': ApplicationDelta, - 'applicationOffer': ApplicationOfferDelta, - 'charm': CharmDelta, - 'machine': MachineDelta, - 'model': ModelDelta, - 'relation': RelationDelta, - 'remoteApplication': RemoteApplicationDelta, - 'unit': UnitDelta, + "action": ActionDelta, + "annotation": AnnotationDelta, + "application": ApplicationDelta, + "applicationOffer": ApplicationOfferDelta, + "charm": CharmDelta, + "machine": MachineDelta, + "model": ModelDelta, + "relation": RelationDelta, + "remoteApplication": RemoteApplicationDelta, + "unit": UnitDelta, } diff --git a/juju/errors.py b/juju/errors.py index 9932057bf..f970c4ab7 100644 --- a/juju/errors.py +++ b/juju/errors.py @@ -1,9 +1,10 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. + class JujuError(Exception): def __init__(self, *args, **kwargs): - self.message = '' + self.message = "" self.errors = [] if args: self.message = str(args[0]) @@ -19,11 +20,11 @@ def __init__(self, *args, **kwargs): class JujuAPIError(JujuError): def __init__(self, result): self.result = result - self.message = result['error'] - self.error_code = result.get('error-code') - self.response = result['response'] - self.request_id = result['request-id'] - self.error_info = result['error-info'] if 'error-info' in result else None + self.message = result["error"] + self.error_code = result.get("error-code") + self.response = result["response"] + self.request_id = result["request-id"] + self.error_info = result["error-info"] if "error-info" in result else None super().__init__(self.message) @@ -37,29 +38,32 @@ class JujuAuthError(JujuConnectionError): class JujuRedirectException(Exception): """Exception indicating that a redirection was requested""" + def __init__(self, redirect_info, follow_redirect=True): self.redirect_info = redirect_info self.follow_redirect = follow_redirect @property def ca_cert(self): - return self.redirect_info['ca-cert'] + return self.redirect_info["ca-cert"] @property def endpoints(self): return [ - ('{value}:{port}'.format(**s), self.ca_cert) - for servers in self.redirect_info['servers'] - for s in servers if s['scope'] == 'public' or not self.follow_redirect + ("{value}:{port}".format(**s), self.ca_cert) + for servers in self.redirect_info["servers"] + for s in servers + if s["scope"] == "public" or not self.follow_redirect ] class JujuEntityNotFoundError(JujuError): """Exception indicating that an entity was not found in the state. It was - expected that the entity was found in state and this is a terminal - condition. - To fix this condition, you should disconnect and reconnect to ensure that - any missing entities are correctly picked up.""" + expected that the entity was found in state and this is a terminal + condition. + To fix this condition, you should disconnect and reconnect to ensure that + any missing entities are correctly picked up.""" + def __init__(self, entity_name, entity_types=None): self.entity_name = entity_name self.entity_types = entity_types @@ -106,18 +110,22 @@ class JujuNotValid(JujuError): def __init__(self, entity_type, entity_name): self.entity_type = entity_type self.entity_name = entity_name - super().__init__(f'Invalid {entity_type} : {entity_name}') + super().__init__(f"Invalid {entity_type} : {entity_name}") class JujuConfigError(JujuError): """Exception raised during processing a configuration key-value pair in a config set for an application. """ + def __init__(self, config, config_pair, message=None): self.config = config self.config_pair = config_pair if message is None: - self.message = "Couldn't process the value of a config pair : %s, value of type %s" % (self.config_pair, type(self.config_pair[1])) + self.message = ( + "Couldn't process the value of a config pair : %s, value of type %s" + % (self.config_pair, type(self.config_pair[1])) + ) else: self.message = message super().__init__(self.message) diff --git a/juju/exceptions.py b/juju/exceptions.py index e0205a0b5..a85449934 100644 --- a/juju/exceptions.py +++ b/juju/exceptions.py @@ -1,5 +1,6 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. + class DeadEntityException(Exception): pass diff --git a/juju/jasyncio.py b/juju/jasyncio.py index d45f8dbde..75e809e58 100644 --- a/juju/jasyncio.py +++ b/juju/jasyncio.py @@ -17,11 +17,30 @@ ROOT_LOGGER = logging.getLogger() -from asyncio import Event, TimeoutError, Queue, ensure_future, \ - gather, sleep, wait_for, create_subprocess_exec, subprocess, \ - wait, FIRST_COMPLETED, Lock, as_completed, new_event_loop, \ - get_event_loop_policy, CancelledError, get_running_loop, \ - create_task, ALL_COMPLETED, all_tasks, current_task, shield # noqa +from asyncio import ( + Event, + TimeoutError, + Queue, + ensure_future, + gather, + sleep, + wait_for, + create_subprocess_exec, + subprocess, + wait, + FIRST_COMPLETED, + Lock, + as_completed, + new_event_loop, + get_event_loop_policy, + CancelledError, + get_running_loop, + create_task, + ALL_COMPLETED, + all_tasks, + current_task, + shield, +) # noqa def create_task_with_handler(coro, task_name, logger=ROOT_LOGGER): @@ -36,6 +55,7 @@ def create_task_with_handler(coro, task_name, logger=ROOT_LOGGER): This makes sure the exceptions are retrieved and properly handled/logged whenever the Task is destroyed. """ + def _task_result_exp_handler(task, task_name=task_name, logger=logger): try: task.result() @@ -53,7 +73,9 @@ def _task_result_exp_handler(task, task_name=task_name, logger=logger): logger.exception("Task %s raised an exception: %s" % (task_name, e)) task = create_task(coro) - task.add_done_callback(functools.partial(_task_result_exp_handler, task_name=task_name, logger=logger)) + task.add_done_callback( + functools.partial(_task_result_exp_handler, task_name=task_name, logger=logger) + ) return task @@ -65,7 +87,7 @@ class SingletonEventLoop(object): loop = None def __new__(cls): - if not hasattr(cls, 'instance'): + if not hasattr(cls, "instance"): cls.instance = super(SingletonEventLoop, cls).__new__(cls) cls.instance.loop = asyncio.new_event_loop() @@ -98,7 +120,7 @@ def abort(): added = True except (ValueError, OSError, RuntimeError) as e: # add_signal_handler doesn't work in a thread - if 'main thread' not in str(e): + if "main thread" not in str(e): raise try: for step in steps: diff --git a/juju/juju.py b/juju/juju.py index 1f324341d..69b3ec137 100644 --- a/juju/juju.py +++ b/juju/juju.py @@ -7,14 +7,11 @@ class Juju(object): - def __init__(self, jujudata=None): self.jujudata = jujudata or FileJujuData() def get_controllers(self): - """Return list of all available controllers. - - """ + """Return list of all available controllers.""" return self.jujudata.controllers() async def get_controller(self, name, include_passwords=False): @@ -30,7 +27,9 @@ async def get_controller(self, name, include_passwords=False): controllers = self.jujudata.controllers() assert isinstance(controllers, dict) if name not in controllers: - raise JujuError('%s is not among the controllers: %s' % (name, controllers.keys())) + raise JujuError( + "%s is not among the controllers: %s" % (name, controllers.keys()) + ) # make a new Controller object that's connected to the # controller with the given name diff --git a/juju/loop.py b/juju/loop.py index 6a770c171..560c825dc 100644 --- a/juju/loop.py +++ b/juju/loop.py @@ -1,7 +1,8 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -from .jasyncio import * # noqa +from .jasyncio import * # noqa import warnings -warnings.warn('juju.loop module is being deprecated by 3.0, use juju.jasyncio instead') + +warnings.warn("juju.loop module is being deprecated by 3.0, use juju.jasyncio instead") diff --git a/juju/machine.py b/juju/machine.py index b0d77ef65..55fd59cb7 100644 --- a/juju/machine.py +++ b/juju/machine.py @@ -32,10 +32,13 @@ async def destroy(self, force=False): await facade.DestroyMachines(force=force, machine_names=[self.id]) else: facade = client.MachineManagerFacade.from_connection(self.connection) - await facade.DestroyMachineWithParams(force=force, machine_tags=[tag.machine(self.id)]) + await facade.DestroyMachineWithParams( + force=force, machine_tags=[tag.machine(self.id)] + ) + + log.debug("Destroying machine %s", self.id) + return await self.model._wait("machine", self.id, "remove") - log.debug('Destroying machine %s', self.id) - return await self.model._wait('machine', self.id, 'remove') remove = destroy async def get_annotations(self): @@ -65,13 +68,21 @@ def _format_addr(self, addr): """ ipaddr = ipaddress.ip_address(addr) if isinstance(ipaddr, ipaddress.IPv6Address): - fmt = '[{}]' + fmt = "[{}]" else: - fmt = '{}' + fmt = "{}" return fmt.format(ipaddr) - async def scp_to(self, source, destination, user='ubuntu', proxy=False, - scp_opts='', wait_for_active=False, timeout=None): + async def scp_to( + self, + source, + destination, + user="ubuntu", + proxy=False, + scp_opts="", + wait_for_active=False, + timeout=None, + ): """Transfer files to this machine. :param str source: Local path of file(s) to transfer @@ -84,7 +95,7 @@ async def scp_to(self, source, destination, user='ubuntu', proxy=False, :param int timeout: Time in seconds to wait until the machine becomes ready. """ if proxy: - raise NotImplementedError('proxy option is not implemented') + raise NotImplementedError("proxy option is not implemented") if wait_for_active: await block_until(lambda: self.addresses, timeout=timeout) try: @@ -93,11 +104,19 @@ async def scp_to(self, source, destination, user='ubuntu', proxy=False, except ValueError: # otherwise we assume it to be a DNS resolvable string address = self.dns_name - destination = '{}@{}:{}'.format(user, address, destination) + destination = "{}@{}:{}".format(user, address, destination) await self._scp(source, destination, scp_opts) - async def scp_from(self, source, destination, user='ubuntu', proxy=False, - scp_opts='', wait_for_active=False, timeout=None): + async def scp_from( + self, + source, + destination, + user="ubuntu", + proxy=False, + scp_opts="", + wait_for_active=False, + timeout=None, + ): """Transfer files from this machine. :param str source: Remote path of file(s) to transfer @@ -110,7 +129,7 @@ async def scp_from(self, source, destination, user='ubuntu', proxy=False, :param int timeout: Time in seconds to wait until the machine becomes ready. """ if proxy: - raise NotImplementedError('proxy option is not implemented') + raise NotImplementedError("proxy option is not implemented") if wait_for_active: await block_until(lambda: self.addresses, timeout=timeout) try: @@ -119,21 +138,15 @@ async def scp_from(self, source, destination, user='ubuntu', proxy=False, except ValueError: # otherwise we assume it to be a DNS resolvable string address = self.dns_name - source = '{}@{}:{}'.format(user, address, source) + source = "{}@{}:{}".format(user, address, source) await self._scp(source, destination, scp_opts) async def _scp(self, source, destination, scp_opts): - """ Execute an scp command. Requires a fully qualified source and + """Execute an scp command. Requires a fully qualified source and destination. """ _, id_path = juju_ssh_key_paths() - cmd = [ - 'scp', - '-i', id_path, - '-o', 'StrictHostKeyChecking=no', - '-q', - '-B' - ] + cmd = ["scp", "-i", id_path, "-o", "StrictHostKeyChecking=no", "-q", "-B"] cmd.extend(scp_opts.split() if isinstance(scp_opts, str) else scp_opts) cmd.extend([source, destination]) # There's a bit of a gap between the time that the machine is assigned an IP and the ssh @@ -153,7 +166,14 @@ async def _scp(self, source, destination, scp_opts): raise JujuError(f"command failed after {retries} attempts: {cmd}") async def ssh( - self, command, user='ubuntu', proxy=False, ssh_opts=None, wait_for_active=False, timeout=None): + self, + command, + user="ubuntu", + proxy=False, + ssh_opts=None, + wait_for_active=False, + timeout=None, + ): """Execute a command over SSH on this machine. :param str command: Command to execute @@ -164,18 +184,20 @@ async def ssh( :param int timeout: Time in seconds to wait until the machine becomes ready. """ if proxy: - raise NotImplementedError('proxy option is not implemented') + raise NotImplementedError("proxy option is not implemented") if wait_for_active: await block_until(lambda: self.addresses, timeout=timeout) address = self.dns_name destination = "{}@{}".format(user, address) _, id_path = juju_ssh_key_paths() cmd = [ - 'ssh', - '-i', id_path, - '-o', 'StrictHostKeyChecking=no', - '-q', - destination + "ssh", + "-i", + id_path, + "-o", + "StrictHostKeyChecking=no", + "-q", + destination, ] if ssh_opts: cmd.extend(ssh_opts.split() if isinstance(ssh_opts, str) else ssh_opts) @@ -189,36 +211,33 @@ async def ssh( retries = 10 for _ in range(retries): process = await jasyncio.create_subprocess_exec( - *cmd, stdout=jasyncio.subprocess.PIPE, stderr=jasyncio.subprocess.PIPE) + *cmd, stdout=jasyncio.subprocess.PIPE, stderr=jasyncio.subprocess.PIPE + ) stdout, stderr = await process.communicate() if process.returncode == 0: break await jasyncio.sleep(retry_backoff) if process.returncode != 0: - raise JujuError(f"command failed: {cmd} after {retries} attempts, with {stderr.decode()}") + raise JujuError( + f"command failed: {cmd} after {retries} attempts, with {stderr.decode()}" + ) # stdout is a bytes-like object, returning a string might be more useful return stdout.decode() @property def addresses(self) -> typing.List[str]: - """Returns the machine addresses. - - """ - return self.safe_data['addresses'] or [] + """Returns the machine addresses.""" + return self.safe_data["addresses"] or [] @property def agent_status(self): - """Returns the current Juju agent status string. - - """ - return self.safe_data['agent-status']['current'] + """Returns the current Juju agent status string.""" + return self.safe_data["agent-status"]["current"] @property def agent_status_since(self): - """Get the time when the `agent_status` was last updated. - - """ - return pyrfc3339.parse(self.safe_data['agent-status']['since']) + """Get the time when the `agent_status` was last updated.""" + return pyrfc3339.parse(self.safe_data["agent-status"]["since"]) @property def agent_version(self): @@ -226,7 +245,7 @@ def agent_version(self): May return None if the agent is not yet available. """ - version = self.safe_data['agent-status']['version'] + version = self.safe_data["agent-status"]["version"] if version: return client.Number.from_json(version) else: @@ -234,24 +253,18 @@ def agent_version(self): @property def status(self): - """Returns the current machine provisioning status string. - - """ - return self.safe_data['instance-status']['current'] + """Returns the current machine provisioning status string.""" + return self.safe_data["instance-status"]["current"] @property def status_message(self): - """Returns the current machine provisioning status message. - - """ - return self.safe_data['instance-status']['message'] + """Returns the current machine provisioning status message.""" + return self.safe_data["instance-status"]["message"] @property def status_since(self): - """Get the time when the `status` was last updated. - - """ - return pyrfc3339.parse(self.safe_data['instance-status']['since']) + """Get the time when the `status` was last updated.""" + return pyrfc3339.parse(self.safe_data["instance-status"]["since"]) @property def dns_name(self): @@ -261,16 +274,16 @@ def dns_name(self): May return None if no suitable address is found. """ ordered_addresses = [] - ordered_scopes = ['public', 'local-cloud', 'local-fan'] + ordered_scopes = ["public", "local-cloud", "local-fan"] for scope in ordered_scopes: for address in self.addresses: - if scope == address['scope']: + if scope == address["scope"]: ordered_addresses.append(address) for address in ordered_addresses: - scope = address['scope'] + scope = address["scope"] for check_scope in ordered_scopes: if scope == check_scope: - return address['value'] + return address["value"] return None @property @@ -280,16 +293,14 @@ def hostname(self): May return None if no hostname information is available. """ - if 'hostname' in self.safe_data and self.safe_data['hostname'] != '': - return self.safe_data['hostname'] + if "hostname" in self.safe_data and self.safe_data["hostname"] != "": + return self.safe_data["hostname"] return None @property def series(self): - """Returns the series of the current machine - - """ - return self.safe_data['series'] + """Returns the series of the current machine""" + return self.safe_data["series"] @property def tag(self): diff --git a/juju/model.py b/juju/model.py index 2be474d57..0bc3442d6 100644 --- a/juju/model.py +++ b/juju/model.py @@ -32,7 +32,15 @@ from .controller import Controller, ConnectedController from .delta import get_entity_class, get_entity_delta from .errors import JujuAPIError, JujuError, JujuModelConfigError, JujuBackupError -from .errors import JujuModelError, JujuAppError, JujuUnitError, JujuAgentError, JujuMachineError, PylibjujuError, JujuNotSupportedError +from .errors import ( + JujuModelError, + JujuAppError, + JujuUnitError, + JujuAgentError, + JujuMachineError, + PylibjujuError, + JujuNotSupportedError, +) from .exceptions import DeadEntityException from .names import is_valid_application from .offerendpoints import ParseError as OfferParseError @@ -54,6 +62,7 @@ class _Observer: callable so that it's only called for changes that meet the criteria. """ + def __init__(self, callable_, entity_type, action, entity_id, predicate): self.callable_ = callable_ self.entity_type = entity_type @@ -62,10 +71,10 @@ def __init__(self, callable_, entity_type, action, entity_id, predicate): self.predicate = predicate if self.entity_id: self.entity_id = str(self.entity_id) - if not self.entity_id.startswith('^'): - self.entity_id = '^' + self.entity_id - if not self.entity_id.endswith('$'): - self.entity_id += '$' + if not self.entity_id.startswith("^"): + self.entity_id = "^" + self.entity_id + if not self.entity_id.endswith("$"): + self.entity_id += "$" async def __call__(self, delta, old, new, model): await self.callable_(delta, old, new, model) @@ -75,8 +84,11 @@ def cares_about(self, delta): called) for a this delta. """ - if (self.entity_id and delta.get_id() and - not re.match(self.entity_id, str(delta.get_id()))): + if ( + self.entity_id + and delta.get_id() + and not re.match(self.entity_id, str(delta.get_id())) + ): return False if self.entity_type and self.entity_type != delta.entity: @@ -95,8 +107,9 @@ class ModelObserver: """ Base class for creating observers that react to changes in a model. """ + async def __call__(self, delta, old, new, model): - handler_name = 'on_{}_{}'.format(delta.entity, delta.type) + handler_name = "on_{}_{}".format(delta.entity, delta.type) method = getattr(self, handler_name, self.on_change) await method(delta, old, new, model) @@ -119,6 +132,7 @@ class ModelState: entities in the model. """ + def __init__(self, model): self.model = model self.state = dict() @@ -140,7 +154,7 @@ def applications(self): currently in the model. """ - return self._live_entity_map('application') + return self._live_entity_map("application") @property def remote_applications(self): @@ -148,14 +162,14 @@ def remote_applications(self): applications currently in the model. """ - return self._live_entity_map('remoteApplication') + return self._live_entity_map("remoteApplication") @property def application_offers(self): """Return a map of application-name:Application for all applications offers currently in the model. """ - return self._live_entity_map('applicationOffer') + return self._live_entity_map("applicationOffer") @property def machines(self): @@ -163,7 +177,7 @@ def machines(self): the model. """ - return self._live_entity_map('machine') + return self._live_entity_map("machine") @property def units(self): @@ -171,7 +185,7 @@ def units(self): the model. """ - return self._live_entity_map('unit') + return self._live_entity_map("unit") @property def subordinate_units(self): @@ -184,12 +198,10 @@ def relations(self): the model. """ - return self._live_entity_map('relation') + return self._live_entity_map("relation") def entity_history(self, entity_type, entity_id): - """Return the history deque for an entity. - - """ + """Return the history deque for an entity.""" return self.state[entity_type][entity_id] def entity_data(self, entity_type, entity_id, history_index): @@ -212,21 +224,18 @@ def apply_delta(self, delta): if the object was deleted as a result of the delta being applied. """ - history = ( - self.state - .setdefault(delta.entity, {}) - .setdefault(delta.get_id(), collections.deque()) + history = self.state.setdefault(delta.entity, {}).setdefault( + delta.get_id(), collections.deque() ) history.append(delta.data) - if delta.type == 'remove': + if delta.type == "remove": history.append(None) entity = self.get_entity(delta.entity, delta.get_id()) return entity.previous(), entity - def get_entity( - self, entity_type, entity_id, history_index=-1, connected=True): + def get_entity(self, entity_type, entity_id, history_index=-1, connected=True): """Return an object instance for the given entity_type and id. By default the object state matches the most recent state from @@ -247,8 +256,8 @@ def get_entity( entity_class = get_entity_class(entity_type) return entity_class( - entity_id, self.model, history_index=history_index, - connected=connected) + entity_id, self.model, history_index=history_index, connected=connected + ) class ModelEntity: @@ -271,11 +280,10 @@ def __init__(self, entity_id, model, history_index=-1, connected=True): self._history_index = history_index self.connected = connected self.connection = model.connection() - self._status = 'unknown' + self._status = "unknown" def __repr__(self): - return '<{} entity_id="{}">'.format(type(self).__name__, - self.entity_id) + return '<{} entity_id="{}">'.format(type(self).__name__, self.entity_id) def __getattr__(self, name): """Fetch object attributes from the underlying data dict held in the @@ -285,7 +293,7 @@ def __getattr__(self, name): try: return self.safe_data[name] except KeyError: - name = name.replace('_', '-') + name = name.replace("_", "-") if name in self.safe_data: return self.safe_data[name] else: @@ -295,18 +303,12 @@ def __bool__(self): return bool(self.data) def on_change(self, callable_): - """Add a change observer to this entity. - - """ - self.model.add_observer( - callable_, self.entity_type, 'change', self.entity_id) + """Add a change observer to this entity.""" + self.model.add_observer(callable_, self.entity_type, "change", self.entity_id) def on_remove(self, callable_): - """Add a remove observer to this entity. - - """ - self.model.add_observer( - callable_, self.entity_type, 'remove', self.entity_id) + """Add a remove observer to this entity.""" + self.model.add_observer(callable_, self.entity_type, "remove", self.entity_id) @property def entity_type(self): @@ -317,7 +319,9 @@ def entity_type(self): # Allow the overriding of entity names from the type instead of from # the class name. Useful because Model and ModelInfo clash and we really # want ModelInfo to be called Model. - if hasattr(self.__class__, "type_name_override") and callable(self.__class__.type_name_override): + if hasattr(self.__class__, "type_name_override") and callable( + self.__class__.type_name_override + ): return self.__class__.type_name_override() def first_lower(s): @@ -325,6 +329,7 @@ def first_lower(s): return s else: return s[0].lower() + s[1:] + return first_lower(self.__class__.__name__) @property @@ -346,9 +351,9 @@ def dead(self): """ return ( - self.data is None or - self.model.state.entity_data( - self.entity_type, self.entity_id, -1) is None + self.data is None + or self.model.state.entity_data(self.entity_type, self.entity_id, -1) + is None ) @property @@ -361,11 +366,10 @@ def alive(self): @property def data(self): - """The data dictionary for this entity. - - """ + """The data dictionary for this entity.""" return self.model.state.entity_data( - self.entity_type, self.entity_id, self._history_index) + self.entity_type, self.entity_id, self._history_index + ) @property def safe_data(self): @@ -380,7 +384,9 @@ def safe_data(self): "Entity {}:{} is dead - its attributes can no longer be " "accessed. Use the .previous() method on this object to get " "a copy of the object at its previous state.".format( - self.entity_type, self.entity_id)) + self.entity_type, self.entity_id + ) + ) return self.data def previous(self): @@ -394,8 +400,8 @@ def previous(self): """ return self.model.state.get_entity( - self.entity_type, self.entity_id, self._history_index - 1, - connected=False) + self.entity_type, self.entity_id, self._history_index - 1, connected=False + ) def next(self): """Return a copy of this object at its next state in @@ -412,12 +418,16 @@ def next(self): new_index = self._history_index + 1 connected = ( - new_index == len(self.model.state.entity_history( - self.entity_type, self.entity_id)) - 1 + new_index + == len(self.model.state.entity_history(self.entity_type, self.entity_id)) + - 1 ) return self.model.state.get_entity( - self.entity_type, self.entity_id, self._history_index - 1, - connected=connected) + self.entity_type, + self.entity_id, + self._history_index - 1, + connected=connected, + ) def latest(self): """Return a copy of this object at its current state in the model. @@ -448,13 +458,20 @@ def __init__(self, identifier, origin, app_name, is_local=False, is_bundle=False class LocalDeployType: - """LocalDeployType deals with local only deployments. - """ + """LocalDeployType deals with local only deployments.""" - async def resolve(self, charm_path, architecture, - app_name=None, channel=None, series=None, - revision=None, entity_url=None, force=False, - model_conf=None): + async def resolve( + self, + charm_path, + architecture, + app_name=None, + channel=None, + series=None, + revision=None, + entity_url=None, + force=False, + model_conf=None, + ): """resolve attempts to resolve a local charm or bundle using the url and architecture. If information is missing, it will attempt to backfill that information, before sending the result back. @@ -463,21 +480,23 @@ async def resolve(self, charm_path, architecture, """ entity_path = Path(charm_path) - if entity_path.suffix == '.yaml': + if entity_path.suffix == ".yaml": bundle_path = entity_path else: - bundle_path = entity_path / 'bundle.yaml' + bundle_path = entity_path / "bundle.yaml" origin = client.CharmOrigin(source="local", architecture=architecture) if not (entity_path.is_dir() or entity_path.is_file()): - raise JujuError('{} path not found'.format(entity_url)) + raise JujuError("{} path not found".format(entity_url)) is_bundle = bundle_path.exists() if app_name is None: if is_bundle: - bundle_with_overlays = [b for b in yaml.safe_load_all(bundle_path.read_text())] - app_name = bundle_with_overlays[0].get('name', '') + bundle_with_overlays = [ + b for b in yaml.safe_load_all(bundle_path.read_text()) + ] + app_name = bundle_with_overlays[0].get("name", "") else: app_name = utils.get_local_charm_metadata(entity_path)["name"] @@ -498,39 +517,54 @@ class CharmhubDeployType: def __init__(self, charm_resolver): self.charm_resolver = charm_resolver - async def resolve(self, url, architecture, - app_name=None, channel=None, series=None, - revision=None, entity_url=None, force=False, - model_conf=None): + async def resolve( + self, + url, + architecture, + app_name=None, + channel=None, + series=None, + revision=None, + entity_url=None, + force=False, + model_conf=None, + ): """resolve attempts to resolve charmhub charms or bundles. A request to the charmhub API is required to correctly determine the charm url and underlying origin. """ if revision and not channel: - raise JujuError('specifying a revision requires a channel for future upgrades. Please use --channel') + raise JujuError( + "specifying a revision requires a channel for future upgrades. Please use --channel" + ) - ch = Channel('latest', 'stable') + ch = Channel("latest", "stable") if channel is not None: ch = Channel.parse(channel).normalize() base = client.Base() if series: base.channel = ch.normalize().compute_base_channel(series=series) - base.name = 'ubuntu' - - origin = client.CharmOrigin(source=Source.CHARM_HUB.value, - architecture=architecture, - risk=ch.risk, - track=ch.track, - base=base, - revision=revision, - ) + base.name = "ubuntu" + + origin = client.CharmOrigin( + source=Source.CHARM_HUB.value, + architecture=architecture, + risk=ch.risk, + track=ch.track, + base=base, + revision=revision, + ) - charm_url, origin = await self.charm_resolver(url, origin, force, series, model_conf) + charm_url, origin = await self.charm_resolver( + url, origin, force, series, model_conf + ) is_bundle = origin.type_ == "bundle" if is_bundle and revision and channel: - raise JujuError('revision and channel are mutually exclusive when deploying a bundle. Please choose one.') + raise JujuError( + "revision and channel are mutually exclusive when deploying a bundle. Please choose one." + ) if app_name is None: app_name = charm_url.name @@ -547,6 +581,7 @@ class Model: """ The main API for interacting with a Juju model. """ + def __init__( self, max_frame_size=None, @@ -601,9 +636,10 @@ async def get_controller(self): :return Controller: """ from juju.controller import Controller + controller = Controller(jujudata=self._connector.jujudata) kwargs = self.connection().connect_params() - kwargs.pop('uuid') + kwargs.pop("uuid") await controller._connect_direct(**kwargs) return controller @@ -652,54 +688,58 @@ async def connect(self, *args, **kwargs): :param specified_facades: (deprecated) overwrite the facades with a series of specified facades. """ - is_debug_log_conn = 'debug_log_conn' in kwargs + is_debug_log_conn = "debug_log_conn" in kwargs if not is_debug_log_conn: await self.disconnect() model_name = model_uuid = None - if 'endpoint' not in kwargs and len(args) < 2: + if "endpoint" not in kwargs and len(args) < 2: # Then we're using the model_name to pick the model - if args and 'model_name' in kwargs: - raise TypeError('connect() got multiple values for model_name') + if args and "model_name" in kwargs: + raise TypeError("connect() got multiple values for model_name") elif args: model_name = args[0] else: - model_name = kwargs.pop('model_name', None) + model_name = kwargs.pop("model_name", None) model_uuid = await self._connector.connect_model(model_name, **kwargs) else: # Then we're using the endpoint to pick the model - if 'model_name' in kwargs: - raise TypeError('connect() got values for both ' - 'model_name and endpoint') - if args and 'endpoint' in kwargs: - raise TypeError('connect() got multiple values for endpoint') - if len(args) < 2 and 'uuid' not in kwargs: - raise TypeError('connect() missing value for uuid') - has_userpass = (len(args) >= 4 or - {'username', 'password'}.issubset(kwargs)) - has_macaroons = (len(args) >= 6 or not - {'bakery_client', 'macaroons'}.isdisjoint(kwargs)) + if "model_name" in kwargs: + raise TypeError("connect() got values for both model_name and endpoint") + if args and "endpoint" in kwargs: + raise TypeError("connect() got multiple values for endpoint") + if len(args) < 2 and "uuid" not in kwargs: + raise TypeError("connect() missing value for uuid") + has_userpass = len(args) >= 4 or {"username", "password"}.issubset(kwargs) + has_macaroons = len(args) >= 6 or not { + "bakery_client", + "macaroons", + }.isdisjoint(kwargs) if not (has_userpass or has_macaroons): - raise TypeError('connect() missing auth params') + raise TypeError("connect() missing auth params") arg_names = [ - 'endpoint', - 'uuid', - 'username', - 'password', - 'cacert', - 'bakery_client', - 'macaroons', - 'max_frame_size', + "endpoint", + "uuid", + "username", + "password", + "cacert", + "bakery_client", + "macaroons", + "max_frame_size", ] for i, arg in enumerate(args): kwargs[arg_names[i]] = arg - model_uuid = kwargs['uuid'] - if not {'endpoint', 'uuid'}.issubset(kwargs): - raise ValueError('endpoint and uuid are required ' - 'if model_name not given') - if not ({'username', 'password'}.issubset(kwargs) or - {'bakery_client', 'macaroons'}.intersection(kwargs)): - raise ValueError('Authentication parameters are required ' - 'if model_name not given') + model_uuid = kwargs["uuid"] + if not {"endpoint", "uuid"}.issubset(kwargs): + raise ValueError( + "endpoint and uuid are required if model_name not given" + ) + if not ( + {"username", "password"}.issubset(kwargs) + or {"bakery_client", "macaroons"}.intersection(kwargs) + ): + raise ValueError( + "Authentication parameters are required if model_name not given" + ) await self._connector.connect(**kwargs) if not is_debug_log_conn: await self._after_connect(model_name, model_uuid) @@ -725,8 +765,8 @@ async def connect_to(self, connection): async def _connect_direct(self, **kwargs): if self.info: uuid = self.info.uuid - elif 'uuid' in kwargs: - uuid = kwargs['uuid'] + elif "uuid" in kwargs: + uuid = kwargs["uuid"] else: raise PylibjujuError("Unable to find uuid for the model") await self.disconnect() @@ -744,6 +784,7 @@ async def _after_connect(self, model_name=None, model_uuid=None): # to do is make one RPC call. async def watch_received_waiter(): await self._watch_received.wait() + waiter = jasyncio.create_task(watch_received_waiter()) # If we just wait for the _watch_received event and the _all_watcher task @@ -753,33 +794,34 @@ async def watch_received_waiter(): # If _all_watcher is done before the _watch_received, then we should see # (and raise) an exception coming from the _all_watcher # Otherwise (i.e. _watch_received is set), then we're good to go - done, pending = await jasyncio.wait([waiter, self._watcher_task], - return_when=jasyncio.FIRST_COMPLETED) + done, pending = await jasyncio.wait( + [waiter, self._watcher_task], return_when=jasyncio.FIRST_COMPLETED + ) if self._watcher_task in done: # Cancel the _watch_received.wait waiter.cancel() # If there's no exception, then why did the _all_watcher broke its loop? if not self._watcher_task.exception(): - raise JujuError("AllWatcher task is finished abruptly without an exception.") + raise JujuError( + "AllWatcher task is finished abruptly without an exception." + ) raise self._watcher_task.exception() if self._info is None: # TODO (cderici): See if this can be optimized away, or at least - # be done lazily (i.e. not everytime after_connect, but whenever + # be done lazily (i.e. not every time after_connect, but whenever # self.info is needed -- which here can be bypassed if model_uuid # is known) async with ConnectedController(self.connection()) as contr: self._info = await contr.get_model_info(model_name, model_uuid) - log.debug('Got ModelInfo: %s', vars(self.info)) + log.debug("Got ModelInfo: %s", vars(self.info)) self.uuid = self.info.uuid async def disconnect(self): - """Shut down the watcher task and close websockets. - - """ + """Shut down the watcher task and close websockets.""" if not self._watch_stopped.is_set(): - log.debug('Stopping watcher task') + log.debug("Stopping watcher task") self._watch_stopping.set() # If the _all_watcher task is finished, # check to see an exception, if yes, raise, @@ -791,7 +833,7 @@ async def disconnect(self): self._watch_stopping.clear() if self.is_connected(): - await self._connector.disconnect(entity='model') + await self._connector.disconnect(entity="model") self._info = None async def add_local_charm_dir(self, charm_dir, series): @@ -805,18 +847,17 @@ async def add_local_charm_dir(self, charm_dir, series): """ charm_dir = Path(charm_dir) - if charm_dir.suffix == '.charm': + if charm_dir.suffix == ".charm": fn = charm_dir else: fn = tempfile.NamedTemporaryFile().name CharmArchiveGenerator(str(charm_dir)).make_archive(fn) - with open(str(fn), 'rb') as fh: - func = partial( - self.add_local_charm, fh, series, os.stat(str(fn)).st_size) + with open(str(fn), "rb") as fh: + func = partial(self.add_local_charm, fh, series, os.stat(str(fn)).st_size) loop = jasyncio.get_running_loop() charm_url = await loop.run_in_executor(None, func) - log.debug('Uploaded local charm: %s -> %s', charm_dir, charm_url) + log.debug("Uploaded local charm: %s -> %s", charm_dir, charm_url) return charm_url def add_local_charm(self, charm_file, series="", size=None): @@ -841,24 +882,22 @@ def add_local_charm(self, charm_file, series="", size=None): """ conn, headers, path_prefix = self.connection().https_connection() path = "%s/charms?series=%s" % (path_prefix, series) - headers['Content-Type'] = 'application/zip' + headers["Content-Type"] = "application/zip" if size: - headers['Content-Length'] = size + headers["Content-Length"] = size conn.request("POST", path, charm_file, headers) response = conn.getresponse() result = response.read().decode() if not response.status == 200: raise JujuError(result) result = json.loads(result) - return result['charm-url'] + return result["charm-url"] def all_units_idle(self): - """Return True if all units are idle. - - """ + """Return True if all units are idle.""" for unit in self.units.values(): - unit_status = unit.data['agent-status']['current'] - if unit_status != 'idle': + unit_status = unit.data["agent-status"]["current"] + if unit_status != "idle": return False return True @@ -871,17 +910,13 @@ async def reset(self, force=False): means no applications or machines exist in the model. """ - log.debug('Resetting model') + log.debug("Resetting model") for app in self.applications.values(): await app.destroy() - await self.block_until( - lambda: len(self.applications) == 0 - ) + await self.block_until(lambda: len(self.applications) == 0) for machine in self.machines.values(): await machine.destroy(force=force) - await self.block_until( - lambda: len(self.machines) == 0 - ) + await self.block_until(lambda: len(self.machines) == 0) async def create_storage_pool(self, name, provider_type, attributes=""): """Create or define a storage pool. @@ -896,11 +931,13 @@ async def create_storage_pool(self, name, provider_type, attributes=""): _attrs = [splt.split("=") for splt in attributes.split()] storage_facade = client.StorageFacade.from_connection(self.connection()) - return await storage_facade.CreatePool(pools=[client.StoragePool( - name=name, - provider=provider_type, - attrs=dict(_attrs) - )]) + return await storage_facade.CreatePool( + pools=[ + client.StoragePool( + name=name, provider=provider_type, attrs=dict(_attrs) + ) + ] + ) async def remove_storage_pool(self, name): """Remove an existing storage pool. @@ -909,10 +946,12 @@ async def remove_storage_pool(self, name): :return: """ storage_facade = client.StorageFacade.from_connection(self.connection()) - return await storage_facade.RemovePool(pools=[client.StoragePoolDeleteArg(name)]) + return await storage_facade.RemovePool( + pools=[client.StoragePoolDeleteArg(name)] + ) async def update_storage_pool(self, name, attributes=""): - """ Update storage pool attributes. + """Update storage pool attributes. :param name: :param attributes: "key=value key=value ..." @@ -923,10 +962,14 @@ async def update_storage_pool(self, name, attributes=""): raise JujuError("Expected at least one attribute to update") storage_facade = client.StorageFacade.from_connection(self.connection()) - return await storage_facade.UpdatePool(pools=[client.StoragePool( - name=name, - attrs=_attrs, - )]) + return await storage_facade.UpdatePool( + pools=[ + client.StoragePool( + name=name, + attrs=_attrs, + ) + ] + ) async def list_storage(self, filesystem=False, volume=False): """Lists storage details. @@ -940,11 +983,15 @@ async def list_storage(self, filesystem=False, volume=False): if filesystem and volume: raise JujuError("--filesystem and --volume can not be used together") if filesystem: - _res = await storage_facade.ListFilesystems(filters=[client.FilesystemFilter()]) + _res = await storage_facade.ListFilesystems( + filters=[client.FilesystemFilter()] + ) elif volume: _res = await storage_facade.ListVolumes(filters=[client.VolumeFilter()]) else: - _res = await storage_facade.ListStorageDetails(filters=[client.StorageFilter()]) + _res = await storage_facade.ListStorageDetails( + filters=[client.StorageFilter()] + ) err = _res.results[0].error res = _res.results[0].result @@ -964,7 +1011,9 @@ async def show_storage_details(self, *storage_ids): raise JujuError("Expected at least one storage ID") storage_facade = client.StorageFacade.from_connection(self.connection()) - res = await storage_facade.StorageDetails(entities=[client.Entity(tag.storage(s)) for s in storage_ids]) + res = await storage_facade.StorageDetails( + entities=[client.Entity(tag.storage(s)) for s in storage_ids] + ) return [s.result.serialize() for s in res.results] async def list_storage_pools(self): @@ -992,11 +1041,16 @@ async def remove_storage(self, *storage_ids, force=False, destroy_storage=False) raise JujuError("Expected at least one storage ID") storage_facade = client.StorageFacade.from_connection(self.connection()) - ret = await storage_facade.Remove(storage=[client.RemoveStorageInstance( - destroy_storage=destroy_storage, - force=force, - tag=s, - ) for s in storage_ids]) + ret = await storage_facade.Remove( + storage=[ + client.RemoveStorageInstance( + destroy_storage=destroy_storage, + force=force, + tag=s, + ) + for s in storage_ids + ] + ) if ret.results[0].error: raise JujuError(ret.results[0].error.message) @@ -1007,7 +1061,7 @@ async def remove_application( force=False, destroy_storage=False, no_wait=False, - timeout=None + timeout=None, ): """Removes the given application from the model. @@ -1021,32 +1075,36 @@ async def remove_application( within the timeout period. """ if app_name not in self.applications: - raise JujuError("Given application doesn't seem to appear in the\ - model: %s\nCurrent applications are: %s" % - (app_name, self.applications)) - await self.applications[app_name].remove(destroy_storage=destroy_storage, - force=force, - no_wait=no_wait, - ) + raise JujuError( + "Given application doesn't seem to appear in the\ + model: %s\nCurrent applications are: %s" + % (app_name, self.applications) + ) + await self.applications[app_name].remove( + destroy_storage=destroy_storage, + force=force, + no_wait=no_wait, + ) if block_until_done: - await self.block_until(lambda: app_name not in self.applications, timeout=timeout) + await self.block_until( + lambda: app_name not in self.applications, timeout=timeout + ) async def block_until(self, *conditions, timeout=None, wait_period=0.5): """Return only after all conditions are true. Raises `websockets.ConnectionClosed` if disconnected. """ + def _disconnected(): return not (self.is_connected() and self.connection().is_open) def done(): return _disconnected() or all(c() for c in conditions) - await utils.block_until(done, - timeout=timeout, - wait_period=wait_period) + await utils.block_until(done, timeout=timeout, wait_period=wait_period) if _disconnected(): - raise websockets.ConnectionClosed(1006, 'no reason') + raise websockets.ConnectionClosed(1006, "no reason") @property def tag(self): @@ -1101,9 +1159,7 @@ def subordinate_units(self): @property def relations(self): - """Return a list of all Relations currently in the model. - - """ + """Return a list of all Relations currently in the model.""" return list(self.state.relations.values()) @property @@ -1116,9 +1172,7 @@ def charmhub(self): @property def name(self): - """Return the name of this model - - """ + """Return the name of this model""" if self._info is None: raise JujuModelError("Model is not connected") return self._info.name @@ -1136,8 +1190,8 @@ def strict_mode(self): return self._mode is not None and "strict" in self._mode def add_observer( - self, callable_, entity_type=None, action=None, entity_id=None, - predicate=None): + self, callable_, entity_type=None, action=None, entity_id=None, predicate=None + ): """Register an "on-model-change" callback Once the model is connected, ``callable_`` @@ -1171,8 +1225,7 @@ def add_observer( function returns True, the ``callable_`` will be called. """ - observer = _Observer( - callable_, entity_type, action, entity_id, predicate) + observer = _Observer(callable_, entity_type, action, entity_id, predicate) self._observers[observer] = callable_ def _watch(self): @@ -1198,16 +1251,14 @@ async def _all_watcher(): self._mode = model_config["mode"]["value"] try: - allwatcher = client.AllWatcherFacade.from_connection( - self.connection()) + allwatcher = client.AllWatcherFacade.from_connection(self.connection()) while not self._watch_stopping.is_set(): try: results = await utils.run_with_interrupt( - allwatcher.Next(), - self._watch_stopping, - log=log) + allwatcher.Next(), self._watch_stopping, log=log + ) except JujuAPIError as e: - if 'watcher was stopped' not in str(e): + if "watcher was stopped" not in str(e): raise if self._watch_stopping.is_set(): # this shouldn't ever actually happen, because @@ -1217,21 +1268,21 @@ async def _all_watcher(): break # controller stopped our watcher for some reason # but we're not actually stopping, so just restart it - log.warning( - 'Watcher: watcher stopped, restarting') + log.warning("Watcher: watcher stopped, restarting") del allwatcher.Id continue except websockets.ConnectionClosed: monitor = self.connection().monitor if monitor.status == monitor.ERROR: # closed unexpectedly, try to reopen - log.warning( - 'Watcher: connection closed, reopening') + log.warning("Watcher: connection closed, reopening") await self.connection().reconnect() if monitor.status != monitor.CONNECTED: # reconnect failed; abort and shutdown - log.error('Watcher: automatic reconnect ' - 'failed; stopping watcher') + log.error( + "Watcher: automatic reconnect " + "failed; stopping watcher" + ) break del allwatcher.Id continue @@ -1250,7 +1301,9 @@ async def _all_watcher(): entity = get_entity_delta(delta) except KeyError: if self.strict_mode: - raise JujuError("unknown delta type '{}'".format(delta.entity)) + raise JujuError( + "unknown delta type '{}'".format(delta.entity) + ) if not self.strict_mode and entity is None: continue @@ -1263,12 +1316,12 @@ async def _all_watcher(): except CancelledError: pass except Exception: - log.exception('Error in watcher') + log.exception("Error in watcher") raise finally: self._watch_stopped.set() - log.debug('Starting watcher task') + log.debug("Starting watcher task") self._watch_received.clear() self._watch_stopping.clear() self._watch_stopped.clear() @@ -1286,11 +1339,9 @@ async def _notify_observers(self, delta, old_obj, new_obj): """ if new_obj and not old_obj: - delta.type = 'add' + delta.type = "add" - log.debug( - 'Model changed: %s %s %s', - delta.entity, delta.type, delta.get_id()) + log.debug("Model changed: %s %s %s", delta.entity, delta.type, delta.get_id()) for o in self._observers: if o.cares_about(delta): @@ -1345,9 +1396,9 @@ async def wait_for_action(self, action_id): action_id = action_id[7:] def predicate(delta): - return delta.data['status'] in ('completed', 'failed') + return delta.data["status"] in ("completed", "failed") - return await self._wait('action', action_id, None, predicate) + return await self._wait("action", action_id, None, predicate) async def get_annotations(self): """Get annotations on this model. @@ -1365,8 +1416,7 @@ async def set_annotations(self, annotations): """ return await _set_annotations(self.tag, annotations, self.connection()) - async def add_machine( - self, spec=None, constraints=None, disks=None, series=None): + async def add_machine(self, spec=None, constraints=None, disks=None, series=None): """Start a new, empty machine and optionally a container, or add a container to a machine. @@ -1444,14 +1494,13 @@ async def add_machine( if placement: params.placement = placement[0] - params.jobs = ['JobHostUnits'] + params.jobs = ["JobHostUnits"] if constraints: params.constraints = client.Value.from_json(constraints) if disks: - params.disks = [ - client.Constraints.from_json(o) for o in disks] + params.disks = [client.Constraints.from_json(o) for o in disks] if series: params.series = series @@ -1474,8 +1523,8 @@ async def add_machine( machine_id, ) - log.debug('Added new machine %s', machine_id) - return await self._wait_for_new('machine', machine_id) + log.debug("Added new machine %s", machine_id) + return await self._wait_for_new("machine", machine_id) async def add_relation(self, relation1, relation2): """ @@ -1519,17 +1568,21 @@ async def integrate(self, relation1, relation2): if remote_endpoint is not None: if facade_cls.best_facade_version(self.connection()) < 5: # old clients don't support cross model capability - raise JujuError("cannot add relation to {}: remote endpoints not supported".format(remote_endpoint.string())) + raise JujuError( + "cannot add relation to {}: remote endpoints not supported".format( + remote_endpoint.string() + ) + ) if remote_endpoint.has_empty_source(): async with ConnectedController(self.connection()) as current: remote_endpoint.source = current.controller_name # consume the remote endpoint - await self.consume(remote_endpoint.string(), - application_alias=remote_endpoint.application) + await self.consume( + remote_endpoint.string(), application_alias=remote_endpoint.application + ) - log.debug( - 'Adding relation %s <-> %s', endpoints[0], endpoints[1]) + log.debug("Adding relation %s <-> %s", endpoints[0], endpoints[1]) def _find_relation(*specs): for rel in self.relations: @@ -1541,16 +1594,20 @@ def _find_relation(*specs): try: result = await app_facade.AddRelation(endpoints=endpoints, via_cidrs=None) except JujuAPIError as e: - if 'relation already exists' not in e.message: + if "relation already exists" not in e.message: raise rel = _find_relation(endpoints[0], endpoints[1]) if rel: return rel - raise JujuError('Relation {} {} exists but not in model'.format( - endpoints[0], endpoints[1])) + raise JujuError( + "Relation {} {} exists but not in model".format( + endpoints[0], endpoints[1] + ) + ) - specs = ['{}:{}'.format(app, data['name']) - for app, data in result.endpoints.items()] + specs = [ + "{}:{}".format(app, data["name"]) for app, data in result.endpoints.items() + ] await self.block_until(lambda: _find_relation(*specs) is not None) return _find_relation(*specs) @@ -1573,11 +1630,7 @@ async def add_space(self, name, cidrs=None, public=True): :param List[str] cidrs: Optional list of existing subnet CIDRs """ space_facade = client.SpacesFacade.from_connection(self.connection()) - spaces = [ - { - "cidrs": cidrs, - "space-tag": tag.space(name), - "public": public}] + spaces = [{"cidrs": cidrs, "space-tag": tag.space(name), "public": public}] return await space_facade.CreateSpaces(spaces=spaces) async def add_ssh_key(self, user, key): @@ -1589,6 +1642,7 @@ async def add_ssh_key(self, user, key): """ key_facade = client.KeyManagerFacade.from_connection(self.connection()) return await key_facade.AddKeys(ssh_keys=[key], user=user) + add_ssh_keys = add_ssh_key async def get_backups(self): @@ -1599,9 +1653,9 @@ async def get_backups(self): backups_facade = client.BackupsFacade.from_connection(self.connection()) _backups_metadata = await backups_facade.List() backups_metadata = _backups_metadata.serialize() - if 'list' not in backups_metadata: + if "list" not in backups_metadata: raise JujuAPIError("Unexpected response metadata : %s" % backups_metadata) - return backups_metadata['list'] + return backups_metadata["list"] async def create_backup(self, notes=None): """Create a backup of this model. @@ -1620,19 +1674,29 @@ async def create_backup(self, notes=None): backup_metadata = results.serialize() - if 'error' in backup_metadata: - raise JujuBackupError("unable to create a backup, got %s from Juju API" % backup_metadata) + if "error" in backup_metadata: + raise JujuBackupError( + "unable to create a backup, got %s from Juju API" % backup_metadata + ) - backup_id = backup_metadata['filename'] + backup_id = backup_metadata["filename"] file_name = self.download_backup(backup_id) return file_name, backup_metadata async def debug_log( - self, target=sys.stdout, no_tail=False, exclude_module=[], - include_module=[], include=[], level="", limit=sys.maxsize, - lines=10, exclude=[]): + self, + target=sys.stdout, + no_tail=False, + exclude_module=[], + include_module=[], + include=[], + level="", + limit=sys.maxsize, + lines=10, + exclude=[], + ): """Get log messages for this model. :param bool no_tail: Stop after returning existing log messages @@ -1654,22 +1718,38 @@ async def debug_log( await self.connect() params = { - 'no_tail': no_tail, - 'exclude_module': exclude_module, - 'include_module': include_module, - 'include': include, - 'level': level, - 'limit': limit, - 'lines': lines, - 'exclude': exclude, + "no_tail": no_tail, + "exclude_module": exclude_module, + "include_module": include_module, + "include": include, + "level": level, + "limit": limit, + "lines": lines, + "exclude": exclude, } await self.connect(debug_log_conn=target, debug_log_params=params) async def deploy( - self, entity_url, application_name=None, bind=None, - channel=None, config=None, constraints=None, force=False, - num_units=1, overlays=[], base=None, resources=None, series=None, revision=None, - storage=None, to=None, devices=None, trust=False, attach_storage=[]): + self, + entity_url, + application_name=None, + bind=None, + channel=None, + config=None, + constraints=None, + force=False, + num_units=1, + overlays=[], + base=None, + resources=None, + series=None, + revision=None, + storage=None, + to=None, + devices=None, + trust=False, + attach_storage=[], + ): """Deploy a new service or bundle. :param str entity_url: Charm or bundle to deploy. Charm url or file path @@ -1707,15 +1787,20 @@ async def deploy( """ if storage: - storage = { - k: client.Constraints(**v) - for k, v in storage.items() - } - if trust and (self.info.agent_version < client.Number.from_json('2.4.0')): - raise NotImplementedError("trusted is not supported on model version {}".format(self.info.agent_version)) + storage = {k: client.Constraints(**v) for k, v in storage.items()} + if trust and (self.info.agent_version < client.Number.from_json("2.4.0")): + raise NotImplementedError( + "trusted is not supported on model version {}".format( + self.info.agent_version + ) + ) if not all([isinstance(st, str) for st in attach_storage]): - raise JujuError("Expected attach_storage to be a list of strings, given {}".format(attach_storage)) + raise JujuError( + "Expected attach_storage to be a list of strings, given {}".format( + attach_storage + ) + ) # Ensure what we pass in, is a string. entity = str(entity_url) @@ -1737,17 +1822,25 @@ async def deploy( name = url.name if schema not in self.deploy_types: - raise JujuError("unknown deploy type {}, expected charmhub or local".format(schema)) + raise JujuError( + "unknown deploy type {}, expected charmhub or local".format(schema) + ) model_conf = await self.get_config() - res = await self.deploy_types[schema].resolve(entity, architecture, - application_name, channel, - series, revision, - entity_url, force, - model_conf) + res = await self.deploy_types[schema].resolve( + entity, + architecture, + application_name, + channel, + series, + revision, + entity_url, + force, + model_conf, + ) if res.identifier is None: - raise JujuError('unknown charm or bundle {}'.format(entity_url)) + raise JujuError("unknown charm or bundle {}".format(entity_url)) identifier = res.identifier charm_series = series @@ -1767,15 +1860,20 @@ async def deploy( # new apps will usually be in the model by now, but if some # haven't made it yet we'll need to wait on them to be added await jasyncio.gather(*[ - jasyncio.ensure_future( - self._wait_for_new('application', app_name)) + jasyncio.ensure_future(self._wait_for_new("application", app_name)) for app_name in pending_apps ]) - return [app for name, app in self.applications.items() - if name in handler.applications] + return [ + app + for name, app in self.applications.items() + if name in handler.applications + ] else: if overlays: - raise JujuError("options provided but not supported when deploying a charm: overlays=%s" % overlays) + raise JujuError( + "options provided but not supported when deploying a charm: overlays=%s" + % overlays + ) # XXX: we're dropping local resources here, but we don't # actually support them yet anyway if not res.is_local: @@ -1783,12 +1881,14 @@ async def deploy( if isinstance(add_charm_res, dict): # This is for backwards compatibility for older # versions where AddCharm returns a dictionary - charm_origin = add_charm_res.get('charm_origin', - charm_origin) + charm_origin = add_charm_res.get("charm_origin", charm_origin) else: charm_origin = add_charm_res.charm_origin if Schema.CHARM_HUB.matches(schema): - if client.ApplicationFacade.best_facade_version(self.connection()) >= 19: + if ( + client.ApplicationFacade.best_facade_version(self.connection()) + >= 19 + ): server_side_deploy = True else: # TODO (cderici): this is an awkward workaround for basically not calling @@ -1797,14 +1897,16 @@ async def deploy( # resources) are handled at the server side if this is a server side deploy # (local uploads are handled right after we get the pendingIDs returned # from the facade call). - resources = await self._add_charmhub_resources(res.app_name, - identifier, - add_charm_res.charm_origin) + resources = await self._add_charmhub_resources( + res.app_name, identifier, add_charm_res.charm_origin + ) is_sub = await self.charmhub.is_subordinate(name) if is_sub: if num_units > 1: - raise JujuError("cannot use num_units with subordinate application") + raise JujuError( + "cannot use num_units with subordinate application" + ) num_units = 0 else: @@ -1817,20 +1919,19 @@ async def deploy( charm_origin.base = base if not application_name: - application_name = metadata['name'] + application_name = metadata["name"] if not application_name: - application_name = metadata['name'] + application_name = metadata["name"] if base is None and charm_series is None: raise JujuError( "Either series or base is needed to deploy the " - "charm at {}. ".format(charm_dir)) + "charm at {}. ".format(charm_dir) + ) - identifier = await self.add_local_charm_dir(charm_dir, - charm_series) - resources = await self.add_local_resources(application_name, - identifier, - metadata, - resources=resources) + identifier = await self.add_local_charm_dir(charm_dir, charm_series) + resources = await self.add_local_resources( + application_name, identifier, metadata, resources=resources + ) if config is None: config = {} @@ -1871,12 +1972,18 @@ async def _add_charm(self, charm_url, origin): charms_cls = client.CharmsFacade if charms_cls.best_facade_version(self.connection()) > 2: charms_facade = charms_cls.from_connection(self.connection()) - return await charms_facade.AddCharm(charm_origin=origin, url=charm_url, force=False) + return await charms_facade.AddCharm( + charm_origin=origin, url=charm_url, force=False + ) client_facade = client.ClientFacade.from_connection(self.connection()) - return await client_facade.AddCharm(channel=str(origin.risk), url=charm_url, force=False) + return await client_facade.AddCharm( + channel=str(origin.risk), url=charm_url, force=False + ) - async def _resolve_charm(self, url, origin, force=False, series=None, model_config=None): + async def _resolve_charm( + self, url, origin, force=False, series=None, model_config=None + ): """Calls Charms.ResolveCharms to resolve all the fields of the charm_origin and also the url and the supported_series @@ -1901,30 +2008,39 @@ async def _resolve_charm(self, url, origin, force=False, series=None, model_conf # committing to make sure there's no regression source = Source.CHARM_HUB.value - resolve_origin = {'source': source, 'architecture': origin.architecture, - 'track': origin.track, 'risk': origin.risk, - 'base': origin.base, 'revision': origin.revision, - } + resolve_origin = { + "source": source, + "architecture": origin.architecture, + "track": origin.track, + "risk": origin.risk, + "base": origin.base, + "revision": origin.revision, + } - resp = await charms_facade.ResolveCharms(resolve=[{ - 'reference': str(url), - 'charm-origin': resolve_origin - }]) + resp = await charms_facade.ResolveCharms( + resolve=[{"reference": str(url), "charm-origin": resolve_origin}] + ) if len(resp.results) != 1: raise JujuError("expected one result, received {}".format(resp.results)) result = resp.results[0] if result.error: - raise JujuError(f'resolving {url} : {result.error.message}') + raise JujuError(f"resolving {url} : {result.error.message}") # TODO (cderici) : supported_bases - supported_series = result.get('supported_series', result.unknown_fields['supported-series']) + supported_series = result.get( + "supported_series", result.unknown_fields["supported-series"] + ) resolved_origin = result.charm_origin charm_url = URL.parse(result.url) # run the series selector to get a series for the base - selected_series = utils.series_selector(series, charm_url, model_config, supported_series, force) - result.charm_origin.base = utils.get_base_from_origin_or_channel(resolved_origin, selected_series) + selected_series = utils.series_selector( + series, charm_url, model_config, supported_series, force + ) + result.charm_origin.base = utils.get_base_from_origin_or_channel( + resolved_origin, selected_series + ) charm_url.series = selected_series return charm_url, resolved_origin @@ -1942,15 +2058,14 @@ async def _resolve_architecture(self, url=None): return url.architecture constraints = await self.get_constraints() - if 'arch' in constraints: - return constraints['arch'] + if "arch" in constraints: + return constraints["arch"] return DEFAULT_ARCHITECTURE - async def _add_charmhub_resources(self, application, - entity_url, - origin, - overrides=None): + async def _add_charmhub_resources( + self, application, entity_url, origin, overrides=None + ): """_add_charmhub_resources is called by the deploy to add pending resources requested by the charm being deployed. It calls the ResourcesFacade.AddPendingResources. @@ -1967,27 +2082,28 @@ async def _add_charmhub_resources(self, application, resources = [] for resource in res.meta.resources.values(): resources.append({ - 'description': resource.description, - 'name': resource.name, - 'path': resource.path, - 'type_': resource.type_, - 'origin': 'store', - 'revision': -1, + "description": resource.description, + "name": resource.name, + "path": resource.path, + "type_": resource.type_, + "origin": "store", + "revision": -1, }) if overrides: - names = {r['name'] for r in resources} + names = {r["name"] for r in resources} unknown = overrides.keys() - names if unknown: - raise JujuError('Unrecognized resource{}: {}'.format( - 's' if len(unknown) > 1 else '', - ', '.join(unknown))) + raise JujuError( + "Unrecognized resource{}: {}".format( + "s" if len(unknown) > 1 else "", ", ".join(unknown) + ) + ) for resource in resources: - if resource['name'] in overrides: - resource['revision'] = overrides[resource['name']] + if resource["name"] in overrides: + resource["revision"] = overrides[resource["name"]] - resources_facade = client.ResourcesFacade.from_connection( - self.connection()) + resources_facade = client.ResourcesFacade.from_connection(self.connection()) response = await resources_facade.AddPendingResources( application_tag=tag.application(application), charm_url=entity_url, @@ -1997,9 +2113,10 @@ async def _add_charmhub_resources(self, application, # response.pending_ids always exists but it can itself be None # see juju/client/_definitions.py for AddPendingResourcesResult - resource_map = {resource['name']: pid - for resource, pid - in zip(resources, response.pending_ids or {})} + resource_map = { + resource["name"]: pid + for resource, pid in zip(resources, response.pending_ids or {}) + } return resource_map @@ -2026,40 +2143,44 @@ async def add_local_resources(self, application, entity_url, metadata, resources for name, path in resources.items(): resource_type = metadata["resources"][name]["type"] if resource_type not in {"oci-image", "file"}: - log.info("Resource {} of type {} is not supported".format(name, resource_type)) + log.info( + "Resource {} of type {} is not supported".format( + name, resource_type + ) + ) continue charmresource = { - 'description': '', - 'fingerprint': '', - 'name': name, - 'path': Path(path).name, - 'revision': 0, - 'size': 0, - 'type_': resource_type, - 'origin': 'upload', + "description": "", + "fingerprint": "", + "name": name, + "path": Path(path).name, + "revision": 0, + "size": 0, + "type_": resource_type, + "origin": "upload", } - resources_facade = client.ResourcesFacade.from_connection( - self.connection()) + resources_facade = client.ResourcesFacade.from_connection(self.connection()) response = await resources_facade.AddPendingResources( application_tag=tag.application(application), charm_url=entity_url, - resources=[client.CharmResource(**charmresource)]) + resources=[client.CharmResource(**charmresource)], + ) pending_id = response.pending_ids[0] resource_map[name] = pending_id if resource_type == "oci-image": # TODO Docker Image validation and support for local images. docker_image_details = { - 'registrypath': path, - 'username': '', - 'password': '', + "registrypath": path, + "username": "", + "password": "", } data = yaml.dump(docker_image_details) else: p = Path(path) - data = p.read_text() if p.exists() else '' + data = p.read_text() if p.exists() else "" self._upload(data, path, application, name, resource_type, pending_id) @@ -2069,38 +2190,52 @@ def _upload(self, data, path, app_name, res_name, res_type, pending_id): conn, headers, path_prefix = self.connection().https_connection() query = "?pendingid={}".format(pending_id) - url = "{}/applications/{}/resources/{}{}".format(path_prefix, app_name, res_name, query) + url = "{}/applications/{}/resources/{}{}".format( + path_prefix, app_name, res_name, query + ) if res_type == "oci-image": - disp = "multipart/form-data; filename=\"{}\"".format(path) + disp = 'multipart/form-data; filename="{}"'.format(path) else: - disp = "form-data; filename=\"{}\"".format(path) + disp = 'form-data; filename="{}"'.format(path) - headers['Content-Type'] = 'application/octet-stream' - headers['Content-Length'] = len(data) - headers['Content-Sha384'] = hashlib.sha384(bytes(data, 'utf-8')).hexdigest() - headers['Content-Disposition'] = disp + headers["Content-Type"] = "application/octet-stream" + headers["Content-Length"] = len(data) + headers["Content-Sha384"] = hashlib.sha384(bytes(data, "utf-8")).hexdigest() + headers["Content-Disposition"] = disp - conn.request('PUT', url, data, headers) + conn.request("PUT", url, data, headers) response = conn.getresponse() result = response.read().decode() if not response.status == 200: raise JujuError(result) - async def _deploy(self, charm_url, application, series, config, - constraints, endpoint_bindings, resources, storage, - channel=None, num_units=None, placement=None, - devices=None, charm_origin=None, attach_storage=[], - force=False, server_side_deploy=False): - """Logic shared between `Model.deploy` and `BundleHandler.deploy`. - """ - log.info('Deploying %s', charm_url) + async def _deploy( + self, + charm_url, + application, + series, + config, + constraints, + endpoint_bindings, + resources, + storage, + channel=None, + num_units=None, + placement=None, + devices=None, + charm_origin=None, + attach_storage=[], + force=False, + server_side_deploy=False, + ): + """Logic shared between `Model.deploy` and `BundleHandler.deploy`.""" + log.info("Deploying %s", charm_url) - trust = config.get('trust', False) + trust = config.get("trust", False) # stringify all config values for API, and convert to YAML config = {k: str(v) for k, v in config.items()} - config = yaml.dump({application: config}, - default_flow_style=False) + config = yaml.dump({application: config}, default_flow_style=False) app_facade = client.ApplicationFacade.from_connection(self.connection()) @@ -2133,11 +2268,20 @@ async def _deploy(self, charm_url, application, series, config, errors.extend([e.message for e in r.errors]) # Upload pending local resources if any for _result in result.results: - for pending_upload_resource in getattr(_result, 'pendingresourceuploads', []): + for pending_upload_resource in getattr( + _result, "pendingresourceuploads", [] + ): _path = pending_upload_resource.filename p = Path(_path) - data = p.read_text() if p.exists() else '' - self._upload(data, _path, application, pending_upload_resource.name, 'file', '') + data = p.read_text() if p.exists() else "" + self._upload( + data, + _path, + application, + pending_upload_resource.name, + "file", + "", + ) else: app = client.ApplicationDeploy( charm_url=charm_url, @@ -2159,25 +2303,31 @@ async def _deploy(self, charm_url, application, series, config, result = await app_facade.Deploy(applications=[app]) errors = [r.error.message for r in result.results if r.error] if errors: - raise JujuError('\n'.join(errors)) - - return await self._wait_for_new('application', application) + raise JujuError("\n".join(errors)) - async def destroy_unit(self, unit_id, destroy_storage=False, dry_run=False, force=False, max_wait=None): - """Destroy units by name. + return await self._wait_for_new("application", application) - """ - return await self.destroy_units(unit_id, - destroy_storage=destroy_storage, - dry_run=dry_run, - force=force, - max_wait=max_wait - ) - - async def destroy_units(self, *unit_names, destroy_storage=False, dry_run=False, force=False, max_wait=None): - """Destroy several units at once. + async def destroy_unit( + self, unit_id, destroy_storage=False, dry_run=False, force=False, max_wait=None + ): + """Destroy units by name.""" + return await self.destroy_units( + unit_id, + destroy_storage=destroy_storage, + dry_run=dry_run, + force=force, + max_wait=max_wait, + ) - """ + async def destroy_units( + self, + *unit_names, + destroy_storage=False, + dry_run=False, + force=False, + max_wait=None, + ): + """Destroy several units at once.""" connection = self.connection() app_facade = client.ApplicationFacade.from_connection(connection) @@ -2188,13 +2338,13 @@ async def destroy_units(self, *unit_names, destroy_storage=False, dry_run=False, log.error("Error converting %s to a valid unit tag", unit_id) raise JujuUnitError("Error converting %s to a valid unit tag", unit_id) units_to_destroy.append({ - 'unit-tag': unit_tag, - 'destroy-storage': destroy_storage, - 'force': force, - 'max-wait': max_wait, - 'dry-run': dry_run, + "unit-tag": unit_tag, + "destroy-storage": destroy_storage, + "force": force, + "max-wait": max_wait, + "dry-run": dry_run, }) - log.debug('Destroying units %s', unit_names) + log.debug("Destroying units %s", unit_names) return await app_facade.DestroyUnit(units=units_to_destroy) def download_backup(self, archive_id, target_filename=None): @@ -2208,29 +2358,34 @@ def download_backup(self, archive_id, target_filename=None): conn, headers, path_prefix = self.connection().https_connection() path = "%s/backups" % path_prefix - headers['Content-Type'] = 'application/json' - args = {'id': archive_id} + headers["Content-Type"] = "application/json" + args = {"id": archive_id} conn.request("GET", path, json.dumps(args, indent=2), headers=headers) response = conn.getresponse() result = response.read() if not response.status == 200: - raise JujuBackupError("unable to download the backup ID : %s -- got : %s from the JujuAPI with a HTTP response code : %s" % (archive_id, result, response.status)) + raise JujuBackupError( + "unable to download the backup ID : %s -- got : %s from the JujuAPI with a HTTP response code : %s" + % (archive_id, result, response.status) + ) if target_filename: file_name = target_filename else: # check if archive_id is a filename - if re.match(r'.*\.tar\.gz', archive_id): + if re.match(r".*\.tar\.gz", archive_id): # if so, use the same ID generated & sent by the Juju API - archive_id = re.compile('[0-9]+').findall(archive_id)[0] + archive_id = re.compile("[0-9]+").findall(archive_id)[0] file_name = "juju-backup-%s.tar.gz" % archive_id - with open(str(file_name), 'wb') as f: + with open(str(file_name), "wb") as f: try: f.write(result) except (OSError, IOError) as e: - raise JujuBackupError("backup ID : %s was fetched, but : %s" % (archive_id, e)) + raise JujuBackupError( + "backup ID : %s was fetched, but : %s" % (archive_id, e) + ) log.info("Backup archive downloaded in : %s" % file_name) return file_name @@ -2241,9 +2396,7 @@ async def get_config(self): :returns: A ``dict`` mapping keys to `ConfigValue` instances, which have `source` and `value` attributes. """ - config_facade = client.ModelConfigFacade.from_connection( - self.connection() - ) + config_facade = client.ModelConfigFacade.from_connection(self.connection()) result = await config_facade.ModelGet() config = result.config for key, value in config.items(): @@ -2268,19 +2421,17 @@ async def get_constraints(self): # constraint, each of these in turn will be None if they have not been # set. if result.constraints: - constraint_types = [a for a in dir(result.constraints) - if a in client.Value._toSchema.keys()] + constraint_types = [ + a for a in dir(result.constraints) if a in client.Value._toSchema.keys() + ] for constraint in constraint_types: value = getattr(result.constraints, constraint) if value is not None: - constraints[constraint] = getattr(result.constraints, - constraint) + constraints[constraint] = getattr(result.constraints, constraint) return constraints async def get_machines(self): - """Return list of machines in this model. - - """ + """Return list of machines in this model.""" return list(self.state.machines.keys()) async def get_spaces(self): @@ -2299,9 +2450,10 @@ async def get_ssh_key(self, raw_ssh=False): """ key_facade = client.KeyManagerFacade.from_connection(self.connection()) - entity = {'tag': tag.model(self.info.uuid)} + entity = {"tag": tag.model(self.info.uuid)} entities = client.Entities([entity]) return await key_facade.ListKeys(entities=entities, mode=raw_ssh) + get_ssh_keys = get_ssh_key async def remove_backup(self, backup_id): @@ -2330,15 +2482,21 @@ async def remove_ssh_key(self, user, key): """ key_facade = client.KeyManagerFacade.from_connection(self.connection()) - key = base64.b64decode(bytes(key.strip().split()[1].encode('ascii'))) + key = base64.b64decode(bytes(key.strip().split()[1].encode("ascii"))) key = hashlib.md5(key).hexdigest() - key = ':'.join(a + b for a, b in zip(key[::2], key[1::2])) + key = ":".join(a + b for a, b in zip(key[::2], key[1::2])) await key_facade.DeleteKeys(ssh_keys=[key], user=user) + remove_ssh_keys = remove_ssh_key def restore_backup( - self, backup_id, bootstrap=False, - constraints=None, archive=None, upload_tools=False): + self, + backup_id, + bootstrap=False, + constraints=None, + archive=None, + upload_tools=False, + ): """Restore a backup archive to a new controller. :param str backup_id: Id of backup to restore @@ -2349,7 +2507,9 @@ def restore_backup( :param bool upload_tools: Upload tools if bootstrapping a new machine """ - raise DeprecationWarning("juju restore-backup is deprecated in favor of the stand-alone 'juju-restore' tool: https://github.com/juju/juju-restore") + raise DeprecationWarning( + "juju restore-backup is deprecated in favor of the stand-alone 'juju-restore' tool: https://github.com/juju/juju-restore" + ) async def set_config(self, config): """Set configuration keys on this model. @@ -2357,9 +2517,7 @@ async def set_config(self, config): :param dict config: Mapping of config keys to either string values or `ConfigValue` instances, as returned by `get_config`. """ - config_facade = client.ModelConfigFacade.from_connection( - self.connection() - ) + config_facade = client.ModelConfigFacade.from_connection(self.connection()) new_conf = {} for key, value in config.items(): @@ -2368,7 +2526,10 @@ async def set_config(self, config): elif isinstance(value, str): new_conf[key] = value else: - raise JujuModelConfigError("Expected either a string or a ConfigValue as a config value, found : %s of type %s" % (value, type(value))) + raise JujuModelConfigError( + "Expected either a string or a ConfigValue as a config value, found : %s of type %s" + % (value, type(value)) + ) await config_facade.ModelSet(config=new_conf) async def set_constraints(self, constraints): @@ -2381,12 +2542,10 @@ async def set_constraints(self, constraints): facade = facade_cls.from_connection(self.connection()) - await facade.SetModelConstraints( - application='', - constraints=constraints) + await facade.SetModelConstraints(application="", constraints=constraints) async def get_action_output(self, action_uuid, wait=None): - """ Get the results of an action by ID. + """Get the results of an action by ID. :param str action_uuid: Id of the action :param int wait: Time in seconds to wait for action to complete. @@ -2405,25 +2564,22 @@ async def _get_completed_action(self, action_uuid, wait=None): :return dict: Output from action :raises: :class:`JujuError` if invalid action_uuid """ - action_facade = client.ActionFacade.from_connection( - self.connection() - ) - entity = [{'tag': tag.action(action_uuid)}] + action_facade = client.ActionFacade.from_connection(self.connection()) + entity = [{"tag": tag.action(action_uuid)}] # Cannot use self.wait_for_action as the action event has probably # already happened and self.wait_for_action works by processing # model deltas and checking if they match our type. If the action - # has already occured then the delta has gone. + # has already occurred then the delta has gone. async def _wait_for_action_status(): while True: action_output = await action_facade.Actions(entities=entity) - if action_output.results[0].status in ('completed', 'failed'): + if action_output.results[0].status in ("completed", "failed"): return else: await jasyncio.sleep(1) - await jasyncio.wait_for( - _wait_for_action_status(), - timeout=wait) + + await jasyncio.wait_for(_wait_for_action_status(), timeout=wait) action_results = await action_facade.Actions(entities=entity) return action_results.results[0] @@ -2436,24 +2592,23 @@ async def get_action_status(self, uuid_or_prefix=None, name=None): """ results = {} action_results = [] - action_facade = client.ActionFacade.from_connection( - self.connection() - ) + action_facade = client.ActionFacade.from_connection(self.connection()) if name: name_results = await action_facade.FindActionsByNames(names=[name]) action_results.extend(name_results.actions[0].actions) if uuid_or_prefix: # Collect list of actions matching uuid or prefix matching_actions = await action_facade.FindActionTagsByPrefix( - prefixes=[uuid_or_prefix]) + prefixes=[uuid_or_prefix] + ) entities = [] for actions in matching_actions.matches.values(): - entities = [{'tag': a.tag} for a in actions] + entities = [{"tag": a.tag} for a in actions] # Get action results matching action tags uuid_results = await action_facade.Actions(entities=entities) action_results.extend(uuid_results.results) for a in action_results: - results[tag.untag('action-', a.action.tag)] = a.status + results[tag.untag("action-", a.action.tag)] = a.status return results async def get_status(self, filters=None, utc=False): @@ -2475,11 +2630,9 @@ async def get_metrics(self, *tags): :return: Dictionary of unit_name:metrics """ - log.debug("Retrieving metrics for %s", - ', '.join(tags) if tags else "all units") + log.debug("Retrieving metrics for %s", ", ".join(tags) if tags else "all units") - metrics_facade = client.MetricsDebugFacade.from_connection( - self.connection()) + metrics_facade = client.MetricsDebugFacade.from_connection(self.connection()) entities = [client.Entity(tag) for tag in tags] metrics_result = await metrics_facade.GetMetrics(entities=entities) @@ -2508,9 +2661,12 @@ async def create_offer(self, endpoint, offer_name=None, application_name=None): @param offer_name: over ride the offer name to help the consumer """ async with ConnectedController(self.connection()) as controller: - return await controller.create_offer(self.info.uuid, endpoint, - offer_name=offer_name, - application_name=application_name) + return await controller.create_offer( + self.info.uuid, + endpoint, + offer_name=offer_name, + application_name=application_name, + ) async def list_offers(self): """ @@ -2530,7 +2686,9 @@ async def remove_offer(self, endpoint, force=False): async with ConnectedController(self.connection()) as controller: return await controller.remove_offer(self.info.uuid, endpoint, force) - async def consume(self, endpoint, application_alias="", controller_name=None, controller=None): + async def consume( + self, endpoint, application_alias="", controller_name=None, controller=None + ): """ Adds a remote offer to the model. Relations can be created later using "juju relate". @@ -2548,15 +2706,18 @@ async def consume(self, endpoint, application_alias="", controller_name=None, co log.error(e.message) raise if offer.has_endpoint(): - raise JujuError("remote offer {} should not include an endpoint".format(endpoint)) + raise JujuError( + "remote offer {} should not include an endpoint".format(endpoint) + ) if offer.user == "": offer.user = self.info.username endpoint = offer.string() if controller_name: log.warning( - 'controller_name argument will soon be deprecated, controller ' - 'should be specified in endpoint url') + "controller_name argument will soon be deprecated, controller " + "should be specified in endpoint url" + ) if offer.source == "": offer.source = controller_name @@ -2579,7 +2740,9 @@ async def consume(self, endpoint, application_alias="", controller_name=None, co if not controller: await source.disconnect() if consume_details is None or consume_details.offer is None: - raise JujuAPIError("missing consuming offer url for {}".format(offer.string())) + raise JujuAPIError( + "missing consuming offer url for {}".format(offer.string()) + ) offer_url = parse_offer_url(consume_details.offer.offer_url) offer_url.source = offer.source @@ -2587,14 +2750,18 @@ async def consume(self, endpoint, application_alias="", controller_name=None, co consume_details.offer.offer_url = offer_url.string() consume_details.offer.application_alias = application_alias - arg = _create_consume_args(consume_details.offer, - consume_details.macaroon, - consume_details.external_controller) + arg = _create_consume_args( + consume_details.offer, + consume_details.macaroon, + consume_details.external_controller, + ) facade = client.ApplicationFacade.from_connection(self.connection()) results = await facade.Consume(args=[arg]) if len(results.results) != 1: - raise JujuAPIError("expected 1 result, recieved {}".format(len(results.results))) + raise JujuAPIError( + "expected 1 result, received {}".format(len(results.results)) + ) if results.results[0].error is not None: raise JujuAPIError(results.results[0].error) local_name = offer_url.application @@ -2658,11 +2825,13 @@ async def add_secret(self, name, data_args, file="", info=""): raise JujuNotSupportedError("user secrets") secretsFacade = client.SecretsFacade.from_connection(self.connection()) - results = await secretsFacade.CreateSecrets([{ - 'content': {'data': data}, - 'description': info, - 'label': name, - }]) + results = await secretsFacade.CreateSecrets([ + { + "content": {"data": data}, + "description": info, + "label": name, + } + ]) if len(results.results) != 1: raise JujuAPIError(f"expected 1 result, got {len(results.results)}") result = results.results[0] @@ -2691,12 +2860,14 @@ async def update_secret(self, name, data_args=[], new_name="", file="", info="") if client.SecretsFacade.best_facade_version(self.connection()) < 2: raise JujuNotSupportedError("user secrets") secretsFacade = client.SecretsFacade.from_connection(self.connection()) - results = await secretsFacade.UpdateSecrets([{ - 'content': {'data': data}, - 'description': info, - 'existing-label': name, - 'label': new_name, - }]) + results = await secretsFacade.UpdateSecrets([ + { + "content": {"data": data}, + "description": info, + "existing-label": name, + "label": new_name, + } + ]) if len(results.results) != 1: raise JujuAPIError(f"expected 1 result, got {len(results.results)}") result_error = results.results[0] @@ -2723,10 +2894,10 @@ async def remove_secret(self, secret_name, revision=-1): if client.SecretsFacade.best_facade_version(self.connection()) < 2: raise JujuNotSupportedError("user secrets") remove_secret_arg = { - 'label': secret_name, + "label": secret_name, } if revision >= 0: - remove_secret_arg['revisions'] = [revision] + remove_secret_arg["revisions"] = [revision] secretsFacade = client.SecretsFacade.from_connection(self.connection()) results = await secretsFacade.RemoveSecrets([remove_secret_arg]) @@ -2747,8 +2918,8 @@ async def grant_secret(self, secret_name, application, *applications): raise JujuNotSupportedError("user secrets") secretsFacade = client.SecretsFacade.from_connection(self.connection()) results = await secretsFacade.GrantSecret( - applications=[application] + list(applications), - label=secret_name) + applications=[application] + list(applications), label=secret_name + ) if len(results.results) != 1: raise JujuAPIError(f"expected 1 result, got {len(results.results)}") result_error = results.results[0] @@ -2768,8 +2939,8 @@ async def revoke_secret(self, secret_name, application, *applications): raise JujuNotSupportedError("user secrets") secretsFacade = client.SecretsFacade.from_connection(self.connection()) results = await secretsFacade.RevokeSecret( - applications=[application] + list(applications), - label=secret_name) + applications=[application] + list(applications), label=secret_name + ) if len(results.results) != 1: raise JujuAPIError(f"expected 1 result, got {len(results.results)}") result_error = results.results[0] @@ -2788,9 +2959,19 @@ async def _get_source_api(self, url): await controller.connect(controller_name=controller_name) return controller - async def wait_for_idle(self, apps=None, raise_on_error=True, raise_on_blocked=False, - wait_for_active=False, timeout=10 * 60, idle_period=15, check_freq=0.5, - status=None, wait_for_at_least_units=None, wait_for_exact_units=None): + async def wait_for_idle( + self, + apps=None, + raise_on_error=True, + raise_on_blocked=False, + wait_for_active=False, + timeout=10 * 60, + idle_period=15, + check_freq=0.5, + status=None, + wait_for_at_least_units=None, + wait_for_exact_units=None, + ): """Wait for applications in the model to settle into an idle state. :param List[str] apps: Optional list of specific app names to wait on. @@ -2836,19 +3017,23 @@ async def wait_for_idle(self, apps=None, raise_on_error=True, raise_on_blocked=F When set, takes precedence over the `wait_for_units` parameter. """ if wait_for_active: - warnings.warn("wait_for_active is deprecated; use status", DeprecationWarning) + warnings.warn( + "wait_for_active is deprecated; use status", DeprecationWarning + ) status = "active" - _wait_for_units = wait_for_at_least_units if wait_for_at_least_units is not None else 1 + _wait_for_units = ( + wait_for_at_least_units if wait_for_at_least_units is not None else 1 + ) timeout = timedelta(seconds=timeout) if timeout is not None else None idle_period = timedelta(seconds=idle_period) start_time = datetime.now() # Type check against the common error of passing a str for apps - if apps is not None and (not isinstance(apps, list) or - any(not isinstance(o, str) - for o in apps)): - raise JujuError(f'Expected a List[str] for apps, given {apps}') + if apps is not None and ( + not isinstance(apps, list) or any(not isinstance(o, str) for o in apps) + ): + raise JujuError(f"Expected a List[str] for apps, given {apps}") apps = apps or self.applications idle_times = {} @@ -2859,23 +3044,28 @@ async def wait_for_idle(self, apps=None, raise_on_error=True, raise_on_blocked=F def _raise_for_status(entities, status): if not entities: return - for entity_name, error_type in (("Machine", JujuMachineError), - ("Agent", JujuAgentError), - ("Unit", JujuUnitError), - ("App", JujuAppError)): + for entity_name, error_type in ( + ("Machine", JujuMachineError), + ("Agent", JujuAgentError), + ("Unit", JujuUnitError), + ("App", JujuAppError), + ): errored = entities.get(entity_name, []) if not errored: continue - raise error_type("{}{} in {}: {}".format( - entity_name, - "s" if len(errored) > 1 else "", - status, - ", ".join(errored), - )) + raise error_type( + "{}{} in {}: {}".format( + entity_name, + "s" if len(errored) > 1 else "", + status, + ", ".join(errored), + ) + ) if wait_for_exact_units is not None: - assert isinstance(wait_for_exact_units, int) and wait_for_exact_units >= 0, \ - 'Invalid value for wait_for_exact_units : %s' % wait_for_exact_units + assert ( + isinstance(wait_for_exact_units, int) and wait_for_exact_units >= 0 + ), "Invalid value for wait_for_exact_units : %s" % wait_for_exact_units while True: # The list 'busy' is what keeps this loop going, @@ -2898,13 +3088,19 @@ def _raise_for_status(entities, status): # Check if wait_for_exact_units flag is used if wait_for_exact_units is not None: if len(app.units) != wait_for_exact_units: - busy.append(app.name + " (waiting for exactly %s units, current : %s)" % - (wait_for_exact_units, len(app.units))) + busy.append( + app.name + + " (waiting for exactly %s units, current : %s)" + % (wait_for_exact_units, len(app.units)) + ) continue # If we have less # of units then required, then wait a bit more elif len(app.units) < _wait_for_units: - busy.append(app.name + " (not enough units yet - %s/%s)" % - (len(app.units), _wait_for_units)) + busy.append( + app.name + + " (not enough units yet - %s/%s)" + % (len(app.units), _wait_for_units) + ) continue # User is waiting for at least a certain # of units, and we have enough elif wait_for_at_least_units and len(units_ready) >= _wait_for_units: @@ -2913,7 +3109,11 @@ def _raise_for_status(entities, status): # errors to raise at the end break for unit in app.units: - if raise_on_error and unit.machine is not None and unit.machine.status == "error": + if ( + raise_on_error + and unit.machine is not None + and unit.machine.status == "error" + ): errors.setdefault("Machine", []).append(unit.machine.id) continue if raise_on_error and unit.agent_status == "error": @@ -2929,11 +3129,15 @@ def _raise_for_status(entities, status): # individual units, another one for waiting for an application. # The convoluted logic below is the result of trying to do both at the same # time - need_to_wait_more_for_a_particular_status = status and (unit.workload_status != status) + need_to_wait_more_for_a_particular_status = status and ( + unit.workload_status != status + ) app_is_in_desired_status = (not status) or (app_status == status) - if not need_to_wait_more_for_a_particular_status and \ - unit.agent_status == "idle" and \ - (wait_for_at_least_units or app_is_in_desired_status): + if ( + not need_to_wait_more_for_a_particular_status + and unit.agent_status == "idle" + and (wait_for_at_least_units or app_is_in_desired_status) + ): # A unit is ready if either: # 1) Don't need to wait more for a particular status and the agent is "idle" # 2) We're looking for a particular status and the unit's workload, @@ -2950,16 +3154,24 @@ def _raise_for_status(entities, status): idle_start = idle_times.setdefault(unit.name, now) if now - idle_start < idle_period: - busy.append("{} [{}] {}: {}".format(unit.name, - unit.agent_status, - unit.workload_status, - unit.workload_status_message)) + busy.append( + "{} [{}] {}: {}".format( + unit.name, + unit.agent_status, + unit.workload_status, + unit.workload_status_message, + ) + ) else: idle_times.pop(unit.name, None) - busy.append("{} [{}] {}: {}".format(unit.name, - unit.agent_status, - unit.workload_status, - unit.workload_status_message)) + busy.append( + "{} [{}] {}: {}".format( + unit.name, + unit.agent_status, + unit.workload_status, + unit.workload_status_message, + ) + ) _raise_for_status(errors, "error") _raise_for_status(blocks, "blocked") if not busy: @@ -2975,7 +3187,7 @@ def _raise_for_status(entities, status): def _create_consume_args(offer, macaroon, controller_info): """ - Convert a typed object that has been normalised to a overrided typed + Convert a typed object that has been normalised to a overridden typed definition. @param offer: takes an offer and serialises it into a valid type @@ -2985,26 +3197,33 @@ def _create_consume_args(offer, macaroon, controller_info): """ endpoints = [] for ep in offer.endpoints: - endpoints.append(client.RemoteEndpoint(interface=ep.interface, - limit=ep.limit, - name=ep.name, - role=ep.role)) + endpoints.append( + client.RemoteEndpoint( + interface=ep.interface, limit=ep.limit, name=ep.name, role=ep.role + ) + ) users = [] for u in offer.users: - users.append(client.OfferUserDetails(access=u.access, - display_name=u.display_name, - user=u.user)) - external_controller = client.ExternalControllerInfo(addrs=controller_info.addrs, - ca_cert=controller_info.ca_cert, - controller_alias=controller_info.controller_alias, - controller_tag=controller_info.controller_tag) + users.append( + client.OfferUserDetails( + access=u.access, display_name=u.display_name, user=u.user + ) + ) + external_controller = client.ExternalControllerInfo( + addrs=controller_info.addrs, + ca_cert=controller_info.ca_cert, + controller_alias=controller_info.controller_alias, + controller_tag=controller_info.controller_tag, + ) caveats = [] for c in macaroon.unknown_fields["caveats"]: caveats.append(Caveat(cid=c["cid"])) - macaroon = Macaroon(signature=macaroon.unknown_fields["signature"], - caveats=caveats, - location=macaroon.unknown_fields["location"], - identifier=macaroon.unknown_fields["identifier"]) + macaroon = Macaroon( + signature=macaroon.unknown_fields["signature"], + caveats=caveats, + location=macaroon.unknown_fields["location"], + identifier=macaroon.unknown_fields["identifier"], + ) arg = client.ConsumeApplicationArg() arg.application_description = offer.application_description @@ -3028,6 +3247,7 @@ class CharmArchiveGenerator: This is used automatically by `Model.add_local_charm_dir <#juju.model.Model.add_local_charm_dir>`_. """ + def __init__(self, path): self.path = os.path.abspath(os.path.expanduser(path)) @@ -3045,9 +3265,9 @@ def make_archive(self, path): (.bzr, etc) """ - zf = zipfile.ZipFile(str(path), 'w', zipfile.ZIP_DEFLATED) + zf = zipfile.ZipFile(str(path), "w", zipfile.ZIP_DEFLATED) for dirpath, dirnames, filenames in os.walk(self.path): - relative_path = dirpath[len(self.path) + 1:] + relative_path = dirpath[len(self.path) + 1 :] if relative_path and not self._ignore(relative_path): zf.write(dirpath, relative_path) for dirname in dirnames: @@ -3063,34 +3283,33 @@ def make_archive(self, path): self._check_type(real_path) if os.path.islink(real_path): self._check_link(real_path) - self._write_symlink( - zf, os.readlink(real_path), archive_name) + self._write_symlink(zf, os.readlink(real_path), archive_name) else: zf.write(real_path, archive_name) zf.close() return path def _check_type(self, path): - """Check the path - """ + """Check the path""" s = os.stat(str(path)) if stat.S_ISDIR(s.st_mode) or stat.S_ISREG(s.st_mode): return path - raise ValueError("Invalid Charm at %s %s" % ( - path, "Invalid file type for a charm")) + raise ValueError( + "Invalid Charm at %s %s" % (path, "Invalid file type for a charm") + ) def _check_link(self, path): link_path = os.readlink(path) if link_path[0] == "/": raise ValueError( - "Invalid Charm at %s: %s" % ( - path, "Absolute links are invalid")) + "Invalid Charm at %s: %s" % (path, "Absolute links are invalid") + ) path_dir = os.path.dirname(path) link_path = os.path.join(path_dir, link_path) if not link_path.startswith(os.path.abspath(self.path)): raise ValueError( - "Invalid charm at %s %s" % ( - path, "Only internal symlinks are allowed")) + "Invalid charm at %s %s" % (path, "Only internal symlinks are allowed") + ) def _write_symlink(self, zf, link_target, link_path): """Package symlinks with appropriate zipfile metadata.""" @@ -3105,12 +3324,11 @@ def _write_symlink(self, zf, link_target, link_path): def _ignore(self, path): if path == "build" or path.startswith("build/"): return True - if path.startswith('.'): + if path.startswith("."): return True class ModelInfo(ModelEntity): - @property def tag(self): return tag.model(self.uuid) diff --git a/juju/names.py b/juju/names.py index 554e0f805..845d8ab80 100644 --- a/juju/names.py +++ b/juju/names.py @@ -11,7 +11,7 @@ class MatchType(Enum): SEARCH = 2 -MODEL = re.compile('^[a-z0-9]+[a-z0-9-]*$') +MODEL = re.compile("^[a-z0-9]+[a-z0-9-]*$") def match_model(val, match_type=None): @@ -21,7 +21,7 @@ def match_model(val, match_type=None): return re.match(MODEL, val) -APPLICATION = re.compile('^(?:[a-z][a-z0-9]*(?:-[a-z0-9]*[a-z][a-z0-9]*)*)$') +APPLICATION = re.compile("^(?:[a-z][a-z0-9]*(?:-[a-z0-9]*[a-z][a-z0-9]*)*)$") def match_application(val, match_type=None): @@ -35,7 +35,9 @@ def is_valid_application(val): return match_application(val) is not None -ENDPOINT = re.compile('/?((?P[^\\.]*)\\.)?(?P[^:]*)(:(?P.*))?') +ENDPOINT = re.compile( + "/?((?P[^\\.]*)\\.)?(?P[^:]*)(:(?P.*))?" +) def match_endpoint(val, match_type=None): @@ -45,7 +47,7 @@ def match_endpoint(val, match_type=None): return re.match(ENDPOINT, val) -SOURCE_ENDPOINT = re.compile('^[a-zA-Z0-9]+$') +SOURCE_ENDPOINT = re.compile("^[a-zA-Z0-9]+$") def match_source_endpoint(val, match_type=None): @@ -55,7 +57,9 @@ def match_source_endpoint(val, match_type=None): return re.match(SOURCE_ENDPOINT, val) -MODEL_APPLICATION = re.compile('(/?((?P[^/]+)/)?(?P[^.]*)(.(?P[^:]*(:.*)?))?)?') +MODEL_APPLICATION = re.compile( + "(/?((?P[^/]+)/)?(?P[^.]*)(.(?P[^:]*(:.*)?))?)?" +) def match_model_application(val, match_type=None): @@ -66,8 +70,14 @@ def match_model_application(val, match_type=None): valid_user_name_snippet = "[a-zA-Z0-9][a-zA-Z0-9.+-]*[a-zA-Z0-9]" -valid_user_snippet = "(?:{}(?:@{})?)".format(valid_user_name_snippet, valid_user_name_snippet) -USER = re.compile("^(?P{})(?:@(?P{}))?$".format(valid_user_name_snippet, valid_user_name_snippet)) +valid_user_snippet = "(?:{}(?:@{})?)".format( + valid_user_name_snippet, valid_user_name_snippet +) +USER = re.compile( + "^(?P{})(?:@(?P{}))?$".format( + valid_user_name_snippet, valid_user_name_snippet + ) +) def match_user(val, match_type=None): diff --git a/juju/offerendpoints.py b/juju/offerendpoints.py index e72c86c07..44931ba87 100644 --- a/juju/offerendpoints.py +++ b/juju/offerendpoints.py @@ -6,9 +6,16 @@ # -from .names import (MatchType, match_application, match_endpoint, match_model, - match_model_application, match_relation, - match_source_endpoint, match_user) +from .names import ( + MatchType, + match_application, + match_endpoint, + match_model, + match_model_application, + match_relation, + match_source_endpoint, + match_user, +) class ParseError(Exception): @@ -27,26 +34,32 @@ def __init__(self, application, endpoints, model=None, qualified_model_name=None def __eq__(self, other): if not isinstance(other, OfferEndpoints): return NotImplemented - return (self.application == other.application and - self.endpoints == other.endpoints and - self.model == other.model and - self.qualified_model_name == other.qualified_model_name) + return ( + self.application == other.application + and self.endpoints == other.endpoints + and self.model == other.model + and self.qualified_model_name == other.qualified_model_name + ) def parse_offer_endpoint(endpoint): if ":" not in endpoint: - raise ParseError("endpoint must conform to format \":\"") + raise ParseError( + 'endpoint must conform to format ":"' + ) matches = match_endpoint(endpoint, MatchType.SEARCH) if matches is None: - raise ParseError("endpoint must conform to format \":\"") + raise ParseError( + 'endpoint must conform to format ":"' + ) model_group = matches.group("model") application_group = matches.group("appname") endpoints_group = matches.group("endpoints") qualified_model_name = None if (model_group is not None) and (model_group != ""): - if ("/" not in model_group): + if "/" not in model_group: raise NotImplementedError() qualified_model_name = model_group model_group = model_group.split("/")[0] @@ -63,7 +76,9 @@ def parse_offer_endpoint(endpoint): if len(endpoints) == 0 or len(endpoints_group) == 0: raise ParseError("specify endpoints for {}".format(application)) - return OfferEndpoints(application, endpoints, model=model, qualified_model_name=qualified_model_name) + return OfferEndpoints( + application, endpoints, model=model, qualified_model_name=qualified_model_name + ) class OfferURL: @@ -76,10 +91,12 @@ def __init__(self, source="", user="", model="", application=""): def __eq__(self, other): if not isinstance(other, OfferURL): return NotImplemented - return (self.source == other.source and - self.user == other.user and - self.model == other.model and - self.application == other.application) + return ( + self.source == other.source + and self.user == other.user + and self.model == other.model + and self.application == other.application + ) def has_empty_source(self): return self.source is None or self.source == "" @@ -109,7 +126,11 @@ def parse_offer_url(url): valid = url[0] != ":" valid = valid and match_model_application(rest) if not valid: - raise ParseError("application offer URL has invalid form, must be [.: {}".format(url)) + raise ParseError( + "application offer URL has invalid form, must be [.: {}".format( + url + ) + ) offer_source = source @@ -119,7 +140,11 @@ def parse_offer_url(url): offer_application = _get_or_else(matches.group("application"), "") if valid and (("/" in offer_model) or ("/" in offer_application)): - raise ParseError("application offer URL has invalid form, must be [.: {}".format(url)) + raise ParseError( + "application offer URL has invalid form, must be [.: {}".format( + url + ) + ) if not offer_model: raise ParseError("application offer URL is missing model") if not offer_application: @@ -134,8 +159,12 @@ def parse_offer_url(url): if app_name and not match_application(app_name): raise ParseError("application name {} not valid".format(app_name)) - return OfferURL(source=offer_source, user=offer_user, model=offer_model, - application=offer_application) + return OfferURL( + source=offer_source, + user=offer_user, + model=offer_model, + application=offer_application, + ) def _get_or_else(val, res): @@ -163,8 +192,7 @@ def __init__(self, application="", relation=None): def __eq__(self, other): if not isinstance(other, LocalEndpoint): return NotImplemented - return (self.relation == other.relation and - self.application == other.application) + return self.relation == other.relation and self.application == other.application def parse_local_endpoint(url): diff --git a/juju/origin.py b/juju/origin.py index 7f12d745a..8561a432d 100644 --- a/juju/origin.py +++ b/juju/origin.py @@ -12,6 +12,7 @@ class Source(Enum): what the charm identity is from the URL and origin source. """ + LOCAL = "local" CHARM_HUB = "charm-hub" @@ -26,7 +27,9 @@ def __init__(self, source, channel, platform): self.platform = platform def __str__(self): - return "origin using source {} for channel {} and platform {}".format(str(self.source), self.channel, self.platform) + return "origin using source {} for channel {} and platform {}".format( + str(self.source), self.channel, self.platform + ) class Risk(Enum): @@ -49,18 +52,19 @@ def valid(potential): class Channel: """Channel identifies and describes completely a store channel. - A channel consists of, and is subdivided by, tracks, risk-levels and - - Tracks enable snap developers to publish multiple supported releases of - their application under the same snap name. - - Risk-levels represent a progressive potential trade-off between stability - and new features. + A channel consists of, and is subdivided by, tracks, risk-levels and + - Tracks enable snap developers to publish multiple supported releases of + their application under the same snap name. + - Risk-levels represent a progressive potential trade-off between stability + and new features. - The complete channel name can be structured as three distinct parts separated - by slashes: + The complete channel name can be structured as three distinct parts separated + by slashes: - / + / """ + def __init__(self, track=None, risk=None): if not Risk.valid(risk): raise JujuError("unexpected risk {}".format(risk)) @@ -91,7 +95,9 @@ def parse(s: str): track = p[0] risk = p[1] else: - raise JujuError("channel is malformed and has too many components {}".format(s)) + raise JujuError( + "channel is malformed and has too many components {}".format(s) + ) if risk is not None and not Risk.valid(risk): raise JujuError("risk in channel {} is not valid".format(s)) @@ -147,6 +153,7 @@ class Platform: 4. `/unknown/` """ + def __init__(self, arch, series=None, os=None): self.arch = arch self.series = series @@ -172,7 +179,9 @@ def parse(s): os = p[1] series = p[2] else: - raise JujuError("platform is malformed and has too many components {}".format(s)) + raise JujuError( + "platform is malformed and has too many components {}".format(s) + ) if not arch: raise JujuError("architecture in platform {} is not valid".format(s)) @@ -194,7 +203,11 @@ def normalize(self): def __eq__(self, other): if isinstance(other, self.__class__): - return self.arch == other.arch and self.os == other.os and self.series == other.series + return ( + self.arch == other.arch + and self.os == other.os + and self.series == other.series + ) return False def __str__(self): diff --git a/juju/placement.py b/juju/placement.py index 74a29c4a5..323c70d24 100644 --- a/juju/placement.py +++ b/juju/placement.py @@ -37,7 +37,7 @@ def parse(directive): return [directive] # Juju 2.0 can't handle lxc containers. - directive = directive.replace('lxc', 'lxd') + directive = directive.replace("lxc", "lxd") if ":" in directive: # Planner has given us a scope and directive in string form diff --git a/juju/provisioner.py b/juju/provisioner.py index 31e7fe8f5..ba914878c 100644 --- a/juju/provisioner.py +++ b/juju/provisioner.py @@ -19,7 +19,6 @@ [re.compile(r"aarch64"), "arm64"], [re.compile(r"ppc64|ppc64el|ppc64le"), "ppc64el"], [re.compile(r"s390x?"), "s390x"], - ] @@ -61,6 +60,7 @@ def normalize_arch(rawArch): class SSHProvisioner: """Provision a manually created machine via SSH.""" + user = "" host = "" private_key_path = "" @@ -89,7 +89,7 @@ def _get_ssh_client(self, host, user, key): # Read the private key into a paramiko.RSAKey if os.path.exists(key): - with open(key, 'r') as f: + with open(key, "r") as f: pkey = paramiko.RSAKey.from_private_key(f) ####################################################################### @@ -108,7 +108,7 @@ def _get_ssh_client(self, host, user, key): try: ssh.connect(host, port=22, username=user, pkey=pkey) except paramiko.ssh_exception.SSHException as e: - if 'Error reading SSH protocol banner' == str(e): + if "Error reading SSH protocol banner" == str(e): # Once more, with feeling ssh.connect(host, port=22, username=user, pkey=pkey) else: @@ -135,17 +135,16 @@ def _run_command(self, ssh, cmd, pty=True): if type(cmd) is not list: cmd = [cmd] - cmds = ' '.join(cmd) + cmds = " ".join(cmd) stdin, stdout, stderr = ssh.exec_command(cmds, get_pty=pty) retcode = stdout.channel.recv_exit_status() if retcode > 0: output = stderr.read().strip() - raise CalledProcessError(returncode=retcode, cmd=cmd, - output=output) + raise CalledProcessError(returncode=retcode, cmd=cmd, output=output) return ( - stdout.read().decode('utf-8').strip(), - stderr.read().decode('utf-8').strip() + stdout.read().decode("utf-8").strip(), + stderr.read().decode("utf-8").strip(), ) def _init_ubuntu_user(self): @@ -193,9 +192,7 @@ def _init_ubuntu_user(self): ) self._run_command( - ssh, - ["sudo", "/bin/bash -c " + shlex.quote(script)], - pty=True + ssh, ["sudo", "/bin/bash -c " + shlex.quote(script)], pty=True ) except paramiko.ssh_exception.AuthenticationException as e: raise e @@ -212,10 +209,10 @@ def _detect_hardware_and_os(self, ssh): """ info = { - 'series': '', - 'arch': '', - 'cpu-cores': '', - 'mem': '', + "series": "", + "arch": "", + "cpu-cores": "", + "mem": "", } stdout, stderr = self._run_command( @@ -225,13 +222,13 @@ def _detect_hardware_and_os(self, ssh): ) lines = stdout.split("\n") - info['series'] = lines[0].strip() - info['arch'] = normalize_arch(lines[1].strip()) + info["series"] = lines[0].strip() + info["arch"] = normalize_arch(lines[1].strip()) - memKb = re.split(r'\s+', lines[2])[1] + memKb = re.split(r"\s+", lines[2])[1] # Convert megabytes -> kilobytes - info['mem'] = round(int(memKb) / 1024) + info["mem"] = round(int(memKb) / 1024) # Detect available CPUs recorded = {} @@ -245,7 +242,7 @@ def _detect_hardware_and_os(self, ssh): cores = line.split(":")[1].strip() if physical_id not in recorded.keys(): - info['cpu-cores'] += cores + info["cpu-cores"] += cores recorded[physical_id] = True return info @@ -261,30 +258,27 @@ def provision_machine(self): if self._init_ubuntu_user(): try: - - ssh = self._get_ssh_client( - self.host, - self.user, - self.private_key_path - ) + ssh = self._get_ssh_client(self.host, self.user, self.private_key_path) hw = self._detect_hardware_and_os(ssh) - params.series = hw['series'] + params.series = hw["series"] params.instance_id = "manual:{}".format(self.host) params.nonce = "manual:{}:{}".format( self.host, str(uuid.uuid4()), # a nop for Juju w/manual machines ) params.hardware_characteristics = { - 'arch': hw['arch'], - 'mem': int(hw['mem']), - 'cpu-cores': int(hw['cpu-cores']), + "arch": hw["arch"], + "mem": int(hw["mem"]), + "cpu-cores": int(hw["cpu-cores"]), } - params.addresses = [{ - 'value': self.host, - 'type': 'ipv4', - 'scope': 'public', - }] + params.addresses = [ + { + "value": self.host, + "type": "ipv4", + "scope": "public", + } + ] except paramiko.ssh_exception.AuthenticationException as e: raise e @@ -333,7 +327,7 @@ def _run_configure_script(self, script): """ _, tmpFile = tempfile.mkstemp() - with open(tmpFile, 'w') as f: + with open(tmpFile, "w") as f: f.write(script) try: diff --git a/juju/relation.py b/juju/relation.py index c7c84161a..8ef6468d6 100644 --- a/juju/relation.py +++ b/juju/relation.py @@ -15,11 +15,11 @@ def __init__(self, model, data): self.data = data def __repr__(self): - return ''.format(self.data['application-name'], self.name) + return "".format(self.data["application-name"], self.name) @property def application_name(self): - return self.data['application-name'] + return self.data["application-name"] @property def application(self): @@ -28,36 +28,35 @@ def application(self): this scenario it is expected that you disconnect and reconnect to the model. """ - app_name = self.data['application-name'] + app_name = self.data["application-name"] if app_name in self.model.applications: return self.model.applications[app_name] raise JujuEntityNotFoundError(app_name, ["application"]) @property def name(self): - return self.data['relation']['name'] + return self.data["relation"]["name"] @property def interface(self): - return self.data['relation']['interface'] + return self.data["relation"]["interface"] @property def role(self): - return self.data['relation']['role'] + return self.data["relation"]["role"] @property def scope(self): - return self.data['relation']['scope'] + return self.data["relation"]["scope"] class Relation(model.ModelEntity): def __repr__(self): - return ''.format(self.entity_id, self.key) + return "".format(self.entity_id, self.key) @property def endpoints(self): - return [Endpoint(self.model, data) - for data in self.safe_data['endpoints']] + return [Endpoint(self.model, data) for data in self.safe_data["endpoints"]] @property def provides(self): @@ -65,7 +64,7 @@ def provides(self): The endpoint on the provides side of this relation, or None. """ for endpoint in self.endpoints: - if endpoint.role == 'provider': + if endpoint.role == "provider": return endpoint return None @@ -75,7 +74,7 @@ def requires(self): The endpoint on the requires side of this relation, or None. """ for endpoint in self.endpoints: - if endpoint.role == 'requirer': + if endpoint.role == "requirer": return endpoint return None @@ -85,17 +84,17 @@ def peers(self): The peers endpoint of this relation, or None. """ for endpoint in self.endpoints: - if endpoint.role == 'peer': + if endpoint.role == "peer": return endpoint return None @property def is_subordinate(self): - return any(ep.scope == 'container' for ep in self.endpoints) + return any(ep.scope == "container" for ep in self.endpoints) @property def is_peer(self): - return any(ep.role == 'peer' for ep in self.endpoints) + return any(ep.role == "peer" for ep in self.endpoints) def matches(self, *specs): """ @@ -112,6 +111,7 @@ def matches(self, *specs): :return: True if all specs match. """ + # Matches expects that the underlying application exists when it walks # over the endpoints. # This isn't directly required, but it validates that the framework @@ -131,14 +131,16 @@ def model_application_exists(app_name): return model_app_name == app_name for spec in specs: - if ':' in spec: - app_name, endpoint_name = spec.split(':') + if ":" in spec: + app_name, endpoint_name = spec.split(":") else: app_name, endpoint_name = spec, None for endpoint in self.endpoints: - if app_name == endpoint.application_name and \ - model_application_exists(app_name) and \ - endpoint_name in (endpoint.name, None): + if ( + app_name == endpoint.application_name + and model_application_exists(app_name) + and endpoint_name in (endpoint.name, None) + ): # found a match for this spec, so move to next one break else: diff --git a/juju/remoteapplication.py b/juju/remoteapplication.py index 18100f06a..4cd16cdcd 100644 --- a/juju/remoteapplication.py +++ b/juju/remoteapplication.py @@ -9,20 +9,15 @@ class RemoteApplication(model.ModelEntity): - @property def status(self): - """Get the application status, as set by the charm's leader. - - """ - return self.safe_data['status']['current'] + """Get the application status, as set by the charm's leader.""" + return self.safe_data["status"]["current"] @property def status_message(self): - """Get the application status message, as set by the charm's leader. - - """ - return self.safe_data['status']['message'] + """Get the application status message, as set by the charm's leader.""" + return self.safe_data["status"]["message"] @property def tag(self): @@ -36,8 +31,8 @@ def tag(self): @property def offer_name(self): - return self.safe_data['offer-name'] + return self.safe_data["offer-name"] @property def application_name(self): - return self.safe_data['application-name'] + return self.safe_data["application-name"] diff --git a/juju/secrets.py b/juju/secrets.py index af9f75c3a..b4d31ada9 100644 --- a/juju/secrets.py +++ b/juju/secrets.py @@ -5,7 +5,6 @@ This module contains utility logic for secrets such as reading secret data from yaml and creating data bag for secrets. """ - import base64 import json import re @@ -29,13 +28,13 @@ def create_secret_data(args): data = {} for val in args: # Remove any base64 padding ("=") before splitting the key=value. - stripped = val.rstrip(base64.b64encode(b'=').decode('utf-8')) + stripped = val.rstrip(base64.b64encode(b"=").decode("utf-8")) idx = stripped.find("=") if idx < 1: raise ValueError(f"Invalid key value {val}") key = stripped[0:idx] - value = stripped[idx + 1:] + value = stripped[idx + 1 :] # If the key doesn't have the #file suffix, then add it to the bag and continue. if not key.endswith(file_suffix): @@ -47,7 +46,9 @@ def create_secret_data(args): try: fs = path.stat() if fs.st_size > max_value_size_bytes: - raise ValueError(f"Secret content in file {path} too large: {fs.st_size} bytes") + raise ValueError( + f"Secret content in file {path} too large: {fs.st_size} bytes" + ) content = path.read_text() data[key] = content except Exception as e: @@ -69,14 +70,16 @@ def read_secret_data(file): try: fs = path.stat() if fs.st_size > max_content_size_bytes: - raise ValueError(f"Secret content in file {path} too large: {fs.st_size} bytes") + raise ValueError( + f"Secret content in file {path} too large: {fs.st_size} bytes" + ) except FileNotFoundError: raise FileNotFoundError(f"The file {path} does not exist.") except OSError: raise try: - with open(path, 'r', encoding='utf-8') as file: + with open(path, "r", encoding="utf-8") as file: data = file.read() except Exception: raise diff --git a/juju/status.py b/juju/status.py index 46485dac6..f6ac08823 100644 --- a/juju/status.py +++ b/juju/status.py @@ -16,31 +16,31 @@ def derive_status(statues): - current = 'unknown' + current = "unknown" for status in statues: - if status in serverities and serverities[status] > serverities[current]: + if status in severities and severities[status] > severities[current]: current = status return current -""" serverities holds status values with a severity measure. +""" severities holds status values with a severity measure. Status values with higher severity are used in preference to others. """ -serverities = { - 'error': 100, - 'blocked': 90, - 'waiting': 80, - 'maintenance': 70, - 'active': 60, - 'terminated': 50, - 'unknown': 40 +severities = { + "error": 100, + "blocked": 90, + "waiting": 80, + "maintenance": 70, + "active": 60, + "terminated": 50, + "unknown": 40, } async def formatted_status(model, target=None, raw=False, filters=None): """Returns a string that mimics the content of the information returned in the juju status command. If the raw parameter is - enabled, the function retursn a FullStatus object. + enabled, the function returns a FullStatus object. :param Model model: model object to be used :param Fileobject target: if set expects a file object such as sys.stdout or a file descriptor. The obtained status will @@ -60,13 +60,13 @@ async def formatted_status(model, target=None, raw=False, filters=None): result_str = str(result_status) else: result_str = _print_status_model(result_status) - result_str += '\n' + result_str += "\n" result_str += _print_status_apps(result_status) - result_str += '\n' + result_str += "\n" result_str += _print_status_units(result_status) - result_str += '\n' + result_str += "\n" result_str += _print_status_machines(result_status) - result_str += '\n' + result_str += "\n" if target is None: return result_str @@ -82,61 +82,61 @@ def _print_status_model(result_status): """Private function to print the status of a model""" m = result_status.model # print model - result_str = '{:<25} {:<25} {:<15} {:<15} {:<30} {:<30}\n'.format( - 'Model', 'Cloud/Region', 'Version', 'SLA', 'Timestamp', 'Notes') - sla = m.unknown_fields['sla'] - cloud = m.cloud_tag.split('-')[1] + result_str = "{:<25} {:<25} {:<15} {:<15} {:<30} {:<30}\n".format( + "Model", "Cloud/Region", "Version", "SLA", "Timestamp", "Notes" + ) + sla = m.unknown_fields["sla"] + cloud = m.cloud_tag.split("-")[1] timestamp = result_status.controller_timestamp - if m.available_version is not None and m.available_version != '': - available_version = 'upgrade available: {}'.format(m.available_version) + if m.available_version is not None and m.available_version != "": + available_version = "upgrade available: {}".format(m.available_version) else: - available_version = '' - result_str += '{:<25} {:<25} {:<15} {:<15} {:<30} {:<30}'.format( - m.name, cloud + '/' + m.region, m.version, sla, - timestamp, available_version) - result_str += '\n' + available_version = "" + result_str += "{:<25} {:<25} {:<15} {:<15} {:<30} {:<30}".format( + m.name, cloud + "/" + m.region, m.version, sla, timestamp, available_version + ) + result_str += "\n" return result_str def _print_status_apps(result_status): - """Auxiliar function to print the apps received + """Auxiliary function to print the apps received in a status result""" apps = result_status.applications if apps is None or len(apps) == 0: - return '' + return "" - limits = '{:<25} {:<10} {:<10} {:<5} {:<20} {:<8}' + limits = "{:<25} {:<10} {:<10} {:<5} {:<20} {:<8}" # print header - result_str = limits.format( - 'App', 'Version', 'Status', 'Scale', 'Charm', 'Channel') + result_str = limits.format("App", "Version", "Status", "Scale", "Charm", "Channel") for name, app in apps.items(): # extract charm name from the path # like in ch:amd64/trusty/mediawiki-28 - charm_name = app.charm.split('/')[-1] - charm_name = charm_name.split('-')[0] - work_ver = 'NA' if app.workload_version is None else app.workload_version - charm_channel = 'NA' if app.charm_channel is None else app.charm_channel - app_units = 'NA' if app.units is None else len(app.units) - app_status = 'NA' if app.status.status is None else app.status.status - result_str += '\n' + charm_name = app.charm.split("/")[-1] + charm_name = charm_name.split("-")[0] + work_ver = "NA" if app.workload_version is None else app.workload_version + charm_channel = "NA" if app.charm_channel is None else app.charm_channel + app_units = "NA" if app.units is None else len(app.units) + app_status = "NA" if app.status.status is None else app.status.status + result_str += "\n" result_str += limits.format( - name, work_ver, app_status, app_units, charm_name, - charm_channel) - result_str += '\n' + name, work_ver, app_status, app_units, charm_name, charm_channel + ) + result_str += "\n" return result_str def _print_status_units(result_status): - """Auxiliar function to print the units received + """Auxiliary function to print the units received in a status result""" apps = result_status.applications if apps is None or len(apps) == 0: return - limits = '{:<15} {:<15} {:<20} {:<10} {:<15} {:<10} {:<30}' - summary = '' + limits = "{:<15} {:<15} {:<20} {:<10} {:<15} {:<10} {:<30}" + summary = "" for app_name, app in apps.items(): units = app.units if units is None or len(units) == 0: @@ -145,34 +145,39 @@ def _print_status_units(result_status): for name, unit in units.items(): addr = unit.public_address if addr is None: - addr = '' + addr = "" if unit.opened_ports is None: - opened_ports = '' + opened_ports = "" else: - opened_ports = ','.join(unit.opened_ports) + opened_ports = ",".join(unit.opened_ports) info = unit.workload_status.info if info is None: - info = '' + info = "" step = limits.format( - name, unit.workload_status.status, - unit.agent_status.status, unit.machine, - addr, opened_ports, info) - if summary == '': + name, + unit.workload_status.status, + unit.agent_status.status, + unit.machine, + addr, + opened_ports, + info, + ) + if summary == "": summary = step else: - summary = summary + '\n' + step + summary = summary + "\n" + step if len(summary) == 0: - return '' + return "" result_str = limits.format( - 'Unit', 'Workload', 'Agent', 'Machine', - 'Public address', 'Ports', 'Message') - result_str += '\n' + "Unit", "Workload", "Agent", "Machine", "Public address", "Ports", "Message" + ) + result_str += "\n" result_str += summary - result_str += '\n' + result_str += "\n" return result_str @@ -181,29 +186,31 @@ def _print_status_machines(result_status): if machines is None or len(machines) == 0: return - limits = '{:<15} {:<15} {:<15} {:<20} {:<15} {:<30}' - summary = '' + limits = "{:<15} {:<15} {:<15} {:<20} {:<15} {:<30}" + summary = "" for name, machine in machines.items(): dns = machine.dns_name if dns is None: - dns = '' + dns = "" step = limits.format( name, machine.agent_status.status, dns, machine.instance_id, machine.series, - machine.agent_status.info + machine.agent_status.info, ) - if summary == '': + if summary == "": summary = step else: - summary = summary + '\n' + step + summary = summary + "\n" + step - if summary == '': + if summary == "": return - result_str = limits.format('Machine', 'State', 'DNS', 'Inst id', 'Series', 'Message') - result_str += '\n' + result_str = limits.format( + "Machine", "State", "DNS", "Inst id", "Series", "Message" + ) + result_str += "\n" result_str += summary - result_str += '\n' + result_str += "\n" return result_str diff --git a/juju/tag.py b/juju/tag.py index f6070978b..70a78d166 100644 --- a/juju/tag.py +++ b/juju/tag.py @@ -8,56 +8,56 @@ def _prefix(prefix, s): if s and not s.startswith(prefix): - return '{}{}'.format(prefix, s) + return "{}{}".format(prefix, s) return s def untag(prefix, s): if s and s.startswith(prefix): - return s[len(prefix):] + return s[len(prefix) :] return s def cloud(cloud_name): - return _prefix('cloud-', cloud_name) + return _prefix("cloud-", cloud_name) def controller(controller_uuid): - return _prefix('controller-', controller_uuid) + return _prefix("controller-", controller_uuid) def credential(cloud, user, credential_name): - credential_string = '{}_{}_{}'.format(cloud, user, credential_name) - return _prefix('cloudcred-', credential_string) + credential_string = "{}_{}_{}".format(cloud, user, credential_name) + return _prefix("cloudcred-", credential_string) def model(model_uuid): - return _prefix('model-', model_uuid) + return _prefix("model-", model_uuid) def machine(machine_id): - return _prefix('machine-', machine_id) + return _prefix("machine-", machine_id) def user(username): - return _prefix('user-', username) + return _prefix("user-", username) def application(app_name): - return _prefix('application-', app_name) + return _prefix("application-", app_name) def storage(app_name): - return _prefix('storage-', app_name) + return _prefix("storage-", app_name) def unit(unit_name): - return _prefix('unit-', unit_name.replace('/', '-')) + return _prefix("unit-", unit_name.replace("/", "-")) def action(action_uuid): - return _prefix('action-', action_uuid) + return _prefix("action-", action_uuid) def space(space_name): - return _prefix('space-', space_name) + return _prefix("space-", space_name) diff --git a/juju/unit.py b/juju/unit.py index 6c8b03d82..b5098e878 100644 --- a/juju/unit.py +++ b/juju/unit.py @@ -17,66 +17,50 @@ class Unit(model.ModelEntity): @property def agent_status(self): - """Returns the current agent status string. - - """ - return self.safe_data['agent-status']['current'] + """Returns the current agent status string.""" + return self.safe_data["agent-status"]["current"] @property def agent_status_since(self): - """Get the time when the `agent_status` was last updated. - - """ - return pyrfc3339.parse(self.safe_data['agent-status']['since']) + """Get the time when the `agent_status` was last updated.""" + return pyrfc3339.parse(self.safe_data["agent-status"]["since"]) @property def is_subordinate(self): - """True if the unit is subordinate of another unit - - """ - return self.safe_data['subordinate'] + """True if the unit is subordinate of another unit""" + return self.safe_data["subordinate"] @property def principal_unit(self): """Returns the name of the unit of which this unit is a subordinate to. Returns '' for principal units themselves. """ - return self.safe_data['principal'] + return self.safe_data["principal"] @property def agent_status_message(self): - """Get the agent status message. - - """ - return self.safe_data['agent-status']['message'] + """Get the agent status message.""" + return self.safe_data["agent-status"]["message"] @property def workload_status(self): - """Returns the current workload status string. - - """ - return self.safe_data['workload-status']['current'] + """Returns the current workload status string.""" + return self.safe_data["workload-status"]["current"] @property def workload_status_since(self): - """Get the time when the `workload_status` was last updated. - - """ - return pyrfc3339.parse(self.safe_data['workload-status']['since']) + """Get the time when the `workload_status` was last updated.""" + return pyrfc3339.parse(self.safe_data["workload-status"]["since"]) @property def workload_status_message(self): - """Get the workload status message. - - """ - return self.safe_data['workload-status']['message'] + """Get the workload status message.""" + return self.safe_data["workload-status"]["message"] @property def machine(self): - """Get the machine object for this unit. - - """ - machine_id = self.safe_data['machine-id'] + """Get the machine object for this unit.""" + machine_id = self.safe_data["machine-id"] if machine_id: return self.model.machines.get(machine_id, None) else: @@ -84,11 +68,11 @@ def machine(self): @property def public_address(self): - """ Get the public address. + """Get the public address. This property is deprecated, use get_public_address method. """ - return self.safe_data['public-address'] or None + return self.safe_data["public-address"] or None @property def tag(self): @@ -99,24 +83,32 @@ def get_subordinates(self): :return [Unit] """ - return [u for u_name, u in self.model.units.items() if u.is_subordinate and - u.principal_unit == self.name] - - async def destroy(self, destroy_storage=False, dry_run=False, force=False, max_wait=None): - """Destroy this unit. - - """ + return [ + u + for u_name, u in self.model.units.items() + if u.is_subordinate and u.principal_unit == self.name + ] + + async def destroy( + self, destroy_storage=False, dry_run=False, force=False, max_wait=None + ): + """Destroy this unit.""" app_facade = client.ApplicationFacade.from_connection(self.connection) - log.debug( - 'Destroying %s', self.name) + log.debug("Destroying %s", self.name) + + return await app_facade.DestroyUnit( + units=[ + { + "unit-tag": self.tag, + "destroy-storage": destroy_storage, + "force": force, + "max-wait": max_wait, + "dry-run": dry_run, + } + ] + ) - return await app_facade.DestroyUnit(units=[{"unit-tag": self.tag, - 'destroy-storage': destroy_storage, - 'force': force, - 'max-wait': max_wait, - 'dry-run': dry_run, - }]) remove = destroy async def get_public_address(self): @@ -124,7 +116,7 @@ async def get_public_address(self): :return int public-address """ - addr = self.safe_data['public-address'] or None + addr = self.safe_data["public-address"] or None if addr is not None: return addr @@ -132,7 +124,7 @@ async def get_public_address(self): defResult = await app_facade.UnitsInfo(entities=[client.Entity(self.tag)]) if defResult is not None and len(defResult.results) > 1: raise JujuAPIError("expected one result") - return defResult.results[0].result.get('public-address', None) + return defResult.results[0].result.get("public-address", None) async def resolved(self, retry=False): """Mark unit errors resolved. @@ -142,13 +134,11 @@ async def resolved(self, retry=False): """ app_facade = client.ApplicationFacade.from_connection(self.connection) - log.debug( - 'Resolving %s', self.name) + log.debug("Resolving %s", self.name) return await app_facade.ResolveUnitErrors( - all_=False, - retry=retry, - tags={'entities': [{'tag': self.tag}]}) + all_=False, retry=retry, tags={"entities": [{"tag": self.tag}]} + ) async def add_storage(self, storage_name, pool=None, count=1, size=1024): """Creates a storage and adds it to this unit. @@ -169,11 +159,15 @@ async def add_storage(self, storage_name, pool=None, count=1, size=1024): constraints = client.StorageConstraints(pool=pool, count=count, size=size) storage_facade = client.StorageFacade.from_connection(self.connection) - res = await storage_facade.AddToUnit(storages=[client.StorageAddParams( - name=storage_name, - unit=self.tag, - storage=constraints, - )]) + res = await storage_facade.AddToUnit( + storages=[ + client.StorageAddParams( + name=storage_name, + unit=self.tag, + storage=constraints, + ) + ] + ) result = res.results[0] if result.error is not None: raise JujuError("{}".format(result.error)) @@ -187,13 +181,20 @@ async def attach_storage(self, storage_ids=[]): :return: """ if not storage_ids: - raise JujuError("Expected a storage ID to be attached to unit {}".format(self.name)) + raise JujuError( + "Expected a storage ID to be attached to unit {}".format(self.name) + ) storage_facade = client.StorageFacade.from_connection(self.connection) - return await storage_facade.Attach(ids=[client.StorageAttachmentId( - storage_tag=tag.storage(s_id), - unit_tag=self.tag, - ) for s_id in storage_ids]) + return await storage_facade.Attach( + ids=[ + client.StorageAttachmentId( + storage_tag=tag.storage(s_id), + unit_tag=self.tag, + ) + for s_id in storage_ids + ] + ) async def detach_storage(self, *storage_ids, force=False): """Detaches storage from units. @@ -208,10 +209,15 @@ async def detach_storage(self, *storage_ids, force=False): storage_facade = client.StorageFacade.from_connection(self.connection) ret = await storage_facade.DetachStorage( force=force, - ids=client.StorageAttachmentIds(ids=[client.StorageAttachmentId( - storage_tag=tag.storage(s), - unit_tag=self.tag, - ) for s in storage_ids]) + ids=client.StorageAttachmentIds( + ids=[ + client.StorageAttachmentId( + storage_tag=tag.storage(s), + unit_tag=self.tag, + ) + for s in storage_ids + ] + ), ) if ret.results[0].error: raise JujuError(ret.results[0].error.message) @@ -234,8 +240,7 @@ async def run(self, command, timeout=None, block=False): """ action = client.ActionFacade.from_connection(self.connection) - log.debug( - 'Running `%s` on %s', command, self.name) + log.debug("Running `%s` on %s", command, self.name) if timeout: # Convert seconds to nanoseconds @@ -266,7 +271,7 @@ async def run(self, command, timeout=None, block=False): if error: raise JujuError("Action error - {} : {}".format(error.code, error.message)) - action = await self.model._wait_for_new('action', action_id) + action = await self.model._wait_for_new("action", action_id) if block: return await action.wait() return action @@ -284,34 +289,38 @@ async def run_action(self, action_name, **params): """ action_facade = client.ActionFacade.from_connection(self.connection) - log.debug('Starting action `%s` on %s', action_name, self.name) + log.debug("Starting action `%s` on %s", action_name, self.name) old_client = self.connection.is_using_old_client op = action_facade.Enqueue if old_client else action_facade.EnqueueOperation - res = await op(actions=[client.Action( - name=action_name, - parameters=params, - receiver=self.tag, - )]) + res = await op( + actions=[ + client.Action( + name=action_name, + parameters=params, + receiver=self.tag, + ) + ] + ) _action = res.results[0] if old_client else res.actions[0] action = _action.action error = _action.error - if error and error.code == 'not found': - raise ValueError('Action `%s` not found on %s' % (action_name, - self.name)) + if error and error.code == "not found": + raise ValueError("Action `%s` not found on %s" % (action_name, self.name)) elif error: - raise Exception('Unknown action error: %s' % error.serialize()) - action_id = action.tag[len('action-'):] - log.debug('Action started as %s', action_id) + raise Exception("Unknown action error: %s" % error.serialize()) + action_id = action.tag[len("action-") :] + log.debug("Action started as %s", action_id) # we mustn't use wait_for_action because that blocks until the # action is complete, rather than just being in the model - return await self.model._wait_for_new('action', action_id) + return await self.model._wait_for_new("action", action_id) - async def scp_to(self, source, destination, user='ubuntu', proxy=False, - scp_opts=''): + async def scp_to( + self, source, destination, user="ubuntu", proxy=False, scp_opts="" + ): """Transfer files to this unit. :param str source: Local path of file(s) to transfer @@ -321,11 +330,13 @@ async def scp_to(self, source, destination, user='ubuntu', proxy=False, :param scp_opts: Additional options to the `scp` command :type scp_opts: str or list """ - await self.machine.scp_to(source, destination, user=user, proxy=proxy, - scp_opts=scp_opts) + await self.machine.scp_to( + source, destination, user=user, proxy=proxy, scp_opts=scp_opts + ) - async def scp_from(self, source, destination, user='ubuntu', proxy=False, - scp_opts=''): + async def scp_from( + self, source, destination, user="ubuntu", proxy=False, scp_opts="" + ): """Transfer files from this unit. :param str source: Remote path of file(s) to transfer @@ -335,11 +346,11 @@ async def scp_from(self, source, destination, user='ubuntu', proxy=False, :param scp_opts: Additional options to the `scp` command :type scp_opts: str or list """ - await self.machine.scp_from(source, destination, user=user, - proxy=proxy, scp_opts=scp_opts) + await self.machine.scp_from( + source, destination, user=user, proxy=proxy, scp_opts=scp_opts + ) - async def ssh( - self, command, user='ubuntu', proxy=False, ssh_opts=None): + async def ssh(self, command, user="ubuntu", proxy=False, ssh_opts=None): """Execute a command over SSH on this unit. :param str command: Command to execute diff --git a/juju/url.py b/juju/url.py index a00798d41..5048f1af7 100644 --- a/juju/url.py +++ b/juju/url.py @@ -19,7 +19,15 @@ def __str__(self): class URL: - def __init__(self, schema, user=None, name=None, revision=None, series=None, architecture=None): + def __init__( + self, + schema, + user=None, + name=None, + revision=None, + series=None, + architecture=None, + ): self.schema = schema self.user = user self.name = name @@ -34,17 +42,18 @@ def __init__(self, schema, user=None, name=None, revision=None, series=None, arc @staticmethod def parse(s, default_store=Schema.CHARM_HUB): """parse parses the provided charm URL string into its respective - structure. + structure. - A missing schema is assumed to be 'ch'. + A missing schema is assumed to be 'ch'. """ u = urlparse(s) if u.query != "" or u.fragment != "" or u.username or u.password: raise JujuError("charm or bundle URL {} has unrecognized parts".format(u)) - if Schema.CHARM_STORE.matches(u.scheme) or \ - (u.scheme == "" and Schema.CHARM_STORE.matches(default_store)): + if Schema.CHARM_STORE.matches(u.scheme) or ( + u.scheme == "" and Schema.CHARM_STORE.matches(default_store) + ): c = parse_v1_url(Schema.CHARM_STORE, u, s) else: c = parse_v2_url(u, s, default_store) @@ -54,10 +63,14 @@ def parse(s, default_store=Schema.CHARM_HUB): return c def with_revision(self, rev): - return URL(self.schema, self.user, self.name, rev, self.series, self.architecture) + return URL( + self.schema, self.user, self.name, rev, self.series, self.architecture + ) def with_series(self, series): - return URL(self.schema, self.user, self.name, self.revision, series, self.architecture) + return URL( + self.schema, self.user, self.name, self.revision, series, self.architecture + ) def path(self): parts = [] @@ -75,12 +88,14 @@ def path(self): def __eq__(self, other): if isinstance(other, self.__class__): - return self.schema == other.schema and \ - self.user == other.user and \ - self.name == other.name and \ - self.revision == other.revision and \ - self.series == other.series and \ - self.architecture == other.architecture + return ( + self.schema == other.schema + and self.user == other.user + and self.name == other.name + and self.revision == other.revision + and self.series == other.series + and self.architecture == other.architecture + ) return False def __str__(self): @@ -155,7 +170,7 @@ def extract_revision(name): if c.isnumeric(): continue if c == "-" and i != (len(name) - 1): - revision = int(name[(i + 1):]) + revision = int(name[(i + 1) :]) name = name[:i] break return (name, revision) diff --git a/juju/user.py b/juju/user.py index a42886d6e..06946dfbd 100644 --- a/juju/user.py +++ b/juju/user.py @@ -59,8 +59,7 @@ def secret_key(self): return self._secret_key async def set_password(self, password): - """Update this user's password. - """ + """Update this user's password.""" await self.controller.change_user_password(self.username, password) self._user_info.password = password @@ -74,11 +73,14 @@ async def modify_model_access(self, acl, action, model_name): :return bool: True if access changed, Error if user already has it """ modelmanager_facade = client.ModelManagerFacade.from_connection( - self.controller.connection()) + self.controller.connection() + ) models = await self.controller.model_uuids() if model_name not in models: - raise errors.JujuError(f'Unable to find model : {model_name}') - changes = client.ModifyModelAccess(acl, action, tag.model(models[model_name]), self.tag) + raise errors.JujuError(f"Unable to find model : {model_name}") + changes = client.ModifyModelAccess( + acl, action, tag.model(models[model_name]), self.tag + ) await modelmanager_facade.ModifyModelAccess(changes=[changes]) return True @@ -90,13 +92,15 @@ async def modify_controller_access(self, acl, action): :return bool: True if access changed, Error if user already has it """ - controller_facade = client.ControllerFacade.from_connection(self.controller.connection()) + controller_facade = client.ControllerFacade.from_connection( + self.controller.connection() + ) changes = client.ModifyControllerAccess(acl, action, self.tag) await controller_facade.ModifyControllerAccess(changes=[changes]) new_access = acl - if action == 'revoke': - new_access = '' + if action == "revoke": + new_access = "" self._user_info.access = new_access return True @@ -110,7 +114,8 @@ async def modify_offer_access(self, acl, action, offer_url): :return bool: True if access changed, Error if user already has it """ application_offers_facade = client.ApplicationOffersFacade.from_connection( - self.controller.connection()) + self.controller.connection() + ) changes = client.ModifyOfferAccess(acl, action, offer_url, self.tag) await application_offers_facade.ModifyOfferAccess(changes=[changes]) return True @@ -129,14 +134,14 @@ async def grant_or_revoke(self, acl, action, **kwargs): :return: True if access changed, False if user already has it """ try: - if 'model_name' in kwargs: - return await self.modify_model_access(acl, action, kwargs['model_name']) - elif 'offer_url' in kwargs: - return await self.modify_offer_access(acl, action, kwargs['offer_url']) + if "model_name" in kwargs: + return await self.modify_model_access(acl, action, kwargs["model_name"]) + elif "offer_url" in kwargs: + return await self.modify_offer_access(acl, action, kwargs["offer_url"]) else: return await self.modify_controller_access(acl, action) except errors.JujuError as e: - if 'user already has' in str(e): + if "user already has" in str(e): return False else: raise @@ -153,9 +158,9 @@ async def grant(self, acl, **kwargs): :return: None or Error """ - return await self.grant_or_revoke(acl, 'grant', **kwargs) + return await self.grant_or_revoke(acl, "grant", **kwargs) - async def revoke(self, acl='login', **kwargs): + async def revoke(self, acl="login", **kwargs): """The opposite of user.grant(). Revokes the given access level of this user on model, offer or controller, depending on the given access level. @@ -165,16 +170,14 @@ async def revoke(self, acl='login', **kwargs): :param str model_name: name of the model if acl is one of model access levels :param str offer_url: url for the offer if acl is one of offer access levels """ - return await self.grant_or_revoke(acl, 'revoke', **kwargs) + return await self.grant_or_revoke(acl, "revoke", **kwargs) async def disable(self): - """Disable this user. - """ + """Disable this user.""" await self.controller.disable_user(self.username) self._user_info.disabled = True async def enable(self): - """Re-enable this user. - """ + """Re-enable this user.""" await self.controller.enable_user(self.username) self._user_info.disabled = False diff --git a/juju/utils.py b/juju/utils.py index c4f4780ac..07e4687b3 100644 --- a/juju/utils.py +++ b/juju/utils.py @@ -18,22 +18,23 @@ async def execute_process(*cmd, log=None): - ''' + """ Wrapper around asyncio.create_subprocess_exec. - ''' + """ p = await jasyncio.create_subprocess_exec( *cmd, stdin=jasyncio.subprocess.PIPE, stdout=jasyncio.subprocess.PIPE, - stderr=jasyncio.subprocess.PIPE) + stderr=jasyncio.subprocess.PIPE, + ) stdout, stderr = await p.communicate() if log: log.debug("Exec %s -> %d", cmd, p.returncode) if stdout: - log.debug(stdout.decode('utf-8')) + log.debug(stdout.decode("utf-8")) if stderr: - log.debug(stderr.decode('utf-8')) + log.debug(stderr.decode("utf-8")) return p.returncode == 0 @@ -48,14 +49,14 @@ def juju_config_dir(): """ # Set it to ~/.local/share/juju as default - config_dir = Path('~/.local/share/juju') + config_dir = Path("~/.local/share/juju") # Check $JUJU_DATA - if juju_data := os.environ.get('JUJU_DATA'): + if juju_data := os.environ.get("JUJU_DATA"): config_dir = Path(juju_data) # Secondly check: $XDG_DATA_HOME for ~/.local/share - elif xdg_data_home := os.environ.get('XDG_DATA_HOME'): - config_dir = Path(xdg_data_home) / 'juju' + elif xdg_data_home := os.environ.get("XDG_DATA_HOME"): + config_dir = Path(xdg_data_home) / "juju" return str(config_dir.expanduser().resolve()) @@ -66,31 +67,31 @@ def juju_ssh_key_paths(): """ config_dir = juju_config_dir() - public_key_path = os.path.join(config_dir, 'ssh', 'juju_id_rsa.pub') - private_key_path = os.path.join(config_dir, 'ssh', 'juju_id_rsa') + public_key_path = os.path.join(config_dir, "ssh", "juju_id_rsa.pub") + private_key_path = os.path.join(config_dir, "ssh", "juju_id_rsa") return public_key_path, private_key_path def _read_ssh_key(): - ''' + """ Inner function for read_ssh_key, suitable for passing to our Executor. - ''' + """ public_key_path_str, _ = juju_ssh_key_paths() ssh_key_path = Path(public_key_path_str) - with ssh_key_path.open('r') as ssh_key_file: + with ssh_key_path.open("r") as ssh_key_file: ssh_key = ssh_key_file.readlines()[0].strip() return ssh_key async def read_ssh_key(): - ''' + """ Attempt to read the local juju admin's public ssh key, so that it can be passed on to a model. - ''' + """ loop = jasyncio.get_running_loop() return await loop.run_in_executor(None, _read_ssh_key) @@ -124,20 +125,26 @@ async def block_until(*conditions, timeout=None, wait_period=0.5): asyncio.TimeoutError. """ + async def _block(): while not all(c() for c in conditions): await jasyncio.sleep(wait_period) + await jasyncio.shield(jasyncio.wait_for(_block(), timeout)) -async def block_until_with_coroutine(condition_coroutine, timeout=None, wait_period=0.5): +async def block_until_with_coroutine( + condition_coroutine, timeout=None, wait_period=0.5 +): """Return only after the given coroutine returns True. If a timeout occurs, it cancels the task and raises asyncio.TimeoutError. """ + async def _block(): while not await condition_coroutine(): await jasyncio.sleep(wait_period) + await jasyncio.shield(jasyncio.wait_for(_block(), timeout=timeout)) @@ -153,7 +160,7 @@ async def wait_for_bundle(model, bundle, **kwargs): if bundle_path.is_file(): bundle = bundle_path.read_text() elif (bundle_path / "bundle.yaml").is_file(): - bundle = (bundle_path / "bundle.yaml") + bundle = bundle_path / "bundle.yaml" except OSError: pass bundle = yaml.safe_load(textwrap.dedent(bundle).strip()) @@ -174,10 +181,11 @@ async def run_with_interrupt(task, *events, log=None): :param events: One or more `asyncio.Event`s which, if set, will interrupt `task` and cause it to be cancelled. """ - task = jasyncio.create_task_with_handler(task, 'tmp', log) + task = jasyncio.create_task_with_handler(task, "tmp", log) event_tasks = [jasyncio.ensure_future(event.wait()) for event in events] - done, pending = await jasyncio.wait([task] + event_tasks, - return_when=jasyncio.FIRST_COMPLETED) + done, pending = await jasyncio.wait( + [task] + event_tasks, return_when=jasyncio.FIRST_COMPLETED + ) for f in pending: f.cancel() # cancel unfinished tasks for f in pending: @@ -211,11 +219,14 @@ class RegistrationInfo(univ.Sequence): ControllerName string } """ + pass -def generate_user_controller_access_token(username, controller_endpoints, secret_key, controller_name): - """" Implement in python what is currently done in GO +def generate_user_controller_access_token( + username, controller_endpoints, secret_key, controller_name +): + """ " Implement in python what is currently done in GO https://github.com/juju/juju/blob/a5ab92ec9b7f5da3678d9ac603fe52d45af24412/cmd/juju/user/utils.go#L16 :param username: name of the user to register @@ -226,7 +237,7 @@ def generate_user_controller_access_token(username, controller_endpoints, secret # Secret key is returned as base64 encoded string in: # https://websockets.readthedocs.io/en/stable/_modules/websockets/protocol.html#WebSocketCommonProtocol.recv - # Deconding it before marshalling into the ASN.1 message + # Decoding it before marshalling into the ASN.1 message secret_key = base64.b64decode(secret_key) addr = Addrs() for endpoint in controller_endpoints: @@ -252,8 +263,8 @@ def get_local_charm_data(path, yaml_file): :return: Object of charm metadata """ - if str(path).endswith('.charm'): - with zipfile.ZipFile(str(path), 'r') as charm_file: + if str(path).endswith(".charm"): + with zipfile.ZipFile(str(path), "r") as charm_file: metadata = yaml.load(charm_file.read(yaml_file), Loader=yaml.FullLoader) else: entity_path = Path(path) @@ -266,15 +277,15 @@ def get_local_charm_data(path, yaml_file): def get_local_charm_metadata(path): - return get_local_charm_data(path, 'metadata.yaml') + return get_local_charm_data(path, "metadata.yaml") def get_local_charm_manifest(path): - return get_local_charm_data(path, 'manifest.yaml') + return get_local_charm_data(path, "manifest.yaml") def get_local_charm_charmcraft_yaml(path): - return get_local_charm_data(path, 'charmcraft.yaml') + return get_local_charm_data(path, "charmcraft.yaml") PRECISE = "precise" @@ -332,9 +343,7 @@ def get_local_charm_charmcraft_yaml(path): } KUBERNETES = "kubernetes" -KUBERNETES_SERIES = { - KUBERNETES: "kubernetes" -} +KUBERNETES_SERIES = {KUBERNETES: "kubernetes"} ALL_SERIES_VERSIONS = {**UBUNTU_SERIES, **KUBERNETES_SERIES} @@ -370,47 +379,46 @@ def get_local_charm_base(series, charm_path, base_class): :param str series: This may come from the argument or the metadata.yaml :param str charm_path: Path of charm directory/.charm file :param class base_class: - :return: Instance of the baseCls with channel/osname informaiton + :return: Instance of the baseCls with channel/osname information """ - channel_for_base = '' - os_name_for_base = '' + channel_for_base = "" + os_name_for_base = "" # We should know the series, so use it to get a channel if series: - channel_for_base = get_series_version(series) if series else '' + channel_for_base = get_series_version(series) if series else "" if channel_for_base: # we currently only support ubuntu series (statically) # TODO (cderici) : go juju/core/series/supported.go and get the # others here too if series in KUBERNETES_SERIES: - os_name_for_base = 'kubernetes' + os_name_for_base = "kubernetes" else: - os_name_for_base = 'ubuntu' + os_name_for_base = "ubuntu" # Check the charm manifest - if channel_for_base == '': + if channel_for_base == "": charm_manifest = get_local_charm_manifest(charm_path) - if 'bases' in charm_manifest: - channel_for_base = charm_manifest['bases'][0]['channel'] - os_name_for_base = charm_manifest['bases'][0]['name'] + if "bases" in charm_manifest: + channel_for_base = charm_manifest["bases"][0]["channel"] + os_name_for_base = charm_manifest["bases"][0]["name"] # Also check the charmcraft.yaml - if channel_for_base == '': + if channel_for_base == "": charmcraft_yaml = get_local_charm_charmcraft_yaml(charm_path) - if 'bases' in charmcraft_yaml: - channel_for_base = charmcraft_yaml['bases'][0]['run-on'][0]['channel'] - os_name_for_base = charmcraft_yaml['bases'][0]['run-on'][0]['name'] + if "bases" in charmcraft_yaml: + channel_for_base = charmcraft_yaml["bases"][0]["run-on"][0]["channel"] + os_name_for_base = charmcraft_yaml["bases"][0]["run-on"][0]["name"] - if channel_for_base == '': - raise errors.JujuError("Unable to determine base for charm : %s" % - charm_path) + if channel_for_base == "": + raise errors.JujuError("Unable to determine base for charm : %s" % charm_path) # Legacy k8s charms - assume ubuntu focal # as per juju/cmd/juju/application/utils.DeduceOrigin() if channel_for_base == "kubernetes" or os_name_for_base == "kubernetes": - channel_for_base = '20.04/stable' - os_name_for_base = 'ubuntu' + channel_for_base = "20.04/stable" + os_name_for_base = "ubuntu" return base_class(channel_for_base, os_name_for_base) @@ -429,30 +437,38 @@ def parse_base_arg(base): """ client.CharmBase() if not (isinstance(base, str) and "@" in base): - raise errors.JujuError(f"expected base string to contain os and channel separated by '@', got : {base}") + raise errors.JujuError( + f"expected base string to contain os and channel separated by '@', got : {base}" + ) - name, channel = base.split('@') + name, channel = base.split("@") return client.Base(name=name, channel=channel) -DEFAULT_SUPPORTED_LTS = 'jammy' -DEFAULT_SUPPORTED_LTS_BASE = client.Base(channel='22.04', name='ubuntu') +DEFAULT_SUPPORTED_LTS = "jammy" +DEFAULT_SUPPORTED_LTS_BASE = client.Base(channel="22.04", name="ubuntu") def base_channel_from_series(track, risk, series): - return origin.Channel(track=track, risk=risk).normalize().compute_base_channel(series=series) + return ( + origin.Channel(track=track, risk=risk) + .normalize() + .compute_base_channel(series=series) + ) def get_os_from_series(series): if series in UBUNTU_SERIES: - return 'ubuntu' - raise JujuError(f'os for the series {series} needs to be added') + return "ubuntu" + raise JujuError(f"os for the series {series} needs to be added") def get_base_from_origin_or_channel(origin_or_channel, series=None): channel, os_name = None, None if series: - channel = base_channel_from_series(origin_or_channel.track, origin_or_channel.risk, series) + channel = base_channel_from_series( + origin_or_channel.track, origin_or_channel.risk, series + ) os_name = get_os_from_series(series) return client.Base(channel=channel, name=os_name) @@ -463,21 +479,23 @@ def series_for_charm(requested_series, supported_series): If the requested series is empty, then the first supported series is used, otherwise the requested series is validated against the supported series. """ - if len(supported_series) == 1 and supported_series[0] == '': + if len(supported_series) == 1 and supported_series[0] == "": raise JujuError("invalid supported series reported by charm : ['']") if len(supported_series) == 0: - if requested_series == '': + if requested_series == "": raise JujuError("missing series") return requested_series # use the charm default - if requested_series == '': + if requested_series == "": return supported_series[-1] for s in supported_series: if requested_series == s: return requested_series - raise JujuError(f'requested series {requested_series} is not among the supported series {supported_series}') + raise JujuError( + f"requested series {requested_series} is not among the supported series {supported_series}" + ) def user_requested(series_arg, supported_series, force): @@ -488,7 +506,9 @@ def user_requested(series_arg, supported_series, force): return series -def series_selector(series_arg='', charm_url=None, model_config=None, supported_series=[], force=False): +def series_selector( + series_arg="", charm_url=None, model_config=None, supported_series=[], force=False +): """ series_selector corresponds to the CharmSeries() in https://github.com/juju/juju/blob/develop/core/charm/series_selector.go @@ -513,8 +533,8 @@ def series_selector(series_arg='', charm_url=None, model_config=None, supported_ # No series explicitly requested by the user. # Use model default series, if explicitly set and supported by the charm. - if model_config and model_config['default-base'].value: - default_base = model_config['default-base'].value + if model_config and model_config["default-base"].value: + default_base = model_config["default-base"].value base = parse_base_arg(default_base) series = base_channel_to_series(base.channel) return user_requested(series, supported_series, force) @@ -525,7 +545,7 @@ def series_selector(series_arg='', charm_url=None, model_config=None, supported_ # order (precise, xenial, bionic, trusty, etc). try: # TODO (cderici): restrict the supported_series with JujuSupportedSeries - return user_requested('', supported_series, force) + return user_requested("", supported_series, force) except JujuError: pass @@ -548,7 +568,7 @@ def should_upgrade_resource(available_resource, existing_resources, arg_resource """ # should upgrade resource? - res_name = available_resource.get('Name', available_resource.get('name')) + res_name = available_resource.get("Name", available_resource.get("name")) if res_name in arg_resources: return True @@ -556,12 +576,14 @@ def should_upgrade_resource(available_resource, existing_resources, arg_resource # do we have it already? if res_name in existing_resources: # no upgrade, if it's upload - if existing_resources[res_name].origin == 'upload': + if existing_resources[res_name].origin == "upload": return False # no upgrade, if upstream doesn't have a newer revision of the resource available - available_rev = available_resource.get('Revision', available_resource.get('revision', -1)) + available_rev = available_resource.get( + "Revision", available_resource.get("revision", -1) + ) u_fields = existing_resources[res_name].unknown_fields - existing_rev = u_fields.get('Revision', u_fields.get('revision', -1)) + existing_rev = u_fields.get("Revision", u_fields.get("revision", -1)) if existing_rev >= available_rev: return False return True diff --git a/juju/version.py b/juju/version.py index 3b14eca58..f99462925 100644 --- a/juju/version.py +++ b/juju/version.py @@ -3,6 +3,6 @@ LTS_RELEASES = ["jammy", "focal", "bionic", "xenial", "trusty", "precise"] -DEFAULT_ARCHITECTURE = 'amd64' +DEFAULT_ARCHITECTURE = "amd64" CLIENT_VERSION = "3.5.2.0" diff --git a/scripts/copyright.sh b/scripts/copyright.sh index b93e035c5..d6b01af9d 100755 --- a/scripts/copyright.sh +++ b/scripts/copyright.sh @@ -47,4 +47,4 @@ test_copyright() { ) } -test_copyright \ No newline at end of file +test_copyright diff --git a/setup.py b/setup.py index f650b5478..b982170c7 100644 --- a/setup.py +++ b/setup.py @@ -8,42 +8,38 @@ from juju.version import CLIENT_VERSION here = Path(__file__).absolute().parent -readme = here / 'docs' / 'readme.rst' -changelog = here / 'docs' / 'changelog.rst' -long_description = '{}\n\n{}'.format( - readme.read_text(), - changelog.read_text() -) -long_description_content_type = 'text/x-rst' +readme = here / "docs" / "readme.rst" +changelog = here / "docs" / "changelog.rst" +long_description = "{}\n\n{}".format(readme.read_text(), changelog.read_text()) +long_description_content_type = "text/x-rst" setup( - name='juju', + name="juju", version=CLIENT_VERSION.strip(), - packages=find_packages( - exclude=["*.tests", "*.tests.*", "tests.*", "tests"]), - package_data={'juju': ['py.typed']}, + packages=find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"]), + package_data={"juju": ["py.typed"]}, install_requires=[ - 'macaroonbakery>=1.1,<2.0', - 'pyRFC3339>=1.0,<2.0', - 'pyyaml>=5.1.2', - 'websockets>=8.1,<14.0', - 'paramiko>=2.4.0', - 'pyasn1>=0.4.4', - 'toposort>=1.5,<2', - 'typing_inspect>=0.6.0', - 'kubernetes>=12.0.1,<31.0.0', - 'hvac', - 'packaging', - 'typing-extensions>=4.5.0', + "macaroonbakery>=1.1,<2.0", + "pyRFC3339>=1.0,<2.0", + "pyyaml>=5.1.2", + "websockets>=8.1,<14.0", + "paramiko>=2.4.0", + "pyasn1>=0.4.4", + "toposort>=1.5,<2", + "typing_inspect>=0.6.0", + "kubernetes>=12.0.1,<31.0.0", + "hvac", + "packaging", + "typing-extensions>=4.5.0", ], include_package_data=True, - maintainer='Juju Ecosystem Engineering', - maintainer_email='juju@lists.ubuntu.com', - description=('Python library for Juju'), + maintainer="Juju Ecosystem Engineering", + maintainer_email="juju@lists.ubuntu.com", + description=("Python library for Juju"), long_description=long_description, long_description_content_type=long_description_content_type, - url='https://github.com/juju/python-libjuju', - license='Apache 2', + url="https://github.com/juju/python-libjuju", + license="Apache 2", classifiers=[ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", @@ -54,7 +50,6 @@ "Programming Language :: Python :: 3.10", ], entry_points={ - 'console_scripts': [ - ], + "console_scripts": [], }, ) diff --git a/tests/base.py b/tests/base.py index 550b158b1..0d5dac8ac 100644 --- a/tests/base.py +++ b/tests/base.py @@ -14,22 +14,20 @@ def is_bootstrapped(): try: - result = subprocess.run(['juju', 'switch'], stdout=subprocess.PIPE) - return ( - result.returncode == 0 and - len(result.stdout.decode().strip()) > 0) + result = subprocess.run(["juju", "switch"], stdout=subprocess.PIPE) + return result.returncode == 0 and len(result.stdout.decode().strip()) > 0 except FileNotFoundError: return False bootstrapped = pytest.mark.skipif( - not is_bootstrapped(), - reason='bootstrapped Juju environment required') + not is_bootstrapped(), reason="bootstrapped Juju environment required" +) test_run_nonce = uuid.uuid4().hex[-4:] -class CleanController(): +class CleanController: """ Context manager that automatically connects and disconnects from the currently active controller. @@ -37,6 +35,7 @@ class CleanController(): Note: Unlike CleanModel, this will not create a new controller for you, and an active controller must already be available. """ + def __init__(self): self._controller = None @@ -49,7 +48,7 @@ async def __aexit__(self, exc_type, exc, tb): await self._controller.disconnect() -class CleanModel(): +class CleanModel: """ Context manager that automatically connects to the currently active controller, adds a fresh model, returns the connection to that model, @@ -58,6 +57,7 @@ class CleanModel(): The new model is also set as the current default for the controller connection. """ + def __init__(self, bakery_client=None): self._controller = None self._model = None @@ -67,17 +67,17 @@ def __init__(self, bakery_client=None): async def __aenter__(self): model_nonce = uuid.uuid4().hex[-4:] frame = inspect.stack()[1] - test_name = frame.function.replace('_', '-') + test_name = frame.function.replace("_", "-") jujudata = TestJujuData() self._controller = Controller( jujudata=jujudata, bakery_client=self._bakery_client, ) controller_name = jujudata.current_controller() - user_name = jujudata.accounts()[controller_name]['user'] + user_name = jujudata.accounts()[controller_name]["user"] await self._controller.connect(controller_name) - model_name = 'test-{}-{}-{}'.format( + model_name = "test-{}-{}-{}".format( test_run_nonce, test_name, model_nonce, @@ -125,9 +125,9 @@ def models(self): if self.__model_name is None: return all_models all_models.setdefault(self.__controller_name, {}) - all_models[self.__controller_name].setdefault('models', {}) - cmodels = all_models[self.__controller_name]['models'] - cmodels[self.__model_name] = {'uuid': self.__model_uuid} + all_models[self.__controller_name].setdefault("models", {}) + cmodels = all_models[self.__controller_name]["models"] + cmodels[self.__model_name] = {"uuid": self.__model_uuid} return all_models diff --git a/tests/bundle/bundle.yaml b/tests/bundle/bundle.yaml index b3783aa66..66b574054 100644 --- a/tests/bundle/bundle.yaml +++ b/tests/bundle/bundle.yaml @@ -6,4 +6,4 @@ applications: nrpe: charm: "nrpe" relations: - - ["nrpe:general-info", "juju-qa-test:juju-info"] \ No newline at end of file + - ["nrpe:general-info", "juju-qa-test:juju-info"] diff --git a/tests/charm-folder-symlink/metadata.yaml b/tests/charm-folder-symlink/metadata.yaml index 14ab70e3a..fa8afd67d 100644 --- a/tests/charm-folder-symlink/metadata.yaml +++ b/tests/charm-folder-symlink/metadata.yaml @@ -2,4 +2,4 @@ name: simple summary: A simple example charm with the new operator framework series: ["focal"] description: | - Simple is an example charm \ No newline at end of file + Simple is an example charm diff --git a/tests/charm-secret/config.yaml b/tests/charm-secret/config.yaml index 26b5b563a..c2e0a18c5 100644 --- a/tests/charm-secret/config.yaml +++ b/tests/charm-secret/config.yaml @@ -7,7 +7,7 @@ options: # An example config option to customise the log level of the workload log-level: description: | - Configures the log level of gunicorn. + Configures the log level of gunicorn. Acceptable values are: "info", "debug", "warning", "error" and "critical" default: "info" diff --git a/tests/charm-secret/metadata.yaml b/tests/charm-secret/metadata.yaml index e5b9df6f4..10b996cd2 100644 --- a/tests/charm-secret/metadata.yaml +++ b/tests/charm-secret/metadata.yaml @@ -4,7 +4,7 @@ # The charm package name, no spaces (required) # See https://juju.is/docs/sdk/naming#heading--naming-charms for guidance. name: charm-secret - + # The following metadata are human-readable and will be published prominently on Charmhub. # (Recommended) @@ -14,4 +14,4 @@ display-name: Charm with secrets summary: Naive charm using secrets description: | - A naive charm using secrets to be used in testing. \ No newline at end of file + A naive charm using secrets to be used in testing. diff --git a/tests/charm-secret/src/charm.py b/tests/charm-secret/src/charm.py index ee0ba2bc6..05e4af1b8 100755 --- a/tests/charm-secret/src/charm.py +++ b/tests/charm-secret/src/charm.py @@ -29,8 +29,8 @@ def __init__(self, *args): def _on_secrets_start(self, event): """Create a secret to play with.""" content = { - 'username': 'useradmin', - 'password': '1234', + "username": "useradmin", + "password": "1234", } secret = self.app.add_secret(content) logger.info("created secret %s", secret) diff --git a/tests/charm-secret/tox.ini b/tests/charm-secret/tox.ini index e283925a0..373bcfeba 100644 --- a/tests/charm-secret/tox.ini +++ b/tests/charm-secret/tox.ini @@ -10,7 +10,7 @@ envlist = fmt, lint, unit src_path = {toxinidir}/src/ tst_path = {toxinidir}/tests/ ;lib_path = {toxinidir}/lib/charms/operator_name_with_underscores -all_path = {[vars]src_path} {[vars]tst_path} +all_path = {[vars]src_path} {[vars]tst_path} [testenv] setenv = @@ -48,7 +48,7 @@ commands = --skip {toxinidir}/venv \ --skip {toxinidir}/.mypy_cache \ --skip {toxinidir}/icon.svg - + ruff {[vars]all_path} black --check --diff {[vars]all_path} diff --git a/tests/integration/bundle/bundle-include-base64.yaml b/tests/integration/bundle/bundle-include-base64.yaml index 8dd430d59..79d9d9e47 100644 --- a/tests/integration/bundle/bundle-include-base64.yaml +++ b/tests/integration/bundle/bundle-include-base64.yaml @@ -29,4 +29,4 @@ applications: channel: stable num_units: 1 test: - charm: "../charm" \ No newline at end of file + charm: "../charm" diff --git a/tests/integration/bundle/config-base64.yaml b/tests/integration/bundle/config-base64.yaml index 509e69c16..713364392 100644 --- a/tests/integration/bundle/config-base64.yaml +++ b/tests/integration/bundle/config-base64.yaml @@ -1 +1 @@ -aHR0cDovL215LWp1anUuY29t \ No newline at end of file +aHR0cDovL215LWp1anUuY29t diff --git a/tests/integration/bundle/test-overlays/bundle-with-overlay-multi.yaml b/tests/integration/bundle/test-overlays/bundle-with-overlay-multi.yaml index fb9c0e406..61124a80f 100644 --- a/tests/integration/bundle/test-overlays/bundle-with-overlay-multi.yaml +++ b/tests/integration/bundle/test-overlays/bundle-with-overlay-multi.yaml @@ -8,8 +8,8 @@ applications: channel: 8.0/stable num_units: 1 relations: - - ["ghost", "mysql"] + - ["ghost", "mysql"] --- # overlay.yaml description: Overlay to remove the ghost app and the relation applications: - ghost: \ No newline at end of file + ghost: diff --git a/tests/integration/bundle/test-overlays/test-multi-overlay.yaml b/tests/integration/bundle/test-overlays/test-multi-overlay.yaml index aa20d25a0..4e140082b 100644 --- a/tests/integration/bundle/test-overlays/test-multi-overlay.yaml +++ b/tests/integration/bundle/test-overlays/test-multi-overlay.yaml @@ -12,4 +12,4 @@ applications: mysql: charm: "mysql" channel: candidate - num_units: 1 \ No newline at end of file + num_units: 1 diff --git a/tests/integration/bundle/test-overlays/test-overlay.yaml b/tests/integration/bundle/test-overlays/test-overlay.yaml index 79073fdd9..cb42c3d77 100644 --- a/tests/integration/bundle/test-overlays/test-overlay.yaml +++ b/tests/integration/bundle/test-overlays/test-overlay.yaml @@ -8,6 +8,6 @@ applications: mysql: charm: "mysql" channel: candidate - num_units: 1 + num_units: 1 relations: - - ["ghost", "mysql"] \ No newline at end of file + - ["ghost", "mysql"] diff --git a/tests/integration/bundle/test-overlays/test-overlay2.yaml b/tests/integration/bundle/test-overlays/test-overlay2.yaml index 9e5d28bce..408ddb5c7 100644 --- a/tests/integration/bundle/test-overlays/test-overlay2.yaml +++ b/tests/integration/bundle/test-overlays/test-overlay2.yaml @@ -5,4 +5,4 @@ applications: memcached: charm: "memcached" channel: stable - num_units: 1 \ No newline at end of file + num_units: 1 diff --git a/tests/integration/bundle/test-overlays/test-overlay3.yaml b/tests/integration/bundle/test-overlays/test-overlay3.yaml index 84f60933f..cd737a4c6 100644 --- a/tests/integration/bundle/test-overlays/test-overlay3.yaml +++ b/tests/integration/bundle/test-overlays/test-overlay3.yaml @@ -1,3 +1,3 @@ description: Another overlay to remove memcached applications: - memcached: \ No newline at end of file + memcached: diff --git a/tests/integration/charm-assumes/manifest.yaml b/tests/integration/charm-assumes/manifest.yaml index 9d88ef131..09843dfbe 100644 --- a/tests/integration/charm-assumes/manifest.yaml +++ b/tests/integration/charm-assumes/manifest.yaml @@ -2,4 +2,4 @@ bases: - architectures: - amd64 channel: '22.04' - name: ubuntu \ No newline at end of file + name: ubuntu diff --git a/tests/integration/charm-assumes/metadata.yaml b/tests/integration/charm-assumes/metadata.yaml index 876fe7b2c..602e589f2 100644 --- a/tests/integration/charm-assumes/metadata.yaml +++ b/tests/integration/charm-assumes/metadata.yaml @@ -10,4 +10,4 @@ assumes: - juju < 3 - all-of: - juju >= 3.1 - - juju < 4 \ No newline at end of file + - juju < 4 diff --git a/tests/integration/charm-base-charmcraft-yaml/charmcraft.yaml b/tests/integration/charm-base-charmcraft-yaml/charmcraft.yaml index 0734131c2..58ebf16c6 100644 --- a/tests/integration/charm-base-charmcraft-yaml/charmcraft.yaml +++ b/tests/integration/charm-base-charmcraft-yaml/charmcraft.yaml @@ -7,4 +7,4 @@ bases: channel: "20.04" run-on: - name: "ubuntu" - channel: "20.04" \ No newline at end of file + channel: "20.04" diff --git a/tests/integration/file-resource-charm/test.file b/tests/integration/file-resource-charm/test.file index 191028156..257cc5642 100644 --- a/tests/integration/file-resource-charm/test.file +++ b/tests/integration/file-resource-charm/test.file @@ -1 +1 @@ -foo \ No newline at end of file +foo diff --git a/tests/integration/test_application.py b/tests/integration/test_application.py index b33d99752..889a3de87 100644 --- a/tests/integration/test_application.py +++ b/tests/integration/test_application.py @@ -24,26 +24,26 @@ @base.bootstrapped async def test_action(): async with base.CleanModel() as model: - app = await model.deploy('juju-qa-test') + app = await model.deploy("juju-qa-test") await jasyncio.sleep(10) actions = await app.get_actions(schema=True) - assert 'fortune' in actions.keys(), 'mis"fortune" in charm actions' + assert "fortune" in actions.keys(), 'mis"fortune" in charm actions' @base.bootstrapped async def test_get_set_config(): async with base.CleanModel() as model: app = await model.deploy( - 'ubuntu', - application_name='ubuntu', - series='jammy', - channel='stable', + "ubuntu", + application_name="ubuntu", + series="jammy", + channel="stable", config={ - 'hostname': 'myubuntu', + "hostname": "myubuntu", }, constraints={ - 'arch': 'amd64', - 'mem': 256 * MB, + "arch": "amd64", + "mem": 256 * MB, }, ) @@ -55,45 +55,45 @@ async def test_get_set_config(): @base.bootstrapped -@pytest.mark.skip('Update charm') +@pytest.mark.skip("Update charm") async def test_status_is_not_unset(): async with base.CleanModel() as model: app = await model.deploy( - 'ubuntu-0', - application_name='ubuntu', - series='jammy', - channel='stable', + "ubuntu-0", + application_name="ubuntu", + series="jammy", + channel="stable", ) - assert app.status != 'unset' + assert app.status != "unset" @base.bootstrapped -@pytest.mark.skip('Update charm') +@pytest.mark.skip("Update charm") async def test_status(): async with base.CleanModel() as model: - app = await model.deploy('ch:juju-qa-test') + app = await model.deploy("ch:juju-qa-test") def app_ready(): if not app.units: return False - return app.status == 'blocked' + return app.status == "blocked" await model.block_until(app_ready, timeout=480) - assert app.status == 'blocked' + assert app.status == "blocked" @base.bootstrapped -@pytest.mark.skip('Update charm') +@pytest.mark.skip("Update charm") async def test_add_units(): from juju.unit import Unit async with base.CleanModel() as model: app = await model.deploy( - 'ubuntu', - application_name='ubuntu', - series='jammy', - channel='stable', + "ubuntu", + application_name="ubuntu", + series="jammy", + channel="stable", ) units = await app.add_units(count=2) @@ -105,14 +105,13 @@ async def test_add_units(): @base.bootstrapped async def test_deploy_charmhub_charm(): async with base.CleanModel() as model: - app = await model.deploy('ubuntu') - await model.block_until(lambda: (len(app.units) > 0 and - app.units[0].machine)) - assert 'ubuntu' in app.data['charm-url'] + app = await model.deploy("ubuntu") + await model.block_until(lambda: (len(app.units) > 0 and app.units[0].machine)) + assert "ubuntu" in app.data["charm-url"] @base.bootstrapped -@pytest.mark.skip('Skip until a similar k8s solution is found') +@pytest.mark.skip("Skip until a similar k8s solution is found") async def test_upgrade_charm_switch_channel(): # Note for future: # This test requires a charm that has different @@ -123,113 +122,117 @@ async def test_upgrade_charm_switch_channel(): # So checks are in place for that. async with base.CleanModel() as model: - app = await model.deploy('juju-qa-test', channel='2.0/stable') - await model.wait_for_idle(status='active') + app = await model.deploy("juju-qa-test", channel="2.0/stable") + await model.wait_for_idle(status="active") - charm_url = URL.parse(app.data['charm-url']) + charm_url = URL.parse(app.data["charm-url"]) assert Schema.CHARM_HUB.matches(charm_url.schema) still22 = False try: assert charm_url.revision == 22 still22 = True except AssertionError: - logger.warning("Charm used in test_upgrade_charm_switch_channel " - "seems to have been updated, the test needs to be revised") + logger.warning( + "Charm used in test_upgrade_charm_switch_channel " + "seems to have been updated, the test needs to be revised" + ) - await app.upgrade_charm(channel='2.0/edge') - await model.wait_for_idle(status='active') + await app.upgrade_charm(channel="2.0/edge") + await model.wait_for_idle(status="active") if still22: try: - charm_url = URL.parse(app.data['charm-url']) + charm_url = URL.parse(app.data["charm-url"]) assert charm_url.revision == 23 except AssertionError: - raise errors.JujuError("Either the upgrade has failed, or the used charm moved " - "the candidate channel to stable, so no upgrade took place, " - "the test needs to be revised.") + raise errors.JujuError( + "Either the upgrade has failed, or the used charm moved " + "the candidate channel to stable, so no upgrade took place, " + "the test needs to be revised." + ) # Try with another charm too, just in case, no need to check revisions etc - app = await model.deploy('ubuntu', channel='stable') - await model.wait_for_idle(status='active') - await app.upgrade_charm(channel='candidate') - await model.wait_for_idle(status='active') + app = await model.deploy("ubuntu", channel="stable") + await model.wait_for_idle(status="active") + await app.upgrade_charm(channel="candidate") + await model.wait_for_idle(status="active") @base.bootstrapped -@pytest.mark.skip('Update charm') +@pytest.mark.skip("Update charm") async def test_upgrade_charm_revision(): async with base.CleanModel() as model: - app = await model.deploy('ubuntu') - await model.block_until(lambda: (len(app.units) > 0 and - app.units[0].machine)) - assert app.data['charm-url'] == 'ubuntu' + app = await model.deploy("ubuntu") + await model.block_until(lambda: (len(app.units) > 0 and app.units[0].machine)) + assert app.data["charm-url"] == "ubuntu" await app.upgrade_charm(revision=8) - assert app.data['charm-url'] == 'ubuntu' + assert app.data["charm-url"] == "ubuntu" @base.bootstrapped -@pytest.mark.skip('Update charm') +@pytest.mark.skip("Update charm") async def test_upgrade_charm_switch(): async with base.CleanModel() as model: - app = await model.deploy('ubuntu') - await model.block_until(lambda: (len(app.units) > 0 and - app.units[0].machine)) - assert app.data['charm-url'] == 'ubuntu' + app = await model.deploy("ubuntu") + await model.block_until(lambda: (len(app.units) > 0 and app.units[0].machine)) + assert app.data["charm-url"] == "ubuntu" with pytest.raises(errors.JujuError): - await app.upgrade_charm(switch='ubuntu') - await app.upgrade_charm(switch='ubuntu') - assert app.data['charm-url'] == 'ubuntu' + await app.upgrade_charm(switch="ubuntu") + await app.upgrade_charm(switch="ubuntu") + assert app.data["charm-url"] == "ubuntu" @base.bootstrapped async def test_upgrade_local_charm(): async with base.CleanModel() as model: tests_dir = Path(__file__).absolute().parent - charm_path = tests_dir / 'upgrade-charm' - app = await model.deploy('ubuntu', series='focal', revision=15, channel='latest/stable') + charm_path = tests_dir / "upgrade-charm" + app = await model.deploy( + "ubuntu", series="focal", revision=15, channel="latest/stable" + ) await model.wait_for_idle(status="active") - assert 'ubuntu' in app.data['charm-url'] + assert "ubuntu" in app.data["charm-url"] await app.upgrade_charm(path=charm_path) await model.wait_for_idle(status="waiting") - assert app.data['charm-url'] == 'local:focal/ubuntu-0' + assert app.data["charm-url"] == "local:focal/ubuntu-0" @base.bootstrapped async def test_upgrade_local_charm_resource(): async with base.CleanModel() as model: - charm_path = INTEGRATION_TEST_DIR / 'file-resource-charm' + charm_path = INTEGRATION_TEST_DIR / "file-resource-charm" resources = {"file-res": "test.file"} app = await model.deploy(str(charm_path), resources=resources) - assert 'file-resource-charm' in model.applications + assert "file-resource-charm" in model.applications await model.wait_for_idle(raise_on_error=False) - assert app.units[0].agent_status == 'idle' + assert app.units[0].agent_status == "idle" await app.upgrade_charm(path=charm_path, resources=resources) await model.wait_for_idle(raise_on_error=False) ress = await app.get_resources() - assert 'file-res' in ress - assert ress['file-res'] + assert "file-res" in ress + assert ress["file-res"] @base.bootstrapped @pytest.mark.asyncio -@pytest.mark.skip('Update charm') +@pytest.mark.skip("Update charm") async def test_upgrade_charm_resource(): async with base.CleanModel() as model: - app = await model.deploy('cs:~juju-qa/bionic/upgrade-charm-resource-test-0') + app = await model.deploy("cs:~juju-qa/bionic/upgrade-charm-resource-test-0") await model.wait_for_idle(wait_for_units=1) unit = app.units[0] - expected_message = 'I have no resource.' + expected_message = "I have no resource." assert unit.workload_status_message == expected_message await app.upgrade_charm(revision=1) await model.block_until( - lambda: unit.workload_status_message != 'I have no resource.', + lambda: unit.workload_status_message != "I have no resource.", timeout=60, ) - expected_message = 'My resource: I am the resource.' + expected_message = "My resource: I am the resource." assert app.units[0].workload_status_message == expected_message @@ -237,62 +240,72 @@ async def test_upgrade_charm_resource(): @pytest.mark.asyncio async def test_refresh_with_resource_argument(): async with base.CleanModel() as model: - app = await model.deploy('juju-qa-test', resources={'foo-file': '2'}) + app = await model.deploy("juju-qa-test", resources={"foo-file": "2"}) res2 = await app.get_resources() - assert res2['foo-file'].revision == 2 - await app.refresh(resources={'foo-file': 4}) + assert res2["foo-file"].revision == 2 + await app.refresh(resources={"foo-file": 4}) res4 = await app.get_resources() - assert res4['foo-file'].revision == 4 + assert res4["foo-file"].revision == 4 @base.bootstrapped @pytest.mark.asyncio async def test_upgrade_charm_resource_same_rev_no_update(): async with base.CleanModel() as model: - app = await model.deploy('keystone', channel='victoria/stable') + app = await model.deploy("keystone", channel="victoria/stable") ress = await app.get_resources() - await app.refresh(channel='ussuri/stable') + await app.refresh(channel="ussuri/stable") ress2 = await app.get_resources() - assert ress['policyd-override'].fingerprint == ress2['policyd-override'].fingerprint + assert ( + ress["policyd-override"].fingerprint + == ress2["policyd-override"].fingerprint + ) @base.bootstrapped @pytest.mark.asyncio async def test_refresh_charmhub_to_local(): - charm_path = INTEGRATION_TEST_DIR / 'charm' + charm_path = INTEGRATION_TEST_DIR / "charm" async with base.CleanModel() as model: app = await model.deploy( - 'ubuntu', - application_name='ubu-path', - channel='stable', + "ubuntu", + application_name="ubu-path", + channel="stable", revision=24, # revision 25 requires v2 format for local charm ) await app.refresh(path=str(charm_path)) - assert app.data['charm-url'].startswith('local:') + assert app.data["charm-url"].startswith("local:") app = await model.deploy( - 'ubuntu', - application_name='ubu-switch', - channel='stable', + "ubuntu", + application_name="ubu-switch", + channel="stable", revision=24, # revision 25 requires v2 format for local charm ) await app.refresh(switch=str(charm_path)) - assert app.data['charm-url'].startswith('local:') + assert app.data["charm-url"].startswith("local:") @base.bootstrapped @pytest.mark.asyncio async def test_local_refresh(): - charm_path = INTEGRATION_TEST_DIR / 'charm' + charm_path = INTEGRATION_TEST_DIR / "charm" async with base.CleanModel() as model: app = await model.deploy( - 'ubuntu', - channel='stable', + "ubuntu", + channel="stable", revision=24, # revision 25 requires v2 format for local charm ) - origin = client.CharmOrigin(source="charm-hub", track="20.04", risk="stable", - branch="deadbeef", hash_="hash", id_="id", revision=12, - base=client.Base("20.04", "ubuntu")) + origin = client.CharmOrigin( + source="charm-hub", + track="20.04", + risk="stable", + branch="deadbeef", + hash_="hash", + id_="id", + revision=12, + base=client.Base("20.04", "ubuntu"), + ) await app.local_refresh( charm_origin=origin, @@ -303,19 +316,20 @@ async def test_local_refresh(): resources=None, ) - assert origin == client.CharmOrigin(source="local", revision=0, - base=client.Base("20.04", "ubuntu")) + assert origin == client.CharmOrigin( + source="local", revision=0, base=client.Base("20.04", "ubuntu") + ) @base.bootstrapped @pytest.mark.asyncio async def test_refresh_revision(): async with base.CleanModel() as model: - app = await model.deploy('juju-qa-test', channel="latest/stable", revision=23) + app = await model.deploy("juju-qa-test", channel="latest/stable", revision=23) # NOTE: juju-qa-test revision 26 has been released to this channel await app.refresh(revision=25) - charm_url = URL.parse(app.data['charm-url']) + charm_url = URL.parse(app.data["charm-url"]) assert charm_url.revision == 25 @@ -323,9 +337,9 @@ async def test_refresh_revision(): @pytest.mark.asyncio async def test_trusted(): async with base.CleanModel() as model: - await model.deploy('ubuntu', trust=True) + await model.deploy("ubuntu", trust=True) - ubuntu_app = model.applications['ubuntu'] + ubuntu_app = model.applications["ubuntu"] trusted = await ubuntu_app.get_trusted() assert trusted is True @@ -337,7 +351,7 @@ async def test_trusted(): @base.bootstrapped async def test_app_destroy(): async with base.CleanModel() as model: - app = await model.deploy('ubuntu') + app = await model.deploy("ubuntu") a_name = app.name # accessing name is impossible after the app is destroyed await model.wait_for_idle(status="active") assert a_name in model.applications @@ -352,7 +366,7 @@ async def test_app_destroy(): @base.bootstrapped async def test_app_remove_wait_flag(): async with base.CleanModel() as model: - app = await model.deploy('ubuntu') + app = await model.deploy("ubuntu") a_name = app.name await model.wait_for_idle(status="active") @@ -363,7 +377,7 @@ async def test_app_remove_wait_flag(): @base.bootstrapped async def test_app_remove_timeout(): async with base.CleanModel() as model: - app = await model.deploy('juju-qa-test') + app = await model.deploy("juju-qa-test") await model.wait_for_idle(status="active") with pytest.raises(asyncio.TimeoutError): @@ -373,18 +387,18 @@ async def test_app_remove_timeout(): @base.bootstrapped async def test_app_charm_name(): async with base.CleanModel() as model: - app = await model.deploy('ubuntu') + app = await model.deploy("ubuntu") await model.wait_for_idle(status="active") - assert 'ubuntu' in app.charm_url - assert 'ubuntu' == app.charm_name + assert "ubuntu" in app.charm_url + assert "ubuntu" == app.charm_name @base.bootstrapped async def test_app_relation_destroy_block_until_done(): async with base.CleanModel() as model: - app: Application = await model.deploy('docker-registry') + app: Application = await model.deploy("docker-registry") rsa: Application = await model.deploy("easyrsa") - relation = await app.relate('cert-provider', rsa.name) + relation = await app.relate("cert-provider", rsa.name) await model.wait_for_idle(status="active") - await app.destroy_relation('cert-provider', rsa.name, block_until_done=True) + await app.destroy_relation("cert-provider", rsa.name, block_until_done=True) assert relation not in app.relations diff --git a/tests/integration/test_charmhub.py b/tests/integration/test_charmhub.py index bada3557e..4cf17708f 100644 --- a/tests/integration/test_charmhub.py +++ b/tests/integration/test_charmhub.py @@ -14,16 +14,16 @@ async def test_info(): _, name = await model.charmhub.get_charm_id("ubuntu") assert name == "ubuntu" - charm_name = 'juju-qa-test' + charm_name = "juju-qa-test" charm_info = await model.charmhub.info(charm_name) - assert charm_info['name'] == 'juju-qa-test' - assert charm_info['type'] == 'charm' - assert charm_info['id'] == 'Hw30RWzpUBnJLGtO71SX8VDWvd3WrjaJ' - assert '2.0/stable' in charm_info['channel-map'] - cm_rev = charm_info['channel-map']['2.0/stable']['revision'] + assert charm_info["name"] == "juju-qa-test" + assert charm_info["type"] == "charm" + assert charm_info["id"] == "Hw30RWzpUBnJLGtO71SX8VDWvd3WrjaJ" + assert "2.0/stable" in charm_info["channel-map"] + cm_rev = charm_info["channel-map"]["2.0/stable"]["revision"] if isinstance(cm_rev, dict): # New client (>= 3.0) - assert cm_rev['revision'] == 22 + assert cm_rev["revision"] == 22 else: # Old client (<= 2.9) assert cm_rev == 22 @@ -33,16 +33,18 @@ async def test_info(): async def test_info_with_channel(): async with base.CleanModel() as model: charm_info = await model.charmhub.info("juju-qa-test", "2.0/stable") - assert charm_info['name'] == 'juju-qa-test' - assert '2.0/stable' in charm_info['channel-map'] - assert 'latest/stable' not in charm_info['channel-map'] + assert charm_info["name"] == "juju-qa-test" + assert "2.0/stable" in charm_info["channel-map"] + assert "latest/stable" not in charm_info["channel-map"] try: await model.charmhub.info("juju-qa-test", "non-existing-channel") except JujuError as err: - assert err.message == 'Charmhub.info : channel ' \ - 'non-existing-channel not found for ' \ - 'juju-qa-test' + assert ( + err.message == "Charmhub.info : channel " + "non-existing-channel not found for " + "juju-qa-test" + ) else: assert False, "non-existing-channel didn't raise an error" @@ -56,7 +58,7 @@ async def test_info_not_found(): @base.bootstrapped -@pytest.mark.skip('CharmHub facade no longer exists') +@pytest.mark.skip("CharmHub facade no longer exists") async def test_find(): async with base.CleanModel() as model: result = await model.charmhub.find("kube") @@ -68,7 +70,7 @@ async def test_find(): @base.bootstrapped -@pytest.mark.skip('CharmHub facade no longer exists') +@pytest.mark.skip("CharmHub facade no longer exists") async def test_find_bundles(): async with base.CleanModel() as model: result = await model.charmhub.find("kube", charm_type="bundle") @@ -80,7 +82,7 @@ async def test_find_bundles(): @base.bootstrapped -@pytest.mark.skip('CharmHub facade no longer exists') +@pytest.mark.skip("CharmHub facade no longer exists") async def test_find_all(): async with base.CleanModel() as model: result = await model.charmhub.find("") @@ -92,15 +94,14 @@ async def test_find_all(): @base.bootstrapped -@pytest.mark.skip('This tries to test juju controller logic') +@pytest.mark.skip("This tries to test juju controller logic") async def test_subordinate_charm_zero_units(): # normally in pylibjuju deploy num_units defaults to 1, we switch # that to 0 behind the scenes if we see that the charmhub charm # we're deploying is a subordinate charm async with base.CleanModel() as model: - # rsyslog-forwarder-ha is a subordinate charm - app = await model.deploy('rsyslog-forwarder-ha') + app = await model.deploy("rsyslog-forwarder-ha") await jasyncio.sleep(5) assert len(app.units) == 0 @@ -109,11 +110,11 @@ async def test_subordinate_charm_zero_units(): # note that it'll error if the user tries to use num_units with pytest.raises(JujuError): - await model.deploy('rsyslog-forwarder-ha', num_units=175) + await model.deploy("rsyslog-forwarder-ha", num_units=175) - # (full disclosure: it'll quitely switch to 0 if user enters + # (full disclosure: it'll quietly switch to 0 if user enters # num_units=1, instead of erroring) - app2 = await model.deploy('rsyslog-forwarder-ha', num_units=1) + app2 = await model.deploy("rsyslog-forwarder-ha", num_units=1) await jasyncio.sleep(5) assert len(app2.units) == 0 @@ -128,5 +129,5 @@ async def test_subordinate_false_field_exists(): @base.bootstrapped async def test_list_resources(): async with base.CleanModel() as model: - resources = await model.charmhub.list_resources('hello-kubecon') + resources = await model.charmhub.list_resources("hello-kubecon") assert isinstance(resources, list) and len(resources) > 0 diff --git a/tests/integration/test_client.py b/tests/integration/test_client.py index 5d50af912..0e42d4bf5 100644 --- a/tests/integration/test_client.py +++ b/tests/integration/test_client.py @@ -13,7 +13,8 @@ async def test_user_info(): um = client.UserManagerFacade.from_connection(controller_conn) result = await um.UserInfo( - entities=[client.Entity('user-admin')], include_disabled=True) + entities=[client.Entity("user-admin")], include_disabled=True + ) await controller_conn.close() assert isinstance(result, client.UserInfoResults) diff --git a/tests/integration/test_connection.py b/tests/integration/test_connection.py index 940a500b5..8d4592059 100644 --- a/tests/integration/test_connection.py +++ b/tests/integration/test_connection.py @@ -28,19 +28,18 @@ async def test_monitor(): async with base.CleanModel() as model: conn = model.connection() - assert conn.monitor.status == 'connected' + assert conn.monitor.status == "connected" await conn.close() - assert conn.monitor.status == 'disconnecting' + assert conn.monitor.status == "disconnecting" @base.bootstrapped async def test_monitor_catches_error(): - async with base.CleanModel() as model: conn = model.connection() - assert conn.monitor.status == 'connected' + assert conn.monitor.status == "connected" try: # grab the reconnect lock to prevent automatic # reconnecting during the test @@ -49,20 +48,20 @@ async def test_monitor_catches_error(): # if auto-reconnect is not disabled by lock, force this # test to fail by deferring to the reconnect task via sleep await jasyncio.sleep(0.1) - assert conn.monitor.status == 'error' + assert conn.monitor.status == "error" finally: await conn.close() @base.bootstrapped -@pytest.mark.skip('Update charm') +@pytest.mark.skip("Update charm") async def test_full_status(): async with base.CleanModel() as model: await model.deploy( - 'ubuntu', - application_name='ubuntu', - series='focal', - channel='stable', + "ubuntu", + application_name="ubuntu", + series="focal", + channel="stable", ) c = client.ClientFacade.from_connection(model.connection()) @@ -86,7 +85,7 @@ async def test_reconnect(): @base.bootstrapped -@pytest.mark.skip('tests the websocket protocol, not pylibjuju, needs to be revised') +@pytest.mark.skip("tests the websocket protocol, not pylibjuju, needs to be revised") async def test_redirect(): controller = Controller() await controller.connect() @@ -98,7 +97,7 @@ async def test_redirect(): # # websockets.protocol.logger.setLevel(logging.DEBUG) # logger.setLevel(logging.DEBUG) - destination = 'wss://{}/api'.format(kwargs['endpoint']) + destination = "wss://{}/api".format(kwargs["endpoint"]) redirect_statuses = [ http.HTTPStatus.MOVED_PERMANENTLY, # 301 http.HTTPStatus.FOUND, @@ -106,29 +105,27 @@ async def test_redirect(): http.HTTPStatus.TEMPORARY_REDIRECT, http.HTTPStatus.PERMANENT_REDIRECT, ] - test_server_cert = Path(__file__).with_name('cert.pem') - kwargs['cacert'] += '\n' + test_server_cert.read_text() + test_server_cert = Path(__file__).with_name("cert.pem") + kwargs["cacert"] += "\n" + test_server_cert.read_text() server = RedirectServer(destination) try: for status in redirect_statuses: - logger.debug('test: starting {}'.format(status)) + logger.debug("test: starting {}".format(status)) server.start(status) - await run_with_interrupt(server.running.wait(), - server.terminated) + await run_with_interrupt(server.running.wait(), server.terminated) if server.exception: raise server.exception assert not server.terminated.is_set() - logger.debug('test: started') - kwargs_copy = dict(kwargs, - endpoint='localhost:{}'.format(server.port)) - logger.debug('test: connecting') + logger.debug("test: started") + kwargs_copy = dict(kwargs, endpoint="localhost:{}".format(server.port)) + logger.debug("test: connecting") conn = await Connection.connect(**kwargs_copy) - logger.debug('test: connected') + logger.debug("test: connected") await conn.close() - logger.debug('test: stopping') + logger.debug("test: stopping") server.stop() await server.stopped.wait() - logger.debug('test: stopped') + logger.debug("test: stopped") finally: server.terminate() await server.terminated.wait() @@ -143,12 +140,12 @@ def __init__(self, destination): self.running = jasyncio.Event() self.stopped = jasyncio.Event() self.terminated = jasyncio.Event() - if hasattr(ssl, 'PROTOCOL_TLS_SERVER'): + if hasattr(ssl, "PROTOCOL_TLS_SERVER"): # python 3.6+ protocol = ssl.PROTOCOL_TLS_SERVER self.ssl_context = ssl.SSLContext(protocol) - crt_file = Path(__file__).with_name('cert.pem') - key_file = Path(__file__).with_name('key.pem') + crt_file = Path(__file__).with_name("cert.pem") + key_file = Path(__file__).with_name("key.pem") self.ssl_context.load_cert_chain(str(crt_file), str(key_file)) self.status = None self.port = None @@ -174,46 +171,45 @@ def exception(self): return None async def run(self): - logger.debug('server: active') + logger.debug("server: active") async def hello(websocket, path): - await websocket.send('hello') + await websocket.send("hello") async def redirect(path, request_headers): - return self.status, {'Location': self.destination}, b"" + return self.status, {"Location": self.destination}, b"" try: while not self._terminate.is_set(): - await run_with_interrupt(self._start.wait(), - self._terminate) + await run_with_interrupt(self._start.wait(), self._terminate) if self._terminate.is_set(): break self._start.clear() - logger.debug('server: starting {}'.format(self.status)) + logger.debug("server: starting {}".format(self.status)) try: - async with websockets.serve(ws_handler=hello, - process_request=redirect, - host='localhost', - port=self.port, - ssl=self.ssl_context, - loop=jasyncio.get_running_loop()): + async with websockets.serve( + ws_handler=hello, + process_request=redirect, + host="localhost", + port=self.port, + ssl=self.ssl_context, + loop=jasyncio.get_running_loop(), + ): self.stopped.clear() self.running.set() - logger.debug('server: started') + logger.debug("server: started") while not self._stop.is_set(): - await run_with_interrupt( - jasyncio.sleep(1), - self._stop) - logger.debug('server: tick') - logger.debug('server: stopping') + await run_with_interrupt(jasyncio.sleep(1), self._stop) + logger.debug("server: tick") + logger.debug("server: stopping") except jasyncio.CancelledError: break finally: self.stopped.set() self._stop.clear() self.running.clear() - logger.debug('server: stopped') - logger.debug('server: terminating') + logger.debug("server: stopped") + logger.debug("server: terminating") except jasyncio.CancelledError: pass finally: @@ -223,12 +219,12 @@ async def redirect(path, request_headers): self.stopped.set() self.running.clear() self.terminated.set() - logger.debug('server: terminated') + logger.debug("server: terminated") def _find_free_port(self): with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s: s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - s.bind(('', 0)) + s.bind(("", 0)) return s.getsockname()[1] @@ -236,7 +232,7 @@ def _find_free_port(self): async def test_verify_controller_cert(): jujudata = FileJujuData() controller_name = jujudata.current_controller() - endpoint = jujudata.controllers()[controller_name]['api-endpoints'][0] + endpoint = jujudata.controllers()[controller_name]["api-endpoints"][0] account = jujudata.accounts()[controller_name] my_random_selfsigned_cert = """-----BEGIN CERTIFICATE----- @@ -263,8 +259,8 @@ async def test_verify_controller_cert(): try: connection = await Connection.connect( endpoint=endpoint, - username=account['user'], - password=account['password'], + username=account["user"], + password=account["password"], cacert=my_random_selfsigned_cert, ) await connection.close() diff --git a/tests/integration/test_controller.py b/tests/integration/test_controller.py index 477f86c96..054bb6bd7 100644 --- a/tests/integration/test_controller.py +++ b/tests/integration/test_controller.py @@ -18,7 +18,7 @@ @base.bootstrapped async def test_add_remove_user(): async with base.CleanController() as controller: - username = 'test{}'.format(uuid.uuid4()) + username = "test{}".format(uuid.uuid4()) user = await controller.get_user(username) assert user is None user = await controller.add_user(username) @@ -37,7 +37,7 @@ async def test_add_remove_user(): @base.bootstrapped async def test_disable_enable_user(): async with base.CleanController() as controller: - username = 'test-disable{}'.format(uuid.uuid4()) + username = "test-disable{}".format(uuid.uuid4()) user = await controller.add_user(username) await user.disable() @@ -60,18 +60,18 @@ async def test_disable_enable_user(): @base.bootstrapped async def test_change_user_password(): async with base.CleanController() as controller: - username = 'test-password{}'.format(uuid.uuid4()) + username = "test-password{}".format(uuid.uuid4()) user = await controller.add_user(username) - await user.set_password('password') + await user.set_password("password") # Check that we can connect with the new password. new_connection = None try: kwargs = controller.connection().connect_params() - kwargs['username'] = username - kwargs['password'] = 'password' + kwargs["username"] = username + kwargs["password"] = "password" new_connection = await Connection.connect(**kwargs) except JujuAPIError: - raise AssertionError('Unable to connect with new password') + raise AssertionError("Unable to connect with new password") finally: if new_connection: await new_connection.close() @@ -80,10 +80,10 @@ async def test_change_user_password(): @base.bootstrapped async def test_reset_user_password(): async with base.CleanController() as controller: - username = 'test{}'.format(uuid.uuid4()) + username = "test{}".format(uuid.uuid4()) user = await controller.add_user(username) origin_secret_key = user.secret_key - await user.set_password('password') + await user.set_password("password") await controller.reset_user_password(username) user = await controller.get_user(username) new_secret_key = user.secret_key @@ -93,8 +93,8 @@ async def test_reset_user_password(): new_connection = None try: kwargs = controller.connection().connect_params() - kwargs['username'] = username - kwargs['password'] = 'password' + kwargs["username"] = username + kwargs["password"] = "password" new_connection = await Connection.connect(**kwargs) except JujuAPIError: pass @@ -117,7 +117,7 @@ async def test_list_models(): async def test_get_model(): async with base.CleanController() as controller: by_name, by_uuid = None, None - model_name = 'test-{}'.format(uuid.uuid4()) + model_name = "test-{}".format(uuid.uuid4()) model = await controller.add_model(model_name) model_uuid = model.info.uuid await model.disconnect() @@ -149,42 +149,37 @@ async def _wait_for_model_gone(controller, model_name): @base.bootstrapped async def test_destroy_model_by_name(): async with base.CleanController() as controller: - model_name = 'test-{}'.format(uuid.uuid4()) + model_name = "test-{}".format(uuid.uuid4()) model = await controller.add_model(model_name) await model.disconnect() - await asyncio.wait_for(_wait_for_model(controller, - model_name), - timeout=60) + await asyncio.wait_for(_wait_for_model(controller, model_name), timeout=60) await controller.destroy_model(model_name) - await asyncio.wait_for(_wait_for_model_gone(controller, - model_name), - timeout=600) + await asyncio.wait_for( + _wait_for_model_gone(controller, model_name), timeout=600 + ) @base.bootstrapped async def test_add_destroy_model_by_uuid(): async with base.CleanController() as controller: - model_name = 'test-{}'.format(uuid.uuid4()) + model_name = "test-{}".format(uuid.uuid4()) model = await controller.add_model(model_name) model_uuid = model.info.uuid await model.disconnect() - await asyncio.wait_for(_wait_for_model(controller, - model_name), - timeout=60) + await asyncio.wait_for(_wait_for_model(controller, model_name), timeout=60) await controller.destroy_model(model_uuid) - await asyncio.wait_for(_wait_for_model_gone(controller, - model_name), - timeout=60) + await asyncio.wait_for(_wait_for_model_gone(controller, model_name), timeout=60) @base.bootstrapped async def test_add_remove_cloud(): async with base.CleanController() as controller: - cloud_name = 'test-{}'.format(uuid.uuid4()) + cloud_name = "test-{}".format(uuid.uuid4()) cloud = client.Cloud( auth_types=["userpass"], endpoint="http://localhost:1234", - type_="kubernetes") + type_="kubernetes", + ) cloud = await controller.add_cloud(cloud_name, cloud) try: assert cloud.auth_types[0] == "userpass" @@ -199,13 +194,13 @@ async def test_secrets_backend_lifecycle(): """Testing the add_secret_backends is particularly costly in term of resources. This test sets a vault charm, add it to the controller and plays with the - list, removal, and update. """ + list, removal, and update.""" async with base.CleanModel() as m: controller = await m.get_controller() # deploy postgresql - await m.deploy('postgresql', base='ubuntu@22.04') + await m.deploy("postgresql", base="ubuntu@22.04") # deploy vault - await m.deploy("vault", channel='1.8/stable', base='ubuntu@22.04') + await m.deploy("vault", channel="1.8/stable", base="ubuntu@22.04") # relate/integrate await m.integrate("vault:db", "postgresql:db") # wait for the postgresql app @@ -218,7 +213,7 @@ async def test_secrets_backend_lifecycle(): # Deploy this entire thing status = await m.get_status() target = "" - for unit in status.applications['vault'].units.values(): + for unit in status.applications["vault"].units.values(): target = unit.public_address vault_url = "http://%s:8200" % target @@ -228,31 +223,39 @@ async def test_secrets_backend_lifecycle(): keys = vault_client.sys.initialize(3, 2) # Unseal vault - vault_client.sys.submit_unseal_keys(keys['keys']) + vault_client.sys.submit_unseal_keys(keys["keys"]) # authorize charm - target_unit = m.applications['vault'].units[0] - action = await target_unit.run_action("authorize-charm", token=keys["root_token"]) + target_unit = m.applications["vault"].units[0] + action = await target_unit.run_action( + "authorize-charm", token=keys["root_token"] + ) await action.wait() # Add the secret backend - response = await controller.add_secret_backends("1001", "myvault", "vault", {"endpoint": vault_url, "token": keys["root_token"]}) + response = await controller.add_secret_backends( + "1001", + "myvault", + "vault", + {"endpoint": vault_url, "token": keys["root_token"]}, + ) assert response["results"] is not None - assert response["results"][0]['error'] is None + assert response["results"][0]["error"] is None # List the secrets backend list = await controller.list_secret_backends() assert len(list["results"]) == 2 # consider the internal secrets backend for entry in list["results"]: - assert entry["result"].name == "internal" or entry["result"].name == "myvault" + assert ( + entry["result"].name == "internal" or entry["result"].name == "myvault" + ) # Update it # There is an ongoing error if no token_rotate_interval is provided resp = await controller.update_secret_backends( - "myvault", - name_change="changed_name", - token_rotate_interval=3600000000000) + "myvault", name_change="changed_name", token_rotate_interval=3600000000000 + ) assert resp["results"][0]["error"] is None # List the secrets backend @@ -260,7 +263,10 @@ async def test_secrets_backend_lifecycle(): assert len(list["results"]) == 2 # consider the internal secrets backend for entry in list["results"]: - assert entry["result"].name == "internal" or entry["result"].name == "changed_name" + assert ( + entry["result"].name == "internal" + or entry["result"].name == "changed_name" + ) # Remove it await controller.remove_secret_backends("changed_name") @@ -274,25 +280,25 @@ async def test_secrets_backend_lifecycle(): @base.bootstrapped async def test_grant_revoke_controller_access(): async with base.CleanController() as controller: - username = 'test-grant{}'.format(uuid.uuid4()) + username = "test-grant{}".format(uuid.uuid4()) user = await controller.add_user(username) - await user.grant('superuser') - assert user.access == 'superuser' + await user.grant("superuser") + assert user.access == "superuser" fresh = await controller.get_user(username) # fetch fresh copy - assert fresh.access == 'superuser' - await user.grant('login') # already has 'superuser', so no-op - assert user.access == 'superuser' + assert fresh.access == "superuser" + await user.grant("login") # already has 'superuser', so no-op + assert user.access == "superuser" fresh = await controller.get_user(username) # fetch fresh copy - assert fresh.access == 'superuser' + assert fresh.access == "superuser" await user.revoke() - assert user.access == '' + assert user.access == "" fresh = await controller.get_user(username) # fetch fresh copy - assert fresh.access == '' + assert fresh.access == "" try: # try removing the created user await controller.remove_user(username) except JujuError as e: - if 'state changing too quickly' in str(e): + if "state changing too quickly" in str(e): pass else: raise @@ -303,11 +309,12 @@ async def test_connection_lazy_jujudata(): async with base.CleanController() as cont1: conn = cont1.connection() new_controller = controller.Controller() - await new_controller.connect(endpoint=conn.endpoints[0][0], - cacert=conn.cacert, - username=conn.usertag, - password=conn.password, - ) + await new_controller.connect( + endpoint=conn.endpoints[0][0], + cacert=conn.cacert, + username=conn.usertag, + password=conn.password, + ) assert new_controller._controller_name is None new_controller.controller_name assert new_controller._controller_name is not None @@ -317,15 +324,15 @@ async def test_connection_lazy_jujudata(): @base.bootstrapped async def test_grant_revoke_model_access(): async with base.CleanController() as controller: - username = 'test-grant{}'.format(uuid.uuid4()) + username = "test-grant{}".format(uuid.uuid4()) user = await controller.add_user(username) - model_name = 'test-{}'.format(uuid.uuid4()) + model_name = "test-{}".format(uuid.uuid4()) model = await controller.add_model(model_name) with pytest.raises(JujuError): # superuser is a controller access level, i.e. not a valid model acl - await user.grant('superuser', model_name=model_name) + await user.grant("superuser", model_name=model_name) models1 = await controller.list_models(username) assert models1 == [] @@ -351,7 +358,7 @@ async def test_grant_revoke_model_access(): # try removing the created user await controller.remove_user(username) except JujuError as e: - if 'state changing too quickly' in str(e): + if "state changing too quickly" in str(e): pass else: raise diff --git a/tests/integration/test_crossmodel.py b/tests/integration/test_crossmodel.py index 4c742dd2a..894e07796 100644 --- a/tests/integration/test_crossmodel.py +++ b/tests/integration/test_crossmodel.py @@ -11,84 +11,84 @@ @base.bootstrapped -@pytest.mark.skip('Update charm') +@pytest.mark.skip("Update charm") async def test_offer(): async with base.CleanModel() as model: await model.deploy( - 'ubuntu', - application_name='ubuntu', - series='focal', - channel='stable', + "ubuntu", + application_name="ubuntu", + series="focal", + channel="stable", ) - assert 'ubuntu' in model.applications + assert "ubuntu" in model.applications await model.wait_for_idle(status="active") await model.create_offer("ubuntu:ubuntu") offers = await model.list_offers() await model.block_until( - lambda: all(offer.application_name == 'ubuntu' - for offer in offers.results)) + lambda: all(offer.application_name == "ubuntu" for offer in offers.results) + ) await model.remove_offer("admin/{}.ubuntu".format(model.name), force=True) @base.bootstrapped -@pytest.mark.skip('Update charm') +@pytest.mark.skip("Update charm") async def test_consume(): async with base.CleanModel() as model_1: await model_1.deploy( - 'ubuntu', - application_name='ubuntu', - series='focal', - channel='stable', + "ubuntu", + application_name="ubuntu", + series="focal", + channel="stable", ) - assert 'ubuntu' in model_1.applications + assert "ubuntu" in model_1.applications await model_1.wait_for_idle(status="active") await model_1.create_offer("ubuntu:ubuntu") offers = await model_1.list_offers() await model_1.block_until( - lambda: all(offer.application_name == 'ubuntu' - for offer in offers.results)) + lambda: all(offer.application_name == "ubuntu" for offer in offers.results) + ) # farm off a new model to test the consumption async with base.CleanModel() as model_2: await model_2.consume("admin/{}.ubuntu".format(model_1.name)) status = await model_2.get_status() - if 'ubuntu' not in status.remote_applications: + if "ubuntu" not in status.remote_applications: raise Exception("Expected ubuntu in saas") await model_1.remove_offer("admin/{}.ubuntu".format(model_1.name), force=True) @base.bootstrapped -@pytest.mark.skip('Update charm') +@pytest.mark.skip("Update charm") async def test_remove_saas(): async with base.CleanModel() as model_1: await model_1.deploy( - 'ubuntu', - application_name='ubuntu', - series='focal', - channel='stable', + "ubuntu", + application_name="ubuntu", + series="focal", + channel="stable", ) - assert 'ubuntu' in model_1.applications + assert "ubuntu" in model_1.applications await model_1.wait_for_idle(status="active") await model_1.create_offer("ubuntu:ubuntu") offers = await model_1.list_offers() await model_1.block_until( - lambda: all(offer.application_name == 'ubuntu' - for offer in offers.results)) + lambda: all(offer.application_name == "ubuntu" for offer in offers.results) + ) # farm off a new model to test the consumption async with base.CleanModel() as model_2: await model_2.consume("admin/{}.ubuntu".format(model_1.name)) - await model_2.remove_saas('ubuntu') + await model_2.remove_saas("ubuntu") await jasyncio.sleep(5) status = await model_2.get_status() - if 'ubuntu' in status.remote_applications: + if "ubuntu" in status.remote_applications: raise Exception("Expected ubuntu not to be in saas") await model_1.remove_offer("admin/{}.ubuntu".format(model_1.name), force=True) @@ -103,44 +103,50 @@ async def test_relate_with_offer(): pytest.skip("postgresql charm requires Juju 3.4.3 or later") application = await model_1.deploy( - 'postgresql', - application_name='postgresql', - channel='14/stable', + "postgresql", + application_name="postgresql", + channel="14/stable", ) - assert 'postgresql' in model_1.applications + assert "postgresql" in model_1.applications await model_1.wait_for_idle() await model_1.create_offer("postgresql:db") offers = await model_1.list_offers() await model_1.block_until( - lambda: all(offer.application_name == 'postgresql' - for offer in offers.results)) + lambda: all( + offer.application_name == "postgresql" for offer in offers.results + ) + ) # farm off a new model to test the consumption async with base.CleanModel() as model_2: await model_2.deploy( - 'hello-juju', - application_name='hello-juju', - series='focal', - channel='stable', + "hello-juju", + application_name="hello-juju", + series="focal", + channel="stable", ) await model_2.block_until( - lambda: all(unit.agent_status == 'idle' - for unit in application.units)) + lambda: all(unit.agent_status == "idle" for unit in application.units) + ) - await model_2.relate("hello-juju:db", "admin/{}.postgresql".format(model_1.name)) + await model_2.relate( + "hello-juju:db", "admin/{}.postgresql".format(model_1.name) + ) status = await model_2.get_status() - if 'postgresql' not in status.remote_applications: + if "postgresql" not in status.remote_applications: raise Exception("Expected postgresql in saas") - await model_2.remove_saas('postgresql') + await model_2.remove_saas("postgresql") await jasyncio.sleep(5) status = await model_2.get_status() - if 'postgresql' in status.remote_applications: + if "postgresql" in status.remote_applications: raise Exception("Expected mysql not to be in saas") - await model_1.remove_offer("admin/{}.postgresql".format(model_1.name), force=True) + await model_1.remove_offer( + "admin/{}.postgresql".format(model_1.name), force=True + ) @base.bootstrapped @@ -148,8 +154,8 @@ async def test_relate_with_offer(): async def test_add_bundle(): pytest.skip("skip until we have a faster example to test") tests_dir = Path(__file__).absolute().parent - bundle_path = tests_dir / 'bundle' - cmr_bundle_path = str(bundle_path / 'cmr-bundle.yaml') + bundle_path = tests_dir / "bundle" + cmr_bundle_path = str(bundle_path / "cmr-bundle.yaml") file_contents = None try: @@ -164,18 +170,18 @@ async def test_add_bundle(): with tempfile.TemporaryDirectory() as dirpath: try: - tmp_path = str(Path(dirpath) / 'bundle.yaml') + tmp_path = str(Path(dirpath) / "bundle.yaml") with open(tmp_path, "w") as file: file.write(file_contents.format(model_1.name)) except IOError: raise await model_1.deploy( - 'influxdb', - application_name='influxdb', - channel='stable', + "influxdb", + application_name="influxdb", + channel="stable", ) - assert 'influxdb' in model_1.applications + assert "influxdb" in model_1.applications await model_1.wait_for_idle(status="active") await model_1.create_offer("influxdb:grafana-source") @@ -183,13 +189,17 @@ async def test_add_bundle(): offers = await model_1.list_offers() await model_1.block_until( - lambda: all(offer.application_name == 'influxdb' - for offer in offers.results), - timeout=60 * wait_for_min) + lambda: all( + offer.application_name == "influxdb" for offer in offers.results + ), + timeout=60 * wait_for_min, + ) # farm off a new model to test the consumption async with base.CleanModel() as model_2: - await model_2.deploy('local:{}'.format(tmp_path)) + await model_2.deploy("local:{}".format(tmp_path)) await model_2.wait_for_idle(status="active") - await model_1.remove_offer("admin/{}.influxdb".format(model_1.name), force=True) + await model_1.remove_offer( + "admin/{}.influxdb".format(model_1.name), force=True + ) diff --git a/tests/integration/test_errors.py b/tests/integration/test_errors.py index fb1d8d2a6..02df87f9b 100644 --- a/tests/integration/test_errors.py +++ b/tests/integration/test_errors.py @@ -11,21 +11,21 @@ @base.bootstrapped async def test_juju_api_error(): - ''' + """ Verify that we raise a JujuAPIError for responses with an error in a top level key (for completely invalid requests). - ''' + """ from juju.errors import JujuAPIError async with base.CleanModel() as model: with pytest.raises(JujuAPIError): - await model.add_machine(constraints={'mem': -50}) + await model.add_machine(constraints={"mem": -50}) @base.bootstrapped async def test_juju_error_in_results_list(): - ''' + """ Replicate the code that caused https://github.com/juju/python-libjuju/issues/67, and verify that we get a JujuError instead of passing silently by the failure. @@ -36,7 +36,7 @@ async def test_juju_error_in_results_list(): This also verifies that we will raise a JujuError any time there is an error in one of a list of results. - ''' + """ from juju.errors import JujuError from juju.client import client @@ -44,8 +44,8 @@ async def test_juju_error_in_results_list(): ann_facade = client.AnnotationsFacade.from_connection(model.connection()) ann = client.EntityAnnotations( - entity='badtag', - annotations={'gui-x': '1', 'gui-y': '1'}, + entity="badtag", + annotations={"gui-x": "1", "gui-y": "1"}, ) with pytest.raises(JujuError): return await ann_facade.Set([ann]) @@ -53,11 +53,11 @@ async def test_juju_error_in_results_list(): @base.bootstrapped async def test_juju_error_in_result(): - ''' + """ Verify that we raise a JujuError when appropriate when we are looking at a single result coming back. - ''' + """ from juju.errors import JujuError from juju.client import client @@ -65,4 +65,4 @@ async def test_juju_error_in_result(): app_facade = client.ApplicationFacade.from_connection(model.connection()) with pytest.raises(JujuError): - return await app_facade.GetCharmURLOrigin(application='foo') + return await app_facade.GetCharmURLOrigin(application="foo") diff --git a/tests/integration/test_expose.py b/tests/integration/test_expose.py index aca223877..1ef346f62 100644 --- a/tests/integration/test_expose.py +++ b/tests/integration/test_expose.py @@ -9,7 +9,7 @@ @base.bootstrapped -@pytest.mark.skip('Update charm') +@pytest.mark.skip("Update charm") async def test_expose_unexpose(): async with base.CleanModel() as model: app = await model.deploy( @@ -17,80 +17,61 @@ async def test_expose_unexpose(): ) if not app.supports_granular_expose_parameters(): - pytest.skip("this test requires a 2.9 or greated controller") + pytest.skip("this test requires a 2.9 or greater controller") # Expose all opened port ranges await app.expose() exposed_endpoints = await get_exposed_endpoints(model, app) assert exposed_endpoints == { - "": { - "expose-to-cidrs": ["0.0.0.0/0", "::/0"], - "expose-to-spaces": None - } + "": {"expose-to-cidrs": ["0.0.0.0/0", "::/0"], "expose-to-spaces": None} } # Expose all opened port ranges to the CIDRs that correspond to a list # of spaces. - await app.expose(exposed_endpoints={ - "": ExposedEndpoint(to_spaces=["alpha"]) - }) + await app.expose(exposed_endpoints={"": ExposedEndpoint(to_spaces=["alpha"])}) exposed_endpoints = await get_exposed_endpoints(model, app) assert exposed_endpoints == { - "": { - "expose-to-cidrs": None, - "expose-to-spaces": ["alpha"] - } + "": {"expose-to-cidrs": None, "expose-to-spaces": ["alpha"]} } # Expose all opened port ranges to a list of CIDRs. - await app.expose(exposed_endpoints={ - "": ExposedEndpoint(to_cidrs=["10.0.0.0/24"]) - }) + await app.expose( + exposed_endpoints={"": ExposedEndpoint(to_cidrs=["10.0.0.0/24"])} + ) exposed_endpoints = await get_exposed_endpoints(model, app) assert exposed_endpoints == { - "": { - "expose-to-cidrs": ["10.0.0.0/24"], - "expose-to-spaces": None - } + "": {"expose-to-cidrs": ["10.0.0.0/24"], "expose-to-spaces": None} } # Expose all opened port ranges to a list of spaces and CIDRs. - await app.expose(exposed_endpoints={ - "": ExposedEndpoint(to_spaces=["alpha"], to_cidrs=["10.0.0.0/24"]) - }) + await app.expose( + exposed_endpoints={ + "": ExposedEndpoint(to_spaces=["alpha"], to_cidrs=["10.0.0.0/24"]) + } + ) exposed_endpoints = await get_exposed_endpoints(model, app) assert exposed_endpoints == { - "": { - "expose-to-spaces": ["alpha"], - "expose-to-cidrs": ["10.0.0.0/24"] - } + "": {"expose-to-spaces": ["alpha"], "expose-to-cidrs": ["10.0.0.0/24"]} } # Expose individual endpoints to different space/CIDR combinations - await app.expose(exposed_endpoints={ - "": ExposedEndpoint(to_spaces=["alpha"], to_cidrs=["10.0.0.0/24"]), - "ubuntu": ExposedEndpoint(to_cidrs=["10.42.42.0/24"]) - }) + await app.expose( + exposed_endpoints={ + "": ExposedEndpoint(to_spaces=["alpha"], to_cidrs=["10.0.0.0/24"]), + "ubuntu": ExposedEndpoint(to_cidrs=["10.42.42.0/24"]), + } + ) exposed_endpoints = await get_exposed_endpoints(model, app) assert exposed_endpoints == { - "": { - "expose-to-spaces": ["alpha"], - "expose-to-cidrs": ["10.0.0.0/24"] - }, - "ubuntu": { - "expose-to-cidrs": ["10.42.42.0/24"], - "expose-to-spaces": None - } + "": {"expose-to-spaces": ["alpha"], "expose-to-cidrs": ["10.0.0.0/24"]}, + "ubuntu": {"expose-to-cidrs": ["10.42.42.0/24"], "expose-to-spaces": None}, } # Unexpose individual endpoints (other endpoints remain exposed). await app.unexpose(exposed_endpoints=["ubuntu"]) exposed_endpoints = await get_exposed_endpoints(model, app) assert exposed_endpoints == { - "": { - "expose-to-spaces": ["alpha"], - "expose-to-cidrs": ["10.0.0.0/24"] - }, + "": {"expose-to-spaces": ["alpha"], "expose-to-cidrs": ["10.0.0.0/24"]}, } # Unexpose application diff --git a/tests/integration/test_macaroon_auth.py b/tests/integration/test_macaroon_auth.py index 2f4a09c6b..280b9bcec 100644 --- a/tests/integration/test_macaroon_auth.py +++ b/tests/integration/test_macaroon_auth.py @@ -23,20 +23,22 @@ # this test must be run serially because it modifies the login password @base.bootstrapped @pytest.mark.serial -@pytest.mark.skip('one of old macaroon_auth tests, needs to be revised') +@pytest.mark.skip("one of old macaroon_auth tests, needs to be revised") async def test_macaroon_auth_serial(): jujudata = FileJujuData() account = jujudata.accounts()[jujudata.current_controller()] - with base.patch_file('~/.local/share/juju/accounts.yaml'): - if 'password' in account: + with base.patch_file("~/.local/share/juju/accounts.yaml"): + if "password" in account: # force macaroon auth by "changing" password to current password result = subprocess.run( - ['juju', 'change-user-password'], - input='{0}\n{0}\n'.format(account['password']), + ["juju", "change-user-password"], + input="{0}\n{0}\n".format(account["password"]), universal_newlines=True, - stderr=subprocess.PIPE) - assert result.returncode == 0, ('Failed to change password: ' - '{}'.format(result.stderr)) + stderr=subprocess.PIPE, + ) + assert result.returncode == 0, "Failed to change password: {}".format( + result.stderr + ) controller = Controller() try: await controller.connect() @@ -50,7 +52,7 @@ async def test_macaroon_auth_serial(): @base.bootstrapped # @pytest.mark.xfail -@pytest.mark.skip('one of old macaroon_auth tests, needs to be revised') +@pytest.mark.skip("one of old macaroon_auth tests, needs to be revised") async def test_macaroon_auth(): auth_info, username = agent_auth_info() # Create a bakery client that can do agent authentication. @@ -61,7 +63,7 @@ async def test_macaroon_auth(): async with base.CleanModel(bakery_client=client) as m: async with await m.get_controller() as c: - await c.grant_model(username, m.info.uuid, 'admin') + await c.grant_model(username, m.info.uuid, "admin") async with Model( jujudata=NoAccountsJujuData(m._connector.jujudata), bakery_client=client, @@ -71,7 +73,7 @@ async def test_macaroon_auth(): @base.bootstrapped # @pytest.mark.xfail -@pytest.mark.skip('one of old macaroon_auth tests, needs to be revised') +@pytest.mark.skip("one of old macaroon_auth tests, needs to be revised") async def test_macaroon_auth_with_bad_key(): auth_info, username = agent_auth_info() # Use a random key rather than the correct key. @@ -84,13 +86,13 @@ async def test_macaroon_auth_with_bad_key(): async with base.CleanModel(bakery_client=client) as m: async with await m.get_controller() as c: - await c.grant_model(username, m.info.uuid, 'admin') + await c.grant_model(username, m.info.uuid, "admin") try: async with Model( jujudata=NoAccountsJujuData(m._connector.jujudata), bakery_client=client, ): - pytest.fail('Should not be able to connect with invalid key') + pytest.fail("Should not be able to connect with invalid key") except httpbakery.BakeryException: # We're expecting this because we're using the # wrong key. @@ -99,7 +101,7 @@ async def test_macaroon_auth_with_bad_key(): @base.bootstrapped # @pytest.mark.xfail -@pytest.mark.skip('one of old macaroon_auth tests, needs to be revised') +@pytest.mark.skip("one of old macaroon_auth tests, needs to be revised") async def test_macaroon_auth_with_unauthorized_user(): auth_info, username = agent_auth_info() # Create a bakery client can do agent authentication. @@ -114,7 +116,7 @@ async def test_macaroon_auth_with_unauthorized_user(): jujudata=NoAccountsJujuData(m._connector.jujudata), bakery_client=client, ): - pytest.fail('Should not be able to connect without grant') + pytest.fail("Should not be able to connect without grant") except (JujuAPIError, httpbakery.DischargeError): # We're expecting this because we're using the # wrong user name. @@ -122,13 +124,14 @@ async def test_macaroon_auth_with_unauthorized_user(): def agent_auth_info(): - agent_data = os.environ.get('TEST_AGENTS') + agent_data = os.environ.get("TEST_AGENTS") if agent_data is None: - pytest.skip('skipping macaroon_auth because no TEST_AGENTS ' - 'environment variable is set') + pytest.skip( + "skipping macaroon_auth because no TEST_AGENTS environment variable is set" + ) auth_info = agent.read_auth_info(agent_data) if len(auth_info.agents) != 1: - raise Exception('TEST_AGENTS agent data requires exactly one agent') + raise Exception("TEST_AGENTS agent data requires exactly one agent") return auth_info, auth_info.agents[0].username diff --git a/tests/integration/test_machine.py b/tests/integration/test_machine.py index 1a6804152..7f4b8111a 100644 --- a/tests/integration/test_machine.py +++ b/tests/integration/test_machine.py @@ -10,33 +10,37 @@ @base.bootstrapped -@pytest.mark.skip('Update charm') +@pytest.mark.skip("Update charm") async def test_status(): async with base.CleanModel() as model: await model.deploy( - 'ubuntu', - application_name='ubuntu', - series='trusty', - channel='stable', + "ubuntu", + application_name="ubuntu", + series="trusty", + channel="stable", ) await asyncio.wait_for( - model.block_until(lambda: len(model.machines)), - timeout=240) - machine = model.machines['0'] + model.block_until(lambda: len(model.machines)), timeout=240 + ) + machine = model.machines["0"] - assert machine.status in ('allocating', 'pending') - assert machine.agent_status == 'pending' + assert machine.status in ("allocating", "pending") + assert machine.agent_status == "pending" assert not machine.agent_version # there is some inconsistency in the capitalization of status_message # between different providers await asyncio.wait_for( model.block_until( - lambda: (machine.status == 'running' and - machine.status_message.lower() == 'running' and - machine.agent_status == 'started')), - timeout=480) + lambda: ( + machine.status == "running" + and machine.status_message.lower() == "running" + and machine.agent_status == "started" + ) + ), + timeout=480, + ) @base.bootstrapped diff --git a/tests/integration/test_model.py b/tests/integration/test_model.py index 0264119cf..1e744972d 100644 --- a/tests/integration/test_model.py +++ b/tests/integration/test_model.py @@ -18,7 +18,12 @@ from juju.client._definitions import FullStatus from juju.errors import JujuError, JujuModelError, JujuUnitError, JujuConnectionError from juju.model import Model, ModelObserver -from juju.utils import block_until, run_with_interrupt, wait_for_bundle, base_channel_to_series +from juju.utils import ( + block_until, + run_with_interrupt, + wait_for_bundle, + base_channel_to_series, +) from .. import base from ..utils import MB, GB, TESTS_DIR, OVERLAYS_DIR, SSH_KEY, INTEGRATION_TEST_DIR @@ -39,65 +44,62 @@ async def test_model_name(): @base.bootstrapped @pytest.mark.bundle async def test_deploy_local_bundle_dir(): - bundle_path = TESTS_DIR / 'bundle' + bundle_path = TESTS_DIR / "bundle" async with base.CleanModel() as model: await model.deploy(str(bundle_path)) - app1 = model.applications.get('juju-qa-test') - app2 = model.applications.get('nrpe') + app1 = model.applications.get("juju-qa-test") + app2 = model.applications.get("nrpe") with open("/tmp/output", "w") as writer: writer.write(str(bundle_path) + "\n") - for (k, v) in model.applications.items(): + for k, v in model.applications.items(): writer.write(k) assert app1 and app2 # import pdb;pdb.set_trace() - await model.wait_for_idle(['juju-qa-test', 'nrpe'], wait_for_at_least_units=1) + await model.wait_for_idle(["juju-qa-test", "nrpe"], wait_for_at_least_units=1) @base.bootstrapped @pytest.mark.bundle async def test_deploy_local_bundle_file(): - bundle_path = TESTS_DIR / 'bundle' - mini_bundle_file_path = bundle_path / 'mini-bundle.yaml' + bundle_path = TESTS_DIR / "bundle" + mini_bundle_file_path = bundle_path / "mini-bundle.yaml" async with base.CleanModel() as model: await model.deploy(str(mini_bundle_file_path)) - app1 = model.applications.get('juju-qa-test') - app2 = model.applications.get('nrpe') + app1 = model.applications.get("juju-qa-test") + app2 = model.applications.get("nrpe") assert app1 and app2 - await model.wait_for_idle(['juju-qa-test', 'nrpe'], wait_for_at_least_units=1) + await model.wait_for_idle(["juju-qa-test", "nrpe"], wait_for_at_least_units=1) @base.bootstrapped @pytest.mark.bundle async def test_deploy_bundle_local_resource_relative_path(): - bundle_file_path = INTEGRATION_TEST_DIR / 'bundle-file-resource.yaml' + bundle_file_path = INTEGRATION_TEST_DIR / "bundle-file-resource.yaml" async with base.CleanModel() as model: await model.deploy(str(bundle_file_path)) - app = model.applications.get('file-resource-charm') + app = model.applications.get("file-resource-charm") assert app - await model.block_until(lambda: (len(app.units) == 1), - timeout=60 * 4) + await model.block_until(lambda: (len(app.units) == 1), timeout=60 * 4) @base.bootstrapped async def test_deploy_by_revision(): async with base.CleanModel() as model: - app = await model.deploy('juju-qa-test', - application_name='test1', - channel='2.0/stable', - revision=22) + app = await model.deploy( + "juju-qa-test", application_name="test1", channel="2.0/stable", revision=22 + ) assert url.URL.parse(app.charm_url).revision == 22 - app = await model.deploy('juju-qa-test', - application_name='test2', - channel='latest/edge', - revision=19) + app = await model.deploy( + "juju-qa-test", application_name="test2", channel="latest/edge", revision=19 + ) assert url.URL.parse(app.charm_url).revision == 19 @@ -110,83 +112,85 @@ async def test_deploy_by_revision_validate_flags(): async with base.CleanModel() as model: # For charms --revision requires --channel with pytest.raises(JujuError): - await model.deploy('juju-qa-test', - # channel='2.0/stable', - revision=22) + await model.deploy( + "juju-qa-test", + # channel='2.0/stable', + revision=22, + ) # For bundles, --revision and --channel are mutually exclusive with pytest.raises(JujuError): - await model.deploy('ch:canonical-livepatch-onprem', - channel='latest/stable', - revision=4) + await model.deploy( + "ch:canonical-livepatch-onprem", channel="latest/stable", revision=4 + ) @base.bootstrapped @pytest.mark.bundle async def test_deploy_local_bundle_include_file(): - bundle_dir = INTEGRATION_TEST_DIR / 'bundle' - bundle_yaml_path = bundle_dir / 'bundle-include-file.yaml' + bundle_dir = INTEGRATION_TEST_DIR / "bundle" + bundle_yaml_path = bundle_dir / "bundle-include-file.yaml" async with base.CleanModel() as model: await model.deploy(str(bundle_yaml_path)) - appa = model.applications.get('helloa', None) - appb = model.applications.get('hellob', None) - test = model.applications.get('test', None) + appa = model.applications.get("helloa", None) + appb = model.applications.get("hellob", None) + test = model.applications.get("test", None) assert appa and appb and test - assert appa.config.get('port', None) == 666 - assert appa.config.get('application-repo', "") == "http://my-juju.com" + assert appa.config.get("port", None) == 666 + assert appa.config.get("application-repo", "") == "http://my-juju.com" @base.bootstrapped @pytest.mark.bundle async def test_deploy_local_bundle_include_base64(): - bundle_dir = INTEGRATION_TEST_DIR / 'bundle' - bundle_yaml_path = bundle_dir / 'bundle-include-base64.yaml' + bundle_dir = INTEGRATION_TEST_DIR / "bundle" + bundle_yaml_path = bundle_dir / "bundle-include-base64.yaml" async with base.CleanModel() as model: await model.deploy(str(bundle_yaml_path)) - appa = model.applications.get('helloa', None) - appb = model.applications.get('hellob', None) - test = model.applications.get('test', None) + appa = model.applications.get("helloa", None) + appb = model.applications.get("hellob", None) + test = model.applications.get("test", None) assert appa and appb and test - assert appa.config.get('application-repo', "") == "http://my-juju.com" + assert appa.config.get("application-repo", "") == "http://my-juju.com" @base.bootstrapped @pytest.mark.bundle async def test_deploy_bundle_local_charms(): - bundle_path = INTEGRATION_TEST_DIR / 'bundle' / 'local.yaml' + bundle_path = INTEGRATION_TEST_DIR / "bundle" / "local.yaml" async with base.CleanModel() as model: await model.deploy(bundle_path) await wait_for_bundle(model, bundle_path) - assert set(model.units.keys()) == set(['test1/0', 'test2/0']) - assert model.units['test1/0'].agent_status == 'idle' - assert model.units['test1/0'].workload_status == 'active' - assert model.units['test2/0'].agent_status == 'idle' - assert model.units['test2/0'].workload_status == 'active' + assert set(model.units.keys()) == set(["test1/0", "test2/0"]) + assert model.units["test1/0"].agent_status == "idle" + assert model.units["test1/0"].workload_status == "active" + assert model.units["test2/0"].agent_status == "idle" + assert model.units["test2/0"].workload_status == "active" @base.bootstrapped @pytest.mark.bundle async def test_deploy_bundle_local_charm_series_manifest(): - bundle_path = INTEGRATION_TEST_DIR / 'bundle' / 'local-manifest.yaml' + bundle_path = INTEGRATION_TEST_DIR / "bundle" / "local-manifest.yaml" async with base.CleanModel() as model: await model.deploy(bundle_path) await wait_for_bundle(model, bundle_path) - assert set(model.units.keys()) == set(['test1/0']) - assert model.units['test1/0'].agent_status == 'idle' - assert model.units['test1/0'].workload_status == 'active' + assert set(model.units.keys()) == set(["test1/0"]) + assert model.units["test1/0"].agent_status == "idle" + assert model.units["test1/0"].workload_status == "active" @base.bootstrapped @pytest.mark.bundle async def test_deploy_bundle_with_pinned_charm_revision(): - bundle_dir = INTEGRATION_TEST_DIR / 'bundle' - bundle_yaml_path = bundle_dir / 'bundle-with-charm-revision.yaml' + bundle_dir = INTEGRATION_TEST_DIR / "bundle" + bundle_yaml_path = bundle_dir / "bundle-with-charm-revision.yaml" # Revision of the hello-juju charm defined in the bundle yaml # We can also read the yaml to get the revision but we are hard-coding it for now for simplicity pinned_revision = 7 @@ -194,18 +198,21 @@ async def test_deploy_bundle_with_pinned_charm_revision(): async with base.CleanModel() as model: await model.deploy(str(bundle_yaml_path)) - application = model.applications.get('hello-juju', None) + application = model.applications.get("hello-juju", None) status: FullStatus = await model.get_status([application.name]) # the 'charm' field of application status should be of this format: # ch:amd64/{series}/{name}-{revision} - assert f"{application.name}-{pinned_revision}" in status.applications[application.name]["charm"] + assert ( + f"{application.name}-{pinned_revision}" + in status.applications[application.name]["charm"] + ) @base.bootstrapped @pytest.mark.bundle async def test_deploy_invalid_bundle(): - pytest.skip('test_deploy_invalid_bundle intermittent test failure') - bundle_path = TESTS_DIR / 'bundle' / 'invalid.yaml' + pytest.skip("test_deploy_invalid_bundle intermittent test failure") + bundle_path = TESTS_DIR / "bundle" / "invalid.yaml" async with base.CleanModel() as model: with pytest.raises(JujuError): await model.deploy(str(bundle_path)) @@ -214,7 +221,9 @@ async def test_deploy_invalid_bundle(): @base.bootstrapped @pytest.mark.bundle async def test_deploy_bundle_with_storage_constraint(): - bundle_path = INTEGRATION_TEST_DIR / 'bundle' / 'bundle-with-storage-constraint.yaml' + bundle_path = ( + INTEGRATION_TEST_DIR / "bundle" / "bundle-with-storage-constraint.yaml" + ) async with base.CleanModel() as model: assert model._info @@ -229,13 +238,13 @@ async def test_deploy_bundle_with_storage_constraint(): @base.bootstrapped async def test_deploy_local_charm(): - charm_path = TESTS_DIR / 'charm' + charm_path = TESTS_DIR / "charm" async with base.CleanModel() as model: await model.deploy(str(charm_path)) - assert 'charm' in model.applications + assert "charm" in model.applications await model.wait_for_idle(status="active") - assert model.units['charm/0'].workload_status == 'active' + assert model.units["charm/0"].workload_status == "active" @base.bootstrapped @@ -245,12 +254,12 @@ async def test_deploy_charm_assumes(): if str(model._info.agent_version) < "3.4.3": pytest.skip("postgresql charm requires Juju 3.4.3 or later") - await model.deploy('postgresql', channel='14/edge') + await model.deploy("postgresql", channel="14/edge") @base.bootstrapped async def test_deploy_local_charm_base_charmcraft_yaml(): - charm_path = INTEGRATION_TEST_DIR / 'charm-base-charmcraft-yaml' + charm_path = INTEGRATION_TEST_DIR / "charm-base-charmcraft-yaml" async with base.CleanModel() as model: await model.deploy(str(charm_path)) @@ -258,34 +267,34 @@ async def test_deploy_local_charm_base_charmcraft_yaml(): @base.bootstrapped async def test_deploy_local_charm_channel(): - charm_path = TESTS_DIR / 'charm' + charm_path = TESTS_DIR / "charm" async with base.CleanModel() as model: - await model.deploy(str(charm_path), channel='stable') - assert 'charm' in model.applications + await model.deploy(str(charm_path), channel="stable") + assert "charm" in model.applications @base.bootstrapped async def test_wait_local_charm_blocked(): - charm_path = TESTS_DIR / 'charm' + charm_path = TESTS_DIR / "charm" async with base.CleanModel() as model: - await model.deploy(str(charm_path), config={'status': 'blocked'}) - assert 'charm' in model.applications + await model.deploy(str(charm_path), config={"status": "blocked"}) + assert "charm" in model.applications await model.wait_for_idle() with pytest.raises(JujuUnitError): - await model.wait_for_idle(status="active", - raise_on_blocked=True, - timeout=30) + await model.wait_for_idle( + status="active", raise_on_blocked=True, timeout=30 + ) @base.bootstrapped async def test_wait_local_charm_waiting_timeout(): - charm_path = TESTS_DIR / 'charm' + charm_path = TESTS_DIR / "charm" async with base.CleanModel() as model: - await model.deploy(str(charm_path), config={'status': 'waiting'}) - assert 'charm' in model.applications + await model.deploy(str(charm_path), config={"status": "waiting"}) + assert "charm" in model.applications await model.wait_for_idle() with pytest.raises(jasyncio.TimeoutError): await model.wait_for_idle(status="active", timeout=30) @@ -295,10 +304,9 @@ async def test_wait_local_charm_waiting_timeout(): @pytest.mark.bundle async def test_deploy_bundle(): async with base.CleanModel() as model: - await model.deploy('anbox-cloud-core', channel='stable', - trust=True) + await model.deploy("anbox-cloud-core", channel="stable", trust=True) - for app in ('ams', 'etcd', 'ams-node-controller', 'etcd-ca', 'lxd'): + for app in ("ams", "etcd", "ams-node-controller", "etcd-ca", "lxd"): assert app in model.applications @@ -310,13 +318,13 @@ async def test_deploy_local_bundle_with_overlay_multi(): if str(model._info.agent_version) < "3.4.3": pytest.skip("bundle/postgresql charm requires Juju 3.4.3 or later") - bundle_with_overlay_path = OVERLAYS_DIR / 'bundle-with-overlay-multi.yaml' + bundle_with_overlay_path = OVERLAYS_DIR / "bundle-with-overlay-multi.yaml" await model.deploy(bundle_with_overlay_path) # this bundle deploys mysql and ghost apps and relates them, # but the overlay attached removes ghost, so - assert 'mysql' in model.applications - assert 'ghost' not in model.applications + assert "mysql" in model.applications + assert "ghost" not in model.applications @base.bootstrapped @@ -328,9 +336,9 @@ async def test_deploy_bundle_with_overlay_as_argument(): if str(model._info.agent_version) < "3.4.3": pytest.skip("bundle/postgresql charm requires Juju 3.4.3 or later") - overlay_path = OVERLAYS_DIR / 'test-overlay.yaml' + overlay_path = OVERLAYS_DIR / "test-overlay.yaml" - await model.deploy('juju-qa-bundle-test', overlays=[overlay_path]) + await model.deploy("juju-qa-bundle-test", overlays=[overlay_path]) # juju-qa-bundle-test installs the applications # - juju-qa-test # - juju-qa-test-focal @@ -339,10 +347,10 @@ async def test_deploy_bundle_with_overlay_as_argument(): # our overlay requests to remove ntp and add ghost and mysql # and relate them, so - assert 'juju-qa-test' in model.applications - assert 'ntp' not in model.applications - assert 'ghost' in model.applications - assert 'mysql' in model.applications + assert "juju-qa-test" in model.applications + assert "ntp" not in model.applications + assert "ghost" in model.applications + assert "mysql" in model.applications @base.bootstrapped @@ -353,12 +361,12 @@ async def test_deploy_bundle_with_multi_overlay_as_argument(): if str(model._info.agent_version) < "3.4.3": pytest.skip("bundle/postgresql charm requires Juju 3.4.3 or later") - overlay_path = OVERLAYS_DIR / 'test-multi-overlay.yaml' + overlay_path = OVERLAYS_DIR / "test-multi-overlay.yaml" - await model.deploy('juju-qa-bundle-test', overlays=[overlay_path]) - assert 'ntp' not in model.applications - assert 'memcached' not in model.applications - assert 'mysql' in model.applications + await model.deploy("juju-qa-bundle-test", overlays=[overlay_path]) + assert "ntp" not in model.applications + assert "memcached" not in model.applications + assert "mysql" in model.applications @base.bootstrapped @@ -366,36 +374,40 @@ async def test_deploy_bundle_with_multi_overlay_as_argument(): @pytest.mark.skip("Always fails -- investigate bundle charms") async def test_deploy_bundle_with_multiple_overlays_with_include_files(): async with base.CleanModel() as model: - bundle_yaml_path = TESTS_DIR / 'integration' / 'bundle' / 'bundle.yaml' - overlay1_path = OVERLAYS_DIR / 'test-overlay2.yaml' - overlay2_path = OVERLAYS_DIR / 'test-overlay3.yaml' - overlay3_path = OVERLAYS_DIR / 'test-overlay4.yaml' + bundle_yaml_path = TESTS_DIR / "integration" / "bundle" / "bundle.yaml" + overlay1_path = OVERLAYS_DIR / "test-overlay2.yaml" + overlay2_path = OVERLAYS_DIR / "test-overlay3.yaml" + overlay3_path = OVERLAYS_DIR / "test-overlay4.yaml" - await model.deploy(str(bundle_yaml_path), overlays=[overlay1_path, overlay2_path, overlay3_path]) + await model.deploy( + str(bundle_yaml_path), + overlays=[overlay1_path, overlay2_path, overlay3_path], + ) - assert 'influxdb' not in model.applications - assert 'test' not in model.applications - assert 'memcached' not in model.applications - assert 'grafana' in model.applications - assert 'grafana' in model.application_offers - assert 'grafana' == model.application_offers['grafana'].application_name - assert 'dashboards' == model.application_offers['grafana'].offer_name + assert "influxdb" not in model.applications + assert "test" not in model.applications + assert "memcached" not in model.applications + assert "grafana" in model.applications + assert "grafana" in model.application_offers + assert "grafana" == model.application_offers["grafana"].application_name + assert "dashboards" == model.application_offers["grafana"].offer_name @base.bootstrapped async def test_deploy_local_charm_folder_symlink(): - charm_path = TESTS_DIR / 'charm-folder-symlink' + charm_path = TESTS_DIR / "charm-folder-symlink" async with base.CleanModel() as model: simple = await model.deploy(str(charm_path)) - assert 'simple' in model.applications - terminal_statuses = ('active', 'error', 'blocked') + assert "simple" in model.applications + terminal_statuses = ("active", "error", "blocked") await model.block_until( lambda: ( - len(simple.units) > 0 and - simple.units[0].workload_status in terminal_statuses) + len(simple.units) > 0 + and simple.units[0].workload_status in terminal_statuses + ) ) - assert simple.units[0].workload_status == 'active' + assert simple.units[0].workload_status == "active" @base.bootstrapped @@ -408,37 +420,46 @@ async def test_deploy_from_ch_channel_revision_success(): # Ensure we're able to resolve charm these with channel and revision, # or channel without revision (note that revision requires channel, # but not vice versa) - await model.deploy("postgresql", application_name="test1", channel='14/stable', base='ubuntu@22.04') - await model.deploy("postgresql", application_name="test2", channel='14/stable', revision=288) + await model.deploy( + "postgresql", + application_name="test1", + channel="14/stable", + base="ubuntu@22.04", + ) + await model.deploy( + "postgresql", application_name="test2", channel="14/stable", revision=288 + ) @base.bootstrapped @pytest.mark.bundle async def test_deploy_trusted_bundle(): - pytest.skip("skip until we have a deployable bundle available. Right now the landscape-dense fails because postgresql is broken") + pytest.skip( + "skip until we have a deployable bundle available. Right now the landscape-dense fails because postgresql is broken" + ) async with base.CleanModel() as model: - await model.deploy('landscape-dense', channel='stable', trust=True) + await model.deploy("landscape-dense", channel="stable", trust=True) - for app in ('haproxy', 'landscape-server', 'postgresql', 'rabbit-mq-server'): + for app in ("haproxy", "landscape-server", "postgresql", "rabbit-mq-server"): assert app in model.applications - haproxy_app = model.applications['haproxy'] + haproxy_app = model.applications["haproxy"] trusted = await haproxy_app.get_trusted() assert trusted is True @base.bootstrapped async def test_deploy_from_ch_with_series(): - charm = 'ch:ubuntu' - for series in ['focal']: + charm = "ch:ubuntu" + for series in ["focal"]: async with base.CleanModel() as model: app_name = "ubuntu-{}".format(series) await model.deploy(charm, application_name=app_name, series=series) - status = (await model.get_status()) + status = await model.get_status() app_status = status["applications"][app_name] - if 'series' in app_status.serialize(): - s = app_status['series'] + if "series" in app_status.serialize(): + s = app_status["series"] else: # If there's no series, we should have a base s = base_channel_to_series(app_status.base.channel) @@ -448,10 +469,10 @@ async def test_deploy_from_ch_with_series(): @base.bootstrapped async def test_deploy_from_ch_with_invalid_series(): async with base.CleanModel() as model: - charm = 'ch:ubuntu' + charm = "ch:ubuntu" try: - await model.deploy(charm, series='invalid') - assert False, 'Invalid deployment should raise JujuError' + await model.deploy(charm, series="invalid") + assert False, "Invalid deployment should raise JujuError" except JujuError: pass @@ -460,16 +481,16 @@ async def test_deploy_from_ch_with_invalid_series(): async def test_deploy_with_base(): async with base.CleanModel() as model: await model.deploy("ubuntu", base="ubuntu@22.04") - await model.wait_for_idle(status='active') + await model.wait_for_idle(status="active") @base.bootstrapped async def test_deploy_noble(): - charm_path = INTEGRATION_TEST_DIR / 'charm-manifest' + charm_path = INTEGRATION_TEST_DIR / "charm-manifest" async with base.CleanModel() as model: await model.deploy(str(charm_path), base="ubuntu@24.04") - await model.wait_for_idle(status='active') + await model.wait_for_idle(status="active") @base.bootstrapped @@ -483,19 +504,20 @@ async def test_add_machine(): # add a machine with constraints, disks, and series machine2 = await model.add_machine( constraints={ - 'arch': 'amd64', - 'mem': 256 * MB, + "arch": "amd64", + "mem": 256 * MB, }, - disks=[{ - 'size': 10 * GB, - 'count': 1, - }], - series='xenial', + disks=[ + { + "size": 10 * GB, + "count": 1, + } + ], + series="xenial", ) # add a lxd container to machine2 - machine3 = await model.add_machine( - 'lxd:{}'.format(machine2.id)) + machine3 = await model.add_machine("lxd:{}".format(machine2.id)) for m in (machine1, machine2, machine3): assert isinstance(m, Machine) @@ -511,33 +533,28 @@ async def test_add_machine(): async def add_manual_machine_ssh(is_root=False): - # Verify controller is localhost async with base.CleanController() as controller: cloud = await controller.get_cloud() if cloud != "localhost": - pytest.skip('Skipping because test requires lxd.') + pytest.skip("Skipping because test requires lxd.") async with base.CleanModel() as model: - private_key_path = os.path.expanduser( - "~/.local/share/juju/ssh/juju_id_rsa" - ) - public_key_path = os.path.expanduser( - "~/.local/share/juju/ssh/juju_id_rsa.pub" - ) + private_key_path = os.path.expanduser("~/.local/share/juju/ssh/juju_id_rsa") + public_key_path = os.path.expanduser("~/.local/share/juju/ssh/juju_id_rsa.pub") # connect using the local unix socket client = pylxd.Client() - test_name = "test-{}-add-manual-machine-ssh".format( - uuid.uuid4().hex[-4:] - ) + test_name = "test-{}-add-manual-machine-ssh".format(uuid.uuid4().hex[-4:]) if is_root: test_user = "root" else: # Create a randomized user name - test_user = ''.join(random.choice(string.ascii_lowercase) for i in range(10)) + test_user = "".join( + random.choice(string.ascii_lowercase) for i in range(10) + ) # create profile w/cloud-init and juju ssh key public_key = "" @@ -566,28 +583,24 @@ async def add_manual_machine_ssh(is_root=False): profile = client.profiles.create( test_name, - config={'user.user-data': cloud_init}, + config={"user.user-data": cloud_init}, devices={ - 'root': {'path': '/', 'pool': 'default', 'type': 'disk'}, - 'eth0': { - 'nictype': 'bridged', - 'parent': 'lxdbr0', - 'type': 'nic' - } - } + "root": {"path": "/", "pool": "default", "type": "disk"}, + "eth0": {"nictype": "bridged", "parent": "lxdbr0", "type": "nic"}, + }, ) # create lxc machine config = { - 'name': test_name, - 'source': { - 'type': 'image', - 'alias': 'focal', - 'mode': 'pull', - 'protocol': 'simplestreams', - 'server': 'https://cloud-images.ubuntu.com/releases', + "name": test_name, + "source": { + "type": "image", + "alias": "focal", + "mode": "pull", + "protocol": "simplestreams", + "server": "https://cloud-images.ubuntu.com/releases", }, - 'profiles': [test_name], + "profiles": [test_name], } container = client.containers.create(config, wait=True) container.start(wait=True) @@ -597,23 +610,23 @@ def wait_for_network(container, timeout=30): starttime = time.perf_counter() while time.perf_counter() < starttime + timeout: time.sleep(1) - if 'eth0' in container.state().network: - addresses = container.state().network['eth0']['addresses'] + if "eth0" in container.state().network: + addresses = container.state().network["eth0"]["addresses"] if len(addresses) > 0: - if addresses[0]['family'] == 'inet': + if addresses[0]["family"] == "inet": return addresses[0] return None host = wait_for_network(container) - assert host, 'Failed to get address for machine' + assert host, "Failed to get address for machine" # HACK: We need to give sshd a chance to bind to the interface, # and pylxd's container.execute seems to be broken and fails and/or # hangs trying to properly check if the service is up. time.sleep(5) - spec = 'ssh:{}@{}:{}'.format( + spec = "ssh:{}@{}:{}".format( test_user, - host['address'], + host["address"], private_key_path, ) err = None @@ -621,7 +634,10 @@ def wait_for_network(container, timeout=30): try: # add a new manual machine machine1 = await model.add_machine(spec=spec) - except (paramiko.ssh_exception.NoValidConnectionsError, paramiko.ssh_exception.AuthenticationException) as e: + except ( + paramiko.ssh_exception.NoValidConnectionsError, + paramiko.ssh_exception.AuthenticationException, + ) as e: # retry the ssh connection a few times if it fails err = e time.sleep(attempt * 5) @@ -633,7 +649,10 @@ def wait_for_network(container, timeout=30): container.stop(wait=True) container.delete(wait=True) profile.delete() - raise AssertionError('Unable to add_machine in %s attempts with spec : %s -- exception was %s' % (attempt, spec, err)) + raise AssertionError( + "Unable to add_machine in %s attempts with spec : %s -- exception was %s" + % (attempt, spec, err) + ) res = await machine1.destroy(force=True) @@ -641,13 +660,16 @@ def wait_for_network(container, timeout=30): container.stop(wait=True) container.delete(wait=True) profile.delete() - raise AssertionError('Bad teardown, res is : %s' % res) + raise AssertionError("Bad teardown, res is : %s" % res) if len(model.machines) != 0: container.stop(wait=True) container.delete(wait=True) profile.delete() - raise AssertionError('Unable to destroy the added machine during cleanup -- model has : %s machines' % len(model.machines)) + raise AssertionError( + "Unable to destroy the added machine during cleanup -- model has : %s machines" + % len(model.machines) + ) container.stop(wait=True) container.delete(wait=True) @@ -676,16 +698,16 @@ async def test_relate(): async with base.CleanModel() as model: await model.deploy( - 'ubuntu', - application_name='ubuntu', - base='ubuntu@20.04/stable', - channel='stable', + "ubuntu", + application_name="ubuntu", + base="ubuntu@20.04/stable", + channel="stable", ) await model.deploy( - 'nrpe', - application_name='nrpe', - base='ubuntu@20.04/stable', - channel='stable', + "nrpe", + application_name="nrpe", + base="ubuntu@20.04/stable", + channel="stable", # subordinates must be deployed without units num_units=0, ) @@ -695,8 +717,7 @@ async def test_relate(): class TestObserver(ModelObserver): async def on_relation_add(self, delta, old, new, model): - if set(new.key.split()) == {'nrpe:general-info', - 'ubuntu:juju-info'}: + if set(new.key.split()) == {"nrpe:general-info", "ubuntu:juju-info"}: relation_added.set() jasyncio.get_running_loop().call_later(10, timeout.set) @@ -714,139 +735,147 @@ async def mock_AddRelation(*args, **kwargs): mock_app_facade.AddRelation = mock_AddRelation - with mock.patch.object(client.ApplicationFacade, 'from_connection', - return_value=mock_app_facade): - my_relation = await run_with_interrupt(model.relate( - 'ubuntu', - 'nrpe', - ), timeout) + with mock.patch.object( + client.ApplicationFacade, "from_connection", return_value=mock_app_facade + ): + my_relation = await run_with_interrupt( + model.relate( + "ubuntu", + "nrpe", + ), + timeout, + ) assert isinstance(my_relation, Relation) @base.bootstrapped async def test_store_resources_charm(): - pytest.skip('Revise: test_store_resources_charm intermittent test failure') + pytest.skip("Revise: test_store_resources_charm intermittent test failure") async with base.CleanModel() as model: - ghost = await model.deploy('ghost', channel='stable') - assert 'ghost' in model.applications - terminal_statuses = ('active', 'error', 'blocked') + ghost = await model.deploy("ghost", channel="stable") + assert "ghost" in model.applications + terminal_statuses = ("active", "error", "blocked") await model.block_until( lambda: ( - len(ghost.units) > 0 and - ghost.units[0].workload_status in terminal_statuses), - timeout=60 * 4 + len(ghost.units) > 0 + and ghost.units[0].workload_status in terminal_statuses + ), + timeout=60 * 4, ) # ghost will go in to blocked (or error, for older # charm revs) if the resource is missing - assert ghost.units[0].workload_status == 'active' + assert ghost.units[0].workload_status == "active" @base.bootstrapped async def test_local_oci_image_resource_charm(): - charm_path = TESTS_DIR / 'integration' / 'oci-image-charm' + charm_path = TESTS_DIR / "integration" / "oci-image-charm" async with base.CleanModel() as model: resources = {"oci-image": "ubuntu/latest"} charm = await model.deploy(str(charm_path), resources=resources) - assert 'oci-image-charm' in model.applications - terminal_statuses = ('active', 'error', 'blocked') + assert "oci-image-charm" in model.applications + terminal_statuses = ("active", "error", "blocked") await model.block_until( lambda: ( - len(charm.units) > 0 and - charm.units[0].workload_status in terminal_statuses), + len(charm.units) > 0 + and charm.units[0].workload_status in terminal_statuses + ), timeout=60 * 10, ) - assert charm.units[0].workload_status == 'active' + assert charm.units[0].workload_status == "active" @base.bootstrapped async def test_local_file_resource_charm(): - charm_path = INTEGRATION_TEST_DIR / 'file-resource-charm' + charm_path = INTEGRATION_TEST_DIR / "file-resource-charm" async with base.CleanModel() as model: resources = {"file-res": "test.file"} app = await model.deploy(str(charm_path), resources=resources) - assert 'file-resource-charm' in model.applications + assert "file-resource-charm" in model.applications await model.wait_for_idle(raise_on_error=False) - assert app.units[0].agent_status == 'idle' + assert app.units[0].agent_status == "idle" ress = await app.get_resources() - assert 'file-res' in ress - assert ress['file-res'] + assert "file-res" in ress + assert ress["file-res"] @base.bootstrapped async def test_attach_resource(): - charm_path = TESTS_DIR / 'integration' / 'file-resource-charm' + charm_path = TESTS_DIR / "integration" / "file-resource-charm" async with base.CleanModel() as model: resources = {"file-res": "test.file"} app = await model.deploy(str(charm_path), resources=resources) - assert 'file-resource-charm' in model.applications + assert "file-resource-charm" in model.applications await model.wait_for_idle(raise_on_error=False) - assert app.units[0].agent_status == 'idle' + assert app.units[0].agent_status == "idle" - with open(str(charm_path / 'test.file')) as f: - app.attach_resource('file-res', 'test.file', f) + with open(str(charm_path / "test.file")) as f: + app.attach_resource("file-res", "test.file", f) - with open(str(charm_path / 'test.file'), 'rb') as f: - app.attach_resource('file-res', 'test.file', f) + with open(str(charm_path / "test.file"), "rb") as f: + app.attach_resource("file-res", "test.file", f) @base.bootstrapped @pytest.mark.bundle async def test_store_resources_bundle(): - pytest.skip('test_store_resources_bundle intermittent test failure') + pytest.skip("test_store_resources_bundle intermittent test failure") async with base.CleanModel() as model: - bundle = INTEGRATION_TEST_DIR / 'bundle' + bundle = INTEGRATION_TEST_DIR / "bundle" await model.deploy(bundle) - assert 'ghost' in model.applications - ghost = model.applications['ghost'] - terminal_statuses = ('active', 'error', 'blocked') + assert "ghost" in model.applications + ghost = model.applications["ghost"] + terminal_statuses = ("active", "error", "blocked") await model.block_until( lambda: ( - len(ghost.units) > 0 and - ghost.units[0].workload_status in terminal_statuses) + len(ghost.units) > 0 + and ghost.units[0].workload_status in terminal_statuses + ) ) # ghost will go in to blocked (or error, for older # charm revs) if the resource is missing - assert ghost.units[0].workload_status == 'active' + assert ghost.units[0].workload_status == "active" resources = await ghost.get_resources() - assert resources['ghost-stable'].revision >= 12 + assert resources["ghost-stable"].revision >= 12 @base.bootstrapped @pytest.mark.bundle async def test_store_resources_bundle_revs(): - pytest.skip('test_store_resources_bundle_revs intermittent test failure') + pytest.skip("test_store_resources_bundle_revs intermittent test failure") async with base.CleanModel() as model: - bundle = INTEGRATION_TEST_DIR / 'bundle/bundle-resource-rev.yaml' + bundle = INTEGRATION_TEST_DIR / "bundle/bundle-resource-rev.yaml" await model.deploy(bundle) - assert 'ghost' in model.applications - ghost = model.applications['ghost'] - terminal_statuses = ('active', 'error', 'blocked') + assert "ghost" in model.applications + ghost = model.applications["ghost"] + terminal_statuses = ("active", "error", "blocked") await model.block_until( lambda: ( - len(ghost.units) > 0 and - ghost.units[0].workload_status in terminal_statuses) + len(ghost.units) > 0 + and ghost.units[0].workload_status in terminal_statuses + ) ) # ghost will go in to blocked (or error, for older # charm revs) if the resource is missing - assert ghost.units[0].workload_status == 'active' + assert ghost.units[0].workload_status == "active" resources = await ghost.get_resources() - assert resources['ghost-stable'].revision == 11 + assert resources["ghost-stable"].revision == 11 @base.bootstrapped async def test_ssh_key(): async with base.CleanModel() as model: - await model.add_ssh_key('admin', SSH_KEY) + await model.add_ssh_key("admin", SSH_KEY) result = await model.get_ssh_key(True) - result = result.serialize()['results'][0].serialize()['result'] + result = result.serialize()["results"][0].serialize()["result"] assert SSH_KEY in result - await model.remove_ssh_key('admin', SSH_KEY) + await model.remove_ssh_key("admin", SSH_KEY) result = await model.get_ssh_key(True) - result = result.serialize()['results'][0].serialize()['result'] + result = result.serialize()["results"][0].serialize()["result"] assert result is None @@ -862,9 +891,9 @@ async def test_get_machines(): async def test_wait_for_idle_without_units(): async with base.CleanModel() as model: await model.deploy( - 'ubuntu', - application_name='ubuntu', - channel='stable', + "ubuntu", + application_name="ubuntu", + channel="stable", num_units=0, ) with pytest.raises(jasyncio.TimeoutError): @@ -876,9 +905,9 @@ async def test_wait_for_idle_without_units(): async def test_wait_for_idle_with_not_enough_units(): async with base.CleanModel() as model: await model.deploy( - 'ubuntu', - application_name='ubuntu', - channel='stable', + "ubuntu", + application_name="ubuntu", + channel="stable", num_units=2, ) with pytest.raises(jasyncio.TimeoutError): @@ -889,7 +918,7 @@ async def test_wait_for_idle_with_not_enough_units(): @pytest.mark.wait_for_idle async def test_wait_for_idle_more_units_than_needed(): async with base.CleanModel() as model: - charm_path = TESTS_DIR / 'charm' + charm_path = TESTS_DIR / "charm" # we add 2 units of a local charm that does nothing # (i.e. can't go into active/idle) @@ -897,14 +926,16 @@ async def test_wait_for_idle_more_units_than_needed(): # then add 1 unit of ubuntu charm await model.deploy( - 'ubuntu', - application_name='ubuntu', + "ubuntu", + application_name="ubuntu", num_units=1, ) # because the wait_for_at_least_units=1, wait_for_idle should return without timing out # even though there are two more units that aren't active/idle - await model.wait_for_idle(timeout=5 * 60, wait_for_at_least_units=1, status='active') + await model.wait_for_idle( + timeout=5 * 60, wait_for_at_least_units=1, status="active" + ) @base.bootstrapped @@ -913,9 +944,9 @@ async def test_wait_for_idle_with_enough_units(): pytest.skip("This is testing juju functionality") async with base.CleanModel() as model: await model.deploy( - 'ubuntu', - application_name='ubuntu', - channel='stable', + "ubuntu", + application_name="ubuntu", + channel="stable", num_units=3, ) await model.wait_for_idle(timeout=5 * 60, wait_for_at_least_units=3) @@ -927,9 +958,9 @@ async def test_wait_for_idle_with_exact_units(): pytest.skip("This is testing juju functionality") async with base.CleanModel() as model: await model.deploy( - 'ubuntu', - application_name='ubuntu', - channel='stable', + "ubuntu", + application_name="ubuntu", + channel="stable", num_units=2, ) await model.wait_for_idle(timeout=5 * 60, wait_for_exact_units=2) @@ -945,10 +976,10 @@ async def test_wait_for_idle_with_exact_units_scale_down(): pytest.skip("This is testing juju functionality") async with base.CleanModel() as model: app = await model.deploy( - 'ubuntu', - application_name='ubuntu', - series='jammy', - channel='stable', + "ubuntu", + application_name="ubuntu", + series="jammy", + channel="stable", num_units=3, ) await model.wait_for_idle(timeout=5 * 60, wait_for_exact_units=3) @@ -974,10 +1005,10 @@ async def test_wait_for_idle_with_exact_units_scale_down_zero(): pytest.skip("This is testing juju functionality") async with base.CleanModel() as model: app = await model.deploy( - 'ubuntu', - application_name='ubuntu', - series='jammy', - channel='stable', + "ubuntu", + application_name="ubuntu", + series="jammy", + channel="stable", num_units=3, ) await model.wait_for_idle(timeout=5 * 60, wait_for_exact_units=3) @@ -998,13 +1029,13 @@ async def test_wait_for_idle_with_exact_units_scale_down_zero(): async def test_destroy_units(): async with base.CleanModel() as model: app = await model.deploy( - 'ubuntu', - application_name='ubuntu', - series='jammy', - channel='stable', + "ubuntu", + application_name="ubuntu", + series="jammy", + channel="stable", num_units=3, ) - await model.wait_for_idle(status='active') + await model.wait_for_idle(status="active") await model.destroy_units(*[u.name for u in app.units]) await model.wait_for_idle(timeout=5 * 60, wait_for_exact_units=0) assert app.units == [] @@ -1022,15 +1053,15 @@ async def test_config(): async with base.CleanModel() as model: # first test get_config with nothing. result = await model.get_config() - assert 'extra-info' not in result + assert "extra-info" not in result await model.set_config({ - 'extra-info': 'booyah', - 'test-mode': client.ConfigValue(value=True), + "extra-info": "booyah", + "test-mode": client.ConfigValue(value=True), }) result = await model.get_config() - assert 'extra-info' in result - assert result['extra-info'].source == 'model' - assert result['extra-info'].value == 'booyah' + assert "extra-info" in result + assert result["extra-info"].source == "model" + assert result["extra-info"].value == "booyah" @base.bootstrapped @@ -1038,26 +1069,27 @@ async def test_config_with_json(): async with base.CleanModel() as model: # first test get_config with nothing. result = await model.get_config() - assert 'extra-complex-info' not in result + assert "extra-complex-info" not in result # test model config with more complex data - expected = ['foo', {'bar': 1}] + expected = ["foo", {"bar": 1}] await model.set_config({ - 'extra-complex-info': json.dumps(expected), - 'test-mode': client.ConfigValue(value=True), + "extra-complex-info": json.dumps(expected), + "test-mode": client.ConfigValue(value=True), }) result = await model.get_config() - assert 'extra-complex-info' in result - assert result['extra-complex-info'].source == 'model' - recieved = json.loads(result['extra-complex-info'].value) - assert recieved == recieved + assert "extra-complex-info" in result + assert result["extra-complex-info"].source == "model" + received = json.loads(result["extra-complex-info"].value) + assert received == received @base.bootstrapped async def test_set_constraints(): async with base.CleanModel() as model: - await model.set_constraints({'cpu-power': 1}) + await model.set_constraints({"cpu-power": 1}) cons = await model.get_constraints() - assert cons['cpu_power'] == 1 + assert cons["cpu_power"] == 1 + # @base.bootstrapped # # async def test_grant() @@ -1073,7 +1105,6 @@ async def test_set_constraints(): @base.bootstrapped async def test_model_annotations(): - async with base.CleanModel() as model: annotations = await model.get_annotations() assert len(annotations) == 0 @@ -1087,7 +1118,6 @@ async def test_model_annotations(): @base.bootstrapped async def test_machine_annotations(): - async with base.CleanModel() as model: machine = await model.add_machine() @@ -1103,9 +1133,8 @@ async def test_machine_annotations(): @base.bootstrapped async def test_application_annotations(): - async with base.CleanModel() as model: - app = await model.deploy('ubuntu', channel="stable") + app = await model.deploy("ubuntu", channel="stable") annotations = await app.get_annotations() assert len(annotations) == 0 @@ -1119,9 +1148,8 @@ async def test_application_annotations(): @base.bootstrapped async def test_unit_annotations(): - async with base.CleanModel() as model: - app = await model.deploy('ubuntu') + app = await model.deploy("ubuntu") await model.wait_for_idle() unit = app.units[0] @@ -1137,18 +1165,18 @@ async def test_unit_annotations(): @base.bootstrapped async def test_backups(): - pytest.skip('Revise: mongodb issues') + pytest.skip("Revise: mongodb issues") m = Model() - await m.connect(model_name='controller') + await m.connect(model_name="controller") test_start = await m.get_backups() num_of_backups_before_test = len(test_start) # Create a backup local_file_name, extra_info = await m.create_backup(notes="hi") - assert 'id' in extra_info - assert 'checksum' in extra_info + assert "id" in extra_info + assert "checksum" in extra_info - assert extra_info['notes'] == "hi" + assert extra_info["notes"] == "hi" # Check if the file is downloaded on disk assert os.path.exists(local_file_name) @@ -1225,9 +1253,9 @@ async def test_model_cache_update(): @base.bootstrapped async def test_add_storage(): - pytest.skip('skip in favour of test_add_and_list_storage') + pytest.skip("skip in favour of test_add_and_list_storage") async with base.CleanModel() as model: - app = await model.deploy('postgresql') + app = await model.deploy("postgresql") await model.wait_for_idle(status="active") unit = app.units[0] ret = await unit.add_storage("pgdata") @@ -1236,7 +1264,7 @@ async def test_add_storage(): @base.bootstrapped async def test_model_attach_storage_at_deploy(): - pytest.skip('detach/attach_storage inconsistent on Juju side, unable to test') + pytest.skip("detach/attach_storage inconsistent on Juju side, unable to test") async with base.CleanModel() as model: # The attach_storage needs to be an existing storage, # so the plan is to: @@ -1246,7 +1274,7 @@ async def test_model_attach_storage_at_deploy(): # - Remove app # - Re-deploy with attach_storage parameter # - Make sure the storage is there - app = await model.deploy('postgresql') + app = await model.deploy("postgresql") await model.wait_for_idle(status="active") unit = app.units[0] @@ -1258,7 +1286,7 @@ async def test_model_attach_storage_at_deploy(): await jasyncio.sleep(10) storages1 = await model.list_storage() - assert any([storage_id in s['storage-tag'] for s in storages1]) + assert any([storage_id in s["storage-tag"] for s in storages1]) # juju remove-application # actually removes the storage even though the destroy_storage=false @@ -1266,20 +1294,20 @@ async def test_model_attach_storage_at_deploy(): await jasyncio.sleep(10) storages2 = await model.list_storage() - assert any([storage_id in s['storage-tag'] for s in storages2]) + assert any([storage_id in s["storage-tag"] for s in storages2]) - await model.deploy('postgresql', attach_storage=[storage_id]) + await model.deploy("postgresql", attach_storage=[storage_id]) await model.wait_for_idle(status="active") storages3 = await model.list_storage() - assert any([storage_id in s['storage-tag'] for s in storages3]) + assert any([storage_id in s["storage-tag"] for s in storages3]) @base.bootstrapped async def test_detach_storage(): - pytest.skip('detach/attach_storage inconsistent on Juju side, unable to test') + pytest.skip("detach/attach_storage inconsistent on Juju side, unable to test") async with base.CleanModel() as model: - app = await model.deploy('postgresql') + app = await model.deploy("postgresql") await model.wait_for_idle(status="active") unit = app.units[0] storage_ids = await unit.add_storage("pgdata") @@ -1288,27 +1316,28 @@ async def test_detach_storage(): _storage_details_1 = await model.show_storage_details(storage_id) storage_details_1 = _storage_details_1[0] - assert 'unit-postgresql-0' in storage_details_1['attachments'] + assert "unit-postgresql-0" in storage_details_1["attachments"] await unit.detach_storage(storage_id, force=True) await jasyncio.sleep(20) _storage_details_2 = await model.show_storage_details(storage_id) storage_details_2 = _storage_details_2[0] - assert ('unit-postgresql-0' not in storage_details_2['attachments']) or \ - storage_details_2['attachments']['unit-postgresql-0'].life == 'dying' + assert ( + "unit-postgresql-0" not in storage_details_2["attachments"] + ) or storage_details_2["attachments"]["unit-postgresql-0"].life == "dying" # remove_storage await model.remove_storage(storage_id, force=True) await jasyncio.sleep(10) storages = await model.list_storage() - assert all([storage_id not in s['storage-tag'] for s in storages]) + assert all([storage_id not in s["storage-tag"] for s in storages]) @base.bootstrapped async def test_add_and_list_storage(): async with base.CleanModel() as model: - app = await model.deploy('postgresql', base='ubuntu@22.04') + app = await model.deploy("postgresql", base="ubuntu@22.04") # TODO (cderici): # This is a good use case for waiting on individual unit status # (i.e. not caring about the app status) @@ -1322,21 +1351,21 @@ async def test_add_and_list_storage(): await model.list_storage(filesystem=True) await model.list_storage(volume=True) - assert any([tag.storage("pgdata") in s['storage-tag'] for s in storages]) + assert any([tag.storage("pgdata") in s["storage-tag"] for s in storages]) @base.bootstrapped async def test_storage_pools_on_lxd(): # This will fail when ran on anything but lxd async with base.CleanModel() as model: - await model.deploy('ubuntu') + await model.deploy("ubuntu") await model.wait_for_idle(status="active") await model.create_storage_pool("test-pool", "lxd") pools = await model.list_storage_pools() - assert "test-pool" in [p['name'] for p in pools] + assert "test-pool" in [p["name"] for p in pools] await model.remove_storage_pool("test-pool") await jasyncio.sleep(5) pools = await model.list_storage_pools() - assert "test-pool" not in [p['name'] for p in pools] + assert "test-pool" not in [p["name"] for p in pools] diff --git a/tests/integration/test_secrets.py b/tests/integration/test_secrets.py index 9465b4188..e989e7680 100644 --- a/tests/integration/test_secrets.py +++ b/tests/integration/test_secrets.py @@ -14,12 +14,14 @@ async def test_add_secret(): if str(model._info.agent_version) < "3.3.0": pytest.skip("Juju too old, need Secrets API v2") - secret = await model.add_secret(name='my-apitoken', data_args=['token=34ae35facd4']) - assert secret.startswith('secret:') + secret = await model.add_secret( + name="my-apitoken", data_args=["token=34ae35facd4"] + ) + assert secret.startswith("secret:") secrets = await model.list_secrets() assert len(secrets) == 1 - assert secrets[0].label == 'my-apitoken' + assert secrets[0].label == "my-apitoken" # This test can only work if we can fully upgrade the whole charm @@ -29,7 +31,7 @@ async def test_list_secrets(): """Use the charm-secret charm definition and see if the arguments defined in the secret are correct or not.""" - charm_path = TESTS_DIR / 'charm-secret/charm-secret_ubuntu-22.04-amd64.charm' + charm_path = TESTS_DIR / "charm-secret/charm-secret_ubuntu-22.04-amd64.charm" async with base.CleanModel() as model: assert model._info @@ -37,9 +39,9 @@ async def test_list_secrets(): pytest.skip("Juju too old, need Secrets API v2") await model.deploy(str(charm_path)) - assert 'charm-secret' in model.applications + assert "charm-secret" in model.applications await model.wait_for_idle(status="active") - assert model.units['charm-secret/0'].workload_status == 'active' + assert model.units["charm-secret/0"].workload_status == "active" secrets = await model.list_secrets(show_secrets=True) assert secrets is not None @@ -54,14 +56,16 @@ async def test_update_secret(): if str(model._info.agent_version) < "3.3.0": pytest.skip("Juju too old, need Secrets API v2") - secret = await model.add_secret(name='my-apitoken', data_args=['token=34ae35facd4']) - assert secret.startswith('secret:') + secret = await model.add_secret( + name="my-apitoken", data_args=["token=34ae35facd4"] + ) + assert secret.startswith("secret:") - await model.update_secret(name='my-apitoken', new_name='new-token') + await model.update_secret(name="my-apitoken", new_name="new-token") secrets = await model.list_secrets() assert len(secrets) == 1 - assert secrets[0].label == 'new-token' + assert secrets[0].label == "new-token" @base.bootstrapped @@ -72,10 +76,12 @@ async def test_remove_secret(): if str(model._info.agent_version) < "3.3.0": pytest.skip("Juju too old, need Secrets API v2") - secret = await model.add_secret(name='my-apitoken', data_args=['token=34ae35facd4']) - assert secret.startswith('secret:') + secret = await model.add_secret( + name="my-apitoken", data_args=["token=34ae35facd4"] + ) + assert secret.startswith("secret:") - await model.remove_secret('my-apitoken') + await model.remove_secret("my-apitoken") secrets = await model.list_secrets() assert len(secrets) == 0 @@ -89,12 +95,14 @@ async def test_grant_secret(): if str(model._info.agent_version) < "3.3.0": pytest.skip("Juju too old, need Secrets API v2") - secret = await model.add_secret(name='my-apitoken', data_args=['token=34ae35facd4']) - assert secret.startswith('secret:') + secret = await model.add_secret( + name="my-apitoken", data_args=["token=34ae35facd4"] + ) + assert secret.startswith("secret:") - await model.deploy('ubuntu') + await model.deploy("ubuntu") - await model.grant_secret('my-apitoken', 'ubuntu') + await model.grant_secret("my-apitoken", "ubuntu") @base.bootstrapped @@ -105,6 +113,8 @@ async def test_revoke_secret(): if str(model._info.agent_version) < "3.3.0": pytest.skip("Juju too old, need Secrets API v2") - secret = await model.add_secret(name='my-apitoken', data_args=['token=34ae35facd4']) - assert secret.startswith('secret:') - await model.revoke_secret('my-apitoken', 'ubuntu') + secret = await model.add_secret( + name="my-apitoken", data_args=["token=34ae35facd4"] + ) + assert secret.startswith("secret:") + await model.revoke_secret("my-apitoken", "ubuntu") diff --git a/tests/integration/test_unit.py b/tests/integration/test_unit.py index d9928e36a..a510f3315 100644 --- a/tests/integration/test_unit.py +++ b/tests/integration/test_unit.py @@ -15,29 +15,29 @@ async def test_block_coroutine(): async with base.CleanModel() as model: app = await model.deploy( - 'ubuntu', - application_name='ubuntu', - series='jammy', - channel='stable', + "ubuntu", + application_name="ubuntu", + series="jammy", + channel="stable", num_units=3, ) async def is_leader_elected(): return any([await u.is_leader_from_status() for u in app.units]) - await utils.block_until_with_coroutine(is_leader_elected, - timeout=480, - wait_period=5) + await utils.block_until_with_coroutine( + is_leader_elected, timeout=480, wait_period=5 + ) @base.bootstrapped async def test_unit_public_address(): async with base.CleanModel() as model: app = await model.deploy( - 'ubuntu', - application_name='ubuntu', - series='jammy', - channel='stable', + "ubuntu", + application_name="ubuntu", + series="jammy", + channel="stable", num_units=1, ) @@ -48,14 +48,16 @@ async def test_unit_public_address(): assert len(app.units) >= 1 unit = app.units[0] - await asyncio.wait_for( - model.block_until(lambda: unit.machine), - timeout=60) + await asyncio.wait_for(model.block_until(lambda: unit.machine), timeout=60) machine = unit.machine await asyncio.wait_for( - model.block_until(lambda: (machine.status == 'running' and - machine.agent_status == 'started')), - timeout=480) + model.block_until( + lambda: ( + machine.status == "running" and machine.agent_status == "started" + ) + ), + timeout=480, + ) for unit in app.units: addr = await unit.get_public_address() @@ -68,91 +70,92 @@ async def test_run(): async with base.CleanModel() as model: app = await model.deploy( - 'ubuntu', - application_name='ubuntu', - series='jammy', - channel='stable', + "ubuntu", + application_name="ubuntu", + series="jammy", + channel="stable", ) await model.wait_for_idle(status="active") for unit in app.units: - action1 = await unit.run('unit-get public-address') + action1 = await unit.run("unit-get public-address") assert isinstance(action1, Action) - assert action1.status == 'pending' + assert action1.status == "pending" await action1.wait() - assert action1.status == 'completed' + assert action1.status == "completed" break for unit in app.units: - action2 = await unit.run('sleep 3', timeout=1) + action2 = await unit.run("sleep 3", timeout=1) assert isinstance(action2, Action) await action2.wait() - assert action2.status == 'failed' + assert action2.status == "failed" break for unit in app.units: - action3 = await unit.run('sleep 1', timeout=3) + action3 = await unit.run("sleep 1", timeout=3) assert isinstance(action3, Action) await action3.wait() - assert action3.status == 'completed' + assert action3.status == "completed" break unit = app.units[0] action4 = await unit.run("df -h", timeout=None) - assert action4.status == 'pending' + assert action4.status == "pending" action5 = await action4.wait() assert action4 is action5 - assert action5.status == 'completed' + assert action5.status == "completed" assert action5.results - assert action5.results['return-code'] == 0 + assert action5.results["return-code"] == 0 @base.bootstrapped async def test_run_action(): - pytest.skip('Find a better charm for this test') + pytest.skip("Find a better charm for this test") async def run_action(unit): # unit.run() returns a juju.action.Action instance - action = await unit.run_action('add-repo', repo='myrepo') + action = await unit.run_action("add-repo", repo="myrepo") # wait for the action to complete return await action.wait() def check_results(results, out): - assert 'dir' in results - assert 'stdout' in results or 'Stdout' in results - assert 'Code' in results or 'return-code' in results - if 'Code' in results: - assert results['Code'] == 0 + assert "dir" in results + assert "stdout" in results or "Stdout" in results + assert "Code" in results or "return-code" in results + if "Code" in results: + assert results["Code"] == 0 else: - assert results['return-code'] == 0 + assert results["return-code"] == 0 - if 'stdout' in results: - assert results['stdout'] == out + if "stdout" in results: + assert results["stdout"] == out else: - assert results['Stdout'] == out - assert results['dir'] == '/var/git/myrepo.git' + assert results["Stdout"] == out + assert results["dir"] == "/var/git/myrepo.git" async with base.CleanModel() as model: app = await model.deploy( - 'git', - application_name='git', - series='trusty', - channel='stable', + "git", + application_name="git", + series="trusty", + channel="stable", ) for unit in app.units: action = await run_action(unit) - out = "Adding group `myrepo' (GID 1001) ...\n" \ - 'Done.\n' \ - 'Initialized empty Git repository in ' \ - '/var/git/myrepo.git/\n' + out = ( + "Adding group `myrepo' (GID 1001) ...\n" + "Done.\n" + "Initialized empty Git repository in " + "/var/git/myrepo.git/\n" + ) check_results(action.results, out) output = await model.get_action_output(action.entity_id, wait=5) check_results(output, out) - status = await model.get_action_status( - uuid_or_prefix=action.entity_id) - assert status[action.entity_id] == 'completed' + status = await model.get_action_status(uuid_or_prefix=action.entity_id) + assert status[action.entity_id] == "completed" break @@ -162,31 +165,31 @@ async def test_scp(): try: asyncio.get_child_watcher().attach_loop(jasyncio.get_running_loop()) except RuntimeError: - pytest.skip('test_scp will always fail outside of MainThread') + pytest.skip("test_scp will always fail outside of MainThread") async with base.CleanModel() as model: - app = await model.deploy('ubuntu', channel='stable') + app = await model.deploy("ubuntu", channel="stable") - await asyncio.wait_for( - model.block_until(lambda: app.units), - timeout=60) + await asyncio.wait_for(model.block_until(lambda: app.units), timeout=60) unit = app.units[0] - await asyncio.wait_for( - model.block_until(lambda: unit.machine), - timeout=60) + await asyncio.wait_for(model.block_until(lambda: unit.machine), timeout=60) machine = unit.machine await asyncio.wait_for( - model.block_until(lambda: (machine.status == 'running' and - machine.agent_status == 'started')), - timeout=480) + model.block_until( + lambda: ( + machine.status == "running" and machine.agent_status == "started" + ) + ), + timeout=480, + ) with NamedTemporaryFile() as f: - f.write(b'testcontents') + f.write(b"testcontents") f.flush() - await unit.scp_to(f.name, 'testfile') + await unit.scp_to(f.name, "testfile") with NamedTemporaryFile() as f: - await unit.scp_from('testfile', f.name) - assert f.read() == b'testcontents' + await unit.scp_from("testfile", f.name) + assert f.read() == b"testcontents" @base.bootstrapped @@ -195,79 +198,81 @@ async def test_ssh(): try: asyncio.get_child_watcher().attach_loop(jasyncio.get_running_loop()) except RuntimeError: - pytest.skip('test_ssh will always fail outside of MainThread') + pytest.skip("test_ssh will always fail outside of MainThread") async with base.CleanModel() as model: - app = await model.deploy('ubuntu', channel='stable') + app = await model.deploy("ubuntu", channel="stable") - await asyncio.wait_for( - model.block_until(lambda: app.units), - timeout=60) + await asyncio.wait_for(model.block_until(lambda: app.units), timeout=60) unit = app.units[0] - await asyncio.wait_for( - model.block_until(lambda: unit.machine), - timeout=60) + await asyncio.wait_for(model.block_until(lambda: unit.machine), timeout=60) machine = unit.machine await asyncio.wait_for( - model.block_until(lambda: (machine.status == 'running' and - machine.agent_status == 'started')), - timeout=480) + model.block_until( + lambda: ( + machine.status == "running" and machine.agent_status == "started" + ) + ), + timeout=480, + ) output = await unit.ssh("echo test") - assert 'test' in output + assert "test" in output @base.bootstrapped async def test_resolve_local(): - charm_file = Path(__file__).absolute().parent / 'charm.charm' + charm_file = Path(__file__).absolute().parent / "charm.charm" async with base.CleanModel() as model: app = await model.deploy( str(charm_file), - config={'status': 'error'}, + config={"status": "error"}, ) try: await model.wait_for_idle(raise_on_error=False, idle_period=1) - assert app.units[0].workload_status == 'error' + assert app.units[0].workload_status == "error" await app.units[0].resolved() await model.wait_for_idle(raise_on_error=False) - assert app.units[0].workload_status == 'active' + assert app.units[0].workload_status == "active" finally: # Errored units won't get cleaned up unless we force them. - await asyncio.gather(*(machine.destroy(force=True) - for machine in model.machines.values())) + await asyncio.gather( + *(machine.destroy(force=True) for machine in model.machines.values()) + ) @base.bootstrapped async def test_unit_introspect(): async with base.CleanModel() as model: - await model.deploy('ubuntu', series='jammy') + await model.deploy("ubuntu", series="jammy") await model.wait_for_idle(status="active") - await model.deploy('juju-introspect', - channel='edge', - series='jammy', - to='0', - ) + await model.deploy( + "juju-introspect", + channel="edge", + series="jammy", + to="0", + ) @base.bootstrapped async def test_subordinate_units(): async with base.CleanModel() as model: - u_app = await model.deploy('ubuntu') - n_app = await model.deploy('ntp') - await model.relate('ubuntu', 'ntp') + u_app = await model.deploy("ubuntu") + n_app = await model.deploy("ntp") + await model.relate("ubuntu", "ntp") await model.wait_for_idle() # model subordinates model_subs = model.subordinate_units assert len(model_subs) == 1 - assert 'ntp/0' in model_subs - assert 'ubuntu/0' not in model_subs + assert "ntp/0" in model_subs + assert "ubuntu/0" not in model_subs - n_unit = model_subs['ntp/0'] + n_unit = model_subs["ntp/0"] u_unit = u_app.units[0] # application subordinates @@ -277,8 +282,8 @@ async def test_subordinate_units(): assert n_unit.is_subordinate assert not u_unit.is_subordinate - assert n_unit.principal_unit == 'ubuntu/0' - assert u_unit.principal_unit == '' + assert n_unit.principal_unit == "ubuntu/0" + assert u_unit.principal_unit == "" assert [u.name for u in u_unit.get_subordinates()] == [n_unit.name] @@ -286,8 +291,8 @@ async def test_subordinate_units(): async def test_destroy_unit(): async with base.CleanModel() as model: app = await model.deploy( - 'juju-qa-test', - application_name='test', + "juju-qa-test", + application_name="test", num_units=3, ) # wait for the units to come up diff --git a/tests/unit/test_application.py b/tests/unit/test_application.py index 927be142a..5e8fc994d 100644 --- a/tests/unit/test_application.py +++ b/tests/unit/test_application.py @@ -28,21 +28,18 @@ async def test_expose_with_exposed_endpoints_as_raw_dict(self, mock_conn): # expose change, it gets correctly converted to ExposedEndpoint values, # validated and converted to a dictionary with the right format before # it gets passed to the facade. - await app.expose(exposed_endpoints={ - "": { - "expose-to-spaces": ["alpha"], - "expose-to-cidrs": ["0.0.0.0/0"] + await app.expose( + exposed_endpoints={ + "": {"expose-to-spaces": ["alpha"], "expose-to-cidrs": ["0.0.0.0/0"]} } - }) + ) mock_facade().Expose.assert_called_once_with( application="app-id", exposed_endpoints={ - "": { - "expose-to-spaces": ["alpha"], - "expose-to-cidrs": ["0.0.0.0/0"] - } - }) + "": {"expose-to-spaces": ["alpha"], "expose-to-cidrs": ["0.0.0.0/0"]} + }, + ) @mock.patch("juju.model.Model.connection") async def test_expose_with_exposed_endpoints(self, mock_conn): @@ -58,26 +55,26 @@ async def test_expose_with_exposed_endpoints(self, mock_conn): # Check that if we pass a dict with ExposedEndpoint values, they get # validated and converted to a dictionary with the right format before # it gets passed to the facade. - await app.expose(exposed_endpoints={ - "": ExposedEndpoint(to_spaces=["alpha"], to_cidrs=["0.0.0.0/0"]), - "x": ExposedEndpoint(to_spaces=["beta"]), - "y": ExposedEndpoint(to_cidrs=["10.0.0.0/24"]) - }) + await app.expose( + exposed_endpoints={ + "": ExposedEndpoint(to_spaces=["alpha"], to_cidrs=["0.0.0.0/0"]), + "x": ExposedEndpoint(to_spaces=["beta"]), + "y": ExposedEndpoint(to_cidrs=["10.0.0.0/24"]), + } + ) mock_facade().Expose.assert_called_once_with( application="app-id", exposed_endpoints={ - "": { - "expose-to-spaces": ["alpha"], - "expose-to-cidrs": ["0.0.0.0/0"] - }, + "": {"expose-to-spaces": ["alpha"], "expose-to-cidrs": ["0.0.0.0/0"]}, "x": { "expose-to-spaces": ["beta"], }, "y": { "expose-to-cidrs": ["10.0.0.0/24"], }, - }) + }, + ) @mock.patch("juju.model.Model.connection") async def test_expose_endpoints_on_older_controller(self, mock_conn): @@ -95,30 +92,38 @@ async def test_expose_endpoints_on_older_controller(self, mock_conn): # Case 1: exposed_endpoints includes an entry with a space list. with self.assertRaises(JujuError): - await app.expose(exposed_endpoints={ - "": ExposedEndpoint(to_spaces=["alpha"]), - }) + await app.expose( + exposed_endpoints={ + "": ExposedEndpoint(to_spaces=["alpha"]), + } + ) # Case 2: exposed_endpoints only includes the wildcard endpoints key # with a non-wildcard CIDR. with self.assertRaises(JujuError): - await app.expose(exposed_endpoints={ - "": ExposedEndpoint(to_cidrs=["0.0.0.0/0", "10.0.0.0/24"]), - }) + await app.expose( + exposed_endpoints={ + "": ExposedEndpoint(to_cidrs=["0.0.0.0/0", "10.0.0.0/24"]), + } + ) # Case 3: exposed_endpoints has a single entry for the # non-wildcard endpoint. with self.assertRaises(JujuError): - await app.expose(exposed_endpoints={ - "": ExposedEndpoint(to_cidrs=["0.0.0.0/0", "10.0.0.0/24"]), - }) + await app.expose( + exposed_endpoints={ + "": ExposedEndpoint(to_cidrs=["0.0.0.0/0", "10.0.0.0/24"]), + } + ) # Case 4: exposed_endpoints has multiple keys. with self.assertRaises(JujuError): - await app.expose(exposed_endpoints={ - "foo": ExposedEndpoint(to_cidrs=["0.0.0.0/0"]), - "bar": ExposedEndpoint(to_spaces=["alpha"]), - }) + await app.expose( + exposed_endpoints={ + "foo": ExposedEndpoint(to_cidrs=["0.0.0.0/0"]), + "bar": ExposedEndpoint(to_spaces=["alpha"]), + } + ) # Check that we call the facade with the right arity. await app.expose() @@ -160,8 +165,7 @@ async def test_unexpose_endpoints_on_29_controller(self, mock_conn): await app.unexpose(exposed_endpoints=["alpha", "beta"]) mock_facade().Unexpose.assert_called_once_with( - application="app-id", - exposed_endpoints=["alpha", "beta"] + application="app-id", exposed_endpoints=["alpha", "beta"] ) diff --git a/tests/unit/test_bundle.py b/tests/unit/test_bundle.py index a6f69a80f..268a0d73a 100644 --- a/tests/unit/test_bundle.py +++ b/tests/unit/test_bundle.py @@ -30,7 +30,6 @@ class TestChangeSet(unittest.TestCase): - def test_sort_empty_changes(self): changeset = ChangeSet([]) result = changeset.sorted() @@ -70,73 +69,100 @@ def test_sort_causes_circular_error(self): class TestAddApplicationChange(unittest.TestCase): - def test_method(self): self.assertEqual("deploy", AddApplicationChange.method()) def test_dict_params(self): - change = AddApplicationChange(1, [], params={"charm": "charm", - "series": "series", - "application": "application", - "options": "options", - "constraints": "constraints", - "storage": "storage", - "endpoint-bindings": "endpoint_bindings", - "resources": "resources", - "devices": "devices", - "num-units": "num_units", - "channel": "channel"}) - self.assertEqual({"change_id": 1, - "requires": [], - "charm": "charm", - "series": "series", - "application": "application", - "options": "options", - "constraints": "constraints", - "storage": "storage", - "endpoint_bindings": "endpoint_bindings", - "resources": "resources", - "devices": "devices", - "num_units": "num_units", - "channel": "channel"}, change.__dict__) + change = AddApplicationChange( + 1, + [], + params={ + "charm": "charm", + "series": "series", + "application": "application", + "options": "options", + "constraints": "constraints", + "storage": "storage", + "endpoint-bindings": "endpoint_bindings", + "resources": "resources", + "devices": "devices", + "num-units": "num_units", + "channel": "channel", + }, + ) + self.assertEqual( + { + "change_id": 1, + "requires": [], + "charm": "charm", + "series": "series", + "application": "application", + "options": "options", + "constraints": "constraints", + "storage": "storage", + "endpoint_bindings": "endpoint_bindings", + "resources": "resources", + "devices": "devices", + "num_units": "num_units", + "channel": "channel", + }, + change.__dict__, + ) def test_dict_params_missing_data(self): - change = AddApplicationChange(1, [], params={"charm": "charm", - "series": "series", - "application": "application", - "options": "options", - "constraints": "constraints", - "storage": "storage"}) - self.assertEqual({"change_id": 1, - "requires": [], - "charm": "charm", - "series": "series", - "application": "application", - "options": "options", - "constraints": "constraints", - "storage": "storage", - "endpoint_bindings": None, - "resources": None, - "devices": None, - "num_units": None, - "channel": None}, change.__dict__) + change = AddApplicationChange( + 1, + [], + params={ + "charm": "charm", + "series": "series", + "application": "application", + "options": "options", + "constraints": "constraints", + "storage": "storage", + }, + ) + self.assertEqual( + { + "change_id": 1, + "requires": [], + "charm": "charm", + "series": "series", + "application": "application", + "options": "options", + "constraints": "constraints", + "storage": "storage", + "endpoint_bindings": None, + "resources": None, + "devices": None, + "num_units": None, + "channel": None, + }, + change.__dict__, + ) class TestAddApplicationChangeRun: async def test_run_with_charmhub_charm(self): storage_label = "some-label" storage_constraint = "ebs,100G,1" - change = AddApplicationChange(1, [], params={"charm": "charm", - "series": "series", - "application": "application", - "options": "options", - "constraints": "constraints", - "storage": {storage_label: storage_constraint}, - "endpoint-bindings": "endpoint_bindings", - "resources": "resources", - "devices": "devices", - "num-units": "num_units", - "channel": "channel"}) + change = AddApplicationChange( + 1, + [], + params={ + "charm": "charm", + "series": "series", + "application": "application", + "options": "options", + "constraints": "constraints", + "storage": {storage_label: storage_constraint}, + "endpoint-bindings": "endpoint_bindings", + "resources": "resources", + "devices": "devices", + "num-units": "num_units", + "channel": "channel", + }, + ) model = Mock() model._deploy = mock.AsyncMock(return_value=None) @@ -151,51 +177,69 @@ async def test_run_with_charmhub_charm(self): info_func = mock.AsyncMock(return_value=["12345", "name"]) - with patch.object(charmhub.CharmHub, 'get_charm_id', info_func): + with patch.object(charmhub.CharmHub, "get_charm_id", info_func): result = await change.run(context) assert result == "application" model._deploy.assert_called_once() - model._deploy.assert_called_with(charm_url="ch:charm1", - application="application", - series="series", - config="options", - constraints="constraints", - endpoint_bindings="endpoint_bindings", - resources=["resource1"], - storage={storage_label: constraints.parse_storage_constraint(storage_constraint)}, - devices="devices", - channel="channel", - charm_origin=ANY, - num_units="num_units") + model._deploy.assert_called_with( + charm_url="ch:charm1", + application="application", + series="series", + config="options", + constraints="constraints", + endpoint_bindings="endpoint_bindings", + resources=["resource1"], + storage={ + storage_label: constraints.parse_storage_constraint(storage_constraint) + }, + devices="devices", + channel="channel", + charm_origin=ANY, + num_units="num_units", + ) async def test_run_with_storage_variations(self): """Test that various valid storage constraints are parsed as expected before model._deploy is called. Uses the mock call logic from test_run_with_charmhub_charm, which will run before this test. """ - storage_arg_pairs: List[Tuple[Dict[str, str], Dict[str, constraints.StorageConstraintDict]]] = [ + storage_arg_pairs: List[ + Tuple[Dict[str, str], Dict[str, constraints.StorageConstraintDict]] + ] = [ # (storage_arg_for_change, storage_arg_for_deploy) - ({'some-label': 'ebs,100G,1'}, {'some-label': {'count': 1, 'pool': 'ebs', 'size': 102400}}), - ({'some-label': 'ebs,2.1G,3'}, {'some-label': {'count': 3, 'pool': 'ebs', 'size': 2150}}), - ({'some-label': 'ebs,100G'}, {'some-label': {'count': 1, 'pool': 'ebs', 'size': 102400}}), - ({'some-label': 'ebs,2'}, {'some-label': {'count': 2, 'pool': 'ebs'}}), - ({'some-label': '200G,7'}, {'some-label': {'count': 7, 'size': 204800}}), - ({'some-label': 'ebs'}, {'some-label': {'count': 1, 'pool': 'ebs'}}), - ({'some-label': '10YB'}, {'some-label': {'count': 1, 'size': 11529215046068469760}}), - ({'some-label': '1'}, {'some-label': {'count': 1}}), - ({'some-label': '-1'}, {'some-label': {'count': 1}}), - ({'some-label': ''}, {'some-label': {'count': 1}}), + ( + {"some-label": "ebs,100G,1"}, + {"some-label": {"count": 1, "pool": "ebs", "size": 102400}}, + ), + ( + {"some-label": "ebs,2.1G,3"}, + {"some-label": {"count": 3, "pool": "ebs", "size": 2150}}, + ), + ( + {"some-label": "ebs,100G"}, + {"some-label": {"count": 1, "pool": "ebs", "size": 102400}}, + ), + ({"some-label": "ebs,2"}, {"some-label": {"count": 2, "pool": "ebs"}}), + ({"some-label": "200G,7"}, {"some-label": {"count": 7, "size": 204800}}), + ({"some-label": "ebs"}, {"some-label": {"count": 1, "pool": "ebs"}}), + ( + {"some-label": "10YB"}, + {"some-label": {"count": 1, "size": 11529215046068469760}}, + ), + ({"some-label": "1"}, {"some-label": {"count": 1}}), + ({"some-label": "-1"}, {"some-label": {"count": 1}}), + ({"some-label": ""}, {"some-label": {"count": 1}}), ( { - 'some-label': '2.1G,3', - 'data': '1MiB,70', - 'logs': 'ebs,-1', + "some-label": "2.1G,3", + "data": "1MiB,70", + "logs": "ebs,-1", }, { - 'some-label': {'count': 3, 'size': 2150}, - 'data': {'count': 70, 'size': 1}, - 'logs': {'count': 1, 'pool': 'ebs'} + "some-label": {"count": 3, "size": 2150}, + "data": {"count": 70, "size": 1}, + "logs": {"count": 1, "pool": "ebs"}, }, ), ] @@ -231,7 +275,7 @@ async def test_run_with_storage_variations(self): # mock info_func info_func = mock.AsyncMock(return_value=["12345", "name"]) # patch and call - with patch.object(charmhub.CharmHub, 'get_charm_id', info_func): + with patch.object(charmhub.CharmHub, "get_charm_id", info_func): result = await change.run(context) assert result == "application" # asserts @@ -253,22 +297,27 @@ async def test_run_with_storage_variations(self): async def test_run_with_charmhub_charm_no_channel(self): """Test to verify if when the given channel is None, the channel defaults to "local/stable", which - is the default channel value for the Charm Hub + is the default channel value for the Charm Hub """ storage_label = "some-label" storage_constraint = "ebs,100G,1" - change = AddApplicationChange(1, [], params={"charm": "charm", - "series": "series", - "application": "application", - "options": "options", - "constraints": "constraints", - "storage": {storage_label: storage_constraint}, - "endpoint-bindings": "endpoint_bindings", - "resources": "resources", - "devices": "devices", - "num-units": "num_units", - "channel": None - }) + change = AddApplicationChange( + 1, + [], + params={ + "charm": "charm", + "series": "series", + "application": "application", + "options": "options", + "constraints": "constraints", + "storage": {storage_label: storage_constraint}, + "endpoint-bindings": "endpoint_bindings", + "resources": "resources", + "devices": "devices", + "num-units": "num_units", + "channel": None, + }, + ) model = Mock() model._deploy = mock.AsyncMock(return_value=None) @@ -283,36 +332,46 @@ async def test_run_with_charmhub_charm_no_channel(self): info_func = mock.AsyncMock(return_value=["12345", "name"]) - with patch.object(charmhub.CharmHub, 'get_charm_id', info_func): + with patch.object(charmhub.CharmHub, "get_charm_id", info_func): result = await change.run(context) assert result == "application" model._deploy.assert_called_once() - model._deploy.assert_called_with(charm_url="ch:charm1", - application="application", - series="series", - config="options", - constraints="constraints", - endpoint_bindings="endpoint_bindings", - resources=["resource1"], - storage={storage_label: constraints.parse_storage_constraint(storage_constraint)}, - devices="devices", - channel="latest/stable", - charm_origin=ANY, - num_units="num_units") + model._deploy.assert_called_with( + charm_url="ch:charm1", + application="application", + series="series", + config="options", + constraints="constraints", + endpoint_bindings="endpoint_bindings", + resources=["resource1"], + storage={ + storage_label: constraints.parse_storage_constraint(storage_constraint) + }, + devices="devices", + channel="latest/stable", + charm_origin=ANY, + num_units="num_units", + ) async def test_run_local(self): storage_label = "some-label" storage_constraint = "ebs,100G,1" - change = AddApplicationChange(1, [], params={"charm": "local:charm", - "series": "series", - "application": "application", - "options": "options", - "constraints": "constraints", - "storage": {storage_label: storage_constraint}, - "endpoint-bindings": "endpoint_bindings", - "devices": "devices", - "num-units": "num_units"}) + change = AddApplicationChange( + 1, + [], + params={ + "charm": "local:charm", + "series": "series", + "application": "application", + "options": "options", + "constraints": "constraints", + "storage": {storage_label: storage_constraint}, + "endpoint-bindings": "endpoint_bindings", + "devices": "devices", + "num-units": "num_units", + }, + ) model = mock.Mock() model._deploy = mock.AsyncMock(return_value=None) @@ -328,33 +387,43 @@ async def test_run_local(self): assert result == "application" model._deploy.assert_called_once() - model._deploy.assert_called_with(charm_url="local:charm1", - application="application", - series="series", - config="options", - constraints="constraints", - endpoint_bindings="endpoint_bindings", - resources={}, - storage={storage_label: constraints.parse_storage_constraint(storage_constraint)}, - devices="devices", - num_units="num_units", - channel="", - charm_origin=ANY) + model._deploy.assert_called_with( + charm_url="local:charm1", + application="application", + series="series", + config="options", + constraints="constraints", + endpoint_bindings="endpoint_bindings", + resources={}, + storage={ + storage_label: constraints.parse_storage_constraint(storage_constraint) + }, + devices="devices", + num_units="num_units", + channel="", + charm_origin=ANY, + ) async def test_run_no_series(self): storage_label = "some-label" storage_constraint = "ebs,100G,1" - change = AddApplicationChange(1, [], params={"charm": "ch:charm1", - "series": "", - "application": "application", - "options": "options", - "constraints": "constraints", - "storage": {storage_label: storage_constraint}, - "endpoint-bindings": "endpoint_bindings", - "resources": "resources", - "devices": "devices", - "num-units": "num_units", - "channel": "channel"}) + change = AddApplicationChange( + 1, + [], + params={ + "charm": "ch:charm1", + "series": "", + "application": "application", + "options": "options", + "constraints": "constraints", + "storage": {storage_label: storage_constraint}, + "endpoint-bindings": "endpoint_bindings", + "resources": "resources", + "devices": "devices", + "num-units": "num_units", + "channel": "channel", + }, + ) model = mock.Mock() model._deploy = mock.AsyncMock(return_value=None) @@ -373,18 +442,22 @@ async def test_run_no_series(self): model._add_charmhub_resources.assert_called_once() model._deploy.assert_called_once() - model._deploy.assert_called_with(charm_url="ch:charm1", - application="application", - series=None, - config="options", - constraints="constraints", - endpoint_bindings="endpoint_bindings", - resources=["resource1"], - storage={storage_label: constraints.parse_storage_constraint(storage_constraint)}, - devices="devices", - channel="channel", - charm_origin=ANY, - num_units="num_units") + model._deploy.assert_called_with( + charm_url="ch:charm1", + application="application", + series=None, + config="options", + constraints="constraints", + endpoint_bindings="endpoint_bindings", + resources=["resource1"], + storage={ + storage_label: constraints.parse_storage_constraint(storage_constraint) + }, + devices="devices", + channel="channel", + charm_origin=ANY, + num_units="num_units", + ) # confirm that it's idempotent model.applications = {"application": None} @@ -395,42 +468,55 @@ async def test_run_no_series(self): class TestAddCharmChange(unittest.TestCase): - def test_method(self): self.assertEqual("addCharm", AddCharmChange.method()) def test_dict_params(self): - change = AddCharmChange(1, [], params={"charm": "charm", - "series": "series", - "channel": "channel", - "revision": "revision", - "architecture": "architecture"}) - self.assertEqual({"change_id": 1, - "requires": [], - "charm": "charm", - "series": "series", - "channel": "channel", - "revision": "revision", - "architecture": "architecture"}, change.__dict__) + change = AddCharmChange( + 1, + [], + params={ + "charm": "charm", + "series": "series", + "channel": "channel", + "revision": "revision", + "architecture": "architecture", + }, + ) + self.assertEqual( + { + "change_id": 1, + "requires": [], + "charm": "charm", + "series": "series", + "channel": "channel", + "revision": "revision", + "architecture": "architecture", + }, + change.__dict__, + ) def test_dict_params_missing_data(self): - change = AddCharmChange(1, [], params={"charm": "charm", - "series": "series"}) - self.assertEqual({"change_id": 1, - "requires": [], - "charm": "charm", - "series": "series", - "channel": None, - "revision": None, - "architecture": None}, change.__dict__) + change = AddCharmChange(1, [], params={"charm": "charm", "series": "series"}) + self.assertEqual( + { + "change_id": 1, + "requires": [], + "charm": "charm", + "series": "series", + "channel": None, + "revision": None, + "architecture": None, + }, + change.__dict__, + ) class TestAddCharmChangeRun: - async def test_run(self): - change = AddCharmChange(1, [], params={"charm": "ch:charm", - "series": "jammy", - "channel": "channel"}) + change = AddCharmChange( + 1, [], params={"charm": "ch:charm", "series": "jammy", "channel": "channel"} + ) charms_facade = mock.Mock() charms_facade.AddCharm = mock.AsyncMock(return_value=None) @@ -438,8 +524,7 @@ async def test_run(self): model = mock.Mock() model._add_charm = mock.AsyncMock(return_value=None) model._resolve_architecture = mock.AsyncMock(return_value=None) - model._resolve_charm = mock.AsyncMock(return_value=("entity_id", - None)) + model._resolve_charm = mock.AsyncMock(return_value=("entity_id", None)) context = mock.Mock() @@ -452,46 +537,74 @@ async def test_run(self): class TestAddMachineChange(unittest.TestCase): - def test_method(self): self.assertEqual("addMachines", AddMachineChange.method()) def test_dict_params(self): - change = AddMachineChange(1, [], params={"series": "series", - "constraints": "constraints", - "container-type": "container_type", - "parent-id": "parent_id"}) - self.assertEqual({"change_id": 1, - "requires": [], - "series": "series", - "constraints": "constraints", - "container_type": "container_type", - "parent_id": "parent_id"}, change.__dict__) + change = AddMachineChange( + 1, + [], + params={ + "series": "series", + "constraints": "constraints", + "container-type": "container_type", + "parent-id": "parent_id", + }, + ) + self.assertEqual( + { + "change_id": 1, + "requires": [], + "series": "series", + "constraints": "constraints", + "container_type": "container_type", + "parent_id": "parent_id", + }, + change.__dict__, + ) def test_dict_params_missing_data(self): - change = AddMachineChange(1, [], params={"series": "series", - "constraints": "constraints", - "container-type": "container_type"}) - self.assertEqual({"change_id": 1, - "requires": [], - "series": "series", - "constraints": "constraints", - "container_type": "container_type", - "parent_id": None}, change.__dict__) + change = AddMachineChange( + 1, + [], + params={ + "series": "series", + "constraints": "constraints", + "container-type": "container_type", + }, + ) + self.assertEqual( + { + "change_id": 1, + "requires": [], + "series": "series", + "constraints": "constraints", + "container_type": "container_type", + "parent_id": None, + }, + change.__dict__, + ) class TestAddMachineChangeRun: - async def test_run(self): - change = AddMachineChange(1, [], params={"series": "series", - "constraints": "cores=1", - "container-type": "container_type", - "parent-id": "parent_id"}) + change = AddMachineChange( + 1, + [], + params={ + "series": "series", + "constraints": "cores=1", + "container-type": "container_type", + "parent-id": "parent_id", + }, + ) machines = [client.AddMachinesResult(machine="machine1")] machine_manager_facade = mock.Mock() - machine_manager_facade.AddMachines = mock.AsyncMock(return_value=client.AddMachinesResults(machines)) + machine_manager_facade.AddMachines = mock.AsyncMock( + return_value=client.AddMachinesResults(machines) + ) context = mock.Mock() context.resolve.return_value = "parent_id1" @@ -501,38 +614,55 @@ async def test_run(self): assert result == "machine1" machine_manager_facade.AddMachines.assert_called_once() - machine_manager_facade.AddMachines.assert_called_with(params=[client.AddMachineParams(series="series", - constraints="{\"cores\":1}", - container_type="container_type", - parent_id="parent_id1", - jobs=["JobHostUnits"])]) + machine_manager_facade.AddMachines.assert_called_with( + params=[ + client.AddMachineParams( + series="series", + constraints='{"cores":1}', + container_type="container_type", + parent_id="parent_id1", + jobs=["JobHostUnits"], + ) + ] + ) class TestAddRelationChange(unittest.TestCase): - def test_method(self): self.assertEqual("addRelation", AddRelationChange.method()) def test_dict_params(self): - change = AddRelationChange(1, [], params={"endpoint1": "endpoint1", - "endpoint2": "endpoint2"}) - self.assertEqual({"change_id": 1, - "requires": [], - "endpoint1": "endpoint1", - "endpoint2": "endpoint2"}, change.__dict__) + change = AddRelationChange( + 1, [], params={"endpoint1": "endpoint1", "endpoint2": "endpoint2"} + ) + self.assertEqual( + { + "change_id": 1, + "requires": [], + "endpoint1": "endpoint1", + "endpoint2": "endpoint2", + }, + change.__dict__, + ) def test_dict_params_missing_data(self): change = AddRelationChange(1, [], params={"endpoint1": "endpoint1"}) - self.assertEqual({"change_id": 1, - "requires": [], - "endpoint1": "endpoint1", - "endpoint2": None}, change.__dict__) + self.assertEqual( + { + "change_id": 1, + "requires": [], + "endpoint1": "endpoint1", + "endpoint2": None, + }, + change.__dict__, + ) class TestAddRelationChangeRun: async def test_run(self): - change = AddRelationChange(1, [], params={"endpoint1": "endpoint1", - "endpoint2": "endpoint2"}) + change = AddRelationChange( + 1, [], params={"endpoint1": "endpoint1", "endpoint2": "endpoint2"} + ) rel1 = mock.Mock(name="rel1", **{"matches.return_value": False}) rel2 = mock.Mock(name="rel2", **{"matches.return_value": True}) @@ -541,7 +671,7 @@ async def test_run(self): model.relate = mock.AsyncMock(return_value=rel2) context = mock.Mock() - context.resolve_relation = mock.Mock(side_effect=['endpoint_1', 'endpoint_2']) + context.resolve_relation = mock.Mock(side_effect=["endpoint_1", "endpoint_2"]) context.model = model model.relations = [rel1] @@ -552,7 +682,7 @@ async def test_run(self): model.relate.assert_called_with("endpoint_1", "endpoint_2") # confirm that it's idempotent - context.resolve_relation = mock.Mock(side_effect=['endpoint_1', 'endpoint_2']) + context.resolve_relation = mock.Mock(side_effect=["endpoint_1", "endpoint_2"]) model.relate.reset_mock() model.relate.return_value = None model.relations = [rel1, rel2] @@ -562,28 +692,25 @@ async def test_run(self): class TestAddUnitChange(unittest.TestCase): - def test_method(self): self.assertEqual("addUnit", AddUnitChange.method()) def test_dict_params(self): - change = AddUnitChange(1, [], params={"application": "application", - "to": "to"}) - self.assertEqual({"change_id": 1, - "requires": [], - "application": "application", - "to": "to"}, change.__dict__) + change = AddUnitChange(1, [], params={"application": "application", "to": "to"}) + self.assertEqual( + {"change_id": 1, "requires": [], "application": "application", "to": "to"}, + change.__dict__, + ) def test_dict_params_missing_data(self): change = AddUnitChange(1, [], params={"application": "application"}) - self.assertEqual({"change_id": 1, - "requires": [], - "application": "application", - "to": None}, change.__dict__) + self.assertEqual( + {"change_id": 1, "requires": [], "application": "application", "to": None}, + change.__dict__, + ) class MockModel: - def __init__(self, app): self.app = app @@ -593,10 +720,8 @@ def applications(self): class TestAddUnitChangeRun: - async def test_run(self): - change = AddUnitChange(1, [], params={"application": "application", - "to": "to"}) + change = AddUnitChange(1, [], params={"application": "application", "to": "to"}) app = mock.Mock() app.add_unit = mock.AsyncMock(return_value="unit1") @@ -604,7 +729,7 @@ async def test_run(self): model = MockModel({"application1": app}) context = mock.Mock() - context.resolve = mock.Mock(side_effect=['application1', 'to1']) + context.resolve = mock.Mock(side_effect=["application1", "to1"]) context._units_by_app = {} context.model = model @@ -612,163 +737,185 @@ async def test_run(self): assert result == "unit1" model.applications["application1"].add_unit.assert_called_once() - model.applications["application1"].add_unit.assert_called_with(count=1, to="to1") + model.applications["application1"].add_unit.assert_called_with( + count=1, to="to1" + ) class TestCreateOfferChange(unittest.TestCase): - def test_method(self): self.assertEqual("createOffer", CreateOfferChange.method()) def test_dict_params(self): - change = CreateOfferChange(1, [], params={"application": "application", - "endpoints": "endpoints", - "offer-name": "offer_name"}) - self.assertEqual({"change_id": 1, - "requires": [], - "application": "application", - "endpoints": "endpoints", - "offer_name": "offer_name"}, change.__dict__) + change = CreateOfferChange( + 1, + [], + params={ + "application": "application", + "endpoints": "endpoints", + "offer-name": "offer_name", + }, + ) + self.assertEqual( + { + "change_id": 1, + "requires": [], + "application": "application", + "endpoints": "endpoints", + "offer_name": "offer_name", + }, + change.__dict__, + ) def test_dict_params_missing_data(self): - change = CreateOfferChange(1, [], params={"application": "application", - "endpoints": "endpoints"}) - self.assertEqual({"change_id": 1, - "requires": [], - "application": "application", - "endpoints": "endpoints", - "offer_name": None}, change.__dict__) + change = CreateOfferChange( + 1, [], params={"application": "application", "endpoints": "endpoints"} + ) + self.assertEqual( + { + "change_id": 1, + "requires": [], + "application": "application", + "endpoints": "endpoints", + "offer_name": None, + }, + change.__dict__, + ) class TestCreateOfferChangeRun: - async def test_run(self): - change = CreateOfferChange(1, [], params={"application": "application", - "endpoints": ["endpoints"], - "offer-name": "offer_name"}) + change = CreateOfferChange( + 1, + [], + params={ + "application": "application", + "endpoints": ["endpoints"], + "offer-name": "offer_name", + }, + ) model = mock.Mock() model.create_offer = mock.AsyncMock(return_value=None) context = mock.Mock() - context.resolve = mock.Mock(side_effect=['application1']) + context.resolve = mock.Mock(side_effect=["application1"]) context.model = model result = await change.run(context) assert result is None model.create_offer.assert_called_once() - model.create_offer.assert_called_with("endpoints", - offer_name="offer_name", - application_name="application1") + model.create_offer.assert_called_with( + "endpoints", offer_name="offer_name", application_name="application1" + ) class TestConsumeOfferChange(unittest.TestCase): - def test_method(self): self.assertEqual("consumeOffer", ConsumeOfferChange.method()) def test_dict_params(self): - change = ConsumeOfferChange(1, [], params={"url": "url", - "application-name": "application_name"}) - self.assertEqual({"change_id": 1, - "requires": [], - "url": "url", - "application_name": "application_name"}, change.__dict__) + change = ConsumeOfferChange( + 1, [], params={"url": "url", "application-name": "application_name"} + ) + self.assertEqual( + { + "change_id": 1, + "requires": [], + "url": "url", + "application_name": "application_name", + }, + change.__dict__, + ) def test_dict_params_missing_data(self): change = ConsumeOfferChange(1, [], params={"url": "url"}) - self.assertEqual({"change_id": 1, - "requires": [], - "url": "url", - "application_name": None}, change.__dict__) + self.assertEqual( + {"change_id": 1, "requires": [], "url": "url", "application_name": None}, + change.__dict__, + ) class TestConsumeOfferChangeRun: - async def test_run(self): - change = ConsumeOfferChange(1, [], params={"url": "url", - "application-name": "application_name"}) + change = ConsumeOfferChange( + 1, [], params={"url": "url", "application-name": "application_name"} + ) model = mock.Mock() model.consume = mock.AsyncMock(return_value=None) context = mock.Mock() - context.resolve = mock.Mock(side_effect=['application1']) + context.resolve = mock.Mock(side_effect=["application1"]) context.model = model result = await change.run(context) assert result is None model.consume.assert_called_once() - model.consume.assert_called_with("url", - application_alias="application1") + model.consume.assert_called_with("url", application_alias="application1") class TestExposeChange(unittest.TestCase): - def test_method(self): self.assertEqual("expose", ExposeChange.method()) def test_dict_params(self): change = ExposeChange(1, [], params={"application": "application"}) - self.assertEqual({"change_id": 1, - "requires": [], - "application": "application", - "exposed_endpoints": None}, change.__dict__) + self.assertEqual( + { + "change_id": 1, + "requires": [], + "application": "application", + "exposed_endpoints": None, + }, + change.__dict__, + ) def test_dict_params_missing_data(self): change = ExposeChange(1, [], params={}) - self.assertEqual({"change_id": 1, - "requires": [], - "application": None, - "exposed_endpoints": None}, change.__dict__) + self.assertEqual( + { + "change_id": 1, + "requires": [], + "application": None, + "exposed_endpoints": None, + }, + change.__dict__, + ) def test_dict_params_with_exposed_endpoints_data(self): params = { "application": "application", "exposed-endpoints": { - "": { - "to-spaces": ["alpha"], - "to-cidrs": ["10.0.0.0/24"] - }, - "foo": { - "to-spaces": ["alien"], - "to-cidrs": ["0.0.0.0/0", "::/0"] - } - } + "": {"to-spaces": ["alpha"], "to-cidrs": ["10.0.0.0/24"]}, + "foo": {"to-spaces": ["alien"], "to-cidrs": ["0.0.0.0/0", "::/0"]}, + }, } change = ExposeChange(1, [], params=params) - self.assertEqual({"change_id": 1, - "requires": [], - "application": "application", - "exposed_endpoints": { - "": { - "to-spaces": ["alpha"], - "to-cidrs": ["10.0.0.0/24"] - }, - "foo": { - "to-spaces": ["alien"], - "to-cidrs": ["0.0.0.0/0", "::/0"] - } - }}, change.__dict__) + self.assertEqual( + { + "change_id": 1, + "requires": [], + "application": "application", + "exposed_endpoints": { + "": {"to-spaces": ["alpha"], "to-cidrs": ["10.0.0.0/24"]}, + "foo": {"to-spaces": ["alien"], "to-cidrs": ["0.0.0.0/0", "::/0"]}, + }, + }, + change.__dict__, + ) class TestExposeChangeRun: - async def test_run(self): params = { "application": "application", "exposed-endpoints": { - "": { - "to-spaces": ["alpha"], - "to-cidrs": ["10.0.0.0/24"] - }, - "foo": { - "to-spaces": ["alien"], - "to-cidrs": ["0.0.0.0/0", "::/0"] - } - } + "": {"to-spaces": ["alpha"], "to-cidrs": ["10.0.0.0/24"]}, + "foo": {"to-spaces": ["alien"], "to-cidrs": ["0.0.0.0/0", "::/0"]}, + }, } change = ExposeChange(1, [], params=params) @@ -778,7 +925,7 @@ async def test_run(self): model = MockModel({"application1": app}) context = mock.Mock() - context.resolve = mock.Mock(side_effect=['application1']) + context.resolve = mock.Mock(side_effect=["application1"]) context.model = model result = await change.run(context) @@ -786,43 +933,45 @@ async def test_run(self): model.applications["application1"].expose.assert_called_once() model.applications["application1"].expose.assert_called_with({ - "": { - "to-spaces": ["alpha"], - "to-cidrs": ["10.0.0.0/24"] - }, - "foo": { - "to-spaces": ["alien"], - "to-cidrs": ["0.0.0.0/0", "::/0"] - } + "": {"to-spaces": ["alpha"], "to-cidrs": ["10.0.0.0/24"]}, + "foo": {"to-spaces": ["alien"], "to-cidrs": ["0.0.0.0/0", "::/0"]}, }) class TestScaleChange(unittest.TestCase): - def test_method(self): self.assertEqual("scale", ScaleChange.method()) def test_dict_params(self): - change = ScaleChange(1, [], params={"application": "application", - "scale": "scale"}) - self.assertEqual({"change_id": 1, - "requires": [], - "application": "application", - "scale": "scale"}, change.__dict__) + change = ScaleChange( + 1, [], params={"application": "application", "scale": "scale"} + ) + self.assertEqual( + { + "change_id": 1, + "requires": [], + "application": "application", + "scale": "scale", + }, + change.__dict__, + ) def test_dict_params_missing_data(self): change = ScaleChange(1, [], params={"application": "application"}) - self.assertEqual({"change_id": 1, - "requires": [], - "application": "application", - "scale": None}, change.__dict__) + self.assertEqual( + { + "change_id": 1, + "requires": [], + "application": "application", + "scale": None, + }, + change.__dict__, + ) class TestScaleChangeRun: - async def test_run(self): - change = ScaleChange(1, [], params={"application": "application", - "scale": 1}) + change = ScaleChange(1, [], params={"application": "application", "scale": 1}) app = mock.Mock() app.scale = mock.AsyncMock(return_value=None) @@ -830,7 +979,7 @@ async def test_run(self): model = MockModel({"application1": app}) context = mock.Mock() - context.resolve = mock.Mock(side_effect=['application1']) + context.resolve = mock.Mock(side_effect=["application1"]) context.model = model result = await change.run(context) @@ -841,36 +990,57 @@ async def test_run(self): class TestSetAnnotationsChange(unittest.TestCase): - def test_method(self): self.assertEqual("setAnnotations", SetAnnotationsChange.method()) def test_dict_params(self): - change = SetAnnotationsChange(1, [], params={"id": "id", - "entity-type": "entity_type", - "annotations": "annotations"}) - self.assertEqual({"change_id": 1, - "requires": [], - "id": "id", - "entity_type": "entity_type", - "annotations": "annotations"}, change.__dict__) + change = SetAnnotationsChange( + 1, + [], + params={ + "id": "id", + "entity-type": "entity_type", + "annotations": "annotations", + }, + ) + self.assertEqual( + { + "change_id": 1, + "requires": [], + "id": "id", + "entity_type": "entity_type", + "annotations": "annotations", + }, + change.__dict__, + ) def test_dict_params_missing_data(self): - change = SetAnnotationsChange(1, [], params={"id": "id", - "entity-type": "entity_type"}) - self.assertEqual({"change_id": 1, - "requires": [], - "id": "id", - "entity_type": "entity_type", - "annotations": None}, change.__dict__) + change = SetAnnotationsChange( + 1, [], params={"id": "id", "entity-type": "entity_type"} + ) + self.assertEqual( + { + "change_id": 1, + "requires": [], + "id": "id", + "entity_type": "entity_type", + "annotations": None, + }, + change.__dict__, + ) class TestSetAnnotationsChangeRun: - async def test_run(self): - change = SetAnnotationsChange(1, [], params={"id": "id", - "entity-type": "entity_type", - "annotations": "annotations"}) + change = SetAnnotationsChange( + 1, + [], + params={ + "id": "id", + "entity-type": "entity_type", + "annotations": "annotations", + }, + ) entity = mock.Mock() entity.set_annotations = mock.AsyncMock(return_value="annotations1") @@ -882,7 +1052,7 @@ async def test_run(self): model.state = state context = mock.Mock() - context.resolve = mock.Mock(side_effect=['application1']) + context.resolve = mock.Mock(side_effect=["application1"]) context.model = model result = await change.run(context) @@ -908,17 +1078,17 @@ async def __call__(self, *args, **kwargs): "applications": { "oci-image-charm": { "charm": charm_dir_1, - "resources": {"oci-image": "ubuntu:latest"} + "resources": {"oci-image": "ubuntu:latest"}, }, "oci-image-charm-2": { "charm": charm_dir_2, - "resources": {"oci-image": "ubuntu:latest"} + "resources": {"oci-image": "ubuntu:latest"}, }, "oci-image-charm-3": { "charm": charm_dir_2, - "resources": {"oci-image": "ubuntu:latest"} - } - } + "resources": {"oci-image": "ubuntu:latest"}, + }, + }, } connection_mock = mock.Mock() @@ -949,29 +1119,44 @@ async def __call__(self, *args, **kwargs): m1 = mock.call( "oci-image-charm", "charm_uri", - yaml.load(Path("tests/integration/oci-image-charm/metadata.yaml").read_text(), Loader=yaml.FullLoader), + yaml.load( + Path("tests/integration/oci-image-charm/metadata.yaml").read_text(), + Loader=yaml.FullLoader, + ), resources={"oci-image": "ubuntu:latest"}, ) m2 = mock.call( "oci-image-charm-2", "charm_uri", - yaml.load(Path("tests/integration/oci-image-charm-no-series/metadata.yaml").read_text(), Loader=yaml.FullLoader), + yaml.load( + Path( + "tests/integration/oci-image-charm-no-series/metadata.yaml" + ).read_text(), + Loader=yaml.FullLoader, + ), resources={"oci-image": "ubuntu:latest"}, ) m3 = mock.call( "oci-image-charm-3", "charm_uri", - yaml.load(Path("tests/integration/oci-image-charm-no-series/metadata.yaml").read_text(), Loader=yaml.FullLoader), + yaml.load( + Path( + "tests/integration/oci-image-charm-no-series/metadata.yaml" + ).read_text(), + Loader=yaml.FullLoader, + ), resources={"oci-image": "ubuntu:latest"}, ) m_add_local_resources_calls = model.add_local_resources.mock_calls assert len(m_add_local_resources_calls) == 3 - assert m1 in m_add_local_resources_calls and \ - m2 in m_add_local_resources_calls and \ - m3 in m_add_local_resources_calls + assert ( + m1 in m_add_local_resources_calls + and m2 in m_add_local_resources_calls + and m3 in m_add_local_resources_calls + ) mc_1 = mock.call(charm_path_1, "focal") mc_2 = mock.call(charm_path_2, "focal") @@ -979,8 +1164,12 @@ async def __call__(self, *args, **kwargs): m_add_local_charm_dir_calls = model.add_local_charm_dir.mock_calls assert len(m_add_local_charm_dir_calls) == 3 - assert mc_1 in m_add_local_charm_dir_calls and \ - mc_2 in m_add_local_charm_dir_calls and \ - mc_3 in m_add_local_charm_dir_calls + assert ( + mc_1 in m_add_local_charm_dir_calls + and mc_2 in m_add_local_charm_dir_calls + and mc_3 in m_add_local_charm_dir_calls + ) - assert bundle["applications"]["oci-image-charm"]["resources"]["oci-image"] == "id" + assert ( + bundle["applications"]["oci-image-charm"]["resources"]["oci-image"] == "id" + ) diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index 79af53684..5f3cd5596 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -20,12 +20,13 @@ def test_basics(): def test_from_connection(): connection = mock.Mock() connection.facades = {"Action": 7} - connection.info = {"server-version": '3.0'} + connection.info = {"server-version": "3.0"} action_facade = client.ActionFacade.from_connection(connection) assert action_facade def test_to_json(): uml = client.UserModelList([client.UserModel()]) - assert uml.to_json() == ('{"user-models": [{"last-connection": null, ' - '"model": null}]}') + assert uml.to_json() == ( + '{"user-models": [{"last-connection": null, "model": null}]}' + ) diff --git a/tests/unit/test_connection.py b/tests/unit/test_connection.py index b9dacf713..c916960ef 100644 --- a/tests/unit/test_connection.py +++ b/tests/unit/test_connection.py @@ -26,7 +26,7 @@ async def send(self, message): async def recv(self): if not self.responses: await asyncio.sleep(1) # delay to give test time to finish - raise ConnectionClosed(0, 'ran out of responses') + raise ConnectionClosed(0, "ran out of responses") return json.dumps(self.responses.popleft()) async def close(self): @@ -36,33 +36,37 @@ async def close(self): async def test_out_of_order(): ws = WebsocketMock([ - {'request-id': 1}, - {'request-id': 3}, - {'request-id': 2}, + {"request-id": 1}, + {"request-id": 3}, + {"request-id": 2}, ]) expected_responses = [ - {'request-id': 1}, - {'request-id': 2}, - {'request-id': 3}, + {"request-id": 1}, + {"request-id": 2}, + {"request-id": 3}, ] - minimal_facades = [{'name': 'Pinger', 'versions': [1]}] + minimal_facades = [{"name": "Pinger", "versions": [1]}] con = None try: - with \ - mock.patch('websockets.connect', mock.AsyncMock(return_value=ws)), \ - mock.patch( - 'juju.client.connection.Connection.login', - mock.AsyncMock(return_value={'response': { - 'facades': minimal_facades, - 'server-version': '3.0', - }}), - ), \ - mock.patch('juju.client.connection.Connection._get_ssl'), \ - mock.patch('juju.client.connection.Connection._pinger', mock.AsyncMock()): - con = await Connection.connect('0.1.2.3:999') + with mock.patch( + "websockets.connect", mock.AsyncMock(return_value=ws) + ), mock.patch( + "juju.client.connection.Connection.login", + mock.AsyncMock( + return_value={ + "response": { + "facades": minimal_facades, + "server-version": "3.0", + } + } + ), + ), mock.patch("juju.client.connection.Connection._get_ssl"), mock.patch( + "juju.client.connection.Connection._pinger", mock.AsyncMock() + ): + con = await Connection.connect("0.1.2.3:999") actual_responses = [] for i in range(3): - actual_responses.append(await con.rpc({'version': 1})) + actual_responses.append(await con.rpc({"version": 1})) assert actual_responses == expected_responses finally: if con: @@ -76,39 +80,41 @@ async def test_bubble_redirect_exception(): -----END CERTIFICATE-----""" ws = WebsocketMock([ { - 'request-id': 1, - 'error': 'redirection to alternative server required', - 'error-code': 'redirection required', - 'error-info': { - 'ca-cert': ca_cert, - 'servers': [[ - { - 'port': 17070, - 'scope': 'local-cloud', - 'type': 'ipv4', - 'value': '42.42.42.42', - }, - { - 'port': 4242, - 'scope': 'public', - 'type': 'ipv4', - 'value': '42.42.42.42', - }, - ]], + "request-id": 1, + "error": "redirection to alternative server required", + "error-code": "redirection required", + "error-info": { + "ca-cert": ca_cert, + "servers": [ + [ + { + "port": 17070, + "scope": "local-cloud", + "type": "ipv4", + "value": "42.42.42.42", + }, + { + "port": 4242, + "scope": "public", + "type": "ipv4", + "value": "42.42.42.42", + }, + ] + ], }, - 'response': {}, + "response": {}, }, ]) with pytest.raises(JujuRedirectException) as caught_ex: - with mock.patch('websockets.connect', mock.AsyncMock(return_value=ws)): - await Connection.connect('0.1.2.3:999') + with mock.patch("websockets.connect", mock.AsyncMock(return_value=ws)): + await Connection.connect("0.1.2.3:999") redir_error = caught_ex.value assert redir_error.follow_redirect is False assert redir_error.ca_cert == ca_cert assert redir_error.endpoints == [ - ('42.42.42.42:17070', ca_cert), - ('42.42.42.42:4242', ca_cert), + ("42.42.42.42:17070", ca_cert), + ("42.42.42.42:4242", ca_cert), ] @@ -119,81 +125,89 @@ async def test_follow_redirect(): -----END CERTIFICATE-----""" wsForCont1 = WebsocketMock([ { - 'request-id': 1, - 'error': 'redirection to alternative server required', - 'error-code': 'redirection required', - 'response': {}, + "request-id": 1, + "error": "redirection to alternative server required", + "error-code": "redirection required", + "response": {}, }, { - 'request-id': 2, - 'response': { - 'ca-cert': ca_cert, - 'servers': [[ - { - 'port': 17070, - 'scope': 'local-cloud', - 'type': 'ipv4', - 'value': '42.42.42.42', - }, - { - 'port': 4242, - 'scope': 'public', - 'type': 'ipv4', - 'value': '42.42.42.42', - }, - ]], + "request-id": 2, + "response": { + "ca-cert": ca_cert, + "servers": [ + [ + { + "port": 17070, + "scope": "local-cloud", + "type": "ipv4", + "value": "42.42.42.42", + }, + { + "port": 4242, + "scope": "public", + "type": "ipv4", + "value": "42.42.42.42", + }, + ] + ], }, }, ]) - minimal_facades = [{'name': 'Pinger', 'versions': [1]}] + minimal_facades = [{"name": "Pinger", "versions": [1]}] wsForCont2 = WebsocketMock([ - {'request-id': 1}, - {'request-id': 2}, - {'request-id': 3, 'response': {'result': minimal_facades, - 'server-version': '3.0', - }}, + {"request-id": 1}, + {"request-id": 2}, + { + "request-id": 3, + "response": { + "result": minimal_facades, + "server-version": "3.0", + }, + }, ]) con = None try: - with \ - mock.patch('websockets.connect', - mock.AsyncMock(side_effect=[wsForCont1, wsForCont2]) - ), \ - mock.patch('juju.client.connection.Connection._get_ssl'), \ - mock.patch('juju.client.connection.Connection._pinger', - mock.AsyncMock()): - con = await Connection.connect('0.1.2.3:999') + with mock.patch( + "websockets.connect", mock.AsyncMock(side_effect=[wsForCont1, wsForCont2]) + ), mock.patch("juju.client.connection.Connection._get_ssl"), mock.patch( + "juju.client.connection.Connection._pinger", mock.AsyncMock() + ): + con = await Connection.connect("0.1.2.3:999") finally: if con: - assert con.connect_params()['endpoint'] == "42.42.42.42:4242" + assert con.connect_params()["endpoint"] == "42.42.42.42:4242" await con.close() async def test_rpc_none_results(): ws = WebsocketMock([ - {'request-id': 1, 'response': {'results': None}}, + {"request-id": 1, "response": {"results": None}}, ]) expected_responses = [ - {'request-id': 1, 'response': {'results': None}}, + {"request-id": 1, "response": {"results": None}}, ] - minimal_facades = [{'name': 'Pinger', 'versions': [1]}] + minimal_facades = [{"name": "Pinger", "versions": [1]}] con = None try: - with \ - mock.patch('websockets.connect', mock.AsyncMock(return_value=ws)), \ - mock.patch( - 'juju.client.connection.Connection.login', - mock.AsyncMock(return_value={'response': { - 'facades': minimal_facades, - 'server-version': '3.0', - }}), - ), \ - mock.patch('juju.client.connection.Connection._get_ssl'), \ - mock.patch('juju.client.connection.Connection._pinger', mock.AsyncMock()): - con = await Connection.connect('0.1.2.3:999') + with mock.patch( + "websockets.connect", mock.AsyncMock(return_value=ws) + ), mock.patch( + "juju.client.connection.Connection.login", + mock.AsyncMock( + return_value={ + "response": { + "facades": minimal_facades, + "server-version": "3.0", + } + } + ), + ), mock.patch("juju.client.connection.Connection._get_ssl"), mock.patch( + "juju.client.connection.Connection._pinger", mock.AsyncMock() + ): + con = await Connection.connect("0.1.2.3:999") actual_responses = [] - actual_responses.append(await con.rpc({'version': 1})) + actual_responses.append(await con.rpc({"version": 1})) assert actual_responses == expected_responses finally: if con: diff --git a/tests/unit/test_constraints.py b/tests/unit/test_constraints.py index 1fac2ccd6..f437f58f6 100644 --- a/tests/unit/test_constraints.py +++ b/tests/unit/test_constraints.py @@ -11,7 +11,6 @@ class TestConstraints(unittest.TestCase): - def test_mem_regex(self): m = constraints.MEM self.assertTrue(m.match("10G")) @@ -52,17 +51,16 @@ def test_normalize_list_val(self): def test_parse_constraints(self): _ = constraints.parse - self.assertEqual( - _("mem=10G"), - {"mem": 10 * 1024} - ) + self.assertEqual(_("mem=10G"), {"mem": 10 * 1024}) self.assertEqual( _("mem=10G zones=bar,baz tags=tag1 spaces=space1,space2"), - {"mem": 10 * 1024, - "zones": ["bar", "baz"], - "tags": ["tag1"], - "spaces": ["space1", "space2"]} + { + "mem": 10 * 1024, + "zones": ["bar", "baz"], + "tags": ["tag1"], + "spaces": ["space1", "space2"], + }, ) self.assertRaises(Exception, lambda: _("root-disk>16G")) @@ -72,71 +70,33 @@ def test_parse_storage_constraint(self): _ = constraints.parse_storage_constraint self.assertEqual( - _("pool,1M"), - {"pool": "pool", - "count": 1, - "size": 1 * 1024 ** 0} - ) - self.assertEqual( - _("pool,"), - {"pool": "pool", - "count": 1} - ) - self.assertEqual( - _("1M"), - {"size": 1 * 1024 ** 0, - "count": 1} - ) - self.assertEqual( - _("p,1G"), - {"pool": "p", - "count": 1, - "size": 1 * 1024 ** 1} - ) - self.assertEqual( - _("p,0.5T"), - {"pool": "p", - "count": 1, - "size": 512 * 1024 ** 1} - ) - self.assertEqual( - _("3,0.5T"), - {"count": 3, - "size": 512 * 1024 ** 1} - ) - self.assertEqual( - _("0.5T,3"), - {"count": 3, - "size": 512 * 1024 ** 1} + _("pool,1M"), {"pool": "pool", "count": 1, "size": 1 * 1024**0} ) + self.assertEqual(_("pool,"), {"pool": "pool", "count": 1}) + self.assertEqual(_("1M"), {"size": 1 * 1024**0, "count": 1}) + self.assertEqual(_("p,1G"), {"pool": "p", "count": 1, "size": 1 * 1024**1}) + self.assertEqual(_("p,0.5T"), {"pool": "p", "count": 1, "size": 512 * 1024**1}) + self.assertEqual(_("3,0.5T"), {"count": 3, "size": 512 * 1024**1}) + self.assertEqual(_("0.5T,3"), {"count": 3, "size": 512 * 1024**1}) def test_parse_device_constraint(self): _ = constraints.parse_device_constraint - self.assertEqual( - _("nvidia.com/gpu"), - {"type": "nvidia.com/gpu", - "count": 1} - ) - self.assertEqual( - _("2,nvidia.com/gpu"), - {"type": "nvidia.com/gpu", - "count": 2} - ) + self.assertEqual(_("nvidia.com/gpu"), {"type": "nvidia.com/gpu", "count": 1}) + self.assertEqual(_("2,nvidia.com/gpu"), {"type": "nvidia.com/gpu", "count": 2}) self.assertEqual( _("3,nvidia.com/gpu,gpu=nvidia-tesla-p100"), - {"type": "nvidia.com/gpu", - "count": 3, - "attributes": { - "gpu": "nvidia-tesla-p100" - }} + { + "type": "nvidia.com/gpu", + "count": 3, + "attributes": {"gpu": "nvidia-tesla-p100"}, + }, ) self.assertEqual( _("3,nvidia.com/gpu,gpu=nvidia-tesla-p100;2ndattr=another-attr"), - {"type": "nvidia.com/gpu", - "count": 3, - "attributes": { - "gpu": "nvidia-tesla-p100", - "2ndattr": "another-attr" - }} + { + "type": "nvidia.com/gpu", + "count": 3, + "attributes": {"gpu": "nvidia-tesla-p100", "2ndattr": "another-attr"}, + }, ) diff --git a/tests/unit/test_controller.py b/tests/unit/test_controller.py index 1fd7a14be..1cbe9efe4 100644 --- a/tests/unit/test_controller.py +++ b/tests/unit/test_controller.py @@ -12,104 +12,121 @@ class TestControllerConnect(unittest.IsolatedAsyncioTestCase): - @mock.patch('juju.controller.Controller.update_endpoints') - @mock.patch('juju.client.connector.Connector.connect_controller') + @mock.patch("juju.controller.Controller.update_endpoints") + @mock.patch("juju.client.connector.Connector.connect_controller") async def test_no_args(self, mock_connect_controller, mock_update_endpoints): c = Controller() await c.connect() mock_connect_controller.assert_called_once_with(None) mock_update_endpoints.assert_called_once_with() - @mock.patch('juju.controller.Controller.update_endpoints') - @mock.patch('juju.client.connector.Connector.connect_controller') - async def test_with_controller_name(self, mock_connect_controller, mock_update_endpoints): + @mock.patch("juju.controller.Controller.update_endpoints") + @mock.patch("juju.client.connector.Connector.connect_controller") + async def test_with_controller_name( + self, mock_connect_controller, mock_update_endpoints + ): c = Controller() - await c.connect(controller_name='foo') - mock_connect_controller.assert_called_once_with('foo') + await c.connect(controller_name="foo") + mock_connect_controller.assert_called_once_with("foo") mock_update_endpoints.assert_called_once_with() - @mock.patch('juju.controller.Controller.update_endpoints') - @mock.patch('juju.client.connector.Connector.connect') + @mock.patch("juju.controller.Controller.update_endpoints") + @mock.patch("juju.client.connector.Connector.connect") async def test_with_endpoint_and_no_auth(self, mock_connect, mock_update_endpoints): c = Controller() with self.assertRaises(TypeError): - await c.connect(endpoint='0.1.2.3:4566') + await c.connect(endpoint="0.1.2.3:4566") self.assertEqual(mock_connect.call_count, 0) - @mock.patch('juju.controller.Controller.update_endpoints') - @mock.patch('juju.client.connector.Connector.connect') - async def test_with_endpoint_and_userpass(self, mock_connect, mock_update_endpoints): + @mock.patch("juju.controller.Controller.update_endpoints") + @mock.patch("juju.client.connector.Connector.connect") + async def test_with_endpoint_and_userpass( + self, mock_connect, mock_update_endpoints + ): c = Controller() with self.assertRaises(TypeError): - await c.connect(endpoint='0.1.2.3:4566', username='dummy') - await c.connect(endpoint='0.1.2.3:4566', - username='user', - password='pass') - mock_connect.assert_called_once_with(endpoint='0.1.2.3:4566', - username='user', - password='pass') + await c.connect(endpoint="0.1.2.3:4566", username="dummy") + await c.connect(endpoint="0.1.2.3:4566", username="user", password="pass") + mock_connect.assert_called_once_with( + endpoint="0.1.2.3:4566", username="user", password="pass" + ) mock_update_endpoints.assert_called_once_with() - @mock.patch('juju.controller.Controller.update_endpoints') - @mock.patch('juju.client.connector.Connector.connect') - async def test_with_endpoint_and_bakery_client(self, mock_connect, mock_update_endpoints): + @mock.patch("juju.controller.Controller.update_endpoints") + @mock.patch("juju.client.connector.Connector.connect") + async def test_with_endpoint_and_bakery_client( + self, mock_connect, mock_update_endpoints + ): c = Controller() - await c.connect(endpoint='0.1.2.3:4566', bakery_client='bakery') - mock_connect.assert_called_once_with(endpoint='0.1.2.3:4566', - bakery_client='bakery') + await c.connect(endpoint="0.1.2.3:4566", bakery_client="bakery") + mock_connect.assert_called_once_with( + endpoint="0.1.2.3:4566", bakery_client="bakery" + ) mock_update_endpoints.assert_called_once_with() - @mock.patch('juju.controller.Controller.update_endpoints') - @mock.patch('juju.client.connector.Connector.connect') - async def test_with_endpoint_and_macaroons(self, mock_connect, mock_update_endpoints): + @mock.patch("juju.controller.Controller.update_endpoints") + @mock.patch("juju.client.connector.Connector.connect") + async def test_with_endpoint_and_macaroons( + self, mock_connect, mock_update_endpoints + ): c = Controller() - await c.connect(endpoint='0.1.2.3:4566', - macaroons=['macaroon']) - mock_connect.assert_called_with(endpoint='0.1.2.3:4566', - macaroons=['macaroon']) + await c.connect(endpoint="0.1.2.3:4566", macaroons=["macaroon"]) + mock_connect.assert_called_with(endpoint="0.1.2.3:4566", macaroons=["macaroon"]) mock_update_endpoints.assert_called_with() - await c.connect(endpoint='0.1.2.3:4566', - bakery_client='bakery', - macaroons=['macaroon']) - mock_connect.assert_called_with(endpoint='0.1.2.3:4566', - bakery_client='bakery', - macaroons=['macaroon']) + await c.connect( + endpoint="0.1.2.3:4566", bakery_client="bakery", macaroons=["macaroon"] + ) + mock_connect.assert_called_with( + endpoint="0.1.2.3:4566", bakery_client="bakery", macaroons=["macaroon"] + ) mock_update_endpoints.assert_called_with() - @mock.patch('juju.controller.Controller.update_endpoints') - @mock.patch('juju.client.connector.Connector.connect_controller') - @mock.patch('juju.client.connector.Connector.connect') - async def test_with_posargs(self, mock_connect, mock_connect_controller, mock_update_endpoints): + @mock.patch("juju.controller.Controller.update_endpoints") + @mock.patch("juju.client.connector.Connector.connect_controller") + @mock.patch("juju.client.connector.Connector.connect") + async def test_with_posargs( + self, mock_connect, mock_connect_controller, mock_update_endpoints + ): c = Controller() - await c.connect('foo') - mock_connect_controller.assert_called_once_with('foo') + await c.connect("foo") + mock_connect_controller.assert_called_once_with("foo") mock_update_endpoints.assert_called_once_with() with self.assertRaises(TypeError): - await c.connect('endpoint', 'user') - await c.connect('endpoint', 'user', 'pass') - mock_connect.assert_called_once_with(endpoint='endpoint', - username='user', - password='pass') + await c.connect("endpoint", "user") + await c.connect("endpoint", "user", "pass") + mock_connect.assert_called_once_with( + endpoint="endpoint", username="user", password="pass" + ) mock_update_endpoints.assert_called_with() - await c.connect('endpoint', 'user', 'pass', 'cacert', 'bakery', - 'macaroons', 'max_frame_size') - mock_connect.assert_called_with(endpoint='endpoint', - username='user', - password='pass', - cacert='cacert', - bakery_client='bakery', - macaroons='macaroons', - max_frame_size='max_frame_size') + await c.connect( + "endpoint", + "user", + "pass", + "cacert", + "bakery", + "macaroons", + "max_frame_size", + ) + mock_connect.assert_called_with( + endpoint="endpoint", + username="user", + password="pass", + cacert="cacert", + bakery_client="bakery", + macaroons="macaroons", + max_frame_size="max_frame_size", + ) mock_update_endpoints.assert_called_with() - @mock.patch('juju.client.client.CloudFacade') + @mock.patch("juju.client.client.CloudFacade") async def test_file_cred_v2(self, mock_cf): with NamedTemporaryFile() as tempfile: tempfile.close() temppath = Path(tempfile.name) - temppath.write_text('cred-test') - cred = client.CloudCredential(auth_type='jsonfile', - attrs={'file': tempfile.name}) + temppath.write_text("cred-test") + cred = client.CloudCredential( + auth_type="jsonfile", attrs={"file": tempfile.name} + ) jujudata = mock.MagicMock() c = Controller(jujudata=jujudata) c._connector = mock.Mock() @@ -118,24 +135,25 @@ async def test_file_cred_v2(self, mock_cf): cloud_facade.version = 2 cloud_facade.UpdateCredentials = up_creds await c.add_credential( - name='name', + name="name", credential=cred, - cloud='cloud', - owner='owner', + cloud="cloud", + owner="owner", ) assert up_creds.called - new_cred = up_creds.call_args[1]['credentials'][0].credential - assert cred.attrs['file'] == tempfile.name - assert new_cred.attrs['file'] == 'cred-test' + new_cred = up_creds.call_args[1]["credentials"][0].credential + assert cred.attrs["file"] == tempfile.name + assert new_cred.attrs["file"] == "cred-test" - @mock.patch('juju.client.client.CloudFacade') + @mock.patch("juju.client.client.CloudFacade") async def test_file_cred_v3(self, mock_cf): with NamedTemporaryFile() as tempfile: tempfile.close() temppath = Path(tempfile.name) - temppath.write_text('cred-test') - cred = client.CloudCredential(auth_type='jsonfile', - attrs={'file': tempfile.name}) + temppath.write_text("cred-test") + cred = client.CloudCredential( + auth_type="jsonfile", attrs={"file": tempfile.name} + ) jujudata = mock.MagicMock() c = Controller(jujudata=jujudata) c._connector = mock.Mock() @@ -144,14 +162,14 @@ async def test_file_cred_v3(self, mock_cf): cloud_facade.version = 3 cloud_facade.UpdateCredentialsCheckModels = up_creds await c.add_credential( - name='name', + name="name", credential=cred, - cloud='cloud', - owner='owner', + cloud="cloud", + owner="owner", force=True, ) assert up_creds.called - assert up_creds.call_args[1]['force'] - new_cred = up_creds.call_args[1]['credentials'][0].credential - assert cred.attrs['file'] == tempfile.name - assert new_cred.attrs['file'] == 'cred-test' + assert up_creds.call_args[1]["force"] + new_cred = up_creds.call_args[1]["credentials"][0].credential + assert cred.attrs["file"] == tempfile.name + assert new_cred.attrs["file"] == "cred-test" diff --git a/tests/unit/test_definitions.py b/tests/unit/test_definitions.py index ac74dd373..1ec7776ec 100644 --- a/tests/unit/test_definitions.py +++ b/tests/unit/test_definitions.py @@ -7,93 +7,100 @@ class TestDefinitions(unittest.TestCase): - def test_dict_legacy(self): status = client.FullStatus.from_json({ - 'relations': [{ - 'endpoints': [{ - 'application': 'application', - 'name': 'name', - 'role': 'role', - 'subordinate': True - }], - 'id': 1, - 'interface': 'interface', - 'key': 'key', - 'scope': 'scope', - 'status': [] - }] + "relations": [ + { + "endpoints": [ + { + "application": "application", + "name": "name", + "role": "role", + "subordinate": True, + } + ], + "id": 1, + "interface": "interface", + "key": "key", + "scope": "scope", + "status": [], + } + ] }) - if status.relations != status['relations']: - raise Exception('subscript not equal to attr') - if status.relations != status.get('relations'): - raise Exception('get() not equal to attr') - if status.get('non-existing', 'foo') != 'foo': - raise Exception('get defaulting missing attr') + if status.relations != status["relations"]: + raise Exception("subscript not equal to attr") + if status.relations != status.get("relations"): + raise Exception("get() not equal to attr") + if status.get("non-existing", "foo") != "foo": + raise Exception("get defaulting missing attr") def test_parse(self): status = client.FullStatus.from_json({ - 'relations': [{ - 'endpoints': [{ - 'application': 'application', - 'name': 'name', - 'role': 'role', - 'subordinate': True - }], - 'id': 1, - 'interface': 'interface', - 'key': 'key', - 'scope': 'scope', - 'status': [] - }], - 'applications': { - 'app': { - 'can-upgrade-to': 'something', - 'charm': 'charm', - 'charm-profile': 'profile', - 'charm-version': '2', - 'endpoint-bindings': None, - 'err': None, - 'exposed': True, - 'int': 0, - 'life': 'life', - 'meter-statuses': {}, - 'provider-id': 'provider-id', - 'public-address': '1.1.1.1', - 'relations': { - 'a': ['b', 'c'], + "relations": [ + { + "endpoints": [ + { + "application": "application", + "name": "name", + "role": "role", + "subordinate": True, + } + ], + "id": 1, + "interface": "interface", + "key": "key", + "scope": "scope", + "status": [], + } + ], + "applications": { + "app": { + "can-upgrade-to": "something", + "charm": "charm", + "charm-profile": "profile", + "charm-version": "2", + "endpoint-bindings": None, + "err": None, + "exposed": True, + "int": 0, + "life": "life", + "meter-statuses": {}, + "provider-id": "provider-id", + "public-address": "1.1.1.1", + "relations": { + "a": ["b", "c"], }, - 'series': 'focal', - 'status': {}, - 'subordinate-to': ['other'], - 'units': { - 'unit-id': { - 'address': '1.1.1.1', - 'agent-status': {}, - 'charm': 'charm', - 'leader': True, - 'machine': 'machine-0', - 'opened-ports': ['1234'], - 'provider-id': 'provider', - 'public-address': '1.1.1.2', - 'subordinates': {}, - 'workload-status': {}, - 'workload-version': '1.2' + "series": "focal", + "status": {}, + "subordinate-to": ["other"], + "units": { + "unit-id": { + "address": "1.1.1.1", + "agent-status": {}, + "charm": "charm", + "leader": True, + "machine": "machine-0", + "opened-ports": ["1234"], + "provider-id": "provider", + "public-address": "1.1.1.2", + "subordinates": {}, + "workload-status": {}, + "workload-version": "1.2", } }, - 'workload-version': '1.2' + "workload-version": "1.2", } - } + }, }) - if status.relations != status['relations']: - raise Exception('subscript not equal to attr') - if status['relations'][0]['endpoints'][0]['application'] != 'application': - raise Exception('failed to use complex subscript') - if status.applications['app'].relations['a'][0] != 'b': - raise Exception('object with array type is invalid') + if status.relations != status["relations"]: + raise Exception("subscript not equal to attr") + if status["relations"][0]["endpoints"][0]["application"] != "application": + raise Exception("failed to use complex subscript") + if status.applications["app"].relations["a"][0] != "b": + raise Exception("object with array type is invalid") if not isinstance(status.relations[0], client.RelationStatus): - raise Exception('status relation is not a RelationStatus') + raise Exception("status relation is not a RelationStatus") if not isinstance(status.relations[0].endpoints[0], client.EndpointStatus): - raise Exception('status relation endpoint is not a EndpointStatus') - if not isinstance(status.applications['app'], client.ApplicationStatus): - raise Exception('status application is not a ApplicationStatus') + raise Exception("status relation endpoint is not a EndpointStatus") + if not isinstance(status.applications["app"], client.ApplicationStatus): + raise Exception("status application is not a ApplicationStatus") diff --git a/tests/unit/test_flags.py b/tests/unit/test_flags.py index e30105402..8e9aeda45 100644 --- a/tests/unit/test_flags.py +++ b/tests/unit/test_flags.py @@ -8,13 +8,14 @@ class TestFlags(unittest.TestCase): - def test_default_flag(self): os.environ[flags.PYLIBJUJU_DEV_FEATURE_FLAG] = flags.DEFAULT_VALUES_FLAG self.assertTrue(flags.feature_enabled(flags.DEFAULT_VALUES_FLAG)) def test_multiple_flag(self): - os.environ[flags.PYLIBJUJU_DEV_FEATURE_FLAG] = "xxx, {},foo, bar".format(flags.DEFAULT_VALUES_FLAG) + os.environ[flags.PYLIBJUJU_DEV_FEATURE_FLAG] = "xxx, {},foo, bar".format( + flags.DEFAULT_VALUES_FLAG + ) self.assertTrue(flags.feature_enabled(flags.DEFAULT_VALUES_FLAG)) def test_missing_flag(self): diff --git a/tests/unit/test_gocookies.py b/tests/unit/test_gocookies.py index 57f5c1bd7..429bab3b7 100644 --- a/tests/unit/test_gocookies.py +++ b/tests/unit/test_gocookies.py @@ -4,6 +4,7 @@ """ Tests for the gocookies code. """ + import os import shutil import tempfile @@ -131,40 +132,57 @@ # the queries on the above cookie_content data # and printing the results. cookie_content_queries = [ - ('http://x.foo.com', [ - ('foo', 'foo-value'), - ('foo1', 'foo1-value'), - ('foo3', 'foo3-value'), - ]), - ('https://x.foo.com', [ - ('foo', 'foo-value'), - ('foo1', 'foo1-value'), - ('foo2', 'foo2-value'), - ('foo3', 'foo3-value'), - ]), - ('http://arble.foo.com', [ - ('foo1', 'foo1-value'), - ('foo3', 'foo3-value'), - ]), - ('http://arble.com', [ - ]), - ('http://x.foo.com/path/x', [ - ('foo', 'foo-path-value'), - ('foo4', 'foo4-value'), - ('foo', 'foo-value'), - ('foo1', 'foo1-value'), - ('foo3', 'foo3-value'), - ]), - ('http://arble.foo.com/path/x', [ - ('foo4', 'foo4-value'), - ('foo1', 'foo1-value'), - ('foo3', 'foo3-value'), - ]), - ('http://foo.com/path/x', [ - ('foo4', 'foo4-value'), - ('foo1', 'foo1-value'), - ('foo3', 'foo3-value'), - ]), + ( + "http://x.foo.com", + [ + ("foo", "foo-value"), + ("foo1", "foo1-value"), + ("foo3", "foo3-value"), + ], + ), + ( + "https://x.foo.com", + [ + ("foo", "foo-value"), + ("foo1", "foo1-value"), + ("foo2", "foo2-value"), + ("foo3", "foo3-value"), + ], + ), + ( + "http://arble.foo.com", + [ + ("foo1", "foo1-value"), + ("foo3", "foo3-value"), + ], + ), + ("http://arble.com", []), + ( + "http://x.foo.com/path/x", + [ + ("foo", "foo-path-value"), + ("foo4", "foo4-value"), + ("foo", "foo-value"), + ("foo1", "foo1-value"), + ("foo3", "foo3-value"), + ], + ), + ( + "http://arble.foo.com/path/x", + [ + ("foo4", "foo4-value"), + ("foo1", "foo1-value"), + ("foo3", "foo3-value"), + ], + ), + ( + "http://foo.com/path/x", + [ + ("foo4", "foo4-value"), + ("foo1", "foo1-value"), + ("foo3", "foo3-value"), + ], + ), ] @@ -181,14 +199,14 @@ def test_readcookies(self): def test_roundtrip(self): jar = self.load_jar(cookie_content) - filename2 = os.path.join(self.dir, 'cookies2') + filename2 = os.path.join(self.dir, "cookies2") jar.save(filename=filename2) jar = GoCookieJar() jar.load(filename=filename2) self.assert_jar_queries(jar, cookie_content_queries) def test_expiry_time(self): - content = '''[ + content = """[ { "CanonicalHost": "bar.com", "Creation": "2017-11-17T08:53:55.088820092Z", @@ -204,26 +222,26 @@ def test_expiry_time(self): "Updated": "2017-11-17T08:53:55.088822562Z", "Value": "bar-value" } - ]''' + ]""" jar = self.load_jar(content) got_expires = tuple(jar)[0].expires - want_expires = int(pyrfc3339.parse('2345-11-15T18:16:08Z').timestamp()) + want_expires = int(pyrfc3339.parse("2345-11-15T18:16:08Z").timestamp()) self.assertEqual(got_expires, want_expires) def load_jar(self, content): - filename = os.path.join(self.dir, 'cookies') - with open(filename, 'x') as f: + filename = os.path.join(self.dir, "cookies") + with open(filename, "x") as f: f.write(content) jar = GoCookieJar() jar.load(filename=filename) return jar def assert_jar_queries(self, jar, queries): - '''Assert that all the given queries (see cookie_content_queries) + """Assert that all the given queries (see cookie_content_queries) are satisfied when run on the given cookie jar. :param jar CookieJar: the cookie jar to query :param queries: the queries to run. - ''' + """ for url, want_cookies in queries: req = urllib.request.Request(url) jar.add_cookie_header(req) @@ -234,14 +252,17 @@ def assert_jar_queries(self, jar, queries): # is OK because we know we don't have to deal # with any complex cases. - cookie_header = req.get_header('Cookie') + cookie_header = req.get_header("Cookie") got_cookies = [] if cookie_header is not None: got_cookies = [ - tuple(part.split('=')) - for part in cookie_header.split('; ') + tuple(part.split("=")) for part in cookie_header.split("; ") ] got_cookies.sort() want_cookies = list(want_cookies) want_cookies.sort() - self.assertEqual(got_cookies, want_cookies, msg='query {}; got {}; want {}'.format(url, got_cookies, want_cookies)) + self.assertEqual( + got_cookies, + want_cookies, + msg="query {}; got {}; want {}".format(url, got_cookies, want_cookies), + ) diff --git a/tests/unit/test_loop.py b/tests/unit/test_loop.py index 86ca13a16..c0abda127 100644 --- a/tests/unit/test_loop.py +++ b/tests/unit/test_loop.py @@ -20,15 +20,18 @@ async def test_run(self): assert jasyncio.get_running_loop() == self.loop async def _test(): - return 'success' - self.assertEqual(jasyncio.run(_test()), 'success') + return "success" + + self.assertEqual(jasyncio.run(_test()), "success") async def test_run_interrupt(self): async def _test(): jasyncio.run._sigint = True + self.assertRaises(KeyboardInterrupt, jasyncio.run, _test()) async def test_run_exception(self): async def _test(): raise ValueError() + self.assertRaises(ValueError, jasyncio.run, _test()) diff --git a/tests/unit/test_machine.py b/tests/unit/test_machine.py index 455ca7188..4da67f726 100644 --- a/tests/unit/test_machine.py +++ b/tests/unit/test_machine.py @@ -7,7 +7,7 @@ from juju.machine import Machine -@mock.patch('juju.client.client.ClientFacade') +@mock.patch("juju.client.client.ClientFacade") async def test_hostname(mock_cf): model = Model() model._connector = mock.MagicMock() @@ -16,10 +16,12 @@ async def test_hostname(mock_cf): # Calling hostname() when no information is available (e.g. targeting # an older controller, agent not started yet etc.) should return None model.state.entity_data = mock.MagicMock(return_value={}) - mach = Machine('test', model) + mach = Machine("test", model) assert mach.hostname is None - model.state.entity_data = mock.MagicMock(return_value={ - 'hostname': 'thundering-herds', - }) - assert mach.hostname == 'thundering-herds' + model.state.entity_data = mock.MagicMock( + return_value={ + "hostname": "thundering-herds", + } + ) + assert mach.hostname == "thundering-herds" diff --git a/tests/unit/test_model.py b/tests/unit/test_model.py index 66a780120..252872284 100644 --- a/tests/unit/test_model.py +++ b/tests/unit/test_model.py @@ -27,77 +27,67 @@ def _make_delta(entity, type_, data=None): class TestObserver(unittest.TestCase): def _make_observer(self, *args): from juju.model import _Observer + return _Observer(*args) def test_cares_about_id(self): - id_ = 'foo' + id_ = "foo" - o = self._make_observer( - None, None, None, id_, None) + o = self._make_observer(None, None, None, id_, None) - delta = _make_delta( - 'application', 'change', dict(name=id_)) + delta = _make_delta("application", "change", dict(name=id_)) self.assertTrue(o.cares_about(delta)) def test_cares_about_type(self): - type_ = 'application' + type_ = "application" - o = self._make_observer( - None, type_, None, None, None) + o = self._make_observer(None, type_, None, None, None) - delta = _make_delta( - type_, 'change', dict(name='foo')) + delta = _make_delta(type_, "change", dict(name="foo")) self.assertTrue(o.cares_about(delta)) def test_cares_about_action(self): - action = 'change' + action = "change" - o = self._make_observer( - None, None, action, None, None) + o = self._make_observer(None, None, action, None, None) - delta = _make_delta( - 'application', action, dict(name='foo')) + delta = _make_delta("application", action, dict(name="foo")) self.assertTrue(o.cares_about(delta)) def test_cares_about_predicate(self): def predicate(delta): - return delta.data.get('fizz') == 'bang' + return delta.data.get("fizz") == "bang" - o = self._make_observer( - None, None, None, None, predicate) + o = self._make_observer(None, None, None, None, predicate) - delta = _make_delta( - 'application', 'change', dict(fizz='bang')) + delta = _make_delta("application", "change", dict(fizz="bang")) self.assertTrue(o.cares_about(delta)) class TestModelState(unittest.TestCase): def test_apply_delta(self): - model = Model() model._connector = mock.MagicMock() - delta = _make_delta('application', 'add', dict(name='foo')) + delta = _make_delta("application", "add", dict(name="foo")) # test add prev, new = model.state.apply_delta(delta) - self.assertEqual( - len(model.state.state[delta.entity][delta.get_id()]), 1) + self.assertEqual(len(model.state.state[delta.entity][delta.get_id()]), 1) self.assertIsNone(prev) self.assertIsInstance(new, Application) # test remove - delta.type = 'remove' + delta.type = "remove" prev, new = model.state.apply_delta(delta) # length of the entity history deque is now 3: # - 1 for the first delta # - 1 for the second delta # - 1 for the None sentinel appended after the 'remove' - self.assertEqual( - len(model.state.state[delta.entity][delta.get_id()]), 3) + self.assertEqual(len(model.state.state[delta.entity][delta.get_id()]), 3) self.assertIsInstance(new, Application) # new object is falsy because its data is None self.assertFalse(new) @@ -106,20 +96,18 @@ def test_apply_delta(self): class TestContextManager(unittest.IsolatedAsyncioTestCase): - @mock.patch('juju.model.Model.disconnect') - @mock.patch('juju.model.Model.connect') + @mock.patch("juju.model.Model.disconnect") + @mock.patch("juju.model.Model.connect") async def test_normal_use(self, mock_connect, mock_disconnect): - async with Model() as model: self.assertTrue(isinstance(model, Model)) self.assertTrue(mock_connect.called) self.assertTrue(mock_disconnect.called) - @mock.patch('juju.model.Model.disconnect') - @mock.patch('juju.model.Model.connect') + @mock.patch("juju.model.Model.disconnect") + @mock.patch("juju.model.Model.connect") async def test_exception(self, mock_connect, mock_disconnect): - class SomeException(Exception): pass @@ -131,7 +119,6 @@ class SomeException(Exception): self.assertTrue(mock_disconnect.called) async def test_no_current_connection(self): - class NoControllerJujuData(FileJujuData): def current_controller(self): return "" @@ -141,116 +128,123 @@ def current_controller(self): pass -@mock.patch('juju.model.Model._after_connect') +@mock.patch("juju.model.Model._after_connect") class TestModelConnect(unittest.IsolatedAsyncioTestCase): - @mock.patch('juju.client.connector.Connector.connect_model') + @mock.patch("juju.client.connector.Connector.connect_model") async def test_no_args(self, mock_connect_model, _): m = Model() mock_connect_model.side_effect = [("_", "uuid")] await m.connect() mock_connect_model.assert_called_once_with(None) - @mock.patch('juju.client.connector.Connector.connect_model') + @mock.patch("juju.client.connector.Connector.connect_model") async def test_with_model_name(self, mock_connect_model, _): m = Model() mock_connect_model.side_effect = [("_", "uuid")] - await m.connect(model_name='foo') - mock_connect_model.assert_called_once_with('foo') + await m.connect(model_name="foo") + mock_connect_model.assert_called_once_with("foo") - @mock.patch('juju.client.connector.Connector.connect_model') + @mock.patch("juju.client.connector.Connector.connect_model") async def test_with_endpoint_but_no_uuid(self, mock_connect_model, _): m = Model() mock_connect_model.side_effect = [("_", "uuid")] with self.assertRaises(TypeError): - await m.connect(endpoint='0.1.2.3:4566') + await m.connect(endpoint="0.1.2.3:4566") self.assertEqual(mock_connect_model.call_count, 0) - @mock.patch('juju.client.connector.Connector.connect') + @mock.patch("juju.client.connector.Connector.connect") async def test_with_endpoint_and_uuid_no_auth(self, mock_connect, _): m = Model() with self.assertRaises(TypeError): - await m.connect(endpoint='0.1.2.3:4566', uuid='some-uuid') + await m.connect(endpoint="0.1.2.3:4566", uuid="some-uuid") self.assertEqual(mock_connect.call_count, 0) - @mock.patch('juju.client.connector.Connector.connect') + @mock.patch("juju.client.connector.Connector.connect") async def test_with_endpoint_and_uuid_with_userpass(self, mock_connect, _): m = Model() with self.assertRaises(TypeError): - await m.connect(endpoint='0.1.2.3:4566', - uuid='some-uuid', - username='user') - await m.connect(endpoint='0.1.2.3:4566', - uuid='some-uuid', - username='user', - password='pass') - mock_connect.assert_called_once_with(endpoint='0.1.2.3:4566', - uuid='some-uuid', - username='user', - password='pass') - - @mock.patch('juju.client.connector.Connector.connect') + await m.connect(endpoint="0.1.2.3:4566", uuid="some-uuid", username="user") + await m.connect( + endpoint="0.1.2.3:4566", uuid="some-uuid", username="user", password="pass" + ) + mock_connect.assert_called_once_with( + endpoint="0.1.2.3:4566", uuid="some-uuid", username="user", password="pass" + ) + + @mock.patch("juju.client.connector.Connector.connect") async def test_with_endpoint_and_uuid_with_bakery(self, mock_connect, _): m = Model() - await m.connect(endpoint='0.1.2.3:4566', - uuid='some-uuid', - bakery_client='bakery') - mock_connect.assert_called_once_with(endpoint='0.1.2.3:4566', - uuid='some-uuid', - bakery_client='bakery') - - @mock.patch('juju.client.connector.Connector.connect') + await m.connect( + endpoint="0.1.2.3:4566", uuid="some-uuid", bakery_client="bakery" + ) + mock_connect.assert_called_once_with( + endpoint="0.1.2.3:4566", uuid="some-uuid", bakery_client="bakery" + ) + + @mock.patch("juju.client.connector.Connector.connect") async def test_with_endpoint_and_uuid_with_macaroon(self, mock_connect, _): m = Model() with self.assertRaises(TypeError): - await m.connect(endpoint='0.1.2.3:4566', - uuid='some-uuid', - username='user') - await m.connect(endpoint='0.1.2.3:4566', - uuid='some-uuid', - macaroons=['macaroon']) - mock_connect.assert_called_with(endpoint='0.1.2.3:4566', - uuid='some-uuid', - macaroons=['macaroon']) - await m.connect(endpoint='0.1.2.3:4566', - uuid='some-uuid', - bakery_client='bakery', - macaroons=['macaroon']) - mock_connect.assert_called_with(endpoint='0.1.2.3:4566', - uuid='some-uuid', - bakery_client='bakery', - macaroons=['macaroon']) - - @mock.patch('juju.client.connector.Connector.connect_model') - @mock.patch('juju.client.connector.Connector.connect') + await m.connect(endpoint="0.1.2.3:4566", uuid="some-uuid", username="user") + await m.connect( + endpoint="0.1.2.3:4566", uuid="some-uuid", macaroons=["macaroon"] + ) + mock_connect.assert_called_with( + endpoint="0.1.2.3:4566", uuid="some-uuid", macaroons=["macaroon"] + ) + await m.connect( + endpoint="0.1.2.3:4566", + uuid="some-uuid", + bakery_client="bakery", + macaroons=["macaroon"], + ) + mock_connect.assert_called_with( + endpoint="0.1.2.3:4566", + uuid="some-uuid", + bakery_client="bakery", + macaroons=["macaroon"], + ) + + @mock.patch("juju.client.connector.Connector.connect_model") + @mock.patch("juju.client.connector.Connector.connect") async def test_with_posargs(self, mock_connect, mock_connect_model, _): m = Model() mock_connect_model.side_effect = [("_", "uuid")] - await m.connect('foo') - mock_connect_model.assert_called_once_with('foo') + await m.connect("foo") + mock_connect_model.assert_called_once_with("foo") with self.assertRaises(TypeError): - await m.connect('endpoint', 'uuid') + await m.connect("endpoint", "uuid") with self.assertRaises(TypeError): - await m.connect('endpoint', 'uuid', 'user') - await m.connect('endpoint', 'uuid', 'user', 'pass') - mock_connect.assert_called_once_with(endpoint='endpoint', - uuid='uuid', - username='user', - password='pass') - await m.connect('endpoint', 'uuid', 'user', 'pass', 'cacert', 'bakery', - 'macaroons', 'max_frame_size') - mock_connect.assert_called_with(endpoint='endpoint', - uuid='uuid', - username='user', - password='pass', - cacert='cacert', - bakery_client='bakery', - macaroons='macaroons', - max_frame_size='max_frame_size') + await m.connect("endpoint", "uuid", "user") + await m.connect("endpoint", "uuid", "user", "pass") + mock_connect.assert_called_once_with( + endpoint="endpoint", uuid="uuid", username="user", password="pass" + ) + await m.connect( + "endpoint", + "uuid", + "user", + "pass", + "cacert", + "bakery", + "macaroons", + "max_frame_size", + ) + mock_connect.assert_called_with( + endpoint="endpoint", + uuid="uuid", + username="user", + password="pass", + cacert="cacert", + bakery_client="bakery", + macaroons="macaroons", + max_frame_size="max_frame_size", + ) # Patch timedelta to immediately force a timeout to avoid introducing an unnecessary delay in the test failing. # It should be safe to always set it up to lead to a timeout. -@patch('juju.model.timedelta', new=lambda *a, **kw: datetime.timedelta(0)) +@patch("juju.model.timedelta", new=lambda *a, **kw: datetime.timedelta(0)) class TestModelWaitForIdle(unittest.IsolatedAsyncioTestCase): async def test_no_args(self): m = Model() @@ -277,28 +271,35 @@ async def test_timeout(self): with self.assertRaises(jasyncio.TimeoutError) as cm: # no apps so should timeout after timeout period await m.wait_for_idle(apps=["nonexisting_app"]) - self.assertEqual(str(cm.exception), "Timed out waiting for model:\nnonexisting_app (missing)") + self.assertEqual( + str(cm.exception), "Timed out waiting for model:\nnonexisting_app (missing)" + ) @pytest.mark.wait_for_idle async def test_wait_for_active_status(self): - app_status = 'active' + app_status = "active" # create a custom apps mock from types import SimpleNamespace + app = SimpleNamespace( status=app_status, - units=[SimpleNamespace( - name="mockunit/0", - workload_status='active', - workload_status_message="workload_status_message", - machine=None, - agent_status="idle", - )], + units=[ + SimpleNamespace( + name="mockunit/0", + workload_status="active", + workload_status_message="workload_status_message", + machine=None, + agent_status="idle", + ) + ], ) app.get_status = mock.AsyncMock(return_value=app_status) apps = {"dummy_app": app} - with patch.object(Model, 'applications', new_callable=PropertyMock) as mock_apps: + with patch.object( + Model, "applications", new_callable=PropertyMock + ) as mock_apps: mock_apps.return_value = apps m = Model() @@ -309,38 +310,45 @@ async def test_wait_for_active_status(self): await m.wait_for_idle(apps=["dummy_app"], wait_for_active=True) # use both `status` and `wait_for_active` - `wait_for_active` takes precedence - await m.wait_for_idle(apps=["dummy_app"], wait_for_active=True, status="doesn't matter") + await m.wait_for_idle( + apps=["dummy_app"], wait_for_active=True, status="doesn't matter" + ) mock_apps.assert_called_with() @pytest.mark.wait_for_idle async def test_wait_for_active_units_waiting_application(self): # If the app is in waiting state, then wait more even if the units are ready - app_status = 'waiting' + app_status = "waiting" # create a custom apps mock from types import SimpleNamespace + app = SimpleNamespace( status=app_status, - units=[SimpleNamespace( - name="mockunit/0", - workload_status='active', - workload_status_message="workload_status_message", - machine=None, - agent_status="idle", - ), + units=[ + SimpleNamespace( + name="mockunit/0", + workload_status="active", + workload_status_message="workload_status_message", + machine=None, + agent_status="idle", + ), SimpleNamespace( name="mockunit/1", - workload_status='active', + workload_status="active", workload_status_message="workload_status_message", machine=None, agent_status="idle", - )], + ), + ], ) app.get_status = mock.AsyncMock(return_value=app_status) apps = {"dummy_app": app} - with patch.object(Model, 'applications', new_callable=PropertyMock) as mock_apps: + with patch.object( + Model, "applications", new_callable=PropertyMock + ) as mock_apps: mock_apps.return_value = apps m = Model() @@ -353,35 +361,44 @@ async def test_wait_for_active_units_waiting_application(self): async def test_wait_for_active_units_waiting_for_units(self): # If user wants to see a particular number of units, then application may be in a waiting # state, return when there's at least that number of units in the desired state - app_status = 'waiting' + app_status = "waiting" # create a custom apps mock from types import SimpleNamespace + app = SimpleNamespace( status=app_status, - units=[SimpleNamespace( - name="mockunit/0", - workload_status='active', - workload_status_message="workload_status_message", - machine=None, - agent_status="idle", - ), + units=[ + SimpleNamespace( + name="mockunit/0", + workload_status="active", + workload_status_message="workload_status_message", + machine=None, + agent_status="idle", + ), SimpleNamespace( name="mockunit/1", - workload_status='waiting', + workload_status="waiting", workload_status_message="workload_status_message", machine=None, agent_status="idle", - )], + ), + ], ) app.get_status = mock.AsyncMock(return_value=app_status) apps = {"dummy_app": app} - with patch.object(Model, 'applications', new_callable=PropertyMock) as mock_apps: + with patch.object( + Model, "applications", new_callable=PropertyMock + ) as mock_apps: mock_apps.return_value = apps m = Model() - await m.wait_for_idle(apps=["dummy_app"], status="active", wait_for_at_least_units=1, - timeout=None) + await m.wait_for_idle( + apps=["dummy_app"], + status="active", + wait_for_at_least_units=1, + timeout=None, + ) mock_apps.assert_called_with() diff --git a/tests/unit/test_offerendpoint.py b/tests/unit/test_offerendpoint.py index 2346321e6..80b376bb3 100644 --- a/tests/unit/test_offerendpoint.py +++ b/tests/unit/test_offerendpoint.py @@ -10,48 +10,78 @@ from juju.model import Model from juju.controller import Controller -from juju.offerendpoints import (LocalEndpoint, OfferEndpoints, OfferURL, - ParseError, maybe_parse_offer_url_source, - parse_local_endpoint, parse_offer_endpoint, - parse_offer_url) +from juju.offerendpoints import ( + LocalEndpoint, + OfferEndpoints, + OfferURL, + ParseError, + maybe_parse_offer_url_source, + parse_local_endpoint, + parse_offer_endpoint, + parse_offer_url, +) class TestOfferEndpoint(unittest.TestCase): - def test_parse_offer_endpoint(self): - - cases = {"mysql:db": OfferEndpoints("mysql", ["db"]), - "model/fred.mysql:db": OfferEndpoints("mysql", ["db"], "model", "model/fred"), - "mysql:db,log": OfferEndpoints("mysql", ["db", "log"]), - } + cases = { + "mysql:db": OfferEndpoints("mysql", ["db"]), + "model/fred.mysql:db": OfferEndpoints( + "mysql", ["db"], "model", "model/fred" + ), + "mysql:db,log": OfferEndpoints("mysql", ["db", "log"]), + } for name, case in cases.items(): self.assertEqual(parse_offer_endpoint(name), case) class TestOfferURL(unittest.TestCase): - def test_parse_offer_url(self): - cases = {"controller:user/modelname.applicationname": OfferURL(source="controller", user="user", model="modelname", application="applicationname"), - "controller:user/modelname.applicationname:rel": OfferURL(source="controller", user="user", model="modelname", application="applicationname:rel"), - "modelname.applicationname": OfferURL(model="modelname", application="applicationname"), - "modelname.applicationname:rel": OfferURL(model="modelname", application="applicationname:rel"), - "/modelname.applicationname": OfferURL(model="modelname", application="applicationname"), - "/modelname.applicationname:rel": OfferURL(model="modelname", application="applicationname:rel"), - "user/modelname.applicationname": OfferURL(user="user", model="modelname", application="applicationname"), - "user/modelname.applicationname:rel": OfferURL(user="user", model="modelname", application="applicationname:rel"), - } + cases = { + "controller:user/modelname.applicationname": OfferURL( + source="controller", + user="user", + model="modelname", + application="applicationname", + ), + "controller:user/modelname.applicationname:rel": OfferURL( + source="controller", + user="user", + model="modelname", + application="applicationname:rel", + ), + "modelname.applicationname": OfferURL( + model="modelname", application="applicationname" + ), + "modelname.applicationname:rel": OfferURL( + model="modelname", application="applicationname:rel" + ), + "/modelname.applicationname": OfferURL( + model="modelname", application="applicationname" + ), + "/modelname.applicationname:rel": OfferURL( + model="modelname", application="applicationname:rel" + ), + "user/modelname.applicationname": OfferURL( + user="user", model="modelname", application="applicationname" + ), + "user/modelname.applicationname:rel": OfferURL( + user="user", model="modelname", application="applicationname:rel" + ), + } for name, case in cases.items(): self.assertEqual(parse_offer_url(name), case) def test_parse_offer_url_failures(self): - cases = {"controller:modelname": "application offer URL is missing application", - "controller:user/modelname": "application offer URL is missing application", - "modelname": "application offer URL is missing application", - "/user/modelname": "application offer URL is missing application", - "modelname.applicationname@bad": "application name applicationname@bad not valid", - "user[bad/model.application": "user name user[bad not valid", - "user/[badmodel.application": "model name [badmodel not valid", - } + cases = { + "controller:modelname": "application offer URL is missing application", + "controller:user/modelname": "application offer URL is missing application", + "modelname": "application offer URL is missing application", + "/user/modelname": "application offer URL is missing application", + "modelname.applicationname@bad": "application name applicationname@bad not valid", + "user[bad/model.application": "user name user[bad not valid", + "user/[badmodel.application": "model name [badmodel not valid", + } for name, case in cases.items(): try: parse_offer_url(name) @@ -61,31 +91,35 @@ def test_parse_offer_url_failures(self): raise def test_maybe_parse_offer_url_source(self): - cases = {"name": ("", "name"), - "name:app": ("", "name:app"), - "name:app:rel": ("name", "app:rel"), - "name:app:rel:other": ("name", "app:rel:other"), - } + cases = { + "name": ("", "name"), + "name:app": ("", "name:app"), + "name:app:rel": ("name", "app:rel"), + "name:app:rel:other": ("name", "app:rel:other"), + } for name, case in cases.items(): self.assertEqual(maybe_parse_offer_url_source(name), case) class TestLocalEndpoint(unittest.TestCase): - def test_parse_local_endpoint(self): - cases = {"applicationname": LocalEndpoint(application="applicationname"), - "applicationname:relation": LocalEndpoint(application="applicationname", relation="relation"), - } + cases = { + "applicationname": LocalEndpoint(application="applicationname"), + "applicationname:relation": LocalEndpoint( + application="applicationname", relation="relation" + ), + } for name, case in cases.items(): self.assertEqual(parse_local_endpoint(name), case) def test_parse_local_endpoint_failures(self): - cases = {":applicationname": "endpoint :applicationname not valid", - "applicationname:": "endpoint applicationname: not valid", - "applicationname:user:relation": "endpoint applicationname:user:relation not valid", - "applicationname:_relation": "endpoint applicationname:_relation not valid", - "applicationname:0relation": "endpoint applicationname:0relation not valid", - } + cases = { + ":applicationname": "endpoint :applicationname not valid", + "applicationname:": "endpoint applicationname: not valid", + "applicationname:user:relation": "endpoint applicationname:user:relation not valid", + "applicationname:_relation": "endpoint applicationname:_relation not valid", + "applicationname:0relation": "endpoint applicationname:0relation not valid", + } for name, case in cases.items(): try: parse_local_endpoint(name) @@ -96,13 +130,18 @@ def test_parse_local_endpoint_failures(self): class TestConsume(unittest.IsolatedAsyncioTestCase): - @mock.patch.object(Model, 'connection') - @mock.patch.object(Controller, 'disconnect') - @mock.patch('juju.model._create_consume_args') - @mock.patch('juju.client.client.ApplicationFacade.from_connection') - async def test_external_controller_consume(self, mock_from_connection, - mock_controller, mock_connection, mock_create_consume_args): - """ Test consuming an offer from an external controller. This would be + @mock.patch.object(Model, "connection") + @mock.patch.object(Controller, "disconnect") + @mock.patch("juju.model._create_consume_args") + @mock.patch("juju.client.client.ApplicationFacade.from_connection") + async def test_external_controller_consume( + self, + mock_from_connection, + mock_controller, + mock_connection, + mock_create_consume_args, + ): + """Test consuming an offer from an external controller. This would be better suited as an integration test however pylibjuju does not allow for bootstrapping of extra controllers. """ @@ -112,7 +151,9 @@ async def test_external_controller_consume(self, mock_from_connection, mock_consume_details = mock.MagicMock() mock_consume_details.offer.offer_url = "user/offerer.app" - mock_controller.get_consume_details = mock.AsyncMock(return_value=mock_consume_details) + mock_controller.get_consume_details = mock.AsyncMock( + return_value=mock_consume_details + ) mock_controller.disconnect = mock.AsyncMock() mock_facade = mock.MagicMock() @@ -147,5 +188,7 @@ async def test_external_controller_consume(self, mock_from_connection, # soon be deprecated. offer_url = "user/offerer.app" await m.consume(offer_url, controller_name="externalcontroller") - m._get_source_api.assert_called_with(parse_offer_url("externalcontroller:user/offerer.app")) + m._get_source_api.assert_called_with( + parse_offer_url("externalcontroller:user/offerer.app") + ) mock_controller.get_consume_details.assert_called_with("user/offerer.app") diff --git a/tests/unit/test_origin.py b/tests/unit/test_origin.py index 40a37e7e3..9225f8e60 100644 --- a/tests/unit/test_origin.py +++ b/tests/unit/test_origin.py @@ -96,4 +96,7 @@ def test_origin(self): p = Platform.parse("amd64/ubuntu/focal") o = Origin(Source.CHARM_HUB, ch, p) - self.assertEqual(str(o), "origin using source charm-hub for channel latest/stable and platform amd64/ubuntu/focal") + self.assertEqual( + str(o), + "origin using source charm-hub for channel latest/stable and platform amd64/ubuntu/focal", + ) diff --git a/tests/unit/test_overrides.py b/tests/unit/test_overrides.py index 5643940a0..9d6e16fb8 100644 --- a/tests/unit/test_overrides.py +++ b/tests/unit/test_overrides.py @@ -8,33 +8,35 @@ # test cases ported from: # https://github.com/juju/version/blob/master/version_test.go -@pytest.mark.parametrize("input,expected", ( - (None, Number(major=0, minor=0, patch=0, tag='', build=0)), - (Number(major=1, minor=0, patch=0), Number(major=1, minor=0, patch=0)), - ({'major': 1, 'minor': 0, 'patch': 0}, Number(major=1, minor=0, patch=0)), - ("0.0.1", Number(major=0, minor=0, patch=1)), - ("0.0.2", Number(major=0, minor=0, patch=2)), - ("0.1.0", Number(major=0, minor=1, patch=0)), - ("0.2.3", Number(major=0, minor=2, patch=3)), - ("1.0.0", Number(major=1, minor=0, patch=0)), - ("10.234.3456", Number(major=10, minor=234, patch=3456)), - ("10.234.3456.1", Number(major=10, minor=234, patch=3456, build=1)), - ("10.234.3456.64", Number(major=10, minor=234, patch=3456, build=64)), - ("10.235.3456", Number(major=10, minor=235, patch=3456)), - ("1.21-alpha1", Number(major=1, minor=21, patch=1, tag="alpha")), - ("1.21-alpha1.1", Number(major=1, minor=21, patch=1, tag="alpha", - build=1)), - ("1.21-alpha10", Number(major=1, minor=21, patch=10, tag="alpha")), - ("1.21.0", Number(major=1, minor=21)), - ("1234567890.2.1", TypeError), - ("0.2..1", TypeError), - ("1.21.alpha1", TypeError), - ("1.21-alpha", TypeError), - ("1.21-alpha1beta", TypeError), - ("1.21-alpha-dev", TypeError), - ("1.21-alpha_dev3", TypeError), - ("1.21-alpha123dev3", TypeError), -)) +@pytest.mark.parametrize( + "input,expected", + ( + (None, Number(major=0, minor=0, patch=0, tag="", build=0)), + (Number(major=1, minor=0, patch=0), Number(major=1, minor=0, patch=0)), + ({"major": 1, "minor": 0, "patch": 0}, Number(major=1, minor=0, patch=0)), + ("0.0.1", Number(major=0, minor=0, patch=1)), + ("0.0.2", Number(major=0, minor=0, patch=2)), + ("0.1.0", Number(major=0, minor=1, patch=0)), + ("0.2.3", Number(major=0, minor=2, patch=3)), + ("1.0.0", Number(major=1, minor=0, patch=0)), + ("10.234.3456", Number(major=10, minor=234, patch=3456)), + ("10.234.3456.1", Number(major=10, minor=234, patch=3456, build=1)), + ("10.234.3456.64", Number(major=10, minor=234, patch=3456, build=64)), + ("10.235.3456", Number(major=10, minor=235, patch=3456)), + ("1.21-alpha1", Number(major=1, minor=21, patch=1, tag="alpha")), + ("1.21-alpha1.1", Number(major=1, minor=21, patch=1, tag="alpha", build=1)), + ("1.21-alpha10", Number(major=1, minor=21, patch=10, tag="alpha")), + ("1.21.0", Number(major=1, minor=21)), + ("1234567890.2.1", TypeError), + ("0.2..1", TypeError), + ("1.21.alpha1", TypeError), + ("1.21-alpha", TypeError), + ("1.21-alpha1beta", TypeError), + ("1.21-alpha-dev", TypeError), + ("1.21-alpha_dev3", TypeError), + ("1.21-alpha123dev3", TypeError), + ), +) def test_number(input, expected): if expected is TypeError: with pytest.raises(expected): @@ -48,26 +50,31 @@ def test_number(input, expected): # test cases ported from: # https://github.com/juju/version/blob/master/version_test.go -@pytest.mark.parametrize("input,expected", ( - (None, Binary(Number(), None, None)), - (Binary(Number(1), 'trusty', 'amd64'), Binary(Number(1), - 'trusty', 'amd64')), - ({'number': {'major': 1}, - 'series': 'trusty', - 'arch': 'amd64'}, Binary(Number(1), 'trusty', 'amd64')), - ("1.2.3-trusty-amd64", Binary(Number(1, 2, 3, "", 0), - "trusty", "amd64")), - ("1.2.3.4-trusty-amd64", Binary(Number(1, 2, 3, "", 4), - "trusty", "amd64")), - ("1.2-alpha3-trusty-amd64", Binary(Number(1, 2, 3, "alpha", 0), - "trusty", "amd64")), - ("1.2-alpha3.4-trusty-amd64", Binary(Number(1, 2, 3, "alpha", 4), - "trusty", "amd64")), - ("1.2.3", TypeError), - ("1.2-beta1", TypeError), - ("1.2.3--amd64", TypeError), - ("1.2.3-trusty-", TypeError), -)) +@pytest.mark.parametrize( + "input,expected", + ( + (None, Binary(Number(), None, None)), + (Binary(Number(1), "trusty", "amd64"), Binary(Number(1), "trusty", "amd64")), + ( + {"number": {"major": 1}, "series": "trusty", "arch": "amd64"}, + Binary(Number(1), "trusty", "amd64"), + ), + ("1.2.3-trusty-amd64", Binary(Number(1, 2, 3, "", 0), "trusty", "amd64")), + ("1.2.3.4-trusty-amd64", Binary(Number(1, 2, 3, "", 4), "trusty", "amd64")), + ( + "1.2-alpha3-trusty-amd64", + Binary(Number(1, 2, 3, "alpha", 0), "trusty", "amd64"), + ), + ( + "1.2-alpha3.4-trusty-amd64", + Binary(Number(1, 2, 3, "alpha", 4), "trusty", "amd64"), + ), + ("1.2.3", TypeError), + ("1.2-beta1", TypeError), + ("1.2.3--amd64", TypeError), + ("1.2.3-trusty-", TypeError), + ), +) def test_binary(input, expected): if expected is TypeError: with pytest.raises(expected): diff --git a/tests/unit/test_placement.py b/tests/unit/test_placement.py index 74c64404e..3c9463be5 100644 --- a/tests/unit/test_placement.py +++ b/tests/unit/test_placement.py @@ -11,7 +11,6 @@ class TestPlacement(unittest.TestCase): - def test_parse_both_specified(self): res = placement.parse("foo:bar") self.assertEqual(res[0].scope, "foo") diff --git a/tests/unit/test_proxy.py b/tests/unit/test_proxy.py index a4e9a15f8..c341432fa 100644 --- a/tests/unit/test_proxy.py +++ b/tests/unit/test_proxy.py @@ -8,24 +8,29 @@ class TestJujuDataFactory(unittest.TestCase): - def test_proxy_from_config_unknown_type(self): """ Test that a unknown proxy type results in a UnknownProxyTypeError exception """ - self.assertRaises(ValueError, proxy_from_config, { - "config": {}, - "type": "does-not-exists", - }) + self.assertRaises( + ValueError, + proxy_from_config, + { + "config": {}, + "type": "does-not-exists", + }, + ) def test_proxy_from_config_missing_type(self): """ Test that a nil proxy type returns None """ - self.assertIsNone(proxy_from_config({ - "config": {}, - })) + self.assertIsNone( + proxy_from_config({ + "config": {}, + }) + ) def test_proxy_from_config_non_arg(self): """ diff --git a/tests/unit/test_registration_string.py b/tests/unit/test_registration_string.py index c1e00a1c6..1713e9d61 100644 --- a/tests/unit/test_registration_string.py +++ b/tests/unit/test_registration_string.py @@ -16,6 +16,11 @@ def test_generate_user_controller_access_token(self): endpoints = ["192.168.1.1:17070", "192.168.1.2:17070", "192.168.1.3:17070"] username = "test-01234" secret_key = "paNZrqOw51ONk1kTER6rkm4hdPcg5VgC/dzXYxtUZaM=" - reg_string = generate_user_controller_access_token(username, endpoints, secret_key, controller_name) - assert reg_string == b"MH4TCnRlc3QtMDEyMzQwORMRMTkyLjE2OC4xLjE6MTcwNzATETE5Mi4xNjguMS4yOjE3MDcwExExOTIuMTY4" \ - b"LjEuMzoxNzA3MAQgpaNZrqOw51ONk1kTER6rkm4hdPcg5VgC_dzXYxtUZaMTE2xvY2FsaG9zdC1sb2NhbGhvc3QA" + reg_string = generate_user_controller_access_token( + username, endpoints, secret_key, controller_name + ) + assert ( + reg_string + == b"MH4TCnRlc3QtMDEyMzQwORMRMTkyLjE2OC4xLjE6MTcwNzATETE5Mi4xNjguMS4yOjE3MDcwExExOTIuMTY4" + b"LjEuMzoxNzA3MAQgpaNZrqOw51ONk1kTER6rkm4hdPcg5VgC_dzXYxtUZaMTE2xvY2FsaG9zdC1sb2NhbGhvc3QA" + ) diff --git a/tests/unit/test_relation.py b/tests/unit/test_relation.py index 52d86bc67..5014b37ac 100644 --- a/tests/unit/test_relation.py +++ b/tests/unit/test_relation.py @@ -23,9 +23,13 @@ def test_relation_does_not_match(self): model = Model() model._connector = mock.MagicMock() - delta = _make_delta('application', 'add', dict(name='foo')) + delta = _make_delta("application", "add", dict(name="foo")) model.state.apply_delta(delta) - delta = _make_delta('relation', 'bar', dict(id="uuid-1234", name='foo', endpoints=[{"application-name": "foo"}])) + delta = _make_delta( + "relation", + "bar", + dict(id="uuid-1234", name="foo", endpoints=[{"application-name": "foo"}]), + ) model.state.apply_delta(delta) rel = Relation("uuid-1234", model) @@ -35,9 +39,13 @@ def test_relation_does_match(self): model = Model() model._connector = mock.MagicMock() - delta = _make_delta('application', 'add', dict(name='foo')) + delta = _make_delta("application", "add", dict(name="foo")) model.state.apply_delta(delta) - delta = _make_delta('relation', 'bar', dict(id="uuid-1234", name='foo', endpoints=[{"application-name": "foo"}])) + delta = _make_delta( + "relation", + "bar", + dict(id="uuid-1234", name="foo", endpoints=[{"application-name": "foo"}]), + ) model.state.apply_delta(delta) rel = Relation("uuid-1234", model) @@ -47,9 +55,13 @@ def test_relation_does_match_remote_app(self): model = Model() model._connector = mock.MagicMock() - delta = _make_delta('remoteApplication', 'add', dict(name='foo')) + delta = _make_delta("remoteApplication", "add", dict(name="foo")) model.state.apply_delta(delta) - delta = _make_delta('relation', 'bar', dict(id="uuid-1234", name='foo', endpoints=[{"application-name": "foo"}])) + delta = _make_delta( + "relation", + "bar", + dict(id="uuid-1234", name="foo", endpoints=[{"application-name": "foo"}]), + ) model.state.apply_delta(delta) rel = Relation("uuid-1234", model) @@ -59,7 +71,11 @@ def test_relation_does_not_match_anything(self): model = Model() model._connector = mock.MagicMock() - delta = _make_delta('relation', 'bar', dict(id="uuid-1234", name='foo', endpoints=[{"application-name": "foo"}])) + delta = _make_delta( + "relation", + "bar", + dict(id="uuid-1234", name="foo", endpoints=[{"application-name": "foo"}]), + ) model.state.apply_delta(delta) rel = Relation("uuid-1234", model) diff --git a/tests/unit/test_secrets.py b/tests/unit/test_secrets.py index e386e93b9..1abca5483 100644 --- a/tests/unit/test_secrets.py +++ b/tests/unit/test_secrets.py @@ -18,21 +18,20 @@ def test_bad_key(self): create_secret_data(["=bar"]) def test_good_key_values(self): - self.assertDictEqual(create_secret_data(["foo=bar", "hello=world", "goodbye#base64=world"]), - { - "foo": "YmFy", - "hello": "d29ybGQ=", - "goodbye": "world"}) + self.assertDictEqual( + create_secret_data(["foo=bar", "hello=world", "goodbye#base64=world"]), + {"foo": "YmFy", "hello": "d29ybGQ=", "goodbye": "world"}, + ) def test_key_content_too_large(self): with pytest.raises(ValueError): - create_secret_data(["foo=" + ('a' * 8 * 1024)]) + create_secret_data(["foo=" + ("a" * 8 * 1024)]) def test_total_content_too_large(self): args = [] - content = 'a' * 4 * 1024 + content = "a" * 4 * 1024 for i in range(20): - args.append(f'key{i}={content}') + args.append(f"key{i}={content}") with pytest.raises(ValueError): create_secret_data(args) @@ -52,12 +51,15 @@ def test_secret_key_from_file(self): data = create_secret_data(["key1=value1", f"key2#file={file_path}"]) - self.assertDictEqual(data, { - "key1": "dmFsdWUx", - "key2": ( - 'ICAgICAgICAgIC0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQogICAgICAgICAgTUlJRllqQ0NBMHFnQXdJQkFnSVFLYVBORDlZZ2dJRzYrak9jZ21wazNEQU5CZ2txaGtpRzl3MEJBUXNGQURBegogICAgICAgICAgTVJ3d0dnWURWUVFLRXhOc2FXNTFlR052Ym5SaGFXNWxjbk11YjNKbk1STXdFUVlEVlFRRERBcDBhVzFBWld4MwogICAgICAgICAgLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQ==' - ), - }) + self.assertDictEqual( + data, + { + "key1": "dmFsdWUx", + "key2": ( + "ICAgICAgICAgIC0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQogICAgICAgICAgTUlJRllqQ0NBMHFnQXdJQkFnSVFLYVBORDlZZ2dJRzYrak9jZ21wazNEQU5CZ2txaGtpRzl3MEJBUXNGQURBegogICAgICAgICAgTVJ3d0dnWURWUVFLRXhOc2FXNTFlR052Ym5SaGFXNWxjbk11YjNKbk1STXdFUVlEVlFRRERBcDBhVzFBWld4MwogICAgICAgICAgLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQ==" + ), + }, + ) class TestReadSecretData(unittest.TestCase): @@ -75,33 +77,33 @@ def test_yaml_file(self): with tempfile.TemporaryDirectory() as temp_dir: file_path = os.path.join(temp_dir, "secret.yaml") - with open(file_path, 'w') as file: + with open(file_path, "w") as file: file.write(data) attrs = read_secret_data(file_path) - self.assertDictEqual(attrs, { - "hello": "d29ybGQ=", - "goodbye": "world", - "another-key": "YiJHSUY4OWFceDBjXHgwMFx4MGNceDAwXHg4NFx4MDBceDAwXHhmZlx4ZmZceGY3XHhmNVx4ZjVceGVlXHhlOVx4ZTlceGU1ZmZmXHgwMFx4MDBceDAwXHhlN1x4ZTdceGU3Xl5eXHhmM1x4ZjNceGVkXHg4ZVx4OGVceDhlXHhlMFx4ZTBceGUwXHg5Zlx4OWZceDlmXHg5M1x4OTNceDkzXHhhN1x4YTdceGE3XHg5ZVx4OWVceDllaWlpY2NjXHhhM1x4YTNceGEzXHg4NFx4ODRceDg0XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5IVx4ZmVceDBlTWFkZSB3aXRoIEdJTVBceDAwLFx4MDBceDAwXHgwMFx4MDBceDBjXHgwMFx4MGNceDAwXHgwMFx4MDUsICBceDhlXHg4MTBceDllXHhlM0BceDE0XHhlOGlceDEwXHhjNFx4ZDFceDhhXHgwOFx4MWNceGNmXHg4ME0kelx4ZWZceGZmMFx4ODVwXHhiOFx4YjAxZlxyXHgxYlx4Y2VceDAxXHhjM1x4MDFceDFlXHgxMCcgXHg4MlxuXHgwMVx4MDA7Ig==" - }) + self.assertDictEqual( + attrs, + { + "hello": "d29ybGQ=", + "goodbye": "world", + "another-key": "YiJHSUY4OWFceDBjXHgwMFx4MGNceDAwXHg4NFx4MDBceDAwXHhmZlx4ZmZceGY3XHhmNVx4ZjVceGVlXHhlOVx4ZTlceGU1ZmZmXHgwMFx4MDBceDAwXHhlN1x4ZTdceGU3Xl5eXHhmM1x4ZjNceGVkXHg4ZVx4OGVceDhlXHhlMFx4ZTBceGUwXHg5Zlx4OWZceDlmXHg5M1x4OTNceDkzXHhhN1x4YTdceGE3XHg5ZVx4OWVceDllaWlpY2NjXHhhM1x4YTNceGEzXHg4NFx4ODRceDg0XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5IVx4ZmVceDBlTWFkZSB3aXRoIEdJTVBceDAwLFx4MDBceDAwXHgwMFx4MDBceDBjXHgwMFx4MGNceDAwXHgwMFx4MDUsICBceDhlXHg4MTBceDllXHhlM0BceDE0XHhlOGlceDEwXHhjNFx4ZDFceDhhXHgwOFx4MWNceGNmXHg4ME0kelx4ZWZceGZmMFx4ODVwXHhiOFx4YjAxZlxyXHgxYlx4Y2VceDAxXHhjM1x4MDFceDFlXHgxMCcgXHg4MlxuXHgwMVx4MDA7Ig==", + }, + ) def test_json_file(self): - data = ''' + data = """ { "hello": "world", "goodbye#base64": "world" } - ''' + """ with tempfile.TemporaryDirectory() as temp_dir: file_path = os.path.join(temp_dir, "secret.json") - with open(file_path, 'w', encoding='utf-8') as file: + with open(file_path, "w", encoding="utf-8") as file: file.write(data) attrs = read_secret_data(file_path) - self.assertDictEqual(attrs, { - "hello": "d29ybGQ=", - "goodbye": "world" - }) + self.assertDictEqual(attrs, {"hello": "d29ybGQ=", "goodbye": "world"}) diff --git a/tests/unit/test_status.py b/tests/unit/test_status.py index 5d891e03f..caf0bcb4e 100644 --- a/tests/unit/test_status.py +++ b/tests/unit/test_status.py @@ -11,16 +11,16 @@ class TestStatus(unittest.TestCase): def test_derive_status_with_empty_list(self): result = derive_status([]) - self.assertEqual(result, 'unknown') + self.assertEqual(result, "unknown") def test_derive_status_with_unknown(self): - result = derive_status(['unknown']) - self.assertEqual(result, 'unknown') + result = derive_status(["unknown"]) + self.assertEqual(result, "unknown") def test_derive_status_with_invalid(self): - result = derive_status(['boom']) - self.assertEqual(result, 'unknown') + result = derive_status(["boom"]) + self.assertEqual(result, "unknown") def test_derive_status_with_highest_value(self): - result = derive_status(sample(['error', 'active', 'terminated'], 3)) - self.assertEqual(result, 'error') + result = derive_status(sample(["error", "active", "terminated"], 3)) + self.assertEqual(result, "error") diff --git a/tests/unit/test_unit.py b/tests/unit/test_unit.py index f062016f3..4504f21f4 100644 --- a/tests/unit/test_unit.py +++ b/tests/unit/test_unit.py @@ -8,128 +8,68 @@ from juju.unit import Unit -@mock.patch('juju.client.client.ClientFacade') +@mock.patch("juju.client.client.ClientFacade") async def test_unit_is_leader(mock_cf): tests = [ { - 'applications': { - 'test': { - 'units': { - 'test/0': { - 'subordinates': { - 'test-sub/0': { - 'leader': True - } - } - } + "applications": { + "test": { + "units": { + "test/0": {"subordinates": {"test-sub/0": {"leader": True}}} } }, - 'test-sub': { - 'subordinate-to': [ - 'test' - ] - } + "test-sub": {"subordinate-to": ["test"]}, }, - 'description': "Tests that subordinate units reports is leader correctly", - 'unit': 'test-sub/0', - 'rval': True + "description": "Tests that subordinate units reports is leader correctly", + "unit": "test-sub/0", + "rval": True, }, { - 'applications': { - 'test': { - 'units': { - 'test/0': { - 'leader': True - } - } - } - }, - 'description': "Tests that unit reports is leader correctly", - 'unit': 'test/0', - 'rval': True + "applications": {"test": {"units": {"test/0": {"leader": True}}}}, + "description": "Tests that unit reports is leader correctly", + "unit": "test/0", + "rval": True, }, { - 'applications': {}, - 'description': "Tests that non existent apps return False as leader", - 'unit': 'test/0', - 'rval': False + "applications": {}, + "description": "Tests that non existent apps return False as leader", + "unit": "test/0", + "rval": False, }, { - 'applications': { - 'test': { - 'units': {} - } - }, - 'description': "Tests that apps with no units report False as leader", - 'unit': 'test/0', - 'rval': False + "applications": {"test": {"units": {}}}, + "description": "Tests that apps with no units report False as leader", + "unit": "test/0", + "rval": False, }, { - 'applications': { - 'test': { - 'units': { - 'test/0': { - 'subordinates': { - 'test-sub/0': {} - } - } - } - }, - 'test1': { - 'units': { - 'test1/0': { - 'subordinates': { - 'test-sub/1': { - 'leader': True - } - } - } + "applications": { + "test": {"units": {"test/0": {"subordinates": {"test-sub/0": {}}}}}, + "test1": { + "units": { + "test1/0": {"subordinates": {"test-sub/1": {"leader": True}}} } }, - 'test-sub': { - 'subordinate-to': [ - 'test', - 'test1' - ] - } + "test-sub": {"subordinate-to": ["test", "test1"]}, }, - 'description': "Tests that subordinate units of multiple applications reports is leader correctly", - 'unit': 'test-sub/1', - 'rval': True + "description": "Tests that subordinate units of multiple applications reports is leader correctly", + "unit": "test-sub/1", + "rval": True, }, { - 'applications': { - 'test': { - 'units': { - 'test/0': { - 'subordinates': { - 'test-sub/0': { - 'leader': True - } - } - } - } - }, - 'test1': { - 'units': { - 'test1/0': { - 'subordinates': { - 'test-sub/1': {} - } - } + "applications": { + "test": { + "units": { + "test/0": {"subordinates": {"test-sub/0": {"leader": True}}} } }, - 'test-sub': { - 'subordinate-to': [ - 'test', - 'test1' - ] - } + "test1": {"units": {"test1/0": {"subordinates": {"test-sub/1": {}}}}}, + "test-sub": {"subordinate-to": ["test", "test1"]}, }, - 'description': "Tests that subordinate units of multiple applications reports is leader correctly", - 'unit': 'test-sub/1', - 'rval': False - } + "description": "Tests that subordinate units of multiple applications reports is leader correctly", + "unit": "test-sub/1", + "rval": False, + }, ] model = Model() @@ -141,7 +81,7 @@ async def test_unit_is_leader(mock_cf): client_facade.FullStatus = mock.AsyncMock(return_value=status) unit = Unit("test", model) - unit.name = test['unit'] + unit.name = test["unit"] rval = await unit.is_leader_from_status() - assert rval == test['rval'] + assert rval == test["rval"] diff --git a/tests/unit/test_url.py b/tests/unit/test_url.py index cd872f65e..9c3514b77 100644 --- a/tests/unit/test_url.py +++ b/tests/unit/test_url.py @@ -17,24 +17,45 @@ def test_parse_v1_user(self): def test_parse_v1_revision(self): u = URL.parse("cs:~fred/mysql-1") - self.assertEqual(u, URL(Schema.CHARM_STORE, name="mysql", user="fred", revision=1)) + self.assertEqual( + u, URL(Schema.CHARM_STORE, name="mysql", user="fred", revision=1) + ) def test_parse_v1_large_revision(self): u = URL.parse("cs:~fred/mysql-12345") - self.assertEqual(u, URL(Schema.CHARM_STORE, name="mysql", user="fred", revision=12345)) + self.assertEqual( + u, URL(Schema.CHARM_STORE, name="mysql", user="fred", revision=12345) + ) def test_parse_v1_series(self): u = URL.parse("cs:~fred/bionic/mysql-1") - self.assertEqual(u, URL(Schema.CHARM_STORE, name="mysql", user="fred", revision=1, series="bionic")) + self.assertEqual( + u, + URL( + Schema.CHARM_STORE, + name="mysql", + user="fred", + revision=1, + series="bionic", + ), + ) class TestURLV2(unittest.TestCase): - schema = Schema.CHARM_HUB def test_parse_charmhub(self): u = URL.parse(f"{self.schema}:arm64/bionic/mysql-1") - self.assertEqual(u, URL(self.schema, name="mysql", architecture="arm64", series="bionic", revision=1)) + self.assertEqual( + u, + URL( + self.schema, + name="mysql", + architecture="arm64", + series="bionic", + revision=1, + ), + ) def test_parse_charmhub_with_no_series(self): u = URL.parse(f"{self.schema}:arm64/mysql") diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index 84f7d214a..6459970f9 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -4,10 +4,17 @@ import unittest import pytest -from juju.utils import series_selector, get_base_from_origin_or_channel, \ - parse_base_arg, DEFAULT_SUPPORTED_LTS, get_series_version, \ - get_version_series, base_channel_to_series, \ - base_channel_from_series, get_os_from_series +from juju.utils import ( + series_selector, + get_base_from_origin_or_channel, + parse_base_arg, + DEFAULT_SUPPORTED_LTS, + get_series_version, + get_version_series, + base_channel_to_series, + base_channel_from_series, + get_os_from_series, +) from juju.errors import JujuError from juju.url import URL from juju import utils @@ -17,39 +24,48 @@ class TestDirResolve(unittest.TestCase): def test_config_dir(self): config_dir = utils.juju_config_dir() - assert 'local/share/juju' in config_dir + assert "local/share/juju" in config_dir def test_juju_ssh_key_paths(self): public, private = utils.juju_ssh_key_paths() - assert public.endswith('ssh/juju_id_rsa.pub') - assert private.endswith('ssh/juju_id_rsa') + assert public.endswith("ssh/juju_id_rsa.pub") + assert private.endswith("ssh/juju_id_rsa") class TestBaseArgument(unittest.TestCase): def test_parse_base_arg(self): - base = parse_base_arg('ubuntu@22.04') + base = parse_base_arg("ubuntu@22.04") assert isinstance(base, client.Base) - assert base.name == 'ubuntu' - assert base.channel == '22.04' + assert base.name == "ubuntu" + assert base.channel == "22.04" class TestSeriesSelector(unittest.TestCase): def test_series_arg(self): - assert series_selector('jammy', []) == 'jammy' - assert series_selector('jammy', ['jammy']) == 'jammy' + assert series_selector("jammy", []) == "jammy" + assert series_selector("jammy", ["jammy"]) == "jammy" with pytest.raises(JujuError): - series_selector(series_arg='jammy', supported_series=['focal']) - assert series_selector(series_arg='foo', supported_series=[], force=True) == 'foo' + series_selector(series_arg="jammy", supported_series=["focal"]) + assert ( + series_selector(series_arg="foo", supported_series=[], force=True) == "foo" + ) def test_charm_url(self): - assert series_selector(charm_url=URL.parse('ch:jammy/ubuntu'), supported_series=['jammy']) == 'jammy' + assert ( + series_selector( + charm_url=URL.parse("ch:jammy/ubuntu"), supported_series=["jammy"] + ) + == "jammy" + ) def test_model_config(self): - mconf = {'default-base': client.ConfigValue(value='ubuntu@22.04')} - assert series_selector(model_config=mconf, supported_series=['jammy']) == 'jammy' + mconf = {"default-base": client.ConfigValue(value="ubuntu@22.04")} + assert ( + series_selector(model_config=mconf, supported_series=["jammy"]) == "jammy" + ) def test_charm_list_series(self): - assert series_selector(supported_series=['focal', 'jammy']) == 'jammy' + assert series_selector(supported_series=["focal", "jammy"]) == "jammy" def test_return_lts(self): assert series_selector() == DEFAULT_SUPPORTED_LTS @@ -57,92 +73,145 @@ def test_return_lts(self): class TestBaseChannelOriginUtils(unittest.TestCase): def test_get_series_version(self): - assert get_series_version(series_name='kubernetes') == 'kubernetes' - assert get_series_version(series_name='jammy') == '22.04' + assert get_series_version(series_name="kubernetes") == "kubernetes" + assert get_series_version(series_name="jammy") == "22.04" def test_get_version_series(self): - assert get_version_series(version='22.04') == 'jammy' + assert get_version_series(version="22.04") == "jammy" def test_base_channel_to_series(self): - assert base_channel_to_series(channel='22.04/stable') == 'jammy' + assert base_channel_to_series(channel="22.04/stable") == "jammy" def test_base_channel_from_series(self): - assert base_channel_from_series(track='latest', risk='stable', series='jammy') == \ - '22.04/stable' + assert ( + base_channel_from_series(track="latest", risk="stable", series="jammy") + == "22.04/stable" + ) def test_get_os_from_series(self): - assert get_os_from_series('jammy') == 'ubuntu' + assert get_os_from_series("jammy") == "ubuntu" def test_get_base_from_series(self): - orgn = client.CharmOrigin(track='latest', risk='edge') - assert get_base_from_origin_or_channel(orgn, series='jammy') == client.Base('22.04/edge', 'ubuntu') + orgn = client.CharmOrigin(track="latest", risk="edge") + assert get_base_from_origin_or_channel(orgn, series="jammy") == client.Base( + "22.04/edge", "ubuntu" + ) class TestShouldUpgradeResource(unittest.TestCase): def test_should_upgrade_resource_no_same_rev(self): # fields are trimmed for readability - res = {'created-at': '2019-10-24T20:45:19.201000', - 'description': 'The policy.d overrides file', - 'download': {'hash-sha-256': 'e3b0c4', 'hash-sha-384': '38b060a751ac914898b95b', - 'hash-sha-512': 'cf83e1357eef1a538327af927da3e', - 'hash-sha3-384': '0c63a75b1bbed1e058d5f004', - 'size': 0, - 'url': 'https://api.charmhub.io/api/v1/resMGU0L516cGTTwNam.policyd-override_0'}, - 'filename': 'policyd-override.zip', 'name': 'policyd-override', 'revision': 0, 'type': 'file'} + res = { + "created-at": "2019-10-24T20:45:19.201000", + "description": "The policy.d overrides file", + "download": { + "hash-sha-256": "e3b0c4", + "hash-sha-384": "38b060a751ac914898b95b", + "hash-sha-512": "cf83e1357eef1a538327af927da3e", + "hash-sha3-384": "0c63a75b1bbed1e058d5f004", + "size": 0, + "url": "https://api.charmhub.io/api/v1/resMGU0L516cGTTwNam.policyd-override_0", + }, + "filename": "policyd-override.zip", + "name": "policyd-override", + "revision": 0, + "type": "file", + } existing = { - 'policyd-override': - client.Resource(charmresource=None, - application='keystone', id_='keystone/policyd-override', pending_id='', - timestamp='0001-01-01T00:00:00Z', username='', name='policyd-override', - origin='store', type='file', path='policyd-override.zip', - description='The policy.doverrides file', - revision=0, fingerprint='OLBgp1GsljhM2TJ+sbHjaiH9txEUvgdDTAzHv2P24donTt6/529l+9Ua0vFImLlb', - size=0)} + "policyd-override": client.Resource( + charmresource=None, + application="keystone", + id_="keystone/policyd-override", + pending_id="", + timestamp="0001-01-01T00:00:00Z", + username="", + name="policyd-override", + origin="store", + type="file", + path="policyd-override.zip", + description="The policy.doverrides file", + revision=0, + fingerprint="OLBgp1GsljhM2TJ+sbHjaiH9txEUvgdDTAzHv2P24donTt6/529l+9Ua0vFImLlb", + size=0, + ) + } assert not utils.should_upgrade_resource(res, existing) def test_should_upgrade_resource_no_local_upload(self): # fields are trimmed for readability - res = {'created-at': '2019-10-24T20:45:19.201000', - 'description': 'The policy.d overrides file', - 'download': {'hash-sha-256': 'e3b0c4', 'hash-sha-384': '38b060a751ac914898b95b', - 'hash-sha-512': 'cf83e1357eef1a538327af927da3e', - 'hash-sha3-384': '0c63a75b1bbed1e058d5f004', - 'size': 0, - 'url': 'https://api.charmhub.io/api/v1/resMGU0L516cGTTwNam.policyd-override_0'}, - 'filename': 'policyd-override.zip', 'name': 'local_res', 'revision': 0, - 'type': 'file'} + res = { + "created-at": "2019-10-24T20:45:19.201000", + "description": "The policy.d overrides file", + "download": { + "hash-sha-256": "e3b0c4", + "hash-sha-384": "38b060a751ac914898b95b", + "hash-sha-512": "cf83e1357eef1a538327af927da3e", + "hash-sha3-384": "0c63a75b1bbed1e058d5f004", + "size": 0, + "url": "https://api.charmhub.io/api/v1/resMGU0L516cGTTwNam.policyd-override_0", + }, + "filename": "policyd-override.zip", + "name": "local_res", + "revision": 0, + "type": "file", + } existing = { - 'local_res': - client.Resource(charmresource=None, - application='keystone', id_='keystone/policyd-override', pending_id='', - timestamp='0001-01-01T00:00:00Z', username='', name='policyd-override', - origin='upload', type='file', path='policyd-override.zip', - description='The policy.doverrides file', - revision=0, fingerprint='OLBgp1GsljhM2TJ+sbHjaiH9txEUvgdDTAzHv2P24donTt6/529l+9Ua0vFImLlb', - size=0)} + "local_res": client.Resource( + charmresource=None, + application="keystone", + id_="keystone/policyd-override", + pending_id="", + timestamp="0001-01-01T00:00:00Z", + username="", + name="policyd-override", + origin="upload", + type="file", + path="policyd-override.zip", + description="The policy.doverrides file", + revision=0, + fingerprint="OLBgp1GsljhM2TJ+sbHjaiH9txEUvgdDTAzHv2P24donTt6/529l+9Ua0vFImLlb", + size=0, + ) + } assert not utils.should_upgrade_resource(res, existing) def test_should_upgrade_resource_yes_new_revision(self): # fields are trimmed for readability - res = {'created-at': '2019-10-24T20:45:19.201000', - 'description': 'The policy.d overrides file', - 'download': {'hash-sha-256': 'e3b0c4', 'hash-sha-384': '38b060a751ac914898b95b', - 'hash-sha-512': 'cf83e1357eef1a538327af927da3e', - 'hash-sha3-384': '0c63a75b1bbed1e058d5f004', - 'size': 0, - 'url': 'https://api.charmhub.io/api/v1/resMGU0L516cGTTwNam.policyd-override_0'}, - 'filename': 'policyd-override.zip', 'name': 'policyd-override', 'revision': 1, - 'type': 'file'} + res = { + "created-at": "2019-10-24T20:45:19.201000", + "description": "The policy.d overrides file", + "download": { + "hash-sha-256": "e3b0c4", + "hash-sha-384": "38b060a751ac914898b95b", + "hash-sha-512": "cf83e1357eef1a538327af927da3e", + "hash-sha3-384": "0c63a75b1bbed1e058d5f004", + "size": 0, + "url": "https://api.charmhub.io/api/v1/resMGU0L516cGTTwNam.policyd-override_0", + }, + "filename": "policyd-override.zip", + "name": "policyd-override", + "revision": 1, + "type": "file", + } existing = { - 'policyd-override': - client.Resource(charmresource=None, - application='keystone', id_='keystone/policyd-override', pending_id='', - timestamp='0001-01-01T00:00:00Z', username='', name='policyd-override', - origin='store', type='file', path='policyd-override.zip', - description='The policy.doverrides file', - revision=0, fingerprint='OLBgp1GsljhM2TJ+sbHjaiH9txEUvgdDTAzHv2P24donTt6/529l+9Ua0vFImLlb', - size=0)} + "policyd-override": client.Resource( + charmresource=None, + application="keystone", + id_="keystone/policyd-override", + pending_id="", + timestamp="0001-01-01T00:00:00Z", + username="", + name="policyd-override", + origin="store", + type="file", + path="policyd-override.zip", + description="The policy.doverrides file", + revision=0, + fingerprint="OLBgp1GsljhM2TJ+sbHjaiH9txEUvgdDTAzHv2P24donTt6/529l+9Ua0vFImLlb", + size=0, + ) + } assert utils.should_upgrade_resource(res, existing) diff --git a/tests/utils.py b/tests/utils.py index 2ae8e0f7b..d328e7ee5 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -7,9 +7,9 @@ MB = 1 GB = 1024 -SSH_KEY = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsYMJGNGG74HAJha3n2CFmWYsOOaORnJK6VqNy86pj0MIpvRXBzFzVy09uPQ66GOQhTEoJHEqE77VMui7+62AcMXT+GG7cFHcnU8XVQsGM6UirCcNyWNysfiEMoAdZScJf/GvoY87tMEszhZIUV37z8PUBx6twIqMdr31W1J0IaPa+sV6FEDadeLaNTvancDcHK1zuKsL39jzAg7+LYjKJfEfrsQP+lj/EQcjtKqlhVS5kzsJVfx8ZEd0xhW5G7N6bCdKNalS8mKCMaBXJpijNQ82AiyqCIDCRrre2To0/i7pTjRiL0U9f9mV3S4NJaQaokR050w/ZLySFf6F7joJT mathijs@Qrama-Mathijs' # noqa +SSH_KEY = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsYMJGNGG74HAJha3n2CFmWYsOOaORnJK6VqNy86pj0MIpvRXBzFzVy09uPQ66GOQhTEoJHEqE77VMui7+62AcMXT+GG7cFHcnU8XVQsGM6UirCcNyWNysfiEMoAdZScJf/GvoY87tMEszhZIUV37z8PUBx6twIqMdr31W1J0IaPa+sV6FEDadeLaNTvancDcHK1zuKsL39jzAg7+LYjKJfEfrsQP+lj/EQcjtKqlhVS5kzsJVfx8ZEd0xhW5G7N6bCdKNalS8mKCMaBXJpijNQ82AiyqCIDCRrre2To0/i7pTjRiL0U9f9mV3S4NJaQaokR050w/ZLySFf6F7joJT mathijs@Qrama-Mathijs" # noqa HERE_DIR = Path(__file__).absolute() # tests/integration TESTS_DIR = HERE_DIR.parent # tests/ -INTEGRATION_TEST_DIR = TESTS_DIR / 'integration' -UNIT_TEST_DIR = TESTS_DIR / 'unit' -OVERLAYS_DIR = INTEGRATION_TEST_DIR / 'bundle' / 'test-overlays' +INTEGRATION_TEST_DIR = TESTS_DIR / "integration" +UNIT_TEST_DIR = TESTS_DIR / "unit" +OVERLAYS_DIR = INTEGRATION_TEST_DIR / "bundle" / "test-overlays" diff --git a/tests/validate/test_facade_versions.py b/tests/validate/test_facade_versions.py index 362336023..0ed4bb586 100644 --- a/tests/validate/test_facade_versions.py +++ b/tests/validate/test_facade_versions.py @@ -8,7 +8,11 @@ import pytest -from juju.client.facade_versions import client_facade_versions, excluded_facade_versions, known_unsupported_facades +from juju.client.facade_versions import ( + client_facade_versions, + excluded_facade_versions, + known_unsupported_facades, +) @pytest.fixture @@ -26,8 +30,8 @@ def generated_code_facades(project_root: Path) -> Dict[str, Sequence[int]]: manually marked as incompatible with the current version of python-libjuju. """ facades: Dict[str, List[int]] = defaultdict(list) - for file in project_root.glob('juju/client/_client*.py'): - module = importlib.import_module(f'juju.client.{file.stem}') + for file in project_root.glob("juju/client/_client*.py"): + module = importlib.import_module(f"juju.client.{file.stem}") for cls_name in dir(module): cls = getattr(module, cls_name) try: # duck typing check for facade types From 9d9c6a8100dbf4072aed765ea0d845c62c606674 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Tue, 12 Nov 2024 17:05:17 +0900 Subject: [PATCH 02/34] chore: ruff autofix --- docs/conf.py | 11 +- examples/action.py | 3 +- examples/add_k8s.py | 6 +- examples/add_machine.py | 5 +- examples/add_model.py | 17 +- examples/add_secrets_backend.py | 5 +- examples/allwatcher.py | 3 +- examples/charmhub_deploy_k8s.py | 3 +- examples/charmhub_deploy_machine.py | 3 +- examples/charmhub_find.py | 3 +- examples/charmhub_info.py | 3 +- examples/cloud.py | 3 +- examples/clouds.py | 3 +- examples/config.py | 5 +- examples/connect_current_model.py | 5 +- examples/controller.py | 5 +- examples/credential.py | 3 +- examples/crossmodel.py | 5 +- examples/crossmodel_bundle.py | 3 +- examples/crossmodel_controller.py | 5 +- examples/crossmodel_relation.py | 5 +- examples/debug-log.py | 5 +- examples/deploy.py | 3 +- examples/deploy_bundle.py | 7 +- examples/deploy_bundle_charmhub.py | 3 +- examples/deploy_bundle_with_trust.py | 3 +- examples/deploy_constraints.py | 3 +- examples/deploy_local_big_k8s_bundle.py | 3 +- .../deploy_local_bundle_with_resources.py | 3 +- examples/deploy_local_file_resource.py | 8 +- examples/deploy_local_resource.py | 8 +- examples/expose-application.py | 5 +- examples/formatted_status.py | 9 +- examples/future.py | 7 +- examples/get_cloud.py | 3 +- examples/leadership.py | 5 +- examples/livemodel.py | 5 +- examples/local_refresh.py | 3 +- examples/localcharm.py | 3 +- examples/machine_hostname.py | 5 +- examples/model.py | 5 +- examples/modelsummaries.py | 5 +- examples/relate.py | 17 +- examples/scp.py | 5 +- examples/status.py | 8 +- examples/unitrun.py | 5 +- examples/upgrade_local_charm_k8s.py | 3 +- juju/application.py | 54 +- juju/bundle.py | 125 +- juju/charm.py | 1 + juju/charmhub.py | 32 +- juju/client/_client.py | 42 +- juju/client/_client1.py | 190 +- juju/client/_client10.py | 211 +- juju/client/_client11.py | 137 +- juju/client/_client12.py | 133 +- juju/client/_client17.py | 303 +- juju/client/_client19.py | 310 +- juju/client/_client2.py | 120 +- juju/client/_client20.py | 310 +- juju/client/_client3.py | 212 +- juju/client/_client4.py | 175 +- juju/client/_client5.py | 84 +- juju/client/_client6.py | 259 +- juju/client/_client7.py | 360 +- juju/client/_client8.py | 25 +- juju/client/_client9.py | 103 +- juju/client/_definitions.py | 7741 +++++------------ juju/client/codegen.py | 9 +- juju/client/connection.py | 54 +- juju/client/connector.py | 17 +- juju/client/facade.py | 101 +- juju/client/facade_versions.py | 1 - juju/client/gocookies.py | 6 +- juju/client/jujudata.py | 14 +- juju/client/overrides.py | 70 +- juju/client/proxy/kubernetes/proxy.py | 7 +- juju/client/proxy/proxy.py | 4 +- juju/constraints.py | 5 +- juju/controller.py | 64 +- juju/errors.py | 5 +- juju/jasyncio.py | 38 +- juju/juju.py | 5 +- juju/machine.py | 9 +- juju/model.py | 180 +- juju/names.py | 8 +- juju/offerendpoints.py | 32 +- juju/origin.py | 35 +- juju/placement.py | 3 +- juju/provisioner.py | 27 +- juju/relation.py | 21 +- juju/secrets.py | 11 +- juju/status.py | 9 +- juju/tag.py | 4 +- juju/unit.py | 11 +- juju/url.py | 27 +- juju/user.py | 4 +- juju/utils.py | 39 +- setup.py | 8 +- tests/base.py | 16 +- tests/integration/test_application.py | 4 +- tests/integration/test_charmhub.py | 5 +- tests/integration/test_connection.py | 15 +- tests/integration/test_controller.py | 31 +- tests/integration/test_crossmodel.py | 33 +- tests/integration/test_errors.py | 13 +- tests/integration/test_juju.py | 1 + tests/integration/test_macaroon_auth.py | 16 +- tests/integration/test_machine.py | 3 +- tests/integration/test_model.py | 39 +- tests/integration/test_secrets.py | 5 +- tests/integration/test_unit.py | 3 +- tests/unit/test_application.py | 8 +- tests/unit/test_bundle.py | 9 +- tests/unit/test_client.py | 7 +- tests/unit/test_connection.py | 8 +- tests/unit/test_controller.py | 5 +- tests/unit/test_flags.py | 4 +- tests/unit/test_gocookies.py | 7 +- tests/unit/test_jujudata.py | 2 +- tests/unit/test_machine.py | 4 +- tests/unit/test_model.py | 13 +- tests/unit/test_offerendpoint.py | 7 +- tests/unit/test_proxy.py | 15 +- tests/unit/test_proxy_kubernetes.py | 1 + tests/unit/test_relation.py | 3 +- tests/unit/test_secrets.py | 3 +- tests/unit/test_status.py | 3 +- tests/unit/test_unit.py | 2 +- tests/unit/test_url.py | 2 +- tests/unit/test_utils.py | 21 +- 131 files changed, 3723 insertions(+), 8583 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index b64396203..2961a3a16 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -15,9 +15,8 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys import os - +import sys from pathlib import Path here = Path(__file__).absolute().parent @@ -229,13 +228,13 @@ latex_elements = { # The paper size ('letterpaper' or 'a4paper'). - #'papersize': 'letterpaper', + # 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). - #'pointsize': '10pt', + # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. - #'preamble': '', + # 'preamble': '', # Latex figure (float) alignment - #'figure_align': 'htbp', + # 'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples diff --git a/examples/action.py b/examples/action.py index 2da3fdad7..e1023377b 100644 --- a/examples/action.py +++ b/examples/action.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to current model and resets it. 2. Deploys a git unit. diff --git a/examples/add_k8s.py b/examples/add_k8s.py index 94121a604..912d2e65d 100644 --- a/examples/add_k8s.py +++ b/examples/add_k8s.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to current controller. 2. Loads kube config from microk8s. @@ -11,10 +10,11 @@ """ +import base64 import logging import os + import yaml -import base64 from juju import jasyncio from juju.client import client diff --git a/examples/add_machine.py b/examples/add_machine.py index a6202844c..589fcf5ad 100755 --- a/examples/add_machine.py +++ b/examples/add_machine.py @@ -3,8 +3,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to the current model 2. Creates two machines and a lxd container @@ -43,7 +42,7 @@ async def main(): ) # add a lxd container to machine2 - machine3 = await model.add_machine("lxd:{}".format(machine2.id), series="jammy") + machine3 = await model.add_machine(f"lxd:{machine2.id}", series="jammy") # deploy charm to the lxd container application = await model.deploy( diff --git a/examples/add_model.py b/examples/add_model.py index 837a3f0fe..892e1c6e1 100644 --- a/examples/add_model.py +++ b/examples/add_model.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Creates a model on the current controller 2. Deploys a charm to it. @@ -10,12 +9,12 @@ """ -from juju import jasyncio -from juju import utils -from juju.controller import Controller import asyncio -from logging import getLogger import uuid +from logging import getLogger + +from juju import jasyncio, utils +from juju.controller import Controller LOG = getLogger(__name__) @@ -27,8 +26,8 @@ async def main(): await controller.connect() try: - model_name = "addmodeltest-{}".format(uuid.uuid4()) - print("Adding model {}".format(model_name)) + model_name = f"addmodeltest-{uuid.uuid4()}" + print(f"Adding model {model_name}") model = await controller.add_model(model_name) print("Deploying ubuntu") @@ -56,7 +55,7 @@ async def main(): await controller.destroy_model(model.info.uuid) except Exception: - LOG.exception("Test failed! Model {} may not be cleaned up".format(model_name)) + LOG.exception(f"Test failed! Model {model_name} may not be cleaned up") finally: print("Disconnecting from controller") diff --git a/examples/add_secrets_backend.py b/examples/add_secrets_backend.py index 896d0cc88..6de59acd1 100644 --- a/examples/add_secrets_backend.py +++ b/examples/add_secrets_backend.py @@ -1,17 +1,16 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. +import hvac + from juju import jasyncio from juju.model import Model -import hvac - async def main(): """This is a complete example that deploys vault, uses a vault client to initialize it, and registers the backend. """ - m = Model() await m.connect() diff --git a/examples/allwatcher.py b/examples/allwatcher.py index fc9687338..cc74f4f94 100644 --- a/examples/allwatcher.py +++ b/examples/allwatcher.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to the current model 2. Starts an AllWatcher diff --git a/examples/charmhub_deploy_k8s.py b/examples/charmhub_deploy_k8s.py index b6676c2d5..cac858522 100644 --- a/examples/charmhub_deploy_k8s.py +++ b/examples/charmhub_deploy_k8s.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to the current model 2. Deploy a charm and waits until it reports itself active diff --git a/examples/charmhub_deploy_machine.py b/examples/charmhub_deploy_machine.py index 09f14963c..b48811119 100644 --- a/examples/charmhub_deploy_machine.py +++ b/examples/charmhub_deploy_machine.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to the current model 2. Deploy a charm and waits until it reports itself active diff --git a/examples/charmhub_find.py b/examples/charmhub_find.py index 24af10f6d..2010962bb 100644 --- a/examples/charmhub_find.py +++ b/examples/charmhub_find.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -Example to show how to connect to the current model and search the charm-hub +"""Example to show how to connect to the current model and search the charm-hub repository for charms. """ diff --git a/examples/charmhub_info.py b/examples/charmhub_info.py index 01d0a2c22..11f563893 100644 --- a/examples/charmhub_info.py +++ b/examples/charmhub_info.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -Example to show how to connect to the current model and query the charm-hub +"""Example to show how to connect to the current model and query the charm-hub repository for information about a given charm. """ diff --git a/examples/cloud.py b/examples/cloud.py index 26e624345..d818df9c6 100644 --- a/examples/cloud.py +++ b/examples/cloud.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to current controller. 2. Gets the cloud diff --git a/examples/clouds.py b/examples/clouds.py index ef03d48db..1dee35b16 100644 --- a/examples/clouds.py +++ b/examples/clouds.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to current controller. 2. Gets all the clouds from a controller diff --git a/examples/config.py b/examples/config.py index cb70abfde..b6388b938 100644 --- a/examples/config.py +++ b/examples/config.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to the current model 2. Resets it @@ -12,8 +11,8 @@ import logging -from juju.model import Model from juju import jasyncio +from juju.model import Model log = logging.getLogger(__name__) diff --git a/examples/connect_current_model.py b/examples/connect_current_model.py index 7aefa7515..c8996b1d0 100644 --- a/examples/connect_current_model.py +++ b/examples/connect_current_model.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This is a very basic example that connects to the currently selected model +"""This is a very basic example that connects to the currently selected model and prints the number of applications deployed to it. """ @@ -19,7 +18,7 @@ async def main(): 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))) + print(f"There are {len(model.applications)} applications") finally: if model.is_connected(): print("Disconnecting from model") diff --git a/examples/controller.py b/examples/controller.py index 078ed3615..d269a16a2 100644 --- a/examples/controller.py +++ b/examples/controller.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to current controller. 2. Creates a new model. @@ -14,8 +13,8 @@ import logging -from juju.controller import Controller from juju import jasyncio +from juju.controller import Controller async def main(): diff --git a/examples/credential.py b/examples/credential.py index 1ba8b155e..257462736 100644 --- a/examples/credential.py +++ b/examples/credential.py @@ -2,6 +2,7 @@ # Licensed under the Apache V2, see LICENCE file for details. import sys + from juju import jasyncio from juju.controller import Controller @@ -19,7 +20,7 @@ async def main(cloud_name, credential_name): ) # verify credential - print("Verify model's credential: {}".format(model.info.cloud_credential_tag)) + print(f"Verify model's credential: {model.info.cloud_credential_tag}") # verify we can deploy print("Deploying ubuntu") diff --git a/examples/crossmodel.py b/examples/crossmodel.py index f5c5638de..226ef4e77 100644 --- a/examples/crossmodel.py +++ b/examples/crossmodel.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to the current model 2. Deploys a charm and waits until it reports itself active @@ -62,7 +61,7 @@ async def main(): print("Exporting bundle") with tempfile.TemporaryDirectory() as dirpath: - await offering_model.export_bundle("{}/bundle.yaml".format(dirpath)) + await offering_model.export_bundle(f"{dirpath}/bundle.yaml") print("Remove SAAS") await consuming_model.remove_saas("mysql") diff --git a/examples/crossmodel_bundle.py b/examples/crossmodel_bundle.py index 6841976ea..06e85d4d9 100644 --- a/examples/crossmodel_bundle.py +++ b/examples/crossmodel_bundle.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to the current controller 2. Creates two models for consuming and offering diff --git a/examples/crossmodel_controller.py b/examples/crossmodel_controller.py index fda5788fe..ec12d02be 100644 --- a/examples/crossmodel_controller.py +++ b/examples/crossmodel_controller.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to test and test2 controllers 2. Creates models on each controllers @@ -70,7 +69,7 @@ async def main(): print("Exporting bundle") with tempfile.TemporaryDirectory() as dirpath: - await offering_model.export_bundle("{}/bundle.yaml".format(dirpath)) + await offering_model.export_bundle(f"{dirpath}/bundle.yaml") print("Remove SAAS") await consuming_model.remove_saas("mysql") diff --git a/examples/crossmodel_relation.py b/examples/crossmodel_relation.py index 42e8b2b50..80ffb3a14 100644 --- a/examples/crossmodel_relation.py +++ b/examples/crossmodel_relation.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to the current controller 2. Creates two models for consuming and offering @@ -83,7 +82,7 @@ async def main(): print("Exporting bundle") with tempfile.TemporaryDirectory() as dirpath: - await offering_model.export_bundle("{}/bundle.yaml".format(dirpath)) + await offering_model.export_bundle(f"{dirpath}/bundle.yaml") time.sleep(10) diff --git a/examples/debug-log.py b/examples/debug-log.py index 0200f0c16..b7e712063 100644 --- a/examples/debug-log.py +++ b/examples/debug-log.py @@ -1,10 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example demonstrate how debug-log works - -""" +"""This example demonstrate how debug-log works""" from juju import jasyncio from juju.model import Model diff --git a/examples/deploy.py b/examples/deploy.py index e1a2ce9e9..831ae85d2 100644 --- a/examples/deploy.py +++ b/examples/deploy.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to the current model 2. Deploy a charm and waits until it reports itself active diff --git a/examples/deploy_bundle.py b/examples/deploy_bundle.py index 79a379e55..dad615eec 100644 --- a/examples/deploy_bundle.py +++ b/examples/deploy_bundle.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to the current model 2. Deploy a bundle and waits until it reports itself active @@ -10,8 +9,8 @@ """ -from juju.controller import Controller from juju import jasyncio +from juju.controller import Controller async def main(): @@ -27,7 +26,7 @@ async def main(): async def deploy_bundle(controller, url, channel=None): models = await controller.list_models() - model = await controller.add_model("model{}".format(len(models) + 1)) + model = await controller.add_model(f"model{len(models) + 1}") try: print("Deploying bundle") diff --git a/examples/deploy_bundle_charmhub.py b/examples/deploy_bundle_charmhub.py index 36a90af27..f3f63b154 100644 --- a/examples/deploy_bundle_charmhub.py +++ b/examples/deploy_bundle_charmhub.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to the current model 2. Deploy a bundle from charmhub and waits until it reports itself active 3. Destroys the unit and application diff --git a/examples/deploy_bundle_with_trust.py b/examples/deploy_bundle_with_trust.py index a3552b48e..0a122e021 100644 --- a/examples/deploy_bundle_with_trust.py +++ b/examples/deploy_bundle_with_trust.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to the current model 2. Deploy a bundle with trust and waits until it reports itself active diff --git a/examples/deploy_constraints.py b/examples/deploy_constraints.py index c5eeaff68..dd876c58a 100644 --- a/examples/deploy_constraints.py +++ b/examples/deploy_constraints.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to the current controller 2. Adds a model to the controller diff --git a/examples/deploy_local_big_k8s_bundle.py b/examples/deploy_local_big_k8s_bundle.py index 686a7b2f5..447206ff5 100644 --- a/examples/deploy_local_big_k8s_bundle.py +++ b/examples/deploy_local_big_k8s_bundle.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to the current model 2. Deploy a bundle and waits until it reports itself active diff --git a/examples/deploy_local_bundle_with_resources.py b/examples/deploy_local_bundle_with_resources.py index eb6c9c1c2..c35382c5c 100644 --- a/examples/deploy_local_bundle_with_resources.py +++ b/examples/deploy_local_bundle_with_resources.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to the current model 2. Deploy a bundle and waits until it reports itself active diff --git a/examples/deploy_local_file_resource.py b/examples/deploy_local_file_resource.py index 6a739e93d..3aa2b5ccf 100644 --- a/examples/deploy_local_file_resource.py +++ b/examples/deploy_local_file_resource.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to the current model 2. Deploy a local charm with a oci-image resource and waits until it reports @@ -11,9 +10,10 @@ """ +from pathlib import Path + from juju import jasyncio from juju.model import Model -from pathlib import Path async def main(): @@ -26,7 +26,7 @@ async def main(): try: print("Deploying local-charm") base_dir = Path(__file__).absolute().parent.parent - charm_path = "{}/tests/integration/file-resource-charm".format(base_dir) + charm_path = f"{base_dir}/tests/integration/file-resource-charm" resources = {"file-res": "test.file"} application = await model.deploy( charm_path, diff --git a/examples/deploy_local_resource.py b/examples/deploy_local_resource.py index dc3c3e18f..cbe086a40 100644 --- a/examples/deploy_local_resource.py +++ b/examples/deploy_local_resource.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to the current model 2. Deploy a local charm with a oci-image resource and waits until it reports @@ -11,9 +10,10 @@ """ +from pathlib import Path + from juju import jasyncio from juju.model import Model -from pathlib import Path async def main(): @@ -25,7 +25,7 @@ async def main(): try: print("Deploying local-charm") base_dir = Path(__file__).absolute().parent.parent - charm_path = "{}/tests/integration/oci-image-charm".format(base_dir) + charm_path = f"{base_dir}/tests/integration/oci-image-charm" resources = {"oci-image": "ubuntu/latest"} application = await model.deploy( charm_path, diff --git a/examples/expose-application.py b/examples/expose-application.py index bd96f95dc..b43a2c679 100644 --- a/examples/expose-application.py +++ b/examples/expose-application.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to the current model. 2. Deploys a charm and waits until it reports itself active. @@ -13,8 +12,8 @@ """ from juju import jasyncio -from juju.model import Model from juju.application import ExposedEndpoint +from juju.model import Model async def main(): diff --git a/examples/formatted_status.py b/examples/formatted_status.py index a0b7cd9fb..4fc2865d0 100644 --- a/examples/formatted_status.py +++ b/examples/formatted_status.py @@ -1,19 +1,18 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example demonstrates how to obtain a formatted full status +"""This example demonstrates how to obtain a formatted full status description. For a similar solution using the FullStatus object check examples/fullstatus.py """ -from juju import jasyncio import logging import sys -from logging import getLogger -from juju.model import Model import tempfile +from logging import getLogger +from juju import jasyncio +from juju.model import Model from juju.status import formatted_status LOG = getLogger(__name__) diff --git a/examples/future.py b/examples/future.py index 0054fecb7..ffb7d9f8c 100644 --- a/examples/future.py +++ b/examples/future.py @@ -1,15 +1,12 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -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 logging -from juju.model import Model from juju import jasyncio +from juju.model import Model async def main(): diff --git a/examples/get_cloud.py b/examples/get_cloud.py index 322998608..657aac556 100644 --- a/examples/get_cloud.py +++ b/examples/get_cloud.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to current controller. 2. Gets the cloud name in which the controller lives on diff --git a/examples/leadership.py b/examples/leadership.py index d0d36ab28..ddd6bddb6 100644 --- a/examples/leadership.py +++ b/examples/leadership.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to the current model. 2. Prints out leadership status for all deployed units in the model. @@ -21,7 +20,7 @@ async def report_leadership(): print("Leadership: ") for app in model.applications.values(): for unit in app.units: - print("{}: {}".format(unit.name, await unit.is_leader_from_status())) + print(f"{unit.name}: {await unit.is_leader_from_status()}") await model.disconnect() diff --git a/examples/livemodel.py b/examples/livemodel.py index ce7f2999c..96609286d 100644 --- a/examples/livemodel.py +++ b/examples/livemodel.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to the current model 2. Watches the model and prints all changes @@ -10,8 +9,8 @@ """ -from juju.model import Model from juju import jasyncio +from juju.model import Model async def on_model_change(delta, old, new, model): diff --git a/examples/local_refresh.py b/examples/local_refresh.py index 7ffd70547..68e581275 100644 --- a/examples/local_refresh.py +++ b/examples/local_refresh.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to the current model 2. Upgrades previously deployed ubuntu charm diff --git a/examples/localcharm.py b/examples/localcharm.py index 93c8e9664..dd2489bad 100644 --- a/examples/localcharm.py +++ b/examples/localcharm.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example shows how to deploy a local charm. It: +"""This example shows how to deploy a local charm. It: 1. Connects to current model. 2. Uploads a local charm (directory on filesystem) to the model. diff --git a/examples/machine_hostname.py b/examples/machine_hostname.py index 5b9ccfb5f..3dca3f4ef 100644 --- a/examples/machine_hostname.py +++ b/examples/machine_hostname.py @@ -4,8 +4,7 @@ # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to the current model 2. Creates a machine @@ -35,7 +34,7 @@ async def main(): # At this point we can access the reported hostname via the hostname # property of the machine model. - print("machine1 hostname: {}".format(machine1.hostname)) + print(f"machine1 hostname: {machine1.hostname}") await machine1.destroy(force=True) finally: diff --git a/examples/model.py b/examples/model.py index 5fdc6483f..d15befb02 100755 --- a/examples/model.py +++ b/examples/model.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example shows how to reconnect to a model if you encounter an error +"""This example shows how to reconnect to a model if you encounter an error 1. Connects to current model. 2. Attempts to get an application that doesn't exist. @@ -11,8 +10,8 @@ """ from juju import jasyncio -from juju.model import Model from juju.errors import JujuEntityNotFoundError +from juju.model import Model async def main(): diff --git a/examples/modelsummaries.py b/examples/modelsummaries.py index ac1d49569..0d1568a0b 100644 --- a/examples/modelsummaries.py +++ b/examples/modelsummaries.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to the current model 2. Starts an AllWatcher @@ -27,7 +26,7 @@ async def watch(): # Need to call the WatchModelSummaries or WatchAllModelSummaries on the # controller. def callback(summary): - print("-- change --\n{}\n".format(summary)) + print(f"-- change --\n{summary}\n") await controller.watch_model_summaries(callback) diff --git a/examples/relate.py b/examples/relate.py index 7ab3912cd..f9f24b6bc 100644 --- a/examples/relate.py +++ b/examples/relate.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to the current model 2. Resets it @@ -14,8 +13,8 @@ import asyncio import logging -from juju.model import Model, ModelObserver from juju import jasyncio +from juju.model import Model, ModelObserver class MyRemoveObserver(ModelObserver): @@ -61,28 +60,28 @@ async def main(): ubuntu_app.on_change( asyncio.coroutine( lambda delta, old_app, new_app, model: print( - "App changed: {}".format(new_app.entity_id) + f"App changed: {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) + f"App removed: {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) + f"Unit added: {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) + f"Unit removed: {old_unit.entity_id}" ) ) ) @@ -90,7 +89,7 @@ async def main(): unit_a.on_change( asyncio.coroutine( lambda delta, old_unit, new_unit, model: print( - "Unit changed: {}".format(new_unit.entity_id) + f"Unit changed: {new_unit.entity_id}" ) ) ) @@ -109,7 +108,7 @@ async def main(): my_relation.on_remove( asyncio.coroutine( lambda delta, old_rel, new_rel, model: print( - "Relation removed: {}".format(old_rel.endpoints) + f"Relation removed: {old_rel.endpoints}" ) ) ) diff --git a/examples/scp.py b/examples/scp.py index 11d0c5265..664bb6447 100644 --- a/examples/scp.py +++ b/examples/scp.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This is a very basic example that connects to the currently selected model +"""This is a very basic example that connects to the currently selected model and prints the number of applications deployed to it. Then attempts to use scp to grab the profile, as a way to show how scp works @@ -22,7 +21,7 @@ async def main(): 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))) + print(f"There are {len(model.applications)} applications") machine = model.machines["0"] # This roughly expands to the following: diff --git a/examples/status.py b/examples/status.py index 9ce52d424..5c6328280 100644 --- a/examples/status.py +++ b/examples/status.py @@ -1,15 +1,13 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example demonstrate how status works +"""This example demonstrate how status works""" -""" - -from juju import jasyncio import logging import sys from logging import getLogger + +from juju import jasyncio from juju.model import Model from juju.status import formatted_status diff --git a/examples/unitrun.py b/examples/unitrun.py index 996461435..3ca761466 100644 --- a/examples/unitrun.py +++ b/examples/unitrun.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to current model and resets it. 2. Deploys one ubuntu unit. @@ -13,8 +12,8 @@ import logging -from juju.model import Model from juju import jasyncio +from juju.model import Model async def run_command(unit): diff --git a/examples/upgrade_local_charm_k8s.py b/examples/upgrade_local_charm_k8s.py index c005fb1a1..bfec519d7 100644 --- a/examples/upgrade_local_charm_k8s.py +++ b/examples/upgrade_local_charm_k8s.py @@ -1,8 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This example: +"""This example: 1. Connects to the current model 2. Deploy a bundle and waits until it reports itself active diff --git a/juju/application.py b/juju/application.py index 1acddc07b..2dbd8f1da 100644 --- a/juju/application.py +++ b/juju/application.py @@ -4,15 +4,15 @@ import hashlib import json import logging -from typing import Dict, List, Optional, Union from pathlib import Path +from typing import Dict, List, Optional, Union from typing_extensions import deprecated from . import jasyncio, model, tag, utils from .annotationhelper import _get_annotations, _set_annotations from .bundle import get_charm_series, is_local_charm -from .client import client, _definitions +from .client import _definitions, client from .errors import JujuApplicationConfigError, JujuError from .origin import Channel from .placement import parse as parse_placement @@ -77,7 +77,7 @@ def workload_version(self) -> str: @property def _unit_match_pattern(self): - return r"^{}.*$".format(self.entity_id) + return rf"^{self.entity_id}.*$" def _facade(self): return client.ApplicationFacade.from_connection(self.connection) @@ -160,9 +160,8 @@ def tag(self): return tag.application(self.name) async def add_relation(self, local_relation, remote_relation): - """ - .. deprecated:: 2.9.9 - Use ``relate()`` instead + """.. deprecated:: 2.9.9 + Use ``relate()`` instead """ return await self.relate(local_relation, remote_relation) @@ -175,7 +174,7 @@ async def relate(self, local_relation, remote_relation): """ if ":" not in local_relation: - local_relation = "{}:{}".format(self.name, local_relation) + local_relation = f"{self.name}:{local_relation}" return await self.model.relate(local_relation, remote_relation) @@ -193,7 +192,6 @@ async def add_unit(self, count=1, to=None, attach_storage=[]): If None, a new machine is provisioned. """ - if self.model.info.type_ == "caas": log.warning( "adding units to a container-based model not supported, auto-switching to scale" @@ -219,8 +217,7 @@ async def add_unit(self, count=1, to=None, attach_storage=[]): add_units = add_unit async def scale(self, scale=None, scale_change=None): - """ - Set or adjust the scale of this (K8s) application. + """Set or adjust the scale of this (K8s) application. One or the other of scale or scale_change must be provided. @@ -260,7 +257,7 @@ async def destroy_relation( """ if ":" not in local_relation: - local_relation = "{}:{}".format(self.name, local_relation) + local_relation = f"{self.name}:{local_relation}" app_facade = self._facade() @@ -291,16 +288,13 @@ async def destroy(self, destroy_storage=False, force=False, no_wait=False): :param bool no_wait: Rush through application removal without waiting for each individual step to complete (=false) :param bool block: Blocks until the application is removed from the model """ - if no_wait and not force: raise JujuError("--no-wait without --force is not valid") app_facade = self._facade() log.debug( - "Destroying {} with parameters -- destroy-storage : {} -- force : {} -- no-wait : {}".format( - self.name, destroy_storage, force, no_wait - ) + f"Destroying {self.name} with parameters -- destroy-storage : {destroy_storage} -- force : {force} -- no-wait : {no_wait}" ) res = await app_facade.DestroyApplication( @@ -319,7 +313,8 @@ async def destroy(self, destroy_storage=False, force=False, no_wait=False): def supports_granular_expose_parameters(self): """Returns true if the controller supports granular, per-endpoint - expose parameters.""" + expose parameters. + """ return self._facade_version() >= 13 async def expose(self, exposed_endpoints=None): @@ -475,9 +470,7 @@ async def get_trusted(self): """Return the trusted configuration setting for this application.""" if self.model.info.agent_version < client.Number.from_json("2.4.0"): raise NotImplementedError( - "trusted is not supported on model version {}".format( - self.model.info.agent_version - ) + f"trusted is not supported on model version {self.model.info.agent_version}" ) app_facade = self._facade() @@ -498,9 +491,7 @@ async def set_trusted(self, trust): """ if self.model.info.agent_version < client.Number.from_json("2.4.0"): raise NotImplementedError( - "trusted is not supported on model version {}".format( - self.model.info.agent_version - ) + f"trusted is not supported on model version {self.model.info.agent_version}" ) # clamp trust to exactly the value juju expects, rather than allowing @@ -565,7 +556,6 @@ async def get_status(self): :return: str status """ - client_facade = client.ClientFacade.from_connection(self.connection) full_status = await client_facade.FullStatus(patterns=None) @@ -586,9 +576,7 @@ def attach_resource(self, resource_name, file_name, file_obj): """ conn, headers, path_prefix = self.connection.https_connection() - url = "{}/applications/{}/resources/{}".format( - path_prefix, self.name, resource_name - ) + url = f"{path_prefix}/applications/{self.name}/resources/{resource_name}" data = file_obj.read() @@ -601,7 +589,7 @@ def attach_resource(self, resource_name, file_name, file_obj): if not file_name.startswith("./"): file_name = "./" + file_name - headers["Content-Disposition"] = 'form-data; filename="{}"'.format(file_name) + headers["Content-Disposition"] = f'form-data; filename="{file_name}"' headers["Accept-Encoding"] = "gzip" headers["Bakery-Protocol-Version"] = 3 headers["Connection"] = "close" @@ -713,8 +701,7 @@ async def set_config(self, config): ) async def reset_config(self, to_default): - """ - Restore application config to default values. + """Restore application config to default values. :param list to_default: A list of config options to be reset to their default value. @@ -816,7 +803,7 @@ async def refresh( if parsed_url.schema is None: raise JujuError( - f"A ch: or cs: schema is required for application refresh, given : {str(parsed_url)}" + f"A ch: or cs: schema is required for application refresh, given : {parsed_url!s}" ) # Resolve the given charm URLs with an optionally specified preferred channel. @@ -1045,7 +1032,8 @@ class ExposedEndpoint: """ExposedEndpoint stores the list of CIDRs and space names which should be allowed access to the port ranges that the application has opened for a particular endpoint. Both lists are optional; if empty, the opened port - ranges will be reachable from any source IP address.""" + ranges will be reachable from any source IP address. + """ def __init__(self, to_spaces=None, to_cidrs=None): if to_spaces is not None and not isinstance(to_spaces, list): @@ -1093,7 +1081,7 @@ def __str__(self): descr = "" if self.to_spaces is not None and len(self.to_spaces) > 0: if len(self.to_spaces) == 1: - descr = "from space {}".format(self.to_spaces[0]) + descr = f"from space {self.to_spaces[0]}" elif len(self.to_spaces) > 1: descr = "from spaces {}".format(",".join(self.to_spaces)) @@ -1102,7 +1090,7 @@ def __str__(self): if self.to_cidrs is not None: if len(self.to_cidrs) == 1: - descr = descr + "from CIDR {}".format(self.to_cidrs[0]) + descr = descr + f"from CIDR {self.to_cidrs[0]}" elif len(self.to_cidrs) > 1: descr = descr + "from CIDRs {}".format(",".join(self.to_cidrs)) diff --git a/juju/bundle.py b/juju/bundle.py index affc0a35d..26c82c005 100644 --- a/juju/bundle.py +++ b/juju/bundle.py @@ -1,35 +1,33 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -import logging +import base64 import io +import logging import os import zipfile -import requests -import base64 from contextlib import closing from pathlib import Path from typing import Dict, Optional +import requests import yaml - from toposort import toposort_flatten +from . import jasyncio, utils from .client import client from .constraints import parse as parse_constraints from .constraints import parse_storage_constraint from .errors import JujuError -from . import utils, jasyncio from .origin import Channel, Source -from .url import Schema, URL +from .url import URL, Schema from .utils import get_base_from_origin_or_channel log = logging.getLogger(__name__) class BundleHandler: - """ - Handle bundles by using the API to translate bundle YAML into a plan of + """Handle bundles by using the API to translate bundle YAML into a plan of steps and then dispatching each of those using the API. """ @@ -97,7 +95,7 @@ async def _validate_bundle(self, bundle): raise JujuError( "Bundle cannot be deployed without trusting applications with your cloud credentials.\n" "Please repeat the deploy command with the --trust argument if you consent to trust the following application\n" - " - {}\n".format(app_name) + f" - {app_name}\n" ) return bundle @@ -142,8 +140,8 @@ async def _handle_local_charms(self, bundle, bundle_dir): series = utils.base_channel_to_series(base.channel) if not series: raise JujuError( - "Couldn't determine series for charm at {}. " - "Add a 'series' key to the bundle.".format(charm_dir) + f"Couldn't determine series for charm at {charm_dir}. " + "Add a 'series' key to the bundle." ) # Keep track of what we need to update. We keep a list of apps # that need to be updated, and a corresponding list of args @@ -181,7 +179,7 @@ async def _handle_local_charms(self, bundle, bundle_dir): return bundle def _resolve_include_file_config(self, bundle_dir): - """if any of the applications (including the ones in the overlays) + """If any of the applications (including the ones in the overlays) have "config: include-file:..." or "config: include-base64:...", then we have to resolve and inline them into the bundle here because they're all files with local @@ -301,7 +299,7 @@ async def fetch_plan(self, bundle, origin, overlays=[]): for overlay_yaml_path in overlays: try: overlay_contents = Path(overlay_yaml_path).read_text() - except (OSError, IOError) as e: + except OSError as e: raise JujuError( "unable to open overlay %s \n %s" % (overlay_yaml_path, e) ) @@ -337,9 +335,7 @@ async def fetch_plan(self, bundle, origin, overlays=[]): async def _download_bundle(self, charm_url, origin): if self.charms_facade is None: raise JujuError( - "unable to download bundle for {} using the new charms facade. Upgrade controller to proceed.".format( - charm_url - ) + f"unable to download bundle for {charm_url} using the new charms facade. Upgrade controller to proceed." ) id = origin.id_ if origin.id_ else "" @@ -364,11 +360,11 @@ async def _download_bundle(self, charm_url, origin): entities=[{"charm-url": str(charm_url), "charm-origin": charm_origin}] ) if len(resp.results) != 1: - raise JujuError("expected one result, received {}".format(resp.results)) + raise JujuError(f"expected one result, received {resp.results}") result = resp.results[0] if not result.url: - raise JujuError("no url found for bundle {}".format(charm_url.name)) + raise JujuError(f"no url found for bundle {charm_url.name}") bundle_resp = requests.get(result.url) bundle_resp.raise_for_status() @@ -455,9 +451,9 @@ async def execute_plan(self): for step in changes.sorted(): change_cls = self.change_types.get(step.method) if change_cls is None: - raise NotImplementedError("unknown change type: {}".format(step.method)) + raise NotImplementedError(f"unknown change type: {step.method}") change = change_cls(step.id_, step.requires, step.args) - log.info("Applying change: {}".format(change)) + log.info(f"Applying change: {change}") self.references[step.id_] = await change.run(self) @property @@ -474,7 +470,7 @@ def resolve_relation(self, reference): application = self.resolve(parts[0]) if len(parts) == 1: return application - return "{}:{}".format(application, parts[1]) + return f"{application}:{parts[1]}" def resolve(self, reference): if reference and reference.startswith("$"): @@ -516,7 +512,6 @@ async def get_charm_series(metadata, model): Returns None if no series can be determined. """ - _series = metadata.get("series") series = _series[0] if _series else None @@ -619,7 +614,7 @@ class AddApplicationChange(ChangeInfo): @staticmethod def method(): - """method returns an associated ID for the Juju API call.""" + """Method returns an associated ID for the Juju API call.""" return "deploy" async def run(self, context): @@ -644,9 +639,7 @@ async def run(self, context): if context.trusted: if context.model.info.agent_version < client.Number.from_json("2.4.0"): raise NotImplementedError( - "trusted is not supported on model version {}".format( - context.model.info.agent_version - ) + f"trusted is not supported on model version {context.model.info.agent_version}" ) options["trust"] = "true" @@ -671,9 +664,7 @@ async def run(self, context): ) if origin is None: raise JujuError( - "expected origin to be valid for application {} and charm {} with channel {}".format( - self.application, str(url), str(channel) - ) + f"expected origin to be valid for application {self.application} and charm {url!s} with channel {channel!s}" ) if not self.series: @@ -711,23 +702,14 @@ async def run(self, context): def __str__(self): series = "" if self.series is not None and self.series != "": - series = " on {}".format(self.series) + series = f" on {self.series}" units_info = "" if self.num_units is not None: plural = "" if self.num_units > 1: plural = "s" - units_info = " with {num_units} unit{plural}".format( - num_units=self.num_units, plural=plural - ) - return ( - "deploy application {application}{units_info}{series} using {charm}".format( - application=self.application, - units_info=units_info, - series=series, - charm=self.charm, - ) - ) + units_info = f" with {self.num_units} unit{plural}" + return f"deploy application {self.application}{units_info}{series} using {self.charm}" class AddCharmChange(ChangeInfo): @@ -758,7 +740,7 @@ class AddCharmChange(ChangeInfo): @staticmethod def method(): - """method returns an associated ID for the Juju API call.""" + """Method returns an associated ID for the Juju API call.""" return "addCharm" async def run(self, context): @@ -768,7 +750,6 @@ async def run(self, context): :param context: is used for any methods or properties required to perform a change. """ - # We don't add local charms because they've already been added # by self._handle_local_charms if is_local_charm(str(self.charm)): @@ -796,7 +777,7 @@ async def run(self, context): identifier, origin = await context.model._resolve_charm(url, origin) if identifier is None: - raise JujuError("unknown charm {}".format(self.charm)) + raise JujuError(f"unknown charm {self.charm}") await context.model._add_charm(str(identifier), origin) @@ -810,12 +791,10 @@ def __str__(self): series = "" channel = "" if self.series is not None and self.series != "": - series = " for series {}".format(self.series) + series = f" for series {self.series}" if self.channel is not None: - channel = " from channel {}".format(self.channel) - return "upload charm {charm}{series}{channel}".format( - charm=self.charm, series=series, channel=channel - ) + channel = f" from channel {self.channel}" + return f"upload charm {self.charm}{series}{channel}" class AddMachineChange(ChangeInfo): @@ -845,7 +824,7 @@ class AddMachineChange(ChangeInfo): @staticmethod def method(): - """method returns an associated ID for the Juju API call.""" + """Method returns an associated ID for the Juju API call.""" return "addMachines" async def run(self, context): @@ -895,10 +874,8 @@ async def run(self, context): def __str__(self): machine = "new machine" if self.container_type is not None and self.container_type != "": - machine = "{container_type} container on {machine}".format( - container_type=self.container_type, machine=machine - ) - return "add {}".format(machine) + machine = f"{self.container_type} container on {machine}" + return f"add {machine}" class AddRelationChange(ChangeInfo): @@ -924,7 +901,7 @@ class AddRelationChange(ChangeInfo): @staticmethod def method(): - """method returns an associated ID for the Juju API call.""" + """Method returns an associated ID for the Juju API call.""" return "addRelation" async def run(self, context): @@ -949,9 +926,7 @@ async def run(self, context): return await context.model.relate(ep1, ep2) def __str__(self): - return "add relation {endpoint1} - {endpoint2}".format( - endpoint1=self.endpoint1, endpoint2=self.endpoint2 - ) + return f"add relation {self.endpoint1} - {self.endpoint2}" class AddUnitChange(ChangeInfo): @@ -974,7 +949,7 @@ class AddUnitChange(ChangeInfo): @staticmethod def method(): - """method returns an associated ID for the Juju API call.""" + """Method returns an associated ID for the Juju API call.""" return "addUnit" async def run(self, context): @@ -1006,9 +981,7 @@ async def run(self, context): ) def __str__(self): - return "add {application} unit to {to}".format( - application=self.application, to=self.to - ) + return f"add {self.application} unit to {self.to}" class CreateOfferChange(ChangeInfo): @@ -1037,7 +1010,7 @@ class CreateOfferChange(ChangeInfo): @staticmethod def method(): - """method returns an associated ID for the Juju API call.""" + """Method returns an associated ID for the Juju API call.""" return "createOffer" async def run(self, context): @@ -1057,11 +1030,7 @@ def __str__(self): endpoints = "" if self.endpoints is not None: endpoints = ":{}".format(",".join(self.endpoints)) - return "create offer {offer_name} using {application}{endpoints}".format( - offer_name=self.offer_name, - application=self.application, - endpoints=endpoints, - ) + return f"create offer {self.offer_name} using {self.application}{endpoints}" class ConsumeOfferChange(ChangeInfo): @@ -1082,7 +1051,7 @@ class ConsumeOfferChange(ChangeInfo): @staticmethod def method(): - """method returns an associated ID for the Juju API call.""" + """Method returns an associated ID for the Juju API call.""" return "consumeOffer" async def run(self, context): @@ -1099,9 +1068,7 @@ async def run(self, context): return local_name def __str__(self): - return "consume offer {application_name} at {url}".format( - application_name=self.application_name, url=self.url - ) + return f"consume offer {self.application_name} at {self.url}" class ExposeChange(ChangeInfo): @@ -1129,7 +1096,7 @@ class ExposeChange(ChangeInfo): @staticmethod def method(): - """method returns an associated ID for the Juju API call.""" + """Method returns an associated ID for the Juju API call.""" return "expose" async def run(self, context): @@ -1146,7 +1113,7 @@ async def run(self, context): ) def __str__(self): - return "expose {application}".format(application=self.application) + return f"expose {self.application}" class ScaleChange(ChangeInfo): @@ -1168,7 +1135,7 @@ class ScaleChange(ChangeInfo): @staticmethod def method(): - """method returns an associated ID for the Juju API call.""" + """Method returns an associated ID for the Juju API call.""" return "scale" async def run(self, context): @@ -1182,9 +1149,7 @@ async def run(self, context): return await context.model.applications[application].scale(scale=self.scale) def __str__(self): - return "scale {application} to {scale} units".format( - application=self.application, scale=self.scale - ) + return f"scale {self.application} to {self.scale} units" class SetAnnotationsChange(ChangeInfo): @@ -1208,7 +1173,7 @@ class SetAnnotationsChange(ChangeInfo): @staticmethod def method(): - """method returns an associated ID for the Juju API call.""" + """Method returns an associated ID for the Juju API call.""" return "setAnnotations" async def run(self, context): @@ -1226,4 +1191,4 @@ async def run(self, context): return await entity.set_annotations(self.annotations) def __str__(self): - return "set annotations for {id}".format(id=self.id) + return f"set annotations for {self.id}" diff --git a/juju/charm.py b/juju/charm.py index e5883316a..4d2fe2f3b 100644 --- a/juju/charm.py +++ b/juju/charm.py @@ -2,6 +2,7 @@ # Licensed under the Apache V2, see LICENCE file for details. import logging + from . import model log = logging.getLogger(__name__) diff --git a/juju/charmhub.py b/juju/charmhub.py index 99cf408da..9288287db 100644 --- a/juju/charmhub.py +++ b/juju/charmhub.py @@ -1,12 +1,14 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -from .client import client -from .errors import JujuError -from juju import jasyncio +import json import requests -import json + +from juju import jasyncio + +from .client import client +from .errors import JujuError class CharmHub: @@ -23,13 +25,13 @@ async def request_charmhub_with_retry(self, url, retries): if _response.status_code == 200: return _response await jasyncio.sleep(5) - raise JujuError("Got {} from {}".format(_response.status_code, url)) + raise JujuError(f"Got {_response.status_code} from {url}") async def get_charm_id(self, charm_name): conn, headers, path_prefix = self.model.connection().https_connection() charmhub_url = await self._charmhub_url() - url = "{}/v2/charms/info/{}".format(charmhub_url.value, charm_name) + url = f"{charmhub_url.value}/v2/charms/info/{charm_name}" _response = await self.request_charmhub_with_retry(url, 5) response = json.loads(_response.text) return response["id"], response["name"] @@ -38,9 +40,7 @@ async def is_subordinate(self, charm_name): conn, headers, path_prefix = self.model.connection().https_connection() charmhub_url = await self._charmhub_url() - url = "{}/v2/charms/info/{}?fields=default-release.revision.subordinate".format( - charmhub_url.value, charm_name - ) + url = f"{charmhub_url.value}/v2/charms/info/{charm_name}?fields=default-release.revision.subordinate" _response = await self.request_charmhub_with_retry(url, 5) response = json.loads(_response.text) rev_response = response["default-release"]["revision"] @@ -53,15 +53,13 @@ async def list_resources(self, charm_name): conn, headers, path_prefix = self.model.connection().https_connection() charmhub_url = await self._charmhub_url() - url = "{}/v2/charms/info/{}?fields=default-release.resources".format( - charmhub_url.value, charm_name - ) + url = f"{charmhub_url.value}/v2/charms/info/{charm_name}?fields=default-release.resources" _response = await self.request_charmhub_with_retry(url, 5) response = json.loads(_response.text) return response["default-release"]["resources"] async def info(self, name, channel=None): - """info displays detailed information about a CharmHub charm. The charm + """Info displays detailed information about a CharmHub charm. The charm can be specified by the exact name. Channel is a hint for providing the metadata for a given channel. @@ -76,7 +74,7 @@ async def info(self, name, channel=None): if channel is None: channel = "" facade = self._facade() - res = await facade.Info(tag="application-{}".format(name), channel=channel) + res = await facade.Info(tag=f"application-{name}", channel=channel) err_code = res.errors.error_list.code if err_code: raise JujuError( @@ -89,9 +87,7 @@ async def info(self, name, channel=None): result = result.serialize() else: charmhub_url = await self._charmhub_url() - url = "{}/v2/charms/info/{}?fields=channel-map".format( - charmhub_url.value, name - ) + url = f"{charmhub_url.value}/v2/charms/info/{name}?fields=channel-map" try: _response = await self.request_charmhub_with_retry(url, 5) except JujuError as e: @@ -165,7 +161,7 @@ async def find( relation_requires=None, relation_provides=None, ): - """find queries the CharmHub store for available charms or bundles.""" + """Find queries the CharmHub store for available charms or bundles.""" if charm_type is not None and charm_type not in ["charm", "bundle"]: raise JujuError("expected either charm or bundle for charm_type") diff --git a/juju/client/_client.py b/juju/client/_client.py index 0d94ed24a..e72ae7385 100644 --- a/juju/client/_client.py +++ b/juju/client/_client.py @@ -1,27 +1,24 @@ # DO NOT CHANGE THIS FILE! This file is auto-generated by facade.py. # Changes will be overwritten/lost when the file is regenerated. -from juju.client._definitions import * - - from juju.client import ( - _client7, + _client1, + _client2, _client3, _client4, - _client2, - _client17, + _client5, _client6, - _client11, - _client1, - _client10, + _client7, + _client8, _client9, - _client5, + _client10, + _client11, + _client12, + _client17, _client19, _client20, - _client8, - _client12, ) - +from juju.client._definitions import * CLIENTS = { "7": _client7, @@ -43,8 +40,7 @@ def lookup_facade(name, version): - """ - Given a facade name and version, attempt to pull that facade out + """Given a facade name and version, attempt to pull that facade out of the correct client.py file. """ @@ -55,14 +51,13 @@ def lookup_facade(name, version): except (KeyError, AttributeError): continue else: - raise ImportError("No supported version for facade: {}".format(name)) + raise ImportError(f"No supported version for facade: {name}") class TypeFactory: @classmethod def from_connection(cls, connection): - """ - Given a connected Connection object, return an initialized and + """Given a connected Connection object, return an initialized and connected instance of an API Interface matching the name of this class. @@ -71,13 +66,11 @@ def from_connection(cls, connection): """ facade_name = cls.__name__ if not facade_name.endswith("Facade"): - raise TypeError("Unexpected class name: {}".format(facade_name)) + raise TypeError(f"Unexpected class name: {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) - ) + raise Exception(f"No facade {facade_name} in facades {connection.facades}") c = lookup_facade(cls.__name__, version) c = c() @@ -87,15 +80,14 @@ def from_connection(cls, connection): @classmethod def best_facade_version(cls, connection): - """ - Returns the best facade version for a given facade. This will help with + """Returns the best facade version for a given facade. This will help with trying to provide different functionality for different facade versions. @param connection: initialized Connection object. """ facade_name = cls.__name__ if not facade_name.endswith("Facade"): - raise TypeError("Unexpected class name: {}".format(facade_name)) + raise TypeError(f"Unexpected class name: {facade_name}") facade_name = facade_name[: -len("Facade")] return connection.facades.get(facade_name) diff --git a/juju/client/_client1.py b/juju/client/_client1.py index 687d10338..dcb4e0c2e 100644 --- a/juju/client/_client1.py +++ b/juju/client/_client1.py @@ -1,8 +1,8 @@ # DO NOT CHANGE THIS FILE! This file is auto-generated by facade.py. # Changes will be overwritten/lost when the file is regenerated. -from juju.client.facade import Type, ReturnMapping from juju.client._definitions import * +from juju.client.facade import ReturnMapping, Type class CredentialManagerFacade(Type): @@ -55,16 +55,13 @@ class CredentialManagerFacade(Type): @ReturnMapping(ErrorResult) async def InvalidateModelCredential(self, reason=None): - """ - InvalidateModelCredential marks the cloud credential for this model as invalid. + """InvalidateModelCredential marks the cloud credential for this model as invalid. reason : str Returns -> ErrorResult """ if reason is not None and not isinstance(reason, (bytes, str)): - raise Exception( - "Expected reason to be a str, received: {}".format(type(reason)) - ) + raise Exception(f"Expected reason to be a str, received: {type(reason)}") # map input types to rpc msg _params = dict() @@ -171,13 +168,10 @@ class FirewallRulesFacade(Type): @ReturnMapping(ListFirewallRulesResults) async def ListFirewallRules(self): - """ - ListFirewallRules returns all the firewall rules. - + """ListFirewallRules returns all the firewall rules. Returns -> ListFirewallRulesResults """ - # map input types to rpc msg _params = dict() msg = dict( @@ -189,16 +183,13 @@ async def ListFirewallRules(self): @ReturnMapping(ErrorResults) async def SetFirewallRules(self, args=None): - """ - SetFirewallRules creates or updates the specified firewall rules. + """SetFirewallRules creates or updates the specified firewall rules. args : typing.Sequence[~FirewallRule] Returns -> ErrorResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -361,8 +352,7 @@ class ImageMetadataManagerFacade(Type): @ReturnMapping(ErrorResults) async def Delete(self, image_ids=None): - """ - Delete deletes cloud image metadata for given image ids. + """Delete deletes cloud image metadata for given image ids. It supports bulk calls. image_ids : typing.Sequence[str] @@ -370,9 +360,7 @@ async def Delete(self, image_ids=None): """ if image_ids is not None and not isinstance(image_ids, (bytes, str, list)): raise Exception( - "Expected image_ids to be a Sequence, received: {}".format( - type(image_ids) - ) + f"Expected image_ids to be a Sequence, received: {type(image_ids)}" ) # map input types to rpc msg @@ -394,8 +382,7 @@ async def List( versions=None, virt_type=None, ): - """ - List returns all found cloud image metadata that satisfy + """List returns all found cloud image metadata that satisfy given filter. Returned list contains metadata ordered by priority. @@ -409,38 +396,30 @@ async def List( """ if arches is not None and not isinstance(arches, (bytes, str, list)): raise Exception( - "Expected arches to be a Sequence, received: {}".format(type(arches)) + f"Expected arches to be a Sequence, received: {type(arches)}" ) if region is not None and not isinstance(region, (bytes, str)): - raise Exception( - "Expected region to be a str, received: {}".format(type(region)) - ) + raise Exception(f"Expected region to be a str, received: {type(region)}") if root_storage_type is not None and not isinstance( root_storage_type, (bytes, str) ): raise Exception( - "Expected root_storage_type to be a str, received: {}".format( - type(root_storage_type) - ) + f"Expected root_storage_type to be a str, received: {type(root_storage_type)}" ) if stream is not None and not isinstance(stream, (bytes, str)): - raise Exception( - "Expected stream to be a str, received: {}".format(type(stream)) - ) + raise Exception(f"Expected stream to be a str, received: {type(stream)}") if versions is not None and not isinstance(versions, (bytes, str, list)): raise Exception( - "Expected versions to be a Sequence, received: {}".format( - type(versions) - ) + f"Expected versions to be a Sequence, received: {type(versions)}" ) if virt_type is not None and not isinstance(virt_type, (bytes, str)): raise Exception( - "Expected virt_type to be a str, received: {}".format(type(virt_type)) + f"Expected virt_type to be a str, received: {type(virt_type)}" ) # map input types to rpc msg @@ -459,8 +438,7 @@ async def List( @ReturnMapping(ErrorResults) async def Save(self, metadata=None): - """ - Save stores given cloud image metadata. + """Save stores given cloud image metadata. It supports bulk calls. metadata : typing.Sequence[~CloudImageMetadataList] @@ -468,9 +446,7 @@ async def Save(self, metadata=None): """ if metadata is not None and not isinstance(metadata, (bytes, str, list)): raise Exception( - "Expected metadata to be a Sequence, received: {}".format( - type(metadata) - ) + f"Expected metadata to be a Sequence, received: {type(metadata)}" ) # map input types to rpc msg @@ -620,8 +596,7 @@ class KeyManagerFacade(Type): @ReturnMapping(ErrorResults) async def AddKeys(self, ssh_keys=None, user=None): - """ - AddKeys adds new authorised ssh keys for the specified user. + """AddKeys adds new authorised ssh keys for the specified user. ssh_keys : typing.Sequence[str] user : str @@ -629,15 +604,11 @@ async def AddKeys(self, ssh_keys=None, user=None): """ if ssh_keys is not None and not isinstance(ssh_keys, (bytes, str, list)): raise Exception( - "Expected ssh_keys to be a Sequence, received: {}".format( - type(ssh_keys) - ) + f"Expected ssh_keys to be a Sequence, received: {type(ssh_keys)}" ) if user is not None and not isinstance(user, (bytes, str)): - raise Exception( - "Expected user to be a str, received: {}".format(type(user)) - ) + raise Exception(f"Expected user to be a str, received: {type(user)}") # map input types to rpc msg _params = dict() @@ -649,8 +620,7 @@ async def AddKeys(self, ssh_keys=None, user=None): @ReturnMapping(ErrorResults) async def DeleteKeys(self, ssh_keys=None, user=None): - """ - DeleteKeys deletes the authorised ssh keys for the specified user. + """DeleteKeys deletes the authorised ssh keys for the specified user. ssh_keys : typing.Sequence[str] user : str @@ -658,15 +628,11 @@ async def DeleteKeys(self, ssh_keys=None, user=None): """ if ssh_keys is not None and not isinstance(ssh_keys, (bytes, str, list)): raise Exception( - "Expected ssh_keys to be a Sequence, received: {}".format( - type(ssh_keys) - ) + f"Expected ssh_keys to be a Sequence, received: {type(ssh_keys)}" ) if user is not None and not isinstance(user, (bytes, str)): - raise Exception( - "Expected user to be a str, received: {}".format(type(user)) - ) + raise Exception(f"Expected user to be a str, received: {type(user)}") # map input types to rpc msg _params = dict() @@ -678,8 +644,7 @@ async def DeleteKeys(self, ssh_keys=None, user=None): @ReturnMapping(ErrorResults) async def ImportKeys(self, ssh_keys=None, user=None): - """ - ImportKeys imports new authorised ssh keys from the specified key ids for the specified user. + """ImportKeys imports new authorised ssh keys from the specified key ids for the specified user. ssh_keys : typing.Sequence[str] user : str @@ -687,15 +652,11 @@ async def ImportKeys(self, ssh_keys=None, user=None): """ if ssh_keys is not None and not isinstance(ssh_keys, (bytes, str, list)): raise Exception( - "Expected ssh_keys to be a Sequence, received: {}".format( - type(ssh_keys) - ) + f"Expected ssh_keys to be a Sequence, received: {type(ssh_keys)}" ) if user is not None and not isinstance(user, (bytes, str)): - raise Exception( - "Expected user to be a str, received: {}".format(type(user)) - ) + raise Exception(f"Expected user to be a str, received: {type(user)}") # map input types to rpc msg _params = dict() @@ -707,8 +668,7 @@ async def ImportKeys(self, ssh_keys=None, user=None): @ReturnMapping(StringsResults) async def ListKeys(self, entities=None, mode=None): - """ - ListKeys returns the authorised ssh keys for the specified users. + """ListKeys returns the authorised ssh keys for the specified users. entities : Entities mode : bool @@ -716,15 +676,11 @@ async def ListKeys(self, entities=None, mode=None): """ if entities is not None and not isinstance(entities, (dict, Entities)): raise Exception( - "Expected entities to be a Entities, received: {}".format( - type(entities) - ) + f"Expected entities to be a Entities, received: {type(entities)}" ) if mode is not None and not isinstance(mode, bool): - raise Exception( - "Expected mode to be a bool, received: {}".format(type(mode)) - ) + raise Exception(f"Expected mode to be a bool, received: {type(mode)}") # map input types to rpc msg _params = dict() @@ -819,8 +775,7 @@ class ModelUpgraderFacade(Type): @ReturnMapping(None) async def AbortModelUpgrade(self, model_tag=None): - """ - AbortModelUpgrade aborts and archives the model upgrade + """AbortModelUpgrade aborts and archives the model upgrade synchronisation record, if any. model_tag : str @@ -828,7 +783,7 @@ async def AbortModelUpgrade(self, model_tag=None): """ if model_tag is not None and not isinstance(model_tag, (bytes, str)): raise Exception( - "Expected model_tag to be a str, received: {}".format(type(model_tag)) + f"Expected model_tag to be a str, received: {type(model_tag)}" ) # map input types to rpc msg @@ -849,8 +804,7 @@ async def UpgradeModel( model_tag=None, target_version=None, ): - """ - UpgradeModel upgrades a model. + """UpgradeModel upgrades a model. agent_stream : str dry_run : bool @@ -861,37 +815,29 @@ async def UpgradeModel( """ if agent_stream is not None and not isinstance(agent_stream, (bytes, str)): raise Exception( - "Expected agent_stream to be a str, received: {}".format( - type(agent_stream) - ) + f"Expected agent_stream to be a str, received: {type(agent_stream)}" ) if dry_run is not None and not isinstance(dry_run, bool): - raise Exception( - "Expected dry_run to be a bool, received: {}".format(type(dry_run)) - ) + raise Exception(f"Expected dry_run to be a bool, received: {type(dry_run)}") if ignore_agent_versions is not None and not isinstance( ignore_agent_versions, bool ): raise Exception( - "Expected ignore_agent_versions to be a bool, received: {}".format( - type(ignore_agent_versions) - ) + f"Expected ignore_agent_versions to be a bool, received: {type(ignore_agent_versions)}" ) if model_tag is not None and not isinstance(model_tag, (bytes, str)): raise Exception( - "Expected model_tag to be a str, received: {}".format(type(model_tag)) + f"Expected model_tag to be a str, received: {type(model_tag)}" ) if target_version is not None and not isinstance( target_version, (dict, Number) ): raise Exception( - "Expected target_version to be a Number, received: {}".format( - type(target_version) - ) + f"Expected target_version to be a Number, received: {type(target_version)}" ) # map input types to rpc msg @@ -974,8 +920,7 @@ class PayloadsFacade(Type): @ReturnMapping(PayloadListResults) async def List(self, patterns=None): - """ - List builds the list of payloads being tracked for + """List builds the list of payloads being tracked for the given unit and IDs. If no IDs are provided then all tracked payloads for the unit are returned. @@ -984,9 +929,7 @@ async def List(self, patterns=None): """ if patterns is not None and not isinstance(patterns, (bytes, str, list)): raise Exception( - "Expected patterns to be a Sequence, received: {}".format( - type(patterns) - ) + f"Expected patterns to be a Sequence, received: {type(patterns)}" ) # map input types to rpc msg @@ -1007,11 +950,7 @@ class PingerFacade(Type): @ReturnMapping(None) async def Ping(self): - """ - - Returns -> None - """ - + """Returns -> None""" # map input types to rpc msg _params = dict() msg = dict(type="Pinger", request="Ping", version=1, params=_params) @@ -1021,11 +960,7 @@ async def Ping(self): @ReturnMapping(None) async def Stop(self): - """ - - Returns -> None - """ - + """Returns -> None""" # map input types to rpc msg _params = dict() msg = dict(type="Pinger", request="Stop", version=1, params=_params) @@ -1237,16 +1172,13 @@ class SecretBackendsFacade(Type): @ReturnMapping(ErrorResults) async def AddSecretBackends(self, args=None): - """ - AddSecretBackends adds new secret backends. + """AddSecretBackends adds new secret backends. args : typing.Sequence[~AddSecretBackendArg] Returns -> ErrorResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -1262,22 +1194,17 @@ async def AddSecretBackends(self, args=None): @ReturnMapping(ListSecretBackendsResults) async def ListSecretBackends(self, names=None, reveal=None): - """ - ListSecretBackends lists available secret backends. + """ListSecretBackends lists available secret backends. names : typing.Sequence[str] reveal : bool Returns -> ListSecretBackendsResults """ if names is not None and not isinstance(names, (bytes, str, list)): - raise Exception( - "Expected names to be a Sequence, received: {}".format(type(names)) - ) + raise Exception(f"Expected names to be a Sequence, received: {type(names)}") if reveal is not None and not isinstance(reveal, bool): - raise Exception( - "Expected reveal to be a bool, received: {}".format(type(reveal)) - ) + raise Exception(f"Expected reveal to be a bool, received: {type(reveal)}") # map input types to rpc msg _params = dict() @@ -1294,16 +1221,13 @@ async def ListSecretBackends(self, names=None, reveal=None): @ReturnMapping(ErrorResults) async def RemoveSecretBackends(self, args=None): - """ - RemoveSecretBackends removes secret backends. + """RemoveSecretBackends removes secret backends. args : typing.Sequence[~RemoveSecretBackendArg] Returns -> ErrorResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -1319,16 +1243,13 @@ async def RemoveSecretBackends(self, args=None): @ReturnMapping(ErrorResults) async def UpdateSecretBackends(self, args=None): - """ - UpdateSecretBackends updates secret backends. + """UpdateSecretBackends updates secret backends. args : typing.Sequence[~UpdateSecretBackendArg] Returns -> ErrorResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -1472,8 +1393,7 @@ class SecretsFacade(Type): @ReturnMapping(ListSecretResults) async def ListSecrets(self, filter_=None, show_secrets=None): - """ - ListSecrets lists available secrets. + """ListSecrets lists available secrets. filter_ : SecretsFilter show_secrets : bool @@ -1481,16 +1401,12 @@ async def ListSecrets(self, filter_=None, show_secrets=None): """ if filter_ is not None and not isinstance(filter_, (dict, SecretsFilter)): raise Exception( - "Expected filter_ to be a SecretsFilter, received: {}".format( - type(filter_) - ) + f"Expected filter_ to be a SecretsFilter, received: {type(filter_)}" ) if show_secrets is not None and not isinstance(show_secrets, bool): raise Exception( - "Expected show_secrets to be a bool, received: {}".format( - type(show_secrets) - ) + f"Expected show_secrets to be a bool, received: {type(show_secrets)}" ) # map input types to rpc msg diff --git a/juju/client/_client10.py b/juju/client/_client10.py index 4417a71f8..3be6be9c7 100644 --- a/juju/client/_client10.py +++ b/juju/client/_client10.py @@ -1,8 +1,8 @@ # DO NOT CHANGE THIS FILE! This file is auto-generated by facade.py. # Changes will be overwritten/lost when the file is regenerated. -from juju.client.facade import Type, ReturnMapping from juju.client._definitions import * +from juju.client.facade import ReturnMapping, Type class MachineManagerFacade(Type): @@ -589,8 +589,7 @@ class MachineManagerFacade(Type): @ReturnMapping(AddMachinesResults) async def AddMachines(self, params=None): - """ - AddMachines adds new machines with the supplied parameters. + """AddMachines adds new machines with the supplied parameters. The args will contain Base info. params : typing.Sequence[~AddMachineParams] @@ -598,7 +597,7 @@ async def AddMachines(self, params=None): """ if params is not None and not isinstance(params, (bytes, str, list)): raise Exception( - "Expected params to be a Sequence, received: {}".format(type(params)) + f"Expected params to be a Sequence, received: {type(params)}" ) # map input types to rpc msg @@ -614,8 +613,7 @@ async def AddMachines(self, params=None): async def DestroyMachineWithParams( self, dry_run=None, force=None, keep=None, machine_tags=None, max_wait=None ): - """ - DestroyMachineWithParams removes a set of machines from the model. + """DestroyMachineWithParams removes a set of machines from the model. dry_run : bool force : bool @@ -625,32 +623,24 @@ async def DestroyMachineWithParams( Returns -> DestroyMachineResults """ if dry_run is not None and not isinstance(dry_run, bool): - raise Exception( - "Expected dry_run to be a bool, received: {}".format(type(dry_run)) - ) + raise Exception(f"Expected dry_run to be a bool, received: {type(dry_run)}") if force is not None and not isinstance(force, bool): - raise Exception( - "Expected force to be a bool, received: {}".format(type(force)) - ) + raise Exception(f"Expected force to be a bool, received: {type(force)}") if keep is not None and not isinstance(keep, bool): - raise Exception( - "Expected keep to be a bool, received: {}".format(type(keep)) - ) + raise Exception(f"Expected keep to be a bool, received: {type(keep)}") if machine_tags is not None and not isinstance( machine_tags, (bytes, str, list) ): raise Exception( - "Expected machine_tags to be a Sequence, received: {}".format( - type(machine_tags) - ) + f"Expected machine_tags to be a Sequence, received: {type(machine_tags)}" ) if max_wait is not None and not isinstance(max_wait, int): raise Exception( - "Expected max_wait to be a int, received: {}".format(type(max_wait)) + f"Expected max_wait to be a int, received: {type(max_wait)}" ) # map input types to rpc msg @@ -671,8 +661,7 @@ async def DestroyMachineWithParams( @ReturnMapping(StringsResults) async def GetUpgradeSeriesMessages(self, params=None): - """ - GetUpgradeSeriesMessages returns all new messages associated with upgrade + """GetUpgradeSeriesMessages returns all new messages associated with upgrade series events. Messages that have already been retrieved once are not returned by this method. @@ -681,7 +670,7 @@ async def GetUpgradeSeriesMessages(self, params=None): """ if params is not None and not isinstance(params, (bytes, str, list)): raise Exception( - "Expected params to be a Sequence, received: {}".format(type(params)) + f"Expected params to be a Sequence, received: {type(params)}" ) # map input types to rpc msg @@ -698,8 +687,7 @@ async def GetUpgradeSeriesMessages(self, params=None): @ReturnMapping(InstanceTypesResults) async def InstanceTypes(self, constraints=None): - """ - InstanceTypes returns instance type information for the cloud and region + """InstanceTypes returns instance type information for the cloud and region in which the current model is deployed. constraints : typing.Sequence[~ModelInstanceTypesConstraint] @@ -707,9 +695,7 @@ async def InstanceTypes(self, constraints=None): """ if constraints is not None and not isinstance(constraints, (bytes, str, list)): raise Exception( - "Expected constraints to be a Sequence, received: {}".format( - type(constraints) - ) + f"Expected constraints to be a Sequence, received: {type(constraints)}" ) # map input types to rpc msg @@ -725,8 +711,7 @@ async def InstanceTypes(self, constraints=None): async def ProvisioningScript( self, data_dir=None, disable_package_commands=None, machine_id=None, nonce=None ): - """ - ProvisioningScript returns a shell script that, when run, + """ProvisioningScript returns a shell script that, when run, provisions a machine agent on the machine executing the script. data_dir : str @@ -737,27 +722,23 @@ async def ProvisioningScript( """ if data_dir is not None and not isinstance(data_dir, (bytes, str)): raise Exception( - "Expected data_dir to be a str, received: {}".format(type(data_dir)) + f"Expected data_dir to be a str, received: {type(data_dir)}" ) if disable_package_commands is not None and not isinstance( disable_package_commands, bool ): raise Exception( - "Expected disable_package_commands to be a bool, received: {}".format( - type(disable_package_commands) - ) + f"Expected disable_package_commands to be a bool, received: {type(disable_package_commands)}" ) if machine_id is not None and not isinstance(machine_id, (bytes, str)): raise Exception( - "Expected machine_id to be a str, received: {}".format(type(machine_id)) + f"Expected machine_id to be a str, received: {type(machine_id)}" ) if nonce is not None and not isinstance(nonce, (bytes, str)): - raise Exception( - "Expected nonce to be a str, received: {}".format(type(nonce)) - ) + raise Exception(f"Expected nonce to be a str, received: {type(nonce)}") # map input types to rpc msg _params = dict() @@ -776,23 +757,18 @@ async def ProvisioningScript( @ReturnMapping(ErrorResults) async def RetryProvisioning(self, all_=None, machines=None): - """ - RetryProvisioning marks a provisioning error as transient on the machines. + """RetryProvisioning marks a provisioning error as transient on the machines. all_ : bool machines : typing.Sequence[str] Returns -> ErrorResults """ if all_ is not None and not isinstance(all_, bool): - raise Exception( - "Expected all_ to be a bool, received: {}".format(type(all_)) - ) + raise Exception(f"Expected all_ to be a bool, received: {type(all_)}") if machines is not None and not isinstance(machines, (bytes, str, list)): raise Exception( - "Expected machines to be a Sequence, received: {}".format( - type(machines) - ) + f"Expected machines to be a Sequence, received: {type(machines)}" ) # map input types to rpc msg @@ -810,8 +786,7 @@ async def RetryProvisioning(self, all_=None, machines=None): @ReturnMapping(ErrorResult) async def UpgradeSeriesComplete(self, channel=None, force=None, tag=None): - """ - UpgradeSeriesComplete marks a machine as having completed a managed series + """UpgradeSeriesComplete marks a machine as having completed a managed series upgrade. channel : str @@ -820,19 +795,13 @@ async def UpgradeSeriesComplete(self, channel=None, force=None, tag=None): Returns -> ErrorResult """ if channel is not None and not isinstance(channel, (bytes, str)): - raise Exception( - "Expected channel to be a str, received: {}".format(type(channel)) - ) + raise Exception(f"Expected channel to be a str, received: {type(channel)}") if force is not None and not isinstance(force, bool): - raise Exception( - "Expected force to be a bool, received: {}".format(type(force)) - ) + raise Exception(f"Expected force to be a bool, received: {type(force)}") if tag is not None and not isinstance(tag, (dict, Entity)): - raise Exception( - "Expected tag to be a Entity, received: {}".format(type(tag)) - ) + raise Exception(f"Expected tag to be a Entity, received: {type(tag)}") # map input types to rpc msg _params = dict() @@ -850,8 +819,7 @@ async def UpgradeSeriesComplete(self, channel=None, force=None, tag=None): @ReturnMapping(ErrorResult) async def UpgradeSeriesPrepare(self, channel=None, force=None, tag=None): - """ - UpgradeSeriesPrepare prepares a machine for a OS series upgrade. + """UpgradeSeriesPrepare prepares a machine for a OS series upgrade. channel : str force : bool @@ -859,19 +827,13 @@ async def UpgradeSeriesPrepare(self, channel=None, force=None, tag=None): Returns -> ErrorResult """ if channel is not None and not isinstance(channel, (bytes, str)): - raise Exception( - "Expected channel to be a str, received: {}".format(type(channel)) - ) + raise Exception(f"Expected channel to be a str, received: {type(channel)}") if force is not None and not isinstance(force, bool): - raise Exception( - "Expected force to be a bool, received: {}".format(type(force)) - ) + raise Exception(f"Expected force to be a bool, received: {type(force)}") if tag is not None and not isinstance(tag, (dict, Entity)): - raise Exception( - "Expected tag to be a Entity, received: {}".format(type(tag)) - ) + raise Exception(f"Expected tag to be a Entity, received: {type(tag)}") # map input types to rpc msg _params = dict() @@ -889,8 +851,7 @@ async def UpgradeSeriesPrepare(self, channel=None, force=None, tag=None): @ReturnMapping(UpgradeSeriesUnitsResults) async def UpgradeSeriesValidate(self, args=None): - """ - UpgradeSeriesValidate validates that the incoming arguments correspond to a + """UpgradeSeriesValidate validates that the incoming arguments correspond to a valid series upgrade for the target machine. If they do, a list of the machine's current units is returned for use in soliciting user confirmation of the command. @@ -899,9 +860,7 @@ async def UpgradeSeriesValidate(self, args=None): Returns -> UpgradeSeriesUnitsResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -917,8 +876,7 @@ async def UpgradeSeriesValidate(self, args=None): @ReturnMapping(NotifyWatchResults) async def WatchUpgradeSeriesNotifications(self, entities=None): - """ - WatchUpgradeSeriesNotifications returns a watcher that fires on upgrade + """WatchUpgradeSeriesNotifications returns a watcher that fires on upgrade series events. entities : typing.Sequence[~Entity] @@ -926,9 +884,7 @@ async def WatchUpgradeSeriesNotifications(self, entities=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1804,8 +1760,7 @@ class ModelManagerFacade(Type): @ReturnMapping(ErrorResults) async def ChangeModelCredential(self, model_credentials=None): - """ - ChangeModelCredential changes cloud credential reference for models. + """ChangeModelCredential changes cloud credential reference for models. These new cloud credentials must already exist on the controller. model_credentials : typing.Sequence[~ChangeModelCredentialParams] @@ -1815,9 +1770,7 @@ async def ChangeModelCredential(self, model_credentials=None): model_credentials, (bytes, str, list) ): raise Exception( - "Expected model_credentials to be a Sequence, received: {}".format( - type(model_credentials) - ) + f"Expected model_credentials to be a Sequence, received: {type(model_credentials)}" ) # map input types to rpc msg @@ -1842,8 +1795,7 @@ async def CreateModel( owner_tag=None, region=None, ): - """ - CreateModel creates a new model using the account and + """CreateModel creates a new model using the account and model config specified in the args. cloud_tag : str @@ -1856,33 +1808,29 @@ async def CreateModel( """ if cloud_tag is not None and not isinstance(cloud_tag, (bytes, str)): raise Exception( - "Expected cloud_tag to be a str, received: {}".format(type(cloud_tag)) + f"Expected cloud_tag to be a str, received: {type(cloud_tag)}" ) if config is not None and not isinstance(config, dict): raise Exception( - "Expected config to be a Mapping, received: {}".format(type(config)) + f"Expected config to be a Mapping, received: {type(config)}" ) if credential is not None and not isinstance(credential, (bytes, str)): raise Exception( - "Expected credential to be a str, received: {}".format(type(credential)) + f"Expected credential to be a str, received: {type(credential)}" ) if name is not None and not isinstance(name, (bytes, str)): - raise Exception( - "Expected name to be a str, received: {}".format(type(name)) - ) + raise Exception(f"Expected name to be a str, received: {type(name)}") if owner_tag is not None and not isinstance(owner_tag, (bytes, str)): raise Exception( - "Expected owner_tag to be a str, received: {}".format(type(owner_tag)) + f"Expected owner_tag to be a str, received: {type(owner_tag)}" ) if region is not None and not isinstance(region, (bytes, str)): - raise Exception( - "Expected region to be a str, received: {}".format(type(region)) - ) + raise Exception(f"Expected region to be a str, received: {type(region)}") # map input types to rpc msg _params = dict() @@ -1900,8 +1848,7 @@ async def CreateModel( @ReturnMapping(ErrorResults) async def DestroyModels(self, models=None): - """ - DestroyModels will try to destroy the specified models. + """DestroyModels will try to destroy the specified models. If there is a block on destruction, this method will return an error. From ModelManager v7 onwards, DestroyModels gains 'force' and 'max-wait' parameters. @@ -1910,7 +1857,7 @@ async def DestroyModels(self, models=None): """ if models is not None and not isinstance(models, (bytes, str, list)): raise Exception( - "Expected models to be a Sequence, received: {}".format(type(models)) + f"Expected models to be a Sequence, received: {type(models)}" ) # map input types to rpc msg @@ -1924,8 +1871,7 @@ async def DestroyModels(self, models=None): @ReturnMapping(StringResults) async def DumpModels(self, entities=None, simplified=None): - """ - DumpModels will export the models into the database agnostic + """DumpModels will export the models into the database agnostic representation. The user needs to either be a controller admin, or have admin privileges on the model itself. @@ -1935,16 +1881,12 @@ async def DumpModels(self, entities=None, simplified=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) if simplified is not None and not isinstance(simplified, bool): raise Exception( - "Expected simplified to be a bool, received: {}".format( - type(simplified) - ) + f"Expected simplified to be a bool, received: {type(simplified)}" ) # map input types to rpc msg @@ -1959,8 +1901,7 @@ async def DumpModels(self, entities=None, simplified=None): @ReturnMapping(MapResults) async def DumpModelsDB(self, entities=None): - """ - DumpModelsDB will gather all documents from all model collections + """DumpModelsDB will gather all documents from all model collections for the specified model. The map result contains a map of collection names to lists of documents represented as maps. @@ -1969,9 +1910,7 @@ async def DumpModelsDB(self, entities=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1985,8 +1924,7 @@ async def DumpModelsDB(self, entities=None): @ReturnMapping(ModelSummaryResults) async def ListModelSummaries(self, all_=None, user_tag=None): - """ - ListModelSummaries returns models that the specified user + """ListModelSummaries returns models that the specified user has access to in the current server. Controller admins (superuser) can list models for any user. Other users can only ask about their own models. @@ -1996,13 +1934,11 @@ async def ListModelSummaries(self, all_=None, user_tag=None): Returns -> ModelSummaryResults """ if all_ is not None and not isinstance(all_, bool): - raise Exception( - "Expected all_ to be a bool, received: {}".format(type(all_)) - ) + raise Exception(f"Expected all_ to be a bool, received: {type(all_)}") if user_tag is not None and not isinstance(user_tag, (bytes, str)): raise Exception( - "Expected user_tag to be a str, received: {}".format(type(user_tag)) + f"Expected user_tag to be a str, received: {type(user_tag)}" ) # map input types to rpc msg @@ -2020,8 +1956,7 @@ async def ListModelSummaries(self, all_=None, user_tag=None): @ReturnMapping(UserModelList) async def ListModels(self, tag=None): - """ - ListModels returns the models that the specified user + """ListModels returns the models that the specified user has access to in the current server. Controller admins (superuser) can list models for any user. Other users can only ask about their own models. @@ -2030,7 +1965,7 @@ async def ListModels(self, tag=None): Returns -> UserModelList """ if tag is not None and not isinstance(tag, (bytes, str)): - raise Exception("Expected tag to be a str, received: {}".format(type(tag))) + raise Exception(f"Expected tag to be a str, received: {type(tag)}") # map input types to rpc msg _params = dict() @@ -2043,8 +1978,7 @@ async def ListModels(self, tag=None): @ReturnMapping(ModelDefaultsResults) async def ModelDefaultsForClouds(self, entities=None): - """ - ModelDefaultsForClouds returns the default config values for the specified + """ModelDefaultsForClouds returns the default config values for the specified clouds. entities : typing.Sequence[~Entity] @@ -2052,9 +1986,7 @@ async def ModelDefaultsForClouds(self, entities=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -2071,17 +2003,14 @@ async def ModelDefaultsForClouds(self, entities=None): @ReturnMapping(ModelInfoResults) async def ModelInfo(self, entities=None): - """ - ModelInfo returns information about the specified models. + """ModelInfo returns information about the specified models. entities : typing.Sequence[~Entity] Returns -> ModelInfoResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -2093,17 +2022,14 @@ async def ModelInfo(self, entities=None): @ReturnMapping(ModelStatusResults) async def ModelStatus(self, entities=None): - """ - ModelStatus returns a summary of the model. + """ModelStatus returns a summary of the model. entities : typing.Sequence[~Entity] Returns -> ModelStatusResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -2117,15 +2043,14 @@ async def ModelStatus(self, entities=None): @ReturnMapping(ErrorResults) async def ModifyModelAccess(self, changes=None): - """ - ModifyModelAccess changes the model access granted to users. + """ModifyModelAccess changes the model access granted to users. changes : typing.Sequence[~ModifyModelAccess] Returns -> ErrorResults """ if changes is not None and not isinstance(changes, (bytes, str, list)): raise Exception( - "Expected changes to be a Sequence, received: {}".format(type(changes)) + f"Expected changes to be a Sequence, received: {type(changes)}" ) # map input types to rpc msg @@ -2139,15 +2064,14 @@ async def ModifyModelAccess(self, changes=None): @ReturnMapping(ErrorResults) async def SetModelDefaults(self, config=None): - """ - SetModelDefaults writes new values for the specified default model settings. + """SetModelDefaults writes new values for the specified default model settings. config : typing.Sequence[~ModelDefaultValues] Returns -> ErrorResults """ if config is not None and not isinstance(config, (bytes, str, list)): raise Exception( - "Expected config to be a Sequence, received: {}".format(type(config)) + f"Expected config to be a Sequence, received: {type(config)}" ) # map input types to rpc msg @@ -2161,16 +2085,13 @@ async def SetModelDefaults(self, config=None): @ReturnMapping(ErrorResults) async def UnsetModelDefaults(self, keys=None): - """ - UnsetModelDefaults removes the specified default model settings. + """UnsetModelDefaults removes the specified default model settings. keys : typing.Sequence[~ModelUnsetKeys] Returns -> ErrorResults """ if keys is not None and not isinstance(keys, (bytes, str, list)): - raise Exception( - "Expected keys to be a Sequence, received: {}".format(type(keys)) - ) + raise Exception(f"Expected keys to be a Sequence, received: {type(keys)}") # map input types to rpc msg _params = dict() diff --git a/juju/client/_client11.py b/juju/client/_client11.py index 6c96e3b6c..9fa3fae84 100644 --- a/juju/client/_client11.py +++ b/juju/client/_client11.py @@ -1,8 +1,8 @@ # DO NOT CHANGE THIS FILE! This file is auto-generated by facade.py. # Changes will be overwritten/lost when the file is regenerated. -from juju.client.facade import Type, ReturnMapping from juju.client._definitions import * +from juju.client.facade import ReturnMapping, Type class ControllerFacade(Type): @@ -871,14 +871,12 @@ class ControllerFacade(Type): @ReturnMapping(UserModelList) async def AllModels(self): - """ - AllModels allows controller administrators to get the list of all the + """AllModels allows controller administrators to get the list of all the models in the controller. Returns -> UserModelList """ - # map input types to rpc msg _params = dict() msg = dict(type="Controller", request="AllModels", version=11, params=_params) @@ -888,17 +886,14 @@ async def AllModels(self): @ReturnMapping(CloudSpecResults) async def CloudSpec(self, entities=None): - """ - CloudSpec returns the model's cloud spec. + """CloudSpec returns the model's cloud spec. entities : typing.Sequence[~Entity] Returns -> CloudSpecResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -910,8 +905,7 @@ async def CloudSpec(self, entities=None): @ReturnMapping(None) async def ConfigSet(self, config=None): - """ - ConfigSet changes the value of specified controller configuration + """ConfigSet changes the value of specified controller configuration settings. Only some settings can be changed after bootstrap. Settings that aren't specified in the params are left unchanged. @@ -920,7 +914,7 @@ async def ConfigSet(self, config=None): """ if config is not None and not isinstance(config, dict): raise Exception( - "Expected config to be a Mapping, received: {}".format(type(config)) + f"Expected config to be a Mapping, received: {type(config)}" ) # map input types to rpc msg @@ -932,17 +926,14 @@ async def ConfigSet(self, config=None): @ReturnMapping(ControllerAPIInfoResults) async def ControllerAPIInfoForModels(self, entities=None): - """ - ControllerAPIInfoForModels returns the controller api connection details for the specified models. + """ControllerAPIInfoForModels returns the controller api connection details for the specified models. entities : typing.Sequence[~Entity] Returns -> ControllerAPIInfoResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -959,13 +950,10 @@ async def ControllerAPIInfoForModels(self, entities=None): @ReturnMapping(ControllerConfigResult) async def ControllerConfig(self): - """ - ControllerConfig returns the controller's configuration. - + """ControllerConfig returns the controller's configuration. Returns -> ControllerConfigResult """ - # map input types to rpc msg _params = dict() msg = dict( @@ -977,8 +965,7 @@ async def ControllerConfig(self): @ReturnMapping(ControllerVersionResults) async def ControllerVersion(self): - """ - ControllerVersion returns the version information associated with this + """ControllerVersion returns the version information associated with this controller binary. NOTE: the implementation intentionally does not check for SuperuserAccess @@ -987,7 +974,6 @@ async def ControllerVersion(self): Returns -> ControllerVersionResults """ - # map input types to rpc msg _params = dict() msg = dict( @@ -999,14 +985,12 @@ async def ControllerVersion(self): @ReturnMapping(DashboardConnectionInfo) async def DashboardConnectionInfo(self): - """ - DashboardConnectionInfo returns the connection information for a client to + """DashboardConnectionInfo returns the connection information for a client to connect to the Juju Dashboard including any proxying information. Returns -> DashboardConnectionInfo """ - # map input types to rpc msg _params = dict() msg = dict( @@ -1028,8 +1012,7 @@ async def DestroyController( max_wait=None, model_timeout=None, ): - """ - DestroyController destroys the controller. + """DestroyController destroys the controller. If the args specify the destruction of the models, this method will attempt to do so. Otherwise, if the controller has any non-empty, @@ -1045,33 +1028,25 @@ async def DestroyController( """ if destroy_models is not None and not isinstance(destroy_models, bool): raise Exception( - "Expected destroy_models to be a bool, received: {}".format( - type(destroy_models) - ) + f"Expected destroy_models to be a bool, received: {type(destroy_models)}" ) if destroy_storage is not None and not isinstance(destroy_storage, bool): raise Exception( - "Expected destroy_storage to be a bool, received: {}".format( - type(destroy_storage) - ) + f"Expected destroy_storage to be a bool, received: {type(destroy_storage)}" ) if force is not None and not isinstance(force, bool): - raise Exception( - "Expected force to be a bool, received: {}".format(type(force)) - ) + raise Exception(f"Expected force to be a bool, received: {type(force)}") if max_wait is not None and not isinstance(max_wait, int): raise Exception( - "Expected max_wait to be a int, received: {}".format(type(max_wait)) + f"Expected max_wait to be a int, received: {type(max_wait)}" ) if model_timeout is not None and not isinstance(model_timeout, int): raise Exception( - "Expected model_timeout to be a int, received: {}".format( - type(model_timeout) - ) + f"Expected model_timeout to be a int, received: {type(model_timeout)}" ) # map input types to rpc msg @@ -1089,13 +1064,10 @@ async def DestroyController( @ReturnMapping(CloudSpecResult) async def GetCloudSpec(self): - """ - GetCloudSpec constructs the CloudSpec for a validated and authorized model. - + """GetCloudSpec constructs the CloudSpec for a validated and authorized model. Returns -> CloudSpecResult """ - # map input types to rpc msg _params = dict() msg = dict( @@ -1107,8 +1079,7 @@ async def GetCloudSpec(self): @ReturnMapping(UserAccessResults) async def GetControllerAccess(self, entities=None): - """ - GetControllerAccess returns the level of access the specified users + """GetControllerAccess returns the level of access the specified users have on the controller. entities : typing.Sequence[~Entity] @@ -1116,9 +1087,7 @@ async def GetControllerAccess(self, entities=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1132,15 +1101,13 @@ async def GetControllerAccess(self, entities=None): @ReturnMapping(HostedModelConfigsResults) async def HostedModelConfigs(self): - """ - HostedModelConfigs returns all the information that the client needs in + """HostedModelConfigs returns all the information that the client needs in order to connect directly with the host model's provider and destroy it directly. Returns -> HostedModelConfigsResults """ - # map input types to rpc msg _params = dict() msg = dict( @@ -1152,8 +1119,7 @@ async def HostedModelConfigs(self): @ReturnMapping(StringResult) async def IdentityProviderURL(self): - """ - IdentityProviderURL returns the URL of the configured external identity + """IdentityProviderURL returns the URL of the configured external identity provider for this controller or an empty string if no external identity provider has been configured when the controller was bootstrapped. @@ -1163,7 +1129,6 @@ async def IdentityProviderURL(self): Returns -> StringResult """ - # map input types to rpc msg _params = dict() msg = dict( @@ -1175,17 +1140,14 @@ async def IdentityProviderURL(self): @ReturnMapping(InitiateMigrationResults) async def InitiateMigration(self, specs=None): - """ - InitiateMigration attempts to begin the migration of one or + """InitiateMigration attempts to begin the migration of one or more models to other controllers. specs : typing.Sequence[~MigrationSpec] Returns -> InitiateMigrationResults """ if specs is not None and not isinstance(specs, (bytes, str, list)): - raise Exception( - "Expected specs to be a Sequence, received: {}".format(type(specs)) - ) + raise Exception(f"Expected specs to be a Sequence, received: {type(specs)}") # map input types to rpc msg _params = dict() @@ -1198,8 +1160,7 @@ async def InitiateMigration(self, specs=None): @ReturnMapping(ModelBlockInfoList) async def ListBlockedModels(self): - """ - ListBlockedModels returns a list of all models on the controller + """ListBlockedModels returns a list of all models on the controller which have a block in place. The resulting slice is sorted by model name, then owner. Callers must be controller administrators to retrieve the list. @@ -1207,7 +1168,6 @@ async def ListBlockedModels(self): Returns -> ModelBlockInfoList """ - # map input types to rpc msg _params = dict() msg = dict( @@ -1219,15 +1179,13 @@ async def ListBlockedModels(self): @ReturnMapping(ModelConfigResults) async def ModelConfig(self): - """ - ModelConfig returns the model config for the controller + """ModelConfig returns the model config for the controller model. For information on the current model, use client.ModelGet Returns -> ModelConfigResults """ - # map input types to rpc msg _params = dict() msg = dict(type="Controller", request="ModelConfig", version=11, params=_params) @@ -1237,17 +1195,14 @@ async def ModelConfig(self): @ReturnMapping(ModelStatusResults) async def ModelStatus(self, entities=None): - """ - ModelStatus returns a summary of the model. + """ModelStatus returns a summary of the model. entities : typing.Sequence[~Entity] Returns -> ModelStatusResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1259,15 +1214,14 @@ async def ModelStatus(self, entities=None): @ReturnMapping(ErrorResults) async def ModifyControllerAccess(self, changes=None): - """ - ModifyControllerAccess changes the model access granted to users. + """ModifyControllerAccess changes the model access granted to users. changes : typing.Sequence[~ModifyControllerAccess] Returns -> ErrorResults """ if changes is not None and not isinstance(changes, (bytes, str, list)): raise Exception( - "Expected changes to be a Sequence, received: {}".format(type(changes)) + f"Expected changes to be a Sequence, received: {type(changes)}" ) # map input types to rpc msg @@ -1284,13 +1238,10 @@ async def ModifyControllerAccess(self, changes=None): @ReturnMapping(StringResult) async def MongoVersion(self): - """ - MongoVersion allows the introspection of the mongo version per controller - + """MongoVersion allows the introspection of the mongo version per controller Returns -> StringResult """ - # map input types to rpc msg _params = dict() msg = dict( @@ -1302,16 +1253,13 @@ async def MongoVersion(self): @ReturnMapping(None) async def RemoveBlocks(self, all_=None): - """ - RemoveBlocks removes all the blocks in the controller. + """RemoveBlocks removes all the blocks in the controller. all_ : bool Returns -> None """ if all_ is not None and not isinstance(all_, bool): - raise Exception( - "Expected all_ to be a bool, received: {}".format(type(all_)) - ) + raise Exception(f"Expected all_ to be a bool, received: {type(all_)}") # map input types to rpc msg _params = dict() @@ -1324,15 +1272,13 @@ async def RemoveBlocks(self, all_=None): @ReturnMapping(SummaryWatcherID) async def WatchAllModelSummaries(self): - """ - WatchAllModelSummaries starts watching the summary updates from the cache. + """WatchAllModelSummaries starts watching the summary updates from the cache. This method is superuser access only, and watches all models in the controller. Returns -> SummaryWatcherID """ - # map input types to rpc msg _params = dict() msg = dict( @@ -1347,15 +1293,13 @@ async def WatchAllModelSummaries(self): @ReturnMapping(AllWatcherId) async def WatchAllModels(self): - """ - WatchAllModels starts watching events for all models in the + """WatchAllModels starts watching events for all models in the controller. The returned AllWatcherId should be used with Next on the AllModelWatcher endpoint to receive deltas. Returns -> AllWatcherId """ - # map input types to rpc msg _params = dict() msg = dict( @@ -1367,17 +1311,14 @@ async def WatchAllModels(self): @ReturnMapping(NotifyWatchResults) async def WatchCloudSpecsChanges(self, entities=None): - """ - WatchCloudSpecsChanges returns a watcher for cloud spec changes. + """WatchCloudSpecsChanges returns a watcher for cloud spec changes. entities : typing.Sequence[~Entity] Returns -> NotifyWatchResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1394,14 +1335,12 @@ async def WatchCloudSpecsChanges(self, entities=None): @ReturnMapping(SummaryWatcherID) async def WatchModelSummaries(self): - """ - WatchModelSummaries starts watching the summary updates from the cache. + """WatchModelSummaries starts watching the summary updates from the cache. Only models that the user has access to are returned. Returns -> SummaryWatcherID """ - # map input types to rpc msg _params = dict() msg = dict( diff --git a/juju/client/_client12.py b/juju/client/_client12.py index a0d3dd1c2..d53884bd0 100644 --- a/juju/client/_client12.py +++ b/juju/client/_client12.py @@ -1,8 +1,8 @@ # DO NOT CHANGE THIS FILE! This file is auto-generated by facade.py. # Changes will be overwritten/lost when the file is regenerated. -from juju.client.facade import Type, ReturnMapping from juju.client._definitions import * +from juju.client.facade import ReturnMapping, Type class ControllerFacade(Type): @@ -840,14 +840,12 @@ class ControllerFacade(Type): @ReturnMapping(UserModelList) async def AllModels(self): - """ - AllModels allows controller administrators to get the list of all the + """AllModels allows controller administrators to get the list of all the models in the controller. Returns -> UserModelList """ - # map input types to rpc msg _params = dict() msg = dict(type="Controller", request="AllModels", version=12, params=_params) @@ -857,17 +855,14 @@ async def AllModels(self): @ReturnMapping(CloudSpecResults) async def CloudSpec(self, entities=None): - """ - CloudSpec returns the model's cloud spec. + """CloudSpec returns the model's cloud spec. entities : typing.Sequence[~Entity] Returns -> CloudSpecResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -879,8 +874,7 @@ async def CloudSpec(self, entities=None): @ReturnMapping(None) async def ConfigSet(self, config=None): - """ - ConfigSet changes the value of specified controller configuration + """ConfigSet changes the value of specified controller configuration settings. Only some settings can be changed after bootstrap. Settings that aren't specified in the params are left unchanged. @@ -889,7 +883,7 @@ async def ConfigSet(self, config=None): """ if config is not None and not isinstance(config, dict): raise Exception( - "Expected config to be a Mapping, received: {}".format(type(config)) + f"Expected config to be a Mapping, received: {type(config)}" ) # map input types to rpc msg @@ -901,17 +895,14 @@ async def ConfigSet(self, config=None): @ReturnMapping(ControllerAPIInfoResults) async def ControllerAPIInfoForModels(self, entities=None): - """ - ControllerAPIInfoForModels returns the controller api connection details for the specified models. + """ControllerAPIInfoForModels returns the controller api connection details for the specified models. entities : typing.Sequence[~Entity] Returns -> ControllerAPIInfoResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -928,13 +919,10 @@ async def ControllerAPIInfoForModels(self, entities=None): @ReturnMapping(ControllerConfigResult) async def ControllerConfig(self): - """ - ControllerConfig returns the controller's configuration. - + """ControllerConfig returns the controller's configuration. Returns -> ControllerConfigResult """ - # map input types to rpc msg _params = dict() msg = dict( @@ -946,8 +934,7 @@ async def ControllerConfig(self): @ReturnMapping(ControllerVersionResults) async def ControllerVersion(self): - """ - ControllerVersion returns the version information associated with this + """ControllerVersion returns the version information associated with this controller binary. NOTE: the implementation intentionally does not check for SuperuserAccess @@ -956,7 +943,6 @@ async def ControllerVersion(self): Returns -> ControllerVersionResults """ - # map input types to rpc msg _params = dict() msg = dict( @@ -968,14 +954,12 @@ async def ControllerVersion(self): @ReturnMapping(DashboardConnectionInfo) async def DashboardConnectionInfo(self): - """ - DashboardConnectionInfo returns the connection information for a client to + """DashboardConnectionInfo returns the connection information for a client to connect to the Juju Dashboard including any proxying information. Returns -> DashboardConnectionInfo """ - # map input types to rpc msg _params = dict() msg = dict( @@ -997,8 +981,7 @@ async def DestroyController( max_wait=None, model_timeout=None, ): - """ - DestroyController destroys the controller. + """DestroyController destroys the controller. If the args specify the destruction of the models, this method will attempt to do so. Otherwise, if the controller has any non-empty, @@ -1014,33 +997,25 @@ async def DestroyController( """ if destroy_models is not None and not isinstance(destroy_models, bool): raise Exception( - "Expected destroy_models to be a bool, received: {}".format( - type(destroy_models) - ) + f"Expected destroy_models to be a bool, received: {type(destroy_models)}" ) if destroy_storage is not None and not isinstance(destroy_storage, bool): raise Exception( - "Expected destroy_storage to be a bool, received: {}".format( - type(destroy_storage) - ) + f"Expected destroy_storage to be a bool, received: {type(destroy_storage)}" ) if force is not None and not isinstance(force, bool): - raise Exception( - "Expected force to be a bool, received: {}".format(type(force)) - ) + raise Exception(f"Expected force to be a bool, received: {type(force)}") if max_wait is not None and not isinstance(max_wait, int): raise Exception( - "Expected max_wait to be a int, received: {}".format(type(max_wait)) + f"Expected max_wait to be a int, received: {type(max_wait)}" ) if model_timeout is not None and not isinstance(model_timeout, int): raise Exception( - "Expected model_timeout to be a int, received: {}".format( - type(model_timeout) - ) + f"Expected model_timeout to be a int, received: {type(model_timeout)}" ) # map input types to rpc msg @@ -1058,13 +1033,10 @@ async def DestroyController( @ReturnMapping(CloudSpecResult) async def GetCloudSpec(self): - """ - GetCloudSpec constructs the CloudSpec for a validated and authorized model. - + """GetCloudSpec constructs the CloudSpec for a validated and authorized model. Returns -> CloudSpecResult """ - # map input types to rpc msg _params = dict() msg = dict( @@ -1076,8 +1048,7 @@ async def GetCloudSpec(self): @ReturnMapping(UserAccessResults) async def GetControllerAccess(self, entities=None): - """ - GetControllerAccess returns the level of access the specified users + """GetControllerAccess returns the level of access the specified users have on the controller. entities : typing.Sequence[~Entity] @@ -1085,9 +1056,7 @@ async def GetControllerAccess(self, entities=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1101,15 +1070,13 @@ async def GetControllerAccess(self, entities=None): @ReturnMapping(HostedModelConfigsResults) async def HostedModelConfigs(self): - """ - HostedModelConfigs returns all the information that the client needs in + """HostedModelConfigs returns all the information that the client needs in order to connect directly with the host model's provider and destroy it directly. Returns -> HostedModelConfigsResults """ - # map input types to rpc msg _params = dict() msg = dict( @@ -1121,8 +1088,7 @@ async def HostedModelConfigs(self): @ReturnMapping(StringResult) async def IdentityProviderURL(self): - """ - IdentityProviderURL returns the URL of the configured external identity + """IdentityProviderURL returns the URL of the configured external identity provider for this controller or an empty string if no external identity provider has been configured when the controller was bootstrapped. @@ -1132,7 +1098,6 @@ async def IdentityProviderURL(self): Returns -> StringResult """ - # map input types to rpc msg _params = dict() msg = dict( @@ -1144,17 +1109,14 @@ async def IdentityProviderURL(self): @ReturnMapping(InitiateMigrationResults) async def InitiateMigration(self, specs=None): - """ - InitiateMigration attempts to begin the migration of one or + """InitiateMigration attempts to begin the migration of one or more models to other controllers. specs : typing.Sequence[~MigrationSpec] Returns -> InitiateMigrationResults """ if specs is not None and not isinstance(specs, (bytes, str, list)): - raise Exception( - "Expected specs to be a Sequence, received: {}".format(type(specs)) - ) + raise Exception(f"Expected specs to be a Sequence, received: {type(specs)}") # map input types to rpc msg _params = dict() @@ -1167,8 +1129,7 @@ async def InitiateMigration(self, specs=None): @ReturnMapping(ModelBlockInfoList) async def ListBlockedModels(self): - """ - ListBlockedModels returns a list of all models on the controller + """ListBlockedModels returns a list of all models on the controller which have a block in place. The resulting slice is sorted by model name, then owner. Callers must be controller administrators to retrieve the list. @@ -1176,7 +1137,6 @@ async def ListBlockedModels(self): Returns -> ModelBlockInfoList """ - # map input types to rpc msg _params = dict() msg = dict( @@ -1188,17 +1148,14 @@ async def ListBlockedModels(self): @ReturnMapping(ModelStatusResults) async def ModelStatus(self, entities=None): - """ - ModelStatus returns a summary of the model. + """ModelStatus returns a summary of the model. entities : typing.Sequence[~Entity] Returns -> ModelStatusResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1210,15 +1167,14 @@ async def ModelStatus(self, entities=None): @ReturnMapping(ErrorResults) async def ModifyControllerAccess(self, changes=None): - """ - ModifyControllerAccess changes the model access granted to users. + """ModifyControllerAccess changes the model access granted to users. changes : typing.Sequence[~ModifyControllerAccess] Returns -> ErrorResults """ if changes is not None and not isinstance(changes, (bytes, str, list)): raise Exception( - "Expected changes to be a Sequence, received: {}".format(type(changes)) + f"Expected changes to be a Sequence, received: {type(changes)}" ) # map input types to rpc msg @@ -1235,13 +1191,10 @@ async def ModifyControllerAccess(self, changes=None): @ReturnMapping(StringResult) async def MongoVersion(self): - """ - MongoVersion allows the introspection of the mongo version per controller - + """MongoVersion allows the introspection of the mongo version per controller Returns -> StringResult """ - # map input types to rpc msg _params = dict() msg = dict( @@ -1253,16 +1206,13 @@ async def MongoVersion(self): @ReturnMapping(None) async def RemoveBlocks(self, all_=None): - """ - RemoveBlocks removes all the blocks in the controller. + """RemoveBlocks removes all the blocks in the controller. all_ : bool Returns -> None """ if all_ is not None and not isinstance(all_, bool): - raise Exception( - "Expected all_ to be a bool, received: {}".format(type(all_)) - ) + raise Exception(f"Expected all_ to be a bool, received: {type(all_)}") # map input types to rpc msg _params = dict() @@ -1275,15 +1225,13 @@ async def RemoveBlocks(self, all_=None): @ReturnMapping(SummaryWatcherID) async def WatchAllModelSummaries(self): - """ - WatchAllModelSummaries starts watching the summary updates from the cache. + """WatchAllModelSummaries starts watching the summary updates from the cache. This method is superuser access only, and watches all models in the controller. Returns -> SummaryWatcherID """ - # map input types to rpc msg _params = dict() msg = dict( @@ -1298,15 +1246,13 @@ async def WatchAllModelSummaries(self): @ReturnMapping(AllWatcherId) async def WatchAllModels(self): - """ - WatchAllModels starts watching events for all models in the + """WatchAllModels starts watching events for all models in the controller. The returned AllWatcherId should be used with Next on the AllModelWatcher endpoint to receive deltas. Returns -> AllWatcherId """ - # map input types to rpc msg _params = dict() msg = dict( @@ -1318,17 +1264,14 @@ async def WatchAllModels(self): @ReturnMapping(NotifyWatchResults) async def WatchCloudSpecsChanges(self, entities=None): - """ - WatchCloudSpecsChanges returns a watcher for cloud spec changes. + """WatchCloudSpecsChanges returns a watcher for cloud spec changes. entities : typing.Sequence[~Entity] Returns -> NotifyWatchResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1345,14 +1288,12 @@ async def WatchCloudSpecsChanges(self, entities=None): @ReturnMapping(SummaryWatcherID) async def WatchModelSummaries(self): - """ - WatchModelSummaries starts watching the summary updates from the cache. + """WatchModelSummaries starts watching the summary updates from the cache. Only models that the user has access to are returned. Returns -> SummaryWatcherID """ - # map input types to rpc msg _params = dict() msg = dict( diff --git a/juju/client/_client17.py b/juju/client/_client17.py index 74bf11299..c4ecc5457 100644 --- a/juju/client/_client17.py +++ b/juju/client/_client17.py @@ -1,8 +1,8 @@ # DO NOT CHANGE THIS FILE! This file is auto-generated by facade.py. # Changes will be overwritten/lost when the file is regenerated. -from juju.client.facade import Type, ReturnMapping from juju.client._definitions import * +from juju.client.facade import ReturnMapping, Type class ApplicationFacade(Type): @@ -1407,8 +1407,7 @@ class ApplicationFacade(Type): @ReturnMapping(AddRelationResults) async def AddRelation(self, endpoints=None, via_cidrs=None): - """ - AddRelation adds a relation between the specified endpoints and returns the relation info. + """AddRelation adds a relation between the specified endpoints and returns the relation info. endpoints : typing.Sequence[str] via_cidrs : typing.Sequence[str] @@ -1416,16 +1415,12 @@ async def AddRelation(self, endpoints=None, via_cidrs=None): """ if endpoints is not None and not isinstance(endpoints, (bytes, str, list)): raise Exception( - "Expected endpoints to be a Sequence, received: {}".format( - type(endpoints) - ) + f"Expected endpoints to be a Sequence, received: {type(endpoints)}" ) if via_cidrs is not None and not isinstance(via_cidrs, (bytes, str, list)): raise Exception( - "Expected via_cidrs to be a Sequence, received: {}".format( - type(via_cidrs) - ) + f"Expected via_cidrs to be a Sequence, received: {type(via_cidrs)}" ) # map input types to rpc msg @@ -1447,8 +1442,7 @@ async def AddUnits( placement=None, policy=None, ): - """ - AddUnits adds a given number of units to an application. + """AddUnits adds a given number of units to an application. application : str attach_storage : typing.Sequence[str] @@ -1459,36 +1453,28 @@ async def AddUnits( """ if application is not None and not isinstance(application, (bytes, str)): raise Exception( - "Expected application to be a str, received: {}".format( - type(application) - ) + f"Expected application to be a str, received: {type(application)}" ) if attach_storage is not None and not isinstance( attach_storage, (bytes, str, list) ): raise Exception( - "Expected attach_storage to be a Sequence, received: {}".format( - type(attach_storage) - ) + f"Expected attach_storage to be a Sequence, received: {type(attach_storage)}" ) if num_units is not None and not isinstance(num_units, int): raise Exception( - "Expected num_units to be a int, received: {}".format(type(num_units)) + f"Expected num_units to be a int, received: {type(num_units)}" ) if placement is not None and not isinstance(placement, (bytes, str, list)): raise Exception( - "Expected placement to be a Sequence, received: {}".format( - type(placement) - ) + f"Expected placement to be a Sequence, received: {type(placement)}" ) if policy is not None and not isinstance(policy, (bytes, str)): - raise Exception( - "Expected policy to be a str, received: {}".format(type(policy)) - ) + raise Exception(f"Expected policy to be a str, received: {type(policy)}") # map input types to rpc msg _params = dict() @@ -1503,17 +1489,14 @@ async def AddUnits( @ReturnMapping(ApplicationInfoResults) async def ApplicationsInfo(self, entities=None): - """ - ApplicationsInfo returns applications information. + """ApplicationsInfo returns applications information. entities : typing.Sequence[~Entity] Returns -> ApplicationInfoResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1527,17 +1510,14 @@ async def ApplicationsInfo(self, entities=None): @ReturnMapping(ApplicationGetConfigResults) async def CharmConfig(self, args=None): - """ - CharmConfig returns charm config for the input list of applications and + """CharmConfig returns charm config for the input list of applications and model generations. args : typing.Sequence[~ApplicationGet] Returns -> ApplicationGetConfigResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -1550,17 +1530,14 @@ async def CharmConfig(self, args=None): @ReturnMapping(ApplicationCharmRelationsResults) async def CharmRelations(self, application=None): - """ - CharmRelations implements the server side of Application.CharmRelations. + """CharmRelations implements the server side of Application.CharmRelations. application : str Returns -> ApplicationCharmRelationsResults """ if application is not None and not isinstance(application, (bytes, str)): raise Exception( - "Expected application to be a str, received: {}".format( - type(application) - ) + f"Expected application to be a str, received: {type(application)}" ) # map input types to rpc msg @@ -1574,17 +1551,14 @@ async def CharmRelations(self, application=None): @ReturnMapping(ErrorResults) async def Consume(self, args=None): - """ - Consume adds remote applications to the model without creating any + """Consume adds remote applications to the model without creating any relations. args : typing.Sequence[~ConsumeApplicationArg] Returns -> ErrorResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -1595,8 +1569,7 @@ async def Consume(self, args=None): @ReturnMapping(ErrorResults) async def Deploy(self, applications=None): - """ - Deploy fetches the charms from the charm store and deploys them + """Deploy fetches the charms from the charm store and deploys them using the specified placement directives. applications : typing.Sequence[~ApplicationDeploy] @@ -1606,9 +1579,7 @@ async def Deploy(self, applications=None): applications, (bytes, str, list) ): raise Exception( - "Expected applications to be a Sequence, received: {}".format( - type(applications) - ) + f"Expected applications to be a Sequence, received: {type(applications)}" ) # map input types to rpc msg @@ -1620,8 +1591,7 @@ async def Deploy(self, applications=None): @ReturnMapping(DestroyApplicationResults) async def DestroyApplication(self, applications=None): - """ - DestroyApplication removes a given set of applications. + """DestroyApplication removes a given set of applications. applications : typing.Sequence[~DestroyApplicationParams] Returns -> DestroyApplicationResults @@ -1630,9 +1600,7 @@ async def DestroyApplication(self, applications=None): applications, (bytes, str, list) ): raise Exception( - "Expected applications to be a Sequence, received: {}".format( - type(applications) - ) + f"Expected applications to be a Sequence, received: {type(applications)}" ) # map input types to rpc msg @@ -1646,8 +1614,7 @@ async def DestroyApplication(self, applications=None): @ReturnMapping(ErrorResults) async def DestroyConsumedApplications(self, applications=None): - """ - DestroyConsumedApplications removes a given set of consumed (remote) applications. + """DestroyConsumedApplications removes a given set of consumed (remote) applications. applications : typing.Sequence[~DestroyConsumedApplicationParams] Returns -> ErrorResults @@ -1656,9 +1623,7 @@ async def DestroyConsumedApplications(self, applications=None): applications, (bytes, str, list) ): raise Exception( - "Expected applications to be a Sequence, received: {}".format( - type(applications) - ) + f"Expected applications to be a Sequence, received: {type(applications)}" ) # map input types to rpc msg @@ -1677,8 +1642,7 @@ async def DestroyConsumedApplications(self, applications=None): async def DestroyRelation( self, endpoints=None, force=None, max_wait=None, relation_id=None ): - """ - DestroyRelation removes the relation between the + """DestroyRelation removes the relation between the specified endpoints or an id. endpoints : typing.Sequence[str] @@ -1689,26 +1653,20 @@ async def DestroyRelation( """ if endpoints is not None and not isinstance(endpoints, (bytes, str, list)): raise Exception( - "Expected endpoints to be a Sequence, received: {}".format( - type(endpoints) - ) + f"Expected endpoints to be a Sequence, received: {type(endpoints)}" ) if force is not None and not isinstance(force, bool): - raise Exception( - "Expected force to be a bool, received: {}".format(type(force)) - ) + raise Exception(f"Expected force to be a bool, received: {type(force)}") if max_wait is not None and not isinstance(max_wait, int): raise Exception( - "Expected max_wait to be a int, received: {}".format(type(max_wait)) + f"Expected max_wait to be a int, received: {type(max_wait)}" ) if relation_id is not None and not isinstance(relation_id, int): raise Exception( - "Expected relation_id to be a int, received: {}".format( - type(relation_id) - ) + f"Expected relation_id to be a int, received: {type(relation_id)}" ) # map input types to rpc msg @@ -1725,16 +1683,13 @@ async def DestroyRelation( @ReturnMapping(DestroyUnitResults) async def DestroyUnit(self, units=None): - """ - DestroyUnit removes a given set of application units. + """DestroyUnit removes a given set of application units. units : typing.Sequence[~DestroyUnitParams] Returns -> DestroyUnitResults """ if units is not None and not isinstance(units, (bytes, str, list)): - raise Exception( - "Expected units to be a Sequence, received: {}".format(type(units)) - ) + raise Exception(f"Expected units to be a Sequence, received: {type(units)}") # map input types to rpc msg _params = dict() @@ -1747,8 +1702,7 @@ async def DestroyUnit(self, units=None): @ReturnMapping(None) async def Expose(self, application=None, exposed_endpoints=None): - """ - Expose changes the juju-managed firewall to expose any ports that + """Expose changes the juju-managed firewall to expose any ports that were also explicitly marked by units as open. application : str @@ -1757,16 +1711,12 @@ async def Expose(self, application=None, exposed_endpoints=None): """ if application is not None and not isinstance(application, (bytes, str)): raise Exception( - "Expected application to be a str, received: {}".format( - type(application) - ) + f"Expected application to be a str, received: {type(application)}" ) if exposed_endpoints is not None and not isinstance(exposed_endpoints, dict): raise Exception( - "Expected exposed_endpoints to be a Mapping, received: {}".format( - type(exposed_endpoints) - ) + f"Expected exposed_endpoints to be a Mapping, received: {type(exposed_endpoints)}" ) # map input types to rpc msg @@ -1779,8 +1729,7 @@ async def Expose(self, application=None, exposed_endpoints=None): @ReturnMapping(ApplicationGetResults) async def Get(self, application=None, branch=None): - """ - Get returns the charm configuration for an application. + """Get returns the charm configuration for an application. application : str branch : str @@ -1788,15 +1737,11 @@ async def Get(self, application=None, branch=None): """ if application is not None and not isinstance(application, (bytes, str)): raise Exception( - "Expected application to be a str, received: {}".format( - type(application) - ) + f"Expected application to be a str, received: {type(application)}" ) if branch is not None and not isinstance(branch, (bytes, str)): - raise Exception( - "Expected branch to be a str, received: {}".format(type(branch)) - ) + raise Exception(f"Expected branch to be a str, received: {type(branch)}") # map input types to rpc msg _params = dict() @@ -1808,8 +1753,7 @@ async def Get(self, application=None, branch=None): @ReturnMapping(CharmURLOriginResult) async def GetCharmURLOrigin(self, application=None, branch=None): - """ - GetCharmURLOrigin returns the charm URL and charm origin the given + """GetCharmURLOrigin returns the charm URL and charm origin the given application is running at present. application : str @@ -1818,15 +1762,11 @@ async def GetCharmURLOrigin(self, application=None, branch=None): """ if application is not None and not isinstance(application, (bytes, str)): raise Exception( - "Expected application to be a str, received: {}".format( - type(application) - ) + f"Expected application to be a str, received: {type(application)}" ) if branch is not None and not isinstance(branch, (bytes, str)): - raise Exception( - "Expected branch to be a str, received: {}".format(type(branch)) - ) + raise Exception(f"Expected branch to be a str, received: {type(branch)}") # map input types to rpc msg _params = dict() @@ -1840,17 +1780,14 @@ async def GetCharmURLOrigin(self, application=None, branch=None): @ReturnMapping(ApplicationGetConfigResults) async def GetConfig(self, entities=None): - """ - GetConfig returns the charm config for each of the input applications. + """GetConfig returns the charm config for each of the input applications. entities : typing.Sequence[~Entity] Returns -> ApplicationGetConfigResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1862,17 +1799,14 @@ async def GetConfig(self, entities=None): @ReturnMapping(ApplicationGetConstraintsResults) async def GetConstraints(self, entities=None): - """ - GetConstraints returns the constraints for a given application. + """GetConstraints returns the constraints for a given application. entities : typing.Sequence[~Entity] Returns -> ApplicationGetConstraintsResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1886,14 +1820,13 @@ async def GetConstraints(self, entities=None): @ReturnMapping(StringResult) async def Leader(self, tag=None): - """ - Leader returns the unit name of the leader for the given application. + """Leader returns the unit name of the leader for the given application. tag : str Returns -> StringResult """ if tag is not None and not isinstance(tag, (bytes, str)): - raise Exception("Expected tag to be a str, received: {}".format(type(tag))) + raise Exception(f"Expected tag to be a str, received: {type(tag)}") # map input types to rpc msg _params = dict() @@ -1904,17 +1837,14 @@ async def Leader(self, tag=None): @ReturnMapping(ErrorResults) async def MergeBindings(self, args=None): - """ - MergeBindings merges operator-defined bindings with the current bindings for + """MergeBindings merges operator-defined bindings with the current bindings for one or more applications. args : typing.Sequence[~ApplicationMergeBindings] Returns -> ErrorResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -1927,8 +1857,7 @@ async def MergeBindings(self, args=None): @ReturnMapping(ErrorResults) async def ResolveUnitErrors(self, all_=None, retry=None, tags=None): - """ - ResolveUnitErrors marks errors on the specified units as resolved. + """ResolveUnitErrors marks errors on the specified units as resolved. all_ : bool retry : bool @@ -1936,19 +1865,13 @@ async def ResolveUnitErrors(self, all_=None, retry=None, tags=None): Returns -> ErrorResults """ if all_ is not None and not isinstance(all_, bool): - raise Exception( - "Expected all_ to be a bool, received: {}".format(type(all_)) - ) + raise Exception(f"Expected all_ to be a bool, received: {type(all_)}") if retry is not None and not isinstance(retry, bool): - raise Exception( - "Expected retry to be a bool, received: {}".format(type(retry)) - ) + raise Exception(f"Expected retry to be a bool, received: {type(retry)}") if tags is not None and not isinstance(tags, (dict, Entities)): - raise Exception( - "Expected tags to be a Entities, received: {}".format(type(tags)) - ) + raise Exception(f"Expected tags to be a Entities, received: {type(tags)}") # map input types to rpc msg _params = dict() @@ -1963,8 +1886,7 @@ async def ResolveUnitErrors(self, all_=None, retry=None, tags=None): @ReturnMapping(ScaleApplicationResults) async def ScaleApplications(self, applications=None): - """ - ScaleApplications scales the specified application to the requested number of units. + """ScaleApplications scales the specified application to the requested number of units. applications : typing.Sequence[~ScaleApplicationParams] Returns -> ScaleApplicationResults @@ -1973,9 +1895,7 @@ async def ScaleApplications(self, applications=None): applications, (bytes, str, list) ): raise Exception( - "Expected applications to be a Sequence, received: {}".format( - type(applications) - ) + f"Expected applications to be a Sequence, received: {type(applications)}" ) # map input types to rpc msg @@ -2004,8 +1924,7 @@ async def SetCharm( resource_ids=None, storage_constraints=None, ): - """ - SetCharm sets the charm for a given for the application. + """SetCharm sets the charm for a given for the application. application : str channel : str @@ -2024,91 +1943,69 @@ async def SetCharm( """ if application is not None and not isinstance(application, (bytes, str)): raise Exception( - "Expected application to be a str, received: {}".format( - type(application) - ) + f"Expected application to be a str, received: {type(application)}" ) if channel is not None and not isinstance(channel, (bytes, str)): - raise Exception( - "Expected channel to be a str, received: {}".format(type(channel)) - ) + raise Exception(f"Expected channel to be a str, received: {type(channel)}") if charm_origin is not None and not isinstance( charm_origin, (dict, CharmOrigin) ): raise Exception( - "Expected charm_origin to be a CharmOrigin, received: {}".format( - type(charm_origin) - ) + f"Expected charm_origin to be a CharmOrigin, received: {type(charm_origin)}" ) if charm_url is not None and not isinstance(charm_url, (bytes, str)): raise Exception( - "Expected charm_url to be a str, received: {}".format(type(charm_url)) + f"Expected charm_url to be a str, received: {type(charm_url)}" ) if config_settings is not None and not isinstance(config_settings, dict): raise Exception( - "Expected config_settings to be a Mapping, received: {}".format( - type(config_settings) - ) + f"Expected config_settings to be a Mapping, received: {type(config_settings)}" ) if config_settings_yaml is not None and not isinstance( config_settings_yaml, (bytes, str) ): raise Exception( - "Expected config_settings_yaml to be a str, received: {}".format( - type(config_settings_yaml) - ) + f"Expected config_settings_yaml to be a str, received: {type(config_settings_yaml)}" ) if endpoint_bindings is not None and not isinstance(endpoint_bindings, dict): raise Exception( - "Expected endpoint_bindings to be a Mapping, received: {}".format( - type(endpoint_bindings) - ) + f"Expected endpoint_bindings to be a Mapping, received: {type(endpoint_bindings)}" ) if force is not None and not isinstance(force, bool): - raise Exception( - "Expected force to be a bool, received: {}".format(type(force)) - ) + raise Exception(f"Expected force to be a bool, received: {type(force)}") if force_base is not None and not isinstance(force_base, bool): raise Exception( - "Expected force_base to be a bool, received: {}".format( - type(force_base) - ) + f"Expected force_base to be a bool, received: {type(force_base)}" ) if force_units is not None and not isinstance(force_units, bool): raise Exception( - "Expected force_units to be a bool, received: {}".format( - type(force_units) - ) + f"Expected force_units to be a bool, received: {type(force_units)}" ) if generation is not None and not isinstance(generation, (bytes, str)): raise Exception( - "Expected generation to be a str, received: {}".format(type(generation)) + f"Expected generation to be a str, received: {type(generation)}" ) if resource_ids is not None and not isinstance(resource_ids, dict): raise Exception( - "Expected resource_ids to be a Mapping, received: {}".format( - type(resource_ids) - ) + f"Expected resource_ids to be a Mapping, received: {type(resource_ids)}" ) if storage_constraints is not None and not isinstance( storage_constraints, dict ): raise Exception( - "Expected storage_constraints to be a Mapping, received: {}".format( - type(storage_constraints) - ) + f"Expected storage_constraints to be a Mapping, received: {type(storage_constraints)}" ) # map input types to rpc msg @@ -2132,8 +2029,7 @@ async def SetCharm( @ReturnMapping(ErrorResults) async def SetConfigs(self, args=None): - """ - SetConfigs implements the server side of Application.SetConfig. Both + """SetConfigs implements the server side of Application.SetConfig. Both application and charm config are set. It does not unset values in Config map that are set to an empty string. Unset should be used for that. @@ -2141,9 +2037,7 @@ async def SetConfigs(self, args=None): Returns -> ErrorResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -2154,8 +2048,7 @@ async def SetConfigs(self, args=None): @ReturnMapping(None) async def SetConstraints(self, application=None, constraints=None): - """ - SetConstraints sets the constraints for a given application. + """SetConstraints sets the constraints for a given application. application : str constraints : Value @@ -2163,16 +2056,12 @@ async def SetConstraints(self, application=None, constraints=None): """ if application is not None and not isinstance(application, (bytes, str)): raise Exception( - "Expected application to be a str, received: {}".format( - type(application) - ) + f"Expected application to be a str, received: {type(application)}" ) if constraints is not None and not isinstance(constraints, (dict, Value)): raise Exception( - "Expected constraints to be a Value, received: {}".format( - type(constraints) - ) + f"Expected constraints to be a Value, received: {type(constraints)}" ) # map input types to rpc msg @@ -2187,16 +2076,13 @@ async def SetConstraints(self, application=None, constraints=None): @ReturnMapping(ErrorResults) async def SetMetricCredentials(self, creds=None): - """ - SetMetricCredentials sets credentials on the application. + """SetMetricCredentials sets credentials on the application. creds : typing.Sequence[~ApplicationMetricCredential] Returns -> ErrorResults """ if creds is not None and not isinstance(creds, (bytes, str, list)): - raise Exception( - "Expected creds to be a Sequence, received: {}".format(type(creds)) - ) + raise Exception(f"Expected creds to be a Sequence, received: {type(creds)}") # map input types to rpc msg _params = dict() @@ -2212,16 +2098,13 @@ async def SetMetricCredentials(self, creds=None): @ReturnMapping(ErrorResults) async def SetRelationsSuspended(self, args=None): - """ - SetRelationsSuspended sets the suspended status of the specified relations. + """SetRelationsSuspended sets the suspended status of the specified relations. args : typing.Sequence[~RelationSuspendedArg] Returns -> ErrorResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -2237,8 +2120,7 @@ async def SetRelationsSuspended(self, args=None): @ReturnMapping(None) async def Unexpose(self, application=None, exposed_endpoints=None): - """ - Unexpose changes the juju-managed firewall to unexpose any ports that + """Unexpose changes the juju-managed firewall to unexpose any ports that were also explicitly marked by units as open. application : str @@ -2247,18 +2129,14 @@ async def Unexpose(self, application=None, exposed_endpoints=None): """ if application is not None and not isinstance(application, (bytes, str)): raise Exception( - "Expected application to be a str, received: {}".format( - type(application) - ) + f"Expected application to be a str, received: {type(application)}" ) if exposed_endpoints is not None and not isinstance( exposed_endpoints, (bytes, str, list) ): raise Exception( - "Expected exposed_endpoints to be a Sequence, received: {}".format( - type(exposed_endpoints) - ) + f"Expected exposed_endpoints to be a Sequence, received: {type(exposed_endpoints)}" ) # map input types to rpc msg @@ -2271,8 +2149,7 @@ async def Unexpose(self, application=None, exposed_endpoints=None): @ReturnMapping(UnitInfoResults) async def UnitsInfo(self, entities=None): - """ - UnitsInfo returns unit information for the given entities (units or + """UnitsInfo returns unit information for the given entities (units or applications). entities : typing.Sequence[~Entity] @@ -2280,9 +2157,7 @@ async def UnitsInfo(self, entities=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -2294,16 +2169,13 @@ async def UnitsInfo(self, entities=None): @ReturnMapping(ErrorResults) async def UnsetApplicationsConfig(self, args=None): - """ - UnsetApplicationsConfig implements the server side of Application.UnsetApplicationsConfig. + """UnsetApplicationsConfig implements the server side of Application.UnsetApplicationsConfig. args : typing.Sequence[~ApplicationUnset] Returns -> ErrorResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -2319,17 +2191,14 @@ async def UnsetApplicationsConfig(self, args=None): @ReturnMapping(ErrorResults) async def UpdateApplicationBase(self, args=None): - """ - UpdateApplicationBase updates the application base. + """UpdateApplicationBase updates the application base. Base for subordinates is updated too. args : typing.Sequence[~UpdateChannelArg] Returns -> ErrorResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() diff --git a/juju/client/_client19.py b/juju/client/_client19.py index f8c7fb849..f5e3535a6 100644 --- a/juju/client/_client19.py +++ b/juju/client/_client19.py @@ -1,8 +1,8 @@ # DO NOT CHANGE THIS FILE! This file is auto-generated by facade.py. # Changes will be overwritten/lost when the file is regenerated. -from juju.client.facade import Type, ReturnMapping from juju.client._definitions import * +from juju.client.facade import ReturnMapping, Type class ApplicationFacade(Type): @@ -1556,8 +1556,7 @@ class ApplicationFacade(Type): @ReturnMapping(AddRelationResults) async def AddRelation(self, endpoints=None, via_cidrs=None): - """ - AddRelation adds a relation between the specified endpoints and returns the relation info. + """AddRelation adds a relation between the specified endpoints and returns the relation info. endpoints : typing.Sequence[str] via_cidrs : typing.Sequence[str] @@ -1565,16 +1564,12 @@ async def AddRelation(self, endpoints=None, via_cidrs=None): """ if endpoints is not None and not isinstance(endpoints, (bytes, str, list)): raise Exception( - "Expected endpoints to be a Sequence, received: {}".format( - type(endpoints) - ) + f"Expected endpoints to be a Sequence, received: {type(endpoints)}" ) if via_cidrs is not None and not isinstance(via_cidrs, (bytes, str, list)): raise Exception( - "Expected via_cidrs to be a Sequence, received: {}".format( - type(via_cidrs) - ) + f"Expected via_cidrs to be a Sequence, received: {type(via_cidrs)}" ) # map input types to rpc msg @@ -1596,8 +1591,7 @@ async def AddUnits( placement=None, policy=None, ): - """ - AddUnits adds a given number of units to an application. + """AddUnits adds a given number of units to an application. application : str attach_storage : typing.Sequence[str] @@ -1608,36 +1602,28 @@ async def AddUnits( """ if application is not None and not isinstance(application, (bytes, str)): raise Exception( - "Expected application to be a str, received: {}".format( - type(application) - ) + f"Expected application to be a str, received: {type(application)}" ) if attach_storage is not None and not isinstance( attach_storage, (bytes, str, list) ): raise Exception( - "Expected attach_storage to be a Sequence, received: {}".format( - type(attach_storage) - ) + f"Expected attach_storage to be a Sequence, received: {type(attach_storage)}" ) if num_units is not None and not isinstance(num_units, int): raise Exception( - "Expected num_units to be a int, received: {}".format(type(num_units)) + f"Expected num_units to be a int, received: {type(num_units)}" ) if placement is not None and not isinstance(placement, (bytes, str, list)): raise Exception( - "Expected placement to be a Sequence, received: {}".format( - type(placement) - ) + f"Expected placement to be a Sequence, received: {type(placement)}" ) if policy is not None and not isinstance(policy, (bytes, str)): - raise Exception( - "Expected policy to be a str, received: {}".format(type(policy)) - ) + raise Exception(f"Expected policy to be a str, received: {type(policy)}") # map input types to rpc msg _params = dict() @@ -1652,17 +1638,14 @@ async def AddUnits( @ReturnMapping(ApplicationInfoResults) async def ApplicationsInfo(self, entities=None): - """ - ApplicationsInfo returns applications information. + """ApplicationsInfo returns applications information. entities : typing.Sequence[~Entity] Returns -> ApplicationInfoResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1676,17 +1659,14 @@ async def ApplicationsInfo(self, entities=None): @ReturnMapping(ApplicationGetConfigResults) async def CharmConfig(self, args=None): - """ - CharmConfig returns charm config for the input list of applications and + """CharmConfig returns charm config for the input list of applications and model generations. args : typing.Sequence[~ApplicationGet] Returns -> ApplicationGetConfigResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -1699,17 +1679,14 @@ async def CharmConfig(self, args=None): @ReturnMapping(ApplicationCharmRelationsResults) async def CharmRelations(self, application=None): - """ - CharmRelations implements the server side of Application.CharmRelations. + """CharmRelations implements the server side of Application.CharmRelations. application : str Returns -> ApplicationCharmRelationsResults """ if application is not None and not isinstance(application, (bytes, str)): raise Exception( - "Expected application to be a str, received: {}".format( - type(application) - ) + f"Expected application to be a str, received: {type(application)}" ) # map input types to rpc msg @@ -1723,17 +1700,14 @@ async def CharmRelations(self, application=None): @ReturnMapping(ErrorResults) async def Consume(self, args=None): - """ - Consume adds remote applications to the model without creating any + """Consume adds remote applications to the model without creating any relations. args : typing.Sequence[~ConsumeApplicationArg] Returns -> ErrorResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -1744,8 +1718,7 @@ async def Consume(self, args=None): @ReturnMapping(ErrorResults) async def Deploy(self, applications=None): - """ - Deploy fetches the charms from the charm store and deploys them + """Deploy fetches the charms from the charm store and deploys them using the specified placement directives. applications : typing.Sequence[~ApplicationDeploy] @@ -1755,9 +1728,7 @@ async def Deploy(self, applications=None): applications, (bytes, str, list) ): raise Exception( - "Expected applications to be a Sequence, received: {}".format( - type(applications) - ) + f"Expected applications to be a Sequence, received: {type(applications)}" ) # map input types to rpc msg @@ -1769,8 +1740,7 @@ async def Deploy(self, applications=None): @ReturnMapping(DeployFromRepositoryResults) async def DeployFromRepository(self, args=None): - """ - DeployFromRepository is a one-stop deployment method for repository + """DeployFromRepository is a one-stop deployment method for repository charms. Only a charm name is required to deploy. If argument validation fails, a list of all errors found in validation will be returned. If a local resource is provided, details required for uploading the validated @@ -1780,9 +1750,7 @@ async def DeployFromRepository(self, args=None): Returns -> DeployFromRepositoryResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -1798,8 +1766,7 @@ async def DeployFromRepository(self, args=None): @ReturnMapping(DestroyApplicationResults) async def DestroyApplication(self, applications=None): - """ - DestroyApplication removes a given set of applications. + """DestroyApplication removes a given set of applications. applications : typing.Sequence[~DestroyApplicationParams] Returns -> DestroyApplicationResults @@ -1808,9 +1775,7 @@ async def DestroyApplication(self, applications=None): applications, (bytes, str, list) ): raise Exception( - "Expected applications to be a Sequence, received: {}".format( - type(applications) - ) + f"Expected applications to be a Sequence, received: {type(applications)}" ) # map input types to rpc msg @@ -1824,8 +1789,7 @@ async def DestroyApplication(self, applications=None): @ReturnMapping(ErrorResults) async def DestroyConsumedApplications(self, applications=None): - """ - DestroyConsumedApplications removes a given set of consumed (remote) applications. + """DestroyConsumedApplications removes a given set of consumed (remote) applications. applications : typing.Sequence[~DestroyConsumedApplicationParams] Returns -> ErrorResults @@ -1834,9 +1798,7 @@ async def DestroyConsumedApplications(self, applications=None): applications, (bytes, str, list) ): raise Exception( - "Expected applications to be a Sequence, received: {}".format( - type(applications) - ) + f"Expected applications to be a Sequence, received: {type(applications)}" ) # map input types to rpc msg @@ -1855,8 +1817,7 @@ async def DestroyConsumedApplications(self, applications=None): async def DestroyRelation( self, endpoints=None, force=None, max_wait=None, relation_id=None ): - """ - DestroyRelation removes the relation between the + """DestroyRelation removes the relation between the specified endpoints or an id. endpoints : typing.Sequence[str] @@ -1867,26 +1828,20 @@ async def DestroyRelation( """ if endpoints is not None and not isinstance(endpoints, (bytes, str, list)): raise Exception( - "Expected endpoints to be a Sequence, received: {}".format( - type(endpoints) - ) + f"Expected endpoints to be a Sequence, received: {type(endpoints)}" ) if force is not None and not isinstance(force, bool): - raise Exception( - "Expected force to be a bool, received: {}".format(type(force)) - ) + raise Exception(f"Expected force to be a bool, received: {type(force)}") if max_wait is not None and not isinstance(max_wait, int): raise Exception( - "Expected max_wait to be a int, received: {}".format(type(max_wait)) + f"Expected max_wait to be a int, received: {type(max_wait)}" ) if relation_id is not None and not isinstance(relation_id, int): raise Exception( - "Expected relation_id to be a int, received: {}".format( - type(relation_id) - ) + f"Expected relation_id to be a int, received: {type(relation_id)}" ) # map input types to rpc msg @@ -1903,16 +1858,13 @@ async def DestroyRelation( @ReturnMapping(DestroyUnitResults) async def DestroyUnit(self, units=None): - """ - DestroyUnit removes a given set of application units. + """DestroyUnit removes a given set of application units. units : typing.Sequence[~DestroyUnitParams] Returns -> DestroyUnitResults """ if units is not None and not isinstance(units, (bytes, str, list)): - raise Exception( - "Expected units to be a Sequence, received: {}".format(type(units)) - ) + raise Exception(f"Expected units to be a Sequence, received: {type(units)}") # map input types to rpc msg _params = dict() @@ -1925,8 +1877,7 @@ async def DestroyUnit(self, units=None): @ReturnMapping(None) async def Expose(self, application=None, exposed_endpoints=None): - """ - Expose changes the juju-managed firewall to expose any ports that + """Expose changes the juju-managed firewall to expose any ports that were also explicitly marked by units as open. application : str @@ -1935,16 +1886,12 @@ async def Expose(self, application=None, exposed_endpoints=None): """ if application is not None and not isinstance(application, (bytes, str)): raise Exception( - "Expected application to be a str, received: {}".format( - type(application) - ) + f"Expected application to be a str, received: {type(application)}" ) if exposed_endpoints is not None and not isinstance(exposed_endpoints, dict): raise Exception( - "Expected exposed_endpoints to be a Mapping, received: {}".format( - type(exposed_endpoints) - ) + f"Expected exposed_endpoints to be a Mapping, received: {type(exposed_endpoints)}" ) # map input types to rpc msg @@ -1957,8 +1904,7 @@ async def Expose(self, application=None, exposed_endpoints=None): @ReturnMapping(ApplicationGetResults) async def Get(self, application=None, branch=None): - """ - Get returns the charm configuration for an application. + """Get returns the charm configuration for an application. application : str branch : str @@ -1966,15 +1912,11 @@ async def Get(self, application=None, branch=None): """ if application is not None and not isinstance(application, (bytes, str)): raise Exception( - "Expected application to be a str, received: {}".format( - type(application) - ) + f"Expected application to be a str, received: {type(application)}" ) if branch is not None and not isinstance(branch, (bytes, str)): - raise Exception( - "Expected branch to be a str, received: {}".format(type(branch)) - ) + raise Exception(f"Expected branch to be a str, received: {type(branch)}") # map input types to rpc msg _params = dict() @@ -1986,8 +1928,7 @@ async def Get(self, application=None, branch=None): @ReturnMapping(CharmURLOriginResult) async def GetCharmURLOrigin(self, application=None, branch=None): - """ - GetCharmURLOrigin returns the charm URL and charm origin the given + """GetCharmURLOrigin returns the charm URL and charm origin the given application is running at present. application : str @@ -1996,15 +1937,11 @@ async def GetCharmURLOrigin(self, application=None, branch=None): """ if application is not None and not isinstance(application, (bytes, str)): raise Exception( - "Expected application to be a str, received: {}".format( - type(application) - ) + f"Expected application to be a str, received: {type(application)}" ) if branch is not None and not isinstance(branch, (bytes, str)): - raise Exception( - "Expected branch to be a str, received: {}".format(type(branch)) - ) + raise Exception(f"Expected branch to be a str, received: {type(branch)}") # map input types to rpc msg _params = dict() @@ -2018,17 +1955,14 @@ async def GetCharmURLOrigin(self, application=None, branch=None): @ReturnMapping(ApplicationGetConfigResults) async def GetConfig(self, entities=None): - """ - GetConfig returns the charm config for each of the input applications. + """GetConfig returns the charm config for each of the input applications. entities : typing.Sequence[~Entity] Returns -> ApplicationGetConfigResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -2040,17 +1974,14 @@ async def GetConfig(self, entities=None): @ReturnMapping(ApplicationGetConstraintsResults) async def GetConstraints(self, entities=None): - """ - GetConstraints returns the constraints for a given application. + """GetConstraints returns the constraints for a given application. entities : typing.Sequence[~Entity] Returns -> ApplicationGetConstraintsResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -2064,14 +1995,13 @@ async def GetConstraints(self, entities=None): @ReturnMapping(StringResult) async def Leader(self, tag=None): - """ - Leader returns the unit name of the leader for the given application. + """Leader returns the unit name of the leader for the given application. tag : str Returns -> StringResult """ if tag is not None and not isinstance(tag, (bytes, str)): - raise Exception("Expected tag to be a str, received: {}".format(type(tag))) + raise Exception(f"Expected tag to be a str, received: {type(tag)}") # map input types to rpc msg _params = dict() @@ -2082,17 +2012,14 @@ async def Leader(self, tag=None): @ReturnMapping(ErrorResults) async def MergeBindings(self, args=None): - """ - MergeBindings merges operator-defined bindings with the current bindings for + """MergeBindings merges operator-defined bindings with the current bindings for one or more applications. args : typing.Sequence[~ApplicationMergeBindings] Returns -> ErrorResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -2105,8 +2032,7 @@ async def MergeBindings(self, args=None): @ReturnMapping(ErrorResults) async def ResolveUnitErrors(self, all_=None, retry=None, tags=None): - """ - ResolveUnitErrors marks errors on the specified units as resolved. + """ResolveUnitErrors marks errors on the specified units as resolved. all_ : bool retry : bool @@ -2114,19 +2040,13 @@ async def ResolveUnitErrors(self, all_=None, retry=None, tags=None): Returns -> ErrorResults """ if all_ is not None and not isinstance(all_, bool): - raise Exception( - "Expected all_ to be a bool, received: {}".format(type(all_)) - ) + raise Exception(f"Expected all_ to be a bool, received: {type(all_)}") if retry is not None and not isinstance(retry, bool): - raise Exception( - "Expected retry to be a bool, received: {}".format(type(retry)) - ) + raise Exception(f"Expected retry to be a bool, received: {type(retry)}") if tags is not None and not isinstance(tags, (dict, Entities)): - raise Exception( - "Expected tags to be a Entities, received: {}".format(type(tags)) - ) + raise Exception(f"Expected tags to be a Entities, received: {type(tags)}") # map input types to rpc msg _params = dict() @@ -2141,8 +2061,7 @@ async def ResolveUnitErrors(self, all_=None, retry=None, tags=None): @ReturnMapping(ScaleApplicationResults) async def ScaleApplications(self, applications=None): - """ - ScaleApplications scales the specified application to the requested number of units. + """ScaleApplications scales the specified application to the requested number of units. applications : typing.Sequence[~ScaleApplicationParams] Returns -> ScaleApplicationResults @@ -2151,9 +2070,7 @@ async def ScaleApplications(self, applications=None): applications, (bytes, str, list) ): raise Exception( - "Expected applications to be a Sequence, received: {}".format( - type(applications) - ) + f"Expected applications to be a Sequence, received: {type(applications)}" ) # map input types to rpc msg @@ -2182,8 +2099,7 @@ async def SetCharm( resource_ids=None, storage_constraints=None, ): - """ - SetCharm sets the charm for a given for the application. + """SetCharm sets the charm for a given for the application. application : str channel : str @@ -2202,91 +2118,69 @@ async def SetCharm( """ if application is not None and not isinstance(application, (bytes, str)): raise Exception( - "Expected application to be a str, received: {}".format( - type(application) - ) + f"Expected application to be a str, received: {type(application)}" ) if channel is not None and not isinstance(channel, (bytes, str)): - raise Exception( - "Expected channel to be a str, received: {}".format(type(channel)) - ) + raise Exception(f"Expected channel to be a str, received: {type(channel)}") if charm_origin is not None and not isinstance( charm_origin, (dict, CharmOrigin) ): raise Exception( - "Expected charm_origin to be a CharmOrigin, received: {}".format( - type(charm_origin) - ) + f"Expected charm_origin to be a CharmOrigin, received: {type(charm_origin)}" ) if charm_url is not None and not isinstance(charm_url, (bytes, str)): raise Exception( - "Expected charm_url to be a str, received: {}".format(type(charm_url)) + f"Expected charm_url to be a str, received: {type(charm_url)}" ) if config_settings is not None and not isinstance(config_settings, dict): raise Exception( - "Expected config_settings to be a Mapping, received: {}".format( - type(config_settings) - ) + f"Expected config_settings to be a Mapping, received: {type(config_settings)}" ) if config_settings_yaml is not None and not isinstance( config_settings_yaml, (bytes, str) ): raise Exception( - "Expected config_settings_yaml to be a str, received: {}".format( - type(config_settings_yaml) - ) + f"Expected config_settings_yaml to be a str, received: {type(config_settings_yaml)}" ) if endpoint_bindings is not None and not isinstance(endpoint_bindings, dict): raise Exception( - "Expected endpoint_bindings to be a Mapping, received: {}".format( - type(endpoint_bindings) - ) + f"Expected endpoint_bindings to be a Mapping, received: {type(endpoint_bindings)}" ) if force is not None and not isinstance(force, bool): - raise Exception( - "Expected force to be a bool, received: {}".format(type(force)) - ) + raise Exception(f"Expected force to be a bool, received: {type(force)}") if force_base is not None and not isinstance(force_base, bool): raise Exception( - "Expected force_base to be a bool, received: {}".format( - type(force_base) - ) + f"Expected force_base to be a bool, received: {type(force_base)}" ) if force_units is not None and not isinstance(force_units, bool): raise Exception( - "Expected force_units to be a bool, received: {}".format( - type(force_units) - ) + f"Expected force_units to be a bool, received: {type(force_units)}" ) if generation is not None and not isinstance(generation, (bytes, str)): raise Exception( - "Expected generation to be a str, received: {}".format(type(generation)) + f"Expected generation to be a str, received: {type(generation)}" ) if resource_ids is not None and not isinstance(resource_ids, dict): raise Exception( - "Expected resource_ids to be a Mapping, received: {}".format( - type(resource_ids) - ) + f"Expected resource_ids to be a Mapping, received: {type(resource_ids)}" ) if storage_constraints is not None and not isinstance( storage_constraints, dict ): raise Exception( - "Expected storage_constraints to be a Mapping, received: {}".format( - type(storage_constraints) - ) + f"Expected storage_constraints to be a Mapping, received: {type(storage_constraints)}" ) # map input types to rpc msg @@ -2310,8 +2204,7 @@ async def SetCharm( @ReturnMapping(ErrorResults) async def SetConfigs(self, args=None): - """ - SetConfigs implements the server side of Application.SetConfig. Both + """SetConfigs implements the server side of Application.SetConfig. Both application and charm config are set. It does not unset values in Config map that are set to an empty string. Unset should be used for that. @@ -2319,9 +2212,7 @@ async def SetConfigs(self, args=None): Returns -> ErrorResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -2332,8 +2223,7 @@ async def SetConfigs(self, args=None): @ReturnMapping(None) async def SetConstraints(self, application=None, constraints=None): - """ - SetConstraints sets the constraints for a given application. + """SetConstraints sets the constraints for a given application. application : str constraints : Value @@ -2341,16 +2231,12 @@ async def SetConstraints(self, application=None, constraints=None): """ if application is not None and not isinstance(application, (bytes, str)): raise Exception( - "Expected application to be a str, received: {}".format( - type(application) - ) + f"Expected application to be a str, received: {type(application)}" ) if constraints is not None and not isinstance(constraints, (dict, Value)): raise Exception( - "Expected constraints to be a Value, received: {}".format( - type(constraints) - ) + f"Expected constraints to be a Value, received: {type(constraints)}" ) # map input types to rpc msg @@ -2365,8 +2251,7 @@ async def SetConstraints(self, application=None, constraints=None): @ReturnMapping(ErrorResults) async def SetMetricCredentials(self, creds=None): - """ - SetMetricCredentials sets credentials on the application. + """SetMetricCredentials sets credentials on the application. TODO (cderici) only used for metered charms in cmd MeteredDeployAPI, kept for client compatibility, remove in juju 4.0 @@ -2374,9 +2259,7 @@ async def SetMetricCredentials(self, creds=None): Returns -> ErrorResults """ if creds is not None and not isinstance(creds, (bytes, str, list)): - raise Exception( - "Expected creds to be a Sequence, received: {}".format(type(creds)) - ) + raise Exception(f"Expected creds to be a Sequence, received: {type(creds)}") # map input types to rpc msg _params = dict() @@ -2392,16 +2275,13 @@ async def SetMetricCredentials(self, creds=None): @ReturnMapping(ErrorResults) async def SetRelationsSuspended(self, args=None): - """ - SetRelationsSuspended sets the suspended status of the specified relations. + """SetRelationsSuspended sets the suspended status of the specified relations. args : typing.Sequence[~RelationSuspendedArg] Returns -> ErrorResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -2417,8 +2297,7 @@ async def SetRelationsSuspended(self, args=None): @ReturnMapping(None) async def Unexpose(self, application=None, exposed_endpoints=None): - """ - Unexpose changes the juju-managed firewall to unexpose any ports that + """Unexpose changes the juju-managed firewall to unexpose any ports that were also explicitly marked by units as open. application : str @@ -2427,18 +2306,14 @@ async def Unexpose(self, application=None, exposed_endpoints=None): """ if application is not None and not isinstance(application, (bytes, str)): raise Exception( - "Expected application to be a str, received: {}".format( - type(application) - ) + f"Expected application to be a str, received: {type(application)}" ) if exposed_endpoints is not None and not isinstance( exposed_endpoints, (bytes, str, list) ): raise Exception( - "Expected exposed_endpoints to be a Sequence, received: {}".format( - type(exposed_endpoints) - ) + f"Expected exposed_endpoints to be a Sequence, received: {type(exposed_endpoints)}" ) # map input types to rpc msg @@ -2451,8 +2326,7 @@ async def Unexpose(self, application=None, exposed_endpoints=None): @ReturnMapping(UnitInfoResults) async def UnitsInfo(self, entities=None): - """ - UnitsInfo returns unit information for the given entities (units or + """UnitsInfo returns unit information for the given entities (units or applications). entities : typing.Sequence[~Entity] @@ -2460,9 +2334,7 @@ async def UnitsInfo(self, entities=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -2474,16 +2346,13 @@ async def UnitsInfo(self, entities=None): @ReturnMapping(ErrorResults) async def UnsetApplicationsConfig(self, args=None): - """ - UnsetApplicationsConfig implements the server side of Application.UnsetApplicationsConfig. + """UnsetApplicationsConfig implements the server side of Application.UnsetApplicationsConfig. args : typing.Sequence[~ApplicationUnset] Returns -> ErrorResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -2499,17 +2368,14 @@ async def UnsetApplicationsConfig(self, args=None): @ReturnMapping(ErrorResults) async def UpdateApplicationBase(self, args=None): - """ - UpdateApplicationBase updates the application base. + """UpdateApplicationBase updates the application base. Base for subordinates is updated too. args : typing.Sequence[~UpdateChannelArg] Returns -> ErrorResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() diff --git a/juju/client/_client2.py b/juju/client/_client2.py index 7101c77d1..128446dd4 100644 --- a/juju/client/_client2.py +++ b/juju/client/_client2.py @@ -1,8 +1,8 @@ # DO NOT CHANGE THIS FILE! This file is auto-generated by facade.py. # Changes will be overwritten/lost when the file is regenerated. -from juju.client.facade import Type, ReturnMapping from juju.client._definitions import * +from juju.client.facade import ReturnMapping, Type class AnnotationsFacade(Type): @@ -135,8 +135,7 @@ class AnnotationsFacade(Type): @ReturnMapping(AnnotationsGetResults) async def Get(self, entities=None): - """ - Get returns annotations for given entities. + """Get returns annotations for given entities. If annotations cannot be retrieved for a given entity, an error is returned. Each entity is treated independently and, hence, will fail or succeed independently. @@ -145,9 +144,7 @@ async def Get(self, entities=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -159,17 +156,14 @@ async def Get(self, entities=None): @ReturnMapping(ErrorResults) async def Set(self, annotations=None): - """ - Set stores annotations for given entities + """Set stores annotations for given entities annotations : typing.Sequence[~EntityAnnotations] Returns -> ErrorResults """ if annotations is not None and not isinstance(annotations, (bytes, str, list)): raise Exception( - "Expected annotations to be a Sequence, received: {}".format( - type(annotations) - ) + f"Expected annotations to be a Sequence, received: {type(annotations)}" ) # map input types to rpc msg @@ -273,13 +267,10 @@ class BlockFacade(Type): @ReturnMapping(BlockResults) async def List(self): - """ - List implements Block.List(). - + """List implements Block.List(). Returns -> BlockResults """ - # map input types to rpc msg _params = dict() msg = dict(type="Block", request="List", version=2, params=_params) @@ -289,22 +280,17 @@ async def List(self): @ReturnMapping(ErrorResult) async def SwitchBlockOff(self, message=None, type_=None): - """ - SwitchBlockOff implements Block.SwitchBlockOff(). + """SwitchBlockOff implements Block.SwitchBlockOff(). message : str type_ : str Returns -> ErrorResult """ if message is not None and not isinstance(message, (bytes, str)): - raise Exception( - "Expected message to be a str, received: {}".format(type(message)) - ) + raise Exception(f"Expected message to be a str, received: {type(message)}") if type_ is not None and not isinstance(type_, (bytes, str)): - raise Exception( - "Expected type_ to be a str, received: {}".format(type(type_)) - ) + raise Exception(f"Expected type_ to be a str, received: {type(type_)}") # map input types to rpc msg _params = dict() @@ -316,22 +302,17 @@ async def SwitchBlockOff(self, message=None, type_=None): @ReturnMapping(ErrorResult) async def SwitchBlockOn(self, message=None, type_=None): - """ - SwitchBlockOn implements Block.SwitchBlockOn(). + """SwitchBlockOn implements Block.SwitchBlockOn(). message : str type_ : str Returns -> ErrorResult """ if message is not None and not isinstance(message, (bytes, str)): - raise Exception( - "Expected message to be a str, received: {}".format(type(message)) - ) + raise Exception(f"Expected message to be a str, received: {type(message)}") if type_ is not None and not isinstance(type_, (bytes, str)): - raise Exception( - "Expected type_ to be a str, received: {}".format(type(type_)) - ) + raise Exception(f"Expected type_ to be a str, received: {type(type_)}") # map input types to rpc msg _params = dict() @@ -453,17 +434,14 @@ class HighAvailabilityFacade(Type): @ReturnMapping(ControllersChangeResults) async def EnableHA(self, specs=None): - """ - EnableHA adds controller machines as necessary to ensure the + """EnableHA adds controller machines as necessary to ensure the controller has the number of machines specified. specs : typing.Sequence[~ControllersSpec] Returns -> ControllersChangeResults """ if specs is not None and not isinstance(specs, (bytes, str, list)): - raise Exception( - "Expected specs to be a Sequence, received: {}".format(type(specs)) - ) + raise Exception(f"Expected specs to be a Sequence, received: {type(specs)}") # map input types to rpc msg _params = dict() @@ -611,17 +589,14 @@ class MetricsDebugFacade(Type): @ReturnMapping(MetricResults) async def GetMetrics(self, entities=None): - """ - GetMetrics returns all metrics stored by the state server. + """GetMetrics returns all metrics stored by the state server. entities : typing.Sequence[~Entity] Returns -> MetricResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -633,15 +608,14 @@ async def GetMetrics(self, entities=None): @ReturnMapping(ErrorResults) async def SetMeterStatus(self, statues=None): - """ - SetMeterStatus sets meter statuses for entities. + """SetMeterStatus sets meter statuses for entities. statues : typing.Sequence[~MeterStatusParam] Returns -> ErrorResults """ if statues is not None and not isinstance(statues, (bytes, str, list)): raise Exception( - "Expected statues to be a Sequence, received: {}".format(type(statues)) + f"Expected statues to be a Sequence, received: {type(statues)}" ) # map input types to rpc msg @@ -1001,16 +975,13 @@ class SecretsFacade(Type): @ReturnMapping(StringResults) async def CreateSecrets(self, args=None): - """ - CreateSecrets creates new secrets. + """CreateSecrets creates new secrets. args : typing.Sequence[~CreateSecretArg] Returns -> StringResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -1021,8 +992,7 @@ async def CreateSecrets(self, args=None): @ReturnMapping(ErrorResults) async def GrantSecret(self, applications=None, label=None, uri=None): - """ - GrantSecret grants access to a user secret. + """GrantSecret grants access to a user secret. applications : typing.Sequence[str] label : str @@ -1033,18 +1003,14 @@ async def GrantSecret(self, applications=None, label=None, uri=None): applications, (bytes, str, list) ): raise Exception( - "Expected applications to be a Sequence, received: {}".format( - type(applications) - ) + f"Expected applications to be a Sequence, received: {type(applications)}" ) if label is not None and not isinstance(label, (bytes, str)): - raise Exception( - "Expected label to be a str, received: {}".format(type(label)) - ) + raise Exception(f"Expected label to be a str, received: {type(label)}") if uri is not None and not isinstance(uri, (bytes, str)): - raise Exception("Expected uri to be a str, received: {}".format(type(uri))) + raise Exception(f"Expected uri to be a str, received: {type(uri)}") # map input types to rpc msg _params = dict() @@ -1057,8 +1023,7 @@ async def GrantSecret(self, applications=None, label=None, uri=None): @ReturnMapping(ListSecretResults) async def ListSecrets(self, filter_=None, show_secrets=None): - """ - ListSecrets lists available secrets. + """ListSecrets lists available secrets. filter_ : SecretsFilter show_secrets : bool @@ -1066,16 +1031,12 @@ async def ListSecrets(self, filter_=None, show_secrets=None): """ if filter_ is not None and not isinstance(filter_, (dict, SecretsFilter)): raise Exception( - "Expected filter_ to be a SecretsFilter, received: {}".format( - type(filter_) - ) + f"Expected filter_ to be a SecretsFilter, received: {type(filter_)}" ) if show_secrets is not None and not isinstance(show_secrets, bool): raise Exception( - "Expected show_secrets to be a bool, received: {}".format( - type(show_secrets) - ) + f"Expected show_secrets to be a bool, received: {type(show_secrets)}" ) # map input types to rpc msg @@ -1088,16 +1049,13 @@ async def ListSecrets(self, filter_=None, show_secrets=None): @ReturnMapping(ErrorResults) async def RemoveSecrets(self, args=None): - """ - RemoveSecrets remove user secret. + """RemoveSecrets remove user secret. args : typing.Sequence[~DeleteSecretArg] Returns -> ErrorResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -1108,8 +1066,7 @@ async def RemoveSecrets(self, args=None): @ReturnMapping(ErrorResults) async def RevokeSecret(self, applications=None, label=None, uri=None): - """ - RevokeSecret revokes access to a user secret. + """RevokeSecret revokes access to a user secret. applications : typing.Sequence[str] label : str @@ -1120,18 +1077,14 @@ async def RevokeSecret(self, applications=None, label=None, uri=None): applications, (bytes, str, list) ): raise Exception( - "Expected applications to be a Sequence, received: {}".format( - type(applications) - ) + f"Expected applications to be a Sequence, received: {type(applications)}" ) if label is not None and not isinstance(label, (bytes, str)): - raise Exception( - "Expected label to be a str, received: {}".format(type(label)) - ) + raise Exception(f"Expected label to be a str, received: {type(label)}") if uri is not None and not isinstance(uri, (bytes, str)): - raise Exception("Expected uri to be a str, received: {}".format(type(uri))) + raise Exception(f"Expected uri to be a str, received: {type(uri)}") # map input types to rpc msg _params = dict() @@ -1144,16 +1097,13 @@ async def RevokeSecret(self, applications=None, label=None, uri=None): @ReturnMapping(ErrorResults) async def UpdateSecrets(self, args=None): - """ - UpdateSecrets creates new secrets. + """UpdateSecrets creates new secrets. args : typing.Sequence[~UpdateUserSecretArg] Returns -> ErrorResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() diff --git a/juju/client/_client20.py b/juju/client/_client20.py index 4df353400..9121b0710 100644 --- a/juju/client/_client20.py +++ b/juju/client/_client20.py @@ -1,8 +1,8 @@ # DO NOT CHANGE THIS FILE! This file is auto-generated by facade.py. # Changes will be overwritten/lost when the file is regenerated. -from juju.client.facade import Type, ReturnMapping from juju.client._definitions import * +from juju.client.facade import ReturnMapping, Type class ApplicationFacade(Type): @@ -1498,8 +1498,7 @@ class ApplicationFacade(Type): @ReturnMapping(AddRelationResults) async def AddRelation(self, endpoints=None, via_cidrs=None): - """ - AddRelation adds a relation between the specified endpoints and returns the relation info. + """AddRelation adds a relation between the specified endpoints and returns the relation info. endpoints : typing.Sequence[str] via_cidrs : typing.Sequence[str] @@ -1507,16 +1506,12 @@ async def AddRelation(self, endpoints=None, via_cidrs=None): """ if endpoints is not None and not isinstance(endpoints, (bytes, str, list)): raise Exception( - "Expected endpoints to be a Sequence, received: {}".format( - type(endpoints) - ) + f"Expected endpoints to be a Sequence, received: {type(endpoints)}" ) if via_cidrs is not None and not isinstance(via_cidrs, (bytes, str, list)): raise Exception( - "Expected via_cidrs to be a Sequence, received: {}".format( - type(via_cidrs) - ) + f"Expected via_cidrs to be a Sequence, received: {type(via_cidrs)}" ) # map input types to rpc msg @@ -1538,8 +1533,7 @@ async def AddUnits( placement=None, policy=None, ): - """ - AddUnits adds a given number of units to an application. + """AddUnits adds a given number of units to an application. application : str attach_storage : typing.Sequence[str] @@ -1550,36 +1544,28 @@ async def AddUnits( """ if application is not None and not isinstance(application, (bytes, str)): raise Exception( - "Expected application to be a str, received: {}".format( - type(application) - ) + f"Expected application to be a str, received: {type(application)}" ) if attach_storage is not None and not isinstance( attach_storage, (bytes, str, list) ): raise Exception( - "Expected attach_storage to be a Sequence, received: {}".format( - type(attach_storage) - ) + f"Expected attach_storage to be a Sequence, received: {type(attach_storage)}" ) if num_units is not None and not isinstance(num_units, int): raise Exception( - "Expected num_units to be a int, received: {}".format(type(num_units)) + f"Expected num_units to be a int, received: {type(num_units)}" ) if placement is not None and not isinstance(placement, (bytes, str, list)): raise Exception( - "Expected placement to be a Sequence, received: {}".format( - type(placement) - ) + f"Expected placement to be a Sequence, received: {type(placement)}" ) if policy is not None and not isinstance(policy, (bytes, str)): - raise Exception( - "Expected policy to be a str, received: {}".format(type(policy)) - ) + raise Exception(f"Expected policy to be a str, received: {type(policy)}") # map input types to rpc msg _params = dict() @@ -1594,17 +1580,14 @@ async def AddUnits( @ReturnMapping(ApplicationInfoResults) async def ApplicationsInfo(self, entities=None): - """ - ApplicationsInfo returns applications information. + """ApplicationsInfo returns applications information. entities : typing.Sequence[~Entity] Returns -> ApplicationInfoResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1618,17 +1601,14 @@ async def ApplicationsInfo(self, entities=None): @ReturnMapping(ApplicationGetConfigResults) async def CharmConfig(self, args=None): - """ - CharmConfig returns charm config for the input list of applications and + """CharmConfig returns charm config for the input list of applications and model generations. args : typing.Sequence[~ApplicationGet] Returns -> ApplicationGetConfigResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -1641,17 +1621,14 @@ async def CharmConfig(self, args=None): @ReturnMapping(ApplicationCharmRelationsResults) async def CharmRelations(self, application=None): - """ - CharmRelations implements the server side of Application.CharmRelations. + """CharmRelations implements the server side of Application.CharmRelations. application : str Returns -> ApplicationCharmRelationsResults """ if application is not None and not isinstance(application, (bytes, str)): raise Exception( - "Expected application to be a str, received: {}".format( - type(application) - ) + f"Expected application to be a str, received: {type(application)}" ) # map input types to rpc msg @@ -1665,17 +1642,14 @@ async def CharmRelations(self, application=None): @ReturnMapping(ErrorResults) async def Consume(self, args=None): - """ - Consume adds remote applications to the model without creating any + """Consume adds remote applications to the model without creating any relations. args : typing.Sequence[~ConsumeApplicationArgV5] Returns -> ErrorResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -1686,8 +1660,7 @@ async def Consume(self, args=None): @ReturnMapping(ErrorResults) async def Deploy(self, applications=None): - """ - Deploy fetches the charms from the charm store and deploys them + """Deploy fetches the charms from the charm store and deploys them using the specified placement directives. applications : typing.Sequence[~ApplicationDeploy] @@ -1697,9 +1670,7 @@ async def Deploy(self, applications=None): applications, (bytes, str, list) ): raise Exception( - "Expected applications to be a Sequence, received: {}".format( - type(applications) - ) + f"Expected applications to be a Sequence, received: {type(applications)}" ) # map input types to rpc msg @@ -1711,8 +1682,7 @@ async def Deploy(self, applications=None): @ReturnMapping(DeployFromRepositoryResults) async def DeployFromRepository(self, args=None): - """ - DeployFromRepository is a one-stop deployment method for repository + """DeployFromRepository is a one-stop deployment method for repository charms. Only a charm name is required to deploy. If argument validation fails, a list of all errors found in validation will be returned. If a local resource is provided, details required for uploading the validated @@ -1722,9 +1692,7 @@ async def DeployFromRepository(self, args=None): Returns -> DeployFromRepositoryResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -1740,8 +1708,7 @@ async def DeployFromRepository(self, args=None): @ReturnMapping(DestroyApplicationResults) async def DestroyApplication(self, applications=None): - """ - DestroyApplication removes a given set of applications. + """DestroyApplication removes a given set of applications. applications : typing.Sequence[~DestroyApplicationParams] Returns -> DestroyApplicationResults @@ -1750,9 +1717,7 @@ async def DestroyApplication(self, applications=None): applications, (bytes, str, list) ): raise Exception( - "Expected applications to be a Sequence, received: {}".format( - type(applications) - ) + f"Expected applications to be a Sequence, received: {type(applications)}" ) # map input types to rpc msg @@ -1766,8 +1731,7 @@ async def DestroyApplication(self, applications=None): @ReturnMapping(ErrorResults) async def DestroyConsumedApplications(self, applications=None): - """ - DestroyConsumedApplications removes a given set of consumed (remote) applications. + """DestroyConsumedApplications removes a given set of consumed (remote) applications. applications : typing.Sequence[~DestroyConsumedApplicationParams] Returns -> ErrorResults @@ -1776,9 +1740,7 @@ async def DestroyConsumedApplications(self, applications=None): applications, (bytes, str, list) ): raise Exception( - "Expected applications to be a Sequence, received: {}".format( - type(applications) - ) + f"Expected applications to be a Sequence, received: {type(applications)}" ) # map input types to rpc msg @@ -1797,8 +1759,7 @@ async def DestroyConsumedApplications(self, applications=None): async def DestroyRelation( self, endpoints=None, force=None, max_wait=None, relation_id=None ): - """ - DestroyRelation removes the relation between the + """DestroyRelation removes the relation between the specified endpoints or an id. endpoints : typing.Sequence[str] @@ -1809,26 +1770,20 @@ async def DestroyRelation( """ if endpoints is not None and not isinstance(endpoints, (bytes, str, list)): raise Exception( - "Expected endpoints to be a Sequence, received: {}".format( - type(endpoints) - ) + f"Expected endpoints to be a Sequence, received: {type(endpoints)}" ) if force is not None and not isinstance(force, bool): - raise Exception( - "Expected force to be a bool, received: {}".format(type(force)) - ) + raise Exception(f"Expected force to be a bool, received: {type(force)}") if max_wait is not None and not isinstance(max_wait, int): raise Exception( - "Expected max_wait to be a int, received: {}".format(type(max_wait)) + f"Expected max_wait to be a int, received: {type(max_wait)}" ) if relation_id is not None and not isinstance(relation_id, int): raise Exception( - "Expected relation_id to be a int, received: {}".format( - type(relation_id) - ) + f"Expected relation_id to be a int, received: {type(relation_id)}" ) # map input types to rpc msg @@ -1845,16 +1800,13 @@ async def DestroyRelation( @ReturnMapping(DestroyUnitResults) async def DestroyUnit(self, units=None): - """ - DestroyUnit removes a given set of application units. + """DestroyUnit removes a given set of application units. units : typing.Sequence[~DestroyUnitParams] Returns -> DestroyUnitResults """ if units is not None and not isinstance(units, (bytes, str, list)): - raise Exception( - "Expected units to be a Sequence, received: {}".format(type(units)) - ) + raise Exception(f"Expected units to be a Sequence, received: {type(units)}") # map input types to rpc msg _params = dict() @@ -1867,8 +1819,7 @@ async def DestroyUnit(self, units=None): @ReturnMapping(None) async def Expose(self, application=None, exposed_endpoints=None): - """ - Expose changes the juju-managed firewall to expose any ports that + """Expose changes the juju-managed firewall to expose any ports that were also explicitly marked by units as open. application : str @@ -1877,16 +1828,12 @@ async def Expose(self, application=None, exposed_endpoints=None): """ if application is not None and not isinstance(application, (bytes, str)): raise Exception( - "Expected application to be a str, received: {}".format( - type(application) - ) + f"Expected application to be a str, received: {type(application)}" ) if exposed_endpoints is not None and not isinstance(exposed_endpoints, dict): raise Exception( - "Expected exposed_endpoints to be a Mapping, received: {}".format( - type(exposed_endpoints) - ) + f"Expected exposed_endpoints to be a Mapping, received: {type(exposed_endpoints)}" ) # map input types to rpc msg @@ -1899,8 +1846,7 @@ async def Expose(self, application=None, exposed_endpoints=None): @ReturnMapping(ApplicationGetResults) async def Get(self, application=None, branch=None): - """ - Get returns the charm configuration for an application. + """Get returns the charm configuration for an application. application : str branch : str @@ -1908,15 +1854,11 @@ async def Get(self, application=None, branch=None): """ if application is not None and not isinstance(application, (bytes, str)): raise Exception( - "Expected application to be a str, received: {}".format( - type(application) - ) + f"Expected application to be a str, received: {type(application)}" ) if branch is not None and not isinstance(branch, (bytes, str)): - raise Exception( - "Expected branch to be a str, received: {}".format(type(branch)) - ) + raise Exception(f"Expected branch to be a str, received: {type(branch)}") # map input types to rpc msg _params = dict() @@ -1928,8 +1870,7 @@ async def Get(self, application=None, branch=None): @ReturnMapping(CharmURLOriginResult) async def GetCharmURLOrigin(self, application=None, branch=None): - """ - GetCharmURLOrigin returns the charm URL and charm origin the given + """GetCharmURLOrigin returns the charm URL and charm origin the given application is running at present. application : str @@ -1938,15 +1879,11 @@ async def GetCharmURLOrigin(self, application=None, branch=None): """ if application is not None and not isinstance(application, (bytes, str)): raise Exception( - "Expected application to be a str, received: {}".format( - type(application) - ) + f"Expected application to be a str, received: {type(application)}" ) if branch is not None and not isinstance(branch, (bytes, str)): - raise Exception( - "Expected branch to be a str, received: {}".format(type(branch)) - ) + raise Exception(f"Expected branch to be a str, received: {type(branch)}") # map input types to rpc msg _params = dict() @@ -1960,17 +1897,14 @@ async def GetCharmURLOrigin(self, application=None, branch=None): @ReturnMapping(ApplicationGetConfigResults) async def GetConfig(self, entities=None): - """ - GetConfig returns the charm config for each of the input applications. + """GetConfig returns the charm config for each of the input applications. entities : typing.Sequence[~Entity] Returns -> ApplicationGetConfigResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1982,17 +1916,14 @@ async def GetConfig(self, entities=None): @ReturnMapping(ApplicationGetConstraintsResults) async def GetConstraints(self, entities=None): - """ - GetConstraints returns the constraints for a given application. + """GetConstraints returns the constraints for a given application. entities : typing.Sequence[~Entity] Returns -> ApplicationGetConstraintsResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -2006,14 +1937,13 @@ async def GetConstraints(self, entities=None): @ReturnMapping(StringResult) async def Leader(self, tag=None): - """ - Leader returns the unit name of the leader for the given application. + """Leader returns the unit name of the leader for the given application. tag : str Returns -> StringResult """ if tag is not None and not isinstance(tag, (bytes, str)): - raise Exception("Expected tag to be a str, received: {}".format(type(tag))) + raise Exception(f"Expected tag to be a str, received: {type(tag)}") # map input types to rpc msg _params = dict() @@ -2024,17 +1954,14 @@ async def Leader(self, tag=None): @ReturnMapping(ErrorResults) async def MergeBindings(self, args=None): - """ - MergeBindings merges operator-defined bindings with the current bindings for + """MergeBindings merges operator-defined bindings with the current bindings for one or more applications. args : typing.Sequence[~ApplicationMergeBindings] Returns -> ErrorResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -2047,8 +1974,7 @@ async def MergeBindings(self, args=None): @ReturnMapping(ErrorResults) async def ResolveUnitErrors(self, all_=None, retry=None, tags=None): - """ - ResolveUnitErrors marks errors on the specified units as resolved. + """ResolveUnitErrors marks errors on the specified units as resolved. all_ : bool retry : bool @@ -2056,19 +1982,13 @@ async def ResolveUnitErrors(self, all_=None, retry=None, tags=None): Returns -> ErrorResults """ if all_ is not None and not isinstance(all_, bool): - raise Exception( - "Expected all_ to be a bool, received: {}".format(type(all_)) - ) + raise Exception(f"Expected all_ to be a bool, received: {type(all_)}") if retry is not None and not isinstance(retry, bool): - raise Exception( - "Expected retry to be a bool, received: {}".format(type(retry)) - ) + raise Exception(f"Expected retry to be a bool, received: {type(retry)}") if tags is not None and not isinstance(tags, (dict, Entities)): - raise Exception( - "Expected tags to be a Entities, received: {}".format(type(tags)) - ) + raise Exception(f"Expected tags to be a Entities, received: {type(tags)}") # map input types to rpc msg _params = dict() @@ -2083,8 +2003,7 @@ async def ResolveUnitErrors(self, all_=None, retry=None, tags=None): @ReturnMapping(ScaleApplicationResults) async def ScaleApplications(self, applications=None): - """ - ScaleApplications scales the specified application to the requested number of units. + """ScaleApplications scales the specified application to the requested number of units. applications : typing.Sequence[~ScaleApplicationParams] Returns -> ScaleApplicationResults @@ -2093,9 +2012,7 @@ async def ScaleApplications(self, applications=None): applications, (bytes, str, list) ): raise Exception( - "Expected applications to be a Sequence, received: {}".format( - type(applications) - ) + f"Expected applications to be a Sequence, received: {type(applications)}" ) # map input types to rpc msg @@ -2124,8 +2041,7 @@ async def SetCharm( resource_ids=None, storage_constraints=None, ): - """ - SetCharm sets the charm for a given for the application. + """SetCharm sets the charm for a given for the application. application : str channel : str @@ -2144,91 +2060,69 @@ async def SetCharm( """ if application is not None and not isinstance(application, (bytes, str)): raise Exception( - "Expected application to be a str, received: {}".format( - type(application) - ) + f"Expected application to be a str, received: {type(application)}" ) if channel is not None and not isinstance(channel, (bytes, str)): - raise Exception( - "Expected channel to be a str, received: {}".format(type(channel)) - ) + raise Exception(f"Expected channel to be a str, received: {type(channel)}") if charm_origin is not None and not isinstance( charm_origin, (dict, CharmOrigin) ): raise Exception( - "Expected charm_origin to be a CharmOrigin, received: {}".format( - type(charm_origin) - ) + f"Expected charm_origin to be a CharmOrigin, received: {type(charm_origin)}" ) if charm_url is not None and not isinstance(charm_url, (bytes, str)): raise Exception( - "Expected charm_url to be a str, received: {}".format(type(charm_url)) + f"Expected charm_url to be a str, received: {type(charm_url)}" ) if config_settings is not None and not isinstance(config_settings, dict): raise Exception( - "Expected config_settings to be a Mapping, received: {}".format( - type(config_settings) - ) + f"Expected config_settings to be a Mapping, received: {type(config_settings)}" ) if config_settings_yaml is not None and not isinstance( config_settings_yaml, (bytes, str) ): raise Exception( - "Expected config_settings_yaml to be a str, received: {}".format( - type(config_settings_yaml) - ) + f"Expected config_settings_yaml to be a str, received: {type(config_settings_yaml)}" ) if endpoint_bindings is not None and not isinstance(endpoint_bindings, dict): raise Exception( - "Expected endpoint_bindings to be a Mapping, received: {}".format( - type(endpoint_bindings) - ) + f"Expected endpoint_bindings to be a Mapping, received: {type(endpoint_bindings)}" ) if force is not None and not isinstance(force, bool): - raise Exception( - "Expected force to be a bool, received: {}".format(type(force)) - ) + raise Exception(f"Expected force to be a bool, received: {type(force)}") if force_base is not None and not isinstance(force_base, bool): raise Exception( - "Expected force_base to be a bool, received: {}".format( - type(force_base) - ) + f"Expected force_base to be a bool, received: {type(force_base)}" ) if force_units is not None and not isinstance(force_units, bool): raise Exception( - "Expected force_units to be a bool, received: {}".format( - type(force_units) - ) + f"Expected force_units to be a bool, received: {type(force_units)}" ) if generation is not None and not isinstance(generation, (bytes, str)): raise Exception( - "Expected generation to be a str, received: {}".format(type(generation)) + f"Expected generation to be a str, received: {type(generation)}" ) if resource_ids is not None and not isinstance(resource_ids, dict): raise Exception( - "Expected resource_ids to be a Mapping, received: {}".format( - type(resource_ids) - ) + f"Expected resource_ids to be a Mapping, received: {type(resource_ids)}" ) if storage_constraints is not None and not isinstance( storage_constraints, dict ): raise Exception( - "Expected storage_constraints to be a Mapping, received: {}".format( - type(storage_constraints) - ) + f"Expected storage_constraints to be a Mapping, received: {type(storage_constraints)}" ) # map input types to rpc msg @@ -2252,8 +2146,7 @@ async def SetCharm( @ReturnMapping(ErrorResults) async def SetConfigs(self, args=None): - """ - SetConfigs implements the server side of Application.SetConfig. Both + """SetConfigs implements the server side of Application.SetConfig. Both application and charm config are set. It does not unset values in Config map that are set to an empty string. Unset should be used for that. @@ -2261,9 +2154,7 @@ async def SetConfigs(self, args=None): Returns -> ErrorResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -2274,8 +2165,7 @@ async def SetConfigs(self, args=None): @ReturnMapping(None) async def SetConstraints(self, application=None, constraints=None): - """ - SetConstraints sets the constraints for a given application. + """SetConstraints sets the constraints for a given application. application : str constraints : Value @@ -2283,16 +2173,12 @@ async def SetConstraints(self, application=None, constraints=None): """ if application is not None and not isinstance(application, (bytes, str)): raise Exception( - "Expected application to be a str, received: {}".format( - type(application) - ) + f"Expected application to be a str, received: {type(application)}" ) if constraints is not None and not isinstance(constraints, (dict, Value)): raise Exception( - "Expected constraints to be a Value, received: {}".format( - type(constraints) - ) + f"Expected constraints to be a Value, received: {type(constraints)}" ) # map input types to rpc msg @@ -2307,8 +2193,7 @@ async def SetConstraints(self, application=None, constraints=None): @ReturnMapping(ErrorResults) async def SetMetricCredentials(self, creds=None): - """ - SetMetricCredentials sets credentials on the application. + """SetMetricCredentials sets credentials on the application. TODO (cderici) only used for metered charms in cmd MeteredDeployAPI, kept for client compatibility, remove in juju 4.0 @@ -2316,9 +2201,7 @@ async def SetMetricCredentials(self, creds=None): Returns -> ErrorResults """ if creds is not None and not isinstance(creds, (bytes, str, list)): - raise Exception( - "Expected creds to be a Sequence, received: {}".format(type(creds)) - ) + raise Exception(f"Expected creds to be a Sequence, received: {type(creds)}") # map input types to rpc msg _params = dict() @@ -2334,16 +2217,13 @@ async def SetMetricCredentials(self, creds=None): @ReturnMapping(ErrorResults) async def SetRelationsSuspended(self, args=None): - """ - SetRelationsSuspended sets the suspended status of the specified relations. + """SetRelationsSuspended sets the suspended status of the specified relations. args : typing.Sequence[~RelationSuspendedArg] Returns -> ErrorResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -2359,8 +2239,7 @@ async def SetRelationsSuspended(self, args=None): @ReturnMapping(None) async def Unexpose(self, application=None, exposed_endpoints=None): - """ - Unexpose changes the juju-managed firewall to unexpose any ports that + """Unexpose changes the juju-managed firewall to unexpose any ports that were also explicitly marked by units as open. application : str @@ -2369,18 +2248,14 @@ async def Unexpose(self, application=None, exposed_endpoints=None): """ if application is not None and not isinstance(application, (bytes, str)): raise Exception( - "Expected application to be a str, received: {}".format( - type(application) - ) + f"Expected application to be a str, received: {type(application)}" ) if exposed_endpoints is not None and not isinstance( exposed_endpoints, (bytes, str, list) ): raise Exception( - "Expected exposed_endpoints to be a Sequence, received: {}".format( - type(exposed_endpoints) - ) + f"Expected exposed_endpoints to be a Sequence, received: {type(exposed_endpoints)}" ) # map input types to rpc msg @@ -2393,8 +2268,7 @@ async def Unexpose(self, application=None, exposed_endpoints=None): @ReturnMapping(UnitInfoResults) async def UnitsInfo(self, entities=None): - """ - UnitsInfo returns unit information for the given entities (units or + """UnitsInfo returns unit information for the given entities (units or applications). entities : typing.Sequence[~Entity] @@ -2402,9 +2276,7 @@ async def UnitsInfo(self, entities=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -2416,16 +2288,13 @@ async def UnitsInfo(self, entities=None): @ReturnMapping(ErrorResults) async def UnsetApplicationsConfig(self, args=None): - """ - UnsetApplicationsConfig implements the server side of Application.UnsetApplicationsConfig. + """UnsetApplicationsConfig implements the server side of Application.UnsetApplicationsConfig. args : typing.Sequence[~ApplicationUnset] Returns -> ErrorResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -2441,17 +2310,14 @@ async def UnsetApplicationsConfig(self, args=None): @ReturnMapping(ErrorResults) async def UpdateApplicationBase(self, args=None): - """ - UpdateApplicationBase updates the application base. + """UpdateApplicationBase updates the application base. Base for subordinates is updated too. args : typing.Sequence[~UpdateChannelArg] Returns -> ErrorResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() diff --git a/juju/client/_client3.py b/juju/client/_client3.py index b9c77c523..68152f5f6 100644 --- a/juju/client/_client3.py +++ b/juju/client/_client3.py @@ -1,8 +1,8 @@ # DO NOT CHANGE THIS FILE! This file is auto-generated by facade.py. # Changes will be overwritten/lost when the file is regenerated. -from juju.client.facade import Type, ReturnMapping from juju.client._definitions import * +from juju.client.facade import ReturnMapping, Type class AdminFacade(Type): @@ -181,8 +181,7 @@ async def Login( token=None, user_data=None, ): - """ - Login logs in with the provided credentials. All subsequent requests on the + """Login logs in with the provided credentials. All subsequent requests on the connection will act as the authenticated user. auth_tag : str @@ -198,55 +197,43 @@ async def Login( """ if auth_tag is not None and not isinstance(auth_tag, (bytes, str)): raise Exception( - "Expected auth_tag to be a str, received: {}".format(type(auth_tag)) + f"Expected auth_tag to be a str, received: {type(auth_tag)}" ) if bakery_version is not None and not isinstance(bakery_version, int): raise Exception( - "Expected bakery_version to be a int, received: {}".format( - type(bakery_version) - ) + f"Expected bakery_version to be a int, received: {type(bakery_version)}" ) if cli_args is not None and not isinstance(cli_args, (bytes, str)): raise Exception( - "Expected cli_args to be a str, received: {}".format(type(cli_args)) + f"Expected cli_args to be a str, received: {type(cli_args)}" ) if client_version is not None and not isinstance(client_version, (bytes, str)): raise Exception( - "Expected client_version to be a str, received: {}".format( - type(client_version) - ) + f"Expected client_version to be a str, received: {type(client_version)}" ) if credentials is not None and not isinstance(credentials, (bytes, str)): raise Exception( - "Expected credentials to be a str, received: {}".format( - type(credentials) - ) + f"Expected credentials to be a str, received: {type(credentials)}" ) if macaroons is not None and not isinstance(macaroons, (bytes, str, list)): raise Exception( - "Expected macaroons to be a Sequence, received: {}".format( - type(macaroons) - ) + f"Expected macaroons to be a Sequence, received: {type(macaroons)}" ) if nonce is not None and not isinstance(nonce, (bytes, str)): - raise Exception( - "Expected nonce to be a str, received: {}".format(type(nonce)) - ) + raise Exception(f"Expected nonce to be a str, received: {type(nonce)}") if token is not None and not isinstance(token, (bytes, str)): - raise Exception( - "Expected token to be a str, received: {}".format(type(token)) - ) + raise Exception(f"Expected token to be a str, received: {type(token)}") if user_data is not None and not isinstance(user_data, (bytes, str)): raise Exception( - "Expected user_data to be a str, received: {}".format(type(user_data)) + f"Expected user_data to be a str, received: {type(user_data)}" ) # map input types to rpc msg @@ -266,15 +253,13 @@ async def Login( @ReturnMapping(RedirectInfoResult) async def RedirectInfo(self): - """ - RedirectInfo returns redirected host information for the model. + """RedirectInfo returns redirected host information for the model. In Juju it always returns an error because the Juju controller does not multiplex controllers. Returns -> RedirectInfoResult """ - # map input types to rpc msg _params = dict() msg = dict(type="Admin", request="RedirectInfo", version=3, params=_params) @@ -326,14 +311,12 @@ class AllWatcherFacade(Type): @ReturnMapping(AllWatcherNextResults) async def Next(self): - """ - Next will return the current state of everything on the first call + """Next will return the current state of everything on the first call and subsequent calls will Returns -> AllWatcherNextResults """ - # map input types to rpc msg _params = dict() msg = dict(type="AllWatcher", request="Next", version=3, params=_params) @@ -343,13 +326,10 @@ async def Next(self): @ReturnMapping(None) async def Stop(self): - """ - Stop stops the watcher. - + """Stop stops the watcher. Returns -> None """ - # map input types to rpc msg _params = dict() msg = dict(type="AllWatcher", request="Stop", version=3, params=_params) @@ -358,9 +338,7 @@ async def Stop(self): return reply async def rpc(self, msg): - """ - Patch rpc method to add Id. - """ + """Patch rpc method to add Id.""" if not hasattr(self, "Id"): raise RuntimeError('Missing "Id" field') msg["Id"] = id @@ -462,8 +440,7 @@ class BackupsFacade(Type): @ReturnMapping(BackupsMetadataResult) async def Create(self, no_download=None, notes=None): - """ - Create is the API method that requests juju to create a new backup + """Create is the API method that requests juju to create a new backup of its state. no_download : bool @@ -472,15 +449,11 @@ async def Create(self, no_download=None, notes=None): """ if no_download is not None and not isinstance(no_download, bool): raise Exception( - "Expected no_download to be a bool, received: {}".format( - type(no_download) - ) + f"Expected no_download to be a bool, received: {type(no_download)}" ) if notes is not None and not isinstance(notes, (bytes, str)): - raise Exception( - "Expected notes to be a str, received: {}".format(type(notes)) - ) + raise Exception(f"Expected notes to be a str, received: {type(notes)}") # map input types to rpc msg _params = dict() @@ -692,13 +665,10 @@ class ModelConfigFacade(Type): @ReturnMapping(GetConstraintsResults) async def GetModelConstraints(self): - """ - GetModelConstraints returns the constraints for the model. - + """GetModelConstraints returns the constraints for the model. Returns -> GetConstraintsResults """ - # map input types to rpc msg _params = dict() msg = dict( @@ -710,14 +680,12 @@ async def GetModelConstraints(self): @ReturnMapping(ModelConfigResults) async def ModelGet(self): - """ - ModelGet implements the server-side part of the + """ModelGet implements the server-side part of the model-config CLI command. Returns -> ModelConfigResults """ - # map input types to rpc msg _params = dict() msg = dict(type="ModelConfig", request="ModelGet", version=3, params=_params) @@ -727,8 +695,7 @@ async def ModelGet(self): @ReturnMapping(None) async def ModelSet(self, config=None): - """ - ModelSet implements the server-side part of the + """ModelSet implements the server-side part of the set-model-config CLI command. config : typing.Mapping[str, typing.Any] @@ -736,7 +703,7 @@ async def ModelSet(self, config=None): """ if config is not None and not isinstance(config, dict): raise Exception( - "Expected config to be a Mapping, received: {}".format(type(config)) + f"Expected config to be a Mapping, received: {type(config)}" ) # map input types to rpc msg @@ -748,17 +715,14 @@ async def ModelSet(self, config=None): @ReturnMapping(None) async def ModelUnset(self, keys=None): - """ - ModelUnset implements the server-side part of the + """ModelUnset implements the server-side part of the set-model-config CLI command. keys : typing.Sequence[str] Returns -> None """ if keys is not None and not isinstance(keys, (bytes, str, list)): - raise Exception( - "Expected keys to be a Sequence, received: {}".format(type(keys)) - ) + raise Exception(f"Expected keys to be a Sequence, received: {type(keys)}") # map input types to rpc msg _params = dict() @@ -769,13 +733,10 @@ async def ModelUnset(self, keys=None): @ReturnMapping(StringResult) async def SLALevel(self): - """ - SLALevel returns the current sla level for the model. - + """SLALevel returns the current sla level for the model. Returns -> StringResult """ - # map input types to rpc msg _params = dict() msg = dict(type="ModelConfig", request="SLALevel", version=3, params=_params) @@ -785,13 +746,10 @@ async def SLALevel(self): @ReturnMapping(ModelSequencesResult) async def Sequences(self): - """ - Sequences returns the model's sequence names and next values. - + """Sequences returns the model's sequence names and next values. Returns -> ModelSequencesResult """ - # map input types to rpc msg _params = dict() msg = dict(type="ModelConfig", request="Sequences", version=3, params=_params) @@ -801,8 +759,7 @@ async def Sequences(self): @ReturnMapping(None) async def SetModelConstraints(self, application=None, constraints=None): - """ - SetModelConstraints sets the constraints for the model. + """SetModelConstraints sets the constraints for the model. application : str constraints : Value @@ -810,16 +767,12 @@ async def SetModelConstraints(self, application=None, constraints=None): """ if application is not None and not isinstance(application, (bytes, str)): raise Exception( - "Expected application to be a str, received: {}".format( - type(application) - ) + f"Expected application to be a str, received: {type(application)}" ) if constraints is not None and not isinstance(constraints, (dict, Value)): raise Exception( - "Expected constraints to be a Value, received: {}".format( - type(constraints) - ) + f"Expected constraints to be a Value, received: {type(constraints)}" ) # map input types to rpc msg @@ -834,8 +787,7 @@ async def SetModelConstraints(self, application=None, constraints=None): @ReturnMapping(None) async def SetSLALevel(self, modelslainfo=None, creds=None, level=None, owner=None): - """ - SetSLALevel sets the sla level on the model. + """SetSLALevel sets the sla level on the model. modelslainfo : ModelSLAInfo creds : typing.Sequence[int] @@ -847,25 +799,17 @@ async def SetSLALevel(self, modelslainfo=None, creds=None, level=None, owner=Non modelslainfo, (dict, ModelSLAInfo) ): raise Exception( - "Expected modelslainfo to be a ModelSLAInfo, received: {}".format( - type(modelslainfo) - ) + f"Expected modelslainfo to be a ModelSLAInfo, received: {type(modelslainfo)}" ) if creds is not None and not isinstance(creds, (bytes, str, list)): - raise Exception( - "Expected creds to be a Sequence, received: {}".format(type(creds)) - ) + raise Exception(f"Expected creds to be a Sequence, received: {type(creds)}") if level is not None and not isinstance(level, (bytes, str)): - raise Exception( - "Expected level to be a str, received: {}".format(type(level)) - ) + raise Exception(f"Expected level to be a str, received: {type(level)}") if owner is not None and not isinstance(owner, (bytes, str)): - raise Exception( - "Expected owner to be a str, received: {}".format(type(owner)) - ) + raise Exception(f"Expected owner to be a str, received: {type(owner)}") # map input types to rpc msg _params = dict() @@ -1137,8 +1081,7 @@ async def AddPendingResources( tag=None, url=None, ): - """ - AddPendingResources adds the provided resources (info) to the Juju + """AddPendingResources adds the provided resources (info) to the Juju model in a pending state, meaning they are not available until resolved. Handles CharmHub and Local charms. @@ -1151,38 +1094,30 @@ async def AddPendingResources( Returns -> AddPendingResourcesResult """ if entity is not None and not isinstance(entity, (dict, Entity)): - raise Exception( - "Expected entity to be a Entity, received: {}".format(type(entity)) - ) + raise Exception(f"Expected entity to be a Entity, received: {type(entity)}") if charm_origin is not None and not isinstance( charm_origin, (dict, CharmOrigin) ): raise Exception( - "Expected charm_origin to be a CharmOrigin, received: {}".format( - type(charm_origin) - ) + f"Expected charm_origin to be a CharmOrigin, received: {type(charm_origin)}" ) if macaroon is not None and not isinstance(macaroon, (dict, Macaroon)): raise Exception( - "Expected macaroon to be a Macaroon, received: {}".format( - type(macaroon) - ) + f"Expected macaroon to be a Macaroon, received: {type(macaroon)}" ) if resources is not None and not isinstance(resources, (bytes, str, list)): raise Exception( - "Expected resources to be a Sequence, received: {}".format( - type(resources) - ) + f"Expected resources to be a Sequence, received: {type(resources)}" ) if tag is not None and not isinstance(tag, (bytes, str)): - raise Exception("Expected tag to be a str, received: {}".format(type(tag))) + raise Exception(f"Expected tag to be a str, received: {type(tag)}") if url is not None and not isinstance(url, (bytes, str)): - raise Exception("Expected url to be a str, received: {}".format(type(url))) + raise Exception(f"Expected url to be a str, received: {type(url)}") # map input types to rpc msg _params = dict() @@ -1200,17 +1135,14 @@ async def AddPendingResources( @ReturnMapping(ResourcesResults) async def ListResources(self, entities=None): - """ - ListResources returns the list of resources for the given application. + """ListResources returns the list of resources for the given application. entities : typing.Sequence[~Entity] Returns -> ResourcesResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1532,17 +1464,14 @@ class UserManagerFacade(Type): @ReturnMapping(AddUserResults) async def AddUser(self, users=None): - """ - AddUser adds a user with a username, and either a password or + """AddUser adds a user with a username, and either a password or a randomly generated secret key which will be returned. users : typing.Sequence[~AddUser] Returns -> AddUserResults """ if users is not None and not isinstance(users, (bytes, str, list)): - raise Exception( - "Expected users to be a Sequence, received: {}".format(type(users)) - ) + raise Exception(f"Expected users to be a Sequence, received: {type(users)}") # map input types to rpc msg _params = dict() @@ -1553,8 +1482,7 @@ async def AddUser(self, users=None): @ReturnMapping(ErrorResults) async def DisableUser(self, entities=None): - """ - DisableUser disables one or more users. If the user is already disabled, + """DisableUser disables one or more users. If the user is already disabled, the action is considered a success. entities : typing.Sequence[~Entity] @@ -1562,9 +1490,7 @@ async def DisableUser(self, entities=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1576,8 +1502,7 @@ async def DisableUser(self, entities=None): @ReturnMapping(ErrorResults) async def EnableUser(self, entities=None): - """ - EnableUser enables one or more users. If the user is already enabled, + """EnableUser enables one or more users. If the user is already enabled, the action is considered a success. entities : typing.Sequence[~Entity] @@ -1585,9 +1510,7 @@ async def EnableUser(self, entities=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1599,17 +1522,14 @@ async def EnableUser(self, entities=None): @ReturnMapping(ModelUserInfoResults) async def ModelUserInfo(self, entities=None): - """ - ModelUserInfo returns information on all users in the model. + """ModelUserInfo returns information on all users in the model. entities : typing.Sequence[~Entity] Returns -> ModelUserInfoResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1623,8 +1543,7 @@ async def ModelUserInfo(self, entities=None): @ReturnMapping(ErrorResults) async def RemoveUser(self, entities=None): - """ - RemoveUser permanently removes a user from the current controller for each + """RemoveUser permanently removes a user from the current controller for each entity provided. While the user is permanently removed we keep it's information around for auditing purposes. TODO(redir): Add information about getting deleted user information when we @@ -1635,9 +1554,7 @@ async def RemoveUser(self, entities=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1649,8 +1566,7 @@ async def RemoveUser(self, entities=None): @ReturnMapping(AddUserResults) async def ResetPassword(self, entities=None): - """ - ResetPassword resets password for supplied users by + """ResetPassword resets password for supplied users by invalidating current passwords (if any) and generating new random secret keys which will be returned. Users cannot reset their own password. @@ -1660,9 +1576,7 @@ async def ResetPassword(self, entities=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1676,15 +1590,14 @@ async def ResetPassword(self, entities=None): @ReturnMapping(ErrorResults) async def SetPassword(self, changes=None): - """ - SetPassword changes the stored password for the specified users. + """SetPassword changes the stored password for the specified users. changes : typing.Sequence[~EntityPassword] Returns -> ErrorResults """ if changes is not None and not isinstance(changes, (bytes, str, list)): raise Exception( - "Expected changes to be a Sequence, received: {}".format(type(changes)) + f"Expected changes to be a Sequence, received: {type(changes)}" ) # map input types to rpc msg @@ -1696,8 +1609,7 @@ async def SetPassword(self, changes=None): @ReturnMapping(UserInfoResults) async def UserInfo(self, entities=None, include_disabled=None): - """ - UserInfo returns information on a user. + """UserInfo returns information on a user. entities : typing.Sequence[~Entity] include_disabled : bool @@ -1705,16 +1617,12 @@ async def UserInfo(self, entities=None, include_disabled=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) if include_disabled is not None and not isinstance(include_disabled, bool): raise Exception( - "Expected include_disabled to be a bool, received: {}".format( - type(include_disabled) - ) + f"Expected include_disabled to be a bool, received: {type(include_disabled)}" ) # map input types to rpc msg diff --git a/juju/client/_client4.py b/juju/client/_client4.py index 4c6d8e413..e66612aea 100644 --- a/juju/client/_client4.py +++ b/juju/client/_client4.py @@ -1,8 +1,8 @@ # DO NOT CHANGE THIS FILE! This file is auto-generated by facade.py. # Changes will be overwritten/lost when the file is regenerated. -from juju.client.facade import Type, ReturnMapping from juju.client._definitions import * +from juju.client.facade import ReturnMapping, Type class AllModelWatcherFacade(Type): @@ -48,14 +48,12 @@ class AllModelWatcherFacade(Type): @ReturnMapping(AllWatcherNextResults) async def Next(self): - """ - Next will return the current state of everything on the first call + """Next will return the current state of everything on the first call and subsequent calls will Returns -> AllWatcherNextResults """ - # map input types to rpc msg _params = dict() msg = dict(type="AllModelWatcher", request="Next", version=4, params=_params) @@ -65,13 +63,10 @@ async def Next(self): @ReturnMapping(None) async def Stop(self): - """ - Stop stops the watcher. - + """Stop stops the watcher. Returns -> None """ - # map input types to rpc msg _params = dict() msg = dict(type="AllModelWatcher", request="Stop", version=4, params=_params) @@ -80,9 +75,7 @@ async def Stop(self): return reply async def rpc(self, msg): - """ - Patch rpc method to add Id. - """ + """Patch rpc method to add Id.""" if not hasattr(self, "Id"): raise RuntimeError('Missing "Id" field') msg["Id"] = id @@ -672,8 +665,7 @@ class ApplicationOffersFacade(Type): @ReturnMapping(ApplicationOffersResults) async def ApplicationOffers(self, bakery_version=None, offer_urls=None): - """ - ApplicationOffers gets details about remote applications that match given URLs. + """ApplicationOffers gets details about remote applications that match given URLs. bakery_version : int offer_urls : typing.Sequence[str] @@ -681,16 +673,12 @@ async def ApplicationOffers(self, bakery_version=None, offer_urls=None): """ if bakery_version is not None and not isinstance(bakery_version, int): raise Exception( - "Expected bakery_version to be a int, received: {}".format( - type(bakery_version) - ) + f"Expected bakery_version to be a int, received: {type(bakery_version)}" ) if offer_urls is not None and not isinstance(offer_urls, (bytes, str, list)): raise Exception( - "Expected offer_urls to be a Sequence, received: {}".format( - type(offer_urls) - ) + f"Expected offer_urls to be a Sequence, received: {type(offer_urls)}" ) # map input types to rpc msg @@ -708,23 +696,18 @@ async def ApplicationOffers(self, bakery_version=None, offer_urls=None): @ReturnMapping(ErrorResults) async def DestroyOffers(self, force=None, offer_urls=None): - """ - DestroyOffers removes the offers specified by the given URLs, forcing if necessary. + """DestroyOffers removes the offers specified by the given URLs, forcing if necessary. force : bool offer_urls : typing.Sequence[str] Returns -> ErrorResults """ if force is not None and not isinstance(force, bool): - raise Exception( - "Expected force to be a bool, received: {}".format(type(force)) - ) + raise Exception(f"Expected force to be a bool, received: {type(force)}") if offer_urls is not None and not isinstance(offer_urls, (bytes, str, list)): raise Exception( - "Expected offer_urls to be a Sequence, received: {}".format( - type(offer_urls) - ) + f"Expected offer_urls to be a Sequence, received: {type(offer_urls)}" ) # map input types to rpc msg @@ -739,15 +722,14 @@ async def DestroyOffers(self, force=None, offer_urls=None): @ReturnMapping(QueryApplicationOffersResults) async def FindApplicationOffers(self, filters=None): - """ - FindApplicationOffers gets details about remote applications that match given filter. + """FindApplicationOffers gets details about remote applications that match given filter. filters : typing.Sequence[~OfferFilter] Returns -> QueryApplicationOffersResults """ if filters is not None and not isinstance(filters, (bytes, str, list)): raise Exception( - "Expected filters to be a Sequence, received: {}".format(type(filters)) + f"Expected filters to be a Sequence, received: {type(filters)}" ) # map input types to rpc msg @@ -764,8 +746,7 @@ async def FindApplicationOffers(self, filters=None): @ReturnMapping(ConsumeOfferDetailsResults) async def GetConsumeDetails(self, offer_urls=None, user_tag=None): - """ - GetConsumeDetails returns the details necessary to pass to another model + """GetConsumeDetails returns the details necessary to pass to another model to allow the specified args user to consume the offers represented by the args URLs. offer_urls : OfferURLs @@ -774,14 +755,12 @@ async def GetConsumeDetails(self, offer_urls=None, user_tag=None): """ if offer_urls is not None and not isinstance(offer_urls, (dict, OfferURLs)): raise Exception( - "Expected offer_urls to be a OfferURLs, received: {}".format( - type(offer_urls) - ) + f"Expected offer_urls to be a OfferURLs, received: {type(offer_urls)}" ) if user_tag is not None and not isinstance(user_tag, (bytes, str)): raise Exception( - "Expected user_tag to be a str, received: {}".format(type(user_tag)) + f"Expected user_tag to be a str, received: {type(user_tag)}" ) # map input types to rpc msg @@ -799,8 +778,7 @@ async def GetConsumeDetails(self, offer_urls=None, user_tag=None): @ReturnMapping(QueryApplicationOffersResults) async def ListApplicationOffers(self, filters=None): - """ - ListApplicationOffers gets deployed details about application offers that match given filter. + """ListApplicationOffers gets deployed details about application offers that match given filter. The results contain details about the deployed applications such as connection count. filters : typing.Sequence[~OfferFilter] @@ -808,7 +786,7 @@ async def ListApplicationOffers(self, filters=None): """ if filters is not None and not isinstance(filters, (bytes, str, list)): raise Exception( - "Expected filters to be a Sequence, received: {}".format(type(filters)) + f"Expected filters to be a Sequence, received: {type(filters)}" ) # map input types to rpc msg @@ -825,15 +803,14 @@ async def ListApplicationOffers(self, filters=None): @ReturnMapping(ErrorResults) async def ModifyOfferAccess(self, changes=None): - """ - ModifyOfferAccess changes the application offer access granted to users. + """ModifyOfferAccess changes the application offer access granted to users. changes : typing.Sequence[~ModifyOfferAccess] Returns -> ErrorResults """ if changes is not None and not isinstance(changes, (bytes, str, list)): raise Exception( - "Expected changes to be a Sequence, received: {}".format(type(changes)) + f"Expected changes to be a Sequence, received: {type(changes)}" ) # map input types to rpc msg @@ -850,15 +827,14 @@ async def ModifyOfferAccess(self, changes=None): @ReturnMapping(ErrorResults) async def Offer(self, offers=None): - """ - Offer makes application endpoints available for consumption at a specified URL. + """Offer makes application endpoints available for consumption at a specified URL. offers : typing.Sequence[~AddApplicationOffer] Returns -> ErrorResults """ if offers is not None and not isinstance(offers, (bytes, str, list)): raise Exception( - "Expected offers to be a Sequence, received: {}".format(type(offers)) + f"Expected offers to be a Sequence, received: {type(offers)}" ) # map input types to rpc msg @@ -870,8 +846,7 @@ async def Offer(self, offers=None): @ReturnMapping(RemoteApplicationInfoResults) async def RemoteApplicationInfo(self, bakery_version=None, offer_urls=None): - """ - RemoteApplicationInfo returns information about the requested remote application. + """RemoteApplicationInfo returns information about the requested remote application. This call currently has no client side API, only there for the Dashboard at this stage. bakery_version : int @@ -880,16 +855,12 @@ async def RemoteApplicationInfo(self, bakery_version=None, offer_urls=None): """ if bakery_version is not None and not isinstance(bakery_version, int): raise Exception( - "Expected bakery_version to be a int, received: {}".format( - type(bakery_version) - ) + f"Expected bakery_version to be a int, received: {type(bakery_version)}" ) if offer_urls is not None and not isinstance(offer_urls, (bytes, str, list)): raise Exception( - "Expected offer_urls to be a Sequence, received: {}".format( - type(offer_urls) - ) + f"Expected offer_urls to be a Sequence, received: {type(offer_urls)}" ) # map input types to rpc msg @@ -1164,8 +1135,7 @@ class ModelGenerationFacade(Type): @ReturnMapping(ErrorResult) async def AbortBranch(self, branch=None): - """ - AbortBranch aborts the input branch, marking it complete. However no + """AbortBranch aborts the input branch, marking it complete. However no changes are made applicable to the whole model. No units may be assigned to the branch when aborting. @@ -1173,9 +1143,7 @@ async def AbortBranch(self, branch=None): Returns -> ErrorResult """ if branch is not None and not isinstance(branch, (bytes, str)): - raise Exception( - "Expected branch to be a str, received: {}".format(type(branch)) - ) + raise Exception(f"Expected branch to be a str, received: {type(branch)}") # map input types to rpc msg _params = dict() @@ -1188,16 +1156,13 @@ async def AbortBranch(self, branch=None): @ReturnMapping(ErrorResult) async def AddBranch(self, branch=None): - """ - AddBranch adds a new branch with the input name to the model. + """AddBranch adds a new branch with the input name to the model. branch : str Returns -> ErrorResult """ if branch is not None and not isinstance(branch, (bytes, str)): - raise Exception( - "Expected branch to be a str, received: {}".format(type(branch)) - ) + raise Exception(f"Expected branch to be a str, received: {type(branch)}") # map input types to rpc msg _params = dict() @@ -1210,8 +1175,7 @@ async def AddBranch(self, branch=None): @ReturnMapping(BranchResults) async def BranchInfo(self, branches=None, detailed=None): - """ - BranchInfo will return details of branch identified by the input argument, + """BranchInfo will return details of branch identified by the input argument, including units on the branch and the configuration disjoint with the master generation. An error is returned if no in-flight branch matching in input is found. @@ -1222,14 +1186,12 @@ async def BranchInfo(self, branches=None, detailed=None): """ if branches is not None and not isinstance(branches, (bytes, str, list)): raise Exception( - "Expected branches to be a Sequence, received: {}".format( - type(branches) - ) + f"Expected branches to be a Sequence, received: {type(branches)}" ) if detailed is not None and not isinstance(detailed, bool): raise Exception( - "Expected detailed to be a bool, received: {}".format(type(detailed)) + f"Expected detailed to be a bool, received: {type(detailed)}" ) # map input types to rpc msg @@ -1244,17 +1206,14 @@ async def BranchInfo(self, branches=None, detailed=None): @ReturnMapping(IntResult) async def CommitBranch(self, branch=None): - """ - CommitBranch commits the input branch, making its changes applicable to + """CommitBranch commits the input branch, making its changes applicable to the whole model and marking it complete. branch : str Returns -> IntResult """ if branch is not None and not isinstance(branch, (bytes, str)): - raise Exception( - "Expected branch to be a str, received: {}".format(type(branch)) - ) + raise Exception(f"Expected branch to be a str, received: {type(branch)}") # map input types to rpc msg _params = dict() @@ -1267,17 +1226,14 @@ async def CommitBranch(self, branch=None): @ReturnMapping(BoolResult) async def HasActiveBranch(self, branch=None): - """ - HasActiveBranch returns a true result if the input model has an "in-flight" + """HasActiveBranch returns a true result if the input model has an "in-flight" branch matching the input name. branch : str Returns -> BoolResult """ if branch is not None and not isinstance(branch, (bytes, str)): - raise Exception( - "Expected branch to be a str, received: {}".format(type(branch)) - ) + raise Exception(f"Expected branch to be a str, received: {type(branch)}") # map input types to rpc msg _params = dict() @@ -1290,13 +1246,10 @@ async def HasActiveBranch(self, branch=None): @ReturnMapping(BranchResults) async def ListCommits(self): - """ - ListCommits will return the commits, hence only branches with generation_id higher than 0 - + """ListCommits will return the commits, hence only branches with generation_id higher than 0 Returns -> BranchResults """ - # map input types to rpc msg _params = dict() msg = dict( @@ -1308,8 +1261,7 @@ async def ListCommits(self): @ReturnMapping(GenerationResult) async def ShowCommit(self, generation_id=None): - """ - ShowCommit will return details a commit given by its generationId + """ShowCommit will return details a commit given by its generationId An error is returned if either no branch can be found corresponding to the generation id. Or the generation id given is below 1. @@ -1318,9 +1270,7 @@ async def ShowCommit(self, generation_id=None): """ if generation_id is not None and not isinstance(generation_id, int): raise Exception( - "Expected generation_id to be a int, received: {}".format( - type(generation_id) - ) + f"Expected generation_id to be a int, received: {type(generation_id)}" ) # map input types to rpc msg @@ -1334,8 +1284,7 @@ async def ShowCommit(self, generation_id=None): @ReturnMapping(ErrorResults) async def TrackBranch(self, branch=None, entities=None, num_units=None): - """ - TrackBranch marks the input units and/or applications as tracking the input + """TrackBranch marks the input units and/or applications as tracking the input branch, causing them to realise changes made under that branch. branch : str @@ -1344,20 +1293,16 @@ async def TrackBranch(self, branch=None, entities=None, num_units=None): Returns -> ErrorResults """ if branch is not None and not isinstance(branch, (bytes, str)): - raise Exception( - "Expected branch to be a str, received: {}".format(type(branch)) - ) + raise Exception(f"Expected branch to be a str, received: {type(branch)}") if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) if num_units is not None and not isinstance(num_units, int): raise Exception( - "Expected num_units to be a int, received: {}".format(type(num_units)) + f"Expected num_units to be a int, received: {type(num_units)}" ) # map input types to rpc msg @@ -1588,8 +1533,7 @@ class SSHClientFacade(Type): @ReturnMapping(SSHAddressesResults) async def AllAddresses(self, entities=None): - """ - AllAddresses reports all addresses that might have SSH listening for each + """AllAddresses reports all addresses that might have SSH listening for each entity in args. The result is sorted with public addresses first. Machines and units are supported as entity types. @@ -1598,9 +1542,7 @@ async def AllAddresses(self, entities=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1612,14 +1554,12 @@ async def AllAddresses(self, entities=None): @ReturnMapping(CloudSpecResult) async def ModelCredentialForSSH(self): - """ - ModelCredentialForSSH returns a cloud spec for ssh purpose. + """ModelCredentialForSSH returns a cloud spec for ssh purpose. This facade call is only used for k8s model. Returns -> CloudSpecResult """ - # map input types to rpc msg _params = dict() msg = dict( @@ -1631,8 +1571,7 @@ async def ModelCredentialForSSH(self): @ReturnMapping(SSHAddressResults) async def PrivateAddress(self, entities=None): - """ - PrivateAddress reports the preferred private network address for one or + """PrivateAddress reports the preferred private network address for one or more entities. Machines and units are supported. entities : typing.Sequence[~Entity] @@ -1640,9 +1579,7 @@ async def PrivateAddress(self, entities=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1656,14 +1593,12 @@ async def PrivateAddress(self, entities=None): @ReturnMapping(SSHProxyResult) async def Proxy(self): - """ - Proxy returns whether SSH connections should be proxied through the + """Proxy returns whether SSH connections should be proxied through the controller hosts for the model associated with the API connection. Returns -> SSHProxyResult """ - # map input types to rpc msg _params = dict() msg = dict(type="SSHClient", request="Proxy", version=4, params=_params) @@ -1673,8 +1608,7 @@ async def Proxy(self): @ReturnMapping(SSHAddressResults) async def PublicAddress(self, entities=None): - """ - PublicAddress reports the preferred public network address for one + """PublicAddress reports the preferred public network address for one or more entities. Machines and units are supported. entities : typing.Sequence[~Entity] @@ -1682,9 +1616,7 @@ async def PublicAddress(self, entities=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1696,8 +1628,7 @@ async def PublicAddress(self, entities=None): @ReturnMapping(SSHPublicKeysResults) async def PublicKeys(self, entities=None): - """ - PublicKeys returns the public SSH hosts for one or more + """PublicKeys returns the public SSH hosts for one or more entities. Machines and units are supported. entities : typing.Sequence[~Entity] @@ -1705,9 +1636,7 @@ async def PublicKeys(self, entities=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg diff --git a/juju/client/_client5.py b/juju/client/_client5.py index 633c2bd25..e99362844 100644 --- a/juju/client/_client5.py +++ b/juju/client/_client5.py @@ -1,8 +1,8 @@ # DO NOT CHANGE THIS FILE! This file is auto-generated by facade.py. # Changes will be overwritten/lost when the file is regenerated. -from juju.client.facade import Type, ReturnMapping from juju.client._definitions import * +from juju.client.facade import ReturnMapping, Type class ApplicationOffersFacade(Type): @@ -528,8 +528,7 @@ class ApplicationOffersFacade(Type): @ReturnMapping(ApplicationOffersResults) async def ApplicationOffers(self, bakery_version=None, offer_urls=None): - """ - ApplicationOffers gets details about remote applications that match given URLs. + """ApplicationOffers gets details about remote applications that match given URLs. bakery_version : int offer_urls : typing.Sequence[str] @@ -537,16 +536,12 @@ async def ApplicationOffers(self, bakery_version=None, offer_urls=None): """ if bakery_version is not None and not isinstance(bakery_version, int): raise Exception( - "Expected bakery_version to be a int, received: {}".format( - type(bakery_version) - ) + f"Expected bakery_version to be a int, received: {type(bakery_version)}" ) if offer_urls is not None and not isinstance(offer_urls, (bytes, str, list)): raise Exception( - "Expected offer_urls to be a Sequence, received: {}".format( - type(offer_urls) - ) + f"Expected offer_urls to be a Sequence, received: {type(offer_urls)}" ) # map input types to rpc msg @@ -564,23 +559,18 @@ async def ApplicationOffers(self, bakery_version=None, offer_urls=None): @ReturnMapping(ErrorResults) async def DestroyOffers(self, force=None, offer_urls=None): - """ - DestroyOffers removes the offers specified by the given URLs, forcing if necessary. + """DestroyOffers removes the offers specified by the given URLs, forcing if necessary. force : bool offer_urls : typing.Sequence[str] Returns -> ErrorResults """ if force is not None and not isinstance(force, bool): - raise Exception( - "Expected force to be a bool, received: {}".format(type(force)) - ) + raise Exception(f"Expected force to be a bool, received: {type(force)}") if offer_urls is not None and not isinstance(offer_urls, (bytes, str, list)): raise Exception( - "Expected offer_urls to be a Sequence, received: {}".format( - type(offer_urls) - ) + f"Expected offer_urls to be a Sequence, received: {type(offer_urls)}" ) # map input types to rpc msg @@ -595,15 +585,14 @@ async def DestroyOffers(self, force=None, offer_urls=None): @ReturnMapping(QueryApplicationOffersResultsV5) async def FindApplicationOffers(self, filters=None): - """ - FindApplicationOffers gets details about remote applications that match given filter. + """FindApplicationOffers gets details about remote applications that match given filter. filters : typing.Sequence[~OfferFilter] Returns -> QueryApplicationOffersResultsV5 """ if filters is not None and not isinstance(filters, (bytes, str, list)): raise Exception( - "Expected filters to be a Sequence, received: {}".format(type(filters)) + f"Expected filters to be a Sequence, received: {type(filters)}" ) # map input types to rpc msg @@ -620,8 +609,7 @@ async def FindApplicationOffers(self, filters=None): @ReturnMapping(ConsumeOfferDetailsResults) async def GetConsumeDetails(self, offer_urls=None, user_tag=None): - """ - GetConsumeDetails returns the details necessary to pass to another model + """GetConsumeDetails returns the details necessary to pass to another model to allow the specified args user to consume the offers represented by the args URLs. offer_urls : OfferURLs @@ -630,14 +618,12 @@ async def GetConsumeDetails(self, offer_urls=None, user_tag=None): """ if offer_urls is not None and not isinstance(offer_urls, (dict, OfferURLs)): raise Exception( - "Expected offer_urls to be a OfferURLs, received: {}".format( - type(offer_urls) - ) + f"Expected offer_urls to be a OfferURLs, received: {type(offer_urls)}" ) if user_tag is not None and not isinstance(user_tag, (bytes, str)): raise Exception( - "Expected user_tag to be a str, received: {}".format(type(user_tag)) + f"Expected user_tag to be a str, received: {type(user_tag)}" ) # map input types to rpc msg @@ -655,8 +641,7 @@ async def GetConsumeDetails(self, offer_urls=None, user_tag=None): @ReturnMapping(QueryApplicationOffersResultsV5) async def ListApplicationOffers(self, filters=None): - """ - ListApplicationOffers gets deployed details about application offers that match given filter. + """ListApplicationOffers gets deployed details about application offers that match given filter. The results contain details about the deployed applications such as connection count. filters : typing.Sequence[~OfferFilter] @@ -664,7 +649,7 @@ async def ListApplicationOffers(self, filters=None): """ if filters is not None and not isinstance(filters, (bytes, str, list)): raise Exception( - "Expected filters to be a Sequence, received: {}".format(type(filters)) + f"Expected filters to be a Sequence, received: {type(filters)}" ) # map input types to rpc msg @@ -681,15 +666,14 @@ async def ListApplicationOffers(self, filters=None): @ReturnMapping(ErrorResults) async def ModifyOfferAccess(self, changes=None): - """ - ModifyOfferAccess changes the application offer access granted to users. + """ModifyOfferAccess changes the application offer access granted to users. changes : typing.Sequence[~ModifyOfferAccess] Returns -> ErrorResults """ if changes is not None and not isinstance(changes, (bytes, str, list)): raise Exception( - "Expected changes to be a Sequence, received: {}".format(type(changes)) + f"Expected changes to be a Sequence, received: {type(changes)}" ) # map input types to rpc msg @@ -706,15 +690,14 @@ async def ModifyOfferAccess(self, changes=None): @ReturnMapping(ErrorResults) async def Offer(self, offers=None): - """ - Offer makes application endpoints available for consumption at a specified URL. + """Offer makes application endpoints available for consumption at a specified URL. offers : typing.Sequence[~AddApplicationOffer] Returns -> ErrorResults """ if offers is not None and not isinstance(offers, (bytes, str, list)): raise Exception( - "Expected offers to be a Sequence, received: {}".format(type(offers)) + f"Expected offers to be a Sequence, received: {type(offers)}" ) # map input types to rpc msg @@ -726,8 +709,7 @@ async def Offer(self, offers=None): @ReturnMapping(RemoteApplicationInfoResults) async def RemoteApplicationInfo(self, bakery_version=None, offer_urls=None): - """ - RemoteApplicationInfo returns information about the requested remote application. + """RemoteApplicationInfo returns information about the requested remote application. This call currently has no client side API, only there for the Dashboard at this stage. bakery_version : int @@ -736,16 +718,12 @@ async def RemoteApplicationInfo(self, bakery_version=None, offer_urls=None): """ if bakery_version is not None and not isinstance(bakery_version, int): raise Exception( - "Expected bakery_version to be a int, received: {}".format( - type(bakery_version) - ) + f"Expected bakery_version to be a int, received: {type(bakery_version)}" ) if offer_urls is not None and not isinstance(offer_urls, (bytes, str, list)): raise Exception( - "Expected offer_urls to be a Sequence, received: {}".format( - type(offer_urls) - ) + f"Expected offer_urls to be a Sequence, received: {type(offer_urls)}" ) # map input types to rpc msg @@ -930,15 +908,13 @@ class SubnetsFacade(Type): @ReturnMapping(ZoneResults) async def AllZones(self): - """ - AllZones returns all availability zones known to Juju. If a + """AllZones returns all availability zones known to Juju. If a zone is unusable, unavailable, or deprecated the Available field will be false. Returns -> ZoneResults """ - # map input types to rpc msg _params = dict() msg = dict(type="Subnets", request="AllZones", version=5, params=_params) @@ -948,8 +924,7 @@ async def AllZones(self): @ReturnMapping(ListSubnetsResults) async def ListSubnets(self, space_tag=None, zone=None): - """ - ListSubnets returns the matching subnets after applying + """ListSubnets returns the matching subnets after applying optional filters. space_tag : str @@ -958,13 +933,11 @@ async def ListSubnets(self, space_tag=None, zone=None): """ if space_tag is not None and not isinstance(space_tag, (bytes, str)): raise Exception( - "Expected space_tag to be a str, received: {}".format(type(space_tag)) + f"Expected space_tag to be a str, received: {type(space_tag)}" ) if zone is not None and not isinstance(zone, (bytes, str)): - raise Exception( - "Expected zone to be a str, received: {}".format(type(zone)) - ) + raise Exception(f"Expected zone to be a str, received: {type(zone)}") # map input types to rpc msg _params = dict() @@ -976,16 +949,13 @@ async def ListSubnets(self, space_tag=None, zone=None): @ReturnMapping(SubnetsResults) async def SubnetsByCIDR(self, cidrs=None): - """ - SubnetsByCIDR returns the collection of subnets matching each CIDR in the input. + """SubnetsByCIDR returns the collection of subnets matching each CIDR in the input. cidrs : typing.Sequence[str] Returns -> SubnetsResults """ if cidrs is not None and not isinstance(cidrs, (bytes, str, list)): - raise Exception( - "Expected cidrs to be a Sequence, received: {}".format(type(cidrs)) - ) + raise Exception(f"Expected cidrs to be a Sequence, received: {type(cidrs)}") # map input types to rpc msg _params = dict() diff --git a/juju/client/_client6.py b/juju/client/_client6.py index f93652338..aebf0f98b 100644 --- a/juju/client/_client6.py +++ b/juju/client/_client6.py @@ -1,8 +1,8 @@ # DO NOT CHANGE THIS FILE! This file is auto-generated by facade.py. # Changes will be overwritten/lost when the file is regenerated. -from juju.client.facade import Type, ReturnMapping from juju.client._definitions import * +from juju.client.facade import ReturnMapping, Type class BundleFacade(Type): @@ -161,8 +161,7 @@ class BundleFacade(Type): @ReturnMapping(StringResult) async def ExportBundle(self, include_charm_defaults=None, include_series=None): - """ - ExportBundle exports the current model configuration as bundle. + """ExportBundle exports the current model configuration as bundle. include_charm_defaults : bool include_series : bool @@ -172,16 +171,12 @@ async def ExportBundle(self, include_charm_defaults=None, include_series=None): include_charm_defaults, bool ): raise Exception( - "Expected include_charm_defaults to be a bool, received: {}".format( - type(include_charm_defaults) - ) + f"Expected include_charm_defaults to be a bool, received: {type(include_charm_defaults)}" ) if include_series is not None and not isinstance(include_series, bool): raise Exception( - "Expected include_series to be a bool, received: {}".format( - type(include_series) - ) + f"Expected include_series to be a bool, received: {type(include_series)}" ) # map input types to rpc msg @@ -194,8 +189,7 @@ async def ExportBundle(self, include_charm_defaults=None, include_series=None): @ReturnMapping(BundleChangesResults) async def GetChanges(self, bundleurl=None, yaml=None): - """ - GetChanges returns the list of changes required to deploy the given bundle + """GetChanges returns the list of changes required to deploy the given bundle data. The changes are sorted by requirements, so that they can be applied in order. GetChanges has been superseded in favour of GetChangesMapArgs. It's @@ -208,13 +202,11 @@ async def GetChanges(self, bundleurl=None, yaml=None): """ if bundleurl is not None and not isinstance(bundleurl, (bytes, str)): raise Exception( - "Expected bundleurl to be a str, received: {}".format(type(bundleurl)) + f"Expected bundleurl to be a str, received: {type(bundleurl)}" ) if yaml is not None and not isinstance(yaml, (bytes, str)): - raise Exception( - "Expected yaml to be a str, received: {}".format(type(yaml)) - ) + raise Exception(f"Expected yaml to be a str, received: {type(yaml)}") # map input types to rpc msg _params = dict() @@ -226,8 +218,7 @@ async def GetChanges(self, bundleurl=None, yaml=None): @ReturnMapping(BundleChangesMapArgsResults) async def GetChangesMapArgs(self, bundleurl=None, yaml=None): - """ - GetChangesMapArgs returns the list of changes required to deploy the given + """GetChangesMapArgs returns the list of changes required to deploy the given bundle data. The changes are sorted by requirements, so that they can be applied in order. V4 GetChangesMapArgs is not supported on anything less than v4 @@ -238,13 +229,11 @@ async def GetChangesMapArgs(self, bundleurl=None, yaml=None): """ if bundleurl is not None and not isinstance(bundleurl, (bytes, str)): raise Exception( - "Expected bundleurl to be a str, received: {}".format(type(bundleurl)) + f"Expected bundleurl to be a str, received: {type(bundleurl)}" ) if yaml is not None and not isinstance(yaml, (bytes, str)): - raise Exception( - "Expected yaml to be a str, received: {}".format(type(yaml)) - ) + raise Exception(f"Expected yaml to be a str, received: {type(yaml)}") # map input types to rpc msg _params = dict() @@ -939,8 +928,7 @@ class CharmsFacade(Type): @ReturnMapping(CharmOriginResult) async def AddCharm(self, charm_origin=None, force=None, url=None): - """ - AddCharm adds the given charm URL (which must include revision) to the + """AddCharm adds the given charm URL (which must include revision) to the environment, if it does not exist yet. Local charms are not supported, only charm store and charm hub URLs. See also AddLocalCharm(). @@ -953,18 +941,14 @@ async def AddCharm(self, charm_origin=None, force=None, url=None): charm_origin, (dict, CharmOrigin) ): raise Exception( - "Expected charm_origin to be a CharmOrigin, received: {}".format( - type(charm_origin) - ) + f"Expected charm_origin to be a CharmOrigin, received: {type(charm_origin)}" ) if force is not None and not isinstance(force, bool): - raise Exception( - "Expected force to be a bool, received: {}".format(type(force)) - ) + raise Exception(f"Expected force to be a bool, received: {type(force)}") if url is not None and not isinstance(url, (bytes, str)): - raise Exception("Expected url to be a str, received: {}".format(type(url))) + raise Exception(f"Expected url to be a str, received: {type(url)}") # map input types to rpc msg _params = dict() @@ -977,14 +961,13 @@ async def AddCharm(self, charm_origin=None, force=None, url=None): @ReturnMapping(Charm) async def CharmInfo(self, url=None): - """ - CharmInfo returns information about the requested charm. + """CharmInfo returns information about the requested charm. url : str Returns -> Charm """ if url is not None and not isinstance(url, (bytes, str)): - raise Exception("Expected url to be a str, received: {}".format(type(url))) + raise Exception(f"Expected url to be a str, received: {type(url)}") # map input types to rpc msg _params = dict() @@ -995,8 +978,7 @@ async def CharmInfo(self, url=None): @ReturnMapping(ErrorResults) async def CheckCharmPlacement(self, placements=None): - """ - CheckCharmPlacement checks if a charm is allowed to be placed with in a + """CheckCharmPlacement checks if a charm is allowed to be placed with in a given application. placements : typing.Sequence[~ApplicationCharmPlacement] @@ -1004,9 +986,7 @@ async def CheckCharmPlacement(self, placements=None): """ if placements is not None and not isinstance(placements, (bytes, str, list)): raise Exception( - "Expected placements to be a Sequence, received: {}".format( - type(placements) - ) + f"Expected placements to be a Sequence, received: {type(placements)}" ) # map input types to rpc msg @@ -1020,8 +1000,7 @@ async def CheckCharmPlacement(self, placements=None): @ReturnMapping(DownloadInfoResults) async def GetDownloadInfos(self, entities=None): - """ - GetDownloadInfos attempts to get the bundle corresponding to the charm url + """GetDownloadInfos attempts to get the bundle corresponding to the charm url and origin. entities : typing.Sequence[~CharmURLAndOrigin] @@ -1029,9 +1008,7 @@ async def GetDownloadInfos(self, entities=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1043,14 +1020,13 @@ async def GetDownloadInfos(self, entities=None): @ReturnMapping(IsMeteredResult) async def IsMetered(self, url=None): - """ - IsMetered returns whether or not the charm is metered. + """IsMetered returns whether or not the charm is metered. url : str Returns -> IsMeteredResult """ if url is not None and not isinstance(url, (bytes, str)): - raise Exception("Expected url to be a str, received: {}".format(type(url))) + raise Exception(f"Expected url to be a str, received: {type(url)}") # map input types to rpc msg _params = dict() @@ -1061,8 +1037,7 @@ async def IsMetered(self, url=None): @ReturnMapping(CharmsListResult) async def List(self, names=None): - """ - List returns a list of charm URLs currently in the state. + """List returns a list of charm URLs currently in the state. If supplied parameter contains any names, the result will be filtered to return only the charms with supplied names. @@ -1070,9 +1045,7 @@ async def List(self, names=None): Returns -> CharmsListResult """ if names is not None and not isinstance(names, (bytes, str, list)): - raise Exception( - "Expected names to be a Sequence, received: {}".format(type(names)) - ) + raise Exception(f"Expected names to be a Sequence, received: {type(names)}") # map input types to rpc msg _params = dict() @@ -1083,17 +1056,14 @@ async def List(self, names=None): @ReturnMapping(CharmResourcesResults) async def ListCharmResources(self, entities=None): - """ - ListCharmResources returns a series of resources for a given charm. + """ListCharmResources returns a series of resources for a given charm. entities : typing.Sequence[~CharmURLAndOrigin] Returns -> CharmResourcesResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1107,8 +1077,7 @@ async def ListCharmResources(self, entities=None): @ReturnMapping(ResolveCharmWithChannelResults) async def ResolveCharms(self, macaroon=None, resolve=None): - """ - ResolveCharms resolves the given charm URLs with an optionally specified + """ResolveCharms resolves the given charm URLs with an optionally specified preferred channel. Channel provided via CharmOrigin. macaroon : Macaroon @@ -1117,14 +1086,12 @@ async def ResolveCharms(self, macaroon=None, resolve=None): """ if macaroon is not None and not isinstance(macaroon, (dict, Macaroon)): raise Exception( - "Expected macaroon to be a Macaroon, received: {}".format( - type(macaroon) - ) + f"Expected macaroon to be a Macaroon, received: {type(macaroon)}" ) if resolve is not None and not isinstance(resolve, (bytes, str, list)): raise Exception( - "Expected resolve to be a Sequence, received: {}".format(type(resolve)) + f"Expected resolve to be a Sequence, received: {type(resolve)}" ) # map input types to rpc msg @@ -1778,8 +1745,7 @@ class ClientFacade(Type): async def FindTools( self, agentstream=None, arch=None, major=None, number=None, os_type=None ): - """ - FindTools returns a List containing all tools matching the given parameters. + """FindTools returns a List containing all tools matching the given parameters. TODO(juju 3.1) - remove, used by 2.9 client only agentstream : str @@ -1791,30 +1757,20 @@ async def FindTools( """ if agentstream is not None and not isinstance(agentstream, (bytes, str)): raise Exception( - "Expected agentstream to be a str, received: {}".format( - type(agentstream) - ) + f"Expected agentstream to be a str, received: {type(agentstream)}" ) if arch is not None and not isinstance(arch, (bytes, str)): - raise Exception( - "Expected arch to be a str, received: {}".format(type(arch)) - ) + raise Exception(f"Expected arch to be a str, received: {type(arch)}") if major is not None and not isinstance(major, int): - raise Exception( - "Expected major to be a int, received: {}".format(type(major)) - ) + raise Exception(f"Expected major to be a int, received: {type(major)}") if number is not None and not isinstance(number, (dict, Number)): - raise Exception( - "Expected number to be a Number, received: {}".format(type(number)) - ) + raise Exception(f"Expected number to be a Number, received: {type(number)}") if os_type is not None and not isinstance(os_type, (bytes, str)): - raise Exception( - "Expected os_type to be a str, received: {}".format(type(os_type)) - ) + raise Exception(f"Expected os_type to be a str, received: {type(os_type)}") # map input types to rpc msg _params = dict() @@ -1829,17 +1785,14 @@ async def FindTools( @ReturnMapping(FullStatus) async def FullStatus(self, patterns=None): - """ - FullStatus gives the information needed for juju status over the api + """FullStatus gives the information needed for juju status over the api patterns : typing.Sequence[str] Returns -> FullStatus """ if patterns is not None and not isinstance(patterns, (bytes, str, list)): raise Exception( - "Expected patterns to be a Sequence, received: {}".format( - type(patterns) - ) + f"Expected patterns to be a Sequence, received: {type(patterns)}" ) # map input types to rpc msg @@ -1851,17 +1804,14 @@ async def FullStatus(self, patterns=None): @ReturnMapping(StatusHistoryResults) async def StatusHistory(self, requests=None): - """ - StatusHistory returns a slice of past statuses for several entities. + """StatusHistory returns a slice of past statuses for several entities. requests : typing.Sequence[~StatusHistoryRequest] Returns -> StatusHistoryResults """ if requests is not None and not isinstance(requests, (bytes, str, list)): raise Exception( - "Expected requests to be a Sequence, received: {}".format( - type(requests) - ) + f"Expected requests to be a Sequence, received: {type(requests)}" ) # map input types to rpc msg @@ -1873,13 +1823,10 @@ async def StatusHistory(self, requests=None): @ReturnMapping(AllWatcherId) async def WatchAll(self): - """ - WatchAll initiates a watcher for entities in the connected model. - + """WatchAll initiates a watcher for entities in the connected model. Returns -> AllWatcherId """ - # map input types to rpc msg _params = dict() msg = dict(type="Client", request="WatchAll", version=6, params=_params) @@ -2222,8 +2169,7 @@ class SpacesFacade(Type): @ReturnMapping(ErrorResults) async def CreateSpaces(self, spaces=None): - """ - CreateSpaces creates a new Juju network space, associating the + """CreateSpaces creates a new Juju network space, associating the specified subnets with it (optional; can be empty). spaces : typing.Sequence[~CreateSpaceParams] @@ -2231,7 +2177,7 @@ async def CreateSpaces(self, spaces=None): """ if spaces is not None and not isinstance(spaces, (bytes, str, list)): raise Exception( - "Expected spaces to be a Sequence, received: {}".format(type(spaces)) + f"Expected spaces to be a Sequence, received: {type(spaces)}" ) # map input types to rpc msg @@ -2243,13 +2189,10 @@ async def CreateSpaces(self, spaces=None): @ReturnMapping(ListSpacesResults) async def ListSpaces(self): - """ - ListSpaces lists all the available spaces and their associated subnets. - + """ListSpaces lists all the available spaces and their associated subnets. Returns -> ListSpacesResults """ - # map input types to rpc msg _params = dict() msg = dict(type="Spaces", request="ListSpaces", version=6, params=_params) @@ -2259,16 +2202,13 @@ async def ListSpaces(self): @ReturnMapping(MoveSubnetsResults) async def MoveSubnets(self, args=None): - """ - MoveSubnets ensures that the input subnets are in the input space. + """MoveSubnets ensures that the input subnets are in the input space. args : typing.Sequence[~MoveSubnetsParam] Returns -> MoveSubnetsResults """ if args is not None and not isinstance(args, (bytes, str, list)): - raise Exception( - "Expected args to be a Sequence, received: {}".format(type(args)) - ) + raise Exception(f"Expected args to be a Sequence, received: {type(args)}") # map input types to rpc msg _params = dict() @@ -2279,13 +2219,10 @@ async def MoveSubnets(self, args=None): @ReturnMapping(None) async def ReloadSpaces(self): - """ - ReloadSpaces refreshes spaces from substrate - + """ReloadSpaces refreshes spaces from substrate Returns -> None """ - # map input types to rpc msg _params = dict() msg = dict(type="Spaces", request="ReloadSpaces", version=6, params=_params) @@ -2295,8 +2232,7 @@ async def ReloadSpaces(self): @ReturnMapping(RemoveSpaceResults) async def RemoveSpace(self, space_param=None): - """ - RemoveSpace removes a space. + """RemoveSpace removes a space. Returns SpaceResults if entities/settings are found which makes the deletion not possible. space_param : typing.Sequence[~RemoveSpaceParam] @@ -2304,9 +2240,7 @@ async def RemoveSpace(self, space_param=None): """ if space_param is not None and not isinstance(space_param, (bytes, str, list)): raise Exception( - "Expected space_param to be a Sequence, received: {}".format( - type(space_param) - ) + f"Expected space_param to be a Sequence, received: {type(space_param)}" ) # map input types to rpc msg @@ -2318,15 +2252,14 @@ async def RemoveSpace(self, space_param=None): @ReturnMapping(ErrorResults) async def RenameSpace(self, changes=None): - """ - RenameSpace renames a space. + """RenameSpace renames a space. changes : typing.Sequence[~RenameSpaceParams] Returns -> ErrorResults """ if changes is not None and not isinstance(changes, (bytes, str, list)): raise Exception( - "Expected changes to be a Sequence, received: {}".format(type(changes)) + f"Expected changes to be a Sequence, received: {type(changes)}" ) # map input types to rpc msg @@ -2338,17 +2271,14 @@ async def RenameSpace(self, changes=None): @ReturnMapping(ShowSpaceResults) async def ShowSpace(self, entities=None): - """ - ShowSpace shows the spaces for a set of given entities. + """ShowSpace shows the spaces for a set of given entities. entities : typing.Sequence[~Entity] Returns -> ShowSpaceResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -3141,8 +3071,7 @@ class StorageFacade(Type): @ReturnMapping(AddStorageResults) async def AddToUnit(self, storages=None): - """ - AddToUnit validates and creates additional storage instances for units. + """AddToUnit validates and creates additional storage instances for units. A "CHANGE" block can block this operation. storages : typing.Sequence[~StorageAddParams] @@ -3150,9 +3079,7 @@ async def AddToUnit(self, storages=None): """ if storages is not None and not isinstance(storages, (bytes, str, list)): raise Exception( - "Expected storages to be a Sequence, received: {}".format( - type(storages) - ) + f"Expected storages to be a Sequence, received: {type(storages)}" ) # map input types to rpc msg @@ -3164,17 +3091,14 @@ async def AddToUnit(self, storages=None): @ReturnMapping(ErrorResults) async def Attach(self, ids=None): - """ - Attach attaches existing storage instances to units. + """Attach attaches existing storage instances to units. A "CHANGE" block can block this operation. ids : typing.Sequence[~StorageAttachmentId] Returns -> ErrorResults """ if ids is not None and not isinstance(ids, (bytes, str, list)): - raise Exception( - "Expected ids to be a Sequence, received: {}".format(type(ids)) - ) + raise Exception(f"Expected ids to be a Sequence, received: {type(ids)}") # map input types to rpc msg _params = dict() @@ -3185,16 +3109,13 @@ async def Attach(self, ids=None): @ReturnMapping(ErrorResults) async def CreatePool(self, pools=None): - """ - CreatePool creates a new pool with specified parameters. + """CreatePool creates a new pool with specified parameters. pools : typing.Sequence[~StoragePool] Returns -> ErrorResults """ if pools is not None and not isinstance(pools, (bytes, str, list)): - raise Exception( - "Expected pools to be a Sequence, received: {}".format(type(pools)) - ) + raise Exception(f"Expected pools to be a Sequence, received: {type(pools)}") # map input types to rpc msg _params = dict() @@ -3205,8 +3126,7 @@ async def CreatePool(self, pools=None): @ReturnMapping(ErrorResults) async def DetachStorage(self, force=None, ids=None, max_wait=None): - """ - DetachStorage sets the specified storage attachments to Dying, unless they are + """DetachStorage sets the specified storage attachments to Dying, unless they are already Dying or Dead. Any associated, persistent storage will remain alive. This call can be forced. @@ -3216,20 +3136,16 @@ async def DetachStorage(self, force=None, ids=None, max_wait=None): Returns -> ErrorResults """ if force is not None and not isinstance(force, bool): - raise Exception( - "Expected force to be a bool, received: {}".format(type(force)) - ) + raise Exception(f"Expected force to be a bool, received: {type(force)}") if ids is not None and not isinstance(ids, (dict, StorageAttachmentIds)): raise Exception( - "Expected ids to be a StorageAttachmentIds, received: {}".format( - type(ids) - ) + f"Expected ids to be a StorageAttachmentIds, received: {type(ids)}" ) if max_wait is not None and not isinstance(max_wait, int): raise Exception( - "Expected max_wait to be a int, received: {}".format(type(max_wait)) + f"Expected max_wait to be a int, received: {type(max_wait)}" ) # map input types to rpc msg @@ -3243,8 +3159,7 @@ async def DetachStorage(self, force=None, ids=None, max_wait=None): @ReturnMapping(ImportStorageResults) async def Import(self, storage=None): - """ - Import imports existing storage into the model. + """Import imports existing storage into the model. A "CHANGE" block can block this operation. storage : typing.Sequence[~ImportStorageParams] @@ -3252,7 +3167,7 @@ async def Import(self, storage=None): """ if storage is not None and not isinstance(storage, (bytes, str, list)): raise Exception( - "Expected storage to be a Sequence, received: {}".format(type(storage)) + f"Expected storage to be a Sequence, received: {type(storage)}" ) # map input types to rpc msg @@ -3264,8 +3179,7 @@ async def Import(self, storage=None): @ReturnMapping(FilesystemDetailsListResults) async def ListFilesystems(self, filters=None): - """ - ListFilesystems returns a list of filesystems in the environment matching + """ListFilesystems returns a list of filesystems in the environment matching the provided filter. Each result describes a filesystem in detail, including the filesystem's attachments. @@ -3274,7 +3188,7 @@ async def ListFilesystems(self, filters=None): """ if filters is not None and not isinstance(filters, (bytes, str, list)): raise Exception( - "Expected filters to be a Sequence, received: {}".format(type(filters)) + f"Expected filters to be a Sequence, received: {type(filters)}" ) # map input types to rpc msg @@ -3286,8 +3200,7 @@ async def ListFilesystems(self, filters=None): @ReturnMapping(StoragePoolsResults) async def ListPools(self, filters=None): - """ - ListPools returns a list of pools. + """ListPools returns a list of pools. If filter is provided, returned list only contains pools that match the filter. Pools can be filtered on names and provider types. @@ -3301,7 +3214,7 @@ async def ListPools(self, filters=None): """ if filters is not None and not isinstance(filters, (bytes, str, list)): raise Exception( - "Expected filters to be a Sequence, received: {}".format(type(filters)) + f"Expected filters to be a Sequence, received: {type(filters)}" ) # map input types to rpc msg @@ -3313,15 +3226,14 @@ async def ListPools(self, filters=None): @ReturnMapping(StorageDetailsListResults) async def ListStorageDetails(self, filters=None): - """ - ListStorageDetails returns storage matching a filter. + """ListStorageDetails returns storage matching a filter. filters : typing.Sequence[~StorageFilter] Returns -> StorageDetailsListResults """ if filters is not None and not isinstance(filters, (bytes, str, list)): raise Exception( - "Expected filters to be a Sequence, received: {}".format(type(filters)) + f"Expected filters to be a Sequence, received: {type(filters)}" ) # map input types to rpc msg @@ -3335,8 +3247,7 @@ async def ListStorageDetails(self, filters=None): @ReturnMapping(VolumeDetailsListResults) async def ListVolumes(self, filters=None): - """ - ListVolumes lists volumes with the given filters. Each filter produces + """ListVolumes lists volumes with the given filters. Each filter produces an independent list of volumes, or an error if the filter is invalid or the volumes could not be listed. @@ -3345,7 +3256,7 @@ async def ListVolumes(self, filters=None): """ if filters is not None and not isinstance(filters, (bytes, str, list)): raise Exception( - "Expected filters to be a Sequence, received: {}".format(type(filters)) + f"Expected filters to be a Sequence, received: {type(filters)}" ) # map input types to rpc msg @@ -3357,8 +3268,7 @@ async def ListVolumes(self, filters=None): @ReturnMapping(ErrorResults) async def Remove(self, storage=None): - """ - Remove sets the specified storage entities to Dying, unless they are + """Remove sets the specified storage entities to Dying, unless they are already Dying or Dead, such that the storage will eventually be removed from the model. If the arguments specify that the storage should be destroyed, then the associated cloud storage will be destroyed first; @@ -3369,7 +3279,7 @@ async def Remove(self, storage=None): """ if storage is not None and not isinstance(storage, (bytes, str, list)): raise Exception( - "Expected storage to be a Sequence, received: {}".format(type(storage)) + f"Expected storage to be a Sequence, received: {type(storage)}" ) # map input types to rpc msg @@ -3381,16 +3291,13 @@ async def Remove(self, storage=None): @ReturnMapping(ErrorResults) async def RemovePool(self, pools=None): - """ - RemovePool deletes the named pool + """RemovePool deletes the named pool pools : typing.Sequence[~StoragePoolDeleteArg] Returns -> ErrorResults """ if pools is not None and not isinstance(pools, (bytes, str, list)): - raise Exception( - "Expected pools to be a Sequence, received: {}".format(type(pools)) - ) + raise Exception(f"Expected pools to be a Sequence, received: {type(pools)}") # map input types to rpc msg _params = dict() @@ -3401,8 +3308,7 @@ async def RemovePool(self, pools=None): @ReturnMapping(StorageDetailsResults) async def StorageDetails(self, entities=None): - """ - StorageDetails retrieves and returns detailed information about desired + """StorageDetails retrieves and returns detailed information about desired storage identified by supplied tags. If specified storage cannot be retrieved, individual error is returned instead of storage information. @@ -3411,9 +3317,7 @@ async def StorageDetails(self, entities=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -3425,16 +3329,13 @@ async def StorageDetails(self, entities=None): @ReturnMapping(ErrorResults) async def UpdatePool(self, pools=None): - """ - UpdatePool deletes the named pool + """UpdatePool deletes the named pool pools : typing.Sequence[~StoragePool] Returns -> ErrorResults """ if pools is not None and not isinstance(pools, (bytes, str, list)): - raise Exception( - "Expected pools to be a Sequence, received: {}".format(type(pools)) - ) + raise Exception(f"Expected pools to be a Sequence, received: {type(pools)}") # map input types to rpc msg _params = dict() diff --git a/juju/client/_client7.py b/juju/client/_client7.py index bdf738b4c..f181971a9 100644 --- a/juju/client/_client7.py +++ b/juju/client/_client7.py @@ -1,8 +1,8 @@ # DO NOT CHANGE THIS FILE! This file is auto-generated by facade.py. # Changes will be overwritten/lost when the file is regenerated. -from juju.client.facade import Type, ReturnMapping from juju.client._definitions import * +from juju.client.facade import ReturnMapping, Type class ActionFacade(Type): @@ -351,8 +351,7 @@ class ActionFacade(Type): @ReturnMapping(ActionResults) async def Actions(self, entities=None): - """ - Actions takes a list of ActionTags, and returns the full Action for + """Actions takes a list of ActionTags, and returns the full Action for each ID. entities : typing.Sequence[~Entity] @@ -360,9 +359,7 @@ async def Actions(self, entities=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -374,8 +371,7 @@ async def Actions(self, entities=None): @ReturnMapping(ApplicationsCharmActionsResults) async def ApplicationsCharmsActions(self, entities=None): - """ - ApplicationsCharmsActions returns a slice of charm Actions for a slice of + """ApplicationsCharmsActions returns a slice of charm Actions for a slice of services. entities : typing.Sequence[~Entity] @@ -383,9 +379,7 @@ async def ApplicationsCharmsActions(self, entities=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -402,17 +396,14 @@ async def ApplicationsCharmsActions(self, entities=None): @ReturnMapping(ActionResults) async def Cancel(self, entities=None): - """ - Cancel attempts to cancel enqueued Actions from running. + """Cancel attempts to cancel enqueued Actions from running. entities : typing.Sequence[~Entity] Returns -> ActionResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -424,8 +415,7 @@ async def Cancel(self, entities=None): @ReturnMapping(EnqueuedActions) async def EnqueueOperation(self, actions=None): - """ - EnqueueOperation takes a list of Actions and queues them up to be executed as + """EnqueueOperation takes a list of Actions and queues them up to be executed as an operation, each action running as a task on the designated ActionReceiver. We return the ID of the overall operation and each individual task. @@ -434,7 +424,7 @@ async def EnqueueOperation(self, actions=None): """ if actions is not None and not isinstance(actions, (bytes, str, list)): raise Exception( - "Expected actions to be a Sequence, received: {}".format(type(actions)) + f"Expected actions to be a Sequence, received: {type(actions)}" ) # map input types to rpc msg @@ -455,8 +445,7 @@ async def ListOperations( status=None, units=None, ): - """ - ListOperations fetches the called actions for specified apps/units. + """ListOperations fetches the called actions for specified apps/units. actions : typing.Sequence[str] applications : typing.Sequence[str] @@ -469,44 +458,34 @@ async def ListOperations( """ if actions is not None and not isinstance(actions, (bytes, str, list)): raise Exception( - "Expected actions to be a Sequence, received: {}".format(type(actions)) + f"Expected actions to be a Sequence, received: {type(actions)}" ) if applications is not None and not isinstance( applications, (bytes, str, list) ): raise Exception( - "Expected applications to be a Sequence, received: {}".format( - type(applications) - ) + f"Expected applications to be a Sequence, received: {type(applications)}" ) if limit is not None and not isinstance(limit, int): - raise Exception( - "Expected limit to be a int, received: {}".format(type(limit)) - ) + raise Exception(f"Expected limit to be a int, received: {type(limit)}") if machines is not None and not isinstance(machines, (bytes, str, list)): raise Exception( - "Expected machines to be a Sequence, received: {}".format( - type(machines) - ) + f"Expected machines to be a Sequence, received: {type(machines)}" ) if offset is not None and not isinstance(offset, int): - raise Exception( - "Expected offset to be a int, received: {}".format(type(offset)) - ) + raise Exception(f"Expected offset to be a int, received: {type(offset)}") if status is not None and not isinstance(status, (bytes, str, list)): raise Exception( - "Expected status to be a Sequence, received: {}".format(type(status)) + f"Expected status to be a Sequence, received: {type(status)}" ) if units is not None and not isinstance(units, (bytes, str, list)): - raise Exception( - "Expected units to be a Sequence, received: {}".format(type(units)) - ) + raise Exception(f"Expected units to be a Sequence, received: {type(units)}") # map input types to rpc msg _params = dict() @@ -523,17 +502,14 @@ async def ListOperations( @ReturnMapping(OperationResults) async def Operations(self, entities=None): - """ - Operations fetches the specified operation ids. + """Operations fetches the specified operation ids. entities : typing.Sequence[~Entity] Returns -> OperationResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -555,8 +531,7 @@ async def Run( units=None, workload_context=None, ): - """ - Run the commands specified on the machines identified through the + """Run the commands specified on the machines identified through the list of machines, units and services. applications : typing.Sequence[str] @@ -573,52 +548,40 @@ async def Run( applications, (bytes, str, list) ): raise Exception( - "Expected applications to be a Sequence, received: {}".format( - type(applications) - ) + f"Expected applications to be a Sequence, received: {type(applications)}" ) if commands is not None and not isinstance(commands, (bytes, str)): raise Exception( - "Expected commands to be a str, received: {}".format(type(commands)) + f"Expected commands to be a str, received: {type(commands)}" ) if execution_group is not None and not isinstance( execution_group, (bytes, str) ): raise Exception( - "Expected execution_group to be a str, received: {}".format( - type(execution_group) - ) + f"Expected execution_group to be a str, received: {type(execution_group)}" ) if machines is not None and not isinstance(machines, (bytes, str, list)): raise Exception( - "Expected machines to be a Sequence, received: {}".format( - type(machines) - ) + f"Expected machines to be a Sequence, received: {type(machines)}" ) if parallel is not None and not isinstance(parallel, bool): raise Exception( - "Expected parallel to be a bool, received: {}".format(type(parallel)) + f"Expected parallel to be a bool, received: {type(parallel)}" ) if timeout is not None and not isinstance(timeout, int): - raise Exception( - "Expected timeout to be a int, received: {}".format(type(timeout)) - ) + raise Exception(f"Expected timeout to be a int, received: {type(timeout)}") if units is not None and not isinstance(units, (bytes, str, list)): - raise Exception( - "Expected units to be a Sequence, received: {}".format(type(units)) - ) + raise Exception(f"Expected units to be a Sequence, received: {type(units)}") if workload_context is not None and not isinstance(workload_context, bool): raise Exception( - "Expected workload_context to be a bool, received: {}".format( - type(workload_context) - ) + f"Expected workload_context to be a bool, received: {type(workload_context)}" ) # map input types to rpc msg @@ -647,8 +610,7 @@ async def RunOnAllMachines( units=None, workload_context=None, ): - """ - RunOnAllMachines attempts to run the specified command on all the machines. + """RunOnAllMachines attempts to run the specified command on all the machines. applications : typing.Sequence[str] commands : str @@ -664,52 +626,40 @@ async def RunOnAllMachines( applications, (bytes, str, list) ): raise Exception( - "Expected applications to be a Sequence, received: {}".format( - type(applications) - ) + f"Expected applications to be a Sequence, received: {type(applications)}" ) if commands is not None and not isinstance(commands, (bytes, str)): raise Exception( - "Expected commands to be a str, received: {}".format(type(commands)) + f"Expected commands to be a str, received: {type(commands)}" ) if execution_group is not None and not isinstance( execution_group, (bytes, str) ): raise Exception( - "Expected execution_group to be a str, received: {}".format( - type(execution_group) - ) + f"Expected execution_group to be a str, received: {type(execution_group)}" ) if machines is not None and not isinstance(machines, (bytes, str, list)): raise Exception( - "Expected machines to be a Sequence, received: {}".format( - type(machines) - ) + f"Expected machines to be a Sequence, received: {type(machines)}" ) if parallel is not None and not isinstance(parallel, bool): raise Exception( - "Expected parallel to be a bool, received: {}".format(type(parallel)) + f"Expected parallel to be a bool, received: {type(parallel)}" ) if timeout is not None and not isinstance(timeout, int): - raise Exception( - "Expected timeout to be a int, received: {}".format(type(timeout)) - ) + raise Exception(f"Expected timeout to be a int, received: {type(timeout)}") if units is not None and not isinstance(units, (bytes, str, list)): - raise Exception( - "Expected units to be a Sequence, received: {}".format(type(units)) - ) + raise Exception(f"Expected units to be a Sequence, received: {type(units)}") if workload_context is not None and not isinstance(workload_context, bool): raise Exception( - "Expected workload_context to be a bool, received: {}".format( - type(workload_context) - ) + f"Expected workload_context to be a bool, received: {type(workload_context)}" ) # map input types to rpc msg @@ -728,17 +678,14 @@ async def RunOnAllMachines( @ReturnMapping(StringsWatchResults) async def WatchActionsProgress(self, entities=None): - """ - WatchActionsProgress creates a watcher that reports on action log messages. + """WatchActionsProgress creates a watcher that reports on action log messages. entities : typing.Sequence[~Entity] Returns -> StringsWatchResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1445,8 +1392,7 @@ class CharmsFacade(Type): @ReturnMapping(CharmOriginResult) async def AddCharm(self, charm_origin=None, force=None, url=None): - """ - AddCharm adds the given charm URL (which must include revision) to the + """AddCharm adds the given charm URL (which must include revision) to the environment, if it does not exist yet. Local charms are not supported, only charm store and charm hub URLs. See also AddLocalCharm(). @@ -1459,18 +1405,14 @@ async def AddCharm(self, charm_origin=None, force=None, url=None): charm_origin, (dict, CharmOrigin) ): raise Exception( - "Expected charm_origin to be a CharmOrigin, received: {}".format( - type(charm_origin) - ) + f"Expected charm_origin to be a CharmOrigin, received: {type(charm_origin)}" ) if force is not None and not isinstance(force, bool): - raise Exception( - "Expected force to be a bool, received: {}".format(type(force)) - ) + raise Exception(f"Expected force to be a bool, received: {type(force)}") if url is not None and not isinstance(url, (bytes, str)): - raise Exception("Expected url to be a str, received: {}".format(type(url))) + raise Exception(f"Expected url to be a str, received: {type(url)}") # map input types to rpc msg _params = dict() @@ -1483,14 +1425,13 @@ async def AddCharm(self, charm_origin=None, force=None, url=None): @ReturnMapping(Charm) async def CharmInfo(self, url=None): - """ - CharmInfo returns information about the requested charm. + """CharmInfo returns information about the requested charm. url : str Returns -> Charm """ if url is not None and not isinstance(url, (bytes, str)): - raise Exception("Expected url to be a str, received: {}".format(type(url))) + raise Exception(f"Expected url to be a str, received: {type(url)}") # map input types to rpc msg _params = dict() @@ -1501,8 +1442,7 @@ async def CharmInfo(self, url=None): @ReturnMapping(ErrorResults) async def CheckCharmPlacement(self, placements=None): - """ - CheckCharmPlacement checks if a charm is allowed to be placed with in a + """CheckCharmPlacement checks if a charm is allowed to be placed with in a given application. placements : typing.Sequence[~ApplicationCharmPlacement] @@ -1510,9 +1450,7 @@ async def CheckCharmPlacement(self, placements=None): """ if placements is not None and not isinstance(placements, (bytes, str, list)): raise Exception( - "Expected placements to be a Sequence, received: {}".format( - type(placements) - ) + f"Expected placements to be a Sequence, received: {type(placements)}" ) # map input types to rpc msg @@ -1526,8 +1464,7 @@ async def CheckCharmPlacement(self, placements=None): @ReturnMapping(DownloadInfoResults) async def GetDownloadInfos(self, entities=None): - """ - GetDownloadInfos attempts to get the bundle corresponding to the charm url + """GetDownloadInfos attempts to get the bundle corresponding to the charm url and origin. entities : typing.Sequence[~CharmURLAndOrigin] @@ -1535,9 +1472,7 @@ async def GetDownloadInfos(self, entities=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1549,8 +1484,7 @@ async def GetDownloadInfos(self, entities=None): @ReturnMapping(IsMeteredResult) async def IsMetered(self, url=None): - """ - IsMetered returns whether or not the charm is metered. + """IsMetered returns whether or not the charm is metered. TODO (cderici) only used for metered charms in cmd MeteredDeployAPI, kept for client compatibility, remove in juju 4.0 @@ -1558,7 +1492,7 @@ async def IsMetered(self, url=None): Returns -> IsMeteredResult """ if url is not None and not isinstance(url, (bytes, str)): - raise Exception("Expected url to be a str, received: {}".format(type(url))) + raise Exception(f"Expected url to be a str, received: {type(url)}") # map input types to rpc msg _params = dict() @@ -1569,8 +1503,7 @@ async def IsMetered(self, url=None): @ReturnMapping(CharmsListResult) async def List(self, names=None): - """ - List returns a list of charm URLs currently in the state. + """List returns a list of charm URLs currently in the state. If supplied parameter contains any names, the result will be filtered to return only the charms with supplied names. @@ -1578,9 +1511,7 @@ async def List(self, names=None): Returns -> CharmsListResult """ if names is not None and not isinstance(names, (bytes, str, list)): - raise Exception( - "Expected names to be a Sequence, received: {}".format(type(names)) - ) + raise Exception(f"Expected names to be a Sequence, received: {type(names)}") # map input types to rpc msg _params = dict() @@ -1591,17 +1522,14 @@ async def List(self, names=None): @ReturnMapping(CharmResourcesResults) async def ListCharmResources(self, entities=None): - """ - ListCharmResources returns a series of resources for a given charm. + """ListCharmResources returns a series of resources for a given charm. entities : typing.Sequence[~CharmURLAndOrigin] Returns -> CharmResourcesResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1615,8 +1543,7 @@ async def ListCharmResources(self, entities=None): @ReturnMapping(ResolveCharmWithChannelResults) async def ResolveCharms(self, macaroon=None, resolve=None): - """ - ResolveCharms resolves the given charm URLs with an optionally specified + """ResolveCharms resolves the given charm URLs with an optionally specified preferred channel. Channel provided via CharmOrigin. macaroon : Macaroon @@ -1625,14 +1552,12 @@ async def ResolveCharms(self, macaroon=None, resolve=None): """ if macaroon is not None and not isinstance(macaroon, (dict, Macaroon)): raise Exception( - "Expected macaroon to be a Macaroon, received: {}".format( - type(macaroon) - ) + f"Expected macaroon to be a Macaroon, received: {type(macaroon)}" ) if resolve is not None and not isinstance(resolve, (bytes, str, list)): raise Exception( - "Expected resolve to be a Sequence, received: {}".format(type(resolve)) + f"Expected resolve to be a Sequence, received: {type(resolve)}" ) # map input types to rpc msg @@ -2483,8 +2408,7 @@ class ClientFacade(Type): async def FindTools( self, agentstream=None, arch=None, major=None, number=None, os_type=None ): - """ - FindTools returns a List containing all tools matching the given parameters. + """FindTools returns a List containing all tools matching the given parameters. TODO(juju 3.1) - remove, used by 2.9 client only agentstream : str @@ -2496,30 +2420,20 @@ async def FindTools( """ if agentstream is not None and not isinstance(agentstream, (bytes, str)): raise Exception( - "Expected agentstream to be a str, received: {}".format( - type(agentstream) - ) + f"Expected agentstream to be a str, received: {type(agentstream)}" ) if arch is not None and not isinstance(arch, (bytes, str)): - raise Exception( - "Expected arch to be a str, received: {}".format(type(arch)) - ) + raise Exception(f"Expected arch to be a str, received: {type(arch)}") if major is not None and not isinstance(major, int): - raise Exception( - "Expected major to be a int, received: {}".format(type(major)) - ) + raise Exception(f"Expected major to be a int, received: {type(major)}") if number is not None and not isinstance(number, (dict, Number)): - raise Exception( - "Expected number to be a Number, received: {}".format(type(number)) - ) + raise Exception(f"Expected number to be a Number, received: {type(number)}") if os_type is not None and not isinstance(os_type, (bytes, str)): - raise Exception( - "Expected os_type to be a str, received: {}".format(type(os_type)) - ) + raise Exception(f"Expected os_type to be a str, received: {type(os_type)}") # map input types to rpc msg _params = dict() @@ -2534,8 +2448,7 @@ async def FindTools( @ReturnMapping(FullStatus) async def FullStatus(self, include_storage=None, patterns=None): - """ - FullStatus gives the information needed for juju status over the api + """FullStatus gives the information needed for juju status over the api include_storage : bool patterns : typing.Sequence[str] @@ -2543,16 +2456,12 @@ async def FullStatus(self, include_storage=None, patterns=None): """ if include_storage is not None and not isinstance(include_storage, bool): raise Exception( - "Expected include_storage to be a bool, received: {}".format( - type(include_storage) - ) + f"Expected include_storage to be a bool, received: {type(include_storage)}" ) if patterns is not None and not isinstance(patterns, (bytes, str, list)): raise Exception( - "Expected patterns to be a Sequence, received: {}".format( - type(patterns) - ) + f"Expected patterns to be a Sequence, received: {type(patterns)}" ) # map input types to rpc msg @@ -2565,17 +2474,14 @@ async def FullStatus(self, include_storage=None, patterns=None): @ReturnMapping(StatusHistoryResults) async def StatusHistory(self, requests=None): - """ - StatusHistory returns a slice of past statuses for several entities. + """StatusHistory returns a slice of past statuses for several entities. requests : typing.Sequence[~StatusHistoryRequest] Returns -> StatusHistoryResults """ if requests is not None and not isinstance(requests, (bytes, str, list)): raise Exception( - "Expected requests to be a Sequence, received: {}".format( - type(requests) - ) + f"Expected requests to be a Sequence, received: {type(requests)}" ) # map input types to rpc msg @@ -2587,13 +2493,10 @@ async def StatusHistory(self, requests=None): @ReturnMapping(AllWatcherId) async def WatchAll(self): - """ - WatchAll initiates a watcher for entities in the connected model. - + """WatchAll initiates a watcher for entities in the connected model. Returns -> AllWatcherId """ - # map input types to rpc msg _params = dict() msg = dict(type="Client", request="WatchAll", version=7, params=_params) @@ -3446,8 +3349,7 @@ class CloudFacade(Type): @ReturnMapping(None) async def AddCloud(self, cloud=None, force=None, name=None): - """ - AddCloud adds a new cloud, different from the one managed by the controller. + """AddCloud adds a new cloud, different from the one managed by the controller. cloud : Cloud force : bool @@ -3455,19 +3357,13 @@ async def AddCloud(self, cloud=None, force=None, name=None): Returns -> None """ if cloud is not None and not isinstance(cloud, (dict, Cloud)): - raise Exception( - "Expected cloud to be a Cloud, received: {}".format(type(cloud)) - ) + raise Exception(f"Expected cloud to be a Cloud, received: {type(cloud)}") if force is not None and not isinstance(force, bool): - raise Exception( - "Expected force to be a bool, received: {}".format(type(force)) - ) + raise Exception(f"Expected force to be a bool, received: {type(force)}") if name is not None and not isinstance(name, (bytes, str)): - raise Exception( - "Expected name to be a str, received: {}".format(type(name)) - ) + raise Exception(f"Expected name to be a str, received: {type(name)}") # map input types to rpc msg _params = dict() @@ -3480,8 +3376,7 @@ async def AddCloud(self, cloud=None, force=None, name=None): @ReturnMapping(ErrorResults) async def AddCredentials(self, credentials=None): - """ - AddCredentials adds new credentials. + """AddCredentials adds new credentials. In contrast to UpdateCredentials() below, the new credentials can be for a cloud that the controller does not manage (this is required for CAAS models) @@ -3491,9 +3386,7 @@ async def AddCredentials(self, credentials=None): """ if credentials is not None and not isinstance(credentials, (bytes, str, list)): raise Exception( - "Expected credentials to be a Sequence, received: {}".format( - type(credentials) - ) + f"Expected credentials to be a Sequence, received: {type(credentials)}" ) # map input types to rpc msg @@ -3505,8 +3398,7 @@ async def AddCredentials(self, credentials=None): @ReturnMapping(UpdateCredentialResults) async def CheckCredentialsModels(self, credentials=None): - """ - CheckCredentialsModels validates supplied cloud credentials' content against + """CheckCredentialsModels validates supplied cloud credentials' content against models that currently use these credentials. If there are any models that are using a credential and these models or their cloud instances are not going to be accessible with corresponding credential, @@ -3518,9 +3410,7 @@ async def CheckCredentialsModels(self, credentials=None): """ if credentials is not None and not isinstance(credentials, (bytes, str, list)): raise Exception( - "Expected credentials to be a Sequence, received: {}".format( - type(credentials) - ) + f"Expected credentials to be a Sequence, received: {type(credentials)}" ) # map input types to rpc msg @@ -3534,17 +3424,14 @@ async def CheckCredentialsModels(self, credentials=None): @ReturnMapping(CloudResults) async def Cloud(self, entities=None): - """ - Cloud returns the cloud definitions for the specified clouds. + """Cloud returns the cloud definitions for the specified clouds. entities : typing.Sequence[~Entity] Returns -> CloudResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -3556,17 +3443,14 @@ async def Cloud(self, entities=None): @ReturnMapping(CloudInfoResults) async def CloudInfo(self, entities=None): - """ - CloudInfo returns information about the specified clouds. + """CloudInfo returns information about the specified clouds. entities : typing.Sequence[~Entity] Returns -> CloudInfoResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -3578,14 +3462,12 @@ async def CloudInfo(self, entities=None): @ReturnMapping(CloudsResult) async def Clouds(self): - """ - Clouds returns the definitions of all clouds supported by the controller + """Clouds returns the definitions of all clouds supported by the controller that the logged in user can see. Returns -> CloudsResult """ - # map input types to rpc msg _params = dict() msg = dict(type="Cloud", request="Clouds", version=7, params=_params) @@ -3595,17 +3477,14 @@ async def Clouds(self): @ReturnMapping(CloudCredentialResults) async def Credential(self, entities=None): - """ - Credential returns the specified cloud credential for each tag, minus secrets. + """Credential returns the specified cloud credential for each tag, minus secrets. entities : typing.Sequence[~Entity] Returns -> CloudCredentialResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -3617,8 +3496,7 @@ async def Credential(self, entities=None): @ReturnMapping(CredentialContentResults) async def CredentialContents(self, credentials=None, include_secrets=None): - """ - CredentialContents returns the specified cloud credentials, + """CredentialContents returns the specified cloud credentials, including the secrets if requested. If no specific credential name/cloud was passed in, all credentials for this user are returned. @@ -3631,16 +3509,12 @@ async def CredentialContents(self, credentials=None, include_secrets=None): """ if credentials is not None and not isinstance(credentials, (bytes, str, list)): raise Exception( - "Expected credentials to be a Sequence, received: {}".format( - type(credentials) - ) + f"Expected credentials to be a Sequence, received: {type(credentials)}" ) if include_secrets is not None and not isinstance(include_secrets, bool): raise Exception( - "Expected include_secrets to be a bool, received: {}".format( - type(include_secrets) - ) + f"Expected include_secrets to be a bool, received: {type(include_secrets)}" ) # map input types to rpc msg @@ -3655,8 +3529,7 @@ async def CredentialContents(self, credentials=None, include_secrets=None): @ReturnMapping(InstanceTypesResults) async def InstanceTypes(self, constraints=None): - """ - InstanceTypes returns instance type information for the cloud and region + """InstanceTypes returns instance type information for the cloud and region in which the current model is deployed. constraints : typing.Sequence[~CloudInstanceTypesConstraint] @@ -3664,9 +3537,7 @@ async def InstanceTypes(self, constraints=None): """ if constraints is not None and not isinstance(constraints, (bytes, str, list)): raise Exception( - "Expected constraints to be a Sequence, received: {}".format( - type(constraints) - ) + f"Expected constraints to be a Sequence, received: {type(constraints)}" ) # map input types to rpc msg @@ -3678,8 +3549,7 @@ async def InstanceTypes(self, constraints=None): @ReturnMapping(ListCloudInfoResults) async def ListCloudInfo(self, all_=None, user_tag=None): - """ - ListCloudInfo returns clouds that the specified user has access to. + """ListCloudInfo returns clouds that the specified user has access to. Controller admins (superuser) can list clouds for any user. Other users can only ask about their own clouds. @@ -3688,13 +3558,11 @@ async def ListCloudInfo(self, all_=None, user_tag=None): Returns -> ListCloudInfoResults """ if all_ is not None and not isinstance(all_, bool): - raise Exception( - "Expected all_ to be a bool, received: {}".format(type(all_)) - ) + raise Exception(f"Expected all_ to be a bool, received: {type(all_)}") if user_tag is not None and not isinstance(user_tag, (bytes, str)): raise Exception( - "Expected user_tag to be a str, received: {}".format(type(user_tag)) + f"Expected user_tag to be a str, received: {type(user_tag)}" ) # map input types to rpc msg @@ -3707,15 +3575,14 @@ async def ListCloudInfo(self, all_=None, user_tag=None): @ReturnMapping(ErrorResults) async def ModifyCloudAccess(self, changes=None): - """ - ModifyCloudAccess changes the model access granted to users. + """ModifyCloudAccess changes the model access granted to users. changes : typing.Sequence[~ModifyCloudAccess] Returns -> ErrorResults """ if changes is not None and not isinstance(changes, (bytes, str, list)): raise Exception( - "Expected changes to be a Sequence, received: {}".format(type(changes)) + f"Expected changes to be a Sequence, received: {type(changes)}" ) # map input types to rpc msg @@ -3727,8 +3594,7 @@ async def ModifyCloudAccess(self, changes=None): @ReturnMapping(ErrorResults) async def RemoveClouds(self, entities=None): - """ - RemoveClouds removes the specified clouds from the controller. + """RemoveClouds removes the specified clouds from the controller. If a cloud is in use (has models deployed to it), the removal will fail. entities : typing.Sequence[~Entity] @@ -3736,9 +3602,7 @@ async def RemoveClouds(self, entities=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -3750,8 +3614,7 @@ async def RemoveClouds(self, entities=None): @ReturnMapping(ErrorResults) async def RevokeCredentialsCheckModels(self, credentials=None): - """ - RevokeCredentialsCheckModels revokes a set of cloud credentials. + """RevokeCredentialsCheckModels revokes a set of cloud credentials. If the credentials are used by any of the models, the credential deletion will be aborted. If credential-in-use needs to be revoked nonetheless, this method allows the use of force. @@ -3760,9 +3623,7 @@ async def RevokeCredentialsCheckModels(self, credentials=None): """ if credentials is not None and not isinstance(credentials, (bytes, str, list)): raise Exception( - "Expected credentials to be a Sequence, received: {}".format( - type(credentials) - ) + f"Expected credentials to be a Sequence, received: {type(credentials)}" ) # map input types to rpc msg @@ -3779,15 +3640,14 @@ async def RevokeCredentialsCheckModels(self, credentials=None): @ReturnMapping(ErrorResults) async def UpdateCloud(self, clouds=None): - """ - UpdateCloud updates an existing cloud that the controller knows about. + """UpdateCloud updates an existing cloud that the controller knows about. clouds : typing.Sequence[~AddCloudArgs] Returns -> ErrorResults """ if clouds is not None and not isinstance(clouds, (bytes, str, list)): raise Exception( - "Expected clouds to be a Sequence, received: {}".format(type(clouds)) + f"Expected clouds to be a Sequence, received: {type(clouds)}" ) # map input types to rpc msg @@ -3799,8 +3659,7 @@ async def UpdateCloud(self, clouds=None): @ReturnMapping(UpdateCredentialResults) async def UpdateCredentialsCheckModels(self, credentials=None, force=None): - """ - UpdateCredentialsCheckModels updates a set of cloud credentials' content. + """UpdateCredentialsCheckModels updates a set of cloud credentials' content. If there are any models that are using a credential and these models are not going to be visible with updated credential content, there will be detailed validation errors per model. Such model errors are returned @@ -3814,15 +3673,11 @@ async def UpdateCredentialsCheckModels(self, credentials=None, force=None): """ if credentials is not None and not isinstance(credentials, (bytes, str, list)): raise Exception( - "Expected credentials to be a Sequence, received: {}".format( - type(credentials) - ) + f"Expected credentials to be a Sequence, received: {type(credentials)}" ) if force is not None and not isinstance(force, bool): - raise Exception( - "Expected force to be a bool, received: {}".format(type(force)) - ) + raise Exception(f"Expected force to be a bool, received: {type(force)}") # map input types to rpc msg _params = dict() @@ -3839,17 +3694,14 @@ async def UpdateCredentialsCheckModels(self, credentials=None, force=None): @ReturnMapping(StringsResults) async def UserCredentials(self, user_clouds=None): - """ - UserCredentials returns the cloud credentials for a set of users. + """UserCredentials returns the cloud credentials for a set of users. user_clouds : typing.Sequence[~UserCloud] Returns -> StringsResults """ if user_clouds is not None and not isinstance(user_clouds, (bytes, str, list)): raise Exception( - "Expected user_clouds to be a Sequence, received: {}".format( - type(user_clouds) - ) + f"Expected user_clouds to be a Sequence, received: {type(user_clouds)}" ) # map input types to rpc msg diff --git a/juju/client/_client8.py b/juju/client/_client8.py index c4c36ac57..5a4d738ce 100644 --- a/juju/client/_client8.py +++ b/juju/client/_client8.py @@ -1,8 +1,8 @@ # DO NOT CHANGE THIS FILE! This file is auto-generated by facade.py. # Changes will be overwritten/lost when the file is regenerated. -from juju.client.facade import Type, ReturnMapping from juju.client._definitions import * +from juju.client.facade import ReturnMapping, Type class ClientFacade(Type): @@ -762,8 +762,7 @@ class ClientFacade(Type): @ReturnMapping(FullStatus) async def FullStatus(self, include_storage=None, patterns=None): - """ - FullStatus gives the information needed for juju status over the api + """FullStatus gives the information needed for juju status over the api include_storage : bool patterns : typing.Sequence[str] @@ -771,16 +770,12 @@ async def FullStatus(self, include_storage=None, patterns=None): """ if include_storage is not None and not isinstance(include_storage, bool): raise Exception( - "Expected include_storage to be a bool, received: {}".format( - type(include_storage) - ) + f"Expected include_storage to be a bool, received: {type(include_storage)}" ) if patterns is not None and not isinstance(patterns, (bytes, str, list)): raise Exception( - "Expected patterns to be a Sequence, received: {}".format( - type(patterns) - ) + f"Expected patterns to be a Sequence, received: {type(patterns)}" ) # map input types to rpc msg @@ -793,17 +788,14 @@ async def FullStatus(self, include_storage=None, patterns=None): @ReturnMapping(StatusHistoryResults) async def StatusHistory(self, requests=None): - """ - StatusHistory returns a slice of past statuses for several entities. + """StatusHistory returns a slice of past statuses for several entities. requests : typing.Sequence[~StatusHistoryRequest] Returns -> StatusHistoryResults """ if requests is not None and not isinstance(requests, (bytes, str, list)): raise Exception( - "Expected requests to be a Sequence, received: {}".format( - type(requests) - ) + f"Expected requests to be a Sequence, received: {type(requests)}" ) # map input types to rpc msg @@ -815,13 +807,10 @@ async def StatusHistory(self, requests=None): @ReturnMapping(AllWatcherId) async def WatchAll(self): - """ - WatchAll initiates a watcher for entities in the connected model. - + """WatchAll initiates a watcher for entities in the connected model. Returns -> AllWatcherId """ - # map input types to rpc msg _params = dict() msg = dict(type="Client", request="WatchAll", version=8, params=_params) diff --git a/juju/client/_client9.py b/juju/client/_client9.py index 63d6110cd..e6eaa1857 100644 --- a/juju/client/_client9.py +++ b/juju/client/_client9.py @@ -1,8 +1,8 @@ # DO NOT CHANGE THIS FILE! This file is auto-generated by facade.py. # Changes will be overwritten/lost when the file is regenerated. -from juju.client.facade import Type, ReturnMapping from juju.client._definitions import * +from juju.client.facade import ReturnMapping, Type class ModelManagerFacade(Type): @@ -865,8 +865,7 @@ class ModelManagerFacade(Type): @ReturnMapping(ErrorResults) async def ChangeModelCredential(self, model_credentials=None): - """ - ChangeModelCredential changes cloud credential reference for models. + """ChangeModelCredential changes cloud credential reference for models. These new cloud credentials must already exist on the controller. model_credentials : typing.Sequence[~ChangeModelCredentialParams] @@ -876,9 +875,7 @@ async def ChangeModelCredential(self, model_credentials=None): model_credentials, (bytes, str, list) ): raise Exception( - "Expected model_credentials to be a Sequence, received: {}".format( - type(model_credentials) - ) + f"Expected model_credentials to be a Sequence, received: {type(model_credentials)}" ) # map input types to rpc msg @@ -903,8 +900,7 @@ async def CreateModel( owner_tag=None, region=None, ): - """ - CreateModel creates a new model using the account and + """CreateModel creates a new model using the account and model config specified in the args. cloud_tag : str @@ -917,33 +913,29 @@ async def CreateModel( """ if cloud_tag is not None and not isinstance(cloud_tag, (bytes, str)): raise Exception( - "Expected cloud_tag to be a str, received: {}".format(type(cloud_tag)) + f"Expected cloud_tag to be a str, received: {type(cloud_tag)}" ) if config is not None and not isinstance(config, dict): raise Exception( - "Expected config to be a Mapping, received: {}".format(type(config)) + f"Expected config to be a Mapping, received: {type(config)}" ) if credential is not None and not isinstance(credential, (bytes, str)): raise Exception( - "Expected credential to be a str, received: {}".format(type(credential)) + f"Expected credential to be a str, received: {type(credential)}" ) if name is not None and not isinstance(name, (bytes, str)): - raise Exception( - "Expected name to be a str, received: {}".format(type(name)) - ) + raise Exception(f"Expected name to be a str, received: {type(name)}") if owner_tag is not None and not isinstance(owner_tag, (bytes, str)): raise Exception( - "Expected owner_tag to be a str, received: {}".format(type(owner_tag)) + f"Expected owner_tag to be a str, received: {type(owner_tag)}" ) if region is not None and not isinstance(region, (bytes, str)): - raise Exception( - "Expected region to be a str, received: {}".format(type(region)) - ) + raise Exception(f"Expected region to be a str, received: {type(region)}") # map input types to rpc msg _params = dict() @@ -961,8 +953,7 @@ async def CreateModel( @ReturnMapping(ErrorResults) async def DestroyModels(self, models=None): - """ - DestroyModels will try to destroy the specified models. + """DestroyModels will try to destroy the specified models. If there is a block on destruction, this method will return an error. From ModelManager v7 onwards, DestroyModels gains 'force' and 'max-wait' parameters. @@ -971,7 +962,7 @@ async def DestroyModels(self, models=None): """ if models is not None and not isinstance(models, (bytes, str, list)): raise Exception( - "Expected models to be a Sequence, received: {}".format(type(models)) + f"Expected models to be a Sequence, received: {type(models)}" ) # map input types to rpc msg @@ -985,8 +976,7 @@ async def DestroyModels(self, models=None): @ReturnMapping(StringResults) async def DumpModels(self, entities=None, simplified=None): - """ - DumpModels will export the models into the database agnostic + """DumpModels will export the models into the database agnostic representation. The user needs to either be a controller admin, or have admin privileges on the model itself. @@ -996,16 +986,12 @@ async def DumpModels(self, entities=None, simplified=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) if simplified is not None and not isinstance(simplified, bool): raise Exception( - "Expected simplified to be a bool, received: {}".format( - type(simplified) - ) + f"Expected simplified to be a bool, received: {type(simplified)}" ) # map input types to rpc msg @@ -1018,8 +1004,7 @@ async def DumpModels(self, entities=None, simplified=None): @ReturnMapping(MapResults) async def DumpModelsDB(self, entities=None): - """ - DumpModelsDB will gather all documents from all model collections + """DumpModelsDB will gather all documents from all model collections for the specified model. The map result contains a map of collection names to lists of documents represented as maps. @@ -1028,9 +1013,7 @@ async def DumpModelsDB(self, entities=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1044,8 +1027,7 @@ async def DumpModelsDB(self, entities=None): @ReturnMapping(ModelSummaryResults) async def ListModelSummaries(self, all_=None, user_tag=None): - """ - ListModelSummaries returns models that the specified user + """ListModelSummaries returns models that the specified user has access to in the current server. Controller admins (superuser) can list models for any user. Other users can only ask about their own models. @@ -1055,13 +1037,11 @@ async def ListModelSummaries(self, all_=None, user_tag=None): Returns -> ModelSummaryResults """ if all_ is not None and not isinstance(all_, bool): - raise Exception( - "Expected all_ to be a bool, received: {}".format(type(all_)) - ) + raise Exception(f"Expected all_ to be a bool, received: {type(all_)}") if user_tag is not None and not isinstance(user_tag, (bytes, str)): raise Exception( - "Expected user_tag to be a str, received: {}".format(type(user_tag)) + f"Expected user_tag to be a str, received: {type(user_tag)}" ) # map input types to rpc msg @@ -1076,8 +1056,7 @@ async def ListModelSummaries(self, all_=None, user_tag=None): @ReturnMapping(UserModelList) async def ListModels(self, tag=None): - """ - ListModels returns the models that the specified user + """ListModels returns the models that the specified user has access to in the current server. Controller admins (superuser) can list models for any user. Other users can only ask about their own models. @@ -1086,7 +1065,7 @@ async def ListModels(self, tag=None): Returns -> UserModelList """ if tag is not None and not isinstance(tag, (bytes, str)): - raise Exception("Expected tag to be a str, received: {}".format(type(tag))) + raise Exception(f"Expected tag to be a str, received: {type(tag)}") # map input types to rpc msg _params = dict() @@ -1097,8 +1076,7 @@ async def ListModels(self, tag=None): @ReturnMapping(ModelDefaultsResults) async def ModelDefaultsForClouds(self, entities=None): - """ - ModelDefaultsForClouds returns the default config values for the specified + """ModelDefaultsForClouds returns the default config values for the specified clouds. entities : typing.Sequence[~Entity] @@ -1106,9 +1084,7 @@ async def ModelDefaultsForClouds(self, entities=None): """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1125,17 +1101,14 @@ async def ModelDefaultsForClouds(self, entities=None): @ReturnMapping(ModelInfoResults) async def ModelInfo(self, entities=None): - """ - ModelInfo returns information about the specified models. + """ModelInfo returns information about the specified models. entities : typing.Sequence[~Entity] Returns -> ModelInfoResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1147,17 +1120,14 @@ async def ModelInfo(self, entities=None): @ReturnMapping(ModelStatusResults) async def ModelStatus(self, entities=None): - """ - ModelStatus returns a summary of the model. + """ModelStatus returns a summary of the model. entities : typing.Sequence[~Entity] Returns -> ModelStatusResults """ if entities is not None and not isinstance(entities, (bytes, str, list)): raise Exception( - "Expected entities to be a Sequence, received: {}".format( - type(entities) - ) + f"Expected entities to be a Sequence, received: {type(entities)}" ) # map input types to rpc msg @@ -1171,15 +1141,14 @@ async def ModelStatus(self, entities=None): @ReturnMapping(ErrorResults) async def ModifyModelAccess(self, changes=None): - """ - ModifyModelAccess changes the model access granted to users. + """ModifyModelAccess changes the model access granted to users. changes : typing.Sequence[~ModifyModelAccess] Returns -> ErrorResults """ if changes is not None and not isinstance(changes, (bytes, str, list)): raise Exception( - "Expected changes to be a Sequence, received: {}".format(type(changes)) + f"Expected changes to be a Sequence, received: {type(changes)}" ) # map input types to rpc msg @@ -1193,15 +1162,14 @@ async def ModifyModelAccess(self, changes=None): @ReturnMapping(ErrorResults) async def SetModelDefaults(self, config=None): - """ - SetModelDefaults writes new values for the specified default model settings. + """SetModelDefaults writes new values for the specified default model settings. config : typing.Sequence[~ModelDefaultValues] Returns -> ErrorResults """ if config is not None and not isinstance(config, (bytes, str, list)): raise Exception( - "Expected config to be a Sequence, received: {}".format(type(config)) + f"Expected config to be a Sequence, received: {type(config)}" ) # map input types to rpc msg @@ -1215,16 +1183,13 @@ async def SetModelDefaults(self, config=None): @ReturnMapping(ErrorResults) async def UnsetModelDefaults(self, keys=None): - """ - UnsetModelDefaults removes the specified default model settings. + """UnsetModelDefaults removes the specified default model settings. keys : typing.Sequence[~ModelUnsetKeys] Returns -> ErrorResults """ if keys is not None and not isinstance(keys, (bytes, str, list)): - raise Exception( - "Expected keys to be a Sequence, received: {}".format(type(keys)) - ) + raise Exception(f"Expected keys to be a Sequence, received: {type(keys)}") # map input types to rpc msg _params = dict() diff --git a/juju/client/_definitions.py b/juju/client/_definitions.py index a6df91afb..f02b34717 100644 --- a/juju/client/_definitions.py +++ b/juju/client/_definitions.py @@ -1,7 +1,7 @@ # DO NOT CHANGE THIS FILE! This file is auto-generated by facade.py. # Changes will be overwritten/lost when the file is regenerated. -from juju.client.facade import Type, ReturnMapping +from juju.client.facade import Type class AccessInfo(Type): @@ -9,8 +9,7 @@ class AccessInfo(Type): _toPy = {"role": "role", "scope-tag": "scope_tag", "target-tag": "target_tag"} def __init__(self, role=None, scope_tag=None, target_tag=None, **unknown_fields): - """ - role : str + """Role : str scope_tag : str target_tag : str """ @@ -20,20 +19,16 @@ def __init__(self, role=None, scope_tag=None, target_tag=None, **unknown_fields) # Validate arguments against known Juju API types. if role_ is not None and not isinstance(role_, (bytes, str)): - raise Exception( - "Expected role_ to be a str, received: {}".format(type(role_)) - ) + raise Exception(f"Expected role_ to be a str, received: {type(role_)}") if scope_tag_ is not None and not isinstance(scope_tag_, (bytes, str)): raise Exception( - "Expected scope_tag_ to be a str, received: {}".format(type(scope_tag_)) + f"Expected scope_tag_ to be a str, received: {type(scope_tag_)}" ) if target_tag_ is not None and not isinstance(target_tag_, (bytes, str)): raise Exception( - "Expected target_tag_ to be a str, received: {}".format( - type(target_tag_) - ) + f"Expected target_tag_ to be a str, received: {type(target_tag_)}" ) self.role = role_ @@ -70,8 +65,7 @@ def __init__( tag=None, **unknown_fields, ): - """ - execution_group : str + """execution_group : str name : str parallel : bool parameters : typing.Mapping[str, typing.Any] @@ -90,37 +84,29 @@ def __init__( execution_group_, (bytes, str) ): raise Exception( - "Expected execution_group_ to be a str, received: {}".format( - type(execution_group_) - ) + f"Expected execution_group_ to be a str, received: {type(execution_group_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if parallel_ is not None and not isinstance(parallel_, bool): raise Exception( - "Expected parallel_ to be a bool, received: {}".format(type(parallel_)) + f"Expected parallel_ to be a bool, received: {type(parallel_)}" ) if parameters_ is not None and not isinstance(parameters_, dict): raise Exception( - "Expected parameters_ to be a Mapping, received: {}".format( - type(parameters_) - ) + f"Expected parameters_ to be a Mapping, received: {type(parameters_)}" ) if receiver_ is not None and not isinstance(receiver_, (bytes, str)): raise Exception( - "Expected receiver_ to be a str, received: {}".format(type(receiver_)) + f"Expected receiver_ to be a str, received: {type(receiver_)}" ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception( - "Expected tag_ to be a str, received: {}".format(type(tag_)) - ) + raise Exception(f"Expected tag_ to be a str, received: {type(tag_)}") self.execution_group = execution_group_ self.name = name_ @@ -136,8 +122,7 @@ class ActionMessage(Type): _toPy = {"message": "message", "timestamp": "timestamp"} def __init__(self, message=None, timestamp=None, **unknown_fields): - """ - message : str + """Message : str timestamp : str """ message_ = message @@ -146,12 +131,12 @@ def __init__(self, message=None, timestamp=None, **unknown_fields): # Validate arguments against known Juju API types. if message_ is not None and not isinstance(message_, (bytes, str)): raise Exception( - "Expected message_ to be a str, received: {}".format(type(message_)) + f"Expected message_ to be a str, received: {type(message_)}" ) if timestamp_ is not None and not isinstance(timestamp_, (bytes, str)): raise Exception( - "Expected timestamp_ to be a str, received: {}".format(type(timestamp_)) + f"Expected timestamp_ to be a str, received: {type(timestamp_)}" ) self.message = message_ @@ -196,8 +181,7 @@ def __init__( status=None, **unknown_fields, ): - """ - action : Action + """Action : Action completed : str enqueued : str error : Error @@ -220,48 +204,42 @@ def __init__( # Validate arguments against known Juju API types. if action_ is not None and not isinstance(action_, (dict, Action)): raise Exception( - "Expected action_ to be a Action, received: {}".format(type(action_)) + f"Expected action_ to be a Action, received: {type(action_)}" ) if completed_ is not None and not isinstance(completed_, (bytes, str)): raise Exception( - "Expected completed_ to be a str, received: {}".format(type(completed_)) + f"Expected completed_ to be a str, received: {type(completed_)}" ) if enqueued_ is not None and not isinstance(enqueued_, (bytes, str)): raise Exception( - "Expected enqueued_ to be a str, received: {}".format(type(enqueued_)) + f"Expected enqueued_ to be a str, received: {type(enqueued_)}" ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if log_ is not None and not isinstance(log_, (bytes, str, list)): - raise Exception( - "Expected log_ to be a Sequence, received: {}".format(type(log_)) - ) + raise Exception(f"Expected log_ to be a Sequence, received: {type(log_)}") if message_ is not None and not isinstance(message_, (bytes, str)): raise Exception( - "Expected message_ to be a str, received: {}".format(type(message_)) + f"Expected message_ to be a str, received: {type(message_)}" ) if output_ is not None and not isinstance(output_, dict): raise Exception( - "Expected output_ to be a Mapping, received: {}".format(type(output_)) + f"Expected output_ to be a Mapping, received: {type(output_)}" ) if started_ is not None and not isinstance(started_, (bytes, str)): raise Exception( - "Expected started_ to be a str, received: {}".format(type(started_)) + f"Expected started_ to be a str, received: {type(started_)}" ) if status_ is not None and not isinstance(status_, (bytes, str)): - raise Exception( - "Expected status_ to be a str, received: {}".format(type(status_)) - ) + raise Exception(f"Expected status_ to be a str, received: {type(status_)}") self.action = action_ self.completed = completed_ @@ -280,17 +258,13 @@ class ActionResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~ActionResult] - """ + """Results : typing.Sequence[~ActionResult]""" results_ = [ActionResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -302,8 +276,7 @@ class ActionSpec(Type): _toPy = {"description": "description", "params": "params"} def __init__(self, description=None, params=None, **unknown_fields): - """ - description : str + """Description : str params : typing.Mapping[str, typing.Any] """ description_ = description @@ -312,14 +285,12 @@ def __init__(self, description=None, params=None, **unknown_fields): # Validate arguments against known Juju API types. if description_ is not None and not isinstance(description_, (bytes, str)): raise Exception( - "Expected description_ to be a str, received: {}".format( - type(description_) - ) + f"Expected description_ to be a str, received: {type(description_)}" ) if params_ is not None and not isinstance(params_, dict): raise Exception( - "Expected params_ to be a Mapping, received: {}".format(type(params_)) + f"Expected params_ to be a Mapping, received: {type(params_)}" ) self.description = description_ @@ -332,17 +303,13 @@ class Actions(Type): _toPy = {"actions": "actions"} def __init__(self, actions=None, **unknown_fields): - """ - actions : typing.Sequence[~Action] - """ + """Actions : typing.Sequence[~Action]""" actions_ = [Action.from_json(o) for o in actions or []] # Validate arguments against known Juju API types. if actions_ is not None and not isinstance(actions_, (bytes, str, list)): raise Exception( - "Expected actions_ to be a Sequence, received: {}".format( - type(actions_) - ) + f"Expected actions_ to be a Sequence, received: {type(actions_)}" ) self.actions = actions_ @@ -377,8 +344,7 @@ def __init__( owner_tag=None, **unknown_fields, ): - """ - application_description : str + """application_description : str application_name : str endpoints : typing.Mapping[str, str] model_tag : str @@ -397,42 +363,34 @@ def __init__( application_description_, (bytes, str) ): raise Exception( - "Expected application_description_ to be a str, received: {}".format( - type(application_description_) - ) + f"Expected application_description_ to be a str, received: {type(application_description_)}" ) if application_name_ is not None and not isinstance( application_name_, (bytes, str) ): raise Exception( - "Expected application_name_ to be a str, received: {}".format( - type(application_name_) - ) + f"Expected application_name_ to be a str, received: {type(application_name_)}" ) if endpoints_ is not None and not isinstance(endpoints_, dict): raise Exception( - "Expected endpoints_ to be a Mapping, received: {}".format( - type(endpoints_) - ) + f"Expected endpoints_ to be a Mapping, received: {type(endpoints_)}" ) if model_tag_ is not None and not isinstance(model_tag_, (bytes, str)): raise Exception( - "Expected model_tag_ to be a str, received: {}".format(type(model_tag_)) + f"Expected model_tag_ to be a str, received: {type(model_tag_)}" ) if offer_name_ is not None and not isinstance(offer_name_, (bytes, str)): raise Exception( - "Expected offer_name_ to be a str, received: {}".format( - type(offer_name_) - ) + f"Expected offer_name_ to be a str, received: {type(offer_name_)}" ) if owner_tag_ is not None and not isinstance(owner_tag_, (bytes, str)): raise Exception( - "Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_)) + f"Expected owner_tag_ to be a str, received: {type(owner_tag_)}" ) self.application_description = application_description_ @@ -449,15 +407,13 @@ class AddApplicationOffers(Type): _toPy = {"Offers": "offers"} def __init__(self, offers=None, **unknown_fields): - """ - offers : typing.Sequence[~AddApplicationOffer] - """ + """Offers : typing.Sequence[~AddApplicationOffer]""" offers_ = [AddApplicationOffer.from_json(o) for o in offers or []] # Validate arguments against known Juju API types. if offers_ is not None and not isinstance(offers_, (bytes, str, list)): raise Exception( - "Expected offers_ to be a Sequence, received: {}".format(type(offers_)) + f"Expected offers_ to be a Sequence, received: {type(offers_)}" ) self.offers = offers_ @@ -489,8 +445,7 @@ def __init__( policy=None, **unknown_fields, ): - """ - application : str + """Application : str attach_storage : typing.Sequence[str] num_units : int placement : typing.Sequence[~Placement] @@ -505,36 +460,28 @@ def __init__( # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): raise Exception( - "Expected application_ to be a str, received: {}".format( - type(application_) - ) + f"Expected application_ to be a str, received: {type(application_)}" ) if attach_storage_ is not None and not isinstance( attach_storage_, (bytes, str, list) ): raise Exception( - "Expected attach_storage_ to be a Sequence, received: {}".format( - type(attach_storage_) - ) + f"Expected attach_storage_ to be a Sequence, received: {type(attach_storage_)}" ) if num_units_ is not None and not isinstance(num_units_, int): raise Exception( - "Expected num_units_ to be a int, received: {}".format(type(num_units_)) + f"Expected num_units_ to be a int, received: {type(num_units_)}" ) if placement_ is not None and not isinstance(placement_, (bytes, str, list)): raise Exception( - "Expected placement_ to be a Sequence, received: {}".format( - type(placement_) - ) + f"Expected placement_ to be a Sequence, received: {type(placement_)}" ) if policy_ is not None and not isinstance(policy_, (bytes, str)): - raise Exception( - "Expected policy_ to be a str, received: {}".format(type(policy_)) - ) + raise Exception(f"Expected policy_ to be a str, received: {type(policy_)}") self.application = application_ self.attach_storage = attach_storage_ @@ -549,15 +496,13 @@ class AddApplicationUnitsResults(Type): _toPy = {"units": "units"} def __init__(self, units=None, **unknown_fields): - """ - units : typing.Sequence[str] - """ + """Units : typing.Sequence[str]""" units_ = units # Validate arguments against known Juju API types. if units_ is not None and not isinstance(units_, (bytes, str, list)): raise Exception( - "Expected units_ to be a Sequence, received: {}".format(type(units_)) + f"Expected units_ to be a Sequence, received: {type(units_)}" ) self.units = units_ @@ -569,8 +514,7 @@ class AddCharmWithOrigin(Type): _toPy = {"charm-origin": "charm_origin", "force": "force", "url": "url"} def __init__(self, charm_origin=None, force=None, url=None, **unknown_fields): - """ - charm_origin : CharmOrigin + """charm_origin : CharmOrigin force : bool url : str """ @@ -583,20 +527,14 @@ def __init__(self, charm_origin=None, force=None, url=None, **unknown_fields): charm_origin_, (dict, CharmOrigin) ): raise Exception( - "Expected charm_origin_ to be a CharmOrigin, received: {}".format( - type(charm_origin_) - ) + f"Expected charm_origin_ to be a CharmOrigin, received: {type(charm_origin_)}" ) if force_ is not None and not isinstance(force_, bool): - raise Exception( - "Expected force_ to be a bool, received: {}".format(type(force_)) - ) + raise Exception(f"Expected force_ to be a bool, received: {type(force_)}") if url_ is not None and not isinstance(url_, (bytes, str)): - raise Exception( - "Expected url_ to be a str, received: {}".format(type(url_)) - ) + raise Exception(f"Expected url_ to be a str, received: {type(url_)}") self.charm_origin = charm_origin_ self.force = force_ @@ -609,8 +547,7 @@ class AddCloudArgs(Type): _toPy = {"cloud": "cloud", "force": "force", "name": "name"} def __init__(self, cloud=None, force=None, name=None, **unknown_fields): - """ - cloud : Cloud + """Cloud : Cloud force : bool name : str """ @@ -620,19 +557,13 @@ def __init__(self, cloud=None, force=None, name=None, **unknown_fields): # Validate arguments against known Juju API types. if cloud_ is not None and not isinstance(cloud_, (dict, Cloud)): - raise Exception( - "Expected cloud_ to be a Cloud, received: {}".format(type(cloud_)) - ) + raise Exception(f"Expected cloud_ to be a Cloud, received: {type(cloud_)}") if force_ is not None and not isinstance(force_, bool): - raise Exception( - "Expected force_ to be a bool, received: {}".format(type(force_)) - ) + raise Exception(f"Expected force_ to be a bool, received: {type(force_)}") if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") self.cloud = cloud_ self.force = force_ @@ -683,8 +614,7 @@ def __init__( placement=None, **unknown_fields, ): - """ - addresses : typing.Sequence[~Address] + """Addresses : typing.Sequence[~Address] base : Base constraints : Value container_type : str @@ -715,73 +645,55 @@ def __init__( # Validate arguments against known Juju API types. if addresses_ is not None and not isinstance(addresses_, (bytes, str, list)): raise Exception( - "Expected addresses_ to be a Sequence, received: {}".format( - type(addresses_) - ) + f"Expected addresses_ to be a Sequence, received: {type(addresses_)}" ) if base_ is not None and not isinstance(base_, (dict, Base)): - raise Exception( - "Expected base_ to be a Base, received: {}".format(type(base_)) - ) + raise Exception(f"Expected base_ to be a Base, received: {type(base_)}") if constraints_ is not None and not isinstance(constraints_, (dict, Value)): raise Exception( - "Expected constraints_ to be a Value, received: {}".format( - type(constraints_) - ) + f"Expected constraints_ to be a Value, received: {type(constraints_)}" ) if container_type_ is not None and not isinstance( container_type_, (bytes, str) ): raise Exception( - "Expected container_type_ to be a str, received: {}".format( - type(container_type_) - ) + f"Expected container_type_ to be a str, received: {type(container_type_)}" ) if disks_ is not None and not isinstance(disks_, (bytes, str, list)): raise Exception( - "Expected disks_ to be a Sequence, received: {}".format(type(disks_)) + f"Expected disks_ to be a Sequence, received: {type(disks_)}" ) if hardware_characteristics_ is not None and not isinstance( hardware_characteristics_, (dict, HardwareCharacteristics) ): raise Exception( - "Expected hardware_characteristics_ to be a HardwareCharacteristics, received: {}".format( - type(hardware_characteristics_) - ) + f"Expected hardware_characteristics_ to be a HardwareCharacteristics, received: {type(hardware_characteristics_)}" ) if instance_id_ is not None and not isinstance(instance_id_, (bytes, str)): raise Exception( - "Expected instance_id_ to be a str, received: {}".format( - type(instance_id_) - ) + f"Expected instance_id_ to be a str, received: {type(instance_id_)}" ) if jobs_ is not None and not isinstance(jobs_, (bytes, str, list)): - raise Exception( - "Expected jobs_ to be a Sequence, received: {}".format(type(jobs_)) - ) + raise Exception(f"Expected jobs_ to be a Sequence, received: {type(jobs_)}") if nonce_ is not None and not isinstance(nonce_, (bytes, str)): - raise Exception( - "Expected nonce_ to be a str, received: {}".format(type(nonce_)) - ) + raise Exception(f"Expected nonce_ to be a str, received: {type(nonce_)}") if parent_id_ is not None and not isinstance(parent_id_, (bytes, str)): raise Exception( - "Expected parent_id_ to be a str, received: {}".format(type(parent_id_)) + f"Expected parent_id_ to be a str, received: {type(parent_id_)}" ) if placement_ is not None and not isinstance(placement_, (dict, Placement)): raise Exception( - "Expected placement_ to be a Placement, received: {}".format( - type(placement_) - ) + f"Expected placement_ to be a Placement, received: {type(placement_)}" ) self.addresses = addresses_ @@ -803,15 +715,13 @@ class AddMachines(Type): _toPy = {"params": "params"} def __init__(self, params=None, **unknown_fields): - """ - params : typing.Sequence[~AddMachineParams] - """ + """Params : typing.Sequence[~AddMachineParams]""" params_ = [AddMachineParams.from_json(o) for o in params or []] # Validate arguments against known Juju API types. if params_ is not None and not isinstance(params_, (bytes, str, list)): raise Exception( - "Expected params_ to be a Sequence, received: {}".format(type(params_)) + f"Expected params_ to be a Sequence, received: {type(params_)}" ) self.params = params_ @@ -823,8 +733,7 @@ class AddMachinesResult(Type): _toPy = {"error": "error", "machine": "machine"} def __init__(self, error=None, machine=None, **unknown_fields): - """ - error : Error + """Error : Error machine : str """ error_ = Error.from_json(error) if error else None @@ -832,13 +741,11 @@ def __init__(self, error=None, machine=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if machine_ is not None and not isinstance(machine_, (bytes, str)): raise Exception( - "Expected machine_ to be a str, received: {}".format(type(machine_)) + f"Expected machine_ to be a str, received: {type(machine_)}" ) self.error = error_ @@ -851,17 +758,13 @@ class AddMachinesResults(Type): _toPy = {"machines": "machines"} def __init__(self, machines=None, **unknown_fields): - """ - machines : typing.Sequence[~AddMachinesResult] - """ + """Machines : typing.Sequence[~AddMachinesResult]""" machines_ = [AddMachinesResult.from_json(o) for o in machines or []] # Validate arguments against known Juju API types. if machines_ is not None and not isinstance(machines_, (bytes, str, list)): raise Exception( - "Expected machines_ to be a Sequence, received: {}".format( - type(machines_) - ) + f"Expected machines_ to be a Sequence, received: {type(machines_)}" ) self.machines = machines_ @@ -896,8 +799,7 @@ def __init__( url=None, **unknown_fields, ): - """ - entity : Entity + """Entity : Entity charm_origin : CharmOrigin macaroon : Macaroon resources : typing.Sequence[~CharmResource] @@ -914,41 +816,31 @@ def __init__( # Validate arguments against known Juju API types. if entity_ is not None and not isinstance(entity_, (dict, Entity)): raise Exception( - "Expected entity_ to be a Entity, received: {}".format(type(entity_)) + f"Expected entity_ to be a Entity, received: {type(entity_)}" ) if charm_origin_ is not None and not isinstance( charm_origin_, (dict, CharmOrigin) ): raise Exception( - "Expected charm_origin_ to be a CharmOrigin, received: {}".format( - type(charm_origin_) - ) + f"Expected charm_origin_ to be a CharmOrigin, received: {type(charm_origin_)}" ) if macaroon_ is not None and not isinstance(macaroon_, (dict, Macaroon)): raise Exception( - "Expected macaroon_ to be a Macaroon, received: {}".format( - type(macaroon_) - ) + f"Expected macaroon_ to be a Macaroon, received: {type(macaroon_)}" ) if resources_ is not None and not isinstance(resources_, (bytes, str, list)): raise Exception( - "Expected resources_ to be a Sequence, received: {}".format( - type(resources_) - ) + f"Expected resources_ to be a Sequence, received: {type(resources_)}" ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception( - "Expected tag_ to be a str, received: {}".format(type(tag_)) - ) + raise Exception(f"Expected tag_ to be a str, received: {type(tag_)}") if url_ is not None and not isinstance(url_, (bytes, str)): - raise Exception( - "Expected url_ to be a str, received: {}".format(type(url_)) - ) + raise Exception(f"Expected url_ to be a str, received: {type(url_)}") self.entity = entity_ self.charm_origin = charm_origin_ @@ -974,8 +866,7 @@ class AddPendingResourcesResult(Type): def __init__( self, errorresult=None, error=None, pending_ids=None, **unknown_fields ): - """ - errorresult : ErrorResult + """Errorresult : ErrorResult error : Error pending_ids : typing.Sequence[str] """ @@ -988,23 +879,17 @@ def __init__( errorresult_, (dict, ErrorResult) ): raise Exception( - "Expected errorresult_ to be a ErrorResult, received: {}".format( - type(errorresult_) - ) + f"Expected errorresult_ to be a ErrorResult, received: {type(errorresult_)}" ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if pending_ids_ is not None and not isinstance( pending_ids_, (bytes, str, list) ): raise Exception( - "Expected pending_ids_ to be a Sequence, received: {}".format( - type(pending_ids_) - ) + f"Expected pending_ids_ to be a Sequence, received: {type(pending_ids_)}" ) self.errorresult = errorresult_ @@ -1018,8 +903,7 @@ class AddRelation(Type): _toPy = {"endpoints": "endpoints", "via-cidrs": "via_cidrs"} def __init__(self, endpoints=None, via_cidrs=None, **unknown_fields): - """ - endpoints : typing.Sequence[str] + """Endpoints : typing.Sequence[str] via_cidrs : typing.Sequence[str] """ endpoints_ = endpoints @@ -1028,16 +912,12 @@ def __init__(self, endpoints=None, via_cidrs=None, **unknown_fields): # Validate arguments against known Juju API types. if endpoints_ is not None and not isinstance(endpoints_, (bytes, str, list)): raise Exception( - "Expected endpoints_ to be a Sequence, received: {}".format( - type(endpoints_) - ) + f"Expected endpoints_ to be a Sequence, received: {type(endpoints_)}" ) if via_cidrs_ is not None and not isinstance(via_cidrs_, (bytes, str, list)): raise Exception( - "Expected via_cidrs_ to be a Sequence, received: {}".format( - type(via_cidrs_) - ) + f"Expected via_cidrs_ to be a Sequence, received: {type(via_cidrs_)}" ) self.endpoints = endpoints_ @@ -1050,9 +930,7 @@ class AddRelationResults(Type): _toPy = {"endpoints": "endpoints"} def __init__(self, endpoints=None, **unknown_fields): - """ - endpoints : typing.Mapping[str, ~CharmRelation] - """ + """Endpoints : typing.Mapping[str, ~CharmRelation]""" endpoints_ = { k: CharmRelation.from_json(v) for k, v in (endpoints or dict()).items() } @@ -1060,9 +938,7 @@ def __init__(self, endpoints=None, **unknown_fields): # Validate arguments against known Juju API types. if endpoints_ is not None and not isinstance(endpoints_, dict): raise Exception( - "Expected endpoints_ to be a Mapping, received: {}".format( - type(endpoints_) - ) + f"Expected endpoints_ to be a Mapping, received: {type(endpoints_)}" ) self.endpoints = endpoints_ @@ -1097,8 +973,7 @@ def __init__( token_rotate_interval=None, **unknown_fields, ): - """ - secretbackend : SecretBackend + """Secretbackend : SecretBackend backend_type : str config : typing.Mapping[str, typing.Any] id_ : str @@ -1119,40 +994,30 @@ def __init__( secretbackend_, (dict, SecretBackend) ): raise Exception( - "Expected secretbackend_ to be a SecretBackend, received: {}".format( - type(secretbackend_) - ) + f"Expected secretbackend_ to be a SecretBackend, received: {type(secretbackend_)}" ) if backend_type_ is not None and not isinstance(backend_type_, (bytes, str)): raise Exception( - "Expected backend_type_ to be a str, received: {}".format( - type(backend_type_) - ) + f"Expected backend_type_ to be a str, received: {type(backend_type_)}" ) if config_ is not None and not isinstance(config_, dict): raise Exception( - "Expected config_ to be a Mapping, received: {}".format(type(config_)) + f"Expected config_ to be a Mapping, received: {type(config_)}" ) if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception( - "Expected id__ to be a str, received: {}".format(type(id__)) - ) + raise Exception(f"Expected id__ to be a str, received: {type(id__)}") if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if token_rotate_interval_ is not None and not isinstance( token_rotate_interval_, int ): raise Exception( - "Expected token_rotate_interval_ to be a int, received: {}".format( - type(token_rotate_interval_) - ) + f"Expected token_rotate_interval_ to be a int, received: {type(token_rotate_interval_)}" ) self.secretbackend = secretbackend_ @@ -1169,16 +1034,12 @@ class AddSecretBackendArgs(Type): _toPy = {"args": "args"} def __init__(self, args=None, **unknown_fields): - """ - args : typing.Sequence[~AddSecretBackendArg] - """ + """Args : typing.Sequence[~AddSecretBackendArg]""" args_ = [AddSecretBackendArg.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception( - "Expected args_ to be a Sequence, received: {}".format(type(args_)) - ) + raise Exception(f"Expected args_ to be a Sequence, received: {type(args_)}") self.args = args_ self.unknown_fields = unknown_fields @@ -1189,9 +1050,7 @@ class AddStorageDetails(Type): _toPy = {"storage-tags": "storage_tags"} def __init__(self, storage_tags=None, **unknown_fields): - """ - storage_tags : typing.Sequence[str] - """ + """storage_tags : typing.Sequence[str]""" storage_tags_ = storage_tags # Validate arguments against known Juju API types. @@ -1199,9 +1058,7 @@ def __init__(self, storage_tags=None, **unknown_fields): storage_tags_, (bytes, str, list) ): raise Exception( - "Expected storage_tags_ to be a Sequence, received: {}".format( - type(storage_tags_) - ) + f"Expected storage_tags_ to be a Sequence, received: {type(storage_tags_)}" ) self.storage_tags = storage_tags_ @@ -1213,8 +1070,7 @@ class AddStorageResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : AddStorageDetails """ error_ = Error.from_json(error) if error else None @@ -1222,15 +1078,11 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance(result_, (dict, AddStorageDetails)): raise Exception( - "Expected result_ to be a AddStorageDetails, received: {}".format( - type(result_) - ) + f"Expected result_ to be a AddStorageDetails, received: {type(result_)}" ) self.error = error_ @@ -1243,17 +1095,13 @@ class AddStorageResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~AddStorageResult] - """ + """Results : typing.Sequence[~AddStorageResult]""" results_ = [AddStorageResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -1275,8 +1123,7 @@ class AddUser(Type): def __init__( self, display_name=None, password=None, username=None, **unknown_fields ): - """ - display_name : str + """display_name : str password : str username : str """ @@ -1287,19 +1134,17 @@ def __init__( # Validate arguments against known Juju API types. if display_name_ is not None and not isinstance(display_name_, (bytes, str)): raise Exception( - "Expected display_name_ to be a str, received: {}".format( - type(display_name_) - ) + f"Expected display_name_ to be a str, received: {type(display_name_)}" ) if password_ is not None and not isinstance(password_, (bytes, str)): raise Exception( - "Expected password_ to be a str, received: {}".format(type(password_)) + f"Expected password_ to be a str, received: {type(password_)}" ) if username_ is not None and not isinstance(username_, (bytes, str)): raise Exception( - "Expected username_ to be a str, received: {}".format(type(username_)) + f"Expected username_ to be a str, received: {type(username_)}" ) self.display_name = display_name_ @@ -1313,8 +1158,7 @@ class AddUserResult(Type): _toPy = {"error": "error", "secret-key": "secret_key", "tag": "tag"} def __init__(self, error=None, secret_key=None, tag=None, **unknown_fields): - """ - error : Error + """Error : Error secret_key : typing.Sequence[int] tag : str """ @@ -1324,21 +1168,15 @@ def __init__(self, error=None, secret_key=None, tag=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if secret_key_ is not None and not isinstance(secret_key_, (bytes, str, list)): raise Exception( - "Expected secret_key_ to be a Sequence, received: {}".format( - type(secret_key_) - ) + f"Expected secret_key_ to be a Sequence, received: {type(secret_key_)}" ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception( - "Expected tag_ to be a str, received: {}".format(type(tag_)) - ) + raise Exception(f"Expected tag_ to be a str, received: {type(tag_)}") self.error = error_ self.secret_key = secret_key_ @@ -1351,17 +1189,13 @@ class AddUserResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~AddUserResult] - """ + """Results : typing.Sequence[~AddUserResult]""" results_ = [AddUserResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -1373,15 +1207,13 @@ class AddUsers(Type): _toPy = {"users": "users"} def __init__(self, users=None, **unknown_fields): - """ - users : typing.Sequence[~AddUser] - """ + """Users : typing.Sequence[~AddUser]""" users_ = [AddUser.from_json(o) for o in users or []] # Validate arguments against known Juju API types. if users_ is not None and not isinstance(users_, (bytes, str, list)): raise Exception( - "Expected users_ to be a Sequence, received: {}".format(type(users_)) + f"Expected users_ to be a Sequence, received: {type(users_)}" ) self.users = users_ @@ -1422,8 +1254,7 @@ def __init__( value=None, **unknown_fields, ): - """ - cidr : str + """Cidr : str config_type : str is_secondary : bool scope : str @@ -1443,50 +1274,36 @@ def __init__( # Validate arguments against known Juju API types. if cidr_ is not None and not isinstance(cidr_, (bytes, str)): - raise Exception( - "Expected cidr_ to be a str, received: {}".format(type(cidr_)) - ) + raise Exception(f"Expected cidr_ to be a str, received: {type(cidr_)}") if config_type_ is not None and not isinstance(config_type_, (bytes, str)): raise Exception( - "Expected config_type_ to be a str, received: {}".format( - type(config_type_) - ) + f"Expected config_type_ to be a str, received: {type(config_type_)}" ) if is_secondary_ is not None and not isinstance(is_secondary_, bool): raise Exception( - "Expected is_secondary_ to be a bool, received: {}".format( - type(is_secondary_) - ) + f"Expected is_secondary_ to be a bool, received: {type(is_secondary_)}" ) if scope_ is not None and not isinstance(scope_, (bytes, str)): - raise Exception( - "Expected scope_ to be a str, received: {}".format(type(scope_)) - ) + raise Exception(f"Expected scope_ to be a str, received: {type(scope_)}") if space_id_ is not None and not isinstance(space_id_, (bytes, str)): raise Exception( - "Expected space_id_ to be a str, received: {}".format(type(space_id_)) + f"Expected space_id_ to be a str, received: {type(space_id_)}" ) if space_name_ is not None and not isinstance(space_name_, (bytes, str)): raise Exception( - "Expected space_name_ to be a str, received: {}".format( - type(space_name_) - ) + f"Expected space_name_ to be a str, received: {type(space_name_)}" ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") if value_ is not None and not isinstance(value_, (bytes, str)): - raise Exception( - "Expected value_ to be a str, received: {}".format(type(value_)) - ) + raise Exception(f"Expected value_ to be a str, received: {type(value_)}") self.cidr = cidr_ self.config_type = config_type_ @@ -1504,17 +1321,13 @@ class AllWatcherId(Type): _toPy = {"watcher-id": "watcher_id"} def __init__(self, watcher_id=None, **unknown_fields): - """ - watcher_id : str - """ + """watcher_id : str""" watcher_id_ = watcher_id # Validate arguments against known Juju API types. if watcher_id_ is not None and not isinstance(watcher_id_, (bytes, str)): raise Exception( - "Expected watcher_id_ to be a str, received: {}".format( - type(watcher_id_) - ) + f"Expected watcher_id_ to be a str, received: {type(watcher_id_)}" ) self.watcher_id = watcher_id_ @@ -1526,15 +1339,13 @@ class AllWatcherNextResults(Type): _toPy = {"deltas": "deltas"} def __init__(self, deltas=None, **unknown_fields): - """ - deltas : typing.Sequence[~Delta] - """ + """Deltas : typing.Sequence[~Delta]""" deltas_ = [Delta.from_json(o) for o in deltas or []] # Validate arguments against known Juju API types. if deltas_ is not None and not isinstance(deltas_, (bytes, str, list)): raise Exception( - "Expected deltas_ to be a Sequence, received: {}".format(type(deltas_)) + f"Expected deltas_ to be a Sequence, received: {type(deltas_)}" ) self.deltas = deltas_ @@ -1546,8 +1357,7 @@ class AnnotationsGetResult(Type): _toPy = {"annotations": "annotations", "entity": "entity", "error": "error"} def __init__(self, annotations=None, entity=None, error=None, **unknown_fields): - """ - annotations : typing.Mapping[str, str] + """Annotations : typing.Mapping[str, str] entity : str error : ErrorResult """ @@ -1558,19 +1368,15 @@ def __init__(self, annotations=None, entity=None, error=None, **unknown_fields): # Validate arguments against known Juju API types. if annotations_ is not None and not isinstance(annotations_, dict): raise Exception( - "Expected annotations_ to be a Mapping, received: {}".format( - type(annotations_) - ) + f"Expected annotations_ to be a Mapping, received: {type(annotations_)}" ) if entity_ is not None and not isinstance(entity_, (bytes, str)): - raise Exception( - "Expected entity_ to be a str, received: {}".format(type(entity_)) - ) + raise Exception(f"Expected entity_ to be a str, received: {type(entity_)}") if error_ is not None and not isinstance(error_, (dict, ErrorResult)): raise Exception( - "Expected error_ to be a ErrorResult, received: {}".format(type(error_)) + f"Expected error_ to be a ErrorResult, received: {type(error_)}" ) self.annotations = annotations_ @@ -1584,17 +1390,13 @@ class AnnotationsGetResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~AnnotationsGetResult] - """ + """Results : typing.Sequence[~AnnotationsGetResult]""" results_ = [AnnotationsGetResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -1606,9 +1408,7 @@ class AnnotationsSet(Type): _toPy = {"annotations": "annotations"} def __init__(self, annotations=None, **unknown_fields): - """ - annotations : typing.Sequence[~EntityAnnotations] - """ + """Annotations : typing.Sequence[~EntityAnnotations]""" annotations_ = [EntityAnnotations.from_json(o) for o in annotations or []] # Validate arguments against known Juju API types. @@ -1616,9 +1416,7 @@ def __init__(self, annotations=None, **unknown_fields): annotations_, (bytes, str, list) ): raise Exception( - "Expected annotations_ to be a Sequence, received: {}".format( - type(annotations_) - ) + f"Expected annotations_ to be a Sequence, received: {type(annotations_)}" ) self.annotations = annotations_ @@ -1640,8 +1438,7 @@ class ApplicationCharmActionsResult(Type): def __init__( self, actions=None, application_tag=None, error=None, **unknown_fields ): - """ - actions : typing.Mapping[str, ~ActionSpec] + """Actions : typing.Mapping[str, ~ActionSpec] application_tag : str error : Error """ @@ -1652,22 +1449,18 @@ def __init__( # Validate arguments against known Juju API types. if actions_ is not None and not isinstance(actions_, dict): raise Exception( - "Expected actions_ to be a Mapping, received: {}".format(type(actions_)) + f"Expected actions_ to be a Mapping, received: {type(actions_)}" ) if application_tag_ is not None and not isinstance( application_tag_, (bytes, str) ): raise Exception( - "Expected application_tag_ to be a str, received: {}".format( - type(application_tag_) - ) + f"Expected application_tag_ to be a str, received: {type(application_tag_)}" ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") self.actions = actions_ self.application_tag = application_tag_ @@ -1680,8 +1473,7 @@ class ApplicationCharmPlacement(Type): _toPy = {"application": "application", "charm-url": "charm_url"} def __init__(self, application=None, charm_url=None, **unknown_fields): - """ - application : str + """Application : str charm_url : str """ application_ = application @@ -1690,14 +1482,12 @@ def __init__(self, application=None, charm_url=None, **unknown_fields): # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): raise Exception( - "Expected application_ to be a str, received: {}".format( - type(application_) - ) + f"Expected application_ to be a str, received: {type(application_)}" ) if charm_url_ is not None and not isinstance(charm_url_, (bytes, str)): raise Exception( - "Expected charm_url_ to be a str, received: {}".format(type(charm_url_)) + f"Expected charm_url_ to be a str, received: {type(charm_url_)}" ) self.application = application_ @@ -1710,17 +1500,13 @@ class ApplicationCharmPlacements(Type): _toPy = {"placements": "placements"} def __init__(self, placements=None, **unknown_fields): - """ - placements : typing.Sequence[~ApplicationCharmPlacement] - """ + """Placements : typing.Sequence[~ApplicationCharmPlacement]""" placements_ = [ApplicationCharmPlacement.from_json(o) for o in placements or []] # Validate arguments against known Juju API types. if placements_ is not None and not isinstance(placements_, (bytes, str, list)): raise Exception( - "Expected placements_ to be a Sequence, received: {}".format( - type(placements_) - ) + f"Expected placements_ to be a Sequence, received: {type(placements_)}" ) self.placements = placements_ @@ -1732,17 +1518,13 @@ class ApplicationCharmRelations(Type): _toPy = {"application": "application"} def __init__(self, application=None, **unknown_fields): - """ - application : str - """ + """Application : str""" application_ = application # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): raise Exception( - "Expected application_ to be a str, received: {}".format( - type(application_) - ) + f"Expected application_ to be a str, received: {type(application_)}" ) self.application = application_ @@ -1754,9 +1536,7 @@ class ApplicationCharmRelationsResults(Type): _toPy = {"charm-relations": "charm_relations"} def __init__(self, charm_relations=None, **unknown_fields): - """ - charm_relations : typing.Sequence[str] - """ + """charm_relations : typing.Sequence[str]""" charm_relations_ = charm_relations # Validate arguments against known Juju API types. @@ -1764,9 +1544,7 @@ def __init__(self, charm_relations=None, **unknown_fields): charm_relations_, (bytes, str, list) ): raise Exception( - "Expected charm_relations_ to be a Sequence, received: {}".format( - type(charm_relations_) - ) + f"Expected charm_relations_ to be a Sequence, received: {type(charm_relations_)}" ) self.charm_relations = charm_relations_ @@ -1778,16 +1556,12 @@ class ApplicationConfigUnsetArgs(Type): _toPy = {"Args": "args"} def __init__(self, args=None, **unknown_fields): - """ - args : typing.Sequence[~ApplicationUnset] - """ + """Args : typing.Sequence[~ApplicationUnset]""" args_ = [ApplicationUnset.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception( - "Expected args_ to be a Sequence, received: {}".format(type(args_)) - ) + raise Exception(f"Expected args_ to be a Sequence, received: {type(args_)}") self.args = args_ self.unknown_fields = unknown_fields @@ -1798,8 +1572,7 @@ class ApplicationConstraint(Type): _toPy = {"constraints": "constraints", "error": "error"} def __init__(self, constraints=None, error=None, **unknown_fields): - """ - constraints : Value + """Constraints : Value error : Error """ constraints_ = Value.from_json(constraints) if constraints else None @@ -1808,15 +1581,11 @@ def __init__(self, constraints=None, error=None, **unknown_fields): # Validate arguments against known Juju API types. if constraints_ is not None and not isinstance(constraints_, (dict, Value)): raise Exception( - "Expected constraints_ to be a Value, received: {}".format( - type(constraints_) - ) + f"Expected constraints_ to be a Value, received: {type(constraints_)}" ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") self.constraints = constraints_ self.error = error_ @@ -1881,8 +1650,7 @@ def __init__( storage=None, **unknown_fields, ): - """ - force : bool + """Force : bool application : str attach_storage : typing.Sequence[str] channel : str @@ -1918,103 +1686,83 @@ def __init__( # Validate arguments against known Juju API types. if force_ is not None and not isinstance(force_, bool): - raise Exception( - "Expected force_ to be a bool, received: {}".format(type(force_)) - ) + raise Exception(f"Expected force_ to be a bool, received: {type(force_)}") if application_ is not None and not isinstance(application_, (bytes, str)): raise Exception( - "Expected application_ to be a str, received: {}".format( - type(application_) - ) + f"Expected application_ to be a str, received: {type(application_)}" ) if attach_storage_ is not None and not isinstance( attach_storage_, (bytes, str, list) ): raise Exception( - "Expected attach_storage_ to be a Sequence, received: {}".format( - type(attach_storage_) - ) + f"Expected attach_storage_ to be a Sequence, received: {type(attach_storage_)}" ) if channel_ is not None and not isinstance(channel_, (bytes, str)): raise Exception( - "Expected channel_ to be a str, received: {}".format(type(channel_)) + f"Expected channel_ to be a str, received: {type(channel_)}" ) if charm_origin_ is not None and not isinstance( charm_origin_, (dict, CharmOrigin) ): raise Exception( - "Expected charm_origin_ to be a CharmOrigin, received: {}".format( - type(charm_origin_) - ) + f"Expected charm_origin_ to be a CharmOrigin, received: {type(charm_origin_)}" ) if charm_url_ is not None and not isinstance(charm_url_, (bytes, str)): raise Exception( - "Expected charm_url_ to be a str, received: {}".format(type(charm_url_)) + f"Expected charm_url_ to be a str, received: {type(charm_url_)}" ) if config_ is not None and not isinstance(config_, dict): raise Exception( - "Expected config_ to be a Mapping, received: {}".format(type(config_)) + f"Expected config_ to be a Mapping, received: {type(config_)}" ) if config_yaml_ is not None and not isinstance(config_yaml_, (bytes, str)): raise Exception( - "Expected config_yaml_ to be a str, received: {}".format( - type(config_yaml_) - ) + f"Expected config_yaml_ to be a str, received: {type(config_yaml_)}" ) if constraints_ is not None and not isinstance(constraints_, (dict, Value)): raise Exception( - "Expected constraints_ to be a Value, received: {}".format( - type(constraints_) - ) + f"Expected constraints_ to be a Value, received: {type(constraints_)}" ) if devices_ is not None and not isinstance(devices_, dict): raise Exception( - "Expected devices_ to be a Mapping, received: {}".format(type(devices_)) + f"Expected devices_ to be a Mapping, received: {type(devices_)}" ) if endpoint_bindings_ is not None and not isinstance(endpoint_bindings_, dict): raise Exception( - "Expected endpoint_bindings_ to be a Mapping, received: {}".format( - type(endpoint_bindings_) - ) + f"Expected endpoint_bindings_ to be a Mapping, received: {type(endpoint_bindings_)}" ) if num_units_ is not None and not isinstance(num_units_, int): raise Exception( - "Expected num_units_ to be a int, received: {}".format(type(num_units_)) + f"Expected num_units_ to be a int, received: {type(num_units_)}" ) if placement_ is not None and not isinstance(placement_, (bytes, str, list)): raise Exception( - "Expected placement_ to be a Sequence, received: {}".format( - type(placement_) - ) + f"Expected placement_ to be a Sequence, received: {type(placement_)}" ) if policy_ is not None and not isinstance(policy_, (bytes, str)): - raise Exception( - "Expected policy_ to be a str, received: {}".format(type(policy_)) - ) + raise Exception(f"Expected policy_ to be a str, received: {type(policy_)}") if resources_ is not None and not isinstance(resources_, dict): raise Exception( - "Expected resources_ to be a Mapping, received: {}".format( - type(resources_) - ) + f"Expected resources_ to be a Mapping, received: {type(resources_)}" ) if storage_ is not None and not isinstance(storage_, dict): raise Exception( - "Expected storage_ to be a Mapping, received: {}".format(type(storage_)) + f"Expected storage_ to be a Mapping, received: {type(storage_)}" ) self.force = force_ @@ -2041,8 +1789,7 @@ class ApplicationExpose(Type): _toPy = {"application": "application", "exposed-endpoints": "exposed_endpoints"} def __init__(self, application=None, exposed_endpoints=None, **unknown_fields): - """ - application : str + """Application : str exposed_endpoints : typing.Mapping[str, ~ExposedEndpoint] """ application_ = application @@ -2054,16 +1801,12 @@ def __init__(self, application=None, exposed_endpoints=None, **unknown_fields): # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): raise Exception( - "Expected application_ to be a str, received: {}".format( - type(application_) - ) + f"Expected application_ to be a str, received: {type(application_)}" ) if exposed_endpoints_ is not None and not isinstance(exposed_endpoints_, dict): raise Exception( - "Expected exposed_endpoints_ to be a Mapping, received: {}".format( - type(exposed_endpoints_) - ) + f"Expected exposed_endpoints_ to be a Mapping, received: {type(exposed_endpoints_)}" ) self.application = application_ @@ -2076,8 +1819,7 @@ class ApplicationGet(Type): _toPy = {"application": "application", "branch": "branch"} def __init__(self, application=None, branch=None, **unknown_fields): - """ - application : str + """Application : str branch : str """ application_ = application @@ -2086,15 +1828,11 @@ def __init__(self, application=None, branch=None, **unknown_fields): # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): raise Exception( - "Expected application_ to be a str, received: {}".format( - type(application_) - ) + f"Expected application_ to be a str, received: {type(application_)}" ) if branch_ is not None and not isinstance(branch_, (bytes, str)): - raise Exception( - "Expected branch_ to be a str, received: {}".format(type(branch_)) - ) + raise Exception(f"Expected branch_ to be a str, received: {type(branch_)}") self.application = application_ self.branch = branch_ @@ -2106,16 +1844,12 @@ class ApplicationGetArgs(Type): _toPy = {"args": "args"} def __init__(self, args=None, **unknown_fields): - """ - args : typing.Sequence[~ApplicationGet] - """ + """Args : typing.Sequence[~ApplicationGet]""" args_ = [ApplicationGet.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception( - "Expected args_ to be a Sequence, received: {}".format(type(args_)) - ) + raise Exception(f"Expected args_ to be a Sequence, received: {type(args_)}") self.args = args_ self.unknown_fields = unknown_fields @@ -2126,17 +1860,13 @@ class ApplicationGetConfigResults(Type): _toPy = {"Results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~ConfigResult] - """ + """Results : typing.Sequence[~ConfigResult]""" results_ = [ConfigResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -2148,17 +1878,13 @@ class ApplicationGetConstraintsResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~ApplicationConstraint] - """ + """Results : typing.Sequence[~ApplicationConstraint]""" results_ = [ApplicationConstraint.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -2199,8 +1925,7 @@ def __init__( endpoint_bindings=None, **unknown_fields, ): - """ - application : str + """Application : str application_config : typing.Mapping[str, typing.Any] base : Base channel : str @@ -2221,52 +1946,40 @@ def __init__( # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): raise Exception( - "Expected application_ to be a str, received: {}".format( - type(application_) - ) + f"Expected application_ to be a str, received: {type(application_)}" ) if application_config_ is not None and not isinstance( application_config_, dict ): raise Exception( - "Expected application_config_ to be a Mapping, received: {}".format( - type(application_config_) - ) + f"Expected application_config_ to be a Mapping, received: {type(application_config_)}" ) if base_ is not None and not isinstance(base_, (dict, Base)): - raise Exception( - "Expected base_ to be a Base, received: {}".format(type(base_)) - ) + raise Exception(f"Expected base_ to be a Base, received: {type(base_)}") if channel_ is not None and not isinstance(channel_, (bytes, str)): raise Exception( - "Expected channel_ to be a str, received: {}".format(type(channel_)) + f"Expected channel_ to be a str, received: {type(channel_)}" ) if charm_ is not None and not isinstance(charm_, (bytes, str)): - raise Exception( - "Expected charm_ to be a str, received: {}".format(type(charm_)) - ) + raise Exception(f"Expected charm_ to be a str, received: {type(charm_)}") if config_ is not None and not isinstance(config_, dict): raise Exception( - "Expected config_ to be a Mapping, received: {}".format(type(config_)) + f"Expected config_ to be a Mapping, received: {type(config_)}" ) if constraints_ is not None and not isinstance(constraints_, (dict, Value)): raise Exception( - "Expected constraints_ to be a Value, received: {}".format( - type(constraints_) - ) + f"Expected constraints_ to be a Value, received: {type(constraints_)}" ) if endpoint_bindings_ is not None and not isinstance(endpoint_bindings_, dict): raise Exception( - "Expected endpoint_bindings_ to be a Mapping, received: {}".format( - type(endpoint_bindings_) - ) + f"Expected endpoint_bindings_ to be a Mapping, received: {type(endpoint_bindings_)}" ) self.application = application_ @@ -2285,8 +1998,7 @@ class ApplicationInfoResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : ApplicationResult """ error_ = Error.from_json(error) if error else None @@ -2294,15 +2006,11 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance(result_, (dict, ApplicationResult)): raise Exception( - "Expected result_ to be a ApplicationResult, received: {}".format( - type(result_) - ) + f"Expected result_ to be a ApplicationResult, received: {type(result_)}" ) self.error = error_ @@ -2315,17 +2023,13 @@ class ApplicationInfoResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~ApplicationInfoResult] - """ + """Results : typing.Sequence[~ApplicationInfoResult]""" results_ = [ApplicationInfoResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -2347,8 +2051,7 @@ class ApplicationMergeBindings(Type): def __init__( self, application_tag=None, bindings=None, force=None, **unknown_fields ): - """ - application_tag : str + """application_tag : str bindings : typing.Mapping[str, str] force : bool """ @@ -2361,22 +2064,16 @@ def __init__( application_tag_, (bytes, str) ): raise Exception( - "Expected application_tag_ to be a str, received: {}".format( - type(application_tag_) - ) + f"Expected application_tag_ to be a str, received: {type(application_tag_)}" ) if bindings_ is not None and not isinstance(bindings_, dict): raise Exception( - "Expected bindings_ to be a Mapping, received: {}".format( - type(bindings_) - ) + f"Expected bindings_ to be a Mapping, received: {type(bindings_)}" ) if force_ is not None and not isinstance(force_, bool): - raise Exception( - "Expected force_ to be a bool, received: {}".format(type(force_)) - ) + raise Exception(f"Expected force_ to be a bool, received: {type(force_)}") self.application_tag = application_tag_ self.bindings = bindings_ @@ -2389,16 +2086,12 @@ class ApplicationMergeBindingsArgs(Type): _toPy = {"args": "args"} def __init__(self, args=None, **unknown_fields): - """ - args : typing.Sequence[~ApplicationMergeBindings] - """ + """Args : typing.Sequence[~ApplicationMergeBindings]""" args_ = [ApplicationMergeBindings.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception( - "Expected args_ to be a Sequence, received: {}".format(type(args_)) - ) + raise Exception(f"Expected args_ to be a Sequence, received: {type(args_)}") self.args = args_ self.unknown_fields = unknown_fields @@ -2412,8 +2105,7 @@ class ApplicationMetricCredential(Type): _toPy = {"application": "application", "metrics-credentials": "metrics_credentials"} def __init__(self, application=None, metrics_credentials=None, **unknown_fields): - """ - application : str + """Application : str metrics_credentials : typing.Sequence[int] """ application_ = application @@ -2422,18 +2114,14 @@ def __init__(self, application=None, metrics_credentials=None, **unknown_fields) # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): raise Exception( - "Expected application_ to be a str, received: {}".format( - type(application_) - ) + f"Expected application_ to be a str, received: {type(application_)}" ) if metrics_credentials_ is not None and not isinstance( metrics_credentials_, (bytes, str, list) ): raise Exception( - "Expected metrics_credentials_ to be a Sequence, received: {}".format( - type(metrics_credentials_) - ) + f"Expected metrics_credentials_ to be a Sequence, received: {type(metrics_credentials_)}" ) self.application = application_ @@ -2446,15 +2134,13 @@ class ApplicationMetricCredentials(Type): _toPy = {"creds": "creds"} def __init__(self, creds=None, **unknown_fields): - """ - creds : typing.Sequence[~ApplicationMetricCredential] - """ + """Creds : typing.Sequence[~ApplicationMetricCredential]""" creds_ = [ApplicationMetricCredential.from_json(o) for o in creds or []] # Validate arguments against known Juju API types. if creds_ is not None and not isinstance(creds_, (bytes, str, list)): raise Exception( - "Expected creds_ to be a Sequence, received: {}".format(type(creds_)) + f"Expected creds_ to be a Sequence, received: {type(creds_)}" ) self.creds = creds_ @@ -2510,8 +2196,7 @@ def __init__( users=None, **unknown_fields, ): - """ - applicationofferdetails : ApplicationOfferDetails + """Applicationofferdetails : ApplicationOfferDetails application_description : str application_name : str bindings : typing.Mapping[str, str] @@ -2548,93 +2233,75 @@ def __init__( applicationofferdetails_, (dict, ApplicationOfferDetails) ): raise Exception( - "Expected applicationofferdetails_ to be a ApplicationOfferDetails, received: {}".format( - type(applicationofferdetails_) - ) + f"Expected applicationofferdetails_ to be a ApplicationOfferDetails, received: {type(applicationofferdetails_)}" ) if application_description_ is not None and not isinstance( application_description_, (bytes, str) ): raise Exception( - "Expected application_description_ to be a str, received: {}".format( - type(application_description_) - ) + f"Expected application_description_ to be a str, received: {type(application_description_)}" ) if application_name_ is not None and not isinstance( application_name_, (bytes, str) ): raise Exception( - "Expected application_name_ to be a str, received: {}".format( - type(application_name_) - ) + f"Expected application_name_ to be a str, received: {type(application_name_)}" ) if bindings_ is not None and not isinstance(bindings_, dict): raise Exception( - "Expected bindings_ to be a Mapping, received: {}".format( - type(bindings_) - ) + f"Expected bindings_ to be a Mapping, received: {type(bindings_)}" ) if charm_url_ is not None and not isinstance(charm_url_, (bytes, str)): raise Exception( - "Expected charm_url_ to be a str, received: {}".format(type(charm_url_)) + f"Expected charm_url_ to be a str, received: {type(charm_url_)}" ) if connections_ is not None and not isinstance( connections_, (bytes, str, list) ): raise Exception( - "Expected connections_ to be a Sequence, received: {}".format( - type(connections_) - ) + f"Expected connections_ to be a Sequence, received: {type(connections_)}" ) if endpoints_ is not None and not isinstance(endpoints_, (bytes, str, list)): raise Exception( - "Expected endpoints_ to be a Sequence, received: {}".format( - type(endpoints_) - ) + f"Expected endpoints_ to be a Sequence, received: {type(endpoints_)}" ) if offer_name_ is not None and not isinstance(offer_name_, (bytes, str)): raise Exception( - "Expected offer_name_ to be a str, received: {}".format( - type(offer_name_) - ) + f"Expected offer_name_ to be a str, received: {type(offer_name_)}" ) if offer_url_ is not None and not isinstance(offer_url_, (bytes, str)): raise Exception( - "Expected offer_url_ to be a str, received: {}".format(type(offer_url_)) + f"Expected offer_url_ to be a str, received: {type(offer_url_)}" ) if offer_uuid_ is not None and not isinstance(offer_uuid_, (bytes, str)): raise Exception( - "Expected offer_uuid_ to be a str, received: {}".format( - type(offer_uuid_) - ) + f"Expected offer_uuid_ to be a str, received: {type(offer_uuid_)}" ) if source_model_tag_ is not None and not isinstance( source_model_tag_, (bytes, str) ): raise Exception( - "Expected source_model_tag_ to be a str, received: {}".format( - type(source_model_tag_) - ) + f"Expected source_model_tag_ to be a str, received: {type(source_model_tag_)}" ) if spaces_ is not None and not isinstance(spaces_, (bytes, str, list)): raise Exception( - "Expected spaces_ to be a Sequence, received: {}".format(type(spaces_)) + f"Expected spaces_ to be a Sequence, received: {type(spaces_)}" ) if users_ is not None and not isinstance(users_, (bytes, str, list)): raise Exception( - "Expected users_ to be a Sequence, received: {}".format(type(users_)) + f"Expected users_ to be a Sequence, received: {type(users_)}" ) self.applicationofferdetails = applicationofferdetails_ @@ -2696,8 +2363,7 @@ def __init__( users=None, **unknown_fields, ): - """ - applicationofferdetailsv5 : ApplicationOfferDetailsV5 + """applicationofferdetailsv5 : ApplicationOfferDetailsV5 application_description : str application_name : str charm_url : str @@ -2730,81 +2396,65 @@ def __init__( applicationofferdetailsv5_, (dict, ApplicationOfferDetailsV5) ): raise Exception( - "Expected applicationofferdetailsv5_ to be a ApplicationOfferDetailsV5, received: {}".format( - type(applicationofferdetailsv5_) - ) + f"Expected applicationofferdetailsv5_ to be a ApplicationOfferDetailsV5, received: {type(applicationofferdetailsv5_)}" ) if application_description_ is not None and not isinstance( application_description_, (bytes, str) ): raise Exception( - "Expected application_description_ to be a str, received: {}".format( - type(application_description_) - ) + f"Expected application_description_ to be a str, received: {type(application_description_)}" ) if application_name_ is not None and not isinstance( application_name_, (bytes, str) ): raise Exception( - "Expected application_name_ to be a str, received: {}".format( - type(application_name_) - ) + f"Expected application_name_ to be a str, received: {type(application_name_)}" ) if charm_url_ is not None and not isinstance(charm_url_, (bytes, str)): raise Exception( - "Expected charm_url_ to be a str, received: {}".format(type(charm_url_)) + f"Expected charm_url_ to be a str, received: {type(charm_url_)}" ) if connections_ is not None and not isinstance( connections_, (bytes, str, list) ): raise Exception( - "Expected connections_ to be a Sequence, received: {}".format( - type(connections_) - ) + f"Expected connections_ to be a Sequence, received: {type(connections_)}" ) if endpoints_ is not None and not isinstance(endpoints_, (bytes, str, list)): raise Exception( - "Expected endpoints_ to be a Sequence, received: {}".format( - type(endpoints_) - ) + f"Expected endpoints_ to be a Sequence, received: {type(endpoints_)}" ) if offer_name_ is not None and not isinstance(offer_name_, (bytes, str)): raise Exception( - "Expected offer_name_ to be a str, received: {}".format( - type(offer_name_) - ) + f"Expected offer_name_ to be a str, received: {type(offer_name_)}" ) if offer_url_ is not None and not isinstance(offer_url_, (bytes, str)): raise Exception( - "Expected offer_url_ to be a str, received: {}".format(type(offer_url_)) + f"Expected offer_url_ to be a str, received: {type(offer_url_)}" ) if offer_uuid_ is not None and not isinstance(offer_uuid_, (bytes, str)): raise Exception( - "Expected offer_uuid_ to be a str, received: {}".format( - type(offer_uuid_) - ) + f"Expected offer_uuid_ to be a str, received: {type(offer_uuid_)}" ) if source_model_tag_ is not None and not isinstance( source_model_tag_, (bytes, str) ): raise Exception( - "Expected source_model_tag_ to be a str, received: {}".format( - type(source_model_tag_) - ) + f"Expected source_model_tag_ to be a str, received: {type(source_model_tag_)}" ) if users_ is not None and not isinstance(users_, (bytes, str, list)): raise Exception( - "Expected users_ to be a Sequence, received: {}".format(type(users_)) + f"Expected users_ to be a Sequence, received: {type(users_)}" ) self.applicationofferdetailsv5 = applicationofferdetailsv5_ @@ -2858,8 +2508,7 @@ def __init__( users=None, **unknown_fields, ): - """ - application_description : str + """application_description : str bindings : typing.Mapping[str, str] endpoints : typing.Sequence[~RemoteEndpoint] offer_name : str @@ -2884,61 +2533,49 @@ def __init__( application_description_, (bytes, str) ): raise Exception( - "Expected application_description_ to be a str, received: {}".format( - type(application_description_) - ) + f"Expected application_description_ to be a str, received: {type(application_description_)}" ) if bindings_ is not None and not isinstance(bindings_, dict): raise Exception( - "Expected bindings_ to be a Mapping, received: {}".format( - type(bindings_) - ) + f"Expected bindings_ to be a Mapping, received: {type(bindings_)}" ) if endpoints_ is not None and not isinstance(endpoints_, (bytes, str, list)): raise Exception( - "Expected endpoints_ to be a Sequence, received: {}".format( - type(endpoints_) - ) + f"Expected endpoints_ to be a Sequence, received: {type(endpoints_)}" ) if offer_name_ is not None and not isinstance(offer_name_, (bytes, str)): raise Exception( - "Expected offer_name_ to be a str, received: {}".format( - type(offer_name_) - ) + f"Expected offer_name_ to be a str, received: {type(offer_name_)}" ) if offer_url_ is not None and not isinstance(offer_url_, (bytes, str)): raise Exception( - "Expected offer_url_ to be a str, received: {}".format(type(offer_url_)) + f"Expected offer_url_ to be a str, received: {type(offer_url_)}" ) if offer_uuid_ is not None and not isinstance(offer_uuid_, (bytes, str)): raise Exception( - "Expected offer_uuid_ to be a str, received: {}".format( - type(offer_uuid_) - ) + f"Expected offer_uuid_ to be a str, received: {type(offer_uuid_)}" ) if source_model_tag_ is not None and not isinstance( source_model_tag_, (bytes, str) ): raise Exception( - "Expected source_model_tag_ to be a str, received: {}".format( - type(source_model_tag_) - ) + f"Expected source_model_tag_ to be a str, received: {type(source_model_tag_)}" ) if spaces_ is not None and not isinstance(spaces_, (bytes, str, list)): raise Exception( - "Expected spaces_ to be a Sequence, received: {}".format(type(spaces_)) + f"Expected spaces_ to be a Sequence, received: {type(spaces_)}" ) if users_ is not None and not isinstance(users_, (bytes, str, list)): raise Exception( - "Expected users_ to be a Sequence, received: {}".format(type(users_)) + f"Expected users_ to be a Sequence, received: {type(users_)}" ) self.application_description = application_description_ @@ -2984,8 +2621,7 @@ def __init__( users=None, **unknown_fields, ): - """ - application_description : str + """application_description : str endpoints : typing.Sequence[~RemoteEndpoint] offer_name : str offer_url : str @@ -3006,49 +2642,39 @@ def __init__( application_description_, (bytes, str) ): raise Exception( - "Expected application_description_ to be a str, received: {}".format( - type(application_description_) - ) + f"Expected application_description_ to be a str, received: {type(application_description_)}" ) if endpoints_ is not None and not isinstance(endpoints_, (bytes, str, list)): raise Exception( - "Expected endpoints_ to be a Sequence, received: {}".format( - type(endpoints_) - ) + f"Expected endpoints_ to be a Sequence, received: {type(endpoints_)}" ) if offer_name_ is not None and not isinstance(offer_name_, (bytes, str)): raise Exception( - "Expected offer_name_ to be a str, received: {}".format( - type(offer_name_) - ) + f"Expected offer_name_ to be a str, received: {type(offer_name_)}" ) if offer_url_ is not None and not isinstance(offer_url_, (bytes, str)): raise Exception( - "Expected offer_url_ to be a str, received: {}".format(type(offer_url_)) + f"Expected offer_url_ to be a str, received: {type(offer_url_)}" ) if offer_uuid_ is not None and not isinstance(offer_uuid_, (bytes, str)): raise Exception( - "Expected offer_uuid_ to be a str, received: {}".format( - type(offer_uuid_) - ) + f"Expected offer_uuid_ to be a str, received: {type(offer_uuid_)}" ) if source_model_tag_ is not None and not isinstance( source_model_tag_, (bytes, str) ): raise Exception( - "Expected source_model_tag_ to be a str, received: {}".format( - type(source_model_tag_) - ) + f"Expected source_model_tag_ to be a str, received: {type(source_model_tag_)}" ) if users_ is not None and not isinstance(users_, (bytes, str, list)): raise Exception( - "Expected users_ to be a Sequence, received: {}".format(type(users_)) + f"Expected users_ to be a Sequence, received: {type(users_)}" ) self.application_description = application_description_ @@ -3066,8 +2692,7 @@ class ApplicationOfferResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : ApplicationOfferAdminDetailsV5 """ error_ = Error.from_json(error) if error else None @@ -3075,17 +2700,13 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance( result_, (dict, ApplicationOfferAdminDetailsV5) ): raise Exception( - "Expected result_ to be a ApplicationOfferAdminDetailsV5, received: {}".format( - type(result_) - ) + f"Expected result_ to be a ApplicationOfferAdminDetailsV5, received: {type(result_)}" ) self.error = error_ @@ -3124,8 +2745,7 @@ def __init__( total_connected_count=None, **unknown_fields, ): - """ - active_connected_count : int + """active_connected_count : int application_name : str charm : str endpoints : typing.Mapping[str, ~RemoteEndpoint] @@ -3148,51 +2768,37 @@ def __init__( active_connected_count_, int ): raise Exception( - "Expected active_connected_count_ to be a int, received: {}".format( - type(active_connected_count_) - ) + f"Expected active_connected_count_ to be a int, received: {type(active_connected_count_)}" ) if application_name_ is not None and not isinstance( application_name_, (bytes, str) ): raise Exception( - "Expected application_name_ to be a str, received: {}".format( - type(application_name_) - ) + f"Expected application_name_ to be a str, received: {type(application_name_)}" ) if charm_ is not None and not isinstance(charm_, (bytes, str)): - raise Exception( - "Expected charm_ to be a str, received: {}".format(type(charm_)) - ) + raise Exception(f"Expected charm_ to be a str, received: {type(charm_)}") if endpoints_ is not None and not isinstance(endpoints_, dict): raise Exception( - "Expected endpoints_ to be a Mapping, received: {}".format( - type(endpoints_) - ) + f"Expected endpoints_ to be a Mapping, received: {type(endpoints_)}" ) if err_ is not None and not isinstance(err_, (dict, Error)): - raise Exception( - "Expected err_ to be a Error, received: {}".format(type(err_)) - ) + raise Exception(f"Expected err_ to be a Error, received: {type(err_)}") if offer_name_ is not None and not isinstance(offer_name_, (bytes, str)): raise Exception( - "Expected offer_name_ to be a str, received: {}".format( - type(offer_name_) - ) + f"Expected offer_name_ to be a str, received: {type(offer_name_)}" ) if total_connected_count_ is not None and not isinstance( total_connected_count_, int ): raise Exception( - "Expected total_connected_count_ to be a int, received: {}".format( - type(total_connected_count_) - ) + f"Expected total_connected_count_ to be a int, received: {type(total_connected_count_)}" ) self.active_connected_count = active_connected_count_ @@ -3210,17 +2816,13 @@ class ApplicationOffersResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~ApplicationOfferResult] - """ + """Results : typing.Sequence[~ApplicationOfferResult]""" results_ = [ApplicationOfferResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -3270,8 +2872,7 @@ def __init__( tag=None, **unknown_fields, ): - """ - base : Base + """Base : Base channel : str charm : str constraints : Value @@ -3300,67 +2901,49 @@ def __init__( # Validate arguments against known Juju API types. if base_ is not None and not isinstance(base_, (dict, Base)): - raise Exception( - "Expected base_ to be a Base, received: {}".format(type(base_)) - ) + raise Exception(f"Expected base_ to be a Base, received: {type(base_)}") if channel_ is not None and not isinstance(channel_, (bytes, str)): raise Exception( - "Expected channel_ to be a str, received: {}".format(type(channel_)) + f"Expected channel_ to be a str, received: {type(channel_)}" ) if charm_ is not None and not isinstance(charm_, (bytes, str)): - raise Exception( - "Expected charm_ to be a str, received: {}".format(type(charm_)) - ) + raise Exception(f"Expected charm_ to be a str, received: {type(charm_)}") if constraints_ is not None and not isinstance(constraints_, (dict, Value)): raise Exception( - "Expected constraints_ to be a Value, received: {}".format( - type(constraints_) - ) + f"Expected constraints_ to be a Value, received: {type(constraints_)}" ) if endpoint_bindings_ is not None and not isinstance(endpoint_bindings_, dict): raise Exception( - "Expected endpoint_bindings_ to be a Mapping, received: {}".format( - type(endpoint_bindings_) - ) + f"Expected endpoint_bindings_ to be a Mapping, received: {type(endpoint_bindings_)}" ) if exposed_ is not None and not isinstance(exposed_, bool): raise Exception( - "Expected exposed_ to be a bool, received: {}".format(type(exposed_)) + f"Expected exposed_ to be a bool, received: {type(exposed_)}" ) if exposed_endpoints_ is not None and not isinstance(exposed_endpoints_, dict): raise Exception( - "Expected exposed_endpoints_ to be a Mapping, received: {}".format( - type(exposed_endpoints_) - ) + f"Expected exposed_endpoints_ to be a Mapping, received: {type(exposed_endpoints_)}" ) if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception( - "Expected life_ to be a str, received: {}".format(type(life_)) - ) + raise Exception(f"Expected life_ to be a str, received: {type(life_)}") if principal_ is not None and not isinstance(principal_, bool): raise Exception( - "Expected principal_ to be a bool, received: {}".format( - type(principal_) - ) + f"Expected principal_ to be a bool, received: {type(principal_)}" ) if remote_ is not None and not isinstance(remote_, bool): - raise Exception( - "Expected remote_ to be a bool, received: {}".format(type(remote_)) - ) + raise Exception(f"Expected remote_ to be a bool, received: {type(remote_)}") if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception( - "Expected tag_ to be a str, received: {}".format(type(tag_)) - ) + raise Exception(f"Expected tag_ to be a str, received: {type(tag_)}") self.base = base_ self.channel = channel_ @@ -3425,8 +3008,7 @@ def __init__( storage_constraints=None, **unknown_fields, ): - """ - application : str + """Application : str channel : str charm_origin : CharmOrigin charm_url : str @@ -3460,93 +3042,71 @@ def __init__( # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): raise Exception( - "Expected application_ to be a str, received: {}".format( - type(application_) - ) + f"Expected application_ to be a str, received: {type(application_)}" ) if channel_ is not None and not isinstance(channel_, (bytes, str)): raise Exception( - "Expected channel_ to be a str, received: {}".format(type(channel_)) + f"Expected channel_ to be a str, received: {type(channel_)}" ) if charm_origin_ is not None and not isinstance( charm_origin_, (dict, CharmOrigin) ): raise Exception( - "Expected charm_origin_ to be a CharmOrigin, received: {}".format( - type(charm_origin_) - ) + f"Expected charm_origin_ to be a CharmOrigin, received: {type(charm_origin_)}" ) if charm_url_ is not None and not isinstance(charm_url_, (bytes, str)): raise Exception( - "Expected charm_url_ to be a str, received: {}".format(type(charm_url_)) + f"Expected charm_url_ to be a str, received: {type(charm_url_)}" ) if config_settings_ is not None and not isinstance(config_settings_, dict): raise Exception( - "Expected config_settings_ to be a Mapping, received: {}".format( - type(config_settings_) - ) + f"Expected config_settings_ to be a Mapping, received: {type(config_settings_)}" ) if config_settings_yaml_ is not None and not isinstance( config_settings_yaml_, (bytes, str) ): raise Exception( - "Expected config_settings_yaml_ to be a str, received: {}".format( - type(config_settings_yaml_) - ) + f"Expected config_settings_yaml_ to be a str, received: {type(config_settings_yaml_)}" ) if endpoint_bindings_ is not None and not isinstance(endpoint_bindings_, dict): raise Exception( - "Expected endpoint_bindings_ to be a Mapping, received: {}".format( - type(endpoint_bindings_) - ) + f"Expected endpoint_bindings_ to be a Mapping, received: {type(endpoint_bindings_)}" ) if force_ is not None and not isinstance(force_, bool): - raise Exception( - "Expected force_ to be a bool, received: {}".format(type(force_)) - ) + raise Exception(f"Expected force_ to be a bool, received: {type(force_)}") if force_base_ is not None and not isinstance(force_base_, bool): raise Exception( - "Expected force_base_ to be a bool, received: {}".format( - type(force_base_) - ) + f"Expected force_base_ to be a bool, received: {type(force_base_)}" ) if force_units_ is not None and not isinstance(force_units_, bool): raise Exception( - "Expected force_units_ to be a bool, received: {}".format( - type(force_units_) - ) + f"Expected force_units_ to be a bool, received: {type(force_units_)}" ) if generation_ is not None and not isinstance(generation_, (bytes, str)): raise Exception( - "Expected generation_ to be a str, received: {}".format( - type(generation_) - ) + f"Expected generation_ to be a str, received: {type(generation_)}" ) if resource_ids_ is not None and not isinstance(resource_ids_, dict): raise Exception( - "Expected resource_ids_ to be a Mapping, received: {}".format( - type(resource_ids_) - ) + f"Expected resource_ids_ to be a Mapping, received: {type(resource_ids_)}" ) if storage_constraints_ is not None and not isinstance( storage_constraints_, dict ): raise Exception( - "Expected storage_constraints_ to be a Mapping, received: {}".format( - type(storage_constraints_) - ) + f"Expected storage_constraints_ to be a Mapping, received: {type(storage_constraints_)}" ) self.application = application_ @@ -3635,8 +3195,7 @@ def __init__( workload_version=None, **unknown_fields, ): - """ - base : Base + """Base : Base can_upgrade_to : str charm : str charm_channel : str @@ -3685,137 +3244,101 @@ def __init__( # Validate arguments against known Juju API types. if base_ is not None and not isinstance(base_, (dict, Base)): - raise Exception( - "Expected base_ to be a Base, received: {}".format(type(base_)) - ) + raise Exception(f"Expected base_ to be a Base, received: {type(base_)}") if can_upgrade_to_ is not None and not isinstance( can_upgrade_to_, (bytes, str) ): raise Exception( - "Expected can_upgrade_to_ to be a str, received: {}".format( - type(can_upgrade_to_) - ) + f"Expected can_upgrade_to_ to be a str, received: {type(can_upgrade_to_)}" ) if charm_ is not None and not isinstance(charm_, (bytes, str)): - raise Exception( - "Expected charm_ to be a str, received: {}".format(type(charm_)) - ) + raise Exception(f"Expected charm_ to be a str, received: {type(charm_)}") if charm_channel_ is not None and not isinstance(charm_channel_, (bytes, str)): raise Exception( - "Expected charm_channel_ to be a str, received: {}".format( - type(charm_channel_) - ) + f"Expected charm_channel_ to be a str, received: {type(charm_channel_)}" ) if charm_profile_ is not None and not isinstance(charm_profile_, (bytes, str)): raise Exception( - "Expected charm_profile_ to be a str, received: {}".format( - type(charm_profile_) - ) + f"Expected charm_profile_ to be a str, received: {type(charm_profile_)}" ) if charm_version_ is not None and not isinstance(charm_version_, (bytes, str)): raise Exception( - "Expected charm_version_ to be a str, received: {}".format( - type(charm_version_) - ) + f"Expected charm_version_ to be a str, received: {type(charm_version_)}" ) if endpoint_bindings_ is not None and not isinstance(endpoint_bindings_, dict): raise Exception( - "Expected endpoint_bindings_ to be a Mapping, received: {}".format( - type(endpoint_bindings_) - ) + f"Expected endpoint_bindings_ to be a Mapping, received: {type(endpoint_bindings_)}" ) if err_ is not None and not isinstance(err_, (dict, Error)): - raise Exception( - "Expected err_ to be a Error, received: {}".format(type(err_)) - ) + raise Exception(f"Expected err_ to be a Error, received: {type(err_)}") if exposed_ is not None and not isinstance(exposed_, bool): raise Exception( - "Expected exposed_ to be a bool, received: {}".format(type(exposed_)) + f"Expected exposed_ to be a bool, received: {type(exposed_)}" ) if exposed_endpoints_ is not None and not isinstance(exposed_endpoints_, dict): raise Exception( - "Expected exposed_endpoints_ to be a Mapping, received: {}".format( - type(exposed_endpoints_) - ) + f"Expected exposed_endpoints_ to be a Mapping, received: {type(exposed_endpoints_)}" ) if int__ is not None and not isinstance(int__, int): - raise Exception( - "Expected int__ to be a int, received: {}".format(type(int__)) - ) + raise Exception(f"Expected int__ to be a int, received: {type(int__)}") if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception( - "Expected life_ to be a str, received: {}".format(type(life_)) - ) + raise Exception(f"Expected life_ to be a str, received: {type(life_)}") if meter_statuses_ is not None and not isinstance(meter_statuses_, dict): raise Exception( - "Expected meter_statuses_ to be a Mapping, received: {}".format( - type(meter_statuses_) - ) + f"Expected meter_statuses_ to be a Mapping, received: {type(meter_statuses_)}" ) if provider_id_ is not None and not isinstance(provider_id_, (bytes, str)): raise Exception( - "Expected provider_id_ to be a str, received: {}".format( - type(provider_id_) - ) + f"Expected provider_id_ to be a str, received: {type(provider_id_)}" ) if public_address_ is not None and not isinstance( public_address_, (bytes, str) ): raise Exception( - "Expected public_address_ to be a str, received: {}".format( - type(public_address_) - ) + f"Expected public_address_ to be a str, received: {type(public_address_)}" ) if relations_ is not None and not isinstance(relations_, dict): raise Exception( - "Expected relations_ to be a Mapping, received: {}".format( - type(relations_) - ) + f"Expected relations_ to be a Mapping, received: {type(relations_)}" ) if status_ is not None and not isinstance(status_, (dict, DetailedStatus)): raise Exception( - "Expected status_ to be a DetailedStatus, received: {}".format( - type(status_) - ) + f"Expected status_ to be a DetailedStatus, received: {type(status_)}" ) if subordinate_to_ is not None and not isinstance( subordinate_to_, (bytes, str, list) ): raise Exception( - "Expected subordinate_to_ to be a Sequence, received: {}".format( - type(subordinate_to_) - ) + f"Expected subordinate_to_ to be a Sequence, received: {type(subordinate_to_)}" ) if units_ is not None and not isinstance(units_, dict): raise Exception( - "Expected units_ to be a Mapping, received: {}".format(type(units_)) + f"Expected units_ to be a Mapping, received: {type(units_)}" ) if workload_version_ is not None and not isinstance( workload_version_, (bytes, str) ): raise Exception( - "Expected workload_version_ to be a str, received: {}".format( - type(workload_version_) - ) + f"Expected workload_version_ to be a str, received: {type(workload_version_)}" ) self.base = base_ @@ -3846,8 +3369,7 @@ class ApplicationUnexpose(Type): _toPy = {"application": "application", "exposed-endpoints": "exposed_endpoints"} def __init__(self, application=None, exposed_endpoints=None, **unknown_fields): - """ - application : str + """Application : str exposed_endpoints : typing.Sequence[str] """ application_ = application @@ -3856,18 +3378,14 @@ def __init__(self, application=None, exposed_endpoints=None, **unknown_fields): # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): raise Exception( - "Expected application_ to be a str, received: {}".format( - type(application_) - ) + f"Expected application_ to be a str, received: {type(application_)}" ) if exposed_endpoints_ is not None and not isinstance( exposed_endpoints_, (bytes, str, list) ): raise Exception( - "Expected exposed_endpoints_ to be a Sequence, received: {}".format( - type(exposed_endpoints_) - ) + f"Expected exposed_endpoints_ to be a Sequence, received: {type(exposed_endpoints_)}" ) self.application = application_ @@ -3880,8 +3398,7 @@ class ApplicationUnset(Type): _toPy = {"application": "application", "branch": "branch", "options": "options"} def __init__(self, application=None, branch=None, options=None, **unknown_fields): - """ - application : str + """Application : str branch : str options : typing.Sequence[str] """ @@ -3892,21 +3409,15 @@ def __init__(self, application=None, branch=None, options=None, **unknown_fields # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): raise Exception( - "Expected application_ to be a str, received: {}".format( - type(application_) - ) + f"Expected application_ to be a str, received: {type(application_)}" ) if branch_ is not None and not isinstance(branch_, (bytes, str)): - raise Exception( - "Expected branch_ to be a str, received: {}".format(type(branch_)) - ) + raise Exception(f"Expected branch_ to be a str, received: {type(branch_)}") if options_ is not None and not isinstance(options_, (bytes, str, list)): raise Exception( - "Expected options_ to be a Sequence, received: {}".format( - type(options_) - ) + f"Expected options_ to be a Sequence, received: {type(options_)}" ) self.application = application_ @@ -3920,17 +3431,13 @@ class ApplicationsCharmActionsResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~ApplicationCharmActionsResult] - """ + """Results : typing.Sequence[~ApplicationCharmActionsResult]""" results_ = [ApplicationCharmActionsResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -3942,9 +3449,7 @@ class ApplicationsDeploy(Type): _toPy = {"applications": "applications"} def __init__(self, applications=None, **unknown_fields): - """ - applications : typing.Sequence[~ApplicationDeploy] - """ + """Applications : typing.Sequence[~ApplicationDeploy]""" applications_ = [ApplicationDeploy.from_json(o) for o in applications or []] # Validate arguments against known Juju API types. @@ -3952,9 +3457,7 @@ def __init__(self, applications=None, **unknown_fields): applications_, (bytes, str, list) ): raise Exception( - "Expected applications_ to be a Sequence, received: {}".format( - type(applications_) - ) + f"Expected applications_ to be a Sequence, received: {type(applications_)}" ) self.applications = applications_ @@ -3989,8 +3492,7 @@ def __init__( model_access=None, **unknown_fields, ): - """ - controller_access : str + """controller_access : str credentials : str display_name : str identity : str @@ -4009,44 +3511,34 @@ def __init__( controller_access_, (bytes, str) ): raise Exception( - "Expected controller_access_ to be a str, received: {}".format( - type(controller_access_) - ) + f"Expected controller_access_ to be a str, received: {type(controller_access_)}" ) if credentials_ is not None and not isinstance(credentials_, (bytes, str)): raise Exception( - "Expected credentials_ to be a str, received: {}".format( - type(credentials_) - ) + f"Expected credentials_ to be a str, received: {type(credentials_)}" ) if display_name_ is not None and not isinstance(display_name_, (bytes, str)): raise Exception( - "Expected display_name_ to be a str, received: {}".format( - type(display_name_) - ) + f"Expected display_name_ to be a str, received: {type(display_name_)}" ) if identity_ is not None and not isinstance(identity_, (bytes, str)): raise Exception( - "Expected identity_ to be a str, received: {}".format(type(identity_)) + f"Expected identity_ to be a str, received: {type(identity_)}" ) if last_connection_ is not None and not isinstance( last_connection_, (bytes, str) ): raise Exception( - "Expected last_connection_ to be a str, received: {}".format( - type(last_connection_) - ) + f"Expected last_connection_ to be a str, received: {type(last_connection_)}" ) if model_access_ is not None and not isinstance(model_access_, (bytes, str)): raise Exception( - "Expected model_access_ to be a str, received: {}".format( - type(model_access_) - ) + f"Expected model_access_ to be a str, received: {type(model_access_)}" ) self.controller_access = controller_access_ @@ -4063,8 +3555,7 @@ class BackupsCreateArgs(Type): _toPy = {"no-download": "no_download", "notes": "notes"} def __init__(self, no_download=None, notes=None, **unknown_fields): - """ - no_download : bool + """no_download : bool notes : str """ no_download_ = no_download @@ -4073,15 +3564,11 @@ def __init__(self, no_download=None, notes=None, **unknown_fields): # Validate arguments against known Juju API types. if no_download_ is not None and not isinstance(no_download_, bool): raise Exception( - "Expected no_download_ to be a bool, received: {}".format( - type(no_download_) - ) + f"Expected no_download_ to be a bool, received: {type(no_download_)}" ) if notes_ is not None and not isinstance(notes_, (bytes, str)): - raise Exception( - "Expected notes_ to be a str, received: {}".format(type(notes_)) - ) + raise Exception(f"Expected notes_ to be a str, received: {type(notes_)}") self.no_download = no_download_ self.notes = notes_ @@ -4155,8 +3642,7 @@ def __init__( version=None, **unknown_fields, ): - """ - base : str + """Base : str checksum : str checksum_format : str controller_machine_id : str @@ -4198,116 +3684,94 @@ def __init__( # Validate arguments against known Juju API types. if base_ is not None and not isinstance(base_, (bytes, str)): - raise Exception( - "Expected base_ to be a str, received: {}".format(type(base_)) - ) + raise Exception(f"Expected base_ to be a str, received: {type(base_)}") if checksum_ is not None and not isinstance(checksum_, (bytes, str)): raise Exception( - "Expected checksum_ to be a str, received: {}".format(type(checksum_)) + f"Expected checksum_ to be a str, received: {type(checksum_)}" ) if checksum_format_ is not None and not isinstance( checksum_format_, (bytes, str) ): raise Exception( - "Expected checksum_format_ to be a str, received: {}".format( - type(checksum_format_) - ) + f"Expected checksum_format_ to be a str, received: {type(checksum_format_)}" ) if controller_machine_id_ is not None and not isinstance( controller_machine_id_, (bytes, str) ): raise Exception( - "Expected controller_machine_id_ to be a str, received: {}".format( - type(controller_machine_id_) - ) + f"Expected controller_machine_id_ to be a str, received: {type(controller_machine_id_)}" ) if controller_machine_inst_id_ is not None and not isinstance( controller_machine_inst_id_, (bytes, str) ): raise Exception( - "Expected controller_machine_inst_id_ to be a str, received: {}".format( - type(controller_machine_inst_id_) - ) + f"Expected controller_machine_inst_id_ to be a str, received: {type(controller_machine_inst_id_)}" ) if controller_uuid_ is not None and not isinstance( controller_uuid_, (bytes, str) ): raise Exception( - "Expected controller_uuid_ to be a str, received: {}".format( - type(controller_uuid_) - ) + f"Expected controller_uuid_ to be a str, received: {type(controller_uuid_)}" ) if filename_ is not None and not isinstance(filename_, (bytes, str)): raise Exception( - "Expected filename_ to be a str, received: {}".format(type(filename_)) + f"Expected filename_ to be a str, received: {type(filename_)}" ) if finished_ is not None and not isinstance(finished_, (bytes, str)): raise Exception( - "Expected finished_ to be a str, received: {}".format(type(finished_)) + f"Expected finished_ to be a str, received: {type(finished_)}" ) if format_version_ is not None and not isinstance(format_version_, int): raise Exception( - "Expected format_version_ to be a int, received: {}".format( - type(format_version_) - ) + f"Expected format_version_ to be a int, received: {type(format_version_)}" ) if ha_nodes_ is not None and not isinstance(ha_nodes_, int): raise Exception( - "Expected ha_nodes_ to be a int, received: {}".format(type(ha_nodes_)) + f"Expected ha_nodes_ to be a int, received: {type(ha_nodes_)}" ) if hostname_ is not None and not isinstance(hostname_, (bytes, str)): raise Exception( - "Expected hostname_ to be a str, received: {}".format(type(hostname_)) + f"Expected hostname_ to be a str, received: {type(hostname_)}" ) if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception( - "Expected id__ to be a str, received: {}".format(type(id__)) - ) + raise Exception(f"Expected id__ to be a str, received: {type(id__)}") if machine_ is not None and not isinstance(machine_, (bytes, str)): raise Exception( - "Expected machine_ to be a str, received: {}".format(type(machine_)) + f"Expected machine_ to be a str, received: {type(machine_)}" ) if model_ is not None and not isinstance(model_, (bytes, str)): - raise Exception( - "Expected model_ to be a str, received: {}".format(type(model_)) - ) + raise Exception(f"Expected model_ to be a str, received: {type(model_)}") if notes_ is not None and not isinstance(notes_, (bytes, str)): - raise Exception( - "Expected notes_ to be a str, received: {}".format(type(notes_)) - ) + raise Exception(f"Expected notes_ to be a str, received: {type(notes_)}") if size_ is not None and not isinstance(size_, int): - raise Exception( - "Expected size_ to be a int, received: {}".format(type(size_)) - ) + raise Exception(f"Expected size_ to be a int, received: {type(size_)}") if started_ is not None and not isinstance(started_, (bytes, str)): raise Exception( - "Expected started_ to be a str, received: {}".format(type(started_)) + f"Expected started_ to be a str, received: {type(started_)}" ) if stored_ is not None and not isinstance(stored_, (bytes, str)): - raise Exception( - "Expected stored_ to be a str, received: {}".format(type(stored_)) - ) + raise Exception(f"Expected stored_ to be a str, received: {type(stored_)}") if version_ is not None and not isinstance(version_, (dict, Number)): raise Exception( - "Expected version_ to be a Number, received: {}".format(type(version_)) + f"Expected version_ to be a Number, received: {type(version_)}" ) self.base = base_ @@ -4337,8 +3801,7 @@ class Base(Type): _toPy = {"channel": "channel", "name": "name"} def __init__(self, channel=None, name=None, **unknown_fields): - """ - channel : str + """Channel : str name : str """ channel_ = channel @@ -4347,13 +3810,11 @@ def __init__(self, channel=None, name=None, **unknown_fields): # Validate arguments against known Juju API types. if channel_ is not None and not isinstance(channel_, (bytes, str)): raise Exception( - "Expected channel_ to be a str, received: {}".format(type(channel_)) + f"Expected channel_ to be a str, received: {type(channel_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") self.channel = channel_ self.name = name_ @@ -4394,8 +3855,7 @@ def __init__( tag=None, **unknown_fields, ): - """ - arch : str + """Arch : str build : int major : int minor : int @@ -4415,44 +3875,32 @@ def __init__( # Validate arguments against known Juju API types. if arch_ is not None and not isinstance(arch_, (bytes, str)): - raise Exception( - "Expected arch_ to be a str, received: {}".format(type(arch_)) - ) + raise Exception(f"Expected arch_ to be a str, received: {type(arch_)}") if build_ is not None and not isinstance(build_, int): - raise Exception( - "Expected build_ to be a int, received: {}".format(type(build_)) - ) + raise Exception(f"Expected build_ to be a int, received: {type(build_)}") if major_ is not None and not isinstance(major_, int): - raise Exception( - "Expected major_ to be a int, received: {}".format(type(major_)) - ) + raise Exception(f"Expected major_ to be a int, received: {type(major_)}") if minor_ is not None and not isinstance(minor_, int): - raise Exception( - "Expected minor_ to be a int, received: {}".format(type(minor_)) - ) + raise Exception(f"Expected minor_ to be a int, received: {type(minor_)}") if number_ is not None and not isinstance(number_, (dict, Number)): raise Exception( - "Expected number_ to be a Number, received: {}".format(type(number_)) + f"Expected number_ to be a Number, received: {type(number_)}" ) if patch_ is not None and not isinstance(patch_, int): - raise Exception( - "Expected patch_ to be a int, received: {}".format(type(patch_)) - ) + raise Exception(f"Expected patch_ to be a int, received: {type(patch_)}") if release_ is not None and not isinstance(release_, (bytes, str)): raise Exception( - "Expected release_ to be a str, received: {}".format(type(release_)) + f"Expected release_ to be a str, received: {type(release_)}" ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception( - "Expected tag_ to be a str, received: {}".format(type(tag_)) - ) + raise Exception(f"Expected tag_ to be a str, received: {type(tag_)}") self.arch = arch_ self.build = build_ @@ -4470,8 +3918,7 @@ class Block(Type): _toPy = {"id": "id_", "message": "message", "tag": "tag", "type": "type_"} def __init__(self, id_=None, message=None, tag=None, type_=None, **unknown_fields): - """ - id_ : str + """id_ : str message : str tag : str type_ : str @@ -4483,24 +3930,18 @@ def __init__(self, id_=None, message=None, tag=None, type_=None, **unknown_field # Validate arguments against known Juju API types. if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception( - "Expected id__ to be a str, received: {}".format(type(id__)) - ) + raise Exception(f"Expected id__ to be a str, received: {type(id__)}") if message_ is not None and not isinstance(message_, (bytes, str)): raise Exception( - "Expected message_ to be a str, received: {}".format(type(message_)) + f"Expected message_ to be a str, received: {type(message_)}" ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception( - "Expected tag_ to be a str, received: {}".format(type(tag_)) - ) + raise Exception(f"Expected tag_ to be a str, received: {type(tag_)}") if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") self.id_ = id__ self.message = message_ @@ -4514,8 +3955,7 @@ class BlockResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : Block """ error_ = Error.from_json(error) if error else None @@ -4523,13 +3963,11 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance(result_, (dict, Block)): raise Exception( - "Expected result_ to be a Block, received: {}".format(type(result_)) + f"Expected result_ to be a Block, received: {type(result_)}" ) self.error = error_ @@ -4542,17 +3980,13 @@ class BlockResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~BlockResult] - """ + """Results : typing.Sequence[~BlockResult]""" results_ = [BlockResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -4564,8 +3998,7 @@ class BlockSwitchParams(Type): _toPy = {"message": "message", "type": "type_"} def __init__(self, message=None, type_=None, **unknown_fields): - """ - message : str + """Message : str type_ : str """ message_ = message @@ -4574,13 +4007,11 @@ def __init__(self, message=None, type_=None, **unknown_fields): # Validate arguments against known Juju API types. if message_ is not None and not isinstance(message_, (bytes, str)): raise Exception( - "Expected message_ to be a str, received: {}".format(type(message_)) + f"Expected message_ to be a str, received: {type(message_)}" ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") self.message = message_ self.type_ = type__ @@ -4592,8 +4023,7 @@ class BoolResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : bool """ error_ = Error.from_json(error) if error else None @@ -4601,14 +4031,10 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance(result_, bool): - raise Exception( - "Expected result_ to be a bool, received: {}".format(type(result_)) - ) + raise Exception(f"Expected result_ to be a bool, received: {type(result_)}") self.error = error_ self.result = result_ @@ -4620,16 +4046,12 @@ class BranchArg(Type): _toPy = {"branch": "branch"} def __init__(self, branch=None, **unknown_fields): - """ - branch : str - """ + """Branch : str""" branch_ = branch # Validate arguments against known Juju API types. if branch_ is not None and not isinstance(branch_, (bytes, str)): - raise Exception( - "Expected branch_ to be a str, received: {}".format(type(branch_)) - ) + raise Exception(f"Expected branch_ to be a str, received: {type(branch_)}") self.branch = branch_ self.unknown_fields = unknown_fields @@ -4640,8 +4062,7 @@ class BranchInfoArgs(Type): _toPy = {"branches": "branches", "detailed": "detailed"} def __init__(self, branches=None, detailed=None, **unknown_fields): - """ - branches : typing.Sequence[str] + """Branches : typing.Sequence[str] detailed : bool """ branches_ = branches @@ -4650,14 +4071,12 @@ def __init__(self, branches=None, detailed=None, **unknown_fields): # Validate arguments against known Juju API types. if branches_ is not None and not isinstance(branches_, (bytes, str, list)): raise Exception( - "Expected branches_ to be a Sequence, received: {}".format( - type(branches_) - ) + f"Expected branches_ to be a Sequence, received: {type(branches_)}" ) if detailed_ is not None and not isinstance(detailed_, bool): raise Exception( - "Expected detailed_ to be a bool, received: {}".format(type(detailed_)) + f"Expected detailed_ to be a bool, received: {type(detailed_)}" ) self.branches = branches_ @@ -4670,8 +4089,7 @@ class BranchResults(Type): _toPy = {"error": "error", "generations": "generations"} def __init__(self, error=None, generations=None, **unknown_fields): - """ - error : Error + """Error : Error generations : typing.Sequence[~Generation] """ error_ = Error.from_json(error) if error else None @@ -4679,17 +4097,13 @@ def __init__(self, error=None, generations=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if generations_ is not None and not isinstance( generations_, (bytes, str, list) ): raise Exception( - "Expected generations_ to be a Sequence, received: {}".format( - type(generations_) - ) + f"Expected generations_ to be a Sequence, received: {type(generations_)}" ) self.error = error_ @@ -4712,8 +4126,7 @@ class BranchStatus(Type): def __init__( self, assigned_units=None, created=None, created_by=None, **unknown_fields ): - """ - assigned_units : typing.Mapping[str, typing.Sequence[str]] + """assigned_units : typing.Mapping[str, typing.Sequence[str]] created : int created_by : str """ @@ -4724,21 +4137,17 @@ def __init__( # Validate arguments against known Juju API types. if assigned_units_ is not None and not isinstance(assigned_units_, dict): raise Exception( - "Expected assigned_units_ to be a Mapping, received: {}".format( - type(assigned_units_) - ) + f"Expected assigned_units_ to be a Mapping, received: {type(assigned_units_)}" ) if created_ is not None and not isinstance(created_, int): raise Exception( - "Expected created_ to be a int, received: {}".format(type(created_)) + f"Expected created_ to be a int, received: {type(created_)}" ) if created_by_ is not None and not isinstance(created_by_, (bytes, str)): raise Exception( - "Expected created_by_ to be a str, received: {}".format( - type(created_by_) - ) + f"Expected created_by_ to be a str, received: {type(created_by_)}" ) self.assigned_units = assigned_units_ @@ -4752,8 +4161,7 @@ class BranchTrackArg(Type): _toPy = {"branch": "branch", "entities": "entities", "num-units": "num_units"} def __init__(self, branch=None, entities=None, num_units=None, **unknown_fields): - """ - branch : str + """Branch : str entities : typing.Sequence[~Entity] num_units : int """ @@ -4763,20 +4171,16 @@ def __init__(self, branch=None, entities=None, num_units=None, **unknown_fields) # Validate arguments against known Juju API types. if branch_ is not None and not isinstance(branch_, (bytes, str)): - raise Exception( - "Expected branch_ to be a str, received: {}".format(type(branch_)) - ) + raise Exception(f"Expected branch_ to be a str, received: {type(branch_)}") if entities_ is not None and not isinstance(entities_, (bytes, str, list)): raise Exception( - "Expected entities_ to be a Sequence, received: {}".format( - type(entities_) - ) + f"Expected entities_ to be a Sequence, received: {type(entities_)}" ) if num_units_ is not None and not isinstance(num_units_, int): raise Exception( - "Expected num_units_ to be a int, received: {}".format(type(num_units_)) + f"Expected num_units_ to be a int, received: {type(num_units_)}" ) self.branch = branch_ @@ -4790,17 +4194,13 @@ class BulkImportStorageParams(Type): _toPy = {"storage": "storage"} def __init__(self, storage=None, **unknown_fields): - """ - storage : typing.Sequence[~ImportStorageParams] - """ + """Storage : typing.Sequence[~ImportStorageParams]""" storage_ = [ImportStorageParams.from_json(o) for o in storage or []] # Validate arguments against known Juju API types. if storage_ is not None and not isinstance(storage_, (bytes, str, list)): raise Exception( - "Expected storage_ to be a Sequence, received: {}".format( - type(storage_) - ) + f"Expected storage_ to be a Sequence, received: {type(storage_)}" ) self.storage = storage_ @@ -4819,8 +4219,7 @@ class BundleChange(Type): def __init__( self, args=None, id_=None, method=None, requires=None, **unknown_fields ): - """ - args : typing.Sequence[typing.Any] + """Args : typing.Sequence[typing.Any] id_ : str method : str requires : typing.Sequence[str] @@ -4832,25 +4231,17 @@ def __init__( # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception( - "Expected args_ to be a Sequence, received: {}".format(type(args_)) - ) + raise Exception(f"Expected args_ to be a Sequence, received: {type(args_)}") if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception( - "Expected id__ to be a str, received: {}".format(type(id__)) - ) + raise Exception(f"Expected id__ to be a str, received: {type(id__)}") if method_ is not None and not isinstance(method_, (bytes, str)): - raise Exception( - "Expected method_ to be a str, received: {}".format(type(method_)) - ) + raise Exception(f"Expected method_ to be a str, received: {type(method_)}") if requires_ is not None and not isinstance(requires_, (bytes, str, list)): raise Exception( - "Expected requires_ to be a Sequence, received: {}".format( - type(requires_) - ) + f"Expected requires_ to be a Sequence, received: {type(requires_)}" ) self.args = args_ @@ -4872,8 +4263,7 @@ class BundleChangesMapArgs(Type): def __init__( self, args=None, id_=None, method=None, requires=None, **unknown_fields ): - """ - args : typing.Mapping[str, typing.Any] + """Args : typing.Mapping[str, typing.Any] id_ : str method : str requires : typing.Sequence[str] @@ -4885,25 +4275,17 @@ def __init__( # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, dict): - raise Exception( - "Expected args_ to be a Mapping, received: {}".format(type(args_)) - ) + raise Exception(f"Expected args_ to be a Mapping, received: {type(args_)}") if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception( - "Expected id__ to be a str, received: {}".format(type(id__)) - ) + raise Exception(f"Expected id__ to be a str, received: {type(id__)}") if method_ is not None and not isinstance(method_, (bytes, str)): - raise Exception( - "Expected method_ to be a str, received: {}".format(type(method_)) - ) + raise Exception(f"Expected method_ to be a str, received: {type(method_)}") if requires_ is not None and not isinstance(requires_, (bytes, str, list)): raise Exception( - "Expected requires_ to be a Sequence, received: {}".format( - type(requires_) - ) + f"Expected requires_ to be a Sequence, received: {type(requires_)}" ) self.args = args_ @@ -4918,8 +4300,7 @@ class BundleChangesMapArgsResults(Type): _toPy = {"changes": "changes", "errors": "errors"} def __init__(self, changes=None, errors=None, **unknown_fields): - """ - changes : typing.Sequence[~BundleChangesMapArgs] + """Changes : typing.Sequence[~BundleChangesMapArgs] errors : typing.Sequence[str] """ changes_ = [BundleChangesMapArgs.from_json(o) for o in changes or []] @@ -4928,14 +4309,12 @@ def __init__(self, changes=None, errors=None, **unknown_fields): # Validate arguments against known Juju API types. if changes_ is not None and not isinstance(changes_, (bytes, str, list)): raise Exception( - "Expected changes_ to be a Sequence, received: {}".format( - type(changes_) - ) + f"Expected changes_ to be a Sequence, received: {type(changes_)}" ) if errors_ is not None and not isinstance(errors_, (bytes, str, list)): raise Exception( - "Expected errors_ to be a Sequence, received: {}".format(type(errors_)) + f"Expected errors_ to be a Sequence, received: {type(errors_)}" ) self.changes = changes_ @@ -4948,8 +4327,7 @@ class BundleChangesParams(Type): _toPy = {"bundleURL": "bundleurl", "yaml": "yaml"} def __init__(self, bundleurl=None, yaml=None, **unknown_fields): - """ - bundleurl : str + """Bundleurl : str yaml : str """ bundleurl_ = bundleurl @@ -4958,13 +4336,11 @@ def __init__(self, bundleurl=None, yaml=None, **unknown_fields): # Validate arguments against known Juju API types. if bundleurl_ is not None and not isinstance(bundleurl_, (bytes, str)): raise Exception( - "Expected bundleurl_ to be a str, received: {}".format(type(bundleurl_)) + f"Expected bundleurl_ to be a str, received: {type(bundleurl_)}" ) if yaml_ is not None and not isinstance(yaml_, (bytes, str)): - raise Exception( - "Expected yaml_ to be a str, received: {}".format(type(yaml_)) - ) + raise Exception(f"Expected yaml_ to be a str, received: {type(yaml_)}") self.bundleurl = bundleurl_ self.yaml = yaml_ @@ -4976,8 +4352,7 @@ class BundleChangesResults(Type): _toPy = {"changes": "changes", "errors": "errors"} def __init__(self, changes=None, errors=None, **unknown_fields): - """ - changes : typing.Sequence[~BundleChange] + """Changes : typing.Sequence[~BundleChange] errors : typing.Sequence[str] """ changes_ = [BundleChange.from_json(o) for o in changes or []] @@ -4986,14 +4361,12 @@ def __init__(self, changes=None, errors=None, **unknown_fields): # Validate arguments against known Juju API types. if changes_ is not None and not isinstance(changes_, (bytes, str, list)): raise Exception( - "Expected changes_ to be a Sequence, received: {}".format( - type(changes_) - ) + f"Expected changes_ to be a Sequence, received: {type(changes_)}" ) if errors_ is not None and not isinstance(errors_, (bytes, str, list)): raise Exception( - "Expected errors_ to be a Sequence, received: {}".format(type(errors_)) + f"Expected errors_ to be a Sequence, received: {type(errors_)}" ) self.changes = changes_ @@ -5006,15 +4379,13 @@ class CIDRParams(Type): _toPy = {"cidrs": "cidrs"} def __init__(self, cidrs=None, **unknown_fields): - """ - cidrs : typing.Sequence[str] - """ + """Cidrs : typing.Sequence[str]""" cidrs_ = cidrs # Validate arguments against known Juju API types. if cidrs_ is not None and not isinstance(cidrs_, (bytes, str, list)): raise Exception( - "Expected cidrs_ to be a Sequence, received: {}".format(type(cidrs_)) + f"Expected cidrs_ to be a Sequence, received: {type(cidrs_)}" ) self.cidrs = cidrs_ @@ -5026,8 +4397,7 @@ class ChangeModelCredentialParams(Type): _toPy = {"credential-tag": "credential_tag", "model-tag": "model_tag"} def __init__(self, credential_tag=None, model_tag=None, **unknown_fields): - """ - credential_tag : str + """credential_tag : str model_tag : str """ credential_tag_ = credential_tag @@ -5038,14 +4408,12 @@ def __init__(self, credential_tag=None, model_tag=None, **unknown_fields): credential_tag_, (bytes, str) ): raise Exception( - "Expected credential_tag_ to be a str, received: {}".format( - type(credential_tag_) - ) + f"Expected credential_tag_ to be a str, received: {type(credential_tag_)}" ) if model_tag_ is not None and not isinstance(model_tag_, (bytes, str)): raise Exception( - "Expected model_tag_ to be a str, received: {}".format(type(model_tag_)) + f"Expected model_tag_ to be a str, received: {type(model_tag_)}" ) self.credential_tag = credential_tag_ @@ -5058,9 +4426,7 @@ class ChangeModelCredentialsParams(Type): _toPy = {"model-credentials": "model_credentials"} def __init__(self, model_credentials=None, **unknown_fields): - """ - model_credentials : typing.Sequence[~ChangeModelCredentialParams] - """ + """model_credentials : typing.Sequence[~ChangeModelCredentialParams]""" model_credentials_ = [ ChangeModelCredentialParams.from_json(o) for o in model_credentials or [] ] @@ -5070,9 +4436,7 @@ def __init__(self, model_credentials=None, **unknown_fields): model_credentials_, (bytes, str, list) ): raise Exception( - "Expected model_credentials_ to be a Sequence, received: {}".format( - type(model_credentials_) - ) + f"Expected model_credentials_ to be a Sequence, received: {type(model_credentials_)}" ) self.model_credentials = model_credentials_ @@ -5113,8 +4477,7 @@ def __init__( url=None, **unknown_fields, ): - """ - actions : CharmActions + """Actions : CharmActions config : typing.Mapping[str, ~CharmOption] lxd_profile : CharmLXDProfile manifest : CharmManifest @@ -5135,53 +4498,43 @@ def __init__( # Validate arguments against known Juju API types. if actions_ is not None and not isinstance(actions_, (dict, CharmActions)): raise Exception( - "Expected actions_ to be a CharmActions, received: {}".format( - type(actions_) - ) + f"Expected actions_ to be a CharmActions, received: {type(actions_)}" ) if config_ is not None and not isinstance(config_, dict): raise Exception( - "Expected config_ to be a Mapping, received: {}".format(type(config_)) + f"Expected config_ to be a Mapping, received: {type(config_)}" ) if lxd_profile_ is not None and not isinstance( lxd_profile_, (dict, CharmLXDProfile) ): raise Exception( - "Expected lxd_profile_ to be a CharmLXDProfile, received: {}".format( - type(lxd_profile_) - ) + f"Expected lxd_profile_ to be a CharmLXDProfile, received: {type(lxd_profile_)}" ) if manifest_ is not None and not isinstance(manifest_, (dict, CharmManifest)): raise Exception( - "Expected manifest_ to be a CharmManifest, received: {}".format( - type(manifest_) - ) + f"Expected manifest_ to be a CharmManifest, received: {type(manifest_)}" ) if meta_ is not None and not isinstance(meta_, (dict, CharmMeta)): raise Exception( - "Expected meta_ to be a CharmMeta, received: {}".format(type(meta_)) + f"Expected meta_ to be a CharmMeta, received: {type(meta_)}" ) if metrics_ is not None and not isinstance(metrics_, (dict, CharmMetrics)): raise Exception( - "Expected metrics_ to be a CharmMetrics, received: {}".format( - type(metrics_) - ) + f"Expected metrics_ to be a CharmMetrics, received: {type(metrics_)}" ) if revision_ is not None and not isinstance(revision_, int): raise Exception( - "Expected revision_ to be a int, received: {}".format(type(revision_)) + f"Expected revision_ to be a int, received: {type(revision_)}" ) if url_ is not None and not isinstance(url_, (bytes, str)): - raise Exception( - "Expected url_ to be a str, received: {}".format(type(url_)) - ) + raise Exception(f"Expected url_ to be a str, received: {type(url_)}") self.actions = actions_ self.config = config_ @@ -5199,8 +4552,7 @@ class CharmActionSpec(Type): _toPy = {"description": "description", "params": "params"} def __init__(self, description=None, params=None, **unknown_fields): - """ - description : str + """Description : str params : typing.Mapping[str, typing.Any] """ description_ = description @@ -5209,14 +4561,12 @@ def __init__(self, description=None, params=None, **unknown_fields): # Validate arguments against known Juju API types. if description_ is not None and not isinstance(description_, (bytes, str)): raise Exception( - "Expected description_ to be a str, received: {}".format( - type(description_) - ) + f"Expected description_ to be a str, received: {type(description_)}" ) if params_ is not None and not isinstance(params_, dict): raise Exception( - "Expected params_ to be a Mapping, received: {}".format(type(params_)) + f"Expected params_ to be a Mapping, received: {type(params_)}" ) self.description = description_ @@ -5229,15 +4579,13 @@ class CharmActions(Type): _toPy = {"specs": "specs"} def __init__(self, specs=None, **unknown_fields): - """ - specs : typing.Mapping[str, ~CharmActionSpec] - """ + """Specs : typing.Mapping[str, ~CharmActionSpec]""" specs_ = {k: CharmActionSpec.from_json(v) for k, v in (specs or dict()).items()} # Validate arguments against known Juju API types. if specs_ is not None and not isinstance(specs_, dict): raise Exception( - "Expected specs_ to be a Mapping, received: {}".format(type(specs_)) + f"Expected specs_ to be a Mapping, received: {type(specs_)}" ) self.specs = specs_ @@ -5249,8 +4597,7 @@ class CharmBase(Type): _toPy = {"architectures": "architectures", "channel": "channel", "name": "name"} def __init__(self, architectures=None, channel=None, name=None, **unknown_fields): - """ - architectures : typing.Sequence[str] + """Architectures : typing.Sequence[str] channel : str name : str """ @@ -5263,20 +4610,16 @@ def __init__(self, architectures=None, channel=None, name=None, **unknown_fields architectures_, (bytes, str, list) ): raise Exception( - "Expected architectures_ to be a Sequence, received: {}".format( - type(architectures_) - ) + f"Expected architectures_ to be a Sequence, received: {type(architectures_)}" ) if channel_ is not None and not isinstance(channel_, (bytes, str)): raise Exception( - "Expected channel_ to be a str, received: {}".format(type(channel_)) + f"Expected channel_ to be a str, received: {type(channel_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") self.architectures = architectures_ self.channel = channel_ @@ -5291,8 +4634,7 @@ class CharmContainer(Type): def __init__( self, gid=None, mounts=None, resource=None, uid=None, **unknown_fields ): - """ - gid : int + """Gid : int mounts : typing.Sequence[~CharmMount] resource : str uid : int @@ -5304,24 +4646,20 @@ def __init__( # Validate arguments against known Juju API types. if gid_ is not None and not isinstance(gid_, int): - raise Exception( - "Expected gid_ to be a int, received: {}".format(type(gid_)) - ) + raise Exception(f"Expected gid_ to be a int, received: {type(gid_)}") if mounts_ is not None and not isinstance(mounts_, (bytes, str, list)): raise Exception( - "Expected mounts_ to be a Sequence, received: {}".format(type(mounts_)) + f"Expected mounts_ to be a Sequence, received: {type(mounts_)}" ) if resource_ is not None and not isinstance(resource_, (bytes, str)): raise Exception( - "Expected resource_ to be a str, received: {}".format(type(resource_)) + f"Expected resource_ to be a str, received: {type(resource_)}" ) if uid_ is not None and not isinstance(uid_, int): - raise Exception( - "Expected uid_ to be a int, received: {}".format(type(uid_)) - ) + raise Exception(f"Expected uid_ to be a int, received: {type(uid_)}") self.gid = gid_ self.mounts = mounts_ @@ -5347,8 +4685,7 @@ class CharmDeployment(Type): def __init__( self, min_version=None, mode=None, service=None, type_=None, **unknown_fields ): - """ - min_version : str + """min_version : str mode : str service : str type_ : str @@ -5361,25 +4698,19 @@ def __init__( # Validate arguments against known Juju API types. if min_version_ is not None and not isinstance(min_version_, (bytes, str)): raise Exception( - "Expected min_version_ to be a str, received: {}".format( - type(min_version_) - ) + f"Expected min_version_ to be a str, received: {type(min_version_)}" ) if mode_ is not None and not isinstance(mode_, (bytes, str)): - raise Exception( - "Expected mode_ to be a str, received: {}".format(type(mode_)) - ) + raise Exception(f"Expected mode_ to be a str, received: {type(mode_)}") if service_ is not None and not isinstance(service_, (bytes, str)): raise Exception( - "Expected service_ to be a str, received: {}".format(type(service_)) + f"Expected service_ to be a str, received: {type(service_)}" ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") self.min_version = min_version_ self.mode = mode_ @@ -5413,8 +4744,7 @@ def __init__( type_=None, **unknown_fields, ): - """ - countmax : int + """Countmax : int countmin : int description : str name : str @@ -5429,30 +4759,24 @@ def __init__( # Validate arguments against known Juju API types. if countmax_ is not None and not isinstance(countmax_, int): raise Exception( - "Expected countmax_ to be a int, received: {}".format(type(countmax_)) + f"Expected countmax_ to be a int, received: {type(countmax_)}" ) if countmin_ is not None and not isinstance(countmin_, int): raise Exception( - "Expected countmin_ to be a int, received: {}".format(type(countmin_)) + f"Expected countmin_ to be a int, received: {type(countmin_)}" ) if description_ is not None and not isinstance(description_, (bytes, str)): raise Exception( - "Expected description_ to be a str, received: {}".format( - type(description_) - ) + f"Expected description_ to be a str, received: {type(description_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") self.countmax = countmax_ self.countmin = countmin_ @@ -5467,8 +4791,7 @@ class CharmLXDProfile(Type): _toPy = {"config": "config", "description": "description", "devices": "devices"} def __init__(self, config=None, description=None, devices=None, **unknown_fields): - """ - config : typing.Mapping[str, str] + """Config : typing.Mapping[str, str] description : str devices : typing.Mapping[str, typing.Any] """ @@ -5479,19 +4802,17 @@ def __init__(self, config=None, description=None, devices=None, **unknown_fields # Validate arguments against known Juju API types. if config_ is not None and not isinstance(config_, dict): raise Exception( - "Expected config_ to be a Mapping, received: {}".format(type(config_)) + f"Expected config_ to be a Mapping, received: {type(config_)}" ) if description_ is not None and not isinstance(description_, (bytes, str)): raise Exception( - "Expected description_ to be a str, received: {}".format( - type(description_) - ) + f"Expected description_ to be a str, received: {type(description_)}" ) if devices_ is not None and not isinstance(devices_, dict): raise Exception( - "Expected devices_ to be a Mapping, received: {}".format(type(devices_)) + f"Expected devices_ to be a Mapping, received: {type(devices_)}" ) self.config = config_ @@ -5505,15 +4826,13 @@ class CharmManifest(Type): _toPy = {"bases": "bases"} def __init__(self, bases=None, **unknown_fields): - """ - bases : typing.Sequence[~CharmBase] - """ + """Bases : typing.Sequence[~CharmBase]""" bases_ = [CharmBase.from_json(o) for o in bases or []] # Validate arguments against known Juju API types. if bases_ is not None and not isinstance(bases_, (bytes, str, list)): raise Exception( - "Expected bases_ to be a Sequence, received: {}".format(type(bases_)) + f"Expected bases_ to be a Sequence, received: {type(bases_)}" ) self.bases = bases_ @@ -5593,8 +4912,7 @@ def __init__( terms=None, **unknown_fields, ): - """ - assumes_expr : ExpressionTree + """assumes_expr : ExpressionTree categories : typing.Sequence[str] charm_user : str containers : typing.Mapping[str, ~CharmContainer] @@ -5656,137 +4974,107 @@ def __init__( assumes_expr_, (dict, ExpressionTree) ): raise Exception( - "Expected assumes_expr_ to be a ExpressionTree, received: {}".format( - type(assumes_expr_) - ) + f"Expected assumes_expr_ to be a ExpressionTree, received: {type(assumes_expr_)}" ) if categories_ is not None and not isinstance(categories_, (bytes, str, list)): raise Exception( - "Expected categories_ to be a Sequence, received: {}".format( - type(categories_) - ) + f"Expected categories_ to be a Sequence, received: {type(categories_)}" ) if charm_user_ is not None and not isinstance(charm_user_, (bytes, str)): raise Exception( - "Expected charm_user_ to be a str, received: {}".format( - type(charm_user_) - ) + f"Expected charm_user_ to be a str, received: {type(charm_user_)}" ) if containers_ is not None and not isinstance(containers_, dict): raise Exception( - "Expected containers_ to be a Mapping, received: {}".format( - type(containers_) - ) + f"Expected containers_ to be a Mapping, received: {type(containers_)}" ) if deployment_ is not None and not isinstance( deployment_, (dict, CharmDeployment) ): raise Exception( - "Expected deployment_ to be a CharmDeployment, received: {}".format( - type(deployment_) - ) + f"Expected deployment_ to be a CharmDeployment, received: {type(deployment_)}" ) if description_ is not None and not isinstance(description_, (bytes, str)): raise Exception( - "Expected description_ to be a str, received: {}".format( - type(description_) - ) + f"Expected description_ to be a str, received: {type(description_)}" ) if devices_ is not None and not isinstance(devices_, dict): raise Exception( - "Expected devices_ to be a Mapping, received: {}".format(type(devices_)) + f"Expected devices_ to be a Mapping, received: {type(devices_)}" ) if extra_bindings_ is not None and not isinstance(extra_bindings_, dict): raise Exception( - "Expected extra_bindings_ to be a Mapping, received: {}".format( - type(extra_bindings_) - ) + f"Expected extra_bindings_ to be a Mapping, received: {type(extra_bindings_)}" ) if min_juju_version_ is not None and not isinstance( min_juju_version_, (bytes, str) ): raise Exception( - "Expected min_juju_version_ to be a str, received: {}".format( - type(min_juju_version_) - ) + f"Expected min_juju_version_ to be a str, received: {type(min_juju_version_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if payload_classes_ is not None and not isinstance(payload_classes_, dict): raise Exception( - "Expected payload_classes_ to be a Mapping, received: {}".format( - type(payload_classes_) - ) + f"Expected payload_classes_ to be a Mapping, received: {type(payload_classes_)}" ) if peers_ is not None and not isinstance(peers_, dict): raise Exception( - "Expected peers_ to be a Mapping, received: {}".format(type(peers_)) + f"Expected peers_ to be a Mapping, received: {type(peers_)}" ) if provides_ is not None and not isinstance(provides_, dict): raise Exception( - "Expected provides_ to be a Mapping, received: {}".format( - type(provides_) - ) + f"Expected provides_ to be a Mapping, received: {type(provides_)}" ) if requires_ is not None and not isinstance(requires_, dict): raise Exception( - "Expected requires_ to be a Mapping, received: {}".format( - type(requires_) - ) + f"Expected requires_ to be a Mapping, received: {type(requires_)}" ) if resources_ is not None and not isinstance(resources_, dict): raise Exception( - "Expected resources_ to be a Mapping, received: {}".format( - type(resources_) - ) + f"Expected resources_ to be a Mapping, received: {type(resources_)}" ) if series_ is not None and not isinstance(series_, (bytes, str, list)): raise Exception( - "Expected series_ to be a Sequence, received: {}".format(type(series_)) + f"Expected series_ to be a Sequence, received: {type(series_)}" ) if storage_ is not None and not isinstance(storage_, dict): raise Exception( - "Expected storage_ to be a Mapping, received: {}".format(type(storage_)) + f"Expected storage_ to be a Mapping, received: {type(storage_)}" ) if subordinate_ is not None and not isinstance(subordinate_, bool): raise Exception( - "Expected subordinate_ to be a bool, received: {}".format( - type(subordinate_) - ) + f"Expected subordinate_ to be a bool, received: {type(subordinate_)}" ) if summary_ is not None and not isinstance(summary_, (bytes, str)): raise Exception( - "Expected summary_ to be a str, received: {}".format(type(summary_)) + f"Expected summary_ to be a str, received: {type(summary_)}" ) if tags_ is not None and not isinstance(tags_, (bytes, str, list)): - raise Exception( - "Expected tags_ to be a Sequence, received: {}".format(type(tags_)) - ) + raise Exception(f"Expected tags_ to be a Sequence, received: {type(tags_)}") if terms_ is not None and not isinstance(terms_, (bytes, str, list)): raise Exception( - "Expected terms_ to be a Sequence, received: {}".format(type(terms_)) + f"Expected terms_ to be a Sequence, received: {type(terms_)}" ) self.assumes_expr = assumes_expr_ @@ -5818,8 +5106,7 @@ class CharmMetric(Type): _toPy = {"description": "description", "type": "type_"} def __init__(self, description=None, type_=None, **unknown_fields): - """ - description : str + """Description : str type_ : str """ description_ = description @@ -5828,15 +5115,11 @@ def __init__(self, description=None, type_=None, **unknown_fields): # Validate arguments against known Juju API types. if description_ is not None and not isinstance(description_, (bytes, str)): raise Exception( - "Expected description_ to be a str, received: {}".format( - type(description_) - ) + f"Expected description_ to be a str, received: {type(description_)}" ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") self.description = description_ self.type_ = type__ @@ -5848,8 +5131,7 @@ class CharmMetrics(Type): _toPy = {"metrics": "metrics", "plan": "plan"} def __init__(self, metrics=None, plan=None, **unknown_fields): - """ - metrics : typing.Mapping[str, ~CharmMetric] + """Metrics : typing.Mapping[str, ~CharmMetric] plan : CharmPlan """ metrics_ = {k: CharmMetric.from_json(v) for k, v in (metrics or dict()).items()} @@ -5858,12 +5140,12 @@ def __init__(self, metrics=None, plan=None, **unknown_fields): # Validate arguments against known Juju API types. if metrics_ is not None and not isinstance(metrics_, dict): raise Exception( - "Expected metrics_ to be a Mapping, received: {}".format(type(metrics_)) + f"Expected metrics_ to be a Mapping, received: {type(metrics_)}" ) if plan_ is not None and not isinstance(plan_, (dict, CharmPlan)): raise Exception( - "Expected plan_ to be a CharmPlan, received: {}".format(type(plan_)) + f"Expected plan_ to be a CharmPlan, received: {type(plan_)}" ) self.metrics = metrics_ @@ -5876,8 +5158,7 @@ class CharmMount(Type): _toPy = {"location": "location", "storage": "storage"} def __init__(self, location=None, storage=None, **unknown_fields): - """ - location : str + """Location : str storage : str """ location_ = location @@ -5886,12 +5167,12 @@ def __init__(self, location=None, storage=None, **unknown_fields): # Validate arguments against known Juju API types. if location_ is not None and not isinstance(location_, (bytes, str)): raise Exception( - "Expected location_ to be a str, received: {}".format(type(location_)) + f"Expected location_ to be a str, received: {type(location_)}" ) if storage_ is not None and not isinstance(storage_, (bytes, str)): raise Exception( - "Expected storage_ to be a str, received: {}".format(type(storage_)) + f"Expected storage_ to be a str, received: {type(storage_)}" ) self.location = location_ @@ -5904,8 +5185,7 @@ class CharmOption(Type): _toPy = {"default": "default", "description": "description", "type": "type_"} def __init__(self, default=None, description=None, type_=None, **unknown_fields): - """ - default : Any + """Default : Any description : str type_ : str """ @@ -5916,15 +5196,11 @@ def __init__(self, default=None, description=None, type_=None, **unknown_fields) # Validate arguments against known Juju API types. if description_ is not None and not isinstance(description_, (bytes, str)): raise Exception( - "Expected description_ to be a str, received: {}".format( - type(description_) - ) + f"Expected description_ to be a str, received: {type(description_)}" ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") self.default = default_ self.description = description_ @@ -5975,8 +5251,7 @@ def __init__( type_=None, **unknown_fields, ): - """ - architecture : str + """Architecture : str base : Base branch : str hash_ : str @@ -6003,62 +5278,42 @@ def __init__( # Validate arguments against known Juju API types. if architecture_ is not None and not isinstance(architecture_, (bytes, str)): raise Exception( - "Expected architecture_ to be a str, received: {}".format( - type(architecture_) - ) + f"Expected architecture_ to be a str, received: {type(architecture_)}" ) if base_ is not None and not isinstance(base_, (dict, Base)): - raise Exception( - "Expected base_ to be a Base, received: {}".format(type(base_)) - ) + raise Exception(f"Expected base_ to be a Base, received: {type(base_)}") if branch_ is not None and not isinstance(branch_, (bytes, str)): - raise Exception( - "Expected branch_ to be a str, received: {}".format(type(branch_)) - ) + raise Exception(f"Expected branch_ to be a str, received: {type(branch_)}") if hash__ is not None and not isinstance(hash__, (bytes, str)): - raise Exception( - "Expected hash__ to be a str, received: {}".format(type(hash__)) - ) + raise Exception(f"Expected hash__ to be a str, received: {type(hash__)}") if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception( - "Expected id__ to be a str, received: {}".format(type(id__)) - ) + raise Exception(f"Expected id__ to be a str, received: {type(id__)}") if instance_key_ is not None and not isinstance(instance_key_, (bytes, str)): raise Exception( - "Expected instance_key_ to be a str, received: {}".format( - type(instance_key_) - ) + f"Expected instance_key_ to be a str, received: {type(instance_key_)}" ) if revision_ is not None and not isinstance(revision_, int): raise Exception( - "Expected revision_ to be a int, received: {}".format(type(revision_)) + f"Expected revision_ to be a int, received: {type(revision_)}" ) if risk_ is not None and not isinstance(risk_, (bytes, str)): - raise Exception( - "Expected risk_ to be a str, received: {}".format(type(risk_)) - ) + raise Exception(f"Expected risk_ to be a str, received: {type(risk_)}") if source_ is not None and not isinstance(source_, (bytes, str)): - raise Exception( - "Expected source_ to be a str, received: {}".format(type(source_)) - ) + raise Exception(f"Expected source_ to be a str, received: {type(source_)}") if track_ is not None and not isinstance(track_, (bytes, str)): - raise Exception( - "Expected track_ to be a str, received: {}".format(type(track_)) - ) + raise Exception(f"Expected track_ to be a str, received: {type(track_)}") if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") self.architecture = architecture_ self.base = base_ @@ -6079,8 +5334,7 @@ class CharmOriginResult(Type): _toPy = {"charm-origin": "charm_origin", "error": "error"} def __init__(self, charm_origin=None, error=None, **unknown_fields): - """ - charm_origin : CharmOrigin + """charm_origin : CharmOrigin error : Error """ charm_origin_ = CharmOrigin.from_json(charm_origin) if charm_origin else None @@ -6091,15 +5345,11 @@ def __init__(self, charm_origin=None, error=None, **unknown_fields): charm_origin_, (dict, CharmOrigin) ): raise Exception( - "Expected charm_origin_ to be a CharmOrigin, received: {}".format( - type(charm_origin_) - ) + f"Expected charm_origin_ to be a CharmOrigin, received: {type(charm_origin_)}" ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") self.charm_origin = charm_origin_ self.error = error_ @@ -6111,8 +5361,7 @@ class CharmPayloadClass(Type): _toPy = {"name": "name", "type": "type_"} def __init__(self, name=None, type_=None, **unknown_fields): - """ - name : str + """Name : str type_ : str """ name_ = name @@ -6120,14 +5369,10 @@ def __init__(self, name=None, type_=None, **unknown_fields): # Validate arguments against known Juju API types. if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") self.name = name_ self.type_ = type__ @@ -6139,15 +5384,13 @@ class CharmPlan(Type): _toPy = {"required": "required"} def __init__(self, required=None, **unknown_fields): - """ - required : bool - """ + """Required : bool""" required_ = required # Validate arguments against known Juju API types. if required_ is not None and not isinstance(required_, bool): raise Exception( - "Expected required_ to be a bool, received: {}".format(type(required_)) + f"Expected required_ to be a bool, received: {type(required_)}" ) self.required = required_ @@ -6182,8 +5425,7 @@ def __init__( scope=None, **unknown_fields, ): - """ - interface : str + """Interface : str limit : int name : str optional : bool @@ -6200,33 +5442,25 @@ def __init__( # Validate arguments against known Juju API types. if interface_ is not None and not isinstance(interface_, (bytes, str)): raise Exception( - "Expected interface_ to be a str, received: {}".format(type(interface_)) + f"Expected interface_ to be a str, received: {type(interface_)}" ) if limit_ is not None and not isinstance(limit_, int): - raise Exception( - "Expected limit_ to be a int, received: {}".format(type(limit_)) - ) + raise Exception(f"Expected limit_ to be a int, received: {type(limit_)}") if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if optional_ is not None and not isinstance(optional_, bool): raise Exception( - "Expected optional_ to be a bool, received: {}".format(type(optional_)) + f"Expected optional_ to be a bool, received: {type(optional_)}" ) if role_ is not None and not isinstance(role_, (bytes, str)): - raise Exception( - "Expected role_ to be a str, received: {}".format(type(role_)) - ) + raise Exception(f"Expected role_ to be a str, received: {type(role_)}") if scope_ is not None and not isinstance(scope_, (bytes, str)): - raise Exception( - "Expected scope_ to be a str, received: {}".format(type(scope_)) - ) + raise Exception(f"Expected scope_ to be a str, received: {type(scope_)}") self.interface = interface_ self.limit = limit_ @@ -6271,8 +5505,7 @@ def __init__( type_=None, **unknown_fields, ): - """ - description : str + """Description : str fingerprint : typing.Sequence[int] name : str origin : str @@ -6293,49 +5526,35 @@ def __init__( # Validate arguments against known Juju API types. if description_ is not None and not isinstance(description_, (bytes, str)): raise Exception( - "Expected description_ to be a str, received: {}".format( - type(description_) - ) + f"Expected description_ to be a str, received: {type(description_)}" ) if fingerprint_ is not None and not isinstance( fingerprint_, (bytes, str, list) ): raise Exception( - "Expected fingerprint_ to be a Sequence, received: {}".format( - type(fingerprint_) - ) + f"Expected fingerprint_ to be a Sequence, received: {type(fingerprint_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if origin_ is not None and not isinstance(origin_, (bytes, str)): - raise Exception( - "Expected origin_ to be a str, received: {}".format(type(origin_)) - ) + raise Exception(f"Expected origin_ to be a str, received: {type(origin_)}") if path_ is not None and not isinstance(path_, (bytes, str)): - raise Exception( - "Expected path_ to be a str, received: {}".format(type(path_)) - ) + raise Exception(f"Expected path_ to be a str, received: {type(path_)}") if revision_ is not None and not isinstance(revision_, int): raise Exception( - "Expected revision_ to be a int, received: {}".format(type(revision_)) + f"Expected revision_ to be a int, received: {type(revision_)}" ) if size_ is not None and not isinstance(size_, int): - raise Exception( - "Expected size_ to be a int, received: {}".format(type(size_)) - ) + raise Exception(f"Expected size_ to be a int, received: {type(size_)}") if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") self.description = description_ self.fingerprint = fingerprint_ @@ -6365,8 +5584,7 @@ class CharmResourceMeta(Type): def __init__( self, description=None, name=None, path=None, type_=None, **unknown_fields ): - """ - description : str + """Description : str name : str path : str type_ : str @@ -6379,25 +5597,17 @@ def __init__( # Validate arguments against known Juju API types. if description_ is not None and not isinstance(description_, (bytes, str)): raise Exception( - "Expected description_ to be a str, received: {}".format( - type(description_) - ) + f"Expected description_ to be a str, received: {type(description_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if path_ is not None and not isinstance(path_, (bytes, str)): - raise Exception( - "Expected path_ to be a str, received: {}".format(type(path_)) - ) + raise Exception(f"Expected path_ to be a str, received: {type(path_)}") if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") self.description = description_ self.name = name_ @@ -6449,8 +5659,7 @@ def __init__( type_=None, **unknown_fields, ): - """ - charmresource : CharmResource + """Charmresource : CharmResource errorresult : ErrorResult description : str error : Error @@ -6481,70 +5690,50 @@ def __init__( charmresource_, (dict, CharmResource) ): raise Exception( - "Expected charmresource_ to be a CharmResource, received: {}".format( - type(charmresource_) - ) + f"Expected charmresource_ to be a CharmResource, received: {type(charmresource_)}" ) if errorresult_ is not None and not isinstance( errorresult_, (dict, ErrorResult) ): raise Exception( - "Expected errorresult_ to be a ErrorResult, received: {}".format( - type(errorresult_) - ) + f"Expected errorresult_ to be a ErrorResult, received: {type(errorresult_)}" ) if description_ is not None and not isinstance(description_, (bytes, str)): raise Exception( - "Expected description_ to be a str, received: {}".format( - type(description_) - ) + f"Expected description_ to be a str, received: {type(description_)}" ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if fingerprint_ is not None and not isinstance( fingerprint_, (bytes, str, list) ): raise Exception( - "Expected fingerprint_ to be a Sequence, received: {}".format( - type(fingerprint_) - ) + f"Expected fingerprint_ to be a Sequence, received: {type(fingerprint_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if origin_ is not None and not isinstance(origin_, (bytes, str)): - raise Exception( - "Expected origin_ to be a str, received: {}".format(type(origin_)) - ) + raise Exception(f"Expected origin_ to be a str, received: {type(origin_)}") if path_ is not None and not isinstance(path_, (bytes, str)): - raise Exception( - "Expected path_ to be a str, received: {}".format(type(path_)) - ) + raise Exception(f"Expected path_ to be a str, received: {type(path_)}") if revision_ is not None and not isinstance(revision_, int): raise Exception( - "Expected revision_ to be a int, received: {}".format(type(revision_)) + f"Expected revision_ to be a int, received: {type(revision_)}" ) if size_ is not None and not isinstance(size_, int): - raise Exception( - "Expected size_ to be a int, received: {}".format(type(size_)) - ) + raise Exception(f"Expected size_ to be a int, received: {type(size_)}") if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") self.charmresource = charmresource_ self.errorresult = errorresult_ @@ -6565,17 +5754,13 @@ class CharmResourcesResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~CharmResourceResult] - """ + """Results : typing.Sequence[~CharmResourceResult]""" results_ = [CharmResourceResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -6622,8 +5807,7 @@ def __init__( type_=None, **unknown_fields, ): - """ - count_max : int + """count_max : int count_min : int description : str location : str @@ -6648,61 +5832,47 @@ def __init__( # Validate arguments against known Juju API types. if count_max_ is not None and not isinstance(count_max_, int): raise Exception( - "Expected count_max_ to be a int, received: {}".format(type(count_max_)) + f"Expected count_max_ to be a int, received: {type(count_max_)}" ) if count_min_ is not None and not isinstance(count_min_, int): raise Exception( - "Expected count_min_ to be a int, received: {}".format(type(count_min_)) + f"Expected count_min_ to be a int, received: {type(count_min_)}" ) if description_ is not None and not isinstance(description_, (bytes, str)): raise Exception( - "Expected description_ to be a str, received: {}".format( - type(description_) - ) + f"Expected description_ to be a str, received: {type(description_)}" ) if location_ is not None and not isinstance(location_, (bytes, str)): raise Exception( - "Expected location_ to be a str, received: {}".format(type(location_)) + f"Expected location_ to be a str, received: {type(location_)}" ) if minimum_size_ is not None and not isinstance(minimum_size_, int): raise Exception( - "Expected minimum_size_ to be a int, received: {}".format( - type(minimum_size_) - ) + f"Expected minimum_size_ to be a int, received: {type(minimum_size_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if properties_ is not None and not isinstance(properties_, (bytes, str, list)): raise Exception( - "Expected properties_ to be a Sequence, received: {}".format( - type(properties_) - ) + f"Expected properties_ to be a Sequence, received: {type(properties_)}" ) if read_only_ is not None and not isinstance(read_only_, bool): raise Exception( - "Expected read_only_ to be a bool, received: {}".format( - type(read_only_) - ) + f"Expected read_only_ to be a bool, received: {type(read_only_)}" ) if shared_ is not None and not isinstance(shared_, bool): - raise Exception( - "Expected shared_ to be a bool, received: {}".format(type(shared_)) - ) + raise Exception(f"Expected shared_ to be a bool, received: {type(shared_)}") if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") self.count_max = count_max_ self.count_min = count_min_ @@ -6722,16 +5892,12 @@ class CharmURL(Type): _toPy = {"url": "url"} def __init__(self, url=None, **unknown_fields): - """ - url : str - """ + """Url : str""" url_ = url # Validate arguments against known Juju API types. if url_ is not None and not isinstance(url_, (bytes, str)): - raise Exception( - "Expected url_ to be a str, received: {}".format(type(url_)) - ) + raise Exception(f"Expected url_ to be a str, received: {type(url_)}") self.url = url_ self.unknown_fields = unknown_fields @@ -6752,8 +5918,7 @@ class CharmURLAndOrigin(Type): def __init__( self, charm_origin=None, charm_url=None, macaroon=None, **unknown_fields ): - """ - charm_origin : CharmOrigin + """charm_origin : CharmOrigin charm_url : str macaroon : Macaroon """ @@ -6766,21 +5931,17 @@ def __init__( charm_origin_, (dict, CharmOrigin) ): raise Exception( - "Expected charm_origin_ to be a CharmOrigin, received: {}".format( - type(charm_origin_) - ) + f"Expected charm_origin_ to be a CharmOrigin, received: {type(charm_origin_)}" ) if charm_url_ is not None and not isinstance(charm_url_, (bytes, str)): raise Exception( - "Expected charm_url_ to be a str, received: {}".format(type(charm_url_)) + f"Expected charm_url_ to be a str, received: {type(charm_url_)}" ) if macaroon_ is not None and not isinstance(macaroon_, (dict, Macaroon)): raise Exception( - "Expected macaroon_ to be a Macaroon, received: {}".format( - type(macaroon_) - ) + f"Expected macaroon_ to be a Macaroon, received: {type(macaroon_)}" ) self.charm_origin = charm_origin_ @@ -6794,17 +5955,13 @@ class CharmURLAndOrigins(Type): _toPy = {"entities": "entities"} def __init__(self, entities=None, **unknown_fields): - """ - entities : typing.Sequence[~CharmURLAndOrigin] - """ + """Entities : typing.Sequence[~CharmURLAndOrigin]""" entities_ = [CharmURLAndOrigin.from_json(o) for o in entities or []] # Validate arguments against known Juju API types. if entities_ is not None and not isinstance(entities_, (bytes, str, list)): raise Exception( - "Expected entities_ to be a Sequence, received: {}".format( - type(entities_) - ) + f"Expected entities_ to be a Sequence, received: {type(entities_)}" ) self.entities = entities_ @@ -6816,8 +5973,7 @@ class CharmURLOriginResult(Type): _toPy = {"charm-origin": "charm_origin", "error": "error", "url": "url"} def __init__(self, charm_origin=None, error=None, url=None, **unknown_fields): - """ - charm_origin : CharmOrigin + """charm_origin : CharmOrigin error : Error url : str """ @@ -6830,20 +5986,14 @@ def __init__(self, charm_origin=None, error=None, url=None, **unknown_fields): charm_origin_, (dict, CharmOrigin) ): raise Exception( - "Expected charm_origin_ to be a CharmOrigin, received: {}".format( - type(charm_origin_) - ) + f"Expected charm_origin_ to be a CharmOrigin, received: {type(charm_origin_)}" ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if url_ is not None and not isinstance(url_, (bytes, str)): - raise Exception( - "Expected url_ to be a str, received: {}".format(type(url_)) - ) + raise Exception(f"Expected url_ to be a str, received: {type(url_)}") self.charm_origin = charm_origin_ self.error = error_ @@ -6856,15 +6006,13 @@ class CharmsList(Type): _toPy = {"names": "names"} def __init__(self, names=None, **unknown_fields): - """ - names : typing.Sequence[str] - """ + """Names : typing.Sequence[str]""" names_ = names # Validate arguments against known Juju API types. if names_ is not None and not isinstance(names_, (bytes, str, list)): raise Exception( - "Expected names_ to be a Sequence, received: {}".format(type(names_)) + f"Expected names_ to be a Sequence, received: {type(names_)}" ) self.names = names_ @@ -6876,17 +6024,13 @@ class CharmsListResult(Type): _toPy = {"charm-urls": "charm_urls"} def __init__(self, charm_urls=None, **unknown_fields): - """ - charm_urls : typing.Sequence[str] - """ + """charm_urls : typing.Sequence[str]""" charm_urls_ = charm_urls # Validate arguments against known Juju API types. if charm_urls_ is not None and not isinstance(charm_urls_, (bytes, str, list)): raise Exception( - "Expected charm_urls_ to be a Sequence, received: {}".format( - type(charm_urls_) - ) + f"Expected charm_urls_ to be a Sequence, received: {type(charm_urls_)}" ) self.charm_urls = charm_urls_ @@ -6939,8 +6083,7 @@ def __init__( type_=None, **unknown_fields, ): - """ - auth_types : typing.Sequence[str] + """auth_types : typing.Sequence[str] ca_certificates : typing.Sequence[str] config : typing.Mapping[str, typing.Any] endpoint : str @@ -6969,91 +6112,71 @@ def __init__( # Validate arguments against known Juju API types. if auth_types_ is not None and not isinstance(auth_types_, (bytes, str, list)): raise Exception( - "Expected auth_types_ to be a Sequence, received: {}".format( - type(auth_types_) - ) + f"Expected auth_types_ to be a Sequence, received: {type(auth_types_)}" ) if ca_certificates_ is not None and not isinstance( ca_certificates_, (bytes, str, list) ): raise Exception( - "Expected ca_certificates_ to be a Sequence, received: {}".format( - type(ca_certificates_) - ) + f"Expected ca_certificates_ to be a Sequence, received: {type(ca_certificates_)}" ) if config_ is not None and not isinstance(config_, dict): raise Exception( - "Expected config_ to be a Mapping, received: {}".format(type(config_)) + f"Expected config_ to be a Mapping, received: {type(config_)}" ) if endpoint_ is not None and not isinstance(endpoint_, (bytes, str)): raise Exception( - "Expected endpoint_ to be a str, received: {}".format(type(endpoint_)) + f"Expected endpoint_ to be a str, received: {type(endpoint_)}" ) if host_cloud_region_ is not None and not isinstance( host_cloud_region_, (bytes, str) ): raise Exception( - "Expected host_cloud_region_ to be a str, received: {}".format( - type(host_cloud_region_) - ) + f"Expected host_cloud_region_ to be a str, received: {type(host_cloud_region_)}" ) if identity_endpoint_ is not None and not isinstance( identity_endpoint_, (bytes, str) ): raise Exception( - "Expected identity_endpoint_ to be a str, received: {}".format( - type(identity_endpoint_) - ) + f"Expected identity_endpoint_ to be a str, received: {type(identity_endpoint_)}" ) if is_controller_cloud_ is not None and not isinstance( is_controller_cloud_, bool ): raise Exception( - "Expected is_controller_cloud_ to be a bool, received: {}".format( - type(is_controller_cloud_) - ) + f"Expected is_controller_cloud_ to be a bool, received: {type(is_controller_cloud_)}" ) if region_config_ is not None and not isinstance(region_config_, dict): raise Exception( - "Expected region_config_ to be a Mapping, received: {}".format( - type(region_config_) - ) + f"Expected region_config_ to be a Mapping, received: {type(region_config_)}" ) if regions_ is not None and not isinstance(regions_, (bytes, str, list)): raise Exception( - "Expected regions_ to be a Sequence, received: {}".format( - type(regions_) - ) + f"Expected regions_ to be a Sequence, received: {type(regions_)}" ) if skip_tls_verify_ is not None and not isinstance(skip_tls_verify_, bool): raise Exception( - "Expected skip_tls_verify_ to be a bool, received: {}".format( - type(skip_tls_verify_) - ) + f"Expected skip_tls_verify_ to be a bool, received: {type(skip_tls_verify_)}" ) if storage_endpoint_ is not None and not isinstance( storage_endpoint_, (bytes, str) ): raise Exception( - "Expected storage_endpoint_ to be a str, received: {}".format( - type(storage_endpoint_) - ) + f"Expected storage_endpoint_ to be a str, received: {type(storage_endpoint_)}" ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") self.auth_types = auth_types_ self.ca_certificates = ca_certificates_ @@ -7075,8 +6198,7 @@ class CloudCredential(Type): _toPy = {"attrs": "attrs", "auth-type": "auth_type", "redacted": "redacted"} def __init__(self, attrs=None, auth_type=None, redacted=None, **unknown_fields): - """ - attrs : typing.Mapping[str, str] + """Attrs : typing.Mapping[str, str] auth_type : str redacted : typing.Sequence[str] """ @@ -7087,19 +6209,17 @@ def __init__(self, attrs=None, auth_type=None, redacted=None, **unknown_fields): # Validate arguments against known Juju API types. if attrs_ is not None and not isinstance(attrs_, dict): raise Exception( - "Expected attrs_ to be a Mapping, received: {}".format(type(attrs_)) + f"Expected attrs_ to be a Mapping, received: {type(attrs_)}" ) if auth_type_ is not None and not isinstance(auth_type_, (bytes, str)): raise Exception( - "Expected auth_type_ to be a str, received: {}".format(type(auth_type_)) + f"Expected auth_type_ to be a str, received: {type(auth_type_)}" ) if redacted_ is not None and not isinstance(redacted_, (bytes, str, list)): raise Exception( - "Expected redacted_ to be a Sequence, received: {}".format( - type(redacted_) - ) + f"Expected redacted_ to be a Sequence, received: {type(redacted_)}" ) self.attrs = attrs_ @@ -7113,8 +6233,7 @@ class CloudCredentialArg(Type): _toPy = {"cloud-name": "cloud_name", "credential-name": "credential_name"} def __init__(self, cloud_name=None, credential_name=None, **unknown_fields): - """ - cloud_name : str + """cloud_name : str credential_name : str """ cloud_name_ = cloud_name @@ -7123,18 +6242,14 @@ def __init__(self, cloud_name=None, credential_name=None, **unknown_fields): # Validate arguments against known Juju API types. if cloud_name_ is not None and not isinstance(cloud_name_, (bytes, str)): raise Exception( - "Expected cloud_name_ to be a str, received: {}".format( - type(cloud_name_) - ) + f"Expected cloud_name_ to be a str, received: {type(cloud_name_)}" ) if credential_name_ is not None and not isinstance( credential_name_, (bytes, str) ): raise Exception( - "Expected credential_name_ to be a str, received: {}".format( - type(credential_name_) - ) + f"Expected credential_name_ to be a str, received: {type(credential_name_)}" ) self.cloud_name = cloud_name_ @@ -7147,8 +6262,7 @@ class CloudCredentialArgs(Type): _toPy = {"credentials": "credentials", "include-secrets": "include_secrets"} def __init__(self, credentials=None, include_secrets=None, **unknown_fields): - """ - credentials : typing.Sequence[~CloudCredentialArg] + """Credentials : typing.Sequence[~CloudCredentialArg] include_secrets : bool """ credentials_ = [CloudCredentialArg.from_json(o) for o in credentials or []] @@ -7159,16 +6273,12 @@ def __init__(self, credentials=None, include_secrets=None, **unknown_fields): credentials_, (bytes, str, list) ): raise Exception( - "Expected credentials_ to be a Sequence, received: {}".format( - type(credentials_) - ) + f"Expected credentials_ to be a Sequence, received: {type(credentials_)}" ) if include_secrets_ is not None and not isinstance(include_secrets_, bool): raise Exception( - "Expected include_secrets_ to be a bool, received: {}".format( - type(include_secrets_) - ) + f"Expected include_secrets_ to be a bool, received: {type(include_secrets_)}" ) self.credentials = credentials_ @@ -7181,8 +6291,7 @@ class CloudCredentialResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : CloudCredential """ error_ = Error.from_json(error) if error else None @@ -7190,15 +6299,11 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance(result_, (dict, CloudCredential)): raise Exception( - "Expected result_ to be a CloudCredential, received: {}".format( - type(result_) - ) + f"Expected result_ to be a CloudCredential, received: {type(result_)}" ) self.error = error_ @@ -7211,17 +6316,13 @@ class CloudCredentialResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~CloudCredentialResult] - """ + """Results : typing.Sequence[~CloudCredentialResult]""" results_ = [CloudCredentialResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -7256,8 +6357,7 @@ def __init__( type_=None, **unknown_fields, ): - """ - auth_types : typing.Sequence[str] + """auth_types : typing.Sequence[str] endpoint : str identity_endpoint : str regions : typing.Sequence[~CloudRegion] @@ -7274,45 +6374,35 @@ def __init__( # Validate arguments against known Juju API types. if auth_types_ is not None and not isinstance(auth_types_, (bytes, str, list)): raise Exception( - "Expected auth_types_ to be a Sequence, received: {}".format( - type(auth_types_) - ) + f"Expected auth_types_ to be a Sequence, received: {type(auth_types_)}" ) if endpoint_ is not None and not isinstance(endpoint_, (bytes, str)): raise Exception( - "Expected endpoint_ to be a str, received: {}".format(type(endpoint_)) + f"Expected endpoint_ to be a str, received: {type(endpoint_)}" ) if identity_endpoint_ is not None and not isinstance( identity_endpoint_, (bytes, str) ): raise Exception( - "Expected identity_endpoint_ to be a str, received: {}".format( - type(identity_endpoint_) - ) + f"Expected identity_endpoint_ to be a str, received: {type(identity_endpoint_)}" ) if regions_ is not None and not isinstance(regions_, (bytes, str, list)): raise Exception( - "Expected regions_ to be a Sequence, received: {}".format( - type(regions_) - ) + f"Expected regions_ to be a Sequence, received: {type(regions_)}" ) if storage_endpoint_ is not None and not isinstance( storage_endpoint_, (bytes, str) ): raise Exception( - "Expected storage_endpoint_ to be a str, received: {}".format( - type(storage_endpoint_) - ) + f"Expected storage_endpoint_ to be a str, received: {type(storage_endpoint_)}" ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") self.auth_types = auth_types_ self.endpoint = endpoint_ @@ -7363,8 +6453,7 @@ def __init__( virt_type=None, **unknown_fields, ): - """ - arch : str + """Arch : str image_id : str priority : int region : str @@ -7388,59 +6477,47 @@ def __init__( # Validate arguments against known Juju API types. if arch_ is not None and not isinstance(arch_, (bytes, str)): - raise Exception( - "Expected arch_ to be a str, received: {}".format(type(arch_)) - ) + raise Exception(f"Expected arch_ to be a str, received: {type(arch_)}") if image_id_ is not None and not isinstance(image_id_, (bytes, str)): raise Exception( - "Expected image_id_ to be a str, received: {}".format(type(image_id_)) + f"Expected image_id_ to be a str, received: {type(image_id_)}" ) if priority_ is not None and not isinstance(priority_, int): raise Exception( - "Expected priority_ to be a int, received: {}".format(type(priority_)) + f"Expected priority_ to be a int, received: {type(priority_)}" ) if region_ is not None and not isinstance(region_, (bytes, str)): - raise Exception( - "Expected region_ to be a str, received: {}".format(type(region_)) - ) + raise Exception(f"Expected region_ to be a str, received: {type(region_)}") if root_storage_size_ is not None and not isinstance(root_storage_size_, int): raise Exception( - "Expected root_storage_size_ to be a int, received: {}".format( - type(root_storage_size_) - ) + f"Expected root_storage_size_ to be a int, received: {type(root_storage_size_)}" ) if root_storage_type_ is not None and not isinstance( root_storage_type_, (bytes, str) ): raise Exception( - "Expected root_storage_type_ to be a str, received: {}".format( - type(root_storage_type_) - ) + f"Expected root_storage_type_ to be a str, received: {type(root_storage_type_)}" ) if source_ is not None and not isinstance(source_, (bytes, str)): - raise Exception( - "Expected source_ to be a str, received: {}".format(type(source_)) - ) + raise Exception(f"Expected source_ to be a str, received: {type(source_)}") if stream_ is not None and not isinstance(stream_, (bytes, str)): - raise Exception( - "Expected stream_ to be a str, received: {}".format(type(stream_)) - ) + raise Exception(f"Expected stream_ to be a str, received: {type(stream_)}") if version_ is not None and not isinstance(version_, (bytes, str)): raise Exception( - "Expected version_ to be a str, received: {}".format(type(version_)) + f"Expected version_ to be a str, received: {type(version_)}" ) if virt_type_ is not None and not isinstance(virt_type_, (bytes, str)): raise Exception( - "Expected virt_type_ to be a str, received: {}".format(type(virt_type_)) + f"Expected virt_type_ to be a str, received: {type(virt_type_)}" ) self.arch = arch_ @@ -7461,17 +6538,13 @@ class CloudImageMetadataList(Type): _toPy = {"metadata": "metadata"} def __init__(self, metadata=None, **unknown_fields): - """ - metadata : typing.Sequence[~CloudImageMetadata] - """ + """Metadata : typing.Sequence[~CloudImageMetadata]""" metadata_ = [CloudImageMetadata.from_json(o) for o in metadata or []] # Validate arguments against known Juju API types. if metadata_ is not None and not isinstance(metadata_, (bytes, str, list)): raise Exception( - "Expected metadata_ to be a Sequence, received: {}".format( - type(metadata_) - ) + f"Expected metadata_ to be a Sequence, received: {type(metadata_)}" ) self.metadata = metadata_ @@ -7483,8 +6556,7 @@ class CloudInfo(Type): _toPy = {"CloudDetails": "clouddetails", "users": "users"} def __init__(self, clouddetails=None, users=None, **unknown_fields): - """ - clouddetails : CloudDetails + """Clouddetails : CloudDetails users : typing.Sequence[~CloudUserInfo] """ clouddetails_ = CloudDetails.from_json(clouddetails) if clouddetails else None @@ -7495,14 +6567,12 @@ def __init__(self, clouddetails=None, users=None, **unknown_fields): clouddetails_, (dict, CloudDetails) ): raise Exception( - "Expected clouddetails_ to be a CloudDetails, received: {}".format( - type(clouddetails_) - ) + f"Expected clouddetails_ to be a CloudDetails, received: {type(clouddetails_)}" ) if users_ is not None and not isinstance(users_, (bytes, str, list)): raise Exception( - "Expected users_ to be a Sequence, received: {}".format(type(users_)) + f"Expected users_ to be a Sequence, received: {type(users_)}" ) self.clouddetails = clouddetails_ @@ -7515,8 +6585,7 @@ class CloudInfoResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : CloudInfo """ error_ = Error.from_json(error) if error else None @@ -7524,13 +6593,11 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance(result_, (dict, CloudInfo)): raise Exception( - "Expected result_ to be a CloudInfo, received: {}".format(type(result_)) + f"Expected result_ to be a CloudInfo, received: {type(result_)}" ) self.error = error_ @@ -7543,17 +6610,13 @@ class CloudInfoResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~CloudInfoResult] - """ + """Results : typing.Sequence[~CloudInfoResult]""" results_ = [CloudInfoResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -7569,8 +6632,7 @@ class CloudInstanceTypesConstraint(Type): _toPy = {"cloud-tag": "cloud_tag", "constraints": "constraints", "region": "region"} def __init__(self, cloud_tag=None, constraints=None, region=None, **unknown_fields): - """ - cloud_tag : str + """cloud_tag : str constraints : Value region : str """ @@ -7581,20 +6643,16 @@ def __init__(self, cloud_tag=None, constraints=None, region=None, **unknown_fiel # Validate arguments against known Juju API types. if cloud_tag_ is not None and not isinstance(cloud_tag_, (bytes, str)): raise Exception( - "Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_)) + f"Expected cloud_tag_ to be a str, received: {type(cloud_tag_)}" ) if constraints_ is not None and not isinstance(constraints_, (dict, Value)): raise Exception( - "Expected constraints_ to be a Value, received: {}".format( - type(constraints_) - ) + f"Expected constraints_ to be a Value, received: {type(constraints_)}" ) if region_ is not None and not isinstance(region_, (bytes, str)): - raise Exception( - "Expected region_ to be a str, received: {}".format(type(region_)) - ) + raise Exception(f"Expected region_ to be a str, received: {type(region_)}") self.cloud_tag = cloud_tag_ self.constraints = constraints_ @@ -7607,9 +6665,7 @@ class CloudInstanceTypesConstraints(Type): _toPy = {"constraints": "constraints"} def __init__(self, constraints=None, **unknown_fields): - """ - constraints : typing.Sequence[~CloudInstanceTypesConstraint] - """ + """Constraints : typing.Sequence[~CloudInstanceTypesConstraint]""" constraints_ = [ CloudInstanceTypesConstraint.from_json(o) for o in constraints or [] ] @@ -7619,9 +6675,7 @@ def __init__(self, constraints=None, **unknown_fields): constraints_, (bytes, str, list) ): raise Exception( - "Expected constraints_ to be a Sequence, received: {}".format( - type(constraints_) - ) + f"Expected constraints_ to be a Sequence, received: {type(constraints_)}" ) self.constraints = constraints_ @@ -7650,8 +6704,7 @@ def __init__( storage_endpoint=None, **unknown_fields, ): - """ - endpoint : str + """Endpoint : str identity_endpoint : str name : str storage_endpoint : str @@ -7664,30 +6717,24 @@ def __init__( # Validate arguments against known Juju API types. if endpoint_ is not None and not isinstance(endpoint_, (bytes, str)): raise Exception( - "Expected endpoint_ to be a str, received: {}".format(type(endpoint_)) + f"Expected endpoint_ to be a str, received: {type(endpoint_)}" ) if identity_endpoint_ is not None and not isinstance( identity_endpoint_, (bytes, str) ): raise Exception( - "Expected identity_endpoint_ to be a str, received: {}".format( - type(identity_endpoint_) - ) + f"Expected identity_endpoint_ to be a str, received: {type(identity_endpoint_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if storage_endpoint_ is not None and not isinstance( storage_endpoint_, (bytes, str) ): raise Exception( - "Expected storage_endpoint_ to be a str, received: {}".format( - type(storage_endpoint_) - ) + f"Expected storage_endpoint_ to be a str, received: {type(storage_endpoint_)}" ) self.endpoint = endpoint_ @@ -7702,8 +6749,7 @@ class CloudResult(Type): _toPy = {"cloud": "cloud", "error": "error"} def __init__(self, cloud=None, error=None, **unknown_fields): - """ - cloud : Cloud + """Cloud : Cloud error : Error """ cloud_ = Cloud.from_json(cloud) if cloud else None @@ -7711,14 +6757,10 @@ def __init__(self, cloud=None, error=None, **unknown_fields): # Validate arguments against known Juju API types. if cloud_ is not None and not isinstance(cloud_, (dict, Cloud)): - raise Exception( - "Expected cloud_ to be a Cloud, received: {}".format(type(cloud_)) - ) + raise Exception(f"Expected cloud_ to be a Cloud, received: {type(cloud_)}") if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") self.cloud = cloud_ self.error = error_ @@ -7730,17 +6772,13 @@ class CloudResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~CloudResult] - """ + """Results : typing.Sequence[~CloudResult]""" results_ = [CloudResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -7787,8 +6825,7 @@ def __init__( type_=None, **unknown_fields, ): - """ - cacertificates : typing.Sequence[str] + """Cacertificates : typing.Sequence[str] credential : CloudCredential endpoint : str identity_endpoint : str @@ -7815,73 +6852,55 @@ def __init__( cacertificates_, (bytes, str, list) ): raise Exception( - "Expected cacertificates_ to be a Sequence, received: {}".format( - type(cacertificates_) - ) + f"Expected cacertificates_ to be a Sequence, received: {type(cacertificates_)}" ) if credential_ is not None and not isinstance( credential_, (dict, CloudCredential) ): raise Exception( - "Expected credential_ to be a CloudCredential, received: {}".format( - type(credential_) - ) + f"Expected credential_ to be a CloudCredential, received: {type(credential_)}" ) if endpoint_ is not None and not isinstance(endpoint_, (bytes, str)): raise Exception( - "Expected endpoint_ to be a str, received: {}".format(type(endpoint_)) + f"Expected endpoint_ to be a str, received: {type(endpoint_)}" ) if identity_endpoint_ is not None and not isinstance( identity_endpoint_, (bytes, str) ): raise Exception( - "Expected identity_endpoint_ to be a str, received: {}".format( - type(identity_endpoint_) - ) + f"Expected identity_endpoint_ to be a str, received: {type(identity_endpoint_)}" ) if is_controller_cloud_ is not None and not isinstance( is_controller_cloud_, bool ): raise Exception( - "Expected is_controller_cloud_ to be a bool, received: {}".format( - type(is_controller_cloud_) - ) + f"Expected is_controller_cloud_ to be a bool, received: {type(is_controller_cloud_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if region_ is not None and not isinstance(region_, (bytes, str)): - raise Exception( - "Expected region_ to be a str, received: {}".format(type(region_)) - ) + raise Exception(f"Expected region_ to be a str, received: {type(region_)}") if skip_tls_verify_ is not None and not isinstance(skip_tls_verify_, bool): raise Exception( - "Expected skip_tls_verify_ to be a bool, received: {}".format( - type(skip_tls_verify_) - ) + f"Expected skip_tls_verify_ to be a bool, received: {type(skip_tls_verify_)}" ) if storage_endpoint_ is not None and not isinstance( storage_endpoint_, (bytes, str) ): raise Exception( - "Expected storage_endpoint_ to be a str, received: {}".format( - type(storage_endpoint_) - ) + f"Expected storage_endpoint_ to be a str, received: {type(storage_endpoint_)}" ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") self.cacertificates = cacertificates_ self.credential = credential_ @@ -7901,8 +6920,7 @@ class CloudSpecResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : CloudSpec """ error_ = Error.from_json(error) if error else None @@ -7910,13 +6928,11 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance(result_, (dict, CloudSpec)): raise Exception( - "Expected result_ to be a CloudSpec, received: {}".format(type(result_)) + f"Expected result_ to be a CloudSpec, received: {type(result_)}" ) self.error = error_ @@ -7929,17 +6945,13 @@ class CloudSpecResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~CloudSpecResult] - """ + """Results : typing.Sequence[~CloudSpecResult]""" results_ = [CloudSpecResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -7951,8 +6963,7 @@ class CloudUserInfo(Type): _toPy = {"access": "access", "display-name": "display_name", "user": "user"} def __init__(self, access=None, display_name=None, user=None, **unknown_fields): - """ - access : str + """Access : str display_name : str user : str """ @@ -7962,21 +6973,15 @@ def __init__(self, access=None, display_name=None, user=None, **unknown_fields): # Validate arguments against known Juju API types. if access_ is not None and not isinstance(access_, (bytes, str)): - raise Exception( - "Expected access_ to be a str, received: {}".format(type(access_)) - ) + raise Exception(f"Expected access_ to be a str, received: {type(access_)}") if display_name_ is not None and not isinstance(display_name_, (bytes, str)): raise Exception( - "Expected display_name_ to be a str, received: {}".format( - type(display_name_) - ) + f"Expected display_name_ to be a str, received: {type(display_name_)}" ) if user_ is not None and not isinstance(user_, (bytes, str)): - raise Exception( - "Expected user_ to be a str, received: {}".format(type(user_)) - ) + raise Exception(f"Expected user_ to be a str, received: {type(user_)}") self.access = access_ self.display_name = display_name_ @@ -7989,15 +6994,13 @@ class CloudsResult(Type): _toPy = {"clouds": "clouds"} def __init__(self, clouds=None, **unknown_fields): - """ - clouds : typing.Mapping[str, ~Cloud] - """ + """Clouds : typing.Mapping[str, ~Cloud]""" clouds_ = {k: Cloud.from_json(v) for k, v in (clouds or dict()).items()} # Validate arguments against known Juju API types. if clouds_ is not None and not isinstance(clouds_, dict): raise Exception( - "Expected clouds_ to be a Mapping, received: {}".format(type(clouds_)) + f"Expected clouds_ to be a Mapping, received: {type(clouds_)}" ) self.clouds = clouds_ @@ -8009,8 +7012,7 @@ class ConfigResult(Type): _toPy = {"config": "config", "error": "error"} def __init__(self, config=None, error=None, **unknown_fields): - """ - config : typing.Mapping[str, typing.Any] + """Config : typing.Mapping[str, typing.Any] error : Error """ config_ = config @@ -8019,13 +7021,11 @@ def __init__(self, config=None, error=None, **unknown_fields): # Validate arguments against known Juju API types. if config_ is not None and not isinstance(config_, dict): raise Exception( - "Expected config_ to be a Mapping, received: {}".format(type(config_)) + f"Expected config_ to be a Mapping, received: {type(config_)}" ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") self.config = config_ self.error = error_ @@ -8054,8 +7054,7 @@ def __init__( generation=None, **unknown_fields, ): - """ - application : str + """Application : str config : typing.Mapping[str, str] config_yaml : str generation : str @@ -8068,28 +7067,22 @@ def __init__( # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): raise Exception( - "Expected application_ to be a str, received: {}".format( - type(application_) - ) + f"Expected application_ to be a str, received: {type(application_)}" ) if config_ is not None and not isinstance(config_, dict): raise Exception( - "Expected config_ to be a Mapping, received: {}".format(type(config_)) + f"Expected config_ to be a Mapping, received: {type(config_)}" ) if config_yaml_ is not None and not isinstance(config_yaml_, (bytes, str)): raise Exception( - "Expected config_yaml_ to be a str, received: {}".format( - type(config_yaml_) - ) + f"Expected config_yaml_ to be a str, received: {type(config_yaml_)}" ) if generation_ is not None and not isinstance(generation_, (bytes, str)): raise Exception( - "Expected generation_ to be a str, received: {}".format( - type(generation_) - ) + f"Expected generation_ to be a str, received: {type(generation_)}" ) self.application = application_ @@ -8104,16 +7097,12 @@ class ConfigSetArgs(Type): _toPy = {"Args": "args"} def __init__(self, args=None, **unknown_fields): - """ - args : typing.Sequence[~ConfigSet] - """ + """Args : typing.Sequence[~ConfigSet]""" args_ = [ConfigSet.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception( - "Expected args_ to be a Sequence, received: {}".format(type(args_)) - ) + raise Exception(f"Expected args_ to be a Sequence, received: {type(args_)}") self.args = args_ self.unknown_fields = unknown_fields @@ -8124,8 +7113,7 @@ class ConfigValue(Type): _toPy = {"source": "source", "value": "value"} def __init__(self, source=None, value=None, **unknown_fields): - """ - source : str + """Source : str value : Any """ source_ = source @@ -8133,9 +7121,7 @@ def __init__(self, source=None, value=None, **unknown_fields): # Validate arguments against known Juju API types. if source_ is not None and not isinstance(source_, (bytes, str)): - raise Exception( - "Expected source_ to be a str, received: {}".format(type(source_)) - ) + raise Exception(f"Expected source_ to be a str, received: {type(source_)}") self.source = source_ self.value = value_ @@ -8147,8 +7133,7 @@ class Constraints(Type): _toPy = {"Count": "count", "Pool": "pool", "Size": "size"} def __init__(self, count=None, pool=None, size=None, **unknown_fields): - """ - count : int + """Count : int pool : str size : int """ @@ -8158,19 +7143,13 @@ def __init__(self, count=None, pool=None, size=None, **unknown_fields): # Validate arguments against known Juju API types. if count_ is not None and not isinstance(count_, int): - raise Exception( - "Expected count_ to be a int, received: {}".format(type(count_)) - ) + raise Exception(f"Expected count_ to be a int, received: {type(count_)}") if pool_ is not None and not isinstance(pool_, (bytes, str)): - raise Exception( - "Expected pool_ to be a str, received: {}".format(type(pool_)) - ) + raise Exception(f"Expected pool_ to be a str, received: {type(pool_)}") if size_ is not None and not isinstance(size_, int): - raise Exception( - "Expected size_ to be a int, received: {}".format(type(size_)) - ) + raise Exception(f"Expected size_ to be a int, received: {type(size_)}") self.count = count_ self.pool = pool_ @@ -8227,8 +7206,7 @@ def __init__( users=None, **unknown_fields, ): - """ - applicationofferdetails : ApplicationOfferDetails + """Applicationofferdetails : ApplicationOfferDetails application_alias : str application_description : str bindings : typing.Mapping[str, str] @@ -8269,95 +7247,75 @@ def __init__( applicationofferdetails_, (dict, ApplicationOfferDetails) ): raise Exception( - "Expected applicationofferdetails_ to be a ApplicationOfferDetails, received: {}".format( - type(applicationofferdetails_) - ) + f"Expected applicationofferdetails_ to be a ApplicationOfferDetails, received: {type(applicationofferdetails_)}" ) if application_alias_ is not None and not isinstance( application_alias_, (bytes, str) ): raise Exception( - "Expected application_alias_ to be a str, received: {}".format( - type(application_alias_) - ) + f"Expected application_alias_ to be a str, received: {type(application_alias_)}" ) if application_description_ is not None and not isinstance( application_description_, (bytes, str) ): raise Exception( - "Expected application_description_ to be a str, received: {}".format( - type(application_description_) - ) + f"Expected application_description_ to be a str, received: {type(application_description_)}" ) if bindings_ is not None and not isinstance(bindings_, dict): raise Exception( - "Expected bindings_ to be a Mapping, received: {}".format( - type(bindings_) - ) + f"Expected bindings_ to be a Mapping, received: {type(bindings_)}" ) if endpoints_ is not None and not isinstance(endpoints_, (bytes, str, list)): raise Exception( - "Expected endpoints_ to be a Sequence, received: {}".format( - type(endpoints_) - ) + f"Expected endpoints_ to be a Sequence, received: {type(endpoints_)}" ) if external_controller_ is not None and not isinstance( external_controller_, (dict, ExternalControllerInfo) ): raise Exception( - "Expected external_controller_ to be a ExternalControllerInfo, received: {}".format( - type(external_controller_) - ) + f"Expected external_controller_ to be a ExternalControllerInfo, received: {type(external_controller_)}" ) if macaroon_ is not None and not isinstance(macaroon_, (dict, Macaroon)): raise Exception( - "Expected macaroon_ to be a Macaroon, received: {}".format( - type(macaroon_) - ) + f"Expected macaroon_ to be a Macaroon, received: {type(macaroon_)}" ) if offer_name_ is not None and not isinstance(offer_name_, (bytes, str)): raise Exception( - "Expected offer_name_ to be a str, received: {}".format( - type(offer_name_) - ) + f"Expected offer_name_ to be a str, received: {type(offer_name_)}" ) if offer_url_ is not None and not isinstance(offer_url_, (bytes, str)): raise Exception( - "Expected offer_url_ to be a str, received: {}".format(type(offer_url_)) + f"Expected offer_url_ to be a str, received: {type(offer_url_)}" ) if offer_uuid_ is not None and not isinstance(offer_uuid_, (bytes, str)): raise Exception( - "Expected offer_uuid_ to be a str, received: {}".format( - type(offer_uuid_) - ) + f"Expected offer_uuid_ to be a str, received: {type(offer_uuid_)}" ) if source_model_tag_ is not None and not isinstance( source_model_tag_, (bytes, str) ): raise Exception( - "Expected source_model_tag_ to be a str, received: {}".format( - type(source_model_tag_) - ) + f"Expected source_model_tag_ to be a str, received: {type(source_model_tag_)}" ) if spaces_ is not None and not isinstance(spaces_, (bytes, str, list)): raise Exception( - "Expected spaces_ to be a Sequence, received: {}".format(type(spaces_)) + f"Expected spaces_ to be a Sequence, received: {type(spaces_)}" ) if users_ is not None and not isinstance(users_, (bytes, str, list)): raise Exception( - "Expected users_ to be a Sequence, received: {}".format(type(users_)) + f"Expected users_ to be a Sequence, received: {type(users_)}" ) self.applicationofferdetails = applicationofferdetails_ @@ -8419,8 +7377,7 @@ def __init__( users=None, **unknown_fields, ): - """ - applicationofferdetailsv5 : ApplicationOfferDetailsV5 + """applicationofferdetailsv5 : ApplicationOfferDetailsV5 application_alias : str application_description : str endpoints : typing.Sequence[~RemoteEndpoint] @@ -8457,83 +7414,65 @@ def __init__( applicationofferdetailsv5_, (dict, ApplicationOfferDetailsV5) ): raise Exception( - "Expected applicationofferdetailsv5_ to be a ApplicationOfferDetailsV5, received: {}".format( - type(applicationofferdetailsv5_) - ) + f"Expected applicationofferdetailsv5_ to be a ApplicationOfferDetailsV5, received: {type(applicationofferdetailsv5_)}" ) if application_alias_ is not None and not isinstance( application_alias_, (bytes, str) ): raise Exception( - "Expected application_alias_ to be a str, received: {}".format( - type(application_alias_) - ) + f"Expected application_alias_ to be a str, received: {type(application_alias_)}" ) if application_description_ is not None and not isinstance( application_description_, (bytes, str) ): raise Exception( - "Expected application_description_ to be a str, received: {}".format( - type(application_description_) - ) + f"Expected application_description_ to be a str, received: {type(application_description_)}" ) if endpoints_ is not None and not isinstance(endpoints_, (bytes, str, list)): raise Exception( - "Expected endpoints_ to be a Sequence, received: {}".format( - type(endpoints_) - ) + f"Expected endpoints_ to be a Sequence, received: {type(endpoints_)}" ) if external_controller_ is not None and not isinstance( external_controller_, (dict, ExternalControllerInfo) ): raise Exception( - "Expected external_controller_ to be a ExternalControllerInfo, received: {}".format( - type(external_controller_) - ) + f"Expected external_controller_ to be a ExternalControllerInfo, received: {type(external_controller_)}" ) if macaroon_ is not None and not isinstance(macaroon_, (dict, Macaroon)): raise Exception( - "Expected macaroon_ to be a Macaroon, received: {}".format( - type(macaroon_) - ) + f"Expected macaroon_ to be a Macaroon, received: {type(macaroon_)}" ) if offer_name_ is not None and not isinstance(offer_name_, (bytes, str)): raise Exception( - "Expected offer_name_ to be a str, received: {}".format( - type(offer_name_) - ) + f"Expected offer_name_ to be a str, received: {type(offer_name_)}" ) if offer_url_ is not None and not isinstance(offer_url_, (bytes, str)): raise Exception( - "Expected offer_url_ to be a str, received: {}".format(type(offer_url_)) + f"Expected offer_url_ to be a str, received: {type(offer_url_)}" ) if offer_uuid_ is not None and not isinstance(offer_uuid_, (bytes, str)): raise Exception( - "Expected offer_uuid_ to be a str, received: {}".format( - type(offer_uuid_) - ) + f"Expected offer_uuid_ to be a str, received: {type(offer_uuid_)}" ) if source_model_tag_ is not None and not isinstance( source_model_tag_, (bytes, str) ): raise Exception( - "Expected source_model_tag_ to be a str, received: {}".format( - type(source_model_tag_) - ) + f"Expected source_model_tag_ to be a str, received: {type(source_model_tag_)}" ) if users_ is not None and not isinstance(users_, (bytes, str, list)): raise Exception( - "Expected users_ to be a Sequence, received: {}".format(type(users_)) + f"Expected users_ to be a Sequence, received: {type(users_)}" ) self.applicationofferdetailsv5 = applicationofferdetailsv5_ @@ -8555,16 +7494,12 @@ class ConsumeApplicationArgs(Type): _toPy = {"args": "args"} def __init__(self, args=None, **unknown_fields): - """ - args : typing.Sequence[~ConsumeApplicationArg] - """ + """Args : typing.Sequence[~ConsumeApplicationArg]""" args_ = [ConsumeApplicationArg.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception( - "Expected args_ to be a Sequence, received: {}".format(type(args_)) - ) + raise Exception(f"Expected args_ to be a Sequence, received: {type(args_)}") self.args = args_ self.unknown_fields = unknown_fields @@ -8575,16 +7510,12 @@ class ConsumeApplicationArgsV5(Type): _toPy = {"args": "args"} def __init__(self, args=None, **unknown_fields): - """ - args : typing.Sequence[~ConsumeApplicationArgV5] - """ + """Args : typing.Sequence[~ConsumeApplicationArgV5]""" args_ = [ConsumeApplicationArgV5.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception( - "Expected args_ to be a Sequence, received: {}".format(type(args_)) - ) + raise Exception(f"Expected args_ to be a Sequence, received: {type(args_)}") self.args = args_ self.unknown_fields = unknown_fields @@ -8605,8 +7536,7 @@ class ConsumeOfferDetails(Type): def __init__( self, external_controller=None, macaroon=None, offer=None, **unknown_fields ): - """ - external_controller : ExternalControllerInfo + """external_controller : ExternalControllerInfo macaroon : Macaroon offer : ApplicationOfferDetailsV5 """ @@ -8623,25 +7553,19 @@ def __init__( external_controller_, (dict, ExternalControllerInfo) ): raise Exception( - "Expected external_controller_ to be a ExternalControllerInfo, received: {}".format( - type(external_controller_) - ) + f"Expected external_controller_ to be a ExternalControllerInfo, received: {type(external_controller_)}" ) if macaroon_ is not None and not isinstance(macaroon_, (dict, Macaroon)): raise Exception( - "Expected macaroon_ to be a Macaroon, received: {}".format( - type(macaroon_) - ) + f"Expected macaroon_ to be a Macaroon, received: {type(macaroon_)}" ) if offer_ is not None and not isinstance( offer_, (dict, ApplicationOfferDetailsV5) ): raise Exception( - "Expected offer_ to be a ApplicationOfferDetailsV5, received: {}".format( - type(offer_) - ) + f"Expected offer_ to be a ApplicationOfferDetailsV5, received: {type(offer_)}" ) self.external_controller = external_controller_ @@ -8655,8 +7579,7 @@ class ConsumeOfferDetailsArg(Type): _toPy = {"offer-urls": "offer_urls", "user-tag": "user_tag"} def __init__(self, offer_urls=None, user_tag=None, **unknown_fields): - """ - offer_urls : OfferURLs + """offer_urls : OfferURLs user_tag : str """ offer_urls_ = OfferURLs.from_json(offer_urls) if offer_urls else None @@ -8665,14 +7588,12 @@ def __init__(self, offer_urls=None, user_tag=None, **unknown_fields): # Validate arguments against known Juju API types. if offer_urls_ is not None and not isinstance(offer_urls_, (dict, OfferURLs)): raise Exception( - "Expected offer_urls_ to be a OfferURLs, received: {}".format( - type(offer_urls_) - ) + f"Expected offer_urls_ to be a OfferURLs, received: {type(offer_urls_)}" ) if user_tag_ is not None and not isinstance(user_tag_, (bytes, str)): raise Exception( - "Expected user_tag_ to be a str, received: {}".format(type(user_tag_)) + f"Expected user_tag_ to be a str, received: {type(user_tag_)}" ) self.offer_urls = offer_urls_ @@ -8705,8 +7626,7 @@ def __init__( offer=None, **unknown_fields, ): - """ - consumeofferdetails : ConsumeOfferDetails + """Consumeofferdetails : ConsumeOfferDetails error : Error external_controller : ExternalControllerInfo macaroon : Macaroon @@ -8731,39 +7651,29 @@ def __init__( consumeofferdetails_, (dict, ConsumeOfferDetails) ): raise Exception( - "Expected consumeofferdetails_ to be a ConsumeOfferDetails, received: {}".format( - type(consumeofferdetails_) - ) + f"Expected consumeofferdetails_ to be a ConsumeOfferDetails, received: {type(consumeofferdetails_)}" ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if external_controller_ is not None and not isinstance( external_controller_, (dict, ExternalControllerInfo) ): raise Exception( - "Expected external_controller_ to be a ExternalControllerInfo, received: {}".format( - type(external_controller_) - ) + f"Expected external_controller_ to be a ExternalControllerInfo, received: {type(external_controller_)}" ) if macaroon_ is not None and not isinstance(macaroon_, (dict, Macaroon)): raise Exception( - "Expected macaroon_ to be a Macaroon, received: {}".format( - type(macaroon_) - ) + f"Expected macaroon_ to be a Macaroon, received: {type(macaroon_)}" ) if offer_ is not None and not isinstance( offer_, (dict, ApplicationOfferDetailsV5) ): raise Exception( - "Expected offer_ to be a ApplicationOfferDetailsV5, received: {}".format( - type(offer_) - ) + f"Expected offer_ to be a ApplicationOfferDetailsV5, received: {type(offer_)}" ) self.consumeofferdetails = consumeofferdetails_ @@ -8779,17 +7689,13 @@ class ConsumeOfferDetailsResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~ConsumeOfferDetailsResult] - """ + """Results : typing.Sequence[~ConsumeOfferDetailsResult]""" results_ = [ConsumeOfferDetailsResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -8801,8 +7707,7 @@ class ControllerAPIInfoResult(Type): _toPy = {"addresses": "addresses", "cacert": "cacert", "error": "error"} def __init__(self, addresses=None, cacert=None, error=None, **unknown_fields): - """ - addresses : typing.Sequence[str] + """Addresses : typing.Sequence[str] cacert : str error : Error """ @@ -8813,20 +7718,14 @@ def __init__(self, addresses=None, cacert=None, error=None, **unknown_fields): # Validate arguments against known Juju API types. if addresses_ is not None and not isinstance(addresses_, (bytes, str, list)): raise Exception( - "Expected addresses_ to be a Sequence, received: {}".format( - type(addresses_) - ) + f"Expected addresses_ to be a Sequence, received: {type(addresses_)}" ) if cacert_ is not None and not isinstance(cacert_, (bytes, str)): - raise Exception( - "Expected cacert_ to be a str, received: {}".format(type(cacert_)) - ) + raise Exception(f"Expected cacert_ to be a str, received: {type(cacert_)}") if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") self.addresses = addresses_ self.cacert = cacert_ @@ -8839,17 +7738,13 @@ class ControllerAPIInfoResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~ControllerAPIInfoResult] - """ + """Results : typing.Sequence[~ControllerAPIInfoResult]""" results_ = [ControllerAPIInfoResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -8861,15 +7756,13 @@ class ControllerConfigResult(Type): _toPy = {"config": "config"} def __init__(self, config=None, **unknown_fields): - """ - config : typing.Mapping[str, typing.Any] - """ + """Config : typing.Mapping[str, typing.Any]""" config_ = config # Validate arguments against known Juju API types. if config_ is not None and not isinstance(config_, dict): raise Exception( - "Expected config_ to be a Mapping, received: {}".format(type(config_)) + f"Expected config_ to be a Mapping, received: {type(config_)}" ) self.config = config_ @@ -8881,15 +7774,13 @@ class ControllerConfigSet(Type): _toPy = {"config": "config"} def __init__(self, config=None, **unknown_fields): - """ - config : typing.Mapping[str, typing.Any] - """ + """Config : typing.Mapping[str, typing.Any]""" config_ = config # Validate arguments against known Juju API types. if config_ is not None and not isinstance(config_, dict): raise Exception( - "Expected config_ to be a Mapping, received: {}".format(type(config_)) + f"Expected config_ to be a Mapping, received: {type(config_)}" ) self.config = config_ @@ -8901,8 +7792,7 @@ class ControllerCredentialInfo(Type): _toPy = {"content": "content", "models": "models"} def __init__(self, content=None, models=None, **unknown_fields): - """ - content : CredentialContent + """Content : CredentialContent models : typing.Sequence[~ModelAccess] """ content_ = CredentialContent.from_json(content) if content else None @@ -8911,14 +7801,12 @@ def __init__(self, content=None, models=None, **unknown_fields): # Validate arguments against known Juju API types. if content_ is not None and not isinstance(content_, (dict, CredentialContent)): raise Exception( - "Expected content_ to be a CredentialContent, received: {}".format( - type(content_) - ) + f"Expected content_ to be a CredentialContent, received: {type(content_)}" ) if models_ is not None and not isinstance(models_, (bytes, str, list)): raise Exception( - "Expected models_ to be a Sequence, received: {}".format(type(models_)) + f"Expected models_ to be a Sequence, received: {type(models_)}" ) self.content = content_ @@ -8931,8 +7819,7 @@ class ControllerVersionResults(Type): _toPy = {"git-commit": "git_commit", "version": "version"} def __init__(self, git_commit=None, version=None, **unknown_fields): - """ - git_commit : str + """git_commit : str version : str """ git_commit_ = git_commit @@ -8941,14 +7828,12 @@ def __init__(self, git_commit=None, version=None, **unknown_fields): # Validate arguments against known Juju API types. if git_commit_ is not None and not isinstance(git_commit_, (bytes, str)): raise Exception( - "Expected git_commit_ to be a str, received: {}".format( - type(git_commit_) - ) + f"Expected git_commit_ to be a str, received: {type(git_commit_)}" ) if version_ is not None and not isinstance(version_, (bytes, str)): raise Exception( - "Expected version_ to be a str, received: {}".format(type(version_)) + f"Expected version_ to be a str, received: {type(version_)}" ) self.git_commit = git_commit_ @@ -8961,8 +7846,7 @@ class ControllersChangeResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : ControllersChanges """ error_ = Error.from_json(error) if error else None @@ -8970,15 +7854,11 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance(result_, (dict, ControllersChanges)): raise Exception( - "Expected result_ to be a ControllersChanges, received: {}".format( - type(result_) - ) + f"Expected result_ to be a ControllersChanges, received: {type(result_)}" ) self.error = error_ @@ -8991,17 +7871,13 @@ class ControllersChangeResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~ControllersChangeResult] - """ + """Results : typing.Sequence[~ControllersChangeResult]""" results_ = [ControllersChangeResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -9030,8 +7906,7 @@ def __init__( removed=None, **unknown_fields, ): - """ - added : typing.Sequence[str] + """Added : typing.Sequence[str] converted : typing.Sequence[str] maintained : typing.Sequence[str] removed : typing.Sequence[str] @@ -9044,28 +7919,22 @@ def __init__( # Validate arguments against known Juju API types. if added_ is not None and not isinstance(added_, (bytes, str, list)): raise Exception( - "Expected added_ to be a Sequence, received: {}".format(type(added_)) + f"Expected added_ to be a Sequence, received: {type(added_)}" ) if converted_ is not None and not isinstance(converted_, (bytes, str, list)): raise Exception( - "Expected converted_ to be a Sequence, received: {}".format( - type(converted_) - ) + f"Expected converted_ to be a Sequence, received: {type(converted_)}" ) if maintained_ is not None and not isinstance(maintained_, (bytes, str, list)): raise Exception( - "Expected maintained_ to be a Sequence, received: {}".format( - type(maintained_) - ) + f"Expected maintained_ to be a Sequence, received: {type(maintained_)}" ) if removed_ is not None and not isinstance(removed_, (bytes, str, list)): raise Exception( - "Expected removed_ to be a Sequence, received: {}".format( - type(removed_) - ) + f"Expected removed_ to be a Sequence, received: {type(removed_)}" ) self.added = added_ @@ -9090,8 +7959,7 @@ class ControllersSpec(Type): def __init__( self, constraints=None, num_controllers=None, placement=None, **unknown_fields ): - """ - constraints : Value + """Constraints : Value num_controllers : int placement : typing.Sequence[str] """ @@ -9102,23 +7970,17 @@ def __init__( # Validate arguments against known Juju API types. if constraints_ is not None and not isinstance(constraints_, (dict, Value)): raise Exception( - "Expected constraints_ to be a Value, received: {}".format( - type(constraints_) - ) + f"Expected constraints_ to be a Value, received: {type(constraints_)}" ) if num_controllers_ is not None and not isinstance(num_controllers_, int): raise Exception( - "Expected num_controllers_ to be a int, received: {}".format( - type(num_controllers_) - ) + f"Expected num_controllers_ to be a int, received: {type(num_controllers_)}" ) if placement_ is not None and not isinstance(placement_, (bytes, str, list)): raise Exception( - "Expected placement_ to be a Sequence, received: {}".format( - type(placement_) - ) + f"Expected placement_ to be a Sequence, received: {type(placement_)}" ) self.constraints = constraints_ @@ -9132,15 +7994,13 @@ class ControllersSpecs(Type): _toPy = {"specs": "specs"} def __init__(self, specs=None, **unknown_fields): - """ - specs : typing.Sequence[~ControllersSpec] - """ + """Specs : typing.Sequence[~ControllersSpec]""" specs_ = [ControllersSpec.from_json(o) for o in specs or []] # Validate arguments against known Juju API types. if specs_ is not None and not isinstance(specs_, (bytes, str, list)): raise Exception( - "Expected specs_ to be a Sequence, received: {}".format(type(specs_)) + f"Expected specs_ to be a Sequence, received: {type(specs_)}" ) self.specs = specs_ @@ -9184,8 +8044,7 @@ def __init__( uri=None, **unknown_fields, ): - """ - upsertsecretarg : UpsertSecretArg + """Upsertsecretarg : UpsertSecretArg content : SecretContentParams description : str expire_time : str @@ -9212,60 +8071,46 @@ def __init__( upsertsecretarg_, (dict, UpsertSecretArg) ): raise Exception( - "Expected upsertsecretarg_ to be a UpsertSecretArg, received: {}".format( - type(upsertsecretarg_) - ) + f"Expected upsertsecretarg_ to be a UpsertSecretArg, received: {type(upsertsecretarg_)}" ) if content_ is not None and not isinstance( content_, (dict, SecretContentParams) ): raise Exception( - "Expected content_ to be a SecretContentParams, received: {}".format( - type(content_) - ) + f"Expected content_ to be a SecretContentParams, received: {type(content_)}" ) if description_ is not None and not isinstance(description_, (bytes, str)): raise Exception( - "Expected description_ to be a str, received: {}".format( - type(description_) - ) + f"Expected description_ to be a str, received: {type(description_)}" ) if expire_time_ is not None and not isinstance(expire_time_, (bytes, str)): raise Exception( - "Expected expire_time_ to be a str, received: {}".format( - type(expire_time_) - ) + f"Expected expire_time_ to be a str, received: {type(expire_time_)}" ) if label_ is not None and not isinstance(label_, (bytes, str)): - raise Exception( - "Expected label_ to be a str, received: {}".format(type(label_)) - ) + raise Exception(f"Expected label_ to be a str, received: {type(label_)}") if owner_tag_ is not None and not isinstance(owner_tag_, (bytes, str)): raise Exception( - "Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_)) + f"Expected owner_tag_ to be a str, received: {type(owner_tag_)}" ) if params_ is not None and not isinstance(params_, dict): raise Exception( - "Expected params_ to be a Mapping, received: {}".format(type(params_)) + f"Expected params_ to be a Mapping, received: {type(params_)}" ) if rotate_policy_ is not None and not isinstance(rotate_policy_, (bytes, str)): raise Exception( - "Expected rotate_policy_ to be a str, received: {}".format( - type(rotate_policy_) - ) + f"Expected rotate_policy_ to be a str, received: {type(rotate_policy_)}" ) if uri_ is not None and not isinstance(uri_, (bytes, str)): - raise Exception( - "Expected uri_ to be a str, received: {}".format(type(uri_)) - ) + raise Exception(f"Expected uri_ to be a str, received: {type(uri_)}") self.upsertsecretarg = upsertsecretarg_ self.content = content_ @@ -9284,16 +8129,12 @@ class CreateSecretArgs(Type): _toPy = {"args": "args"} def __init__(self, args=None, **unknown_fields): - """ - args : typing.Sequence[~CreateSecretArg] - """ + """Args : typing.Sequence[~CreateSecretArg]""" args_ = [CreateSecretArg.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception( - "Expected args_ to be a Sequence, received: {}".format(type(args_)) - ) + raise Exception(f"Expected args_ to be a Sequence, received: {type(args_)}") self.args = args_ self.unknown_fields = unknown_fields @@ -9321,8 +8162,7 @@ def __init__( space_tag=None, **unknown_fields, ): - """ - cidrs : typing.Sequence[str] + """Cidrs : typing.Sequence[str] provider_id : str public : bool space_tag : str @@ -9335,24 +8175,20 @@ def __init__( # Validate arguments against known Juju API types. if cidrs_ is not None and not isinstance(cidrs_, (bytes, str, list)): raise Exception( - "Expected cidrs_ to be a Sequence, received: {}".format(type(cidrs_)) + f"Expected cidrs_ to be a Sequence, received: {type(cidrs_)}" ) if provider_id_ is not None and not isinstance(provider_id_, (bytes, str)): raise Exception( - "Expected provider_id_ to be a str, received: {}".format( - type(provider_id_) - ) + f"Expected provider_id_ to be a str, received: {type(provider_id_)}" ) if public_ is not None and not isinstance(public_, bool): - raise Exception( - "Expected public_ to be a bool, received: {}".format(type(public_)) - ) + raise Exception(f"Expected public_ to be a bool, received: {type(public_)}") if space_tag_ is not None and not isinstance(space_tag_, (bytes, str)): raise Exception( - "Expected space_tag_ to be a str, received: {}".format(type(space_tag_)) + f"Expected space_tag_ to be a str, received: {type(space_tag_)}" ) self.cidrs = cidrs_ @@ -9367,15 +8203,13 @@ class CreateSpacesParams(Type): _toPy = {"spaces": "spaces"} def __init__(self, spaces=None, **unknown_fields): - """ - spaces : typing.Sequence[~CreateSpaceParams] - """ + """Spaces : typing.Sequence[~CreateSpaceParams]""" spaces_ = [CreateSpaceParams.from_json(o) for o in spaces or []] # Validate arguments against known Juju API types. if spaces_ is not None and not isinstance(spaces_, (bytes, str, list)): raise Exception( - "Expected spaces_ to be a Sequence, received: {}".format(type(spaces_)) + f"Expected spaces_ to be a Sequence, received: {type(spaces_)}" ) self.spaces = spaces_ @@ -9407,8 +8241,7 @@ def __init__( valid=None, **unknown_fields, ): - """ - attrs : typing.Mapping[str, str] + """Attrs : typing.Mapping[str, str] auth_type : str cloud : str name : str @@ -9423,28 +8256,22 @@ def __init__( # Validate arguments against known Juju API types. if attrs_ is not None and not isinstance(attrs_, dict): raise Exception( - "Expected attrs_ to be a Mapping, received: {}".format(type(attrs_)) + f"Expected attrs_ to be a Mapping, received: {type(attrs_)}" ) if auth_type_ is not None and not isinstance(auth_type_, (bytes, str)): raise Exception( - "Expected auth_type_ to be a str, received: {}".format(type(auth_type_)) + f"Expected auth_type_ to be a str, received: {type(auth_type_)}" ) if cloud_ is not None and not isinstance(cloud_, (bytes, str)): - raise Exception( - "Expected cloud_ to be a str, received: {}".format(type(cloud_)) - ) + raise Exception(f"Expected cloud_ to be a str, received: {type(cloud_)}") if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if valid_ is not None and not isinstance(valid_, bool): - raise Exception( - "Expected valid_ to be a bool, received: {}".format(type(valid_)) - ) + raise Exception(f"Expected valid_ to be a bool, received: {type(valid_)}") self.attrs = attrs_ self.auth_type = auth_type_ @@ -9459,8 +8286,7 @@ class CredentialContentResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : ControllerCredentialInfo """ error_ = Error.from_json(error) if error else None @@ -9468,17 +8294,13 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance( result_, (dict, ControllerCredentialInfo) ): raise Exception( - "Expected result_ to be a ControllerCredentialInfo, received: {}".format( - type(result_) - ) + f"Expected result_ to be a ControllerCredentialInfo, received: {type(result_)}" ) self.error = error_ @@ -9491,17 +8313,13 @@ class CredentialContentResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~CredentialContentResult] - """ + """Results : typing.Sequence[~CredentialContentResult]""" results_ = [CredentialContentResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -9523,8 +8341,7 @@ class DashboardConnectionInfo(Type): def __init__( self, error=None, proxy_connection=None, ssh_connection=None, **unknown_fields ): - """ - error : Error + """Error : Error proxy_connection : Proxy ssh_connection : DashboardConnectionSSHTunnel """ @@ -9540,26 +8357,20 @@ def __init__( # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if proxy_connection_ is not None and not isinstance( proxy_connection_, (dict, Proxy) ): raise Exception( - "Expected proxy_connection_ to be a Proxy, received: {}".format( - type(proxy_connection_) - ) + f"Expected proxy_connection_ to be a Proxy, received: {type(proxy_connection_)}" ) if ssh_connection_ is not None and not isinstance( ssh_connection_, (dict, DashboardConnectionSSHTunnel) ): raise Exception( - "Expected ssh_connection_ to be a DashboardConnectionSSHTunnel, received: {}".format( - type(ssh_connection_) - ) + f"Expected ssh_connection_ to be a DashboardConnectionSSHTunnel, received: {type(ssh_connection_)}" ) self.error = error_ @@ -9573,8 +8384,7 @@ class DashboardConnectionSSHTunnel(Type): _toPy = {"entity": "entity", "host": "host", "model": "model", "port": "port"} def __init__(self, entity=None, host=None, model=None, port=None, **unknown_fields): - """ - entity : str + """Entity : str host : str model : str port : str @@ -9586,24 +8396,16 @@ def __init__(self, entity=None, host=None, model=None, port=None, **unknown_fiel # Validate arguments against known Juju API types. if entity_ is not None and not isinstance(entity_, (bytes, str)): - raise Exception( - "Expected entity_ to be a str, received: {}".format(type(entity_)) - ) + raise Exception(f"Expected entity_ to be a str, received: {type(entity_)}") if host_ is not None and not isinstance(host_, (bytes, str)): - raise Exception( - "Expected host_ to be a str, received: {}".format(type(host_)) - ) + raise Exception(f"Expected host_ to be a str, received: {type(host_)}") if model_ is not None and not isinstance(model_, (bytes, str)): - raise Exception( - "Expected model_ to be a str, received: {}".format(type(model_)) - ) + raise Exception(f"Expected model_ to be a str, received: {type(model_)}") if port_ is not None and not isinstance(port_, (bytes, str)): - raise Exception( - "Expected port_ to be a str, received: {}".format(type(port_)) - ) + raise Exception(f"Expected port_ to be a str, received: {type(port_)}") self.entity = entity_ self.host = host_ @@ -9617,8 +8419,7 @@ class DeleteSecretArg(Type): _toPy = {"label": "label", "revisions": "revisions", "uri": "uri"} def __init__(self, label=None, revisions=None, uri=None, **unknown_fields): - """ - label : str + """Label : str revisions : typing.Sequence[int] uri : str """ @@ -9628,21 +8429,15 @@ def __init__(self, label=None, revisions=None, uri=None, **unknown_fields): # Validate arguments against known Juju API types. if label_ is not None and not isinstance(label_, (bytes, str)): - raise Exception( - "Expected label_ to be a str, received: {}".format(type(label_)) - ) + raise Exception(f"Expected label_ to be a str, received: {type(label_)}") if revisions_ is not None and not isinstance(revisions_, (bytes, str, list)): raise Exception( - "Expected revisions_ to be a Sequence, received: {}".format( - type(revisions_) - ) + f"Expected revisions_ to be a Sequence, received: {type(revisions_)}" ) if uri_ is not None and not isinstance(uri_, (bytes, str)): - raise Exception( - "Expected uri_ to be a str, received: {}".format(type(uri_)) - ) + raise Exception(f"Expected uri_ to be a str, received: {type(uri_)}") self.label = label_ self.revisions = revisions_ @@ -9655,16 +8450,12 @@ class DeleteSecretArgs(Type): _toPy = {"args": "args"} def __init__(self, args=None, **unknown_fields): - """ - args : typing.Sequence[~DeleteSecretArg] - """ + """Args : typing.Sequence[~DeleteSecretArg]""" args_ = [DeleteSecretArg.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception( - "Expected args_ to be a Sequence, received: {}".format(type(args_)) - ) + raise Exception(f"Expected args_ to be a Sequence, received: {type(args_)}") self.args = args_ self.unknown_fields = unknown_fields @@ -9675,8 +8466,7 @@ class Delta(Type): _toPy = {"entity": "entity", "removed": "removed"} def __init__(self, entity=None, removed=None, **unknown_fields): - """ - entity : Any + """Entity : Any removed : bool """ entity_ = entity @@ -9685,7 +8475,7 @@ def __init__(self, entity=None, removed=None, **unknown_fields): # Validate arguments against known Juju API types. if removed_ is not None and not isinstance(removed_, bool): raise Exception( - "Expected removed_ to be a bool, received: {}".format(type(removed_)) + f"Expected removed_ to be a bool, received: {type(removed_)}" ) self.entity = entity_ @@ -9754,8 +8544,7 @@ def __init__( revision=None, **unknown_fields, ): - """ - applicationname : str + """Applicationname : str attachstorage : typing.Sequence[str] charmname : str configyaml : str @@ -9796,101 +8585,79 @@ def __init__( applicationname_, (bytes, str) ): raise Exception( - "Expected applicationname_ to be a str, received: {}".format( - type(applicationname_) - ) + f"Expected applicationname_ to be a str, received: {type(applicationname_)}" ) if attachstorage_ is not None and not isinstance( attachstorage_, (bytes, str, list) ): raise Exception( - "Expected attachstorage_ to be a Sequence, received: {}".format( - type(attachstorage_) - ) + f"Expected attachstorage_ to be a Sequence, received: {type(attachstorage_)}" ) if charmname_ is not None and not isinstance(charmname_, (bytes, str)): raise Exception( - "Expected charmname_ to be a str, received: {}".format(type(charmname_)) + f"Expected charmname_ to be a str, received: {type(charmname_)}" ) if configyaml_ is not None and not isinstance(configyaml_, (bytes, str)): raise Exception( - "Expected configyaml_ to be a str, received: {}".format( - type(configyaml_) - ) + f"Expected configyaml_ to be a str, received: {type(configyaml_)}" ) if cons_ is not None and not isinstance(cons_, (dict, Value)): - raise Exception( - "Expected cons_ to be a Value, received: {}".format(type(cons_)) - ) + raise Exception(f"Expected cons_ to be a Value, received: {type(cons_)}") if devices_ is not None and not isinstance(devices_, dict): raise Exception( - "Expected devices_ to be a Mapping, received: {}".format(type(devices_)) + f"Expected devices_ to be a Mapping, received: {type(devices_)}" ) if dryrun_ is not None and not isinstance(dryrun_, bool): - raise Exception( - "Expected dryrun_ to be a bool, received: {}".format(type(dryrun_)) - ) + raise Exception(f"Expected dryrun_ to be a bool, received: {type(dryrun_)}") if placement_ is not None and not isinstance(placement_, (bytes, str, list)): raise Exception( - "Expected placement_ to be a Sequence, received: {}".format( - type(placement_) - ) + f"Expected placement_ to be a Sequence, received: {type(placement_)}" ) if storage_ is not None and not isinstance(storage_, dict): raise Exception( - "Expected storage_ to be a Mapping, received: {}".format(type(storage_)) + f"Expected storage_ to be a Mapping, received: {type(storage_)}" ) if trust_ is not None and not isinstance(trust_, bool): - raise Exception( - "Expected trust_ to be a bool, received: {}".format(type(trust_)) - ) + raise Exception(f"Expected trust_ to be a bool, received: {type(trust_)}") if base_ is not None and not isinstance(base_, (dict, Base)): - raise Exception( - "Expected base_ to be a Base, received: {}".format(type(base_)) - ) + raise Exception(f"Expected base_ to be a Base, received: {type(base_)}") if channel_ is not None and not isinstance(channel_, (bytes, str)): raise Exception( - "Expected channel_ to be a str, received: {}".format(type(channel_)) + f"Expected channel_ to be a str, received: {type(channel_)}" ) if endpoint_bindings_ is not None and not isinstance(endpoint_bindings_, dict): raise Exception( - "Expected endpoint_bindings_ to be a Mapping, received: {}".format( - type(endpoint_bindings_) - ) + f"Expected endpoint_bindings_ to be a Mapping, received: {type(endpoint_bindings_)}" ) if force_ is not None and not isinstance(force_, bool): - raise Exception( - "Expected force_ to be a bool, received: {}".format(type(force_)) - ) + raise Exception(f"Expected force_ to be a bool, received: {type(force_)}") if num_units_ is not None and not isinstance(num_units_, int): raise Exception( - "Expected num_units_ to be a int, received: {}".format(type(num_units_)) + f"Expected num_units_ to be a int, received: {type(num_units_)}" ) if resources_ is not None and not isinstance(resources_, dict): raise Exception( - "Expected resources_ to be a Mapping, received: {}".format( - type(resources_) - ) + f"Expected resources_ to be a Mapping, received: {type(resources_)}" ) if revision_ is not None and not isinstance(revision_, int): raise Exception( - "Expected revision_ to be a int, received: {}".format(type(revision_)) + f"Expected revision_ to be a int, received: {type(revision_)}" ) self.applicationname = applicationname_ @@ -9918,16 +8685,12 @@ class DeployFromRepositoryArgs(Type): _toPy = {"Args": "args"} def __init__(self, args=None, **unknown_fields): - """ - args : typing.Sequence[~DeployFromRepositoryArg] - """ + """Args : typing.Sequence[~DeployFromRepositoryArg]""" args_ = [DeployFromRepositoryArg.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception( - "Expected args_ to be a Sequence, received: {}".format(type(args_)) - ) + raise Exception(f"Expected args_ to be a Sequence, received: {type(args_)}") self.args = args_ self.unknown_fields = unknown_fields @@ -9961,8 +8724,7 @@ def __init__( revision=None, **unknown_fields, ): - """ - architecture : str + """Architecture : str base : Base channel : str effective_channel : str @@ -9979,38 +8741,30 @@ def __init__( # Validate arguments against known Juju API types. if architecture_ is not None and not isinstance(architecture_, (bytes, str)): raise Exception( - "Expected architecture_ to be a str, received: {}".format( - type(architecture_) - ) + f"Expected architecture_ to be a str, received: {type(architecture_)}" ) if base_ is not None and not isinstance(base_, (dict, Base)): - raise Exception( - "Expected base_ to be a Base, received: {}".format(type(base_)) - ) + raise Exception(f"Expected base_ to be a Base, received: {type(base_)}") if channel_ is not None and not isinstance(channel_, (bytes, str)): raise Exception( - "Expected channel_ to be a str, received: {}".format(type(channel_)) + f"Expected channel_ to be a str, received: {type(channel_)}" ) if effective_channel_ is not None and not isinstance( effective_channel_, (bytes, str) ): raise Exception( - "Expected effective_channel_ to be a str, received: {}".format( - type(effective_channel_) - ) + f"Expected effective_channel_ to be a str, received: {type(effective_channel_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if revision_ is not None and not isinstance(revision_, int): raise Exception( - "Expected revision_ to be a int, received: {}".format(type(revision_)) + f"Expected revision_ to be a int, received: {type(revision_)}" ) self.architecture = architecture_ @@ -10037,8 +8791,7 @@ class DeployFromRepositoryResult(Type): def __init__( self, errors=None, info=None, pendingresourceuploads=None, **unknown_fields ): - """ - errors : typing.Sequence[~Error] + """Errors : typing.Sequence[~Error] info : DeployFromRepositoryInfo pendingresourceuploads : typing.Sequence[~PendingResourceUpload] """ @@ -10051,25 +8804,21 @@ def __init__( # Validate arguments against known Juju API types. if errors_ is not None and not isinstance(errors_, (bytes, str, list)): raise Exception( - "Expected errors_ to be a Sequence, received: {}".format(type(errors_)) + f"Expected errors_ to be a Sequence, received: {type(errors_)}" ) if info_ is not None and not isinstance( info_, (dict, DeployFromRepositoryInfo) ): raise Exception( - "Expected info_ to be a DeployFromRepositoryInfo, received: {}".format( - type(info_) - ) + f"Expected info_ to be a DeployFromRepositoryInfo, received: {type(info_)}" ) if pendingresourceuploads_ is not None and not isinstance( pendingresourceuploads_, (bytes, str, list) ): raise Exception( - "Expected pendingresourceuploads_ to be a Sequence, received: {}".format( - type(pendingresourceuploads_) - ) + f"Expected pendingresourceuploads_ to be a Sequence, received: {type(pendingresourceuploads_)}" ) self.errors = errors_ @@ -10083,17 +8832,13 @@ class DeployFromRepositoryResults(Type): _toPy = {"Results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~DeployFromRepositoryResult] - """ + """Results : typing.Sequence[~DeployFromRepositoryResult]""" results_ = [DeployFromRepositoryResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -10119,8 +8864,7 @@ def __init__( detached_storage=None, **unknown_fields, ): - """ - destroyed_storage : typing.Sequence[~Entity] + """destroyed_storage : typing.Sequence[~Entity] destroyed_units : typing.Sequence[~Entity] detached_storage : typing.Sequence[~Entity] """ @@ -10133,27 +8877,21 @@ def __init__( destroyed_storage_, (bytes, str, list) ): raise Exception( - "Expected destroyed_storage_ to be a Sequence, received: {}".format( - type(destroyed_storage_) - ) + f"Expected destroyed_storage_ to be a Sequence, received: {type(destroyed_storage_)}" ) if destroyed_units_ is not None and not isinstance( destroyed_units_, (bytes, str, list) ): raise Exception( - "Expected destroyed_units_ to be a Sequence, received: {}".format( - type(destroyed_units_) - ) + f"Expected destroyed_units_ to be a Sequence, received: {type(destroyed_units_)}" ) if detached_storage_ is not None and not isinstance( detached_storage_, (bytes, str, list) ): raise Exception( - "Expected detached_storage_ to be a Sequence, received: {}".format( - type(detached_storage_) - ) + f"Expected detached_storage_ to be a Sequence, received: {type(detached_storage_)}" ) self.destroyed_storage = destroyed_storage_ @@ -10167,8 +8905,7 @@ class DestroyApplicationOffers(Type): _toPy = {"force": "force", "offer-urls": "offer_urls"} def __init__(self, force=None, offer_urls=None, **unknown_fields): - """ - force : bool + """Force : bool offer_urls : typing.Sequence[str] """ force_ = force @@ -10176,15 +8913,11 @@ def __init__(self, force=None, offer_urls=None, **unknown_fields): # Validate arguments against known Juju API types. if force_ is not None and not isinstance(force_, bool): - raise Exception( - "Expected force_ to be a bool, received: {}".format(type(force_)) - ) + raise Exception(f"Expected force_ to be a bool, received: {type(force_)}") if offer_urls_ is not None and not isinstance(offer_urls_, (bytes, str, list)): raise Exception( - "Expected offer_urls_ to be a Sequence, received: {}".format( - type(offer_urls_) - ) + f"Expected offer_urls_ to be a Sequence, received: {type(offer_urls_)}" ) self.force = force_ @@ -10217,8 +8950,7 @@ def __init__( max_wait=None, **unknown_fields, ): - """ - application_tag : str + """application_tag : str destroy_storage : bool dry_run : bool force : bool @@ -10235,31 +8967,25 @@ def __init__( application_tag_, (bytes, str) ): raise Exception( - "Expected application_tag_ to be a str, received: {}".format( - type(application_tag_) - ) + f"Expected application_tag_ to be a str, received: {type(application_tag_)}" ) if destroy_storage_ is not None and not isinstance(destroy_storage_, bool): raise Exception( - "Expected destroy_storage_ to be a bool, received: {}".format( - type(destroy_storage_) - ) + f"Expected destroy_storage_ to be a bool, received: {type(destroy_storage_)}" ) if dry_run_ is not None and not isinstance(dry_run_, bool): raise Exception( - "Expected dry_run_ to be a bool, received: {}".format(type(dry_run_)) + f"Expected dry_run_ to be a bool, received: {type(dry_run_)}" ) if force_ is not None and not isinstance(force_, bool): - raise Exception( - "Expected force_ to be a bool, received: {}".format(type(force_)) - ) + raise Exception(f"Expected force_ to be a bool, received: {type(force_)}") if max_wait_ is not None and not isinstance(max_wait_, int): raise Exception( - "Expected max_wait_ to be a int, received: {}".format(type(max_wait_)) + f"Expected max_wait_ to be a int, received: {type(max_wait_)}" ) self.application_tag = application_tag_ @@ -10275,8 +9001,7 @@ class DestroyApplicationResult(Type): _toPy = {"error": "error", "info": "info"} def __init__(self, error=None, info=None, **unknown_fields): - """ - error : Error + """Error : Error info : DestroyApplicationInfo """ error_ = Error.from_json(error) if error else None @@ -10284,15 +9009,11 @@ def __init__(self, error=None, info=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if info_ is not None and not isinstance(info_, (dict, DestroyApplicationInfo)): raise Exception( - "Expected info_ to be a DestroyApplicationInfo, received: {}".format( - type(info_) - ) + f"Expected info_ to be a DestroyApplicationInfo, received: {type(info_)}" ) self.error = error_ @@ -10305,17 +9026,13 @@ class DestroyApplicationResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~DestroyApplicationResult] - """ + """Results : typing.Sequence[~DestroyApplicationResult]""" results_ = [DestroyApplicationResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -10327,9 +9044,7 @@ class DestroyApplicationsParams(Type): _toPy = {"applications": "applications"} def __init__(self, applications=None, **unknown_fields): - """ - applications : typing.Sequence[~DestroyApplicationParams] - """ + """Applications : typing.Sequence[~DestroyApplicationParams]""" applications_ = [ DestroyApplicationParams.from_json(o) for o in applications or [] ] @@ -10339,9 +9054,7 @@ def __init__(self, applications=None, **unknown_fields): applications_, (bytes, str, list) ): raise Exception( - "Expected applications_ to be a Sequence, received: {}".format( - type(applications_) - ) + f"Expected applications_ to be a Sequence, received: {type(applications_)}" ) self.applications = applications_ @@ -10363,8 +9076,7 @@ class DestroyConsumedApplicationParams(Type): def __init__( self, application_tag=None, force=None, max_wait=None, **unknown_fields ): - """ - application_tag : str + """application_tag : str force : bool max_wait : int """ @@ -10377,19 +9089,15 @@ def __init__( application_tag_, (bytes, str) ): raise Exception( - "Expected application_tag_ to be a str, received: {}".format( - type(application_tag_) - ) + f"Expected application_tag_ to be a str, received: {type(application_tag_)}" ) if force_ is not None and not isinstance(force_, bool): - raise Exception( - "Expected force_ to be a bool, received: {}".format(type(force_)) - ) + raise Exception(f"Expected force_ to be a bool, received: {type(force_)}") if max_wait_ is not None and not isinstance(max_wait_, int): raise Exception( - "Expected max_wait_ to be a int, received: {}".format(type(max_wait_)) + f"Expected max_wait_ to be a int, received: {type(max_wait_)}" ) self.application_tag = application_tag_ @@ -10403,9 +9111,7 @@ class DestroyConsumedApplicationsParams(Type): _toPy = {"applications": "applications"} def __init__(self, applications=None, **unknown_fields): - """ - applications : typing.Sequence[~DestroyConsumedApplicationParams] - """ + """Applications : typing.Sequence[~DestroyConsumedApplicationParams]""" applications_ = [ DestroyConsumedApplicationParams.from_json(o) for o in applications or [] ] @@ -10415,9 +9121,7 @@ def __init__(self, applications=None, **unknown_fields): applications_, (bytes, str, list) ): raise Exception( - "Expected applications_ to be a Sequence, received: {}".format( - type(applications_) - ) + f"Expected applications_ to be a Sequence, received: {type(applications_)}" ) self.applications = applications_ @@ -10449,8 +9153,7 @@ def __init__( model_timeout=None, **unknown_fields, ): - """ - destroy_models : bool + """destroy_models : bool destroy_storage : bool force : bool max_wait : int @@ -10465,33 +9168,25 @@ def __init__( # Validate arguments against known Juju API types. if destroy_models_ is not None and not isinstance(destroy_models_, bool): raise Exception( - "Expected destroy_models_ to be a bool, received: {}".format( - type(destroy_models_) - ) + f"Expected destroy_models_ to be a bool, received: {type(destroy_models_)}" ) if destroy_storage_ is not None and not isinstance(destroy_storage_, bool): raise Exception( - "Expected destroy_storage_ to be a bool, received: {}".format( - type(destroy_storage_) - ) + f"Expected destroy_storage_ to be a bool, received: {type(destroy_storage_)}" ) if force_ is not None and not isinstance(force_, bool): - raise Exception( - "Expected force_ to be a bool, received: {}".format(type(force_)) - ) + raise Exception(f"Expected force_ to be a bool, received: {type(force_)}") if max_wait_ is not None and not isinstance(max_wait_, int): raise Exception( - "Expected max_wait_ to be a int, received: {}".format(type(max_wait_)) + f"Expected max_wait_ to be a int, received: {type(max_wait_)}" ) if model_timeout_ is not None and not isinstance(model_timeout_, int): raise Exception( - "Expected model_timeout_ to be a int, received: {}".format( - type(model_timeout_) - ) + f"Expected model_timeout_ to be a int, received: {type(model_timeout_)}" ) self.destroy_models = destroy_models_ @@ -10527,8 +9222,7 @@ def __init__( machine_id=None, **unknown_fields, ): - """ - destroyed_containers : typing.Sequence[~DestroyMachineResult] + """destroyed_containers : typing.Sequence[~DestroyMachineResult] destroyed_storage : typing.Sequence[~Entity] destroyed_units : typing.Sequence[~Entity] detached_storage : typing.Sequence[~Entity] @@ -10547,43 +9241,33 @@ def __init__( destroyed_containers_, (bytes, str, list) ): raise Exception( - "Expected destroyed_containers_ to be a Sequence, received: {}".format( - type(destroyed_containers_) - ) + f"Expected destroyed_containers_ to be a Sequence, received: {type(destroyed_containers_)}" ) if destroyed_storage_ is not None and not isinstance( destroyed_storage_, (bytes, str, list) ): raise Exception( - "Expected destroyed_storage_ to be a Sequence, received: {}".format( - type(destroyed_storage_) - ) + f"Expected destroyed_storage_ to be a Sequence, received: {type(destroyed_storage_)}" ) if destroyed_units_ is not None and not isinstance( destroyed_units_, (bytes, str, list) ): raise Exception( - "Expected destroyed_units_ to be a Sequence, received: {}".format( - type(destroyed_units_) - ) + f"Expected destroyed_units_ to be a Sequence, received: {type(destroyed_units_)}" ) if detached_storage_ is not None and not isinstance( detached_storage_, (bytes, str, list) ): raise Exception( - "Expected detached_storage_ to be a Sequence, received: {}".format( - type(detached_storage_) - ) + f"Expected detached_storage_ to be a Sequence, received: {type(detached_storage_)}" ) if machine_id_ is not None and not isinstance(machine_id_, (bytes, str)): raise Exception( - "Expected machine_id_ to be a str, received: {}".format( - type(machine_id_) - ) + f"Expected machine_id_ to be a str, received: {type(machine_id_)}" ) self.destroyed_containers = destroyed_containers_ @@ -10599,8 +9283,7 @@ class DestroyMachineResult(Type): _toPy = {"error": "error", "info": "info"} def __init__(self, error=None, info=None, **unknown_fields): - """ - error : Error + """Error : Error info : DestroyMachineInfo """ error_ = Error.from_json(error) if error else None @@ -10608,15 +9291,11 @@ def __init__(self, error=None, info=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if info_ is not None and not isinstance(info_, (dict, DestroyMachineInfo)): raise Exception( - "Expected info_ to be a DestroyMachineInfo, received: {}".format( - type(info_) - ) + f"Expected info_ to be a DestroyMachineInfo, received: {type(info_)}" ) self.error = error_ @@ -10629,17 +9308,13 @@ class DestroyMachineResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~DestroyMachineResult] - """ + """Results : typing.Sequence[~DestroyMachineResult]""" results_ = [DestroyMachineResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -10671,8 +9346,7 @@ def __init__( max_wait=None, **unknown_fields, ): - """ - dry_run : bool + """dry_run : bool force : bool keep : bool machine_tags : typing.Sequence[str] @@ -10687,31 +9361,25 @@ def __init__( # Validate arguments against known Juju API types. if dry_run_ is not None and not isinstance(dry_run_, bool): raise Exception( - "Expected dry_run_ to be a bool, received: {}".format(type(dry_run_)) + f"Expected dry_run_ to be a bool, received: {type(dry_run_)}" ) if force_ is not None and not isinstance(force_, bool): - raise Exception( - "Expected force_ to be a bool, received: {}".format(type(force_)) - ) + raise Exception(f"Expected force_ to be a bool, received: {type(force_)}") if keep_ is not None and not isinstance(keep_, bool): - raise Exception( - "Expected keep_ to be a bool, received: {}".format(type(keep_)) - ) + raise Exception(f"Expected keep_ to be a bool, received: {type(keep_)}") if machine_tags_ is not None and not isinstance( machine_tags_, (bytes, str, list) ): raise Exception( - "Expected machine_tags_ to be a Sequence, received: {}".format( - type(machine_tags_) - ) + f"Expected machine_tags_ to be a Sequence, received: {type(machine_tags_)}" ) if max_wait_ is not None and not isinstance(max_wait_, int): raise Exception( - "Expected max_wait_ to be a int, received: {}".format(type(max_wait_)) + f"Expected max_wait_ to be a int, received: {type(max_wait_)}" ) self.dry_run = dry_run_ @@ -10747,8 +9415,7 @@ def __init__( timeout=None, **unknown_fields, ): - """ - destroy_storage : bool + """destroy_storage : bool force : bool max_wait : int model_tag : str @@ -10763,29 +9430,25 @@ def __init__( # Validate arguments against known Juju API types. if destroy_storage_ is not None and not isinstance(destroy_storage_, bool): raise Exception( - "Expected destroy_storage_ to be a bool, received: {}".format( - type(destroy_storage_) - ) + f"Expected destroy_storage_ to be a bool, received: {type(destroy_storage_)}" ) if force_ is not None and not isinstance(force_, bool): - raise Exception( - "Expected force_ to be a bool, received: {}".format(type(force_)) - ) + raise Exception(f"Expected force_ to be a bool, received: {type(force_)}") if max_wait_ is not None and not isinstance(max_wait_, int): raise Exception( - "Expected max_wait_ to be a int, received: {}".format(type(max_wait_)) + f"Expected max_wait_ to be a int, received: {type(max_wait_)}" ) if model_tag_ is not None and not isinstance(model_tag_, (bytes, str)): raise Exception( - "Expected model_tag_ to be a str, received: {}".format(type(model_tag_)) + f"Expected model_tag_ to be a str, received: {type(model_tag_)}" ) if timeout_ is not None and not isinstance(timeout_, int): raise Exception( - "Expected timeout_ to be a int, received: {}".format(type(timeout_)) + f"Expected timeout_ to be a int, received: {type(timeout_)}" ) self.destroy_storage = destroy_storage_ @@ -10801,15 +9464,13 @@ class DestroyModelsParams(Type): _toPy = {"models": "models"} def __init__(self, models=None, **unknown_fields): - """ - models : typing.Sequence[~DestroyModelParams] - """ + """Models : typing.Sequence[~DestroyModelParams]""" models_ = [DestroyModelParams.from_json(o) for o in models or []] # Validate arguments against known Juju API types. if models_ is not None and not isinstance(models_, (bytes, str, list)): raise Exception( - "Expected models_ to be a Sequence, received: {}".format(type(models_)) + f"Expected models_ to be a Sequence, received: {type(models_)}" ) self.models = models_ @@ -10838,8 +9499,7 @@ def __init__( relation_id=None, **unknown_fields, ): - """ - endpoints : typing.Sequence[str] + """Endpoints : typing.Sequence[str] force : bool max_wait : int relation_id : int @@ -10852,26 +9512,20 @@ def __init__( # Validate arguments against known Juju API types. if endpoints_ is not None and not isinstance(endpoints_, (bytes, str, list)): raise Exception( - "Expected endpoints_ to be a Sequence, received: {}".format( - type(endpoints_) - ) + f"Expected endpoints_ to be a Sequence, received: {type(endpoints_)}" ) if force_ is not None and not isinstance(force_, bool): - raise Exception( - "Expected force_ to be a bool, received: {}".format(type(force_)) - ) + raise Exception(f"Expected force_ to be a bool, received: {type(force_)}") if max_wait_ is not None and not isinstance(max_wait_, int): raise Exception( - "Expected max_wait_ to be a int, received: {}".format(type(max_wait_)) + f"Expected max_wait_ to be a int, received: {type(max_wait_)}" ) if relation_id_ is not None and not isinstance(relation_id_, int): raise Exception( - "Expected relation_id_ to be a int, received: {}".format( - type(relation_id_) - ) + f"Expected relation_id_ to be a int, received: {type(relation_id_)}" ) self.endpoints = endpoints_ @@ -10892,8 +9546,7 @@ class DestroyUnitInfo(Type): } def __init__(self, destroyed_storage=None, detached_storage=None, **unknown_fields): - """ - destroyed_storage : typing.Sequence[~Entity] + """destroyed_storage : typing.Sequence[~Entity] detached_storage : typing.Sequence[~Entity] """ destroyed_storage_ = [Entity.from_json(o) for o in destroyed_storage or []] @@ -10904,18 +9557,14 @@ def __init__(self, destroyed_storage=None, detached_storage=None, **unknown_fiel destroyed_storage_, (bytes, str, list) ): raise Exception( - "Expected destroyed_storage_ to be a Sequence, received: {}".format( - type(destroyed_storage_) - ) + f"Expected destroyed_storage_ to be a Sequence, received: {type(destroyed_storage_)}" ) if detached_storage_ is not None and not isinstance( detached_storage_, (bytes, str, list) ): raise Exception( - "Expected detached_storage_ to be a Sequence, received: {}".format( - type(detached_storage_) - ) + f"Expected detached_storage_ to be a Sequence, received: {type(detached_storage_)}" ) self.destroyed_storage = destroyed_storage_ @@ -10948,8 +9597,7 @@ def __init__( unit_tag=None, **unknown_fields, ): - """ - destroy_storage : bool + """destroy_storage : bool dry_run : bool force : bool max_wait : int @@ -10964,29 +9612,25 @@ def __init__( # Validate arguments against known Juju API types. if destroy_storage_ is not None and not isinstance(destroy_storage_, bool): raise Exception( - "Expected destroy_storage_ to be a bool, received: {}".format( - type(destroy_storage_) - ) + f"Expected destroy_storage_ to be a bool, received: {type(destroy_storage_)}" ) if dry_run_ is not None and not isinstance(dry_run_, bool): raise Exception( - "Expected dry_run_ to be a bool, received: {}".format(type(dry_run_)) + f"Expected dry_run_ to be a bool, received: {type(dry_run_)}" ) if force_ is not None and not isinstance(force_, bool): - raise Exception( - "Expected force_ to be a bool, received: {}".format(type(force_)) - ) + raise Exception(f"Expected force_ to be a bool, received: {type(force_)}") if max_wait_ is not None and not isinstance(max_wait_, int): raise Exception( - "Expected max_wait_ to be a int, received: {}".format(type(max_wait_)) + f"Expected max_wait_ to be a int, received: {type(max_wait_)}" ) if unit_tag_ is not None and not isinstance(unit_tag_, (bytes, str)): raise Exception( - "Expected unit_tag_ to be a str, received: {}".format(type(unit_tag_)) + f"Expected unit_tag_ to be a str, received: {type(unit_tag_)}" ) self.destroy_storage = destroy_storage_ @@ -11002,8 +9646,7 @@ class DestroyUnitResult(Type): _toPy = {"error": "error", "info": "info"} def __init__(self, error=None, info=None, **unknown_fields): - """ - error : Error + """Error : Error info : DestroyUnitInfo """ error_ = Error.from_json(error) if error else None @@ -11011,15 +9654,11 @@ def __init__(self, error=None, info=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if info_ is not None and not isinstance(info_, (dict, DestroyUnitInfo)): raise Exception( - "Expected info_ to be a DestroyUnitInfo, received: {}".format( - type(info_) - ) + f"Expected info_ to be a DestroyUnitInfo, received: {type(info_)}" ) self.error = error_ @@ -11032,17 +9671,13 @@ class DestroyUnitResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~DestroyUnitResult] - """ + """Results : typing.Sequence[~DestroyUnitResult]""" results_ = [DestroyUnitResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -11054,15 +9689,13 @@ class DestroyUnitsParams(Type): _toPy = {"units": "units"} def __init__(self, units=None, **unknown_fields): - """ - units : typing.Sequence[~DestroyUnitParams] - """ + """Units : typing.Sequence[~DestroyUnitParams]""" units_ = [DestroyUnitParams.from_json(o) for o in units or []] # Validate arguments against known Juju API types. if units_ is not None and not isinstance(units_, (bytes, str, list)): raise Exception( - "Expected units_ to be a Sequence, received: {}".format(type(units_)) + f"Expected units_ to be a Sequence, received: {type(units_)}" ) self.units = units_ @@ -11103,8 +9736,7 @@ def __init__( version=None, **unknown_fields, ): - """ - data : typing.Mapping[str, typing.Any] + """Data : typing.Mapping[str, typing.Any] err : Error info : str kind : str @@ -11124,43 +9756,29 @@ def __init__( # Validate arguments against known Juju API types. if data_ is not None and not isinstance(data_, dict): - raise Exception( - "Expected data_ to be a Mapping, received: {}".format(type(data_)) - ) + raise Exception(f"Expected data_ to be a Mapping, received: {type(data_)}") if err_ is not None and not isinstance(err_, (dict, Error)): - raise Exception( - "Expected err_ to be a Error, received: {}".format(type(err_)) - ) + raise Exception(f"Expected err_ to be a Error, received: {type(err_)}") if info_ is not None and not isinstance(info_, (bytes, str)): - raise Exception( - "Expected info_ to be a str, received: {}".format(type(info_)) - ) + raise Exception(f"Expected info_ to be a str, received: {type(info_)}") if kind_ is not None and not isinstance(kind_, (bytes, str)): - raise Exception( - "Expected kind_ to be a str, received: {}".format(type(kind_)) - ) + raise Exception(f"Expected kind_ to be a str, received: {type(kind_)}") if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception( - "Expected life_ to be a str, received: {}".format(type(life_)) - ) + raise Exception(f"Expected life_ to be a str, received: {type(life_)}") if since_ is not None and not isinstance(since_, (bytes, str)): - raise Exception( - "Expected since_ to be a str, received: {}".format(type(since_)) - ) + raise Exception(f"Expected since_ to be a str, received: {type(since_)}") if status_ is not None and not isinstance(status_, (bytes, str)): - raise Exception( - "Expected status_ to be a str, received: {}".format(type(status_)) - ) + raise Exception(f"Expected status_ to be a str, received: {type(status_)}") if version_ is not None and not isinstance(version_, (bytes, str)): raise Exception( - "Expected version_ to be a str, received: {}".format(type(version_)) + f"Expected version_ to be a str, received: {type(version_)}" ) self.data = data_ @@ -11179,8 +9797,7 @@ class DownloadInfoResult(Type): _toPy = {"charm-origin": "charm_origin", "url": "url"} def __init__(self, charm_origin=None, url=None, **unknown_fields): - """ - charm_origin : CharmOrigin + """charm_origin : CharmOrigin url : str """ charm_origin_ = CharmOrigin.from_json(charm_origin) if charm_origin else None @@ -11191,15 +9808,11 @@ def __init__(self, charm_origin=None, url=None, **unknown_fields): charm_origin_, (dict, CharmOrigin) ): raise Exception( - "Expected charm_origin_ to be a CharmOrigin, received: {}".format( - type(charm_origin_) - ) + f"Expected charm_origin_ to be a CharmOrigin, received: {type(charm_origin_)}" ) if url_ is not None and not isinstance(url_, (bytes, str)): - raise Exception( - "Expected url_ to be a str, received: {}".format(type(url_)) - ) + raise Exception(f"Expected url_ to be a str, received: {type(url_)}") self.charm_origin = charm_origin_ self.url = url_ @@ -11211,17 +9824,13 @@ class DownloadInfoResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~DownloadInfoResult] - """ + """Results : typing.Sequence[~DownloadInfoResult]""" results_ = [DownloadInfoResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -11233,8 +9842,7 @@ class DumpModelRequest(Type): _toPy = {"entities": "entities", "simplified": "simplified"} def __init__(self, entities=None, simplified=None, **unknown_fields): - """ - entities : typing.Sequence[~Entity] + """Entities : typing.Sequence[~Entity] simplified : bool """ entities_ = [Entity.from_json(o) for o in entities or []] @@ -11243,16 +9851,12 @@ def __init__(self, entities=None, simplified=None, **unknown_fields): # Validate arguments against known Juju API types. if entities_ is not None and not isinstance(entities_, (bytes, str, list)): raise Exception( - "Expected entities_ to be a Sequence, received: {}".format( - type(entities_) - ) + f"Expected entities_ to be a Sequence, received: {type(entities_)}" ) if simplified_ is not None and not isinstance(simplified_, bool): raise Exception( - "Expected simplified_ to be a bool, received: {}".format( - type(simplified_) - ) + f"Expected simplified_ to be a bool, received: {type(simplified_)}" ) self.entities = entities_ @@ -11265,8 +9869,7 @@ class EndpointFilterAttributes(Type): _toPy = {"interface": "interface", "name": "name", "role": "role"} def __init__(self, interface=None, name=None, role=None, **unknown_fields): - """ - interface : str + """Interface : str name : str role : str """ @@ -11277,18 +9880,14 @@ def __init__(self, interface=None, name=None, role=None, **unknown_fields): # Validate arguments against known Juju API types. if interface_ is not None and not isinstance(interface_, (bytes, str)): raise Exception( - "Expected interface_ to be a str, received: {}".format(type(interface_)) + f"Expected interface_ to be a str, received: {type(interface_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if role_ is not None and not isinstance(role_, (bytes, str)): - raise Exception( - "Expected role_ to be a str, received: {}".format(type(role_)) - ) + raise Exception(f"Expected role_ to be a str, received: {type(role_)}") self.interface = interface_ self.name = name_ @@ -11324,8 +9923,7 @@ def __init__( unit_relation_data=None, **unknown_fields, ): - """ - applicationdata : typing.Mapping[str, typing.Any] + """Applicationdata : typing.Mapping[str, typing.Any] cross_model : bool endpoint : str related_endpoint : str @@ -11345,46 +9943,36 @@ def __init__( # Validate arguments against known Juju API types. if applicationdata_ is not None and not isinstance(applicationdata_, dict): raise Exception( - "Expected applicationdata_ to be a Mapping, received: {}".format( - type(applicationdata_) - ) + f"Expected applicationdata_ to be a Mapping, received: {type(applicationdata_)}" ) if cross_model_ is not None and not isinstance(cross_model_, bool): raise Exception( - "Expected cross_model_ to be a bool, received: {}".format( - type(cross_model_) - ) + f"Expected cross_model_ to be a bool, received: {type(cross_model_)}" ) if endpoint_ is not None and not isinstance(endpoint_, (bytes, str)): raise Exception( - "Expected endpoint_ to be a str, received: {}".format(type(endpoint_)) + f"Expected endpoint_ to be a str, received: {type(endpoint_)}" ) if related_endpoint_ is not None and not isinstance( related_endpoint_, (bytes, str) ): raise Exception( - "Expected related_endpoint_ to be a str, received: {}".format( - type(related_endpoint_) - ) + f"Expected related_endpoint_ to be a str, received: {type(related_endpoint_)}" ) if relation_id_ is not None and not isinstance(relation_id_, int): raise Exception( - "Expected relation_id_ to be a int, received: {}".format( - type(relation_id_) - ) + f"Expected relation_id_ to be a int, received: {type(relation_id_)}" ) if unit_relation_data_ is not None and not isinstance( unit_relation_data_, dict ): raise Exception( - "Expected unit_relation_data_ to be a Mapping, received: {}".format( - type(unit_relation_data_) - ) + f"Expected unit_relation_data_ to be a Mapping, received: {type(unit_relation_data_)}" ) self.applicationdata = applicationdata_ @@ -11413,8 +10001,7 @@ class EndpointStatus(Type): def __init__( self, application=None, name=None, role=None, subordinate=None, **unknown_fields ): - """ - application : str + """Application : str name : str role : str subordinate : bool @@ -11427,26 +10014,18 @@ def __init__( # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): raise Exception( - "Expected application_ to be a str, received: {}".format( - type(application_) - ) + f"Expected application_ to be a str, received: {type(application_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if role_ is not None and not isinstance(role_, (bytes, str)): - raise Exception( - "Expected role_ to be a str, received: {}".format(type(role_)) - ) + raise Exception(f"Expected role_ to be a str, received: {type(role_)}") if subordinate_ is not None and not isinstance(subordinate_, bool): raise Exception( - "Expected subordinate_ to be a bool, received: {}".format( - type(subordinate_) - ) + f"Expected subordinate_ to be a bool, received: {type(subordinate_)}" ) self.application = application_ @@ -11461,8 +10040,7 @@ class EnqueuedActions(Type): _toPy = {"actions": "actions", "operation": "operation"} def __init__(self, actions=None, operation=None, **unknown_fields): - """ - actions : typing.Sequence[~ActionResult] + """Actions : typing.Sequence[~ActionResult] operation : str """ actions_ = [ActionResult.from_json(o) for o in actions or []] @@ -11471,14 +10049,12 @@ def __init__(self, actions=None, operation=None, **unknown_fields): # Validate arguments against known Juju API types. if actions_ is not None and not isinstance(actions_, (bytes, str, list)): raise Exception( - "Expected actions_ to be a Sequence, received: {}".format( - type(actions_) - ) + f"Expected actions_ to be a Sequence, received: {type(actions_)}" ) if operation_ is not None and not isinstance(operation_, (bytes, str)): raise Exception( - "Expected operation_ to be a str, received: {}".format(type(operation_)) + f"Expected operation_ to be a str, received: {type(operation_)}" ) self.actions = actions_ @@ -11491,17 +10067,13 @@ class Entities(Type): _toPy = {"entities": "entities"} def __init__(self, entities=None, **unknown_fields): - """ - entities : typing.Sequence[~Entity] - """ + """Entities : typing.Sequence[~Entity]""" entities_ = [Entity.from_json(o) for o in entities or []] # Validate arguments against known Juju API types. if entities_ is not None and not isinstance(entities_, (bytes, str, list)): raise Exception( - "Expected entities_ to be a Sequence, received: {}".format( - type(entities_) - ) + f"Expected entities_ to be a Sequence, received: {type(entities_)}" ) self.entities = entities_ @@ -11513,16 +10085,12 @@ class Entity(Type): _toPy = {"tag": "tag"} def __init__(self, tag=None, **unknown_fields): - """ - tag : str - """ + """Tag : str""" tag_ = tag # Validate arguments against known Juju API types. if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception( - "Expected tag_ to be a str, received: {}".format(type(tag_)) - ) + raise Exception(f"Expected tag_ to be a str, received: {type(tag_)}") self.tag = tag_ self.unknown_fields = unknown_fields @@ -11533,8 +10101,7 @@ class EntityAnnotations(Type): _toPy = {"annotations": "annotations", "entity": "entity"} def __init__(self, annotations=None, entity=None, **unknown_fields): - """ - annotations : typing.Mapping[str, str] + """Annotations : typing.Mapping[str, str] entity : str """ annotations_ = annotations @@ -11543,15 +10110,11 @@ def __init__(self, annotations=None, entity=None, **unknown_fields): # Validate arguments against known Juju API types. if annotations_ is not None and not isinstance(annotations_, dict): raise Exception( - "Expected annotations_ to be a Mapping, received: {}".format( - type(annotations_) - ) + f"Expected annotations_ to be a Mapping, received: {type(annotations_)}" ) if entity_ is not None and not isinstance(entity_, (bytes, str)): - raise Exception( - "Expected entity_ to be a str, received: {}".format(type(entity_)) - ) + raise Exception(f"Expected entity_ to be a str, received: {type(entity_)}") self.annotations = annotations_ self.entity = entity_ @@ -11563,8 +10126,7 @@ class EntityMetrics(Type): _toPy = {"error": "error", "metrics": "metrics"} def __init__(self, error=None, metrics=None, **unknown_fields): - """ - error : Error + """Error : Error metrics : typing.Sequence[~MetricResult] """ error_ = Error.from_json(error) if error else None @@ -11572,15 +10134,11 @@ def __init__(self, error=None, metrics=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if metrics_ is not None and not isinstance(metrics_, (bytes, str, list)): raise Exception( - "Expected metrics_ to be a Sequence, received: {}".format( - type(metrics_) - ) + f"Expected metrics_ to be a Sequence, received: {type(metrics_)}" ) self.error = error_ @@ -11593,8 +10151,7 @@ class EntityPassword(Type): _toPy = {"password": "password", "tag": "tag"} def __init__(self, password=None, tag=None, **unknown_fields): - """ - password : str + """Password : str tag : str """ password_ = password @@ -11603,13 +10160,11 @@ def __init__(self, password=None, tag=None, **unknown_fields): # Validate arguments against known Juju API types. if password_ is not None and not isinstance(password_, (bytes, str)): raise Exception( - "Expected password_ to be a str, received: {}".format(type(password_)) + f"Expected password_ to be a str, received: {type(password_)}" ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception( - "Expected tag_ to be a str, received: {}".format(type(tag_)) - ) + raise Exception(f"Expected tag_ to be a str, received: {type(tag_)}") self.password = password_ self.tag = tag_ @@ -11621,17 +10176,13 @@ class EntityPasswords(Type): _toPy = {"changes": "changes"} def __init__(self, changes=None, **unknown_fields): - """ - changes : typing.Sequence[~EntityPassword] - """ + """Changes : typing.Sequence[~EntityPassword]""" changes_ = [EntityPassword.from_json(o) for o in changes or []] # Validate arguments against known Juju API types. if changes_ is not None and not isinstance(changes_, (bytes, str, list)): raise Exception( - "Expected changes_ to be a Sequence, received: {}".format( - type(changes_) - ) + f"Expected changes_ to be a Sequence, received: {type(changes_)}" ) self.changes = changes_ @@ -11643,8 +10194,7 @@ class EntityStatus(Type): _toPy = {"data": "data", "info": "info", "since": "since", "status": "status"} def __init__(self, data=None, info=None, since=None, status=None, **unknown_fields): - """ - data : typing.Mapping[str, typing.Any] + """Data : typing.Mapping[str, typing.Any] info : str since : str status : str @@ -11656,24 +10206,16 @@ def __init__(self, data=None, info=None, since=None, status=None, **unknown_fiel # Validate arguments against known Juju API types. if data_ is not None and not isinstance(data_, dict): - raise Exception( - "Expected data_ to be a Mapping, received: {}".format(type(data_)) - ) + raise Exception(f"Expected data_ to be a Mapping, received: {type(data_)}") if info_ is not None and not isinstance(info_, (bytes, str)): - raise Exception( - "Expected info_ to be a str, received: {}".format(type(info_)) - ) + raise Exception(f"Expected info_ to be a str, received: {type(info_)}") if since_ is not None and not isinstance(since_, (bytes, str)): - raise Exception( - "Expected since_ to be a str, received: {}".format(type(since_)) - ) + raise Exception(f"Expected since_ to be a str, received: {type(since_)}") if status_ is not None and not isinstance(status_, (bytes, str)): - raise Exception( - "Expected status_ to be a str, received: {}".format(type(status_)) - ) + raise Exception(f"Expected status_ to be a str, received: {type(status_)}") self.data = data_ self.info = info_ @@ -11687,8 +10229,7 @@ class Error(Type): _toPy = {"code": "code", "info": "info", "message": "message"} def __init__(self, code=None, info=None, message=None, **unknown_fields): - """ - code : str + """Code : str info : typing.Mapping[str, typing.Any] message : str """ @@ -11698,18 +10239,14 @@ def __init__(self, code=None, info=None, message=None, **unknown_fields): # Validate arguments against known Juju API types. if code_ is not None and not isinstance(code_, (bytes, str)): - raise Exception( - "Expected code_ to be a str, received: {}".format(type(code_)) - ) + raise Exception(f"Expected code_ to be a str, received: {type(code_)}") if info_ is not None and not isinstance(info_, dict): - raise Exception( - "Expected info_ to be a Mapping, received: {}".format(type(info_)) - ) + raise Exception(f"Expected info_ to be a Mapping, received: {type(info_)}") if message_ is not None and not isinstance(message_, (bytes, str)): raise Exception( - "Expected message_ to be a str, received: {}".format(type(message_)) + f"Expected message_ to be a str, received: {type(message_)}" ) self.code = code_ @@ -11723,16 +10260,12 @@ class ErrorResult(Type): _toPy = {"error": "error"} def __init__(self, error=None, **unknown_fields): - """ - error : Error - """ + """Error : Error""" error_ = Error.from_json(error) if error else None # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") self.error = error_ self.unknown_fields = unknown_fields @@ -11743,17 +10276,13 @@ class ErrorResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~ErrorResult] - """ + """Results : typing.Sequence[~ErrorResult]""" results_ = [ErrorResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -11773,8 +10302,7 @@ class ExportBundleParams(Type): def __init__( self, include_charm_defaults=None, include_series=None, **unknown_fields ): - """ - include_charm_defaults : bool + """include_charm_defaults : bool include_series : bool """ include_charm_defaults_ = include_charm_defaults @@ -11785,16 +10313,12 @@ def __init__( include_charm_defaults_, bool ): raise Exception( - "Expected include_charm_defaults_ to be a bool, received: {}".format( - type(include_charm_defaults_) - ) + f"Expected include_charm_defaults_ to be a bool, received: {type(include_charm_defaults_)}" ) if include_series_ is not None and not isinstance(include_series_, bool): raise Exception( - "Expected include_series_ to be a bool, received: {}".format( - type(include_series_) - ) + f"Expected include_series_ to be a bool, received: {type(include_series_)}" ) self.include_charm_defaults = include_charm_defaults_ @@ -11813,8 +10337,7 @@ class ExposedEndpoint(Type): } def __init__(self, expose_to_cidrs=None, expose_to_spaces=None, **unknown_fields): - """ - expose_to_cidrs : typing.Sequence[str] + """expose_to_cidrs : typing.Sequence[str] expose_to_spaces : typing.Sequence[str] """ expose_to_cidrs_ = expose_to_cidrs @@ -11825,18 +10348,14 @@ def __init__(self, expose_to_cidrs=None, expose_to_spaces=None, **unknown_fields expose_to_cidrs_, (bytes, str, list) ): raise Exception( - "Expected expose_to_cidrs_ to be a Sequence, received: {}".format( - type(expose_to_cidrs_) - ) + f"Expected expose_to_cidrs_ to be a Sequence, received: {type(expose_to_cidrs_)}" ) if expose_to_spaces_ is not None and not isinstance( expose_to_spaces_, (bytes, str, list) ): raise Exception( - "Expected expose_to_spaces_ to be a Sequence, received: {}".format( - type(expose_to_spaces_) - ) + f"Expected expose_to_spaces_ to be a Sequence, received: {type(expose_to_spaces_)}" ) self.expose_to_cidrs = expose_to_cidrs_ @@ -11849,9 +10368,7 @@ class ExpressionTree(Type): _toPy = {"Expression": "expression"} def __init__(self, expression=None, **unknown_fields): - """ - expression : Any - """ + """Expression : Any""" expression_ = expression # Validate arguments against known Juju API types. @@ -11881,8 +10398,7 @@ def __init__( controller_tag=None, **unknown_fields, ): - """ - addrs : typing.Sequence[str] + """Addrs : typing.Sequence[str] ca_cert : str controller_alias : str controller_tag : str @@ -11895,30 +10411,26 @@ def __init__( # Validate arguments against known Juju API types. if addrs_ is not None and not isinstance(addrs_, (bytes, str, list)): raise Exception( - "Expected addrs_ to be a Sequence, received: {}".format(type(addrs_)) + f"Expected addrs_ to be a Sequence, received: {type(addrs_)}" ) if ca_cert_ is not None and not isinstance(ca_cert_, (bytes, str)): raise Exception( - "Expected ca_cert_ to be a str, received: {}".format(type(ca_cert_)) + f"Expected ca_cert_ to be a str, received: {type(ca_cert_)}" ) if controller_alias_ is not None and not isinstance( controller_alias_, (bytes, str) ): raise Exception( - "Expected controller_alias_ to be a str, received: {}".format( - type(controller_alias_) - ) + f"Expected controller_alias_ to be a str, received: {type(controller_alias_)}" ) if controller_tag_ is not None and not isinstance( controller_tag_, (bytes, str) ): raise Exception( - "Expected controller_tag_ to be a str, received: {}".format( - type(controller_tag_) - ) + f"Expected controller_tag_ to be a str, received: {type(controller_tag_)}" ) self.addrs = addrs_ @@ -11950,8 +10462,7 @@ def __init__( read_only=None, **unknown_fields, ): - """ - filesystemattachmentinfo : FilesystemAttachmentInfo + """Filesystemattachmentinfo : FilesystemAttachmentInfo life : str mount_point : str read_only : bool @@ -11970,28 +10481,20 @@ def __init__( filesystemattachmentinfo_, (dict, FilesystemAttachmentInfo) ): raise Exception( - "Expected filesystemattachmentinfo_ to be a FilesystemAttachmentInfo, received: {}".format( - type(filesystemattachmentinfo_) - ) + f"Expected filesystemattachmentinfo_ to be a FilesystemAttachmentInfo, received: {type(filesystemattachmentinfo_)}" ) if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception( - "Expected life_ to be a str, received: {}".format(type(life_)) - ) + raise Exception(f"Expected life_ to be a str, received: {type(life_)}") if mount_point_ is not None and not isinstance(mount_point_, (bytes, str)): raise Exception( - "Expected mount_point_ to be a str, received: {}".format( - type(mount_point_) - ) + f"Expected mount_point_ to be a str, received: {type(mount_point_)}" ) if read_only_ is not None and not isinstance(read_only_, bool): raise Exception( - "Expected read_only_ to be a bool, received: {}".format( - type(read_only_) - ) + f"Expected read_only_ to be a bool, received: {type(read_only_)}" ) self.filesystemattachmentinfo = filesystemattachmentinfo_ @@ -12006,8 +10509,7 @@ class FilesystemAttachmentInfo(Type): _toPy = {"mount-point": "mount_point", "read-only": "read_only"} def __init__(self, mount_point=None, read_only=None, **unknown_fields): - """ - mount_point : str + """mount_point : str read_only : bool """ mount_point_ = mount_point @@ -12016,16 +10518,12 @@ def __init__(self, mount_point=None, read_only=None, **unknown_fields): # Validate arguments against known Juju API types. if mount_point_ is not None and not isinstance(mount_point_, (bytes, str)): raise Exception( - "Expected mount_point_ to be a str, received: {}".format( - type(mount_point_) - ) + f"Expected mount_point_ to be a str, received: {type(mount_point_)}" ) if read_only_ is not None and not isinstance(read_only_, bool): raise Exception( - "Expected read_only_ to be a bool, received: {}".format( - type(read_only_) - ) + f"Expected read_only_ to be a bool, received: {type(read_only_)}" ) self.mount_point = mount_point_ @@ -12067,8 +10565,7 @@ def __init__( volume_tag=None, **unknown_fields, ): - """ - filesystem_tag : str + """filesystem_tag : str info : FilesystemInfo life : str machine_attachments : typing.Mapping[str, ~FilesystemAttachmentDetails] @@ -12097,58 +10594,42 @@ def __init__( filesystem_tag_, (bytes, str) ): raise Exception( - "Expected filesystem_tag_ to be a str, received: {}".format( - type(filesystem_tag_) - ) + f"Expected filesystem_tag_ to be a str, received: {type(filesystem_tag_)}" ) if info_ is not None and not isinstance(info_, (dict, FilesystemInfo)): raise Exception( - "Expected info_ to be a FilesystemInfo, received: {}".format( - type(info_) - ) + f"Expected info_ to be a FilesystemInfo, received: {type(info_)}" ) if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception( - "Expected life_ to be a str, received: {}".format(type(life_)) - ) + raise Exception(f"Expected life_ to be a str, received: {type(life_)}") if machine_attachments_ is not None and not isinstance( machine_attachments_, dict ): raise Exception( - "Expected machine_attachments_ to be a Mapping, received: {}".format( - type(machine_attachments_) - ) + f"Expected machine_attachments_ to be a Mapping, received: {type(machine_attachments_)}" ) if status_ is not None and not isinstance(status_, (dict, EntityStatus)): raise Exception( - "Expected status_ to be a EntityStatus, received: {}".format( - type(status_) - ) + f"Expected status_ to be a EntityStatus, received: {type(status_)}" ) if storage_ is not None and not isinstance(storage_, (dict, StorageDetails)): raise Exception( - "Expected storage_ to be a StorageDetails, received: {}".format( - type(storage_) - ) + f"Expected storage_ to be a StorageDetails, received: {type(storage_)}" ) if unit_attachments_ is not None and not isinstance(unit_attachments_, dict): raise Exception( - "Expected unit_attachments_ to be a Mapping, received: {}".format( - type(unit_attachments_) - ) + f"Expected unit_attachments_ to be a Mapping, received: {type(unit_attachments_)}" ) if volume_tag_ is not None and not isinstance(volume_tag_, (bytes, str)): raise Exception( - "Expected volume_tag_ to be a str, received: {}".format( - type(volume_tag_) - ) + f"Expected volume_tag_ to be a str, received: {type(volume_tag_)}" ) self.filesystem_tag = filesystem_tag_ @@ -12167,8 +10648,7 @@ class FilesystemDetailsListResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : typing.Sequence[~FilesystemDetails] """ error_ = Error.from_json(error) if error else None @@ -12176,13 +10656,11 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance(result_, (bytes, str, list)): raise Exception( - "Expected result_ to be a Sequence, received: {}".format(type(result_)) + f"Expected result_ to be a Sequence, received: {type(result_)}" ) self.error = error_ @@ -12195,17 +10673,13 @@ class FilesystemDetailsListResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~FilesystemDetailsListResult] - """ + """Results : typing.Sequence[~FilesystemDetailsListResult]""" results_ = [FilesystemDetailsListResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -12217,17 +10691,13 @@ class FilesystemFilter(Type): _toPy = {"machines": "machines"} def __init__(self, machines=None, **unknown_fields): - """ - machines : typing.Sequence[str] - """ + """Machines : typing.Sequence[str]""" machines_ = machines # Validate arguments against known Juju API types. if machines_ is not None and not isinstance(machines_, (bytes, str, list)): raise Exception( - "Expected machines_ to be a Sequence, received: {}".format( - type(machines_) - ) + f"Expected machines_ to be a Sequence, received: {type(machines_)}" ) self.machines = machines_ @@ -12239,17 +10709,13 @@ class FilesystemFilters(Type): _toPy = {"filters": "filters"} def __init__(self, filters=None, **unknown_fields): - """ - filters : typing.Sequence[~FilesystemFilter] - """ + """Filters : typing.Sequence[~FilesystemFilter]""" filters_ = [FilesystemFilter.from_json(o) for o in filters or []] # Validate arguments against known Juju API types. if filters_ is not None and not isinstance(filters_, (bytes, str, list)): raise Exception( - "Expected filters_ to be a Sequence, received: {}".format( - type(filters_) - ) + f"Expected filters_ to be a Sequence, received: {type(filters_)}" ) self.filters = filters_ @@ -12261,8 +10727,7 @@ class FilesystemInfo(Type): _toPy = {"filesystem-id": "filesystem_id", "pool": "pool", "size": "size"} def __init__(self, filesystem_id=None, pool=None, size=None, **unknown_fields): - """ - filesystem_id : str + """filesystem_id : str pool : str size : int """ @@ -12273,20 +10738,14 @@ def __init__(self, filesystem_id=None, pool=None, size=None, **unknown_fields): # Validate arguments against known Juju API types. if filesystem_id_ is not None and not isinstance(filesystem_id_, (bytes, str)): raise Exception( - "Expected filesystem_id_ to be a str, received: {}".format( - type(filesystem_id_) - ) + f"Expected filesystem_id_ to be a str, received: {type(filesystem_id_)}" ) if pool_ is not None and not isinstance(pool_, (bytes, str)): - raise Exception( - "Expected pool_ to be a str, received: {}".format(type(pool_)) - ) + raise Exception(f"Expected pool_ to be a str, received: {type(pool_)}") if size_ is not None and not isinstance(size_, int): - raise Exception( - "Expected size_ to be a int, received: {}".format(type(size_)) - ) + raise Exception(f"Expected size_ to be a int, received: {type(size_)}") self.filesystem_id = filesystem_id_ self.pool = pool_ @@ -12319,8 +10778,7 @@ def __init__( os_type=None, **unknown_fields, ): - """ - agentstream : str + """Agentstream : str arch : str major : int number : Number @@ -12335,29 +10793,23 @@ def __init__( # Validate arguments against known Juju API types. if agentstream_ is not None and not isinstance(agentstream_, (bytes, str)): raise Exception( - "Expected agentstream_ to be a str, received: {}".format( - type(agentstream_) - ) + f"Expected agentstream_ to be a str, received: {type(agentstream_)}" ) if arch_ is not None and not isinstance(arch_, (bytes, str)): - raise Exception( - "Expected arch_ to be a str, received: {}".format(type(arch_)) - ) + raise Exception(f"Expected arch_ to be a str, received: {type(arch_)}") if major_ is not None and not isinstance(major_, int): - raise Exception( - "Expected major_ to be a int, received: {}".format(type(major_)) - ) + raise Exception(f"Expected major_ to be a int, received: {type(major_)}") if number_ is not None and not isinstance(number_, (dict, Number)): raise Exception( - "Expected number_ to be a Number, received: {}".format(type(number_)) + f"Expected number_ to be a Number, received: {type(number_)}" ) if os_type_ is not None and not isinstance(os_type_, (bytes, str)): raise Exception( - "Expected os_type_ to be a str, received: {}".format(type(os_type_)) + f"Expected os_type_ to be a str, received: {type(os_type_)}" ) self.agentstream = agentstream_ @@ -12373,8 +10825,7 @@ class FindToolsResult(Type): _toPy = {"error": "error", "list": "list_"} def __init__(self, error=None, list_=None, **unknown_fields): - """ - error : Error + """Error : Error list_ : typing.Sequence[~Tools] """ error_ = Error.from_json(error) if error else None @@ -12382,13 +10833,11 @@ def __init__(self, error=None, list_=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if list__ is not None and not isinstance(list__, (bytes, str, list)): raise Exception( - "Expected list__ to be a Sequence, received: {}".format(type(list__)) + f"Expected list__ to be a Sequence, received: {type(list__)}" ) self.error = error_ @@ -12401,8 +10850,7 @@ class FirewallRule(Type): _toPy = {"known-service": "known_service", "whitelist-cidrs": "whitelist_cidrs"} def __init__(self, known_service=None, whitelist_cidrs=None, **unknown_fields): - """ - known_service : str + """known_service : str whitelist_cidrs : typing.Sequence[str] """ known_service_ = known_service @@ -12411,18 +10859,14 @@ def __init__(self, known_service=None, whitelist_cidrs=None, **unknown_fields): # Validate arguments against known Juju API types. if known_service_ is not None and not isinstance(known_service_, (bytes, str)): raise Exception( - "Expected known_service_ to be a str, received: {}".format( - type(known_service_) - ) + f"Expected known_service_ to be a str, received: {type(known_service_)}" ) if whitelist_cidrs_ is not None and not isinstance( whitelist_cidrs_, (bytes, str, list) ): raise Exception( - "Expected whitelist_cidrs_ to be a Sequence, received: {}".format( - type(whitelist_cidrs_) - ) + f"Expected whitelist_cidrs_ to be a Sequence, received: {type(whitelist_cidrs_)}" ) self.known_service = known_service_ @@ -12435,16 +10879,12 @@ class FirewallRuleArgs(Type): _toPy = {"args": "args"} def __init__(self, args=None, **unknown_fields): - """ - args : typing.Sequence[~FirewallRule] - """ + """Args : typing.Sequence[~FirewallRule]""" args_ = [FirewallRule.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception( - "Expected args_ to be a Sequence, received: {}".format(type(args_)) - ) + raise Exception(f"Expected args_ to be a Sequence, received: {type(args_)}") self.args = args_ self.unknown_fields = unknown_fields @@ -12493,8 +10933,7 @@ def __init__( volumes=None, **unknown_fields, ): - """ - applications : typing.Mapping[str, ~ApplicationStatus] + """Applications : typing.Mapping[str, ~ApplicationStatus] branches : typing.Mapping[str, ~BranchStatus] controller_timestamp : str filesystems : typing.Sequence[~FilesystemDetails] @@ -12534,83 +10973,63 @@ def __init__( # Validate arguments against known Juju API types. if applications_ is not None and not isinstance(applications_, dict): raise Exception( - "Expected applications_ to be a Mapping, received: {}".format( - type(applications_) - ) + f"Expected applications_ to be a Mapping, received: {type(applications_)}" ) if branches_ is not None and not isinstance(branches_, dict): raise Exception( - "Expected branches_ to be a Mapping, received: {}".format( - type(branches_) - ) + f"Expected branches_ to be a Mapping, received: {type(branches_)}" ) if controller_timestamp_ is not None and not isinstance( controller_timestamp_, (bytes, str) ): raise Exception( - "Expected controller_timestamp_ to be a str, received: {}".format( - type(controller_timestamp_) - ) + f"Expected controller_timestamp_ to be a str, received: {type(controller_timestamp_)}" ) if filesystems_ is not None and not isinstance( filesystems_, (bytes, str, list) ): raise Exception( - "Expected filesystems_ to be a Sequence, received: {}".format( - type(filesystems_) - ) + f"Expected filesystems_ to be a Sequence, received: {type(filesystems_)}" ) if machines_ is not None and not isinstance(machines_, dict): raise Exception( - "Expected machines_ to be a Mapping, received: {}".format( - type(machines_) - ) + f"Expected machines_ to be a Mapping, received: {type(machines_)}" ) if model_ is not None and not isinstance(model_, (dict, ModelStatusInfo)): raise Exception( - "Expected model_ to be a ModelStatusInfo, received: {}".format( - type(model_) - ) + f"Expected model_ to be a ModelStatusInfo, received: {type(model_)}" ) if offers_ is not None and not isinstance(offers_, dict): raise Exception( - "Expected offers_ to be a Mapping, received: {}".format(type(offers_)) + f"Expected offers_ to be a Mapping, received: {type(offers_)}" ) if relations_ is not None and not isinstance(relations_, (bytes, str, list)): raise Exception( - "Expected relations_ to be a Sequence, received: {}".format( - type(relations_) - ) + f"Expected relations_ to be a Sequence, received: {type(relations_)}" ) if remote_applications_ is not None and not isinstance( remote_applications_, dict ): raise Exception( - "Expected remote_applications_ to be a Mapping, received: {}".format( - type(remote_applications_) - ) + f"Expected remote_applications_ to be a Mapping, received: {type(remote_applications_)}" ) if storage_ is not None and not isinstance(storage_, (bytes, str, list)): raise Exception( - "Expected storage_ to be a Sequence, received: {}".format( - type(storage_) - ) + f"Expected storage_ to be a Sequence, received: {type(storage_)}" ) if volumes_ is not None and not isinstance(volumes_, (bytes, str, list)): raise Exception( - "Expected volumes_ to be a Sequence, received: {}".format( - type(volumes_) - ) + f"Expected volumes_ to be a Sequence, received: {type(volumes_)}" ) self.applications = applications_ @@ -12658,8 +11077,7 @@ def __init__( generation_id=None, **unknown_fields, ): - """ - applications : typing.Sequence[~GenerationApplication] + """Applications : typing.Sequence[~GenerationApplication] branch : str completed : int completed_by : str @@ -12680,45 +11098,35 @@ def __init__( applications_, (bytes, str, list) ): raise Exception( - "Expected applications_ to be a Sequence, received: {}".format( - type(applications_) - ) + f"Expected applications_ to be a Sequence, received: {type(applications_)}" ) if branch_ is not None and not isinstance(branch_, (bytes, str)): - raise Exception( - "Expected branch_ to be a str, received: {}".format(type(branch_)) - ) + raise Exception(f"Expected branch_ to be a str, received: {type(branch_)}") if completed_ is not None and not isinstance(completed_, int): raise Exception( - "Expected completed_ to be a int, received: {}".format(type(completed_)) + f"Expected completed_ to be a int, received: {type(completed_)}" ) if completed_by_ is not None and not isinstance(completed_by_, (bytes, str)): raise Exception( - "Expected completed_by_ to be a str, received: {}".format( - type(completed_by_) - ) + f"Expected completed_by_ to be a str, received: {type(completed_by_)}" ) if created_ is not None and not isinstance(created_, int): raise Exception( - "Expected created_ to be a int, received: {}".format(type(created_)) + f"Expected created_ to be a int, received: {type(created_)}" ) if created_by_ is not None and not isinstance(created_by_, (bytes, str)): raise Exception( - "Expected created_by_ to be a str, received: {}".format( - type(created_by_) - ) + f"Expected created_by_ to be a str, received: {type(created_by_)}" ) if generation_id_ is not None and not isinstance(generation_id_, int): raise Exception( - "Expected generation_id_ to be a int, received: {}".format( - type(generation_id_) - ) + f"Expected generation_id_ to be a int, received: {type(generation_id_)}" ) self.applications = applications_ @@ -12756,8 +11164,7 @@ def __init__( tracking=None, **unknown_fields, ): - """ - application : str + """Application : str config : typing.Mapping[str, typing.Any] pending : typing.Sequence[str] progress : str @@ -12772,33 +11179,27 @@ def __init__( # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): raise Exception( - "Expected application_ to be a str, received: {}".format( - type(application_) - ) + f"Expected application_ to be a str, received: {type(application_)}" ) if config_ is not None and not isinstance(config_, dict): raise Exception( - "Expected config_ to be a Mapping, received: {}".format(type(config_)) + f"Expected config_ to be a Mapping, received: {type(config_)}" ) if pending_ is not None and not isinstance(pending_, (bytes, str, list)): raise Exception( - "Expected pending_ to be a Sequence, received: {}".format( - type(pending_) - ) + f"Expected pending_ to be a Sequence, received: {type(pending_)}" ) if progress_ is not None and not isinstance(progress_, (bytes, str)): raise Exception( - "Expected progress_ to be a str, received: {}".format(type(progress_)) + f"Expected progress_ to be a str, received: {type(progress_)}" ) if tracking_ is not None and not isinstance(tracking_, (bytes, str, list)): raise Exception( - "Expected tracking_ to be a Sequence, received: {}".format( - type(tracking_) - ) + f"Expected tracking_ to be a Sequence, received: {type(tracking_)}" ) self.application = application_ @@ -12814,17 +11215,13 @@ class GenerationId(Type): _toPy = {"generation-id": "generation_id"} def __init__(self, generation_id=None, **unknown_fields): - """ - generation_id : int - """ + """generation_id : int""" generation_id_ = generation_id # Validate arguments against known Juju API types. if generation_id_ is not None and not isinstance(generation_id_, int): raise Exception( - "Expected generation_id_ to be a int, received: {}".format( - type(generation_id_) - ) + f"Expected generation_id_ to be a int, received: {type(generation_id_)}" ) self.generation_id = generation_id_ @@ -12836,8 +11233,7 @@ class GenerationResult(Type): _toPy = {"error": "error", "generation": "generation"} def __init__(self, error=None, generation=None, **unknown_fields): - """ - error : Error + """Error : Error generation : Generation """ error_ = Error.from_json(error) if error else None @@ -12845,15 +11241,11 @@ def __init__(self, error=None, generation=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if generation_ is not None and not isinstance(generation_, (dict, Generation)): raise Exception( - "Expected generation_ to be a Generation, received: {}".format( - type(generation_) - ) + f"Expected generation_ to be a Generation, received: {type(generation_)}" ) self.error = error_ @@ -12866,17 +11258,13 @@ class GetConstraintsResults(Type): _toPy = {"constraints": "constraints"} def __init__(self, constraints=None, **unknown_fields): - """ - constraints : Value - """ + """Constraints : Value""" constraints_ = Value.from_json(constraints) if constraints else None # Validate arguments against known Juju API types. if constraints_ is not None and not isinstance(constraints_, (dict, Value)): raise Exception( - "Expected constraints_ to be a Value, received: {}".format( - type(constraints_) - ) + f"Expected constraints_ to be a Value, received: {type(constraints_)}" ) self.constraints = constraints_ @@ -12888,8 +11276,7 @@ class GrantRevokeUserSecretArg(Type): _toPy = {"applications": "applications", "label": "label", "uri": "uri"} def __init__(self, applications=None, label=None, uri=None, **unknown_fields): - """ - applications : typing.Sequence[str] + """Applications : typing.Sequence[str] label : str uri : str """ @@ -12902,20 +11289,14 @@ def __init__(self, applications=None, label=None, uri=None, **unknown_fields): applications_, (bytes, str, list) ): raise Exception( - "Expected applications_ to be a Sequence, received: {}".format( - type(applications_) - ) + f"Expected applications_ to be a Sequence, received: {type(applications_)}" ) if label_ is not None and not isinstance(label_, (bytes, str)): - raise Exception( - "Expected label_ to be a str, received: {}".format(type(label_)) - ) + raise Exception(f"Expected label_ to be a str, received: {type(label_)}") if uri_ is not None and not isinstance(uri_, (bytes, str)): - raise Exception( - "Expected uri_ to be a str, received: {}".format(type(uri_)) - ) + raise Exception(f"Expected uri_ to be a str, received: {type(uri_)}") self.applications = applications_ self.label = label_ @@ -12960,8 +11341,7 @@ def __init__( virt_type=None, **unknown_fields, ): - """ - arch : str + """Arch : str availability_zone : str cpu_cores : int cpu_power : int @@ -12983,56 +11363,46 @@ def __init__( # Validate arguments against known Juju API types. if arch_ is not None and not isinstance(arch_, (bytes, str)): - raise Exception( - "Expected arch_ to be a str, received: {}".format(type(arch_)) - ) + raise Exception(f"Expected arch_ to be a str, received: {type(arch_)}") if availability_zone_ is not None and not isinstance( availability_zone_, (bytes, str) ): raise Exception( - "Expected availability_zone_ to be a str, received: {}".format( - type(availability_zone_) - ) + f"Expected availability_zone_ to be a str, received: {type(availability_zone_)}" ) if cpu_cores_ is not None and not isinstance(cpu_cores_, int): raise Exception( - "Expected cpu_cores_ to be a int, received: {}".format(type(cpu_cores_)) + f"Expected cpu_cores_ to be a int, received: {type(cpu_cores_)}" ) if cpu_power_ is not None and not isinstance(cpu_power_, int): raise Exception( - "Expected cpu_power_ to be a int, received: {}".format(type(cpu_power_)) + f"Expected cpu_power_ to be a int, received: {type(cpu_power_)}" ) if mem_ is not None and not isinstance(mem_, int): - raise Exception( - "Expected mem_ to be a int, received: {}".format(type(mem_)) - ) + raise Exception(f"Expected mem_ to be a int, received: {type(mem_)}") if root_disk_ is not None and not isinstance(root_disk_, int): raise Exception( - "Expected root_disk_ to be a int, received: {}".format(type(root_disk_)) + f"Expected root_disk_ to be a int, received: {type(root_disk_)}" ) if root_disk_source_ is not None and not isinstance( root_disk_source_, (bytes, str) ): raise Exception( - "Expected root_disk_source_ to be a str, received: {}".format( - type(root_disk_source_) - ) + f"Expected root_disk_source_ to be a str, received: {type(root_disk_source_)}" ) if tags_ is not None and not isinstance(tags_, (bytes, str, list)): - raise Exception( - "Expected tags_ to be a Sequence, received: {}".format(type(tags_)) - ) + raise Exception(f"Expected tags_ to be a Sequence, received: {type(tags_)}") if virt_type_ is not None and not isinstance(virt_type_, (bytes, str)): raise Exception( - "Expected virt_type_ to be a str, received: {}".format(type(virt_type_)) + f"Expected virt_type_ to be a str, received: {type(virt_type_)}" ) self.arch = arch_ @@ -13052,8 +11422,7 @@ class History(Type): _toPy = {"error": "error", "statuses": "statuses"} def __init__(self, error=None, statuses=None, **unknown_fields): - """ - error : Error + """Error : Error statuses : typing.Sequence[~DetailedStatus] """ error_ = Error.from_json(error) if error else None @@ -13061,15 +11430,11 @@ def __init__(self, error=None, statuses=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if statuses_ is not None and not isinstance(statuses_, (bytes, str, list)): raise Exception( - "Expected statuses_ to be a Sequence, received: {}".format( - type(statuses_) - ) + f"Expected statuses_ to be a Sequence, received: {type(statuses_)}" ) self.error = error_ @@ -13117,8 +11482,7 @@ def __init__( value=None, **unknown_fields, ): - """ - address : Address + """Address : Address cidr : str config_type : str is_secondary : bool @@ -13143,59 +11507,43 @@ def __init__( # Validate arguments against known Juju API types. if address_ is not None and not isinstance(address_, (dict, Address)): raise Exception( - "Expected address_ to be a Address, received: {}".format(type(address_)) + f"Expected address_ to be a Address, received: {type(address_)}" ) if cidr_ is not None and not isinstance(cidr_, (bytes, str)): - raise Exception( - "Expected cidr_ to be a str, received: {}".format(type(cidr_)) - ) + raise Exception(f"Expected cidr_ to be a str, received: {type(cidr_)}") if config_type_ is not None and not isinstance(config_type_, (bytes, str)): raise Exception( - "Expected config_type_ to be a str, received: {}".format( - type(config_type_) - ) + f"Expected config_type_ to be a str, received: {type(config_type_)}" ) if is_secondary_ is not None and not isinstance(is_secondary_, bool): raise Exception( - "Expected is_secondary_ to be a bool, received: {}".format( - type(is_secondary_) - ) + f"Expected is_secondary_ to be a bool, received: {type(is_secondary_)}" ) if port_ is not None and not isinstance(port_, int): - raise Exception( - "Expected port_ to be a int, received: {}".format(type(port_)) - ) + raise Exception(f"Expected port_ to be a int, received: {type(port_)}") if scope_ is not None and not isinstance(scope_, (bytes, str)): - raise Exception( - "Expected scope_ to be a str, received: {}".format(type(scope_)) - ) + raise Exception(f"Expected scope_ to be a str, received: {type(scope_)}") if space_id_ is not None and not isinstance(space_id_, (bytes, str)): raise Exception( - "Expected space_id_ to be a str, received: {}".format(type(space_id_)) + f"Expected space_id_ to be a str, received: {type(space_id_)}" ) if space_name_ is not None and not isinstance(space_name_, (bytes, str)): raise Exception( - "Expected space_name_ to be a str, received: {}".format( - type(space_name_) - ) + f"Expected space_name_ to be a str, received: {type(space_name_)}" ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") if value_ is not None and not isinstance(value_, (bytes, str)): - raise Exception( - "Expected value_ to be a str, received: {}".format(type(value_)) - ) + raise Exception(f"Expected value_ to be a str, received: {type(value_)}") self.address = address_ self.cidr = cidr_ @@ -13235,8 +11583,7 @@ def __init__( owner=None, **unknown_fields, ): - """ - cloud_spec : CloudSpec + """cloud_spec : CloudSpec config : typing.Mapping[str, typing.Any] error : Error name : str @@ -13251,30 +11598,22 @@ def __init__( # Validate arguments against known Juju API types. if cloud_spec_ is not None and not isinstance(cloud_spec_, (dict, CloudSpec)): raise Exception( - "Expected cloud_spec_ to be a CloudSpec, received: {}".format( - type(cloud_spec_) - ) + f"Expected cloud_spec_ to be a CloudSpec, received: {type(cloud_spec_)}" ) if config_ is not None and not isinstance(config_, dict): raise Exception( - "Expected config_ to be a Mapping, received: {}".format(type(config_)) + f"Expected config_ to be a Mapping, received: {type(config_)}" ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if owner_ is not None and not isinstance(owner_, (bytes, str)): - raise Exception( - "Expected owner_ to be a str, received: {}".format(type(owner_)) - ) + raise Exception(f"Expected owner_ to be a str, received: {type(owner_)}") self.cloud_spec = cloud_spec_ self.config = config_ @@ -13289,15 +11628,13 @@ class HostedModelConfigsResults(Type): _toPy = {"models": "models"} def __init__(self, models=None, **unknown_fields): - """ - models : typing.Sequence[~HostedModelConfig] - """ + """Models : typing.Sequence[~HostedModelConfig]""" models_ = [HostedModelConfig.from_json(o) for o in models or []] # Validate arguments against known Juju API types. if models_ is not None and not isinstance(models_, (bytes, str, list)): raise Exception( - "Expected models_ to be a Sequence, received: {}".format(type(models_)) + f"Expected models_ to be a Sequence, received: {type(models_)}" ) self.models = models_ @@ -13332,8 +11669,7 @@ def __init__( virt_type=None, **unknown_fields, ): - """ - arches : typing.Sequence[str] + """Arches : typing.Sequence[str] region : str root_storage_type : str stream : str @@ -13350,38 +11686,30 @@ def __init__( # Validate arguments against known Juju API types. if arches_ is not None and not isinstance(arches_, (bytes, str, list)): raise Exception( - "Expected arches_ to be a Sequence, received: {}".format(type(arches_)) + f"Expected arches_ to be a Sequence, received: {type(arches_)}" ) if region_ is not None and not isinstance(region_, (bytes, str)): - raise Exception( - "Expected region_ to be a str, received: {}".format(type(region_)) - ) + raise Exception(f"Expected region_ to be a str, received: {type(region_)}") if root_storage_type_ is not None and not isinstance( root_storage_type_, (bytes, str) ): raise Exception( - "Expected root_storage_type_ to be a str, received: {}".format( - type(root_storage_type_) - ) + f"Expected root_storage_type_ to be a str, received: {type(root_storage_type_)}" ) if stream_ is not None and not isinstance(stream_, (bytes, str)): - raise Exception( - "Expected stream_ to be a str, received: {}".format(type(stream_)) - ) + raise Exception(f"Expected stream_ to be a str, received: {type(stream_)}") if versions_ is not None and not isinstance(versions_, (bytes, str, list)): raise Exception( - "Expected versions_ to be a Sequence, received: {}".format( - type(versions_) - ) + f"Expected versions_ to be a Sequence, received: {type(versions_)}" ) if virt_type_ is not None and not isinstance(virt_type_, (bytes, str)): raise Exception( - "Expected virt_type_ to be a str, received: {}".format(type(virt_type_)) + f"Expected virt_type_ to be a str, received: {type(virt_type_)}" ) self.arches = arches_ @@ -13398,17 +11726,13 @@ class ImportStorageDetails(Type): _toPy = {"storage-tag": "storage_tag"} def __init__(self, storage_tag=None, **unknown_fields): - """ - storage_tag : str - """ + """storage_tag : str""" storage_tag_ = storage_tag # Validate arguments against known Juju API types. if storage_tag_ is not None and not isinstance(storage_tag_, (bytes, str)): raise Exception( - "Expected storage_tag_ to be a str, received: {}".format( - type(storage_tag_) - ) + f"Expected storage_tag_ to be a str, received: {type(storage_tag_)}" ) self.storage_tag = storage_tag_ @@ -13437,8 +11761,7 @@ def __init__( storage_name=None, **unknown_fields, ): - """ - kind : int + """Kind : int pool : str provider_id : str storage_name : str @@ -13450,27 +11773,19 @@ def __init__( # Validate arguments against known Juju API types. if kind_ is not None and not isinstance(kind_, int): - raise Exception( - "Expected kind_ to be a int, received: {}".format(type(kind_)) - ) + raise Exception(f"Expected kind_ to be a int, received: {type(kind_)}") if pool_ is not None and not isinstance(pool_, (bytes, str)): - raise Exception( - "Expected pool_ to be a str, received: {}".format(type(pool_)) - ) + raise Exception(f"Expected pool_ to be a str, received: {type(pool_)}") if provider_id_ is not None and not isinstance(provider_id_, (bytes, str)): raise Exception( - "Expected provider_id_ to be a str, received: {}".format( - type(provider_id_) - ) + f"Expected provider_id_ to be a str, received: {type(provider_id_)}" ) if storage_name_ is not None and not isinstance(storage_name_, (bytes, str)): raise Exception( - "Expected storage_name_ to be a str, received: {}".format( - type(storage_name_) - ) + f"Expected storage_name_ to be a str, received: {type(storage_name_)}" ) self.kind = kind_ @@ -13485,8 +11800,7 @@ class ImportStorageResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : ImportStorageDetails """ error_ = Error.from_json(error) if error else None @@ -13494,17 +11808,13 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance( result_, (dict, ImportStorageDetails) ): raise Exception( - "Expected result_ to be a ImportStorageDetails, received: {}".format( - type(result_) - ) + f"Expected result_ to be a ImportStorageDetails, received: {type(result_)}" ) self.error = error_ @@ -13517,17 +11827,13 @@ class ImportStorageResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~ImportStorageResult] - """ + """Results : typing.Sequence[~ImportStorageResult]""" results_ = [ImportStorageResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -13539,15 +11845,13 @@ class InitiateMigrationArgs(Type): _toPy = {"specs": "specs"} def __init__(self, specs=None, **unknown_fields): - """ - specs : typing.Sequence[~MigrationSpec] - """ + """Specs : typing.Sequence[~MigrationSpec]""" specs_ = [MigrationSpec.from_json(o) for o in specs or []] # Validate arguments against known Juju API types. if specs_ is not None and not isinstance(specs_, (bytes, str, list)): raise Exception( - "Expected specs_ to be a Sequence, received: {}".format(type(specs_)) + f"Expected specs_ to be a Sequence, received: {type(specs_)}" ) self.specs = specs_ @@ -13563,8 +11867,7 @@ class InitiateMigrationResult(Type): _toPy = {"error": "error", "migration-id": "migration_id", "model-tag": "model_tag"} def __init__(self, error=None, migration_id=None, model_tag=None, **unknown_fields): - """ - error : Error + """Error : Error migration_id : str model_tag : str """ @@ -13574,20 +11877,16 @@ def __init__(self, error=None, migration_id=None, model_tag=None, **unknown_fiel # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if migration_id_ is not None and not isinstance(migration_id_, (bytes, str)): raise Exception( - "Expected migration_id_ to be a str, received: {}".format( - type(migration_id_) - ) + f"Expected migration_id_ to be a str, received: {type(migration_id_)}" ) if model_tag_ is not None and not isinstance(model_tag_, (bytes, str)): raise Exception( - "Expected model_tag_ to be a str, received: {}".format(type(model_tag_)) + f"Expected model_tag_ to be a str, received: {type(model_tag_)}" ) self.error = error_ @@ -13601,17 +11900,13 @@ class InitiateMigrationResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~InitiateMigrationResult] - """ + """Results : typing.Sequence[~InitiateMigrationResult]""" results_ = [InitiateMigrationResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -13649,8 +11944,7 @@ def __init__( virt_type=None, **unknown_fields, ): - """ - arches : typing.Sequence[str] + """Arches : typing.Sequence[str] cost : int cpu_cores : int memory : int @@ -13669,37 +11963,31 @@ def __init__( # Validate arguments against known Juju API types. if arches_ is not None and not isinstance(arches_, (bytes, str, list)): raise Exception( - "Expected arches_ to be a Sequence, received: {}".format(type(arches_)) + f"Expected arches_ to be a Sequence, received: {type(arches_)}" ) if cost_ is not None and not isinstance(cost_, int): - raise Exception( - "Expected cost_ to be a int, received: {}".format(type(cost_)) - ) + raise Exception(f"Expected cost_ to be a int, received: {type(cost_)}") if cpu_cores_ is not None and not isinstance(cpu_cores_, int): raise Exception( - "Expected cpu_cores_ to be a int, received: {}".format(type(cpu_cores_)) + f"Expected cpu_cores_ to be a int, received: {type(cpu_cores_)}" ) if memory_ is not None and not isinstance(memory_, int): - raise Exception( - "Expected memory_ to be a int, received: {}".format(type(memory_)) - ) + raise Exception(f"Expected memory_ to be a int, received: {type(memory_)}") if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if root_disk_ is not None and not isinstance(root_disk_, int): raise Exception( - "Expected root_disk_ to be a int, received: {}".format(type(root_disk_)) + f"Expected root_disk_ to be a int, received: {type(root_disk_)}" ) if virt_type_ is not None and not isinstance(virt_type_, (bytes, str)): raise Exception( - "Expected virt_type_ to be a str, received: {}".format(type(virt_type_)) + f"Expected virt_type_ to be a str, received: {type(virt_type_)}" ) self.arches = arches_ @@ -13737,8 +12025,7 @@ def __init__( instance_types=None, **unknown_fields, ): - """ - cost_currency : str + """cost_currency : str cost_divisor : int cost_unit : str error : Error @@ -13753,35 +12040,27 @@ def __init__( # Validate arguments against known Juju API types. if cost_currency_ is not None and not isinstance(cost_currency_, (bytes, str)): raise Exception( - "Expected cost_currency_ to be a str, received: {}".format( - type(cost_currency_) - ) + f"Expected cost_currency_ to be a str, received: {type(cost_currency_)}" ) if cost_divisor_ is not None and not isinstance(cost_divisor_, int): raise Exception( - "Expected cost_divisor_ to be a int, received: {}".format( - type(cost_divisor_) - ) + f"Expected cost_divisor_ to be a int, received: {type(cost_divisor_)}" ) if cost_unit_ is not None and not isinstance(cost_unit_, (bytes, str)): raise Exception( - "Expected cost_unit_ to be a str, received: {}".format(type(cost_unit_)) + f"Expected cost_unit_ to be a str, received: {type(cost_unit_)}" ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if instance_types_ is not None and not isinstance( instance_types_, (bytes, str, list) ): raise Exception( - "Expected instance_types_ to be a Sequence, received: {}".format( - type(instance_types_) - ) + f"Expected instance_types_ to be a Sequence, received: {type(instance_types_)}" ) self.cost_currency = cost_currency_ @@ -13797,17 +12076,13 @@ class InstanceTypesResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~InstanceTypesResult] - """ + """Results : typing.Sequence[~InstanceTypesResult]""" results_ = [InstanceTypesResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -13819,8 +12094,7 @@ class IntResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : int """ error_ = Error.from_json(error) if error else None @@ -13828,14 +12102,10 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance(result_, int): - raise Exception( - "Expected result_ to be a int, received: {}".format(type(result_)) - ) + raise Exception(f"Expected result_ to be a int, received: {type(result_)}") self.error = error_ self.result = result_ @@ -13847,16 +12117,12 @@ class InvalidateCredentialArg(Type): _toPy = {"reason": "reason"} def __init__(self, reason=None, **unknown_fields): - """ - reason : str - """ + """Reason : str""" reason_ = reason # Validate arguments against known Juju API types. if reason_ is not None and not isinstance(reason_, (bytes, str)): - raise Exception( - "Expected reason_ to be a str, received: {}".format(type(reason_)) - ) + raise Exception(f"Expected reason_ to be a str, received: {type(reason_)}") self.reason = reason_ self.unknown_fields = unknown_fields @@ -13867,15 +12133,13 @@ class IsMeteredResult(Type): _toPy = {"metered": "metered"} def __init__(self, metered=None, **unknown_fields): - """ - metered : bool - """ + """Metered : bool""" metered_ = metered # Validate arguments against known Juju API types. if metered_ is not None and not isinstance(metered_, bool): raise Exception( - "Expected metered_ to be a bool, received: {}".format(type(metered_)) + f"Expected metered_ to be a bool, received: {type(metered_)}" ) self.metered = metered_ @@ -13887,8 +12151,7 @@ class LXDProfile(Type): _toPy = {"config": "config", "description": "description", "devices": "devices"} def __init__(self, config=None, description=None, devices=None, **unknown_fields): - """ - config : typing.Mapping[str, str] + """Config : typing.Mapping[str, str] description : str devices : typing.Mapping[str, typing.Any] """ @@ -13899,19 +12162,17 @@ def __init__(self, config=None, description=None, devices=None, **unknown_fields # Validate arguments against known Juju API types. if config_ is not None and not isinstance(config_, dict): raise Exception( - "Expected config_ to be a Mapping, received: {}".format(type(config_)) + f"Expected config_ to be a Mapping, received: {type(config_)}" ) if description_ is not None and not isinstance(description_, (bytes, str)): raise Exception( - "Expected description_ to be a str, received: {}".format( - type(description_) - ) + f"Expected description_ to be a str, received: {type(description_)}" ) if devices_ is not None and not isinstance(devices_, dict): raise Exception( - "Expected devices_ to be a Mapping, received: {}".format(type(devices_)) + f"Expected devices_ to be a Mapping, received: {type(devices_)}" ) self.config = config_ @@ -13925,15 +12186,13 @@ class ListCloudImageMetadataResult(Type): _toPy = {"result": "result"} def __init__(self, result=None, **unknown_fields): - """ - result : typing.Sequence[~CloudImageMetadata] - """ + """Result : typing.Sequence[~CloudImageMetadata]""" result_ = [CloudImageMetadata.from_json(o) for o in result or []] # Validate arguments against known Juju API types. if result_ is not None and not isinstance(result_, (bytes, str, list)): raise Exception( - "Expected result_ to be a Sequence, received: {}".format(type(result_)) + f"Expected result_ to be a Sequence, received: {type(result_)}" ) self.result = result_ @@ -13945,8 +12204,7 @@ class ListCloudInfo(Type): _toPy = {"CloudDetails": "clouddetails", "user-access": "user_access"} def __init__(self, clouddetails=None, user_access=None, **unknown_fields): - """ - clouddetails : CloudDetails + """Clouddetails : CloudDetails user_access : str """ clouddetails_ = CloudDetails.from_json(clouddetails) if clouddetails else None @@ -13957,16 +12215,12 @@ def __init__(self, clouddetails=None, user_access=None, **unknown_fields): clouddetails_, (dict, CloudDetails) ): raise Exception( - "Expected clouddetails_ to be a CloudDetails, received: {}".format( - type(clouddetails_) - ) + f"Expected clouddetails_ to be a CloudDetails, received: {type(clouddetails_)}" ) if user_access_ is not None and not isinstance(user_access_, (bytes, str)): raise Exception( - "Expected user_access_ to be a str, received: {}".format( - type(user_access_) - ) + f"Expected user_access_ to be a str, received: {type(user_access_)}" ) self.clouddetails = clouddetails_ @@ -13979,8 +12233,7 @@ class ListCloudInfoResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : ListCloudInfo """ error_ = Error.from_json(error) if error else None @@ -13988,15 +12241,11 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance(result_, (dict, ListCloudInfo)): raise Exception( - "Expected result_ to be a ListCloudInfo, received: {}".format( - type(result_) - ) + f"Expected result_ to be a ListCloudInfo, received: {type(result_)}" ) self.error = error_ @@ -14009,17 +12258,13 @@ class ListCloudInfoResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~ListCloudInfoResult] - """ + """Results : typing.Sequence[~ListCloudInfoResult]""" results_ = [ListCloudInfoResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -14031,8 +12276,7 @@ class ListCloudsRequest(Type): _toPy = {"all": "all_", "user-tag": "user_tag"} def __init__(self, all_=None, user_tag=None, **unknown_fields): - """ - all_ : bool + """all_ : bool user_tag : str """ all__ = all_ @@ -14040,13 +12284,11 @@ def __init__(self, all_=None, user_tag=None, **unknown_fields): # Validate arguments against known Juju API types. if all__ is not None and not isinstance(all__, bool): - raise Exception( - "Expected all__ to be a bool, received: {}".format(type(all__)) - ) + raise Exception(f"Expected all__ to be a bool, received: {type(all__)}") if user_tag_ is not None and not isinstance(user_tag_, (bytes, str)): raise Exception( - "Expected user_tag_ to be a str, received: {}".format(type(user_tag_)) + f"Expected user_tag_ to be a str, received: {type(user_tag_)}" ) self.all_ = all__ @@ -14059,15 +12301,13 @@ class ListFirewallRulesResults(Type): _toPy = {"Rules": "rules"} def __init__(self, rules=None, **unknown_fields): - """ - rules : typing.Sequence[~FirewallRule] - """ + """Rules : typing.Sequence[~FirewallRule]""" rules_ = [FirewallRule.from_json(o) for o in rules or []] # Validate arguments against known Juju API types. if rules_ is not None and not isinstance(rules_, (bytes, str, list)): raise Exception( - "Expected rules_ to be a Sequence, received: {}".format(type(rules_)) + f"Expected rules_ to be a Sequence, received: {type(rules_)}" ) self.rules = rules_ @@ -14079,17 +12319,13 @@ class ListResourcesArgs(Type): _toPy = {"entities": "entities"} def __init__(self, entities=None, **unknown_fields): - """ - entities : typing.Sequence[~Entity] - """ + """Entities : typing.Sequence[~Entity]""" entities_ = [Entity.from_json(o) for o in entities or []] # Validate arguments against known Juju API types. if entities_ is not None and not isinstance(entities_, (bytes, str, list)): raise Exception( - "Expected entities_ to be a Sequence, received: {}".format( - type(entities_) - ) + f"Expected entities_ to be a Sequence, received: {type(entities_)}" ) self.entities = entities_ @@ -14101,8 +12337,7 @@ class ListSSHKeys(Type): _toPy = {"entities": "entities", "mode": "mode"} def __init__(self, entities=None, mode=None, **unknown_fields): - """ - entities : Entities + """Entities : Entities mode : bool """ entities_ = Entities.from_json(entities) if entities else None @@ -14111,15 +12346,11 @@ def __init__(self, entities=None, mode=None, **unknown_fields): # Validate arguments against known Juju API types. if entities_ is not None and not isinstance(entities_, (dict, Entities)): raise Exception( - "Expected entities_ to be a Entities, received: {}".format( - type(entities_) - ) + f"Expected entities_ to be a Entities, received: {type(entities_)}" ) if mode_ is not None and not isinstance(mode_, bool): - raise Exception( - "Expected mode_ to be a bool, received: {}".format(type(mode_)) - ) + raise Exception(f"Expected mode_ to be a bool, received: {type(mode_)}") self.entities = entities_ self.mode = mode_ @@ -14131,8 +12362,7 @@ class ListSecretBackendsArgs(Type): _toPy = {"names": "names", "reveal": "reveal"} def __init__(self, names=None, reveal=None, **unknown_fields): - """ - names : typing.Sequence[str] + """Names : typing.Sequence[str] reveal : bool """ names_ = names @@ -14141,13 +12371,11 @@ def __init__(self, names=None, reveal=None, **unknown_fields): # Validate arguments against known Juju API types. if names_ is not None and not isinstance(names_, (bytes, str, list)): raise Exception( - "Expected names_ to be a Sequence, received: {}".format(type(names_)) + f"Expected names_ to be a Sequence, received: {type(names_)}" ) if reveal_ is not None and not isinstance(reveal_, bool): - raise Exception( - "Expected reveal_ to be a bool, received: {}".format(type(reveal_)) - ) + raise Exception(f"Expected reveal_ to be a bool, received: {type(reveal_)}") self.names = names_ self.reveal = reveal_ @@ -14159,17 +12387,13 @@ class ListSecretBackendsResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~SecretBackendResult] - """ + """Results : typing.Sequence[~SecretBackendResult]""" results_ = [SecretBackendResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -14231,8 +12455,7 @@ def __init__( version=None, **unknown_fields, ): - """ - access : typing.Sequence[~AccessInfo] + """Access : typing.Sequence[~AccessInfo] create_time : str description : str label : str @@ -14267,103 +12490,79 @@ def __init__( # Validate arguments against known Juju API types. if access_ is not None and not isinstance(access_, (bytes, str, list)): raise Exception( - "Expected access_ to be a Sequence, received: {}".format(type(access_)) + f"Expected access_ to be a Sequence, received: {type(access_)}" ) if create_time_ is not None and not isinstance(create_time_, (bytes, str)): raise Exception( - "Expected create_time_ to be a str, received: {}".format( - type(create_time_) - ) + f"Expected create_time_ to be a str, received: {type(create_time_)}" ) if description_ is not None and not isinstance(description_, (bytes, str)): raise Exception( - "Expected description_ to be a str, received: {}".format( - type(description_) - ) + f"Expected description_ to be a str, received: {type(description_)}" ) if label_ is not None and not isinstance(label_, (bytes, str)): - raise Exception( - "Expected label_ to be a str, received: {}".format(type(label_)) - ) + raise Exception(f"Expected label_ to be a str, received: {type(label_)}") if latest_expire_time_ is not None and not isinstance( latest_expire_time_, (bytes, str) ): raise Exception( - "Expected latest_expire_time_ to be a str, received: {}".format( - type(latest_expire_time_) - ) + f"Expected latest_expire_time_ to be a str, received: {type(latest_expire_time_)}" ) if latest_revision_ is not None and not isinstance(latest_revision_, int): raise Exception( - "Expected latest_revision_ to be a int, received: {}".format( - type(latest_revision_) - ) + f"Expected latest_revision_ to be a int, received: {type(latest_revision_)}" ) if latest_revision_checksum_ is not None and not isinstance( latest_revision_checksum_, (bytes, str) ): raise Exception( - "Expected latest_revision_checksum_ to be a str, received: {}".format( - type(latest_revision_checksum_) - ) + f"Expected latest_revision_checksum_ to be a str, received: {type(latest_revision_checksum_)}" ) if next_rotate_time_ is not None and not isinstance( next_rotate_time_, (bytes, str) ): raise Exception( - "Expected next_rotate_time_ to be a str, received: {}".format( - type(next_rotate_time_) - ) + f"Expected next_rotate_time_ to be a str, received: {type(next_rotate_time_)}" ) if owner_tag_ is not None and not isinstance(owner_tag_, (bytes, str)): raise Exception( - "Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_)) + f"Expected owner_tag_ to be a str, received: {type(owner_tag_)}" ) if revisions_ is not None and not isinstance(revisions_, (bytes, str, list)): raise Exception( - "Expected revisions_ to be a Sequence, received: {}".format( - type(revisions_) - ) + f"Expected revisions_ to be a Sequence, received: {type(revisions_)}" ) if rotate_policy_ is not None and not isinstance(rotate_policy_, (bytes, str)): raise Exception( - "Expected rotate_policy_ to be a str, received: {}".format( - type(rotate_policy_) - ) + f"Expected rotate_policy_ to be a str, received: {type(rotate_policy_)}" ) if update_time_ is not None and not isinstance(update_time_, (bytes, str)): raise Exception( - "Expected update_time_ to be a str, received: {}".format( - type(update_time_) - ) + f"Expected update_time_ to be a str, received: {type(update_time_)}" ) if uri_ is not None and not isinstance(uri_, (bytes, str)): - raise Exception( - "Expected uri_ to be a str, received: {}".format(type(uri_)) - ) + raise Exception(f"Expected uri_ to be a str, received: {type(uri_)}") if value_ is not None and not isinstance(value_, (dict, SecretValueResult)): raise Exception( - "Expected value_ to be a SecretValueResult, received: {}".format( - type(value_) - ) + f"Expected value_ to be a SecretValueResult, received: {type(value_)}" ) if version_ is not None and not isinstance(version_, int): raise Exception( - "Expected version_ to be a int, received: {}".format(type(version_)) + f"Expected version_ to be a int, received: {type(version_)}" ) self.access = access_ @@ -14389,17 +12588,13 @@ class ListSecretResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~ListSecretResult] - """ + """Results : typing.Sequence[~ListSecretResult]""" results_ = [ListSecretResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -14411,8 +12606,7 @@ class ListSecretsArgs(Type): _toPy = {"filter": "filter_", "show-secrets": "show_secrets"} def __init__(self, filter_=None, show_secrets=None, **unknown_fields): - """ - filter_ : SecretsFilter + """filter_ : SecretsFilter show_secrets : bool """ filter__ = SecretsFilter.from_json(filter_) if filter_ else None @@ -14421,16 +12615,12 @@ def __init__(self, filter_=None, show_secrets=None, **unknown_fields): # Validate arguments against known Juju API types. if filter__ is not None and not isinstance(filter__, (dict, SecretsFilter)): raise Exception( - "Expected filter__ to be a SecretsFilter, received: {}".format( - type(filter__) - ) + f"Expected filter__ to be a SecretsFilter, received: {type(filter__)}" ) if show_secrets_ is not None and not isinstance(show_secrets_, bool): raise Exception( - "Expected show_secrets_ to be a bool, received: {}".format( - type(show_secrets_) - ) + f"Expected show_secrets_ to be a bool, received: {type(show_secrets_)}" ) self.filter_ = filter__ @@ -14443,17 +12633,13 @@ class ListSpacesResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~Space] - """ + """Results : typing.Sequence[~Space]""" results_ = [Space.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -14465,17 +12651,13 @@ class ListSubnetsResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~Subnet] - """ + """Results : typing.Sequence[~Subnet]""" results_ = [Subnet.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -14519,8 +12701,7 @@ def __init__( user_data=None, **unknown_fields, ): - """ - auth_tag : str + """auth_tag : str bakery_version : int cli_args : str client_version : str @@ -14543,57 +12724,45 @@ def __init__( # Validate arguments against known Juju API types. if auth_tag_ is not None and not isinstance(auth_tag_, (bytes, str)): raise Exception( - "Expected auth_tag_ to be a str, received: {}".format(type(auth_tag_)) + f"Expected auth_tag_ to be a str, received: {type(auth_tag_)}" ) if bakery_version_ is not None and not isinstance(bakery_version_, int): raise Exception( - "Expected bakery_version_ to be a int, received: {}".format( - type(bakery_version_) - ) + f"Expected bakery_version_ to be a int, received: {type(bakery_version_)}" ) if cli_args_ is not None and not isinstance(cli_args_, (bytes, str)): raise Exception( - "Expected cli_args_ to be a str, received: {}".format(type(cli_args_)) + f"Expected cli_args_ to be a str, received: {type(cli_args_)}" ) if client_version_ is not None and not isinstance( client_version_, (bytes, str) ): raise Exception( - "Expected client_version_ to be a str, received: {}".format( - type(client_version_) - ) + f"Expected client_version_ to be a str, received: {type(client_version_)}" ) if credentials_ is not None and not isinstance(credentials_, (bytes, str)): raise Exception( - "Expected credentials_ to be a str, received: {}".format( - type(credentials_) - ) + f"Expected credentials_ to be a str, received: {type(credentials_)}" ) if macaroons_ is not None and not isinstance(macaroons_, (bytes, str, list)): raise Exception( - "Expected macaroons_ to be a Sequence, received: {}".format( - type(macaroons_) - ) + f"Expected macaroons_ to be a Sequence, received: {type(macaroons_)}" ) if nonce_ is not None and not isinstance(nonce_, (bytes, str)): - raise Exception( - "Expected nonce_ to be a str, received: {}".format(type(nonce_)) - ) + raise Exception(f"Expected nonce_ to be a str, received: {type(nonce_)}") if token_ is not None and not isinstance(token_, (bytes, str)): - raise Exception( - "Expected token_ to be a str, received: {}".format(type(token_)) - ) + raise Exception(f"Expected token_ to be a str, received: {type(token_)}") if user_data_ is not None and not isinstance(user_data_, (bytes, str)): raise Exception( - "Expected user_data_ to be a str, received: {}".format(type(user_data_)) + f"Expected user_data_ to be a str, received: {type(user_data_)}" ) self.auth_tag = auth_tag_ @@ -14648,8 +12817,7 @@ def __init__( user_info=None, **unknown_fields, ): - """ - bakery_discharge_required : Macaroon + """bakery_discharge_required : Macaroon controller_tag : str discharge_required : Macaroon discharge_required_error : str @@ -14682,80 +12850,62 @@ def __init__( bakery_discharge_required_, (dict, Macaroon) ): raise Exception( - "Expected bakery_discharge_required_ to be a Macaroon, received: {}".format( - type(bakery_discharge_required_) - ) + f"Expected bakery_discharge_required_ to be a Macaroon, received: {type(bakery_discharge_required_)}" ) if controller_tag_ is not None and not isinstance( controller_tag_, (bytes, str) ): raise Exception( - "Expected controller_tag_ to be a str, received: {}".format( - type(controller_tag_) - ) + f"Expected controller_tag_ to be a str, received: {type(controller_tag_)}" ) if discharge_required_ is not None and not isinstance( discharge_required_, (dict, Macaroon) ): raise Exception( - "Expected discharge_required_ to be a Macaroon, received: {}".format( - type(discharge_required_) - ) + f"Expected discharge_required_ to be a Macaroon, received: {type(discharge_required_)}" ) if discharge_required_error_ is not None and not isinstance( discharge_required_error_, (bytes, str) ): raise Exception( - "Expected discharge_required_error_ to be a str, received: {}".format( - type(discharge_required_error_) - ) + f"Expected discharge_required_error_ to be a str, received: {type(discharge_required_error_)}" ) if facades_ is not None and not isinstance(facades_, (bytes, str, list)): raise Exception( - "Expected facades_ to be a Sequence, received: {}".format( - type(facades_) - ) + f"Expected facades_ to be a Sequence, received: {type(facades_)}" ) if model_tag_ is not None and not isinstance(model_tag_, (bytes, str)): raise Exception( - "Expected model_tag_ to be a str, received: {}".format(type(model_tag_)) + f"Expected model_tag_ to be a str, received: {type(model_tag_)}" ) if public_dns_name_ is not None and not isinstance( public_dns_name_, (bytes, str) ): raise Exception( - "Expected public_dns_name_ to be a str, received: {}".format( - type(public_dns_name_) - ) + f"Expected public_dns_name_ to be a str, received: {type(public_dns_name_)}" ) if server_version_ is not None and not isinstance( server_version_, (bytes, str) ): raise Exception( - "Expected server_version_ to be a str, received: {}".format( - type(server_version_) - ) + f"Expected server_version_ to be a str, received: {type(server_version_)}" ) if servers_ is not None and not isinstance(servers_, (bytes, str, list)): raise Exception( - "Expected servers_ to be a Sequence, received: {}".format( - type(servers_) - ) + f"Expected servers_ to be a Sequence, received: {type(servers_)}" ) if user_info_ is not None and not isinstance(user_info_, (dict, AuthUserInfo)): raise Exception( - "Expected user_info_ to be a AuthUserInfo, received: {}".format( - type(user_info_) - ) + f"Expected user_info_ to be a AuthUserInfo, received: {type(user_info_)}" ) self.bakery_discharge_required = bakery_discharge_required_ @@ -14814,8 +12964,7 @@ def __init__( virt_type=None, **unknown_fields, ): - """ - arch : str + """Arch : str availability_zone : str cores : int cpu_power : int @@ -14835,47 +12984,37 @@ def __init__( # Validate arguments against known Juju API types. if arch_ is not None and not isinstance(arch_, (bytes, str)): - raise Exception( - "Expected arch_ to be a str, received: {}".format(type(arch_)) - ) + raise Exception(f"Expected arch_ to be a str, received: {type(arch_)}") if availability_zone_ is not None and not isinstance( availability_zone_, (bytes, str) ): raise Exception( - "Expected availability_zone_ to be a str, received: {}".format( - type(availability_zone_) - ) + f"Expected availability_zone_ to be a str, received: {type(availability_zone_)}" ) if cores_ is not None and not isinstance(cores_, int): - raise Exception( - "Expected cores_ to be a int, received: {}".format(type(cores_)) - ) + raise Exception(f"Expected cores_ to be a int, received: {type(cores_)}") if cpu_power_ is not None and not isinstance(cpu_power_, int): raise Exception( - "Expected cpu_power_ to be a int, received: {}".format(type(cpu_power_)) + f"Expected cpu_power_ to be a int, received: {type(cpu_power_)}" ) if mem_ is not None and not isinstance(mem_, int): - raise Exception( - "Expected mem_ to be a int, received: {}".format(type(mem_)) - ) + raise Exception(f"Expected mem_ to be a int, received: {type(mem_)}") if root_disk_ is not None and not isinstance(root_disk_, int): raise Exception( - "Expected root_disk_ to be a int, received: {}".format(type(root_disk_)) + f"Expected root_disk_ to be a int, received: {type(root_disk_)}" ) if tags_ is not None and not isinstance(tags_, (bytes, str, list)): - raise Exception( - "Expected tags_ to be a Sequence, received: {}".format(type(tags_)) - ) + raise Exception(f"Expected tags_ to be a Sequence, received: {type(tags_)}") if virt_type_ is not None and not isinstance(virt_type_, (bytes, str)): raise Exception( - "Expected virt_type_ to be a str, received: {}".format(type(virt_type_)) + f"Expected virt_type_ to be a str, received: {type(virt_type_)}" ) self.arch = arch_ @@ -14956,8 +13095,7 @@ def __init__( wants_vote=None, **unknown_fields, ): - """ - agent_status : DetailedStatus + """agent_status : DetailedStatus base : Base constraints : str containers : typing.Mapping[str, ~MachineStatus] @@ -15015,131 +13153,101 @@ def __init__( agent_status_, (dict, DetailedStatus) ): raise Exception( - "Expected agent_status_ to be a DetailedStatus, received: {}".format( - type(agent_status_) - ) + f"Expected agent_status_ to be a DetailedStatus, received: {type(agent_status_)}" ) if base_ is not None and not isinstance(base_, (dict, Base)): - raise Exception( - "Expected base_ to be a Base, received: {}".format(type(base_)) - ) + raise Exception(f"Expected base_ to be a Base, received: {type(base_)}") if constraints_ is not None and not isinstance(constraints_, (bytes, str)): raise Exception( - "Expected constraints_ to be a str, received: {}".format( - type(constraints_) - ) + f"Expected constraints_ to be a str, received: {type(constraints_)}" ) if containers_ is not None and not isinstance(containers_, dict): raise Exception( - "Expected containers_ to be a Mapping, received: {}".format( - type(containers_) - ) + f"Expected containers_ to be a Mapping, received: {type(containers_)}" ) if display_name_ is not None and not isinstance(display_name_, (bytes, str)): raise Exception( - "Expected display_name_ to be a str, received: {}".format( - type(display_name_) - ) + f"Expected display_name_ to be a str, received: {type(display_name_)}" ) if dns_name_ is not None and not isinstance(dns_name_, (bytes, str)): raise Exception( - "Expected dns_name_ to be a str, received: {}".format(type(dns_name_)) + f"Expected dns_name_ to be a str, received: {type(dns_name_)}" ) if hardware_ is not None and not isinstance(hardware_, (bytes, str)): raise Exception( - "Expected hardware_ to be a str, received: {}".format(type(hardware_)) + f"Expected hardware_ to be a str, received: {type(hardware_)}" ) if has_vote_ is not None and not isinstance(has_vote_, bool): raise Exception( - "Expected has_vote_ to be a bool, received: {}".format(type(has_vote_)) + f"Expected has_vote_ to be a bool, received: {type(has_vote_)}" ) if hostname_ is not None and not isinstance(hostname_, (bytes, str)): raise Exception( - "Expected hostname_ to be a str, received: {}".format(type(hostname_)) + f"Expected hostname_ to be a str, received: {type(hostname_)}" ) if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception( - "Expected id__ to be a str, received: {}".format(type(id__)) - ) + raise Exception(f"Expected id__ to be a str, received: {type(id__)}") if instance_id_ is not None and not isinstance(instance_id_, (bytes, str)): raise Exception( - "Expected instance_id_ to be a str, received: {}".format( - type(instance_id_) - ) + f"Expected instance_id_ to be a str, received: {type(instance_id_)}" ) if instance_status_ is not None and not isinstance( instance_status_, (dict, DetailedStatus) ): raise Exception( - "Expected instance_status_ to be a DetailedStatus, received: {}".format( - type(instance_status_) - ) + f"Expected instance_status_ to be a DetailedStatus, received: {type(instance_status_)}" ) if ip_addresses_ is not None and not isinstance( ip_addresses_, (bytes, str, list) ): raise Exception( - "Expected ip_addresses_ to be a Sequence, received: {}".format( - type(ip_addresses_) - ) + f"Expected ip_addresses_ to be a Sequence, received: {type(ip_addresses_)}" ) if jobs_ is not None and not isinstance(jobs_, (bytes, str, list)): - raise Exception( - "Expected jobs_ to be a Sequence, received: {}".format(type(jobs_)) - ) + raise Exception(f"Expected jobs_ to be a Sequence, received: {type(jobs_)}") if lxd_profiles_ is not None and not isinstance(lxd_profiles_, dict): raise Exception( - "Expected lxd_profiles_ to be a Mapping, received: {}".format( - type(lxd_profiles_) - ) + f"Expected lxd_profiles_ to be a Mapping, received: {type(lxd_profiles_)}" ) if modification_status_ is not None and not isinstance( modification_status_, (dict, DetailedStatus) ): raise Exception( - "Expected modification_status_ to be a DetailedStatus, received: {}".format( - type(modification_status_) - ) + f"Expected modification_status_ to be a DetailedStatus, received: {type(modification_status_)}" ) if network_interfaces_ is not None and not isinstance( network_interfaces_, dict ): raise Exception( - "Expected network_interfaces_ to be a Mapping, received: {}".format( - type(network_interfaces_) - ) + f"Expected network_interfaces_ to be a Mapping, received: {type(network_interfaces_)}" ) if primary_controller_machine_ is not None and not isinstance( primary_controller_machine_, bool ): raise Exception( - "Expected primary_controller_machine_ to be a bool, received: {}".format( - type(primary_controller_machine_) - ) + f"Expected primary_controller_machine_ to be a bool, received: {type(primary_controller_machine_)}" ) if wants_vote_ is not None and not isinstance(wants_vote_, bool): raise Exception( - "Expected wants_vote_ to be a bool, received: {}".format( - type(wants_vote_) - ) + f"Expected wants_vote_ to be a bool, received: {type(wants_vote_)}" ) self.agent_status = agent_status_ @@ -15169,8 +13277,7 @@ class MapResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : typing.Mapping[str, typing.Any] """ error_ = Error.from_json(error) if error else None @@ -15178,13 +13285,11 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance(result_, dict): raise Exception( - "Expected result_ to be a Mapping, received: {}".format(type(result_)) + f"Expected result_ to be a Mapping, received: {type(result_)}" ) self.error = error_ @@ -15197,17 +13302,13 @@ class MapResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~MapResult] - """ + """Results : typing.Sequence[~MapResult]""" results_ = [MapResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -15219,17 +13320,13 @@ class MetadataImageIds(Type): _toPy = {"image-ids": "image_ids"} def __init__(self, image_ids=None, **unknown_fields): - """ - image_ids : typing.Sequence[str] - """ + """image_ids : typing.Sequence[str]""" image_ids_ = image_ids # Validate arguments against known Juju API types. if image_ids_ is not None and not isinstance(image_ids_, (bytes, str, list)): raise Exception( - "Expected image_ids_ to be a Sequence, received: {}".format( - type(image_ids_) - ) + f"Expected image_ids_ to be a Sequence, received: {type(image_ids_)}" ) self.image_ids = image_ids_ @@ -15241,17 +13338,13 @@ class MetadataSaveParams(Type): _toPy = {"metadata": "metadata"} def __init__(self, metadata=None, **unknown_fields): - """ - metadata : typing.Sequence[~CloudImageMetadataList] - """ + """Metadata : typing.Sequence[~CloudImageMetadataList]""" metadata_ = [CloudImageMetadataList.from_json(o) for o in metadata or []] # Validate arguments against known Juju API types. if metadata_ is not None and not isinstance(metadata_, (bytes, str, list)): raise Exception( - "Expected metadata_ to be a Sequence, received: {}".format( - type(metadata_) - ) + f"Expected metadata_ to be a Sequence, received: {type(metadata_)}" ) self.metadata = metadata_ @@ -15263,8 +13356,7 @@ class MeterStatus(Type): _toPy = {"color": "color", "message": "message"} def __init__(self, color=None, message=None, **unknown_fields): - """ - color : str + """Color : str message : str """ color_ = color @@ -15272,13 +13364,11 @@ def __init__(self, color=None, message=None, **unknown_fields): # Validate arguments against known Juju API types. if color_ is not None and not isinstance(color_, (bytes, str)): - raise Exception( - "Expected color_ to be a str, received: {}".format(type(color_)) - ) + raise Exception(f"Expected color_ to be a str, received: {type(color_)}") if message_ is not None and not isinstance(message_, (bytes, str)): raise Exception( - "Expected message_ to be a str, received: {}".format(type(message_)) + f"Expected message_ to be a str, received: {type(message_)}" ) self.color = color_ @@ -15291,8 +13381,7 @@ class MeterStatusParam(Type): _toPy = {"code": "code", "info": "info", "tag": "tag"} def __init__(self, code=None, info=None, tag=None, **unknown_fields): - """ - code : str + """Code : str info : str tag : str """ @@ -15302,19 +13391,13 @@ def __init__(self, code=None, info=None, tag=None, **unknown_fields): # Validate arguments against known Juju API types. if code_ is not None and not isinstance(code_, (bytes, str)): - raise Exception( - "Expected code_ to be a str, received: {}".format(type(code_)) - ) + raise Exception(f"Expected code_ to be a str, received: {type(code_)}") if info_ is not None and not isinstance(info_, (bytes, str)): - raise Exception( - "Expected info_ to be a str, received: {}".format(type(info_)) - ) + raise Exception(f"Expected info_ to be a str, received: {type(info_)}") if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception( - "Expected tag_ to be a str, received: {}".format(type(tag_)) - ) + raise Exception(f"Expected tag_ to be a str, received: {type(tag_)}") self.code = code_ self.info = info_ @@ -15327,17 +13410,13 @@ class MeterStatusParams(Type): _toPy = {"statues": "statues"} def __init__(self, statues=None, **unknown_fields): - """ - statues : typing.Sequence[~MeterStatusParam] - """ + """Statues : typing.Sequence[~MeterStatusParam]""" statues_ = [MeterStatusParam.from_json(o) for o in statues or []] # Validate arguments against known Juju API types. if statues_ is not None and not isinstance(statues_, (bytes, str, list)): raise Exception( - "Expected statues_ to be a Sequence, received: {}".format( - type(statues_) - ) + f"Expected statues_ to be a Sequence, received: {type(statues_)}" ) self.statues = statues_ @@ -15363,8 +13442,7 @@ class MetricResult(Type): def __init__( self, key=None, labels=None, time=None, unit=None, value=None, **unknown_fields ): - """ - key : str + """Key : str labels : typing.Mapping[str, str] time : str unit : str @@ -15378,29 +13456,21 @@ def __init__( # Validate arguments against known Juju API types. if key_ is not None and not isinstance(key_, (bytes, str)): - raise Exception( - "Expected key_ to be a str, received: {}".format(type(key_)) - ) + raise Exception(f"Expected key_ to be a str, received: {type(key_)}") if labels_ is not None and not isinstance(labels_, dict): raise Exception( - "Expected labels_ to be a Mapping, received: {}".format(type(labels_)) + f"Expected labels_ to be a Mapping, received: {type(labels_)}" ) if time_ is not None and not isinstance(time_, (bytes, str)): - raise Exception( - "Expected time_ to be a str, received: {}".format(type(time_)) - ) + raise Exception(f"Expected time_ to be a str, received: {type(time_)}") if unit_ is not None and not isinstance(unit_, (bytes, str)): - raise Exception( - "Expected unit_ to be a str, received: {}".format(type(unit_)) - ) + raise Exception(f"Expected unit_ to be a str, received: {type(unit_)}") if value_ is not None and not isinstance(value_, (bytes, str)): - raise Exception( - "Expected value_ to be a str, received: {}".format(type(value_)) - ) + raise Exception(f"Expected value_ to be a str, received: {type(value_)}") self.key = key_ self.labels = labels_ @@ -15415,17 +13485,13 @@ class MetricResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~EntityMetrics] - """ + """Results : typing.Sequence[~EntityMetrics]""" results_ = [EntityMetrics.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -15437,8 +13503,7 @@ class MigrationSpec(Type): _toPy = {"model-tag": "model_tag", "target-info": "target_info"} def __init__(self, model_tag=None, target_info=None, **unknown_fields): - """ - model_tag : str + """model_tag : str target_info : MigrationTargetInfo """ model_tag_ = model_tag @@ -15449,16 +13514,14 @@ def __init__(self, model_tag=None, target_info=None, **unknown_fields): # Validate arguments against known Juju API types. if model_tag_ is not None and not isinstance(model_tag_, (bytes, str)): raise Exception( - "Expected model_tag_ to be a str, received: {}".format(type(model_tag_)) + f"Expected model_tag_ to be a str, received: {type(model_tag_)}" ) if target_info_ is not None and not isinstance( target_info_, (dict, MigrationTargetInfo) ): raise Exception( - "Expected target_info_ to be a MigrationTargetInfo, received: {}".format( - type(target_info_) - ) + f"Expected target_info_ to be a MigrationTargetInfo, received: {type(target_info_)}" ) self.model_tag = model_tag_ @@ -15497,8 +13560,7 @@ def __init__( password=None, **unknown_fields, ): - """ - addrs : typing.Sequence[str] + """Addrs : typing.Sequence[str] auth_tag : str ca_cert : str controller_alias : str @@ -15517,45 +13579,41 @@ def __init__( # Validate arguments against known Juju API types. if addrs_ is not None and not isinstance(addrs_, (bytes, str, list)): raise Exception( - "Expected addrs_ to be a Sequence, received: {}".format(type(addrs_)) + f"Expected addrs_ to be a Sequence, received: {type(addrs_)}" ) if auth_tag_ is not None and not isinstance(auth_tag_, (bytes, str)): raise Exception( - "Expected auth_tag_ to be a str, received: {}".format(type(auth_tag_)) + f"Expected auth_tag_ to be a str, received: {type(auth_tag_)}" ) if ca_cert_ is not None and not isinstance(ca_cert_, (bytes, str)): raise Exception( - "Expected ca_cert_ to be a str, received: {}".format(type(ca_cert_)) + f"Expected ca_cert_ to be a str, received: {type(ca_cert_)}" ) if controller_alias_ is not None and not isinstance( controller_alias_, (bytes, str) ): raise Exception( - "Expected controller_alias_ to be a str, received: {}".format( - type(controller_alias_) - ) + f"Expected controller_alias_ to be a str, received: {type(controller_alias_)}" ) if controller_tag_ is not None and not isinstance( controller_tag_, (bytes, str) ): raise Exception( - "Expected controller_tag_ to be a str, received: {}".format( - type(controller_tag_) - ) + f"Expected controller_tag_ to be a str, received: {type(controller_tag_)}" ) if macaroons_ is not None and not isinstance(macaroons_, (bytes, str)): raise Exception( - "Expected macaroons_ to be a str, received: {}".format(type(macaroons_)) + f"Expected macaroons_ to be a str, received: {type(macaroons_)}" ) if password_ is not None and not isinstance(password_, (bytes, str)): raise Exception( - "Expected password_ to be a str, received: {}".format(type(password_)) + f"Expected password_ to be a str, received: {type(password_)}" ) self.addrs = addrs_ @@ -15580,8 +13638,7 @@ class Model(Type): def __init__( self, name=None, owner_tag=None, type_=None, uuid=None, **unknown_fields ): - """ - name : str + """Name : str owner_tag : str type_ : str uuid : str @@ -15593,24 +13650,18 @@ def __init__( # Validate arguments against known Juju API types. if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if owner_tag_ is not None and not isinstance(owner_tag_, (bytes, str)): raise Exception( - "Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_)) + f"Expected owner_tag_ to be a str, received: {type(owner_tag_)}" ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") if uuid_ is not None and not isinstance(uuid_, (bytes, str)): - raise Exception( - "Expected uuid_ to be a str, received: {}".format(type(uuid_)) - ) + raise Exception(f"Expected uuid_ to be a str, received: {type(uuid_)}") self.name = name_ self.owner_tag = owner_tag_ @@ -15624,8 +13675,7 @@ class ModelAccess(Type): _toPy = {"access": "access", "model": "model"} def __init__(self, access=None, model=None, **unknown_fields): - """ - access : str + """Access : str model : str """ access_ = access @@ -15633,14 +13683,10 @@ def __init__(self, access=None, model=None, **unknown_fields): # Validate arguments against known Juju API types. if access_ is not None and not isinstance(access_, (bytes, str)): - raise Exception( - "Expected access_ to be a str, received: {}".format(type(access_)) - ) + raise Exception(f"Expected access_ to be a str, received: {type(access_)}") if model_ is not None and not isinstance(model_, (bytes, str)): - raise Exception( - "Expected model_ to be a str, received: {}".format(type(model_)) - ) + raise Exception(f"Expected model_ to be a str, received: {type(model_)}") self.access = access_ self.model = model_ @@ -15652,16 +13698,12 @@ class ModelApplicationInfo(Type): _toPy = {"name": "name"} def __init__(self, name=None, **unknown_fields): - """ - name : str - """ + """Name : str""" name_ = name # Validate arguments against known Juju API types. if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") self.name = name_ self.unknown_fields = unknown_fields @@ -15684,8 +13726,7 @@ class ModelBlockInfo(Type): def __init__( self, blocks=None, model_uuid=None, name=None, owner_tag=None, **unknown_fields ): - """ - blocks : typing.Sequence[str] + """Blocks : typing.Sequence[str] model_uuid : str name : str owner_tag : str @@ -15698,24 +13739,20 @@ def __init__( # Validate arguments against known Juju API types. if blocks_ is not None and not isinstance(blocks_, (bytes, str, list)): raise Exception( - "Expected blocks_ to be a Sequence, received: {}".format(type(blocks_)) + f"Expected blocks_ to be a Sequence, received: {type(blocks_)}" ) if model_uuid_ is not None and not isinstance(model_uuid_, (bytes, str)): raise Exception( - "Expected model_uuid_ to be a str, received: {}".format( - type(model_uuid_) - ) + f"Expected model_uuid_ to be a str, received: {type(model_uuid_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if owner_tag_ is not None and not isinstance(owner_tag_, (bytes, str)): raise Exception( - "Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_)) + f"Expected owner_tag_ to be a str, received: {type(owner_tag_)}" ) self.blocks = blocks_ @@ -15730,15 +13767,13 @@ class ModelBlockInfoList(Type): _toPy = {"models": "models"} def __init__(self, models=None, **unknown_fields): - """ - models : typing.Sequence[~ModelBlockInfo] - """ + """Models : typing.Sequence[~ModelBlockInfo]""" models_ = [ModelBlockInfo.from_json(o) for o in models or []] # Validate arguments against known Juju API types. if models_ is not None and not isinstance(models_, (bytes, str, list)): raise Exception( - "Expected models_ to be a Sequence, received: {}".format(type(models_)) + f"Expected models_ to be a Sequence, received: {type(models_)}" ) self.models = models_ @@ -15750,15 +13785,13 @@ class ModelConfigResults(Type): _toPy = {"config": "config"} def __init__(self, config=None, **unknown_fields): - """ - config : typing.Mapping[str, ~ConfigValue] - """ + """Config : typing.Mapping[str, ~ConfigValue]""" config_ = {k: ConfigValue.from_json(v) for k, v in (config or dict()).items()} # Validate arguments against known Juju API types. if config_ is not None and not isinstance(config_, dict): raise Exception( - "Expected config_ to be a Mapping, received: {}".format(type(config_)) + f"Expected config_ to be a Mapping, received: {type(config_)}" ) self.config = config_ @@ -15793,8 +13826,7 @@ def __init__( region=None, **unknown_fields, ): - """ - cloud_tag : str + """cloud_tag : str config : typing.Mapping[str, typing.Any] credential : str name : str @@ -15811,35 +13843,29 @@ def __init__( # Validate arguments against known Juju API types. if cloud_tag_ is not None and not isinstance(cloud_tag_, (bytes, str)): raise Exception( - "Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_)) + f"Expected cloud_tag_ to be a str, received: {type(cloud_tag_)}" ) if config_ is not None and not isinstance(config_, dict): raise Exception( - "Expected config_ to be a Mapping, received: {}".format(type(config_)) + f"Expected config_ to be a Mapping, received: {type(config_)}" ) if credential_ is not None and not isinstance(credential_, (bytes, str)): raise Exception( - "Expected credential_ to be a str, received: {}".format( - type(credential_) - ) + f"Expected credential_ to be a str, received: {type(credential_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if owner_tag_ is not None and not isinstance(owner_tag_, (bytes, str)): raise Exception( - "Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_)) + f"Expected owner_tag_ to be a str, received: {type(owner_tag_)}" ) if region_ is not None and not isinstance(region_, (bytes, str)): - raise Exception( - "Expected region_ to be a str, received: {}".format(type(region_)) - ) + raise Exception(f"Expected region_ to be a str, received: {type(region_)}") self.cloud_tag = cloud_tag_ self.config = config_ @@ -15865,8 +13891,7 @@ class ModelDefaultValues(Type): def __init__( self, cloud_region=None, cloud_tag=None, config=None, **unknown_fields ): - """ - cloud_region : str + """cloud_region : str cloud_tag : str config : typing.Mapping[str, typing.Any] """ @@ -15877,19 +13902,17 @@ def __init__( # Validate arguments against known Juju API types. if cloud_region_ is not None and not isinstance(cloud_region_, (bytes, str)): raise Exception( - "Expected cloud_region_ to be a str, received: {}".format( - type(cloud_region_) - ) + f"Expected cloud_region_ to be a str, received: {type(cloud_region_)}" ) if cloud_tag_ is not None and not isinstance(cloud_tag_, (bytes, str)): raise Exception( - "Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_)) + f"Expected cloud_tag_ to be a str, received: {type(cloud_tag_)}" ) if config_ is not None and not isinstance(config_, dict): raise Exception( - "Expected config_ to be a Mapping, received: {}".format(type(config_)) + f"Expected config_ to be a Mapping, received: {type(config_)}" ) self.cloud_region = cloud_region_ @@ -15903,8 +13926,7 @@ class ModelDefaults(Type): _toPy = {"controller": "controller", "default": "default", "regions": "regions"} def __init__(self, controller=None, default=None, regions=None, **unknown_fields): - """ - controller : Any + """Controller : Any default : Any regions : typing.Sequence[~RegionDefaults] """ @@ -15915,9 +13937,7 @@ def __init__(self, controller=None, default=None, regions=None, **unknown_fields # Validate arguments against known Juju API types. if regions_ is not None and not isinstance(regions_, (bytes, str, list)): raise Exception( - "Expected regions_ to be a Sequence, received: {}".format( - type(regions_) - ) + f"Expected regions_ to be a Sequence, received: {type(regions_)}" ) self.controller = controller_ @@ -15931,8 +13951,7 @@ class ModelDefaultsResult(Type): _toPy = {"config": "config", "error": "error"} def __init__(self, config=None, error=None, **unknown_fields): - """ - config : typing.Mapping[str, ~ModelDefaults] + """Config : typing.Mapping[str, ~ModelDefaults] error : Error """ config_ = {k: ModelDefaults.from_json(v) for k, v in (config or dict()).items()} @@ -15941,13 +13960,11 @@ def __init__(self, config=None, error=None, **unknown_fields): # Validate arguments against known Juju API types. if config_ is not None and not isinstance(config_, dict): raise Exception( - "Expected config_ to be a Mapping, received: {}".format(type(config_)) + f"Expected config_ to be a Mapping, received: {type(config_)}" ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") self.config = config_ self.error = error_ @@ -15959,17 +13976,13 @@ class ModelDefaultsResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~ModelDefaultsResult] - """ + """Results : typing.Sequence[~ModelDefaultsResult]""" results_ = [ModelDefaultsResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -15981,8 +13994,7 @@ class ModelEntityCount(Type): _toPy = {"count": "count", "entity": "entity"} def __init__(self, count=None, entity=None, **unknown_fields): - """ - count : int + """Count : int entity : str """ count_ = count @@ -15990,14 +14002,10 @@ def __init__(self, count=None, entity=None, **unknown_fields): # Validate arguments against known Juju API types. if count_ is not None and not isinstance(count_, int): - raise Exception( - "Expected count_ to be a int, received: {}".format(type(count_)) - ) + raise Exception(f"Expected count_ to be a int, received: {type(count_)}") if entity_ is not None and not isinstance(entity_, (bytes, str)): - raise Exception( - "Expected entity_ to be a str, received: {}".format(type(entity_)) - ) + raise Exception(f"Expected entity_ to be a str, received: {type(entity_)}") self.count = count_ self.entity = entity_ @@ -16029,8 +14037,7 @@ def __init__( status=None, **unknown_fields, ): - """ - detachable : bool + """Detachable : bool id_ : str message : str provider_id : str @@ -16045,32 +14052,24 @@ def __init__( # Validate arguments against known Juju API types. if detachable_ is not None and not isinstance(detachable_, bool): raise Exception( - "Expected detachable_ to be a bool, received: {}".format( - type(detachable_) - ) + f"Expected detachable_ to be a bool, received: {type(detachable_)}" ) if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception( - "Expected id__ to be a str, received: {}".format(type(id__)) - ) + raise Exception(f"Expected id__ to be a str, received: {type(id__)}") if message_ is not None and not isinstance(message_, (bytes, str)): raise Exception( - "Expected message_ to be a str, received: {}".format(type(message_)) + f"Expected message_ to be a str, received: {type(message_)}" ) if provider_id_ is not None and not isinstance(provider_id_, (bytes, str)): raise Exception( - "Expected provider_id_ to be a str, received: {}".format( - type(provider_id_) - ) + f"Expected provider_id_ to be a str, received: {type(provider_id_)}" ) if status_ is not None and not isinstance(status_, (bytes, str)): - raise Exception( - "Expected status_ to be a str, received: {}".format(type(status_)) - ) + raise Exception(f"Expected status_ to be a str, received: {type(status_)}") self.detachable = detachable_ self.id_ = id__ @@ -16156,8 +14155,7 @@ def __init__( uuid=None, **unknown_fields, ): - """ - agent_version : Number + """agent_version : Number cloud_credential_tag : str cloud_credential_validity : bool cloud_region : str @@ -16212,155 +14210,119 @@ def __init__( agent_version_, (dict, Number) ): raise Exception( - "Expected agent_version_ to be a Number, received: {}".format( - type(agent_version_) - ) + f"Expected agent_version_ to be a Number, received: {type(agent_version_)}" ) if cloud_credential_tag_ is not None and not isinstance( cloud_credential_tag_, (bytes, str) ): raise Exception( - "Expected cloud_credential_tag_ to be a str, received: {}".format( - type(cloud_credential_tag_) - ) + f"Expected cloud_credential_tag_ to be a str, received: {type(cloud_credential_tag_)}" ) if cloud_credential_validity_ is not None and not isinstance( cloud_credential_validity_, bool ): raise Exception( - "Expected cloud_credential_validity_ to be a bool, received: {}".format( - type(cloud_credential_validity_) - ) + f"Expected cloud_credential_validity_ to be a bool, received: {type(cloud_credential_validity_)}" ) if cloud_region_ is not None and not isinstance(cloud_region_, (bytes, str)): raise Exception( - "Expected cloud_region_ to be a str, received: {}".format( - type(cloud_region_) - ) + f"Expected cloud_region_ to be a str, received: {type(cloud_region_)}" ) if cloud_tag_ is not None and not isinstance(cloud_tag_, (bytes, str)): raise Exception( - "Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_)) + f"Expected cloud_tag_ to be a str, received: {type(cloud_tag_)}" ) if controller_uuid_ is not None and not isinstance( controller_uuid_, (bytes, str) ): raise Exception( - "Expected controller_uuid_ to be a str, received: {}".format( - type(controller_uuid_) - ) + f"Expected controller_uuid_ to be a str, received: {type(controller_uuid_)}" ) if default_base_ is not None and not isinstance(default_base_, (bytes, str)): raise Exception( - "Expected default_base_ to be a str, received: {}".format( - type(default_base_) - ) + f"Expected default_base_ to be a str, received: {type(default_base_)}" ) if default_series_ is not None and not isinstance( default_series_, (bytes, str) ): raise Exception( - "Expected default_series_ to be a str, received: {}".format( - type(default_series_) - ) + f"Expected default_series_ to be a str, received: {type(default_series_)}" ) if is_controller_ is not None and not isinstance(is_controller_, bool): raise Exception( - "Expected is_controller_ to be a bool, received: {}".format( - type(is_controller_) - ) + f"Expected is_controller_ to be a bool, received: {type(is_controller_)}" ) if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception( - "Expected life_ to be a str, received: {}".format(type(life_)) - ) + raise Exception(f"Expected life_ to be a str, received: {type(life_)}") if machines_ is not None and not isinstance(machines_, (bytes, str, list)): raise Exception( - "Expected machines_ to be a Sequence, received: {}".format( - type(machines_) - ) + f"Expected machines_ to be a Sequence, received: {type(machines_)}" ) if migration_ is not None and not isinstance( migration_, (dict, ModelMigrationStatus) ): raise Exception( - "Expected migration_ to be a ModelMigrationStatus, received: {}".format( - type(migration_) - ) + f"Expected migration_ to be a ModelMigrationStatus, received: {type(migration_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if owner_tag_ is not None and not isinstance(owner_tag_, (bytes, str)): raise Exception( - "Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_)) + f"Expected owner_tag_ to be a str, received: {type(owner_tag_)}" ) if provider_type_ is not None and not isinstance(provider_type_, (bytes, str)): raise Exception( - "Expected provider_type_ to be a str, received: {}".format( - type(provider_type_) - ) + f"Expected provider_type_ to be a str, received: {type(provider_type_)}" ) if secret_backends_ is not None and not isinstance( secret_backends_, (bytes, str, list) ): raise Exception( - "Expected secret_backends_ to be a Sequence, received: {}".format( - type(secret_backends_) - ) + f"Expected secret_backends_ to be a Sequence, received: {type(secret_backends_)}" ) if sla_ is not None and not isinstance(sla_, (dict, ModelSLAInfo)): raise Exception( - "Expected sla_ to be a ModelSLAInfo, received: {}".format(type(sla_)) + f"Expected sla_ to be a ModelSLAInfo, received: {type(sla_)}" ) if status_ is not None and not isinstance(status_, (dict, EntityStatus)): raise Exception( - "Expected status_ to be a EntityStatus, received: {}".format( - type(status_) - ) + f"Expected status_ to be a EntityStatus, received: {type(status_)}" ) if supported_features_ is not None and not isinstance( supported_features_, (bytes, str, list) ): raise Exception( - "Expected supported_features_ to be a Sequence, received: {}".format( - type(supported_features_) - ) + f"Expected supported_features_ to be a Sequence, received: {type(supported_features_)}" ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") if users_ is not None and not isinstance(users_, (bytes, str, list)): raise Exception( - "Expected users_ to be a Sequence, received: {}".format(type(users_)) + f"Expected users_ to be a Sequence, received: {type(users_)}" ) if uuid_ is not None and not isinstance(uuid_, (bytes, str)): - raise Exception( - "Expected uuid_ to be a str, received: {}".format(type(uuid_)) - ) + raise Exception(f"Expected uuid_ to be a str, received: {type(uuid_)}") self.agent_version = agent_version_ self.cloud_credential_tag = cloud_credential_tag_ @@ -16392,8 +14354,7 @@ class ModelInfoResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : ModelInfo """ error_ = Error.from_json(error) if error else None @@ -16401,13 +14362,11 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance(result_, (dict, ModelInfo)): raise Exception( - "Expected result_ to be a ModelInfo, received: {}".format(type(result_)) + f"Expected result_ to be a ModelInfo, received: {type(result_)}" ) self.error = error_ @@ -16420,17 +14379,13 @@ class ModelInfoResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~ModelInfoResult] - """ + """Results : typing.Sequence[~ModelInfoResult]""" results_ = [ModelInfoResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -16442,16 +14397,12 @@ class ModelInstanceTypesConstraint(Type): _toPy = {"value": "value"} def __init__(self, value=None, **unknown_fields): - """ - value : Value - """ + """Value : Value""" value_ = Value.from_json(value) if value else None # Validate arguments against known Juju API types. if value_ is not None and not isinstance(value_, (dict, Value)): - raise Exception( - "Expected value_ to be a Value, received: {}".format(type(value_)) - ) + raise Exception(f"Expected value_ to be a Value, received: {type(value_)}") self.value = value_ self.unknown_fields = unknown_fields @@ -16462,9 +14413,7 @@ class ModelInstanceTypesConstraints(Type): _toPy = {"constraints": "constraints"} def __init__(self, constraints=None, **unknown_fields): - """ - constraints : typing.Sequence[~ModelInstanceTypesConstraint] - """ + """Constraints : typing.Sequence[~ModelInstanceTypesConstraint]""" constraints_ = [ ModelInstanceTypesConstraint.from_json(o) for o in constraints or [] ] @@ -16474,9 +14423,7 @@ def __init__(self, constraints=None, **unknown_fields): constraints_, (bytes, str, list) ): raise Exception( - "Expected constraints_ to be a Sequence, received: {}".format( - type(constraints_) - ) + f"Expected constraints_ to be a Sequence, received: {type(constraints_)}" ) self.constraints = constraints_ @@ -16520,8 +14467,7 @@ def __init__( wants_vote=None, **unknown_fields, ): - """ - display_name : str + """display_name : str ha_primary : bool hardware : MachineHardware has_vote : bool @@ -16544,57 +14490,43 @@ def __init__( # Validate arguments against known Juju API types. if display_name_ is not None and not isinstance(display_name_, (bytes, str)): raise Exception( - "Expected display_name_ to be a str, received: {}".format( - type(display_name_) - ) + f"Expected display_name_ to be a str, received: {type(display_name_)}" ) if ha_primary_ is not None and not isinstance(ha_primary_, bool): raise Exception( - "Expected ha_primary_ to be a bool, received: {}".format( - type(ha_primary_) - ) + f"Expected ha_primary_ to be a bool, received: {type(ha_primary_)}" ) if hardware_ is not None and not isinstance(hardware_, (dict, MachineHardware)): raise Exception( - "Expected hardware_ to be a MachineHardware, received: {}".format( - type(hardware_) - ) + f"Expected hardware_ to be a MachineHardware, received: {type(hardware_)}" ) if has_vote_ is not None and not isinstance(has_vote_, bool): raise Exception( - "Expected has_vote_ to be a bool, received: {}".format(type(has_vote_)) + f"Expected has_vote_ to be a bool, received: {type(has_vote_)}" ) if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception( - "Expected id__ to be a str, received: {}".format(type(id__)) - ) + raise Exception(f"Expected id__ to be a str, received: {type(id__)}") if instance_id_ is not None and not isinstance(instance_id_, (bytes, str)): raise Exception( - "Expected instance_id_ to be a str, received: {}".format( - type(instance_id_) - ) + f"Expected instance_id_ to be a str, received: {type(instance_id_)}" ) if message_ is not None and not isinstance(message_, (bytes, str)): raise Exception( - "Expected message_ to be a str, received: {}".format(type(message_)) + f"Expected message_ to be a str, received: {type(message_)}" ) if status_ is not None and not isinstance(status_, (bytes, str)): - raise Exception( - "Expected status_ to be a str, received: {}".format(type(status_)) - ) + raise Exception(f"Expected status_ to be a str, received: {type(status_)}") if wants_vote_ is not None and not isinstance(wants_vote_, bool): raise Exception( - "Expected wants_vote_ to be a bool, received: {}".format( - type(wants_vote_) - ) + f"Expected wants_vote_ to be a bool, received: {type(wants_vote_)}" ) self.display_name = display_name_ @@ -16614,8 +14546,7 @@ class ModelMigrationStatus(Type): _toPy = {"end": "end", "start": "start", "status": "status"} def __init__(self, end=None, start=None, status=None, **unknown_fields): - """ - end : str + """End : str start : str status : str """ @@ -16625,19 +14556,13 @@ def __init__(self, end=None, start=None, status=None, **unknown_fields): # Validate arguments against known Juju API types. if end_ is not None and not isinstance(end_, (bytes, str)): - raise Exception( - "Expected end_ to be a str, received: {}".format(type(end_)) - ) + raise Exception(f"Expected end_ to be a str, received: {type(end_)}") if start_ is not None and not isinstance(start_, (bytes, str)): - raise Exception( - "Expected start_ to be a str, received: {}".format(type(start_)) - ) + raise Exception(f"Expected start_ to be a str, received: {type(start_)}") if status_ is not None and not isinstance(status_, (bytes, str)): - raise Exception( - "Expected status_ to be a str, received: {}".format(type(status_)) - ) + raise Exception(f"Expected status_ to be a str, received: {type(status_)}") self.end = end_ self.start = start_ @@ -16650,15 +14575,13 @@ class ModelParam(Type): _toPy = {"model-tag": "model_tag"} def __init__(self, model_tag=None, **unknown_fields): - """ - model_tag : str - """ + """model_tag : str""" model_tag_ = model_tag # Validate arguments against known Juju API types. if model_tag_ is not None and not isinstance(model_tag_, (bytes, str)): raise Exception( - "Expected model_tag_ to be a str, received: {}".format(type(model_tag_)) + f"Expected model_tag_ to be a str, received: {type(model_tag_)}" ) self.model_tag = model_tag_ @@ -16682,8 +14605,7 @@ class ModelSLA(Type): def __init__( self, modelslainfo=None, creds=None, level=None, owner=None, **unknown_fields ): - """ - modelslainfo : ModelSLAInfo + """Modelslainfo : ModelSLAInfo creds : typing.Sequence[int] level : str owner : str @@ -16698,25 +14620,19 @@ def __init__( modelslainfo_, (dict, ModelSLAInfo) ): raise Exception( - "Expected modelslainfo_ to be a ModelSLAInfo, received: {}".format( - type(modelslainfo_) - ) + f"Expected modelslainfo_ to be a ModelSLAInfo, received: {type(modelslainfo_)}" ) if creds_ is not None and not isinstance(creds_, (bytes, str, list)): raise Exception( - "Expected creds_ to be a Sequence, received: {}".format(type(creds_)) + f"Expected creds_ to be a Sequence, received: {type(creds_)}" ) if level_ is not None and not isinstance(level_, (bytes, str)): - raise Exception( - "Expected level_ to be a str, received: {}".format(type(level_)) - ) + raise Exception(f"Expected level_ to be a str, received: {type(level_)}") if owner_ is not None and not isinstance(owner_, (bytes, str)): - raise Exception( - "Expected owner_ to be a str, received: {}".format(type(owner_)) - ) + raise Exception(f"Expected owner_ to be a str, received: {type(owner_)}") self.modelslainfo = modelslainfo_ self.creds = creds_ @@ -16730,8 +14646,7 @@ class ModelSLAInfo(Type): _toPy = {"level": "level", "owner": "owner"} def __init__(self, level=None, owner=None, **unknown_fields): - """ - level : str + """Level : str owner : str """ level_ = level @@ -16739,14 +14654,10 @@ def __init__(self, level=None, owner=None, **unknown_fields): # Validate arguments against known Juju API types. if level_ is not None and not isinstance(level_, (bytes, str)): - raise Exception( - "Expected level_ to be a str, received: {}".format(type(level_)) - ) + raise Exception(f"Expected level_ to be a str, received: {type(level_)}") if owner_ is not None and not isinstance(owner_, (bytes, str)): - raise Exception( - "Expected owner_ to be a str, received: {}".format(type(owner_)) - ) + raise Exception(f"Expected owner_ to be a str, received: {type(owner_)}") self.level = level_ self.owner = owner_ @@ -16758,17 +14669,13 @@ class ModelSequencesResult(Type): _toPy = {"sequences": "sequences"} def __init__(self, sequences=None, **unknown_fields): - """ - sequences : typing.Mapping[str, int] - """ + """Sequences : typing.Mapping[str, int]""" sequences_ = sequences # Validate arguments against known Juju API types. if sequences_ is not None and not isinstance(sequences_, dict): raise Exception( - "Expected sequences_ to be a Mapping, received: {}".format( - type(sequences_) - ) + f"Expected sequences_ to be a Mapping, received: {type(sequences_)}" ) self.sequences = sequences_ @@ -16780,15 +14687,13 @@ class ModelSet(Type): _toPy = {"config": "config"} def __init__(self, config=None, **unknown_fields): - """ - config : typing.Mapping[str, typing.Any] - """ + """Config : typing.Mapping[str, typing.Any]""" config_ = config # Validate arguments against known Juju API types. if config_ is not None and not isinstance(config_, dict): raise Exception( - "Expected config_ to be a Mapping, received: {}".format(type(config_)) + f"Expected config_ to be a Mapping, received: {type(config_)}" ) self.config = config_ @@ -16841,8 +14746,7 @@ def __init__( volumes=None, **unknown_fields, ): - """ - application_count : int + """application_count : int applications : typing.Sequence[~ModelApplicationInfo] error : Error filesystems : typing.Sequence[~ModelFilesystemInfo] @@ -16871,82 +14775,62 @@ def __init__( # Validate arguments against known Juju API types. if application_count_ is not None and not isinstance(application_count_, int): raise Exception( - "Expected application_count_ to be a int, received: {}".format( - type(application_count_) - ) + f"Expected application_count_ to be a int, received: {type(application_count_)}" ) if applications_ is not None and not isinstance( applications_, (bytes, str, list) ): raise Exception( - "Expected applications_ to be a Sequence, received: {}".format( - type(applications_) - ) + f"Expected applications_ to be a Sequence, received: {type(applications_)}" ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if filesystems_ is not None and not isinstance( filesystems_, (bytes, str, list) ): raise Exception( - "Expected filesystems_ to be a Sequence, received: {}".format( - type(filesystems_) - ) + f"Expected filesystems_ to be a Sequence, received: {type(filesystems_)}" ) if hosted_machine_count_ is not None and not isinstance( hosted_machine_count_, int ): raise Exception( - "Expected hosted_machine_count_ to be a int, received: {}".format( - type(hosted_machine_count_) - ) + f"Expected hosted_machine_count_ to be a int, received: {type(hosted_machine_count_)}" ) if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception( - "Expected life_ to be a str, received: {}".format(type(life_)) - ) + raise Exception(f"Expected life_ to be a str, received: {type(life_)}") if machines_ is not None and not isinstance(machines_, (bytes, str, list)): raise Exception( - "Expected machines_ to be a Sequence, received: {}".format( - type(machines_) - ) + f"Expected machines_ to be a Sequence, received: {type(machines_)}" ) if model_tag_ is not None and not isinstance(model_tag_, (bytes, str)): raise Exception( - "Expected model_tag_ to be a str, received: {}".format(type(model_tag_)) + f"Expected model_tag_ to be a str, received: {type(model_tag_)}" ) if owner_tag_ is not None and not isinstance(owner_tag_, (bytes, str)): raise Exception( - "Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_)) + f"Expected owner_tag_ to be a str, received: {type(owner_tag_)}" ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") if unit_count_ is not None and not isinstance(unit_count_, int): raise Exception( - "Expected unit_count_ to be a int, received: {}".format( - type(unit_count_) - ) + f"Expected unit_count_ to be a int, received: {type(unit_count_)}" ) if volumes_ is not None and not isinstance(volumes_, (bytes, str, list)): raise Exception( - "Expected volumes_ to be a Sequence, received: {}".format( - type(volumes_) - ) + f"Expected volumes_ to be a Sequence, received: {type(volumes_)}" ) self.application_count = application_count_ @@ -17001,8 +14885,7 @@ def __init__( version=None, **unknown_fields, ): - """ - available_version : str + """available_version : str cloud_tag : str meter_status : MeterStatus model_status : DetailedStatus @@ -17027,57 +14910,43 @@ def __init__( available_version_, (bytes, str) ): raise Exception( - "Expected available_version_ to be a str, received: {}".format( - type(available_version_) - ) + f"Expected available_version_ to be a str, received: {type(available_version_)}" ) if cloud_tag_ is not None and not isinstance(cloud_tag_, (bytes, str)): raise Exception( - "Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_)) + f"Expected cloud_tag_ to be a str, received: {type(cloud_tag_)}" ) if meter_status_ is not None and not isinstance( meter_status_, (dict, MeterStatus) ): raise Exception( - "Expected meter_status_ to be a MeterStatus, received: {}".format( - type(meter_status_) - ) + f"Expected meter_status_ to be a MeterStatus, received: {type(meter_status_)}" ) if model_status_ is not None and not isinstance( model_status_, (dict, DetailedStatus) ): raise Exception( - "Expected model_status_ to be a DetailedStatus, received: {}".format( - type(model_status_) - ) + f"Expected model_status_ to be a DetailedStatus, received: {type(model_status_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if region_ is not None and not isinstance(region_, (bytes, str)): - raise Exception( - "Expected region_ to be a str, received: {}".format(type(region_)) - ) + raise Exception(f"Expected region_ to be a str, received: {type(region_)}") if sla_ is not None and not isinstance(sla_, (bytes, str)): - raise Exception( - "Expected sla_ to be a str, received: {}".format(type(sla_)) - ) + raise Exception(f"Expected sla_ to be a str, received: {type(sla_)}") if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") if version_ is not None and not isinstance(version_, (bytes, str)): raise Exception( - "Expected version_ to be a str, received: {}".format(type(version_)) + f"Expected version_ to be a str, received: {type(version_)}" ) self.available_version = available_version_ @@ -17097,15 +14966,13 @@ class ModelStatusResults(Type): _toPy = {"models": "models"} def __init__(self, models=None, **unknown_fields): - """ - models : typing.Sequence[~ModelStatus] - """ + """Models : typing.Sequence[~ModelStatus]""" models_ = [ModelStatus.from_json(o) for o in models or []] # Validate arguments against known Juju API types. if models_ is not None and not isinstance(models_, (bytes, str, list)): raise Exception( - "Expected models_ to be a Sequence, received: {}".format(type(models_)) + f"Expected models_ to be a Sequence, received: {type(models_)}" ) self.models = models_ @@ -17117,8 +14984,7 @@ class ModelSummariesRequest(Type): _toPy = {"all": "all_", "user-tag": "user_tag"} def __init__(self, all_=None, user_tag=None, **unknown_fields): - """ - all_ : bool + """all_ : bool user_tag : str """ all__ = all_ @@ -17126,13 +14992,11 @@ def __init__(self, all_=None, user_tag=None, **unknown_fields): # Validate arguments against known Juju API types. if all__ is not None and not isinstance(all__, bool): - raise Exception( - "Expected all__ to be a bool, received: {}".format(type(all__)) - ) + raise Exception(f"Expected all__ to be a bool, received: {type(all__)}") if user_tag_ is not None and not isinstance(user_tag_, (bytes, str)): raise Exception( - "Expected user_tag_ to be a str, received: {}".format(type(user_tag_)) + f"Expected user_tag_ to be a str, received: {type(user_tag_)}" ) self.all_ = all__ @@ -17207,8 +15071,7 @@ def __init__( uuid=None, **unknown_fields, ): - """ - agent_version : Number + """agent_version : Number cloud_credential_tag : str cloud_region : str cloud_tag : str @@ -17253,130 +15116,100 @@ def __init__( agent_version_, (dict, Number) ): raise Exception( - "Expected agent_version_ to be a Number, received: {}".format( - type(agent_version_) - ) + f"Expected agent_version_ to be a Number, received: {type(agent_version_)}" ) if cloud_credential_tag_ is not None and not isinstance( cloud_credential_tag_, (bytes, str) ): raise Exception( - "Expected cloud_credential_tag_ to be a str, received: {}".format( - type(cloud_credential_tag_) - ) + f"Expected cloud_credential_tag_ to be a str, received: {type(cloud_credential_tag_)}" ) if cloud_region_ is not None and not isinstance(cloud_region_, (bytes, str)): raise Exception( - "Expected cloud_region_ to be a str, received: {}".format( - type(cloud_region_) - ) + f"Expected cloud_region_ to be a str, received: {type(cloud_region_)}" ) if cloud_tag_ is not None and not isinstance(cloud_tag_, (bytes, str)): raise Exception( - "Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_)) + f"Expected cloud_tag_ to be a str, received: {type(cloud_tag_)}" ) if controller_uuid_ is not None and not isinstance( controller_uuid_, (bytes, str) ): raise Exception( - "Expected controller_uuid_ to be a str, received: {}".format( - type(controller_uuid_) - ) + f"Expected controller_uuid_ to be a str, received: {type(controller_uuid_)}" ) if counts_ is not None and not isinstance(counts_, (bytes, str, list)): raise Exception( - "Expected counts_ to be a Sequence, received: {}".format(type(counts_)) + f"Expected counts_ to be a Sequence, received: {type(counts_)}" ) if default_series_ is not None and not isinstance( default_series_, (bytes, str) ): raise Exception( - "Expected default_series_ to be a str, received: {}".format( - type(default_series_) - ) + f"Expected default_series_ to be a str, received: {type(default_series_)}" ) if is_controller_ is not None and not isinstance(is_controller_, bool): raise Exception( - "Expected is_controller_ to be a bool, received: {}".format( - type(is_controller_) - ) + f"Expected is_controller_ to be a bool, received: {type(is_controller_)}" ) if last_connection_ is not None and not isinstance( last_connection_, (bytes, str) ): raise Exception( - "Expected last_connection_ to be a str, received: {}".format( - type(last_connection_) - ) + f"Expected last_connection_ to be a str, received: {type(last_connection_)}" ) if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception( - "Expected life_ to be a str, received: {}".format(type(life_)) - ) + raise Exception(f"Expected life_ to be a str, received: {type(life_)}") if migration_ is not None and not isinstance( migration_, (dict, ModelMigrationStatus) ): raise Exception( - "Expected migration_ to be a ModelMigrationStatus, received: {}".format( - type(migration_) - ) + f"Expected migration_ to be a ModelMigrationStatus, received: {type(migration_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if owner_tag_ is not None and not isinstance(owner_tag_, (bytes, str)): raise Exception( - "Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_)) + f"Expected owner_tag_ to be a str, received: {type(owner_tag_)}" ) if provider_type_ is not None and not isinstance(provider_type_, (bytes, str)): raise Exception( - "Expected provider_type_ to be a str, received: {}".format( - type(provider_type_) - ) + f"Expected provider_type_ to be a str, received: {type(provider_type_)}" ) if sla_ is not None and not isinstance(sla_, (dict, ModelSLAInfo)): raise Exception( - "Expected sla_ to be a ModelSLAInfo, received: {}".format(type(sla_)) + f"Expected sla_ to be a ModelSLAInfo, received: {type(sla_)}" ) if status_ is not None and not isinstance(status_, (dict, EntityStatus)): raise Exception( - "Expected status_ to be a EntityStatus, received: {}".format( - type(status_) - ) + f"Expected status_ to be a EntityStatus, received: {type(status_)}" ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") if user_access_ is not None and not isinstance(user_access_, (bytes, str)): raise Exception( - "Expected user_access_ to be a str, received: {}".format( - type(user_access_) - ) + f"Expected user_access_ to be a str, received: {type(user_access_)}" ) if uuid_ is not None and not isinstance(uuid_, (bytes, str)): - raise Exception( - "Expected uuid_ to be a str, received: {}".format(type(uuid_)) - ) + raise Exception(f"Expected uuid_ to be a str, received: {type(uuid_)}") self.agent_version = agent_version_ self.cloud_credential_tag = cloud_credential_tag_ @@ -17405,8 +15238,7 @@ class ModelSummaryResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : ModelSummary """ error_ = Error.from_json(error) if error else None @@ -17414,15 +15246,11 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance(result_, (dict, ModelSummary)): raise Exception( - "Expected result_ to be a ModelSummary, received: {}".format( - type(result_) - ) + f"Expected result_ to be a ModelSummary, received: {type(result_)}" ) self.error = error_ @@ -17435,17 +15263,13 @@ class ModelSummaryResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~ModelSummaryResult] - """ + """Results : typing.Sequence[~ModelSummaryResult]""" results_ = [ModelSummaryResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -17466,16 +15290,12 @@ class ModelUnset(Type): _toPy = {"keys": "keys"} def __init__(self, keys=None, **unknown_fields): - """ - keys : typing.Sequence[str] - """ + """Keys : typing.Sequence[str]""" keys_ = keys # Validate arguments against known Juju API types. if keys_ is not None and not isinstance(keys_, (bytes, str, list)): - raise Exception( - "Expected keys_ to be a Sequence, received: {}".format(type(keys_)) - ) + raise Exception(f"Expected keys_ to be a Sequence, received: {type(keys_)}") self.keys = keys_ self.unknown_fields = unknown_fields @@ -17490,8 +15310,7 @@ class ModelUnsetKeys(Type): _toPy = {"cloud-region": "cloud_region", "cloud-tag": "cloud_tag", "keys": "keys"} def __init__(self, cloud_region=None, cloud_tag=None, keys=None, **unknown_fields): - """ - cloud_region : str + """cloud_region : str cloud_tag : str keys : typing.Sequence[str] """ @@ -17502,20 +15321,16 @@ def __init__(self, cloud_region=None, cloud_tag=None, keys=None, **unknown_field # Validate arguments against known Juju API types. if cloud_region_ is not None and not isinstance(cloud_region_, (bytes, str)): raise Exception( - "Expected cloud_region_ to be a str, received: {}".format( - type(cloud_region_) - ) + f"Expected cloud_region_ to be a str, received: {type(cloud_region_)}" ) if cloud_tag_ is not None and not isinstance(cloud_tag_, (bytes, str)): raise Exception( - "Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_)) + f"Expected cloud_tag_ to be a str, received: {type(cloud_tag_)}" ) if keys_ is not None and not isinstance(keys_, (bytes, str, list)): - raise Exception( - "Expected keys_ to be a Sequence, received: {}".format(type(keys_)) - ) + raise Exception(f"Expected keys_ to be a Sequence, received: {type(keys_)}") self.cloud_region = cloud_region_ self.cloud_tag = cloud_tag_ @@ -17548,8 +15363,7 @@ def __init__( user=None, **unknown_fields, ): - """ - access : str + """Access : str display_name : str last_connection : str model_tag : str @@ -17563,35 +15377,27 @@ def __init__( # Validate arguments against known Juju API types. if access_ is not None and not isinstance(access_, (bytes, str)): - raise Exception( - "Expected access_ to be a str, received: {}".format(type(access_)) - ) + raise Exception(f"Expected access_ to be a str, received: {type(access_)}") if display_name_ is not None and not isinstance(display_name_, (bytes, str)): raise Exception( - "Expected display_name_ to be a str, received: {}".format( - type(display_name_) - ) + f"Expected display_name_ to be a str, received: {type(display_name_)}" ) if last_connection_ is not None and not isinstance( last_connection_, (bytes, str) ): raise Exception( - "Expected last_connection_ to be a str, received: {}".format( - type(last_connection_) - ) + f"Expected last_connection_ to be a str, received: {type(last_connection_)}" ) if model_tag_ is not None and not isinstance(model_tag_, (bytes, str)): raise Exception( - "Expected model_tag_ to be a str, received: {}".format(type(model_tag_)) + f"Expected model_tag_ to be a str, received: {type(model_tag_)}" ) if user_ is not None and not isinstance(user_, (bytes, str)): - raise Exception( - "Expected user_ to be a str, received: {}".format(type(user_)) - ) + raise Exception(f"Expected user_ to be a str, received: {type(user_)}") self.access = access_ self.display_name = display_name_ @@ -17606,8 +15412,7 @@ class ModelUserInfoResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : ModelUserInfo """ error_ = Error.from_json(error) if error else None @@ -17615,15 +15420,11 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance(result_, (dict, ModelUserInfo)): raise Exception( - "Expected result_ to be a ModelUserInfo, received: {}".format( - type(result_) - ) + f"Expected result_ to be a ModelUserInfo, received: {type(result_)}" ) self.error = error_ @@ -17636,17 +15437,13 @@ class ModelUserInfoResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~ModelUserInfoResult] - """ + """Results : typing.Sequence[~ModelUserInfoResult]""" results_ = [ModelUserInfoResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -17678,8 +15475,7 @@ def __init__( status=None, **unknown_fields, ): - """ - detachable : bool + """Detachable : bool id_ : str message : str provider_id : str @@ -17694,32 +15490,24 @@ def __init__( # Validate arguments against known Juju API types. if detachable_ is not None and not isinstance(detachable_, bool): raise Exception( - "Expected detachable_ to be a bool, received: {}".format( - type(detachable_) - ) + f"Expected detachable_ to be a bool, received: {type(detachable_)}" ) if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception( - "Expected id__ to be a str, received: {}".format(type(id__)) - ) + raise Exception(f"Expected id__ to be a str, received: {type(id__)}") if message_ is not None and not isinstance(message_, (bytes, str)): raise Exception( - "Expected message_ to be a str, received: {}".format(type(message_)) + f"Expected message_ to be a str, received: {type(message_)}" ) if provider_id_ is not None and not isinstance(provider_id_, (bytes, str)): raise Exception( - "Expected provider_id_ to be a str, received: {}".format( - type(provider_id_) - ) + f"Expected provider_id_ to be a str, received: {type(provider_id_)}" ) if status_ is not None and not isinstance(status_, (bytes, str)): - raise Exception( - "Expected status_ to be a str, received: {}".format(type(status_)) - ) + raise Exception(f"Expected status_ to be a str, received: {type(status_)}") self.detachable = detachable_ self.id_ = id__ @@ -17746,8 +15534,7 @@ class ModifyCloudAccess(Type): def __init__( self, access=None, action=None, cloud_tag=None, user_tag=None, **unknown_fields ): - """ - access : str + """Access : str action : str cloud_tag : str user_tag : str @@ -17759,23 +15546,19 @@ def __init__( # Validate arguments against known Juju API types. if access_ is not None and not isinstance(access_, (bytes, str)): - raise Exception( - "Expected access_ to be a str, received: {}".format(type(access_)) - ) + raise Exception(f"Expected access_ to be a str, received: {type(access_)}") if action_ is not None and not isinstance(action_, (bytes, str)): - raise Exception( - "Expected action_ to be a str, received: {}".format(type(action_)) - ) + raise Exception(f"Expected action_ to be a str, received: {type(action_)}") if cloud_tag_ is not None and not isinstance(cloud_tag_, (bytes, str)): raise Exception( - "Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_)) + f"Expected cloud_tag_ to be a str, received: {type(cloud_tag_)}" ) if user_tag_ is not None and not isinstance(user_tag_, (bytes, str)): raise Exception( - "Expected user_tag_ to be a str, received: {}".format(type(user_tag_)) + f"Expected user_tag_ to be a str, received: {type(user_tag_)}" ) self.access = access_ @@ -17790,17 +15573,13 @@ class ModifyCloudAccessRequest(Type): _toPy = {"changes": "changes"} def __init__(self, changes=None, **unknown_fields): - """ - changes : typing.Sequence[~ModifyCloudAccess] - """ + """Changes : typing.Sequence[~ModifyCloudAccess]""" changes_ = [ModifyCloudAccess.from_json(o) for o in changes or []] # Validate arguments against known Juju API types. if changes_ is not None and not isinstance(changes_, (bytes, str, list)): raise Exception( - "Expected changes_ to be a Sequence, received: {}".format( - type(changes_) - ) + f"Expected changes_ to be a Sequence, received: {type(changes_)}" ) self.changes = changes_ @@ -17812,8 +15591,7 @@ class ModifyControllerAccess(Type): _toPy = {"access": "access", "action": "action", "user-tag": "user_tag"} def __init__(self, access=None, action=None, user_tag=None, **unknown_fields): - """ - access : str + """Access : str action : str user_tag : str """ @@ -17823,18 +15601,14 @@ def __init__(self, access=None, action=None, user_tag=None, **unknown_fields): # Validate arguments against known Juju API types. if access_ is not None and not isinstance(access_, (bytes, str)): - raise Exception( - "Expected access_ to be a str, received: {}".format(type(access_)) - ) + raise Exception(f"Expected access_ to be a str, received: {type(access_)}") if action_ is not None and not isinstance(action_, (bytes, str)): - raise Exception( - "Expected action_ to be a str, received: {}".format(type(action_)) - ) + raise Exception(f"Expected action_ to be a str, received: {type(action_)}") if user_tag_ is not None and not isinstance(user_tag_, (bytes, str)): raise Exception( - "Expected user_tag_ to be a str, received: {}".format(type(user_tag_)) + f"Expected user_tag_ to be a str, received: {type(user_tag_)}" ) self.access = access_ @@ -17848,17 +15622,13 @@ class ModifyControllerAccessRequest(Type): _toPy = {"changes": "changes"} def __init__(self, changes=None, **unknown_fields): - """ - changes : typing.Sequence[~ModifyControllerAccess] - """ + """Changes : typing.Sequence[~ModifyControllerAccess]""" changes_ = [ModifyControllerAccess.from_json(o) for o in changes or []] # Validate arguments against known Juju API types. if changes_ is not None and not isinstance(changes_, (bytes, str, list)): raise Exception( - "Expected changes_ to be a Sequence, received: {}".format( - type(changes_) - ) + f"Expected changes_ to be a Sequence, received: {type(changes_)}" ) self.changes = changes_ @@ -17882,8 +15652,7 @@ class ModifyModelAccess(Type): def __init__( self, access=None, action=None, model_tag=None, user_tag=None, **unknown_fields ): - """ - access : str + """Access : str action : str model_tag : str user_tag : str @@ -17895,23 +15664,19 @@ def __init__( # Validate arguments against known Juju API types. if access_ is not None and not isinstance(access_, (bytes, str)): - raise Exception( - "Expected access_ to be a str, received: {}".format(type(access_)) - ) + raise Exception(f"Expected access_ to be a str, received: {type(access_)}") if action_ is not None and not isinstance(action_, (bytes, str)): - raise Exception( - "Expected action_ to be a str, received: {}".format(type(action_)) - ) + raise Exception(f"Expected action_ to be a str, received: {type(action_)}") if model_tag_ is not None and not isinstance(model_tag_, (bytes, str)): raise Exception( - "Expected model_tag_ to be a str, received: {}".format(type(model_tag_)) + f"Expected model_tag_ to be a str, received: {type(model_tag_)}" ) if user_tag_ is not None and not isinstance(user_tag_, (bytes, str)): raise Exception( - "Expected user_tag_ to be a str, received: {}".format(type(user_tag_)) + f"Expected user_tag_ to be a str, received: {type(user_tag_)}" ) self.access = access_ @@ -17926,17 +15691,13 @@ class ModifyModelAccessRequest(Type): _toPy = {"changes": "changes"} def __init__(self, changes=None, **unknown_fields): - """ - changes : typing.Sequence[~ModifyModelAccess] - """ + """Changes : typing.Sequence[~ModifyModelAccess]""" changes_ = [ModifyModelAccess.from_json(o) for o in changes or []] # Validate arguments against known Juju API types. if changes_ is not None and not isinstance(changes_, (bytes, str, list)): raise Exception( - "Expected changes_ to be a Sequence, received: {}".format( - type(changes_) - ) + f"Expected changes_ to be a Sequence, received: {type(changes_)}" ) self.changes = changes_ @@ -17960,8 +15721,7 @@ class ModifyOfferAccess(Type): def __init__( self, access=None, action=None, offer_url=None, user_tag=None, **unknown_fields ): - """ - access : str + """Access : str action : str offer_url : str user_tag : str @@ -17973,23 +15733,19 @@ def __init__( # Validate arguments against known Juju API types. if access_ is not None and not isinstance(access_, (bytes, str)): - raise Exception( - "Expected access_ to be a str, received: {}".format(type(access_)) - ) + raise Exception(f"Expected access_ to be a str, received: {type(access_)}") if action_ is not None and not isinstance(action_, (bytes, str)): - raise Exception( - "Expected action_ to be a str, received: {}".format(type(action_)) - ) + raise Exception(f"Expected action_ to be a str, received: {type(action_)}") if offer_url_ is not None and not isinstance(offer_url_, (bytes, str)): raise Exception( - "Expected offer_url_ to be a str, received: {}".format(type(offer_url_)) + f"Expected offer_url_ to be a str, received: {type(offer_url_)}" ) if user_tag_ is not None and not isinstance(user_tag_, (bytes, str)): raise Exception( - "Expected user_tag_ to be a str, received: {}".format(type(user_tag_)) + f"Expected user_tag_ to be a str, received: {type(user_tag_)}" ) self.access = access_ @@ -18004,17 +15760,13 @@ class ModifyOfferAccessRequest(Type): _toPy = {"changes": "changes"} def __init__(self, changes=None, **unknown_fields): - """ - changes : typing.Sequence[~ModifyOfferAccess] - """ + """Changes : typing.Sequence[~ModifyOfferAccess]""" changes_ = [ModifyOfferAccess.from_json(o) for o in changes or []] # Validate arguments against known Juju API types. if changes_ is not None and not isinstance(changes_, (bytes, str, list)): raise Exception( - "Expected changes_ to be a Sequence, received: {}".format( - type(changes_) - ) + f"Expected changes_ to be a Sequence, received: {type(changes_)}" ) self.changes = changes_ @@ -18026,8 +15778,7 @@ class ModifyUserSSHKeys(Type): _toPy = {"ssh-keys": "ssh_keys", "user": "user"} def __init__(self, ssh_keys=None, user=None, **unknown_fields): - """ - ssh_keys : typing.Sequence[str] + """ssh_keys : typing.Sequence[str] user : str """ ssh_keys_ = ssh_keys @@ -18036,15 +15787,11 @@ def __init__(self, ssh_keys=None, user=None, **unknown_fields): # Validate arguments against known Juju API types. if ssh_keys_ is not None and not isinstance(ssh_keys_, (bytes, str, list)): raise Exception( - "Expected ssh_keys_ to be a Sequence, received: {}".format( - type(ssh_keys_) - ) + f"Expected ssh_keys_ to be a Sequence, received: {type(ssh_keys_)}" ) if user_ is not None and not isinstance(user_, (bytes, str)): - raise Exception( - "Expected user_ to be a str, received: {}".format(type(user_)) - ) + raise Exception(f"Expected user_ to be a str, received: {type(user_)}") self.ssh_keys = ssh_keys_ self.user = user_ @@ -18056,8 +15803,7 @@ class MoveSubnetsParam(Type): _toPy = {"force": "force", "space-tag": "space_tag", "subnets": "subnets"} def __init__(self, force=None, space_tag=None, subnets=None, **unknown_fields): - """ - force : bool + """Force : bool space_tag : str subnets : typing.Sequence[str] """ @@ -18067,20 +15813,16 @@ def __init__(self, force=None, space_tag=None, subnets=None, **unknown_fields): # Validate arguments against known Juju API types. if force_ is not None and not isinstance(force_, bool): - raise Exception( - "Expected force_ to be a bool, received: {}".format(type(force_)) - ) + raise Exception(f"Expected force_ to be a bool, received: {type(force_)}") if space_tag_ is not None and not isinstance(space_tag_, (bytes, str)): raise Exception( - "Expected space_tag_ to be a str, received: {}".format(type(space_tag_)) + f"Expected space_tag_ to be a str, received: {type(space_tag_)}" ) if subnets_ is not None and not isinstance(subnets_, (bytes, str, list)): raise Exception( - "Expected subnets_ to be a Sequence, received: {}".format( - type(subnets_) - ) + f"Expected subnets_ to be a Sequence, received: {type(subnets_)}" ) self.force = force_ @@ -18094,16 +15836,12 @@ class MoveSubnetsParams(Type): _toPy = {"args": "args"} def __init__(self, args=None, **unknown_fields): - """ - args : typing.Sequence[~MoveSubnetsParam] - """ + """Args : typing.Sequence[~MoveSubnetsParam]""" args_ = [MoveSubnetsParam.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception( - "Expected args_ to be a Sequence, received: {}".format(type(args_)) - ) + raise Exception(f"Expected args_ to be a Sequence, received: {type(args_)}") self.args = args_ self.unknown_fields = unknown_fields @@ -18124,8 +15862,7 @@ class MoveSubnetsResult(Type): def __init__( self, error=None, moved_subnets=None, new_space=None, **unknown_fields ): - """ - error : Error + """Error : Error moved_subnets : typing.Sequence[~MovedSubnet] new_space : str """ @@ -18135,22 +15872,18 @@ def __init__( # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if moved_subnets_ is not None and not isinstance( moved_subnets_, (bytes, str, list) ): raise Exception( - "Expected moved_subnets_ to be a Sequence, received: {}".format( - type(moved_subnets_) - ) + f"Expected moved_subnets_ to be a Sequence, received: {type(moved_subnets_)}" ) if new_space_ is not None and not isinstance(new_space_, (bytes, str)): raise Exception( - "Expected new_space_ to be a str, received: {}".format(type(new_space_)) + f"Expected new_space_ to be a str, received: {type(new_space_)}" ) self.error = error_ @@ -18164,17 +15897,13 @@ class MoveSubnetsResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~MoveSubnetsResult] - """ + """Results : typing.Sequence[~MoveSubnetsResult]""" results_ = [MoveSubnetsResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -18186,8 +15915,7 @@ class MovedSubnet(Type): _toPy = {"cidr": "cidr", "old-space": "old_space", "subnet": "subnet"} def __init__(self, cidr=None, old_space=None, subnet=None, **unknown_fields): - """ - cidr : str + """Cidr : str old_space : str subnet : str """ @@ -18197,19 +15925,15 @@ def __init__(self, cidr=None, old_space=None, subnet=None, **unknown_fields): # Validate arguments against known Juju API types. if cidr_ is not None and not isinstance(cidr_, (bytes, str)): - raise Exception( - "Expected cidr_ to be a str, received: {}".format(type(cidr_)) - ) + raise Exception(f"Expected cidr_ to be a str, received: {type(cidr_)}") if old_space_ is not None and not isinstance(old_space_, (bytes, str)): raise Exception( - "Expected old_space_ to be a str, received: {}".format(type(old_space_)) + f"Expected old_space_ to be a str, received: {type(old_space_)}" ) if subnet_ is not None and not isinstance(subnet_, (bytes, str)): - raise Exception( - "Expected subnet_ to be a str, received: {}".format(type(subnet_)) - ) + raise Exception(f"Expected subnet_ to be a str, received: {type(subnet_)}") self.cidr = cidr_ self.old_space = old_space_ @@ -18245,8 +15969,7 @@ def __init__( space=None, **unknown_fields, ): - """ - dns_nameservers : typing.Sequence[str] + """dns_nameservers : typing.Sequence[str] gateway : str ip_addresses : typing.Sequence[str] is_up : bool @@ -18265,41 +15988,31 @@ def __init__( dns_nameservers_, (bytes, str, list) ): raise Exception( - "Expected dns_nameservers_ to be a Sequence, received: {}".format( - type(dns_nameservers_) - ) + f"Expected dns_nameservers_ to be a Sequence, received: {type(dns_nameservers_)}" ) if gateway_ is not None and not isinstance(gateway_, (bytes, str)): raise Exception( - "Expected gateway_ to be a str, received: {}".format(type(gateway_)) + f"Expected gateway_ to be a str, received: {type(gateway_)}" ) if ip_addresses_ is not None and not isinstance( ip_addresses_, (bytes, str, list) ): raise Exception( - "Expected ip_addresses_ to be a Sequence, received: {}".format( - type(ip_addresses_) - ) + f"Expected ip_addresses_ to be a Sequence, received: {type(ip_addresses_)}" ) if is_up_ is not None and not isinstance(is_up_, bool): - raise Exception( - "Expected is_up_ to be a bool, received: {}".format(type(is_up_)) - ) + raise Exception(f"Expected is_up_ to be a bool, received: {type(is_up_)}") if mac_address_ is not None and not isinstance(mac_address_, (bytes, str)): raise Exception( - "Expected mac_address_ to be a str, received: {}".format( - type(mac_address_) - ) + f"Expected mac_address_ to be a str, received: {type(mac_address_)}" ) if space_ is not None and not isinstance(space_, (bytes, str)): - raise Exception( - "Expected space_ to be a str, received: {}".format(type(space_)) - ) + raise Exception(f"Expected space_ to be a str, received: {type(space_)}") self.dns_nameservers = dns_nameservers_ self.gateway = gateway_ @@ -18315,8 +16028,7 @@ class NotifyWatchResult(Type): _toPy = {"NotifyWatcherId": "notifywatcherid", "error": "error"} def __init__(self, notifywatcherid=None, error=None, **unknown_fields): - """ - notifywatcherid : str + """Notifywatcherid : str error : Error """ notifywatcherid_ = notifywatcherid @@ -18327,15 +16039,11 @@ def __init__(self, notifywatcherid=None, error=None, **unknown_fields): notifywatcherid_, (bytes, str) ): raise Exception( - "Expected notifywatcherid_ to be a str, received: {}".format( - type(notifywatcherid_) - ) + f"Expected notifywatcherid_ to be a str, received: {type(notifywatcherid_)}" ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") self.notifywatcherid = notifywatcherid_ self.error = error_ @@ -18347,17 +16055,13 @@ class NotifyWatchResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~NotifyWatchResult] - """ + """Results : typing.Sequence[~NotifyWatchResult]""" results_ = [NotifyWatchResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -18383,8 +16087,7 @@ class Number(Type): def __init__( self, build=None, major=None, minor=None, patch=None, tag=None, **unknown_fields ): - """ - build : int + """Build : int major : int minor : int patch : int @@ -18398,29 +16101,19 @@ def __init__( # Validate arguments against known Juju API types. if build_ is not None and not isinstance(build_, int): - raise Exception( - "Expected build_ to be a int, received: {}".format(type(build_)) - ) + raise Exception(f"Expected build_ to be a int, received: {type(build_)}") if major_ is not None and not isinstance(major_, int): - raise Exception( - "Expected major_ to be a int, received: {}".format(type(major_)) - ) + raise Exception(f"Expected major_ to be a int, received: {type(major_)}") if minor_ is not None and not isinstance(minor_, int): - raise Exception( - "Expected minor_ to be a int, received: {}".format(type(minor_)) - ) + raise Exception(f"Expected minor_ to be a int, received: {type(minor_)}") if patch_ is not None and not isinstance(patch_, int): - raise Exception( - "Expected patch_ to be a int, received: {}".format(type(patch_)) - ) + raise Exception(f"Expected patch_ to be a int, received: {type(patch_)}") if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception( - "Expected tag_ to be a str, received: {}".format(type(tag_)) - ) + raise Exception(f"Expected tag_ to be a str, received: {type(tag_)}") self.build = build_ self.major = major_ @@ -18458,8 +16151,7 @@ def __init__( username=None, **unknown_fields, ): - """ - endpoint : str + """Endpoint : str ingress_subnets : typing.Sequence[str] relation_id : int source_model_tag : str @@ -18476,44 +16168,36 @@ def __init__( # Validate arguments against known Juju API types. if endpoint_ is not None and not isinstance(endpoint_, (bytes, str)): raise Exception( - "Expected endpoint_ to be a str, received: {}".format(type(endpoint_)) + f"Expected endpoint_ to be a str, received: {type(endpoint_)}" ) if ingress_subnets_ is not None and not isinstance( ingress_subnets_, (bytes, str, list) ): raise Exception( - "Expected ingress_subnets_ to be a Sequence, received: {}".format( - type(ingress_subnets_) - ) + f"Expected ingress_subnets_ to be a Sequence, received: {type(ingress_subnets_)}" ) if relation_id_ is not None and not isinstance(relation_id_, int): raise Exception( - "Expected relation_id_ to be a int, received: {}".format( - type(relation_id_) - ) + f"Expected relation_id_ to be a int, received: {type(relation_id_)}" ) if source_model_tag_ is not None and not isinstance( source_model_tag_, (bytes, str) ): raise Exception( - "Expected source_model_tag_ to be a str, received: {}".format( - type(source_model_tag_) - ) + f"Expected source_model_tag_ to be a str, received: {type(source_model_tag_)}" ) if status_ is not None and not isinstance(status_, (dict, EntityStatus)): raise Exception( - "Expected status_ to be a EntityStatus, received: {}".format( - type(status_) - ) + f"Expected status_ to be a EntityStatus, received: {type(status_)}" ) if username_ is not None and not isinstance(username_, (bytes, str)): raise Exception( - "Expected username_ to be a str, received: {}".format(type(username_)) + f"Expected username_ to be a str, received: {type(username_)}" ) self.endpoint = endpoint_ @@ -18562,8 +16246,7 @@ def __init__( owner_name=None, **unknown_fields, ): - """ - allowed_users : typing.Sequence[str] + """allowed_users : typing.Sequence[str] application_description : str application_name : str application_user : str @@ -18588,73 +16271,55 @@ def __init__( allowed_users_, (bytes, str, list) ): raise Exception( - "Expected allowed_users_ to be a Sequence, received: {}".format( - type(allowed_users_) - ) + f"Expected allowed_users_ to be a Sequence, received: {type(allowed_users_)}" ) if application_description_ is not None and not isinstance( application_description_, (bytes, str) ): raise Exception( - "Expected application_description_ to be a str, received: {}".format( - type(application_description_) - ) + f"Expected application_description_ to be a str, received: {type(application_description_)}" ) if application_name_ is not None and not isinstance( application_name_, (bytes, str) ): raise Exception( - "Expected application_name_ to be a str, received: {}".format( - type(application_name_) - ) + f"Expected application_name_ to be a str, received: {type(application_name_)}" ) if application_user_ is not None and not isinstance( application_user_, (bytes, str) ): raise Exception( - "Expected application_user_ to be a str, received: {}".format( - type(application_user_) - ) + f"Expected application_user_ to be a str, received: {type(application_user_)}" ) if connected_users_ is not None and not isinstance( connected_users_, (bytes, str, list) ): raise Exception( - "Expected connected_users_ to be a Sequence, received: {}".format( - type(connected_users_) - ) + f"Expected connected_users_ to be a Sequence, received: {type(connected_users_)}" ) if endpoints_ is not None and not isinstance(endpoints_, (bytes, str, list)): raise Exception( - "Expected endpoints_ to be a Sequence, received: {}".format( - type(endpoints_) - ) + f"Expected endpoints_ to be a Sequence, received: {type(endpoints_)}" ) if model_name_ is not None and not isinstance(model_name_, (bytes, str)): raise Exception( - "Expected model_name_ to be a str, received: {}".format( - type(model_name_) - ) + f"Expected model_name_ to be a str, received: {type(model_name_)}" ) if offer_name_ is not None and not isinstance(offer_name_, (bytes, str)): raise Exception( - "Expected offer_name_ to be a str, received: {}".format( - type(offer_name_) - ) + f"Expected offer_name_ to be a str, received: {type(offer_name_)}" ) if owner_name_ is not None and not isinstance(owner_name_, (bytes, str)): raise Exception( - "Expected owner_name_ to be a str, received: {}".format( - type(owner_name_) - ) + f"Expected owner_name_ to be a str, received: {type(owner_name_)}" ) self.allowed_users = allowed_users_ @@ -18674,17 +16339,13 @@ class OfferFilters(Type): _toPy = {"Filters": "filters"} def __init__(self, filters=None, **unknown_fields): - """ - filters : typing.Sequence[~OfferFilter] - """ + """Filters : typing.Sequence[~OfferFilter]""" filters_ = [OfferFilter.from_json(o) for o in filters or []] # Validate arguments against known Juju API types. if filters_ is not None and not isinstance(filters_, (bytes, str, list)): raise Exception( - "Expected filters_ to be a Sequence, received: {}".format( - type(filters_) - ) + f"Expected filters_ to be a Sequence, received: {type(filters_)}" ) self.filters = filters_ @@ -18696,8 +16357,7 @@ class OfferURLs(Type): _toPy = {"bakery-version": "bakery_version", "offer-urls": "offer_urls"} def __init__(self, bakery_version=None, offer_urls=None, **unknown_fields): - """ - bakery_version : int + """bakery_version : int offer_urls : typing.Sequence[str] """ bakery_version_ = bakery_version @@ -18706,16 +16366,12 @@ def __init__(self, bakery_version=None, offer_urls=None, **unknown_fields): # Validate arguments against known Juju API types. if bakery_version_ is not None and not isinstance(bakery_version_, int): raise Exception( - "Expected bakery_version_ to be a int, received: {}".format( - type(bakery_version_) - ) + f"Expected bakery_version_ to be a int, received: {type(bakery_version_)}" ) if offer_urls_ is not None and not isinstance(offer_urls_, (bytes, str, list)): raise Exception( - "Expected offer_urls_ to be a Sequence, received: {}".format( - type(offer_urls_) - ) + f"Expected offer_urls_ to be a Sequence, received: {type(offer_urls_)}" ) self.bakery_version = bakery_version_ @@ -18728,8 +16384,7 @@ class OfferUserDetails(Type): _toPy = {"access": "access", "display-name": "display_name", "user": "user"} def __init__(self, access=None, display_name=None, user=None, **unknown_fields): - """ - access : str + """Access : str display_name : str user : str """ @@ -18739,21 +16394,15 @@ def __init__(self, access=None, display_name=None, user=None, **unknown_fields): # Validate arguments against known Juju API types. if access_ is not None and not isinstance(access_, (bytes, str)): - raise Exception( - "Expected access_ to be a str, received: {}".format(type(access_)) - ) + raise Exception(f"Expected access_ to be a str, received: {type(access_)}") if display_name_ is not None and not isinstance(display_name_, (bytes, str)): raise Exception( - "Expected display_name_ to be a str, received: {}".format( - type(display_name_) - ) + f"Expected display_name_ to be a str, received: {type(display_name_)}" ) if user_ is not None and not isinstance(user_, (bytes, str)): - raise Exception( - "Expected user_ to be a str, received: {}".format(type(user_)) - ) + raise Exception(f"Expected user_ to be a str, received: {type(user_)}") self.access = access_ self.display_name = display_name_ @@ -18792,8 +16441,7 @@ def __init__( units=None, **unknown_fields, ): - """ - actions : typing.Sequence[str] + """Actions : typing.Sequence[str] applications : typing.Sequence[str] limit : int machines : typing.Sequence[str] @@ -18812,45 +16460,35 @@ def __init__( # Validate arguments against known Juju API types. if actions_ is not None and not isinstance(actions_, (bytes, str, list)): raise Exception( - "Expected actions_ to be a Sequence, received: {}".format( - type(actions_) - ) + f"Expected actions_ to be a Sequence, received: {type(actions_)}" ) if applications_ is not None and not isinstance( applications_, (bytes, str, list) ): raise Exception( - "Expected applications_ to be a Sequence, received: {}".format( - type(applications_) - ) + f"Expected applications_ to be a Sequence, received: {type(applications_)}" ) if limit_ is not None and not isinstance(limit_, int): - raise Exception( - "Expected limit_ to be a int, received: {}".format(type(limit_)) - ) + raise Exception(f"Expected limit_ to be a int, received: {type(limit_)}") if machines_ is not None and not isinstance(machines_, (bytes, str, list)): raise Exception( - "Expected machines_ to be a Sequence, received: {}".format( - type(machines_) - ) + f"Expected machines_ to be a Sequence, received: {type(machines_)}" ) if offset_ is not None and not isinstance(offset_, int): - raise Exception( - "Expected offset_ to be a int, received: {}".format(type(offset_)) - ) + raise Exception(f"Expected offset_ to be a int, received: {type(offset_)}") if status_ is not None and not isinstance(status_, (bytes, str, list)): raise Exception( - "Expected status_ to be a Sequence, received: {}".format(type(status_)) + f"Expected status_ to be a Sequence, received: {type(status_)}" ) if units_ is not None and not isinstance(units_, (bytes, str, list)): raise Exception( - "Expected units_ to be a Sequence, received: {}".format(type(units_)) + f"Expected units_ to be a Sequence, received: {type(units_)}" ) self.actions = actions_ @@ -18900,8 +16538,7 @@ def __init__( summary=None, **unknown_fields, ): - """ - actions : typing.Sequence[~ActionResult] + """Actions : typing.Sequence[~ActionResult] completed : str enqueued : str error : Error @@ -18924,49 +16561,41 @@ def __init__( # Validate arguments against known Juju API types. if actions_ is not None and not isinstance(actions_, (bytes, str, list)): raise Exception( - "Expected actions_ to be a Sequence, received: {}".format( - type(actions_) - ) + f"Expected actions_ to be a Sequence, received: {type(actions_)}" ) if completed_ is not None and not isinstance(completed_, (bytes, str)): raise Exception( - "Expected completed_ to be a str, received: {}".format(type(completed_)) + f"Expected completed_ to be a str, received: {type(completed_)}" ) if enqueued_ is not None and not isinstance(enqueued_, (bytes, str)): raise Exception( - "Expected enqueued_ to be a str, received: {}".format(type(enqueued_)) + f"Expected enqueued_ to be a str, received: {type(enqueued_)}" ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if fail_ is not None and not isinstance(fail_, (bytes, str)): - raise Exception( - "Expected fail_ to be a str, received: {}".format(type(fail_)) - ) + raise Exception(f"Expected fail_ to be a str, received: {type(fail_)}") if operation_ is not None and not isinstance(operation_, (bytes, str)): raise Exception( - "Expected operation_ to be a str, received: {}".format(type(operation_)) + f"Expected operation_ to be a str, received: {type(operation_)}" ) if started_ is not None and not isinstance(started_, (bytes, str)): raise Exception( - "Expected started_ to be a str, received: {}".format(type(started_)) + f"Expected started_ to be a str, received: {type(started_)}" ) if status_ is not None and not isinstance(status_, (bytes, str)): - raise Exception( - "Expected status_ to be a str, received: {}".format(type(status_)) - ) + raise Exception(f"Expected status_ to be a str, received: {type(status_)}") if summary_ is not None and not isinstance(summary_, (bytes, str)): raise Exception( - "Expected summary_ to be a str, received: {}".format(type(summary_)) + f"Expected summary_ to be a str, received: {type(summary_)}" ) self.actions = actions_ @@ -18986,8 +16615,7 @@ class OperationResults(Type): _toPy = {"results": "results", "truncated": "truncated"} def __init__(self, results=None, truncated=None, **unknown_fields): - """ - results : typing.Sequence[~OperationResult] + """Results : typing.Sequence[~OperationResult] truncated : bool """ results_ = [OperationResult.from_json(o) for o in results or []] @@ -18996,16 +16624,12 @@ def __init__(self, results=None, truncated=None, **unknown_fields): # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) if truncated_ is not None and not isinstance(truncated_, bool): raise Exception( - "Expected truncated_ to be a bool, received: {}".format( - type(truncated_) - ) + f"Expected truncated_ to be a bool, received: {type(truncated_)}" ) self.results = results_ @@ -19044,8 +16668,7 @@ def __init__( unit=None, **unknown_fields, ): - """ - class_ : str + """class_ : str id_ : str labels : typing.Sequence[str] machine : str @@ -19063,39 +16686,29 @@ def __init__( # Validate arguments against known Juju API types. if class__ is not None and not isinstance(class__, (bytes, str)): - raise Exception( - "Expected class__ to be a str, received: {}".format(type(class__)) - ) + raise Exception(f"Expected class__ to be a str, received: {type(class__)}") if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception( - "Expected id__ to be a str, received: {}".format(type(id__)) - ) + raise Exception(f"Expected id__ to be a str, received: {type(id__)}") if labels_ is not None and not isinstance(labels_, (bytes, str, list)): raise Exception( - "Expected labels_ to be a Sequence, received: {}".format(type(labels_)) + f"Expected labels_ to be a Sequence, received: {type(labels_)}" ) if machine_ is not None and not isinstance(machine_, (bytes, str)): raise Exception( - "Expected machine_ to be a str, received: {}".format(type(machine_)) + f"Expected machine_ to be a str, received: {type(machine_)}" ) if status_ is not None and not isinstance(status_, (bytes, str)): - raise Exception( - "Expected status_ to be a str, received: {}".format(type(status_)) - ) + raise Exception(f"Expected status_ to be a str, received: {type(status_)}") if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") if unit_ is not None and not isinstance(unit_, (bytes, str)): - raise Exception( - "Expected unit_ to be a str, received: {}".format(type(unit_)) - ) + raise Exception(f"Expected unit_ to be a str, received: {type(unit_)}") self.class_ = class__ self.id_ = id__ @@ -19112,17 +16725,13 @@ class PayloadListArgs(Type): _toPy = {"patterns": "patterns"} def __init__(self, patterns=None, **unknown_fields): - """ - patterns : typing.Sequence[str] - """ + """Patterns : typing.Sequence[str]""" patterns_ = patterns # Validate arguments against known Juju API types. if patterns_ is not None and not isinstance(patterns_, (bytes, str, list)): raise Exception( - "Expected patterns_ to be a Sequence, received: {}".format( - type(patterns_) - ) + f"Expected patterns_ to be a Sequence, received: {type(patterns_)}" ) self.patterns = patterns_ @@ -19134,17 +16743,13 @@ class PayloadListResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~Payload] - """ + """Results : typing.Sequence[~Payload]""" results_ = [Payload.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -19156,8 +16761,7 @@ class PendingResourceUpload(Type): _toPy = {"Filename": "filename", "Name": "name", "Type": "type_"} def __init__(self, filename=None, name=None, type_=None, **unknown_fields): - """ - filename : str + """Filename : str name : str type_ : str """ @@ -19168,18 +16772,14 @@ def __init__(self, filename=None, name=None, type_=None, **unknown_fields): # Validate arguments against known Juju API types. if filename_ is not None and not isinstance(filename_, (bytes, str)): raise Exception( - "Expected filename_ to be a str, received: {}".format(type(filename_)) + f"Expected filename_ to be a str, received: {type(filename_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") self.filename = filename_ self.name = name_ @@ -19192,8 +16792,7 @@ class Placement(Type): _toPy = {"directive": "directive", "scope": "scope"} def __init__(self, directive=None, scope=None, **unknown_fields): - """ - directive : str + """Directive : str scope : str """ directive_ = directive @@ -19202,13 +16801,11 @@ def __init__(self, directive=None, scope=None, **unknown_fields): # Validate arguments against known Juju API types. if directive_ is not None and not isinstance(directive_, (bytes, str)): raise Exception( - "Expected directive_ to be a str, received: {}".format(type(directive_)) + f"Expected directive_ to be a str, received: {type(directive_)}" ) if scope_ is not None and not isinstance(scope_, (bytes, str)): - raise Exception( - "Expected scope_ to be a str, received: {}".format(type(scope_)) - ) + raise Exception(f"Expected scope_ to be a str, received: {type(scope_)}") self.directive = directive_ self.scope = scope_ @@ -19237,8 +16834,7 @@ def __init__( nonce=None, **unknown_fields, ): - """ - data_dir : str + """data_dir : str disable_package_commands : bool machine_id : str nonce : str @@ -19251,29 +16847,23 @@ def __init__( # Validate arguments against known Juju API types. if data_dir_ is not None and not isinstance(data_dir_, (bytes, str)): raise Exception( - "Expected data_dir_ to be a str, received: {}".format(type(data_dir_)) + f"Expected data_dir_ to be a str, received: {type(data_dir_)}" ) if disable_package_commands_ is not None and not isinstance( disable_package_commands_, bool ): raise Exception( - "Expected disable_package_commands_ to be a bool, received: {}".format( - type(disable_package_commands_) - ) + f"Expected disable_package_commands_ to be a bool, received: {type(disable_package_commands_)}" ) if machine_id_ is not None and not isinstance(machine_id_, (bytes, str)): raise Exception( - "Expected machine_id_ to be a str, received: {}".format( - type(machine_id_) - ) + f"Expected machine_id_ to be a str, received: {type(machine_id_)}" ) if nonce_ is not None and not isinstance(nonce_, (bytes, str)): - raise Exception( - "Expected nonce_ to be a str, received: {}".format(type(nonce_)) - ) + raise Exception(f"Expected nonce_ to be a str, received: {type(nonce_)}") self.data_dir = data_dir_ self.disable_package_commands = disable_package_commands_ @@ -19287,16 +16877,12 @@ class ProvisioningScriptResult(Type): _toPy = {"script": "script"} def __init__(self, script=None, **unknown_fields): - """ - script : str - """ + """Script : str""" script_ = script # Validate arguments against known Juju API types. if script_ is not None and not isinstance(script_, (bytes, str)): - raise Exception( - "Expected script_ to be a str, received: {}".format(type(script_)) - ) + raise Exception(f"Expected script_ to be a str, received: {type(script_)}") self.script = script_ self.unknown_fields = unknown_fields @@ -19307,8 +16893,7 @@ class Proxy(Type): _toPy = {"config": "config", "type": "type_"} def __init__(self, config=None, type_=None, **unknown_fields): - """ - config : typing.Mapping[str, typing.Any] + """Config : typing.Mapping[str, typing.Any] type_ : str """ config_ = config @@ -19317,13 +16902,11 @@ def __init__(self, config=None, type_=None, **unknown_fields): # Validate arguments against known Juju API types. if config_ is not None and not isinstance(config_, dict): raise Exception( - "Expected config_ to be a Mapping, received: {}".format(type(config_)) + f"Expected config_ to be a Mapping, received: {type(config_)}" ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") self.config = config_ self.type_ = type__ @@ -19335,17 +16918,13 @@ class QueryApplicationOffersResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~ApplicationOfferAdminDetails] - """ + """Results : typing.Sequence[~ApplicationOfferAdminDetails]""" results_ = [ApplicationOfferAdminDetails.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -19357,17 +16936,13 @@ class QueryApplicationOffersResultsV5(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~ApplicationOfferAdminDetailsV5] - """ + """Results : typing.Sequence[~ApplicationOfferAdminDetailsV5]""" results_ = [ApplicationOfferAdminDetailsV5.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -19379,8 +16954,7 @@ class RedirectInfoResult(Type): _toPy = {"ca-cert": "ca_cert", "servers": "servers"} def __init__(self, ca_cert=None, servers=None, **unknown_fields): - """ - ca_cert : str + """ca_cert : str servers : typing.Sequence[~HostPort] """ ca_cert_ = ca_cert @@ -19389,14 +16963,12 @@ def __init__(self, ca_cert=None, servers=None, **unknown_fields): # Validate arguments against known Juju API types. if ca_cert_ is not None and not isinstance(ca_cert_, (bytes, str)): raise Exception( - "Expected ca_cert_ to be a str, received: {}".format(type(ca_cert_)) + f"Expected ca_cert_ to be a str, received: {type(ca_cert_)}" ) if servers_ is not None and not isinstance(servers_, (bytes, str, list)): raise Exception( - "Expected servers_ to be a Sequence, received: {}".format( - type(servers_) - ) + f"Expected servers_ to be a Sequence, received: {type(servers_)}" ) self.ca_cert = ca_cert_ @@ -19409,8 +16981,7 @@ class RegionDefaults(Type): _toPy = {"region-name": "region_name", "value": "value"} def __init__(self, region_name=None, value=None, **unknown_fields): - """ - region_name : str + """region_name : str value : Any """ region_name_ = region_name @@ -19419,9 +16990,7 @@ def __init__(self, region_name=None, value=None, **unknown_fields): # Validate arguments against known Juju API types. if region_name_ is not None and not isinstance(region_name_, (bytes, str)): raise Exception( - "Expected region_name_ to be a str, received: {}".format( - type(region_name_) - ) + f"Expected region_name_ to be a str, received: {type(region_name_)}" ) self.region_name = region_name_ @@ -19434,8 +17003,7 @@ class RelationData(Type): _toPy = {"InScope": "inscope", "UnitData": "unitdata"} def __init__(self, inscope=None, unitdata=None, **unknown_fields): - """ - inscope : bool + """Inscope : bool unitdata : typing.Mapping[str, typing.Any] """ inscope_ = inscope @@ -19444,14 +17012,12 @@ def __init__(self, inscope=None, unitdata=None, **unknown_fields): # Validate arguments against known Juju API types. if inscope_ is not None and not isinstance(inscope_, bool): raise Exception( - "Expected inscope_ to be a bool, received: {}".format(type(inscope_)) + f"Expected inscope_ to be a bool, received: {type(inscope_)}" ) if unitdata_ is not None and not isinstance(unitdata_, dict): raise Exception( - "Expected unitdata_ to be a Mapping, received: {}".format( - type(unitdata_) - ) + f"Expected unitdata_ to be a Mapping, received: {type(unitdata_)}" ) self.inscope = inscope_ @@ -19487,8 +17053,7 @@ def __init__( status=None, **unknown_fields, ): - """ - endpoints : typing.Sequence[~EndpointStatus] + """Endpoints : typing.Sequence[~EndpointStatus] id_ : int interface : str key : str @@ -19505,36 +17070,26 @@ def __init__( # Validate arguments against known Juju API types. if endpoints_ is not None and not isinstance(endpoints_, (bytes, str, list)): raise Exception( - "Expected endpoints_ to be a Sequence, received: {}".format( - type(endpoints_) - ) + f"Expected endpoints_ to be a Sequence, received: {type(endpoints_)}" ) if id__ is not None and not isinstance(id__, int): - raise Exception( - "Expected id__ to be a int, received: {}".format(type(id__)) - ) + raise Exception(f"Expected id__ to be a int, received: {type(id__)}") if interface_ is not None and not isinstance(interface_, (bytes, str)): raise Exception( - "Expected interface_ to be a str, received: {}".format(type(interface_)) + f"Expected interface_ to be a str, received: {type(interface_)}" ) if key_ is not None and not isinstance(key_, (bytes, str)): - raise Exception( - "Expected key_ to be a str, received: {}".format(type(key_)) - ) + raise Exception(f"Expected key_ to be a str, received: {type(key_)}") if scope_ is not None and not isinstance(scope_, (bytes, str)): - raise Exception( - "Expected scope_ to be a str, received: {}".format(type(scope_)) - ) + raise Exception(f"Expected scope_ to be a str, received: {type(scope_)}") if status_ is not None and not isinstance(status_, (dict, DetailedStatus)): raise Exception( - "Expected status_ to be a DetailedStatus, received: {}".format( - type(status_) - ) + f"Expected status_ to be a DetailedStatus, received: {type(status_)}" ) self.endpoints = endpoints_ @@ -19561,8 +17116,7 @@ class RelationSuspendedArg(Type): def __init__( self, message=None, relation_id=None, suspended=None, **unknown_fields ): - """ - message : str + """Message : str relation_id : int suspended : bool """ @@ -19573,21 +17127,17 @@ def __init__( # Validate arguments against known Juju API types. if message_ is not None and not isinstance(message_, (bytes, str)): raise Exception( - "Expected message_ to be a str, received: {}".format(type(message_)) + f"Expected message_ to be a str, received: {type(message_)}" ) if relation_id_ is not None and not isinstance(relation_id_, int): raise Exception( - "Expected relation_id_ to be a int, received: {}".format( - type(relation_id_) - ) + f"Expected relation_id_ to be a int, received: {type(relation_id_)}" ) if suspended_ is not None and not isinstance(suspended_, bool): raise Exception( - "Expected suspended_ to be a bool, received: {}".format( - type(suspended_) - ) + f"Expected suspended_ to be a bool, received: {type(suspended_)}" ) self.message = message_ @@ -19601,16 +17151,12 @@ class RelationSuspendedArgs(Type): _toPy = {"args": "args"} def __init__(self, args=None, **unknown_fields): - """ - args : typing.Sequence[~RelationSuspendedArg] - """ + """Args : typing.Sequence[~RelationSuspendedArg]""" args_ = [RelationSuspendedArg.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception( - "Expected args_ to be a Sequence, received: {}".format(type(args_)) - ) + raise Exception(f"Expected args_ to be a Sequence, received: {type(args_)}") self.args = args_ self.unknown_fields = unknown_fields @@ -19647,8 +17193,7 @@ def __init__( source_model_label=None, **unknown_fields, ): - """ - description : str + """Description : str endpoints : typing.Sequence[~RemoteEndpoint] icon_url_path : str model_tag : str @@ -19667,47 +17212,37 @@ def __init__( # Validate arguments against known Juju API types. if description_ is not None and not isinstance(description_, (bytes, str)): raise Exception( - "Expected description_ to be a str, received: {}".format( - type(description_) - ) + f"Expected description_ to be a str, received: {type(description_)}" ) if endpoints_ is not None and not isinstance(endpoints_, (bytes, str, list)): raise Exception( - "Expected endpoints_ to be a Sequence, received: {}".format( - type(endpoints_) - ) + f"Expected endpoints_ to be a Sequence, received: {type(endpoints_)}" ) if icon_url_path_ is not None and not isinstance(icon_url_path_, (bytes, str)): raise Exception( - "Expected icon_url_path_ to be a str, received: {}".format( - type(icon_url_path_) - ) + f"Expected icon_url_path_ to be a str, received: {type(icon_url_path_)}" ) if model_tag_ is not None and not isinstance(model_tag_, (bytes, str)): raise Exception( - "Expected model_tag_ to be a str, received: {}".format(type(model_tag_)) + f"Expected model_tag_ to be a str, received: {type(model_tag_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if offer_url_ is not None and not isinstance(offer_url_, (bytes, str)): raise Exception( - "Expected offer_url_ to be a str, received: {}".format(type(offer_url_)) + f"Expected offer_url_ to be a str, received: {type(offer_url_)}" ) if source_model_label_ is not None and not isinstance( source_model_label_, (bytes, str) ): raise Exception( - "Expected source_model_label_ to be a str, received: {}".format( - type(source_model_label_) - ) + f"Expected source_model_label_ to be a str, received: {type(source_model_label_)}" ) self.description = description_ @@ -19725,8 +17260,7 @@ class RemoteApplicationInfoResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : RemoteApplicationInfo """ error_ = Error.from_json(error) if error else None @@ -19734,17 +17268,13 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance( result_, (dict, RemoteApplicationInfo) ): raise Exception( - "Expected result_ to be a RemoteApplicationInfo, received: {}".format( - type(result_) - ) + f"Expected result_ to be a RemoteApplicationInfo, received: {type(result_)}" ) self.error = error_ @@ -19757,17 +17287,13 @@ class RemoteApplicationInfoResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~RemoteApplicationInfoResult] - """ + """Results : typing.Sequence[~RemoteApplicationInfoResult]""" results_ = [RemoteApplicationInfoResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -19805,8 +17331,7 @@ def __init__( status=None, **unknown_fields, ): - """ - endpoints : typing.Sequence[~RemoteEndpoint] + """Endpoints : typing.Sequence[~RemoteEndpoint] err : Error life : str offer_name : str @@ -19825,45 +17350,33 @@ def __init__( # Validate arguments against known Juju API types. if endpoints_ is not None and not isinstance(endpoints_, (bytes, str, list)): raise Exception( - "Expected endpoints_ to be a Sequence, received: {}".format( - type(endpoints_) - ) + f"Expected endpoints_ to be a Sequence, received: {type(endpoints_)}" ) if err_ is not None and not isinstance(err_, (dict, Error)): - raise Exception( - "Expected err_ to be a Error, received: {}".format(type(err_)) - ) + raise Exception(f"Expected err_ to be a Error, received: {type(err_)}") if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception( - "Expected life_ to be a str, received: {}".format(type(life_)) - ) + raise Exception(f"Expected life_ to be a str, received: {type(life_)}") if offer_name_ is not None and not isinstance(offer_name_, (bytes, str)): raise Exception( - "Expected offer_name_ to be a str, received: {}".format( - type(offer_name_) - ) + f"Expected offer_name_ to be a str, received: {type(offer_name_)}" ) if offer_url_ is not None and not isinstance(offer_url_, (bytes, str)): raise Exception( - "Expected offer_url_ to be a str, received: {}".format(type(offer_url_)) + f"Expected offer_url_ to be a str, received: {type(offer_url_)}" ) if relations_ is not None and not isinstance(relations_, dict): raise Exception( - "Expected relations_ to be a Mapping, received: {}".format( - type(relations_) - ) + f"Expected relations_ to be a Mapping, received: {type(relations_)}" ) if status_ is not None and not isinstance(status_, (dict, DetailedStatus)): raise Exception( - "Expected status_ to be a DetailedStatus, received: {}".format( - type(status_) - ) + f"Expected status_ to be a DetailedStatus, received: {type(status_)}" ) self.endpoints = endpoints_ @@ -19888,8 +17401,7 @@ class RemoteEndpoint(Type): def __init__( self, interface=None, limit=None, name=None, role=None, **unknown_fields ): - """ - interface : str + """Interface : str limit : int name : str role : str @@ -19902,23 +17414,17 @@ def __init__( # Validate arguments against known Juju API types. if interface_ is not None and not isinstance(interface_, (bytes, str)): raise Exception( - "Expected interface_ to be a str, received: {}".format(type(interface_)) + f"Expected interface_ to be a str, received: {type(interface_)}" ) if limit_ is not None and not isinstance(limit_, int): - raise Exception( - "Expected limit_ to be a int, received: {}".format(type(limit_)) - ) + raise Exception(f"Expected limit_ to be a int, received: {type(limit_)}") if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if role_ is not None and not isinstance(role_, (bytes, str)): - raise Exception( - "Expected role_ to be a str, received: {}".format(type(role_)) - ) + raise Exception(f"Expected role_ to be a str, received: {type(role_)}") self.interface = interface_ self.limit = limit_ @@ -19952,8 +17458,7 @@ def __init__( subnets=None, **unknown_fields, ): - """ - cloud_type : str + """cloud_type : str name : str provider_attributes : typing.Mapping[str, typing.Any] provider_id : str @@ -19968,37 +17473,27 @@ def __init__( # Validate arguments against known Juju API types. if cloud_type_ is not None and not isinstance(cloud_type_, (bytes, str)): raise Exception( - "Expected cloud_type_ to be a str, received: {}".format( - type(cloud_type_) - ) + f"Expected cloud_type_ to be a str, received: {type(cloud_type_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if provider_attributes_ is not None and not isinstance( provider_attributes_, dict ): raise Exception( - "Expected provider_attributes_ to be a Mapping, received: {}".format( - type(provider_attributes_) - ) + f"Expected provider_attributes_ to be a Mapping, received: {type(provider_attributes_)}" ) if provider_id_ is not None and not isinstance(provider_id_, (bytes, str)): raise Exception( - "Expected provider_id_ to be a str, received: {}".format( - type(provider_id_) - ) + f"Expected provider_id_ to be a str, received: {type(provider_id_)}" ) if subnets_ is not None and not isinstance(subnets_, (bytes, str, list)): raise Exception( - "Expected subnets_ to be a Sequence, received: {}".format( - type(subnets_) - ) + f"Expected subnets_ to be a Sequence, received: {type(subnets_)}" ) self.cloud_type = cloud_type_ @@ -20014,16 +17509,12 @@ class RemoveBlocksArgs(Type): _toPy = {"all": "all_"} def __init__(self, all_=None, **unknown_fields): - """ - all_ : bool - """ + """all_ : bool""" all__ = all_ # Validate arguments against known Juju API types. if all__ is not None and not isinstance(all__, bool): - raise Exception( - "Expected all__ to be a bool, received: {}".format(type(all__)) - ) + raise Exception(f"Expected all__ to be a bool, received: {type(all__)}") self.all_ = all__ self.unknown_fields = unknown_fields @@ -20034,8 +17525,7 @@ class RemoveSecretBackendArg(Type): _toPy = {"force": "force", "name": "name"} def __init__(self, force=None, name=None, **unknown_fields): - """ - force : bool + """Force : bool name : str """ force_ = force @@ -20043,14 +17533,10 @@ def __init__(self, force=None, name=None, **unknown_fields): # Validate arguments against known Juju API types. if force_ is not None and not isinstance(force_, bool): - raise Exception( - "Expected force_ to be a bool, received: {}".format(type(force_)) - ) + raise Exception(f"Expected force_ to be a bool, received: {type(force_)}") if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") self.force = force_ self.name = name_ @@ -20062,16 +17548,12 @@ class RemoveSecretBackendArgs(Type): _toPy = {"args": "args"} def __init__(self, args=None, **unknown_fields): - """ - args : typing.Sequence[~RemoveSecretBackendArg] - """ + """Args : typing.Sequence[~RemoveSecretBackendArg]""" args_ = [RemoveSecretBackendArg.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception( - "Expected args_ to be a Sequence, received: {}".format(type(args_)) - ) + raise Exception(f"Expected args_ to be a Sequence, received: {type(args_)}") self.args = args_ self.unknown_fields = unknown_fields @@ -20082,8 +17564,7 @@ class RemoveSpaceParam(Type): _toPy = {"dry-run": "dry_run", "force": "force", "space": "space"} def __init__(self, dry_run=None, force=None, space=None, **unknown_fields): - """ - dry_run : bool + """dry_run : bool force : bool space : Entity """ @@ -20094,18 +17575,14 @@ def __init__(self, dry_run=None, force=None, space=None, **unknown_fields): # Validate arguments against known Juju API types. if dry_run_ is not None and not isinstance(dry_run_, bool): raise Exception( - "Expected dry_run_ to be a bool, received: {}".format(type(dry_run_)) + f"Expected dry_run_ to be a bool, received: {type(dry_run_)}" ) if force_ is not None and not isinstance(force_, bool): - raise Exception( - "Expected force_ to be a bool, received: {}".format(type(force_)) - ) + raise Exception(f"Expected force_ to be a bool, received: {type(force_)}") if space_ is not None and not isinstance(space_, (dict, Entity)): - raise Exception( - "Expected space_ to be a Entity, received: {}".format(type(space_)) - ) + raise Exception(f"Expected space_ to be a Entity, received: {type(space_)}") self.dry_run = dry_run_ self.force = force_ @@ -20118,9 +17595,7 @@ class RemoveSpaceParams(Type): _toPy = {"space-param": "space_param"} def __init__(self, space_param=None, **unknown_fields): - """ - space_param : typing.Sequence[~RemoveSpaceParam] - """ + """space_param : typing.Sequence[~RemoveSpaceParam]""" space_param_ = [RemoveSpaceParam.from_json(o) for o in space_param or []] # Validate arguments against known Juju API types. @@ -20128,9 +17603,7 @@ def __init__(self, space_param=None, **unknown_fields): space_param_, (bytes, str, list) ): raise Exception( - "Expected space_param_ to be a Sequence, received: {}".format( - type(space_param_) - ) + f"Expected space_param_ to be a Sequence, received: {type(space_param_)}" ) self.space_param = space_param_ @@ -20159,8 +17632,7 @@ def __init__( error=None, **unknown_fields, ): - """ - bindings : typing.Sequence[~Entity] + """Bindings : typing.Sequence[~Entity] constraints : typing.Sequence[~Entity] controller_settings : typing.Sequence[str] error : Error @@ -20173,33 +17645,25 @@ def __init__( # Validate arguments against known Juju API types. if bindings_ is not None and not isinstance(bindings_, (bytes, str, list)): raise Exception( - "Expected bindings_ to be a Sequence, received: {}".format( - type(bindings_) - ) + f"Expected bindings_ to be a Sequence, received: {type(bindings_)}" ) if constraints_ is not None and not isinstance( constraints_, (bytes, str, list) ): raise Exception( - "Expected constraints_ to be a Sequence, received: {}".format( - type(constraints_) - ) + f"Expected constraints_ to be a Sequence, received: {type(constraints_)}" ) if controller_settings_ is not None and not isinstance( controller_settings_, (bytes, str, list) ): raise Exception( - "Expected controller_settings_ to be a Sequence, received: {}".format( - type(controller_settings_) - ) + f"Expected controller_settings_ to be a Sequence, received: {type(controller_settings_)}" ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") self.bindings = bindings_ self.constraints = constraints_ @@ -20213,17 +17677,13 @@ class RemoveSpaceResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~RemoveSpaceResult] - """ + """Results : typing.Sequence[~RemoveSpaceResult]""" results_ = [RemoveSpaceResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -20235,17 +17695,13 @@ class RemoveStorage(Type): _toPy = {"storage": "storage"} def __init__(self, storage=None, **unknown_fields): - """ - storage : typing.Sequence[~RemoveStorageInstance] - """ + """Storage : typing.Sequence[~RemoveStorageInstance]""" storage_ = [RemoveStorageInstance.from_json(o) for o in storage or []] # Validate arguments against known Juju API types. if storage_ is not None and not isinstance(storage_, (bytes, str, list)): raise Exception( - "Expected storage_ to be a Sequence, received: {}".format( - type(storage_) - ) + f"Expected storage_ to be a Sequence, received: {type(storage_)}" ) self.storage = storage_ @@ -20277,8 +17733,7 @@ def __init__( tag=None, **unknown_fields, ): - """ - destroy_attachments : bool + """destroy_attachments : bool destroy_storage : bool force : bool max_wait : int @@ -20295,32 +17750,24 @@ def __init__( destroy_attachments_, bool ): raise Exception( - "Expected destroy_attachments_ to be a bool, received: {}".format( - type(destroy_attachments_) - ) + f"Expected destroy_attachments_ to be a bool, received: {type(destroy_attachments_)}" ) if destroy_storage_ is not None and not isinstance(destroy_storage_, bool): raise Exception( - "Expected destroy_storage_ to be a bool, received: {}".format( - type(destroy_storage_) - ) + f"Expected destroy_storage_ to be a bool, received: {type(destroy_storage_)}" ) if force_ is not None and not isinstance(force_, bool): - raise Exception( - "Expected force_ to be a bool, received: {}".format(type(force_)) - ) + raise Exception(f"Expected force_ to be a bool, received: {type(force_)}") if max_wait_ is not None and not isinstance(max_wait_, int): raise Exception( - "Expected max_wait_ to be a int, received: {}".format(type(max_wait_)) + f"Expected max_wait_ to be a int, received: {type(max_wait_)}" ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception( - "Expected tag_ to be a str, received: {}".format(type(tag_)) - ) + raise Exception(f"Expected tag_ to be a str, received: {type(tag_)}") self.destroy_attachments = destroy_attachments_ self.destroy_storage = destroy_storage_ @@ -20335,8 +17782,7 @@ class RenameSpaceParams(Type): _toPy = {"from-space-tag": "from_space_tag", "to-space-tag": "to_space_tag"} def __init__(self, from_space_tag=None, to_space_tag=None, **unknown_fields): - """ - from_space_tag : str + """from_space_tag : str to_space_tag : str """ from_space_tag_ = from_space_tag @@ -20347,16 +17793,12 @@ def __init__(self, from_space_tag=None, to_space_tag=None, **unknown_fields): from_space_tag_, (bytes, str) ): raise Exception( - "Expected from_space_tag_ to be a str, received: {}".format( - type(from_space_tag_) - ) + f"Expected from_space_tag_ to be a str, received: {type(from_space_tag_)}" ) if to_space_tag_ is not None and not isinstance(to_space_tag_, (bytes, str)): raise Exception( - "Expected to_space_tag_ to be a str, received: {}".format( - type(to_space_tag_) - ) + f"Expected to_space_tag_ to be a str, received: {type(to_space_tag_)}" ) self.from_space_tag = from_space_tag_ @@ -20369,17 +17811,13 @@ class RenameSpacesParams(Type): _toPy = {"changes": "changes"} def __init__(self, changes=None, **unknown_fields): - """ - changes : typing.Sequence[~RenameSpaceParams] - """ + """Changes : typing.Sequence[~RenameSpaceParams]""" changes_ = [RenameSpaceParams.from_json(o) for o in changes or []] # Validate arguments against known Juju API types. if changes_ is not None and not isinstance(changes_, (bytes, str, list)): raise Exception( - "Expected changes_ to be a Sequence, received: {}".format( - type(changes_) - ) + f"Expected changes_ to be a Sequence, received: {type(changes_)}" ) self.changes = changes_ @@ -20401,8 +17839,7 @@ class ResolveCharmWithChannel(Type): def __init__( self, charm_origin=None, reference=None, switch_charm=None, **unknown_fields ): - """ - charm_origin : CharmOrigin + """charm_origin : CharmOrigin reference : str switch_charm : bool """ @@ -20415,21 +17852,17 @@ def __init__( charm_origin_, (dict, CharmOrigin) ): raise Exception( - "Expected charm_origin_ to be a CharmOrigin, received: {}".format( - type(charm_origin_) - ) + f"Expected charm_origin_ to be a CharmOrigin, received: {type(charm_origin_)}" ) if reference_ is not None and not isinstance(reference_, (bytes, str)): raise Exception( - "Expected reference_ to be a str, received: {}".format(type(reference_)) + f"Expected reference_ to be a str, received: {type(reference_)}" ) if switch_charm_ is not None and not isinstance(switch_charm_, bool): raise Exception( - "Expected switch_charm_ to be a bool, received: {}".format( - type(switch_charm_) - ) + f"Expected switch_charm_ to be a bool, received: {type(switch_charm_)}" ) self.charm_origin = charm_origin_ @@ -20460,8 +17893,7 @@ def __init__( url=None, **unknown_fields, ): - """ - charm_origin : CharmOrigin + """charm_origin : CharmOrigin error : Error supported_bases : typing.Sequence[~Base] url : str @@ -20476,29 +17908,21 @@ def __init__( charm_origin_, (dict, CharmOrigin) ): raise Exception( - "Expected charm_origin_ to be a CharmOrigin, received: {}".format( - type(charm_origin_) - ) + f"Expected charm_origin_ to be a CharmOrigin, received: {type(charm_origin_)}" ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if supported_bases_ is not None and not isinstance( supported_bases_, (bytes, str, list) ): raise Exception( - "Expected supported_bases_ to be a Sequence, received: {}".format( - type(supported_bases_) - ) + f"Expected supported_bases_ to be a Sequence, received: {type(supported_bases_)}" ) if url_ is not None and not isinstance(url_, (bytes, str)): - raise Exception( - "Expected url_ to be a str, received: {}".format(type(url_)) - ) + raise Exception(f"Expected url_ to be a str, received: {type(url_)}") self.charm_origin = charm_origin_ self.error = error_ @@ -20512,17 +17936,13 @@ class ResolveCharmWithChannelResults(Type): _toPy = {"Results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~ResolveCharmWithChannelResult] - """ + """Results : typing.Sequence[~ResolveCharmWithChannelResult]""" results_ = [ResolveCharmWithChannelResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -20534,8 +17954,7 @@ class ResolveCharmsWithChannel(Type): _toPy = {"macaroon": "macaroon", "resolve": "resolve"} def __init__(self, macaroon=None, resolve=None, **unknown_fields): - """ - macaroon : Macaroon + """Macaroon : Macaroon resolve : typing.Sequence[~ResolveCharmWithChannel] """ macaroon_ = Macaroon.from_json(macaroon) if macaroon else None @@ -20544,16 +17963,12 @@ def __init__(self, macaroon=None, resolve=None, **unknown_fields): # Validate arguments against known Juju API types. if macaroon_ is not None and not isinstance(macaroon_, (dict, Macaroon)): raise Exception( - "Expected macaroon_ to be a Macaroon, received: {}".format( - type(macaroon_) - ) + f"Expected macaroon_ to be a Macaroon, received: {type(macaroon_)}" ) if resolve_ is not None and not isinstance(resolve_, (bytes, str, list)): raise Exception( - "Expected resolve_ to be a Sequence, received: {}".format( - type(resolve_) - ) + f"Expected resolve_ to be a Sequence, received: {type(resolve_)}" ) self.macaroon = macaroon_ @@ -20613,8 +18028,7 @@ def __init__( username=None, **unknown_fields, ): - """ - charmresource : CharmResource + """Charmresource : CharmResource application : str description : str fingerprint : typing.Sequence[int] @@ -20651,84 +18065,62 @@ def __init__( charmresource_, (dict, CharmResource) ): raise Exception( - "Expected charmresource_ to be a CharmResource, received: {}".format( - type(charmresource_) - ) + f"Expected charmresource_ to be a CharmResource, received: {type(charmresource_)}" ) if application_ is not None and not isinstance(application_, (bytes, str)): raise Exception( - "Expected application_ to be a str, received: {}".format( - type(application_) - ) + f"Expected application_ to be a str, received: {type(application_)}" ) if description_ is not None and not isinstance(description_, (bytes, str)): raise Exception( - "Expected description_ to be a str, received: {}".format( - type(description_) - ) + f"Expected description_ to be a str, received: {type(description_)}" ) if fingerprint_ is not None and not isinstance( fingerprint_, (bytes, str, list) ): raise Exception( - "Expected fingerprint_ to be a Sequence, received: {}".format( - type(fingerprint_) - ) + f"Expected fingerprint_ to be a Sequence, received: {type(fingerprint_)}" ) if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception( - "Expected id__ to be a str, received: {}".format(type(id__)) - ) + raise Exception(f"Expected id__ to be a str, received: {type(id__)}") if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if origin_ is not None and not isinstance(origin_, (bytes, str)): - raise Exception( - "Expected origin_ to be a str, received: {}".format(type(origin_)) - ) + raise Exception(f"Expected origin_ to be a str, received: {type(origin_)}") if path_ is not None and not isinstance(path_, (bytes, str)): - raise Exception( - "Expected path_ to be a str, received: {}".format(type(path_)) - ) + raise Exception(f"Expected path_ to be a str, received: {type(path_)}") if pending_id_ is not None and not isinstance(pending_id_, (bytes, str)): raise Exception( - "Expected pending_id_ to be a str, received: {}".format( - type(pending_id_) - ) + f"Expected pending_id_ to be a str, received: {type(pending_id_)}" ) if revision_ is not None and not isinstance(revision_, int): raise Exception( - "Expected revision_ to be a int, received: {}".format(type(revision_)) + f"Expected revision_ to be a int, received: {type(revision_)}" ) if size_ is not None and not isinstance(size_, int): - raise Exception( - "Expected size_ to be a int, received: {}".format(type(size_)) - ) + raise Exception(f"Expected size_ to be a int, received: {type(size_)}") if timestamp_ is not None and not isinstance(timestamp_, (bytes, str)): raise Exception( - "Expected timestamp_ to be a str, received: {}".format(type(timestamp_)) + f"Expected timestamp_ to be a str, received: {type(timestamp_)}" ) if type__ is not None and not isinstance(type__, (bytes, str)): - raise Exception( - "Expected type__ to be a str, received: {}".format(type(type__)) - ) + raise Exception(f"Expected type__ to be a str, received: {type(type__)}") if username_ is not None and not isinstance(username_, (bytes, str)): raise Exception( - "Expected username_ to be a str, received: {}".format(type(username_)) + f"Expected username_ to be a str, received: {type(username_)}" ) self.charmresource = charmresource_ @@ -20773,8 +18165,7 @@ def __init__( unit_resources=None, **unknown_fields, ): - """ - errorresult : ErrorResult + """Errorresult : ErrorResult charm_store_resources : typing.Sequence[~CharmResource] error : Error resources : typing.Sequence[~Resource] @@ -20793,39 +18184,29 @@ def __init__( errorresult_, (dict, ErrorResult) ): raise Exception( - "Expected errorresult_ to be a ErrorResult, received: {}".format( - type(errorresult_) - ) + f"Expected errorresult_ to be a ErrorResult, received: {type(errorresult_)}" ) if charm_store_resources_ is not None and not isinstance( charm_store_resources_, (bytes, str, list) ): raise Exception( - "Expected charm_store_resources_ to be a Sequence, received: {}".format( - type(charm_store_resources_) - ) + f"Expected charm_store_resources_ to be a Sequence, received: {type(charm_store_resources_)}" ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if resources_ is not None and not isinstance(resources_, (bytes, str, list)): raise Exception( - "Expected resources_ to be a Sequence, received: {}".format( - type(resources_) - ) + f"Expected resources_ to be a Sequence, received: {type(resources_)}" ) if unit_resources_ is not None and not isinstance( unit_resources_, (bytes, str, list) ): raise Exception( - "Expected unit_resources_ to be a Sequence, received: {}".format( - type(unit_resources_) - ) + f"Expected unit_resources_ to be a Sequence, received: {type(unit_resources_)}" ) self.errorresult = errorresult_ @@ -20841,17 +18222,13 @@ class ResourcesResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~ResourcesResult] - """ + """Results : typing.Sequence[~ResourcesResult]""" results_ = [ResourcesResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -20863,8 +18240,7 @@ class RetryProvisioningArgs(Type): _toPy = {"all": "all_", "machines": "machines"} def __init__(self, all_=None, machines=None, **unknown_fields): - """ - all_ : bool + """all_ : bool machines : typing.Sequence[str] """ all__ = all_ @@ -20872,15 +18248,11 @@ def __init__(self, all_=None, machines=None, **unknown_fields): # Validate arguments against known Juju API types. if all__ is not None and not isinstance(all__, bool): - raise Exception( - "Expected all__ to be a bool, received: {}".format(type(all__)) - ) + raise Exception(f"Expected all__ to be a bool, received: {type(all__)}") if machines_ is not None and not isinstance(machines_, (bytes, str, list)): raise Exception( - "Expected machines_ to be a Sequence, received: {}".format( - type(machines_) - ) + f"Expected machines_ to be a Sequence, received: {type(machines_)}" ) self.all_ = all__ @@ -20893,8 +18265,7 @@ class RevokeCredentialArg(Type): _toPy = {"force": "force", "tag": "tag"} def __init__(self, force=None, tag=None, **unknown_fields): - """ - force : bool + """Force : bool tag : str """ force_ = force @@ -20902,14 +18273,10 @@ def __init__(self, force=None, tag=None, **unknown_fields): # Validate arguments against known Juju API types. if force_ is not None and not isinstance(force_, bool): - raise Exception( - "Expected force_ to be a bool, received: {}".format(type(force_)) - ) + raise Exception(f"Expected force_ to be a bool, received: {type(force_)}") if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception( - "Expected tag_ to be a str, received: {}".format(type(tag_)) - ) + raise Exception(f"Expected tag_ to be a str, received: {type(tag_)}") self.force = force_ self.tag = tag_ @@ -20921,9 +18288,7 @@ class RevokeCredentialArgs(Type): _toPy = {"credentials": "credentials"} def __init__(self, credentials=None, **unknown_fields): - """ - credentials : typing.Sequence[~RevokeCredentialArg] - """ + """Credentials : typing.Sequence[~RevokeCredentialArg]""" credentials_ = [RevokeCredentialArg.from_json(o) for o in credentials or []] # Validate arguments against known Juju API types. @@ -20931,9 +18296,7 @@ def __init__(self, credentials=None, **unknown_fields): credentials_, (bytes, str, list) ): raise Exception( - "Expected credentials_ to be a Sequence, received: {}".format( - type(credentials_) - ) + f"Expected credentials_ to be a Sequence, received: {type(credentials_)}" ) self.credentials = credentials_ @@ -20974,8 +18337,7 @@ def __init__( workload_context=None, **unknown_fields, ): - """ - applications : typing.Sequence[str] + """Applications : typing.Sequence[str] commands : str execution_group : str machines : typing.Sequence[str] @@ -20998,52 +18360,44 @@ def __init__( applications_, (bytes, str, list) ): raise Exception( - "Expected applications_ to be a Sequence, received: {}".format( - type(applications_) - ) + f"Expected applications_ to be a Sequence, received: {type(applications_)}" ) if commands_ is not None and not isinstance(commands_, (bytes, str)): raise Exception( - "Expected commands_ to be a str, received: {}".format(type(commands_)) + f"Expected commands_ to be a str, received: {type(commands_)}" ) if execution_group_ is not None and not isinstance( execution_group_, (bytes, str) ): raise Exception( - "Expected execution_group_ to be a str, received: {}".format( - type(execution_group_) - ) + f"Expected execution_group_ to be a str, received: {type(execution_group_)}" ) if machines_ is not None and not isinstance(machines_, (bytes, str, list)): raise Exception( - "Expected machines_ to be a Sequence, received: {}".format( - type(machines_) - ) + f"Expected machines_ to be a Sequence, received: {type(machines_)}" ) if parallel_ is not None and not isinstance(parallel_, bool): raise Exception( - "Expected parallel_ to be a bool, received: {}".format(type(parallel_)) + f"Expected parallel_ to be a bool, received: {type(parallel_)}" ) if timeout_ is not None and not isinstance(timeout_, int): raise Exception( - "Expected timeout_ to be a int, received: {}".format(type(timeout_)) + f"Expected timeout_ to be a int, received: {type(timeout_)}" ) if units_ is not None and not isinstance(units_, (bytes, str, list)): raise Exception( - "Expected units_ to be a Sequence, received: {}".format(type(units_)) + f"Expected units_ to be a Sequence, received: {type(units_)}" ) if workload_context_ is not None and not isinstance(workload_context_, bool): raise Exception( - "Expected workload_context_ to be a bool, received: {}".format( - type(workload_context_) - ) + f"Expected workload_context_ to be a bool, received: {type(workload_context_)}" ) self.applications = applications_ @@ -21062,8 +18416,7 @@ class SSHAddressResult(Type): _toPy = {"address": "address", "error": "error"} def __init__(self, address=None, error=None, **unknown_fields): - """ - address : str + """Address : str error : Error """ address_ = address @@ -21072,13 +18425,11 @@ def __init__(self, address=None, error=None, **unknown_fields): # Validate arguments against known Juju API types. if address_ is not None and not isinstance(address_, (bytes, str)): raise Exception( - "Expected address_ to be a str, received: {}".format(type(address_)) + f"Expected address_ to be a str, received: {type(address_)}" ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") self.address = address_ self.error = error_ @@ -21090,17 +18441,13 @@ class SSHAddressResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~SSHAddressResult] - """ + """Results : typing.Sequence[~SSHAddressResult]""" results_ = [SSHAddressResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -21112,8 +18459,7 @@ class SSHAddressesResult(Type): _toPy = {"addresses": "addresses", "error": "error"} def __init__(self, addresses=None, error=None, **unknown_fields): - """ - addresses : typing.Sequence[str] + """Addresses : typing.Sequence[str] error : Error """ addresses_ = addresses @@ -21122,15 +18468,11 @@ def __init__(self, addresses=None, error=None, **unknown_fields): # Validate arguments against known Juju API types. if addresses_ is not None and not isinstance(addresses_, (bytes, str, list)): raise Exception( - "Expected addresses_ to be a Sequence, received: {}".format( - type(addresses_) - ) + f"Expected addresses_ to be a Sequence, received: {type(addresses_)}" ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") self.addresses = addresses_ self.error = error_ @@ -21142,17 +18484,13 @@ class SSHAddressesResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~SSHAddressesResult] - """ + """Results : typing.Sequence[~SSHAddressesResult]""" results_ = [SSHAddressesResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -21164,17 +18502,13 @@ class SSHProxyResult(Type): _toPy = {"use-proxy": "use_proxy"} def __init__(self, use_proxy=None, **unknown_fields): - """ - use_proxy : bool - """ + """use_proxy : bool""" use_proxy_ = use_proxy # Validate arguments against known Juju API types. if use_proxy_ is not None and not isinstance(use_proxy_, bool): raise Exception( - "Expected use_proxy_ to be a bool, received: {}".format( - type(use_proxy_) - ) + f"Expected use_proxy_ to be a bool, received: {type(use_proxy_)}" ) self.use_proxy = use_proxy_ @@ -21186,8 +18520,7 @@ class SSHPublicKeysResult(Type): _toPy = {"error": "error", "public-keys": "public_keys"} def __init__(self, error=None, public_keys=None, **unknown_fields): - """ - error : Error + """Error : Error public_keys : typing.Sequence[str] """ error_ = Error.from_json(error) if error else None @@ -21195,17 +18528,13 @@ def __init__(self, error=None, public_keys=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if public_keys_ is not None and not isinstance( public_keys_, (bytes, str, list) ): raise Exception( - "Expected public_keys_ to be a Sequence, received: {}".format( - type(public_keys_) - ) + f"Expected public_keys_ to be a Sequence, received: {type(public_keys_)}" ) self.error = error_ @@ -21218,17 +18547,13 @@ class SSHPublicKeysResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~SSHPublicKeysResult] - """ + """Results : typing.Sequence[~SSHPublicKeysResult]""" results_ = [SSHPublicKeysResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -21240,15 +18565,13 @@ class ScaleApplicationInfo(Type): _toPy = {"num-units": "num_units"} def __init__(self, num_units=None, **unknown_fields): - """ - num_units : int - """ + """num_units : int""" num_units_ = num_units # Validate arguments against known Juju API types. if num_units_ is not None and not isinstance(num_units_, int): raise Exception( - "Expected num_units_ to be a int, received: {}".format(type(num_units_)) + f"Expected num_units_ to be a int, received: {type(num_units_)}" ) self.num_units = num_units_ @@ -21277,8 +18600,7 @@ def __init__( scale_change=None, **unknown_fields, ): - """ - application_tag : str + """application_tag : str force : bool scale : int scale_change : int @@ -21293,26 +18615,18 @@ def __init__( application_tag_, (bytes, str) ): raise Exception( - "Expected application_tag_ to be a str, received: {}".format( - type(application_tag_) - ) + f"Expected application_tag_ to be a str, received: {type(application_tag_)}" ) if force_ is not None and not isinstance(force_, bool): - raise Exception( - "Expected force_ to be a bool, received: {}".format(type(force_)) - ) + raise Exception(f"Expected force_ to be a bool, received: {type(force_)}") if scale_ is not None and not isinstance(scale_, int): - raise Exception( - "Expected scale_ to be a int, received: {}".format(type(scale_)) - ) + raise Exception(f"Expected scale_ to be a int, received: {type(scale_)}") if scale_change_ is not None and not isinstance(scale_change_, int): raise Exception( - "Expected scale_change_ to be a int, received: {}".format( - type(scale_change_) - ) + f"Expected scale_change_ to be a int, received: {type(scale_change_)}" ) self.application_tag = application_tag_ @@ -21327,8 +18641,7 @@ class ScaleApplicationResult(Type): _toPy = {"error": "error", "info": "info"} def __init__(self, error=None, info=None, **unknown_fields): - """ - error : Error + """Error : Error info : ScaleApplicationInfo """ error_ = Error.from_json(error) if error else None @@ -21336,15 +18649,11 @@ def __init__(self, error=None, info=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if info_ is not None and not isinstance(info_, (dict, ScaleApplicationInfo)): raise Exception( - "Expected info_ to be a ScaleApplicationInfo, received: {}".format( - type(info_) - ) + f"Expected info_ to be a ScaleApplicationInfo, received: {type(info_)}" ) self.error = error_ @@ -21357,17 +18666,13 @@ class ScaleApplicationResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~ScaleApplicationResult] - """ + """Results : typing.Sequence[~ScaleApplicationResult]""" results_ = [ScaleApplicationResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -21379,9 +18684,7 @@ class ScaleApplicationsParams(Type): _toPy = {"applications": "applications"} def __init__(self, applications=None, **unknown_fields): - """ - applications : typing.Sequence[~ScaleApplicationParams] - """ + """Applications : typing.Sequence[~ScaleApplicationParams]""" applications_ = [ ScaleApplicationParams.from_json(o) for o in applications or [] ] @@ -21391,9 +18694,7 @@ def __init__(self, applications=None, **unknown_fields): applications_, (bytes, str, list) ): raise Exception( - "Expected applications_ to be a Sequence, received: {}".format( - type(applications_) - ) + f"Expected applications_ to be a Sequence, received: {type(applications_)}" ) self.applications = applications_ @@ -21422,8 +18723,7 @@ def __init__( token_rotate_interval=None, **unknown_fields, ): - """ - backend_type : str + """backend_type : str config : typing.Mapping[str, typing.Any] name : str token_rotate_interval : int @@ -21436,28 +18736,22 @@ def __init__( # Validate arguments against known Juju API types. if backend_type_ is not None and not isinstance(backend_type_, (bytes, str)): raise Exception( - "Expected backend_type_ to be a str, received: {}".format( - type(backend_type_) - ) + f"Expected backend_type_ to be a str, received: {type(backend_type_)}" ) if config_ is not None and not isinstance(config_, dict): raise Exception( - "Expected config_ to be a Mapping, received: {}".format(type(config_)) + f"Expected config_ to be a Mapping, received: {type(config_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if token_rotate_interval_ is not None and not isinstance( token_rotate_interval_, int ): raise Exception( - "Expected token_rotate_interval_ to be a int, received: {}".format( - type(token_rotate_interval_) - ) + f"Expected token_rotate_interval_ to be a int, received: {type(token_rotate_interval_)}" ) self.backend_type = backend_type_ @@ -21495,8 +18789,7 @@ def __init__( status=None, **unknown_fields, ): - """ - error : Error + """Error : Error id_ : str message : str num_secrets : int @@ -21512,38 +18805,28 @@ def __init__( # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception( - "Expected id__ to be a str, received: {}".format(type(id__)) - ) + raise Exception(f"Expected id__ to be a str, received: {type(id__)}") if message_ is not None and not isinstance(message_, (bytes, str)): raise Exception( - "Expected message_ to be a str, received: {}".format(type(message_)) + f"Expected message_ to be a str, received: {type(message_)}" ) if num_secrets_ is not None and not isinstance(num_secrets_, int): raise Exception( - "Expected num_secrets_ to be a int, received: {}".format( - type(num_secrets_) - ) + f"Expected num_secrets_ to be a int, received: {type(num_secrets_)}" ) if result_ is not None and not isinstance(result_, (dict, SecretBackend)): raise Exception( - "Expected result_ to be a SecretBackend, received: {}".format( - type(result_) - ) + f"Expected result_ to be a SecretBackend, received: {type(result_)}" ) if status_ is not None and not isinstance(status_, (bytes, str)): - raise Exception( - "Expected status_ to be a str, received: {}".format(type(status_)) - ) + raise Exception(f"Expected status_ to be a str, received: {type(status_)}") self.error = error_ self.id_ = id__ @@ -21559,8 +18842,7 @@ class SecretContentParams(Type): _toPy = {"checksum": "checksum", "data": "data", "value-ref": "value_ref"} def __init__(self, checksum=None, data=None, value_ref=None, **unknown_fields): - """ - checksum : str + """Checksum : str data : typing.Mapping[str, str] value_ref : SecretValueRef """ @@ -21571,21 +18853,17 @@ def __init__(self, checksum=None, data=None, value_ref=None, **unknown_fields): # Validate arguments against known Juju API types. if checksum_ is not None and not isinstance(checksum_, (bytes, str)): raise Exception( - "Expected checksum_ to be a str, received: {}".format(type(checksum_)) + f"Expected checksum_ to be a str, received: {type(checksum_)}" ) if data_ is not None and not isinstance(data_, dict): - raise Exception( - "Expected data_ to be a Mapping, received: {}".format(type(data_)) - ) + raise Exception(f"Expected data_ to be a Mapping, received: {type(data_)}") if value_ref_ is not None and not isinstance( value_ref_, (dict, SecretValueRef) ): raise Exception( - "Expected value_ref_ to be a SecretValueRef, received: {}".format( - type(value_ref_) - ) + f"Expected value_ref_ to be a SecretValueRef, received: {type(value_ref_)}" ) self.checksum = checksum_ @@ -21622,8 +18900,7 @@ def __init__( value_ref=None, **unknown_fields, ): - """ - backend_name : str + """backend_name : str create_time : str expire_time : str revision : int @@ -21640,44 +18917,34 @@ def __init__( # Validate arguments against known Juju API types. if backend_name_ is not None and not isinstance(backend_name_, (bytes, str)): raise Exception( - "Expected backend_name_ to be a str, received: {}".format( - type(backend_name_) - ) + f"Expected backend_name_ to be a str, received: {type(backend_name_)}" ) if create_time_ is not None and not isinstance(create_time_, (bytes, str)): raise Exception( - "Expected create_time_ to be a str, received: {}".format( - type(create_time_) - ) + f"Expected create_time_ to be a str, received: {type(create_time_)}" ) if expire_time_ is not None and not isinstance(expire_time_, (bytes, str)): raise Exception( - "Expected expire_time_ to be a str, received: {}".format( - type(expire_time_) - ) + f"Expected expire_time_ to be a str, received: {type(expire_time_)}" ) if revision_ is not None and not isinstance(revision_, int): raise Exception( - "Expected revision_ to be a int, received: {}".format(type(revision_)) + f"Expected revision_ to be a int, received: {type(revision_)}" ) if update_time_ is not None and not isinstance(update_time_, (bytes, str)): raise Exception( - "Expected update_time_ to be a str, received: {}".format( - type(update_time_) - ) + f"Expected update_time_ to be a str, received: {type(update_time_)}" ) if value_ref_ is not None and not isinstance( value_ref_, (dict, SecretValueRef) ): raise Exception( - "Expected value_ref_ to be a SecretValueRef, received: {}".format( - type(value_ref_) - ) + f"Expected value_ref_ to be a SecretValueRef, received: {type(value_ref_)}" ) self.backend_name = backend_name_ @@ -21694,8 +18961,7 @@ class SecretValueRef(Type): _toPy = {"backend-id": "backend_id", "revision-id": "revision_id"} def __init__(self, backend_id=None, revision_id=None, **unknown_fields): - """ - backend_id : str + """backend_id : str revision_id : str """ backend_id_ = backend_id @@ -21704,16 +18970,12 @@ def __init__(self, backend_id=None, revision_id=None, **unknown_fields): # Validate arguments against known Juju API types. if backend_id_ is not None and not isinstance(backend_id_, (bytes, str)): raise Exception( - "Expected backend_id_ to be a str, received: {}".format( - type(backend_id_) - ) + f"Expected backend_id_ to be a str, received: {type(backend_id_)}" ) if revision_id_ is not None and not isinstance(revision_id_, (bytes, str)): raise Exception( - "Expected revision_id_ to be a str, received: {}".format( - type(revision_id_) - ) + f"Expected revision_id_ to be a str, received: {type(revision_id_)}" ) self.backend_id = backend_id_ @@ -21726,8 +18988,7 @@ class SecretValueResult(Type): _toPy = {"data": "data", "error": "error"} def __init__(self, data=None, error=None, **unknown_fields): - """ - data : typing.Mapping[str, str] + """Data : typing.Mapping[str, str] error : Error """ data_ = data @@ -21735,14 +18996,10 @@ def __init__(self, data=None, error=None, **unknown_fields): # Validate arguments against known Juju API types. if data_ is not None and not isinstance(data_, dict): - raise Exception( - "Expected data_ to be a Mapping, received: {}".format(type(data_)) - ) + raise Exception(f"Expected data_ to be a Mapping, received: {type(data_)}") if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") self.data = data_ self.error = error_ @@ -21766,8 +19023,7 @@ class SecretsFilter(Type): def __init__( self, label=None, owner_tag=None, revision=None, uri=None, **unknown_fields ): - """ - label : str + """Label : str owner_tag : str revision : int uri : str @@ -21779,24 +19035,20 @@ def __init__( # Validate arguments against known Juju API types. if label_ is not None and not isinstance(label_, (bytes, str)): - raise Exception( - "Expected label_ to be a str, received: {}".format(type(label_)) - ) + raise Exception(f"Expected label_ to be a str, received: {type(label_)}") if owner_tag_ is not None and not isinstance(owner_tag_, (bytes, str)): raise Exception( - "Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_)) + f"Expected owner_tag_ to be a str, received: {type(owner_tag_)}" ) if revision_ is not None and not isinstance(revision_, int): raise Exception( - "Expected revision_ to be a int, received: {}".format(type(revision_)) + f"Expected revision_ to be a int, received: {type(revision_)}" ) if uri_ is not None and not isinstance(uri_, (bytes, str)): - raise Exception( - "Expected uri_ to be a str, received: {}".format(type(uri_)) - ) + raise Exception(f"Expected uri_ to be a str, received: {type(uri_)}") self.label = label_ self.owner_tag = owner_tag_ @@ -21810,8 +19062,7 @@ class SetConstraints(Type): _toPy = {"application": "application", "constraints": "constraints"} def __init__(self, application=None, constraints=None, **unknown_fields): - """ - application : str + """Application : str constraints : Value """ application_ = application @@ -21820,16 +19071,12 @@ def __init__(self, application=None, constraints=None, **unknown_fields): # Validate arguments against known Juju API types. if application_ is not None and not isinstance(application_, (bytes, str)): raise Exception( - "Expected application_ to be a str, received: {}".format( - type(application_) - ) + f"Expected application_ to be a str, received: {type(application_)}" ) if constraints_ is not None and not isinstance(constraints_, (dict, Value)): raise Exception( - "Expected constraints_ to be a Value, received: {}".format( - type(constraints_) - ) + f"Expected constraints_ to be a Value, received: {type(constraints_)}" ) self.application = application_ @@ -21842,15 +19089,13 @@ class SetModelDefaults(Type): _toPy = {"config": "config"} def __init__(self, config=None, **unknown_fields): - """ - config : typing.Sequence[~ModelDefaultValues] - """ + """Config : typing.Sequence[~ModelDefaultValues]""" config_ = [ModelDefaultValues.from_json(o) for o in config or []] # Validate arguments against known Juju API types. if config_ is not None and not isinstance(config_, (bytes, str, list)): raise Exception( - "Expected config_ to be a Sequence, received: {}".format(type(config_)) + f"Expected config_ to be a Sequence, received: {type(config_)}" ) self.config = config_ @@ -21879,8 +19124,7 @@ def __init__( space=None, **unknown_fields, ): - """ - applications : typing.Sequence[str] + """Applications : typing.Sequence[str] error : Error machine_count : int space : Space @@ -21895,27 +19139,19 @@ def __init__( applications_, (bytes, str, list) ): raise Exception( - "Expected applications_ to be a Sequence, received: {}".format( - type(applications_) - ) + f"Expected applications_ to be a Sequence, received: {type(applications_)}" ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if machine_count_ is not None and not isinstance(machine_count_, int): raise Exception( - "Expected machine_count_ to be a int, received: {}".format( - type(machine_count_) - ) + f"Expected machine_count_ to be a int, received: {type(machine_count_)}" ) if space_ is not None and not isinstance(space_, (dict, Space)): - raise Exception( - "Expected space_ to be a Space, received: {}".format(type(space_)) - ) + raise Exception(f"Expected space_ to be a Space, received: {type(space_)}") self.applications = applications_ self.error = error_ @@ -21929,17 +19165,13 @@ class ShowSpaceResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~ShowSpaceResult] - """ + """Results : typing.Sequence[~ShowSpaceResult]""" results_ = [ShowSpaceResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -21951,8 +19183,7 @@ class Space(Type): _toPy = {"error": "error", "id": "id_", "name": "name", "subnets": "subnets"} def __init__(self, error=None, id_=None, name=None, subnets=None, **unknown_fields): - """ - error : Error + """Error : Error id_ : str name : str subnets : typing.Sequence[~Subnet] @@ -21964,25 +19195,17 @@ def __init__(self, error=None, id_=None, name=None, subnets=None, **unknown_fiel # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception( - "Expected id__ to be a str, received: {}".format(type(id__)) - ) + raise Exception(f"Expected id__ to be a str, received: {type(id__)}") if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if subnets_ is not None and not isinstance(subnets_, (bytes, str, list)): raise Exception( - "Expected subnets_ to be a Sequence, received: {}".format( - type(subnets_) - ) + f"Expected subnets_ to be a Sequence, received: {type(subnets_)}" ) self.error = error_ @@ -21999,8 +19222,7 @@ class StatusHistoryFilter(Type): def __init__( self, date=None, delta=None, exclude=None, size=None, **unknown_fields ): - """ - date : str + """Date : str delta : int exclude : typing.Sequence[str] size : int @@ -22012,26 +19234,18 @@ def __init__( # Validate arguments against known Juju API types. if date_ is not None and not isinstance(date_, (bytes, str)): - raise Exception( - "Expected date_ to be a str, received: {}".format(type(date_)) - ) + raise Exception(f"Expected date_ to be a str, received: {type(date_)}") if delta_ is not None and not isinstance(delta_, int): - raise Exception( - "Expected delta_ to be a int, received: {}".format(type(delta_)) - ) + raise Exception(f"Expected delta_ to be a int, received: {type(delta_)}") if exclude_ is not None and not isinstance(exclude_, (bytes, str, list)): raise Exception( - "Expected exclude_ to be a Sequence, received: {}".format( - type(exclude_) - ) + f"Expected exclude_ to be a Sequence, received: {type(exclude_)}" ) if size_ is not None and not isinstance(size_, int): - raise Exception( - "Expected size_ to be a int, received: {}".format(type(size_)) - ) + raise Exception(f"Expected size_ to be a int, received: {type(size_)}") self.date = date_ self.delta = delta_ @@ -22057,8 +19271,7 @@ class StatusHistoryRequest(Type): def __init__( self, filter_=None, historykind=None, size=None, tag=None, **unknown_fields ): - """ - filter_ : StatusHistoryFilter + """filter_ : StatusHistoryFilter historykind : str size : int tag : str @@ -22073,27 +19286,19 @@ def __init__( filter__, (dict, StatusHistoryFilter) ): raise Exception( - "Expected filter__ to be a StatusHistoryFilter, received: {}".format( - type(filter__) - ) + f"Expected filter__ to be a StatusHistoryFilter, received: {type(filter__)}" ) if historykind_ is not None and not isinstance(historykind_, (bytes, str)): raise Exception( - "Expected historykind_ to be a str, received: {}".format( - type(historykind_) - ) + f"Expected historykind_ to be a str, received: {type(historykind_)}" ) if size_ is not None and not isinstance(size_, int): - raise Exception( - "Expected size_ to be a int, received: {}".format(type(size_)) - ) + raise Exception(f"Expected size_ to be a int, received: {type(size_)}") if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception( - "Expected tag_ to be a str, received: {}".format(type(tag_)) - ) + raise Exception(f"Expected tag_ to be a str, received: {type(tag_)}") self.filter_ = filter__ self.historykind = historykind_ @@ -22107,17 +19312,13 @@ class StatusHistoryRequests(Type): _toPy = {"requests": "requests"} def __init__(self, requests=None, **unknown_fields): - """ - requests : typing.Sequence[~StatusHistoryRequest] - """ + """Requests : typing.Sequence[~StatusHistoryRequest]""" requests_ = [StatusHistoryRequest.from_json(o) for o in requests or []] # Validate arguments against known Juju API types. if requests_ is not None and not isinstance(requests_, (bytes, str, list)): raise Exception( - "Expected requests_ to be a Sequence, received: {}".format( - type(requests_) - ) + f"Expected requests_ to be a Sequence, received: {type(requests_)}" ) self.requests = requests_ @@ -22129,8 +19330,7 @@ class StatusHistoryResult(Type): _toPy = {"error": "error", "history": "history"} def __init__(self, error=None, history=None, **unknown_fields): - """ - error : Error + """Error : Error history : History """ error_ = Error.from_json(error) if error else None @@ -22138,13 +19338,11 @@ def __init__(self, error=None, history=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if history_ is not None and not isinstance(history_, (dict, History)): raise Exception( - "Expected history_ to be a History, received: {}".format(type(history_)) + f"Expected history_ to be a History, received: {type(history_)}" ) self.error = error_ @@ -22157,17 +19355,13 @@ class StatusHistoryResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~StatusHistoryResult] - """ + """Results : typing.Sequence[~StatusHistoryResult]""" results_ = [StatusHistoryResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -22179,8 +19373,7 @@ class StatusParams(Type): _toPy = {"include-storage": "include_storage", "patterns": "patterns"} def __init__(self, include_storage=None, patterns=None, **unknown_fields): - """ - include_storage : bool + """include_storage : bool patterns : typing.Sequence[str] """ include_storage_ = include_storage @@ -22189,16 +19382,12 @@ def __init__(self, include_storage=None, patterns=None, **unknown_fields): # Validate arguments against known Juju API types. if include_storage_ is not None and not isinstance(include_storage_, bool): raise Exception( - "Expected include_storage_ to be a bool, received: {}".format( - type(include_storage_) - ) + f"Expected include_storage_ to be a bool, received: {type(include_storage_)}" ) if patterns_ is not None and not isinstance(patterns_, (bytes, str, list)): raise Exception( - "Expected patterns_ to be a Sequence, received: {}".format( - type(patterns_) - ) + f"Expected patterns_ to be a Sequence, received: {type(patterns_)}" ) self.include_storage = include_storage_ @@ -22211,8 +19400,7 @@ class StorageAddParams(Type): _toPy = {"name": "name", "storage": "storage", "unit": "unit"} def __init__(self, name=None, storage=None, unit=None, **unknown_fields): - """ - name : str + """Name : str storage : StorageConstraints unit : str """ @@ -22222,23 +19410,17 @@ def __init__(self, name=None, storage=None, unit=None, **unknown_fields): # Validate arguments against known Juju API types. if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if storage_ is not None and not isinstance( storage_, (dict, StorageConstraints) ): raise Exception( - "Expected storage_ to be a StorageConstraints, received: {}".format( - type(storage_) - ) + f"Expected storage_ to be a StorageConstraints, received: {type(storage_)}" ) if unit_ is not None and not isinstance(unit_, (bytes, str)): - raise Exception( - "Expected unit_ to be a str, received: {}".format(type(unit_)) - ) + raise Exception(f"Expected unit_ to be a str, received: {type(unit_)}") self.name = name_ self.storage = storage_ @@ -22271,8 +19453,7 @@ def __init__( unit_tag=None, **unknown_fields, ): - """ - life : str + """Life : str location : str machine_tag : str storage_tag : str @@ -22286,32 +19467,26 @@ def __init__( # Validate arguments against known Juju API types. if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception( - "Expected life_ to be a str, received: {}".format(type(life_)) - ) + raise Exception(f"Expected life_ to be a str, received: {type(life_)}") if location_ is not None and not isinstance(location_, (bytes, str)): raise Exception( - "Expected location_ to be a str, received: {}".format(type(location_)) + f"Expected location_ to be a str, received: {type(location_)}" ) if machine_tag_ is not None and not isinstance(machine_tag_, (bytes, str)): raise Exception( - "Expected machine_tag_ to be a str, received: {}".format( - type(machine_tag_) - ) + f"Expected machine_tag_ to be a str, received: {type(machine_tag_)}" ) if storage_tag_ is not None and not isinstance(storage_tag_, (bytes, str)): raise Exception( - "Expected storage_tag_ to be a str, received: {}".format( - type(storage_tag_) - ) + f"Expected storage_tag_ to be a str, received: {type(storage_tag_)}" ) if unit_tag_ is not None and not isinstance(unit_tag_, (bytes, str)): raise Exception( - "Expected unit_tag_ to be a str, received: {}".format(type(unit_tag_)) + f"Expected unit_tag_ to be a str, received: {type(unit_tag_)}" ) self.life = life_ @@ -22327,8 +19502,7 @@ class StorageAttachmentId(Type): _toPy = {"storage-tag": "storage_tag", "unit-tag": "unit_tag"} def __init__(self, storage_tag=None, unit_tag=None, **unknown_fields): - """ - storage_tag : str + """storage_tag : str unit_tag : str """ storage_tag_ = storage_tag @@ -22337,14 +19511,12 @@ def __init__(self, storage_tag=None, unit_tag=None, **unknown_fields): # Validate arguments against known Juju API types. if storage_tag_ is not None and not isinstance(storage_tag_, (bytes, str)): raise Exception( - "Expected storage_tag_ to be a str, received: {}".format( - type(storage_tag_) - ) + f"Expected storage_tag_ to be a str, received: {type(storage_tag_)}" ) if unit_tag_ is not None and not isinstance(unit_tag_, (bytes, str)): raise Exception( - "Expected unit_tag_ to be a str, received: {}".format(type(unit_tag_)) + f"Expected unit_tag_ to be a str, received: {type(unit_tag_)}" ) self.storage_tag = storage_tag_ @@ -22357,16 +19529,12 @@ class StorageAttachmentIds(Type): _toPy = {"ids": "ids"} def __init__(self, ids=None, **unknown_fields): - """ - ids : typing.Sequence[~StorageAttachmentId] - """ + """Ids : typing.Sequence[~StorageAttachmentId]""" ids_ = [StorageAttachmentId.from_json(o) for o in ids or []] # Validate arguments against known Juju API types. if ids_ is not None and not isinstance(ids_, (bytes, str, list)): - raise Exception( - "Expected ids_ to be a Sequence, received: {}".format(type(ids_)) - ) + raise Exception(f"Expected ids_ to be a Sequence, received: {type(ids_)}") self.ids = ids_ self.unknown_fields = unknown_fields @@ -22377,8 +19545,7 @@ class StorageConstraints(Type): _toPy = {"count": "count", "pool": "pool", "size": "size"} def __init__(self, count=None, pool=None, size=None, **unknown_fields): - """ - count : int + """Count : int pool : str size : int """ @@ -22388,19 +19555,13 @@ def __init__(self, count=None, pool=None, size=None, **unknown_fields): # Validate arguments against known Juju API types. if count_ is not None and not isinstance(count_, int): - raise Exception( - "Expected count_ to be a int, received: {}".format(type(count_)) - ) + raise Exception(f"Expected count_ to be a int, received: {type(count_)}") if pool_ is not None and not isinstance(pool_, (bytes, str)): - raise Exception( - "Expected pool_ to be a str, received: {}".format(type(pool_)) - ) + raise Exception(f"Expected pool_ to be a str, received: {type(pool_)}") if size_ is not None and not isinstance(size_, int): - raise Exception( - "Expected size_ to be a int, received: {}".format(type(size_)) - ) + raise Exception(f"Expected size_ to be a int, received: {type(size_)}") self.count = count_ self.pool = pool_ @@ -22413,8 +19574,7 @@ class StorageDetachmentParams(Type): _toPy = {"force": "force", "ids": "ids", "max-wait": "max_wait"} def __init__(self, force=None, ids=None, max_wait=None, **unknown_fields): - """ - force : bool + """Force : bool ids : StorageAttachmentIds max_wait : int """ @@ -22424,20 +19584,16 @@ def __init__(self, force=None, ids=None, max_wait=None, **unknown_fields): # Validate arguments against known Juju API types. if force_ is not None and not isinstance(force_, bool): - raise Exception( - "Expected force_ to be a bool, received: {}".format(type(force_)) - ) + raise Exception(f"Expected force_ to be a bool, received: {type(force_)}") if ids_ is not None and not isinstance(ids_, (dict, StorageAttachmentIds)): raise Exception( - "Expected ids_ to be a StorageAttachmentIds, received: {}".format( - type(ids_) - ) + f"Expected ids_ to be a StorageAttachmentIds, received: {type(ids_)}" ) if max_wait_ is not None and not isinstance(max_wait_, int): raise Exception( - "Expected max_wait_ to be a int, received: {}".format(type(max_wait_)) + f"Expected max_wait_ to be a int, received: {type(max_wait_)}" ) self.force = force_ @@ -22477,8 +19633,7 @@ def __init__( storage_tag=None, **unknown_fields, ): - """ - attachments : typing.Mapping[str, ~StorageAttachmentDetails] + """Attachments : typing.Mapping[str, ~StorageAttachmentDetails] kind : int life : str owner_tag : str @@ -22500,45 +19655,33 @@ def __init__( # Validate arguments against known Juju API types. if attachments_ is not None and not isinstance(attachments_, dict): raise Exception( - "Expected attachments_ to be a Mapping, received: {}".format( - type(attachments_) - ) + f"Expected attachments_ to be a Mapping, received: {type(attachments_)}" ) if kind_ is not None and not isinstance(kind_, int): - raise Exception( - "Expected kind_ to be a int, received: {}".format(type(kind_)) - ) + raise Exception(f"Expected kind_ to be a int, received: {type(kind_)}") if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception( - "Expected life_ to be a str, received: {}".format(type(life_)) - ) + raise Exception(f"Expected life_ to be a str, received: {type(life_)}") if owner_tag_ is not None and not isinstance(owner_tag_, (bytes, str)): raise Exception( - "Expected owner_tag_ to be a str, received: {}".format(type(owner_tag_)) + f"Expected owner_tag_ to be a str, received: {type(owner_tag_)}" ) if persistent_ is not None and not isinstance(persistent_, bool): raise Exception( - "Expected persistent_ to be a bool, received: {}".format( - type(persistent_) - ) + f"Expected persistent_ to be a bool, received: {type(persistent_)}" ) if status_ is not None and not isinstance(status_, (dict, EntityStatus)): raise Exception( - "Expected status_ to be a EntityStatus, received: {}".format( - type(status_) - ) + f"Expected status_ to be a EntityStatus, received: {type(status_)}" ) if storage_tag_ is not None and not isinstance(storage_tag_, (bytes, str)): raise Exception( - "Expected storage_tag_ to be a str, received: {}".format( - type(storage_tag_) - ) + f"Expected storage_tag_ to be a str, received: {type(storage_tag_)}" ) self.attachments = attachments_ @@ -22556,8 +19699,7 @@ class StorageDetailsListResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : typing.Sequence[~StorageDetails] """ error_ = Error.from_json(error) if error else None @@ -22565,13 +19707,11 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance(result_, (bytes, str, list)): raise Exception( - "Expected result_ to be a Sequence, received: {}".format(type(result_)) + f"Expected result_ to be a Sequence, received: {type(result_)}" ) self.error = error_ @@ -22584,17 +19724,13 @@ class StorageDetailsListResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~StorageDetailsListResult] - """ + """Results : typing.Sequence[~StorageDetailsListResult]""" results_ = [StorageDetailsListResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -22606,8 +19742,7 @@ class StorageDetailsResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : StorageDetails """ error_ = Error.from_json(error) if error else None @@ -22615,15 +19750,11 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance(result_, (dict, StorageDetails)): raise Exception( - "Expected result_ to be a StorageDetails, received: {}".format( - type(result_) - ) + f"Expected result_ to be a StorageDetails, received: {type(result_)}" ) self.error = error_ @@ -22636,17 +19767,13 @@ class StorageDetailsResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~StorageDetailsResult] - """ + """Results : typing.Sequence[~StorageDetailsResult]""" results_ = [StorageDetailsResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -22667,17 +19794,13 @@ class StorageFilters(Type): _toPy = {"filters": "filters"} def __init__(self, filters=None, **unknown_fields): - """ - filters : typing.Sequence[~StorageFilter] - """ + """Filters : typing.Sequence[~StorageFilter]""" filters_ = [StorageFilter.from_json(o) for o in filters or []] # Validate arguments against known Juju API types. if filters_ is not None and not isinstance(filters_, (bytes, str, list)): raise Exception( - "Expected filters_ to be a Sequence, received: {}".format( - type(filters_) - ) + f"Expected filters_ to be a Sequence, received: {type(filters_)}" ) self.filters = filters_ @@ -22689,8 +19812,7 @@ class StoragePool(Type): _toPy = {"attrs": "attrs", "name": "name", "provider": "provider"} def __init__(self, attrs=None, name=None, provider=None, **unknown_fields): - """ - attrs : typing.Mapping[str, typing.Any] + """Attrs : typing.Mapping[str, typing.Any] name : str provider : str """ @@ -22701,17 +19823,15 @@ def __init__(self, attrs=None, name=None, provider=None, **unknown_fields): # Validate arguments against known Juju API types. if attrs_ is not None and not isinstance(attrs_, dict): raise Exception( - "Expected attrs_ to be a Mapping, received: {}".format(type(attrs_)) + f"Expected attrs_ to be a Mapping, received: {type(attrs_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if provider_ is not None and not isinstance(provider_, (bytes, str)): raise Exception( - "Expected provider_ to be a str, received: {}".format(type(provider_)) + f"Expected provider_ to be a str, received: {type(provider_)}" ) self.attrs = attrs_ @@ -22724,16 +19844,14 @@ class StoragePoolArgs(Type): _toSchema = {"pools": "pools"} _toPy = {"pools": "pools"} - def __init__(self, pools=None, **unknown_fields): - """ - pools : typing.Sequence[~StoragePool] - """ + def __init__(self, pools=None, **unknown_fields): + """Pools : typing.Sequence[~StoragePool]""" pools_ = [StoragePool.from_json(o) for o in pools or []] # Validate arguments against known Juju API types. if pools_ is not None and not isinstance(pools_, (bytes, str, list)): raise Exception( - "Expected pools_ to be a Sequence, received: {}".format(type(pools_)) + f"Expected pools_ to be a Sequence, received: {type(pools_)}" ) self.pools = pools_ @@ -22745,16 +19863,12 @@ class StoragePoolDeleteArg(Type): _toPy = {"name": "name"} def __init__(self, name=None, **unknown_fields): - """ - name : str - """ + """Name : str""" name_ = name # Validate arguments against known Juju API types. if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") self.name = name_ self.unknown_fields = unknown_fields @@ -22765,15 +19879,13 @@ class StoragePoolDeleteArgs(Type): _toPy = {"pools": "pools"} def __init__(self, pools=None, **unknown_fields): - """ - pools : typing.Sequence[~StoragePoolDeleteArg] - """ + """Pools : typing.Sequence[~StoragePoolDeleteArg]""" pools_ = [StoragePoolDeleteArg.from_json(o) for o in pools or []] # Validate arguments against known Juju API types. if pools_ is not None and not isinstance(pools_, (bytes, str, list)): raise Exception( - "Expected pools_ to be a Sequence, received: {}".format(type(pools_)) + f"Expected pools_ to be a Sequence, received: {type(pools_)}" ) self.pools = pools_ @@ -22785,8 +19897,7 @@ class StoragePoolFilter(Type): _toPy = {"names": "names", "providers": "providers"} def __init__(self, names=None, providers=None, **unknown_fields): - """ - names : typing.Sequence[str] + """Names : typing.Sequence[str] providers : typing.Sequence[str] """ names_ = names @@ -22795,14 +19906,12 @@ def __init__(self, names=None, providers=None, **unknown_fields): # Validate arguments against known Juju API types. if names_ is not None and not isinstance(names_, (bytes, str, list)): raise Exception( - "Expected names_ to be a Sequence, received: {}".format(type(names_)) + f"Expected names_ to be a Sequence, received: {type(names_)}" ) if providers_ is not None and not isinstance(providers_, (bytes, str, list)): raise Exception( - "Expected providers_ to be a Sequence, received: {}".format( - type(providers_) - ) + f"Expected providers_ to be a Sequence, received: {type(providers_)}" ) self.names = names_ @@ -22815,17 +19924,13 @@ class StoragePoolFilters(Type): _toPy = {"filters": "filters"} def __init__(self, filters=None, **unknown_fields): - """ - filters : typing.Sequence[~StoragePoolFilter] - """ + """Filters : typing.Sequence[~StoragePoolFilter]""" filters_ = [StoragePoolFilter.from_json(o) for o in filters or []] # Validate arguments against known Juju API types. if filters_ is not None and not isinstance(filters_, (bytes, str, list)): raise Exception( - "Expected filters_ to be a Sequence, received: {}".format( - type(filters_) - ) + f"Expected filters_ to be a Sequence, received: {type(filters_)}" ) self.filters = filters_ @@ -22837,8 +19942,7 @@ class StoragePoolsResult(Type): _toPy = {"error": "error", "storage-pools": "storage_pools"} def __init__(self, error=None, storage_pools=None, **unknown_fields): - """ - error : Error + """Error : Error storage_pools : typing.Sequence[~StoragePool] """ error_ = Error.from_json(error) if error else None @@ -22846,17 +19950,13 @@ def __init__(self, error=None, storage_pools=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if storage_pools_ is not None and not isinstance( storage_pools_, (bytes, str, list) ): raise Exception( - "Expected storage_pools_ to be a Sequence, received: {}".format( - type(storage_pools_) - ) + f"Expected storage_pools_ to be a Sequence, received: {type(storage_pools_)}" ) self.error = error_ @@ -22869,17 +19969,13 @@ class StoragePoolsResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~StoragePoolsResult] - """ + """Results : typing.Sequence[~StoragePoolsResult]""" results_ = [StoragePoolsResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -22891,17 +19987,13 @@ class StoragesAddParams(Type): _toPy = {"storages": "storages"} def __init__(self, storages=None, **unknown_fields): - """ - storages : typing.Sequence[~StorageAddParams] - """ + """Storages : typing.Sequence[~StorageAddParams]""" storages_ = [StorageAddParams.from_json(o) for o in storages or []] # Validate arguments against known Juju API types. if storages_ is not None and not isinstance(storages_, (bytes, str, list)): raise Exception( - "Expected storages_ to be a Sequence, received: {}".format( - type(storages_) - ) + f"Expected storages_ to be a Sequence, received: {type(storages_)}" ) self.storages = storages_ @@ -22913,8 +20005,7 @@ class StringResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : str """ error_ = Error.from_json(error) if error else None @@ -22922,14 +20013,10 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance(result_, (bytes, str)): - raise Exception( - "Expected result_ to be a str, received: {}".format(type(result_)) - ) + raise Exception(f"Expected result_ to be a str, received: {type(result_)}") self.error = error_ self.result = result_ @@ -22941,17 +20028,13 @@ class StringResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~StringResult] - """ + """Results : typing.Sequence[~StringResult]""" results_ = [StringResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -22963,8 +20046,7 @@ class StringsResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : typing.Sequence[str] """ error_ = Error.from_json(error) if error else None @@ -22972,13 +20054,11 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance(result_, (bytes, str, list)): raise Exception( - "Expected result_ to be a Sequence, received: {}".format(type(result_)) + f"Expected result_ to be a Sequence, received: {type(result_)}" ) self.error = error_ @@ -22991,17 +20071,13 @@ class StringsResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~StringsResult] - """ + """Results : typing.Sequence[~StringsResult]""" results_ = [StringsResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -23013,8 +20089,7 @@ class StringsWatchResult(Type): _toPy = {"changes": "changes", "error": "error", "watcher-id": "watcher_id"} def __init__(self, changes=None, error=None, watcher_id=None, **unknown_fields): - """ - changes : typing.Sequence[str] + """Changes : typing.Sequence[str] error : Error watcher_id : str """ @@ -23025,21 +20100,15 @@ def __init__(self, changes=None, error=None, watcher_id=None, **unknown_fields): # Validate arguments against known Juju API types. if changes_ is not None and not isinstance(changes_, (bytes, str, list)): raise Exception( - "Expected changes_ to be a Sequence, received: {}".format( - type(changes_) - ) + f"Expected changes_ to be a Sequence, received: {type(changes_)}" ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if watcher_id_ is not None and not isinstance(watcher_id_, (bytes, str)): raise Exception( - "Expected watcher_id_ to be a str, received: {}".format( - type(watcher_id_) - ) + f"Expected watcher_id_ to be a str, received: {type(watcher_id_)}" ) self.changes = changes_ @@ -23053,17 +20122,13 @@ class StringsWatchResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~StringsWatchResult] - """ + """Results : typing.Sequence[~StringsWatchResult]""" results_ = [StringsWatchResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -23107,8 +20172,7 @@ def __init__( zones=None, **unknown_fields, ): - """ - cidr : str + """Cidr : str life : str provider_id : str provider_network_id : str @@ -23130,58 +20194,46 @@ def __init__( # Validate arguments against known Juju API types. if cidr_ is not None and not isinstance(cidr_, (bytes, str)): - raise Exception( - "Expected cidr_ to be a str, received: {}".format(type(cidr_)) - ) + raise Exception(f"Expected cidr_ to be a str, received: {type(cidr_)}") if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception( - "Expected life_ to be a str, received: {}".format(type(life_)) - ) + raise Exception(f"Expected life_ to be a str, received: {type(life_)}") if provider_id_ is not None and not isinstance(provider_id_, (bytes, str)): raise Exception( - "Expected provider_id_ to be a str, received: {}".format( - type(provider_id_) - ) + f"Expected provider_id_ to be a str, received: {type(provider_id_)}" ) if provider_network_id_ is not None and not isinstance( provider_network_id_, (bytes, str) ): raise Exception( - "Expected provider_network_id_ to be a str, received: {}".format( - type(provider_network_id_) - ) + f"Expected provider_network_id_ to be a str, received: {type(provider_network_id_)}" ) if provider_space_id_ is not None and not isinstance( provider_space_id_, (bytes, str) ): raise Exception( - "Expected provider_space_id_ to be a str, received: {}".format( - type(provider_space_id_) - ) + f"Expected provider_space_id_ to be a str, received: {type(provider_space_id_)}" ) if space_tag_ is not None and not isinstance(space_tag_, (bytes, str)): raise Exception( - "Expected space_tag_ to be a str, received: {}".format(type(space_tag_)) + f"Expected space_tag_ to be a str, received: {type(space_tag_)}" ) if status_ is not None and not isinstance(status_, (bytes, str)): - raise Exception( - "Expected status_ to be a str, received: {}".format(type(status_)) - ) + raise Exception(f"Expected status_ to be a str, received: {type(status_)}") if vlan_tag_ is not None and not isinstance(vlan_tag_, int): raise Exception( - "Expected vlan_tag_ to be a int, received: {}".format(type(vlan_tag_)) + f"Expected vlan_tag_ to be a int, received: {type(vlan_tag_)}" ) if zones_ is not None and not isinstance(zones_, (bytes, str, list)): raise Exception( - "Expected zones_ to be a Sequence, received: {}".format(type(zones_)) + f"Expected zones_ to be a Sequence, received: {type(zones_)}" ) self.cidr = cidr_ @@ -23239,8 +20291,7 @@ def __init__( zones=None, **unknown_fields, ): - """ - subnet : Subnet + """Subnet : Subnet cidr : str id_ : str life : str @@ -23267,67 +20318,53 @@ def __init__( # Validate arguments against known Juju API types. if subnet_ is not None and not isinstance(subnet_, (dict, Subnet)): raise Exception( - "Expected subnet_ to be a Subnet, received: {}".format(type(subnet_)) + f"Expected subnet_ to be a Subnet, received: {type(subnet_)}" ) if cidr_ is not None and not isinstance(cidr_, (bytes, str)): - raise Exception( - "Expected cidr_ to be a str, received: {}".format(type(cidr_)) - ) + raise Exception(f"Expected cidr_ to be a str, received: {type(cidr_)}") if id__ is not None and not isinstance(id__, (bytes, str)): - raise Exception( - "Expected id__ to be a str, received: {}".format(type(id__)) - ) + raise Exception(f"Expected id__ to be a str, received: {type(id__)}") if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception( - "Expected life_ to be a str, received: {}".format(type(life_)) - ) + raise Exception(f"Expected life_ to be a str, received: {type(life_)}") if provider_id_ is not None and not isinstance(provider_id_, (bytes, str)): raise Exception( - "Expected provider_id_ to be a str, received: {}".format( - type(provider_id_) - ) + f"Expected provider_id_ to be a str, received: {type(provider_id_)}" ) if provider_network_id_ is not None and not isinstance( provider_network_id_, (bytes, str) ): raise Exception( - "Expected provider_network_id_ to be a str, received: {}".format( - type(provider_network_id_) - ) + f"Expected provider_network_id_ to be a str, received: {type(provider_network_id_)}" ) if provider_space_id_ is not None and not isinstance( provider_space_id_, (bytes, str) ): raise Exception( - "Expected provider_space_id_ to be a str, received: {}".format( - type(provider_space_id_) - ) + f"Expected provider_space_id_ to be a str, received: {type(provider_space_id_)}" ) if space_tag_ is not None and not isinstance(space_tag_, (bytes, str)): raise Exception( - "Expected space_tag_ to be a str, received: {}".format(type(space_tag_)) + f"Expected space_tag_ to be a str, received: {type(space_tag_)}" ) if status_ is not None and not isinstance(status_, (bytes, str)): - raise Exception( - "Expected status_ to be a str, received: {}".format(type(status_)) - ) + raise Exception(f"Expected status_ to be a str, received: {type(status_)}") if vlan_tag_ is not None and not isinstance(vlan_tag_, int): raise Exception( - "Expected vlan_tag_ to be a int, received: {}".format(type(vlan_tag_)) + f"Expected vlan_tag_ to be a int, received: {type(vlan_tag_)}" ) if zones_ is not None and not isinstance(zones_, (bytes, str, list)): raise Exception( - "Expected zones_ to be a Sequence, received: {}".format(type(zones_)) + f"Expected zones_ to be a Sequence, received: {type(zones_)}" ) self.subnet = subnet_ @@ -23349,8 +20386,7 @@ class SubnetsFilters(Type): _toPy = {"space-tag": "space_tag", "zone": "zone"} def __init__(self, space_tag=None, zone=None, **unknown_fields): - """ - space_tag : str + """space_tag : str zone : str """ space_tag_ = space_tag @@ -23359,13 +20395,11 @@ def __init__(self, space_tag=None, zone=None, **unknown_fields): # Validate arguments against known Juju API types. if space_tag_ is not None and not isinstance(space_tag_, (bytes, str)): raise Exception( - "Expected space_tag_ to be a str, received: {}".format(type(space_tag_)) + f"Expected space_tag_ to be a str, received: {type(space_tag_)}" ) if zone_ is not None and not isinstance(zone_, (bytes, str)): - raise Exception( - "Expected zone_ to be a str, received: {}".format(type(zone_)) - ) + raise Exception(f"Expected zone_ to be a str, received: {type(zone_)}") self.space_tag = space_tag_ self.zone = zone_ @@ -23377,8 +20411,7 @@ class SubnetsResult(Type): _toPy = {"error": "error", "subnets": "subnets"} def __init__(self, error=None, subnets=None, **unknown_fields): - """ - error : Error + """Error : Error subnets : typing.Sequence[~SubnetV2] """ error_ = Error.from_json(error) if error else None @@ -23386,15 +20419,11 @@ def __init__(self, error=None, subnets=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if subnets_ is not None and not isinstance(subnets_, (bytes, str, list)): raise Exception( - "Expected subnets_ to be a Sequence, received: {}".format( - type(subnets_) - ) + f"Expected subnets_ to be a Sequence, received: {type(subnets_)}" ) self.error = error_ @@ -23407,17 +20436,13 @@ class SubnetsResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~SubnetsResult] - """ + """Results : typing.Sequence[~SubnetsResult]""" results_ = [SubnetsResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -23429,17 +20454,13 @@ class SummaryWatcherID(Type): _toPy = {"watcher-id": "watcher_id"} def __init__(self, watcher_id=None, **unknown_fields): - """ - watcher_id : str - """ + """watcher_id : str""" watcher_id_ = watcher_id # Validate arguments against known Juju API types. if watcher_id_ is not None and not isinstance(watcher_id_, (bytes, str)): raise Exception( - "Expected watcher_id_ to be a str, received: {}".format( - type(watcher_id_) - ) + f"Expected watcher_id_ to be a str, received: {type(watcher_id_)}" ) self.watcher_id = watcher_id_ @@ -23451,8 +20472,7 @@ class SupportedFeature(Type): _toPy = {"description": "description", "name": "name", "version": "version"} def __init__(self, description=None, name=None, version=None, **unknown_fields): - """ - description : str + """Description : str name : str version : str """ @@ -23463,19 +20483,15 @@ def __init__(self, description=None, name=None, version=None, **unknown_fields): # Validate arguments against known Juju API types. if description_ is not None and not isinstance(description_, (bytes, str)): raise Exception( - "Expected description_ to be a str, received: {}".format( - type(description_) - ) + f"Expected description_ to be a str, received: {type(description_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if version_ is not None and not isinstance(version_, (bytes, str)): raise Exception( - "Expected version_ to be a str, received: {}".format(type(version_)) + f"Expected version_ to be a str, received: {type(version_)}" ) self.description = description_ @@ -23489,8 +20505,7 @@ class TaggedCredential(Type): _toPy = {"credential": "credential", "tag": "tag"} def __init__(self, credential=None, tag=None, **unknown_fields): - """ - credential : CloudCredential + """Credential : CloudCredential tag : str """ credential_ = CloudCredential.from_json(credential) if credential else None @@ -23501,15 +20516,11 @@ def __init__(self, credential=None, tag=None, **unknown_fields): credential_, (dict, CloudCredential) ): raise Exception( - "Expected credential_ to be a CloudCredential, received: {}".format( - type(credential_) - ) + f"Expected credential_ to be a CloudCredential, received: {type(credential_)}" ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception( - "Expected tag_ to be a str, received: {}".format(type(tag_)) - ) + raise Exception(f"Expected tag_ to be a str, received: {type(tag_)}") self.credential = credential_ self.tag = tag_ @@ -23521,9 +20532,7 @@ class TaggedCredentials(Type): _toPy = {"credentials": "credentials"} def __init__(self, credentials=None, **unknown_fields): - """ - credentials : typing.Sequence[~TaggedCredential] - """ + """Credentials : typing.Sequence[~TaggedCredential]""" credentials_ = [TaggedCredential.from_json(o) for o in credentials or []] # Validate arguments against known Juju API types. @@ -23531,9 +20540,7 @@ def __init__(self, credentials=None, **unknown_fields): credentials_, (bytes, str, list) ): raise Exception( - "Expected credentials_ to be a Sequence, received: {}".format( - type(credentials_) - ) + f"Expected credentials_ to be a Sequence, received: {type(credentials_)}" ) self.credentials = credentials_ @@ -23547,8 +20554,7 @@ class Tools(Type): def __init__( self, sha256=None, size=None, url=None, version=None, **unknown_fields ): - """ - sha256 : str + """sha256 : str size : int url : str version : Binary @@ -23560,23 +20566,17 @@ def __init__( # Validate arguments against known Juju API types. if sha256_ is not None and not isinstance(sha256_, (bytes, str)): - raise Exception( - "Expected sha256_ to be a str, received: {}".format(type(sha256_)) - ) + raise Exception(f"Expected sha256_ to be a str, received: {type(sha256_)}") if size_ is not None and not isinstance(size_, int): - raise Exception( - "Expected size_ to be a int, received: {}".format(type(size_)) - ) + raise Exception(f"Expected size_ to be a int, received: {type(size_)}") if url_ is not None and not isinstance(url_, (bytes, str)): - raise Exception( - "Expected url_ to be a str, received: {}".format(type(url_)) - ) + raise Exception(f"Expected url_ to be a str, received: {type(url_)}") if version_ is not None and not isinstance(version_, (dict, Binary)): raise Exception( - "Expected version_ to be a Binary, received: {}".format(type(version_)) + f"Expected version_ to be a Binary, received: {type(version_)}" ) self.sha256 = sha256_ @@ -23591,8 +20591,7 @@ class UnitInfoResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : UnitResult """ error_ = Error.from_json(error) if error else None @@ -23600,15 +20599,11 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance(result_, (dict, UnitResult)): raise Exception( - "Expected result_ to be a UnitResult, received: {}".format( - type(result_) - ) + f"Expected result_ to be a UnitResult, received: {type(result_)}" ) self.error = error_ @@ -23621,17 +20616,13 @@ class UnitInfoResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~UnitInfoResult] - """ + """Results : typing.Sequence[~UnitInfoResult]""" results_ = [UnitInfoResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -23660,8 +20651,7 @@ def __init__( tag=None, **unknown_fields, ): - """ - entity : Entity + """Entity : Entity download_progress : typing.Mapping[str, int] resources : typing.Sequence[~Resource] tag : str @@ -23674,27 +20664,21 @@ def __init__( # Validate arguments against known Juju API types. if entity_ is not None and not isinstance(entity_, (dict, Entity)): raise Exception( - "Expected entity_ to be a Entity, received: {}".format(type(entity_)) + f"Expected entity_ to be a Entity, received: {type(entity_)}" ) if download_progress_ is not None and not isinstance(download_progress_, dict): raise Exception( - "Expected download_progress_ to be a Mapping, received: {}".format( - type(download_progress_) - ) + f"Expected download_progress_ to be a Mapping, received: {type(download_progress_)}" ) if resources_ is not None and not isinstance(resources_, (bytes, str, list)): raise Exception( - "Expected resources_ to be a Sequence, received: {}".format( - type(resources_) - ) + f"Expected resources_ to be a Sequence, received: {type(resources_)}" ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception( - "Expected tag_ to be a str, received: {}".format(type(tag_)) - ) + raise Exception(f"Expected tag_ to be a str, received: {type(tag_)}") self.entity = entity_ self.download_progress = download_progress_ @@ -23746,8 +20730,7 @@ def __init__( workload_version=None, **unknown_fields, ): - """ - address : str + """Address : str charm : str leader : bool life : str @@ -23776,75 +20759,57 @@ def __init__( # Validate arguments against known Juju API types. if address_ is not None and not isinstance(address_, (bytes, str)): raise Exception( - "Expected address_ to be a str, received: {}".format(type(address_)) + f"Expected address_ to be a str, received: {type(address_)}" ) if charm_ is not None and not isinstance(charm_, (bytes, str)): - raise Exception( - "Expected charm_ to be a str, received: {}".format(type(charm_)) - ) + raise Exception(f"Expected charm_ to be a str, received: {type(charm_)}") if leader_ is not None and not isinstance(leader_, bool): - raise Exception( - "Expected leader_ to be a bool, received: {}".format(type(leader_)) - ) + raise Exception(f"Expected leader_ to be a bool, received: {type(leader_)}") if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception( - "Expected life_ to be a str, received: {}".format(type(life_)) - ) + raise Exception(f"Expected life_ to be a str, received: {type(life_)}") if machine_ is not None and not isinstance(machine_, (bytes, str)): raise Exception( - "Expected machine_ to be a str, received: {}".format(type(machine_)) + f"Expected machine_ to be a str, received: {type(machine_)}" ) if opened_ports_ is not None and not isinstance( opened_ports_, (bytes, str, list) ): raise Exception( - "Expected opened_ports_ to be a Sequence, received: {}".format( - type(opened_ports_) - ) + f"Expected opened_ports_ to be a Sequence, received: {type(opened_ports_)}" ) if provider_id_ is not None and not isinstance(provider_id_, (bytes, str)): raise Exception( - "Expected provider_id_ to be a str, received: {}".format( - type(provider_id_) - ) + f"Expected provider_id_ to be a str, received: {type(provider_id_)}" ) if public_address_ is not None and not isinstance( public_address_, (bytes, str) ): raise Exception( - "Expected public_address_ to be a str, received: {}".format( - type(public_address_) - ) + f"Expected public_address_ to be a str, received: {type(public_address_)}" ) if relation_data_ is not None and not isinstance( relation_data_, (bytes, str, list) ): raise Exception( - "Expected relation_data_ to be a Sequence, received: {}".format( - type(relation_data_) - ) + f"Expected relation_data_ to be a Sequence, received: {type(relation_data_)}" ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception( - "Expected tag_ to be a str, received: {}".format(type(tag_)) - ) + raise Exception(f"Expected tag_ to be a str, received: {type(tag_)}") if workload_version_ is not None and not isinstance( workload_version_, (bytes, str) ): raise Exception( - "Expected workload_version_ to be a str, received: {}".format( - type(workload_version_) - ) + f"Expected workload_version_ to be a str, received: {type(workload_version_)}" ) self.address = address_ @@ -23904,8 +20869,7 @@ def __init__( workload_version=None, **unknown_fields, ): - """ - address : str + """Address : str agent_status : DetailedStatus charm : str leader : bool @@ -23936,81 +20900,63 @@ def __init__( # Validate arguments against known Juju API types. if address_ is not None and not isinstance(address_, (bytes, str)): raise Exception( - "Expected address_ to be a str, received: {}".format(type(address_)) + f"Expected address_ to be a str, received: {type(address_)}" ) if agent_status_ is not None and not isinstance( agent_status_, (dict, DetailedStatus) ): raise Exception( - "Expected agent_status_ to be a DetailedStatus, received: {}".format( - type(agent_status_) - ) + f"Expected agent_status_ to be a DetailedStatus, received: {type(agent_status_)}" ) if charm_ is not None and not isinstance(charm_, (bytes, str)): - raise Exception( - "Expected charm_ to be a str, received: {}".format(type(charm_)) - ) + raise Exception(f"Expected charm_ to be a str, received: {type(charm_)}") if leader_ is not None and not isinstance(leader_, bool): - raise Exception( - "Expected leader_ to be a bool, received: {}".format(type(leader_)) - ) + raise Exception(f"Expected leader_ to be a bool, received: {type(leader_)}") if machine_ is not None and not isinstance(machine_, (bytes, str)): raise Exception( - "Expected machine_ to be a str, received: {}".format(type(machine_)) + f"Expected machine_ to be a str, received: {type(machine_)}" ) if opened_ports_ is not None and not isinstance( opened_ports_, (bytes, str, list) ): raise Exception( - "Expected opened_ports_ to be a Sequence, received: {}".format( - type(opened_ports_) - ) + f"Expected opened_ports_ to be a Sequence, received: {type(opened_ports_)}" ) if provider_id_ is not None and not isinstance(provider_id_, (bytes, str)): raise Exception( - "Expected provider_id_ to be a str, received: {}".format( - type(provider_id_) - ) + f"Expected provider_id_ to be a str, received: {type(provider_id_)}" ) if public_address_ is not None and not isinstance( public_address_, (bytes, str) ): raise Exception( - "Expected public_address_ to be a str, received: {}".format( - type(public_address_) - ) + f"Expected public_address_ to be a str, received: {type(public_address_)}" ) if subordinates_ is not None and not isinstance(subordinates_, dict): raise Exception( - "Expected subordinates_ to be a Mapping, received: {}".format( - type(subordinates_) - ) + f"Expected subordinates_ to be a Mapping, received: {type(subordinates_)}" ) if workload_status_ is not None and not isinstance( workload_status_, (dict, DetailedStatus) ): raise Exception( - "Expected workload_status_ to be a DetailedStatus, received: {}".format( - type(workload_status_) - ) + f"Expected workload_status_ to be a DetailedStatus, received: {type(workload_status_)}" ) if workload_version_ is not None and not isinstance( workload_version_, (bytes, str) ): raise Exception( - "Expected workload_version_ to be a str, received: {}".format( - type(workload_version_) - ) + f"Expected workload_version_ to be a str, received: {type(workload_version_)}" ) self.address = address_ @@ -24032,8 +20978,7 @@ class UnitsResolved(Type): _toPy = {"all": "all_", "retry": "retry", "tags": "tags"} def __init__(self, all_=None, retry=None, tags=None, **unknown_fields): - """ - all_ : bool + """all_ : bool retry : bool tags : Entities """ @@ -24043,19 +20988,13 @@ def __init__(self, all_=None, retry=None, tags=None, **unknown_fields): # Validate arguments against known Juju API types. if all__ is not None and not isinstance(all__, bool): - raise Exception( - "Expected all__ to be a bool, received: {}".format(type(all__)) - ) + raise Exception(f"Expected all__ to be a bool, received: {type(all__)}") if retry_ is not None and not isinstance(retry_, bool): - raise Exception( - "Expected retry_ to be a bool, received: {}".format(type(retry_)) - ) + raise Exception(f"Expected retry_ to be a bool, received: {type(retry_)}") if tags_ is not None and not isinstance(tags_, (dict, Entities)): - raise Exception( - "Expected tags_ to be a Entities, received: {}".format(type(tags_)) - ) + raise Exception(f"Expected tags_ to be a Entities, received: {type(tags_)}") self.all_ = all__ self.retry = retry_ @@ -24068,16 +21007,12 @@ class UnsetModelDefaults(Type): _toPy = {"keys": "keys"} def __init__(self, keys=None, **unknown_fields): - """ - keys : typing.Sequence[~ModelUnsetKeys] - """ + """Keys : typing.Sequence[~ModelUnsetKeys]""" keys_ = [ModelUnsetKeys.from_json(o) for o in keys or []] # Validate arguments against known Juju API types. if keys_ is not None and not isinstance(keys_, (bytes, str, list)): - raise Exception( - "Expected keys_ to be a Sequence, received: {}".format(type(keys_)) - ) + raise Exception(f"Expected keys_ to be a Sequence, received: {type(keys_)}") self.keys = keys_ self.unknown_fields = unknown_fields @@ -24088,8 +21023,7 @@ class UpdateChannelArg(Type): _toPy = {"channel": "channel", "force": "force", "tag": "tag"} def __init__(self, channel=None, force=None, tag=None, **unknown_fields): - """ - channel : str + """Channel : str force : bool tag : Entity """ @@ -24100,18 +21034,14 @@ def __init__(self, channel=None, force=None, tag=None, **unknown_fields): # Validate arguments against known Juju API types. if channel_ is not None and not isinstance(channel_, (bytes, str)): raise Exception( - "Expected channel_ to be a str, received: {}".format(type(channel_)) + f"Expected channel_ to be a str, received: {type(channel_)}" ) if force_ is not None and not isinstance(force_, bool): - raise Exception( - "Expected force_ to be a bool, received: {}".format(type(force_)) - ) + raise Exception(f"Expected force_ to be a bool, received: {type(force_)}") if tag_ is not None and not isinstance(tag_, (dict, Entity)): - raise Exception( - "Expected tag_ to be a Entity, received: {}".format(type(tag_)) - ) + raise Exception(f"Expected tag_ to be a Entity, received: {type(tag_)}") self.channel = channel_ self.force = force_ @@ -24124,16 +21054,12 @@ class UpdateChannelArgs(Type): _toPy = {"args": "args"} def __init__(self, args=None, **unknown_fields): - """ - args : typing.Sequence[~UpdateChannelArg] - """ + """Args : typing.Sequence[~UpdateChannelArg]""" args_ = [UpdateChannelArg.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception( - "Expected args_ to be a Sequence, received: {}".format(type(args_)) - ) + raise Exception(f"Expected args_ to be a Sequence, received: {type(args_)}") self.args = args_ self.unknown_fields = unknown_fields @@ -24144,15 +21070,13 @@ class UpdateCloudArgs(Type): _toPy = {"clouds": "clouds"} def __init__(self, clouds=None, **unknown_fields): - """ - clouds : typing.Sequence[~AddCloudArgs] - """ + """Clouds : typing.Sequence[~AddCloudArgs]""" clouds_ = [AddCloudArgs.from_json(o) for o in clouds or []] # Validate arguments against known Juju API types. if clouds_ is not None and not isinstance(clouds_, (bytes, str, list)): raise Exception( - "Expected clouds_ to be a Sequence, received: {}".format(type(clouds_)) + f"Expected clouds_ to be a Sequence, received: {type(clouds_)}" ) self.clouds = clouds_ @@ -24164,8 +21088,7 @@ class UpdateCredentialArgs(Type): _toPy = {"credentials": "credentials", "force": "force"} def __init__(self, credentials=None, force=None, **unknown_fields): - """ - credentials : typing.Sequence[~TaggedCredential] + """Credentials : typing.Sequence[~TaggedCredential] force : bool """ credentials_ = [TaggedCredential.from_json(o) for o in credentials or []] @@ -24176,15 +21099,11 @@ def __init__(self, credentials=None, force=None, **unknown_fields): credentials_, (bytes, str, list) ): raise Exception( - "Expected credentials_ to be a Sequence, received: {}".format( - type(credentials_) - ) + f"Expected credentials_ to be a Sequence, received: {type(credentials_)}" ) if force_ is not None and not isinstance(force_, bool): - raise Exception( - "Expected force_ to be a bool, received: {}".format(type(force_)) - ) + raise Exception(f"Expected force_ to be a bool, received: {type(force_)}") self.credentials = credentials_ self.force = force_ @@ -24196,8 +21115,7 @@ class UpdateCredentialModelResult(Type): _toPy = {"errors": "errors", "name": "name", "uuid": "uuid"} def __init__(self, errors=None, name=None, uuid=None, **unknown_fields): - """ - errors : typing.Sequence[~ErrorResult] + """Errors : typing.Sequence[~ErrorResult] name : str uuid : str """ @@ -24208,18 +21126,14 @@ def __init__(self, errors=None, name=None, uuid=None, **unknown_fields): # Validate arguments against known Juju API types. if errors_ is not None and not isinstance(errors_, (bytes, str, list)): raise Exception( - "Expected errors_ to be a Sequence, received: {}".format(type(errors_)) + f"Expected errors_ to be a Sequence, received: {type(errors_)}" ) if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if uuid_ is not None and not isinstance(uuid_, (bytes, str)): - raise Exception( - "Expected uuid_ to be a str, received: {}".format(type(uuid_)) - ) + raise Exception(f"Expected uuid_ to be a str, received: {type(uuid_)}") self.errors = errors_ self.name = name_ @@ -24232,8 +21146,7 @@ class UpdateCredentialResult(Type): _toPy = {"error": "error", "models": "models", "tag": "tag"} def __init__(self, error=None, models=None, tag=None, **unknown_fields): - """ - error : Error + """Error : Error models : typing.Sequence[~UpdateCredentialModelResult] tag : str """ @@ -24243,19 +21156,15 @@ def __init__(self, error=None, models=None, tag=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if models_ is not None and not isinstance(models_, (bytes, str, list)): raise Exception( - "Expected models_ to be a Sequence, received: {}".format(type(models_)) + f"Expected models_ to be a Sequence, received: {type(models_)}" ) if tag_ is not None and not isinstance(tag_, (bytes, str)): - raise Exception( - "Expected tag_ to be a str, received: {}".format(type(tag_)) - ) + raise Exception(f"Expected tag_ to be a str, received: {type(tag_)}") self.error = error_ self.models = models_ @@ -24268,17 +21177,13 @@ class UpdateCredentialResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~UpdateCredentialResult] - """ + """Results : typing.Sequence[~UpdateCredentialResult]""" results_ = [UpdateCredentialResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -24313,8 +21218,7 @@ def __init__( token_rotate_interval=None, **unknown_fields, ): - """ - config : typing.Mapping[str, typing.Any] + """Config : typing.Mapping[str, typing.Any] force : bool name : str name_change : str @@ -24331,38 +21235,30 @@ def __init__( # Validate arguments against known Juju API types. if config_ is not None and not isinstance(config_, dict): raise Exception( - "Expected config_ to be a Mapping, received: {}".format(type(config_)) + f"Expected config_ to be a Mapping, received: {type(config_)}" ) if force_ is not None and not isinstance(force_, bool): - raise Exception( - "Expected force_ to be a bool, received: {}".format(type(force_)) - ) + raise Exception(f"Expected force_ to be a bool, received: {type(force_)}") if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") if name_change_ is not None and not isinstance(name_change_, (bytes, str)): raise Exception( - "Expected name_change_ to be a str, received: {}".format( - type(name_change_) - ) + f"Expected name_change_ to be a str, received: {type(name_change_)}" ) if reset_ is not None and not isinstance(reset_, (bytes, str, list)): raise Exception( - "Expected reset_ to be a Sequence, received: {}".format(type(reset_)) + f"Expected reset_ to be a Sequence, received: {type(reset_)}" ) if token_rotate_interval_ is not None and not isinstance( token_rotate_interval_, int ): raise Exception( - "Expected token_rotate_interval_ to be a int, received: {}".format( - type(token_rotate_interval_) - ) + f"Expected token_rotate_interval_ to be a int, received: {type(token_rotate_interval_)}" ) self.config = config_ @@ -24379,16 +21275,12 @@ class UpdateSecretBackendArgs(Type): _toPy = {"args": "args"} def __init__(self, args=None, **unknown_fields): - """ - args : typing.Sequence[~UpdateSecretBackendArg] - """ + """Args : typing.Sequence[~UpdateSecretBackendArg]""" args_ = [UpdateSecretBackendArg.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception( - "Expected args_ to be a Sequence, received: {}".format(type(args_)) - ) + raise Exception(f"Expected args_ to be a Sequence, received: {type(args_)}") self.args = args_ self.unknown_fields = unknown_fields @@ -24434,8 +21326,7 @@ def __init__( uri=None, **unknown_fields, ): - """ - upsertsecretarg : UpsertSecretArg + """Upsertsecretarg : UpsertSecretArg auto_prune : bool content : SecretContentParams description : str @@ -24464,71 +21355,53 @@ def __init__( upsertsecretarg_, (dict, UpsertSecretArg) ): raise Exception( - "Expected upsertsecretarg_ to be a UpsertSecretArg, received: {}".format( - type(upsertsecretarg_) - ) + f"Expected upsertsecretarg_ to be a UpsertSecretArg, received: {type(upsertsecretarg_)}" ) if auto_prune_ is not None and not isinstance(auto_prune_, bool): raise Exception( - "Expected auto_prune_ to be a bool, received: {}".format( - type(auto_prune_) - ) + f"Expected auto_prune_ to be a bool, received: {type(auto_prune_)}" ) if content_ is not None and not isinstance( content_, (dict, SecretContentParams) ): raise Exception( - "Expected content_ to be a SecretContentParams, received: {}".format( - type(content_) - ) + f"Expected content_ to be a SecretContentParams, received: {type(content_)}" ) if description_ is not None and not isinstance(description_, (bytes, str)): raise Exception( - "Expected description_ to be a str, received: {}".format( - type(description_) - ) + f"Expected description_ to be a str, received: {type(description_)}" ) if existing_label_ is not None and not isinstance( existing_label_, (bytes, str) ): raise Exception( - "Expected existing_label_ to be a str, received: {}".format( - type(existing_label_) - ) + f"Expected existing_label_ to be a str, received: {type(existing_label_)}" ) if expire_time_ is not None and not isinstance(expire_time_, (bytes, str)): raise Exception( - "Expected expire_time_ to be a str, received: {}".format( - type(expire_time_) - ) + f"Expected expire_time_ to be a str, received: {type(expire_time_)}" ) if label_ is not None and not isinstance(label_, (bytes, str)): - raise Exception( - "Expected label_ to be a str, received: {}".format(type(label_)) - ) + raise Exception(f"Expected label_ to be a str, received: {type(label_)}") if params_ is not None and not isinstance(params_, dict): raise Exception( - "Expected params_ to be a Mapping, received: {}".format(type(params_)) + f"Expected params_ to be a Mapping, received: {type(params_)}" ) if rotate_policy_ is not None and not isinstance(rotate_policy_, (bytes, str)): raise Exception( - "Expected rotate_policy_ to be a str, received: {}".format( - type(rotate_policy_) - ) + f"Expected rotate_policy_ to be a str, received: {type(rotate_policy_)}" ) if uri_ is not None and not isinstance(uri_, (bytes, str)): - raise Exception( - "Expected uri_ to be a str, received: {}".format(type(uri_)) - ) + raise Exception(f"Expected uri_ to be a str, received: {type(uri_)}") self.upsertsecretarg = upsertsecretarg_ self.auto_prune = auto_prune_ @@ -24548,16 +21421,12 @@ class UpdateUserSecretArgs(Type): _toPy = {"args": "args"} def __init__(self, args=None, **unknown_fields): - """ - args : typing.Sequence[~UpdateUserSecretArg] - """ + """Args : typing.Sequence[~UpdateUserSecretArg]""" args_ = [UpdateUserSecretArg.from_json(o) for o in args or []] # Validate arguments against known Juju API types. if args_ is not None and not isinstance(args_, (bytes, str, list)): - raise Exception( - "Expected args_ to be a Sequence, received: {}".format(type(args_)) - ) + raise Exception(f"Expected args_ to be a Sequence, received: {type(args_)}") self.args = args_ self.unknown_fields = unknown_fields @@ -24588,8 +21457,7 @@ def __init__( target_version=None, **unknown_fields, ): - """ - agent_stream : str + """agent_stream : str dry_run : bool ignore_agent_versions : bool model_tag : str @@ -24604,37 +21472,31 @@ def __init__( # Validate arguments against known Juju API types. if agent_stream_ is not None and not isinstance(agent_stream_, (bytes, str)): raise Exception( - "Expected agent_stream_ to be a str, received: {}".format( - type(agent_stream_) - ) + f"Expected agent_stream_ to be a str, received: {type(agent_stream_)}" ) if dry_run_ is not None and not isinstance(dry_run_, bool): raise Exception( - "Expected dry_run_ to be a bool, received: {}".format(type(dry_run_)) + f"Expected dry_run_ to be a bool, received: {type(dry_run_)}" ) if ignore_agent_versions_ is not None and not isinstance( ignore_agent_versions_, bool ): raise Exception( - "Expected ignore_agent_versions_ to be a bool, received: {}".format( - type(ignore_agent_versions_) - ) + f"Expected ignore_agent_versions_ to be a bool, received: {type(ignore_agent_versions_)}" ) if model_tag_ is not None and not isinstance(model_tag_, (bytes, str)): raise Exception( - "Expected model_tag_ to be a str, received: {}".format(type(model_tag_)) + f"Expected model_tag_ to be a str, received: {type(model_tag_)}" ) if target_version_ is not None and not isinstance( target_version_, (dict, Number) ): raise Exception( - "Expected target_version_ to be a Number, received: {}".format( - type(target_version_) - ) + f"Expected target_version_ to be a Number, received: {type(target_version_)}" ) self.agent_stream = agent_stream_ @@ -24650,8 +21512,7 @@ class UpgradeModelResult(Type): _toPy = {"chosen-version": "chosen_version", "error": "error"} def __init__(self, chosen_version=None, error=None, **unknown_fields): - """ - chosen_version : Number + """chosen_version : Number error : Error """ chosen_version_ = Number.from_json(chosen_version) if chosen_version else None @@ -24662,15 +21523,11 @@ def __init__(self, chosen_version=None, error=None, **unknown_fields): chosen_version_, (dict, Number) ): raise Exception( - "Expected chosen_version_ to be a Number, received: {}".format( - type(chosen_version_) - ) + f"Expected chosen_version_ to be a Number, received: {type(chosen_version_)}" ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") self.chosen_version = chosen_version_ self.error = error_ @@ -24682,8 +21539,7 @@ class UpgradeSeriesNotificationParam(Type): _toPy = {"entity": "entity", "watcher-id": "watcher_id"} def __init__(self, entity=None, watcher_id=None, **unknown_fields): - """ - entity : Entity + """Entity : Entity watcher_id : str """ entity_ = Entity.from_json(entity) if entity else None @@ -24692,14 +21548,12 @@ def __init__(self, entity=None, watcher_id=None, **unknown_fields): # Validate arguments against known Juju API types. if entity_ is not None and not isinstance(entity_, (dict, Entity)): raise Exception( - "Expected entity_ to be a Entity, received: {}".format(type(entity_)) + f"Expected entity_ to be a Entity, received: {type(entity_)}" ) if watcher_id_ is not None and not isinstance(watcher_id_, (bytes, str)): raise Exception( - "Expected watcher_id_ to be a str, received: {}".format( - type(watcher_id_) - ) + f"Expected watcher_id_ to be a str, received: {type(watcher_id_)}" ) self.entity = entity_ @@ -24712,15 +21566,13 @@ class UpgradeSeriesNotificationParams(Type): _toPy = {"params": "params"} def __init__(self, params=None, **unknown_fields): - """ - params : typing.Sequence[~UpgradeSeriesNotificationParam] - """ + """Params : typing.Sequence[~UpgradeSeriesNotificationParam]""" params_ = [UpgradeSeriesNotificationParam.from_json(o) for o in params or []] # Validate arguments against known Juju API types. if params_ is not None and not isinstance(params_, (bytes, str, list)): raise Exception( - "Expected params_ to be a Sequence, received: {}".format(type(params_)) + f"Expected params_ to be a Sequence, received: {type(params_)}" ) self.params = params_ @@ -24732,8 +21584,7 @@ class UpgradeSeriesUnitsResult(Type): _toPy = {"error": "error", "unit-names": "unit_names"} def __init__(self, error=None, unit_names=None, **unknown_fields): - """ - error : Error + """Error : Error unit_names : typing.Sequence[str] """ error_ = Error.from_json(error) if error else None @@ -24741,15 +21592,11 @@ def __init__(self, error=None, unit_names=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if unit_names_ is not None and not isinstance(unit_names_, (bytes, str, list)): raise Exception( - "Expected unit_names_ to be a Sequence, received: {}".format( - type(unit_names_) - ) + f"Expected unit_names_ to be a Sequence, received: {type(unit_names_)}" ) self.error = error_ @@ -24762,17 +21609,13 @@ class UpgradeSeriesUnitsResults(Type): _toPy = {"Results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~UpgradeSeriesUnitsResult] - """ + """Results : typing.Sequence[~UpgradeSeriesUnitsResult]""" results_ = [UpgradeSeriesUnitsResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -24807,8 +21650,7 @@ def __init__( rotate_policy=None, **unknown_fields, ): - """ - content : SecretContentParams + """Content : SecretContentParams description : str expire_time : str label : str @@ -24827,40 +21669,30 @@ def __init__( content_, (dict, SecretContentParams) ): raise Exception( - "Expected content_ to be a SecretContentParams, received: {}".format( - type(content_) - ) + f"Expected content_ to be a SecretContentParams, received: {type(content_)}" ) if description_ is not None and not isinstance(description_, (bytes, str)): raise Exception( - "Expected description_ to be a str, received: {}".format( - type(description_) - ) + f"Expected description_ to be a str, received: {type(description_)}" ) if expire_time_ is not None and not isinstance(expire_time_, (bytes, str)): raise Exception( - "Expected expire_time_ to be a str, received: {}".format( - type(expire_time_) - ) + f"Expected expire_time_ to be a str, received: {type(expire_time_)}" ) if label_ is not None and not isinstance(label_, (bytes, str)): - raise Exception( - "Expected label_ to be a str, received: {}".format(type(label_)) - ) + raise Exception(f"Expected label_ to be a str, received: {type(label_)}") if params_ is not None and not isinstance(params_, dict): raise Exception( - "Expected params_ to be a Mapping, received: {}".format(type(params_)) + f"Expected params_ to be a Mapping, received: {type(params_)}" ) if rotate_policy_ is not None and not isinstance(rotate_policy_, (bytes, str)): raise Exception( - "Expected rotate_policy_ to be a str, received: {}".format( - type(rotate_policy_) - ) + f"Expected rotate_policy_ to be a str, received: {type(rotate_policy_)}" ) self.content = content_ @@ -24877,8 +21709,7 @@ class UserAccess(Type): _toPy = {"access": "access", "user-tag": "user_tag"} def __init__(self, access=None, user_tag=None, **unknown_fields): - """ - access : str + """Access : str user_tag : str """ access_ = access @@ -24886,13 +21717,11 @@ def __init__(self, access=None, user_tag=None, **unknown_fields): # Validate arguments against known Juju API types. if access_ is not None and not isinstance(access_, (bytes, str)): - raise Exception( - "Expected access_ to be a str, received: {}".format(type(access_)) - ) + raise Exception(f"Expected access_ to be a str, received: {type(access_)}") if user_tag_ is not None and not isinstance(user_tag_, (bytes, str)): raise Exception( - "Expected user_tag_ to be a str, received: {}".format(type(user_tag_)) + f"Expected user_tag_ to be a str, received: {type(user_tag_)}" ) self.access = access_ @@ -24905,8 +21734,7 @@ class UserAccessResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : UserAccess """ error_ = Error.from_json(error) if error else None @@ -24914,15 +21742,11 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance(result_, (dict, UserAccess)): raise Exception( - "Expected result_ to be a UserAccess, received: {}".format( - type(result_) - ) + f"Expected result_ to be a UserAccess, received: {type(result_)}" ) self.error = error_ @@ -24935,17 +21759,13 @@ class UserAccessResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~UserAccessResult] - """ + """Results : typing.Sequence[~UserAccessResult]""" results_ = [UserAccessResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -24957,8 +21777,7 @@ class UserCloud(Type): _toPy = {"cloud-tag": "cloud_tag", "user-tag": "user_tag"} def __init__(self, cloud_tag=None, user_tag=None, **unknown_fields): - """ - cloud_tag : str + """cloud_tag : str user_tag : str """ cloud_tag_ = cloud_tag @@ -24967,12 +21786,12 @@ def __init__(self, cloud_tag=None, user_tag=None, **unknown_fields): # Validate arguments against known Juju API types. if cloud_tag_ is not None and not isinstance(cloud_tag_, (bytes, str)): raise Exception( - "Expected cloud_tag_ to be a str, received: {}".format(type(cloud_tag_)) + f"Expected cloud_tag_ to be a str, received: {type(cloud_tag_)}" ) if user_tag_ is not None and not isinstance(user_tag_, (bytes, str)): raise Exception( - "Expected user_tag_ to be a str, received: {}".format(type(user_tag_)) + f"Expected user_tag_ to be a str, received: {type(user_tag_)}" ) self.cloud_tag = cloud_tag_ @@ -24985,9 +21804,7 @@ class UserClouds(Type): _toPy = {"user-clouds": "user_clouds"} def __init__(self, user_clouds=None, **unknown_fields): - """ - user_clouds : typing.Sequence[~UserCloud] - """ + """user_clouds : typing.Sequence[~UserCloud]""" user_clouds_ = [UserCloud.from_json(o) for o in user_clouds or []] # Validate arguments against known Juju API types. @@ -24995,9 +21812,7 @@ def __init__(self, user_clouds=None, **unknown_fields): user_clouds_, (bytes, str, list) ): raise Exception( - "Expected user_clouds_ to be a Sequence, received: {}".format( - type(user_clouds_) - ) + f"Expected user_clouds_ to be a Sequence, received: {type(user_clouds_)}" ) self.user_clouds = user_clouds_ @@ -25035,8 +21850,7 @@ def __init__( username=None, **unknown_fields, ): - """ - access : str + """Access : str created_by : str date_created : str disabled : bool @@ -25054,48 +21868,38 @@ def __init__( # Validate arguments against known Juju API types. if access_ is not None and not isinstance(access_, (bytes, str)): - raise Exception( - "Expected access_ to be a str, received: {}".format(type(access_)) - ) + raise Exception(f"Expected access_ to be a str, received: {type(access_)}") if created_by_ is not None and not isinstance(created_by_, (bytes, str)): raise Exception( - "Expected created_by_ to be a str, received: {}".format( - type(created_by_) - ) + f"Expected created_by_ to be a str, received: {type(created_by_)}" ) if date_created_ is not None and not isinstance(date_created_, (bytes, str)): raise Exception( - "Expected date_created_ to be a str, received: {}".format( - type(date_created_) - ) + f"Expected date_created_ to be a str, received: {type(date_created_)}" ) if disabled_ is not None and not isinstance(disabled_, bool): raise Exception( - "Expected disabled_ to be a bool, received: {}".format(type(disabled_)) + f"Expected disabled_ to be a bool, received: {type(disabled_)}" ) if display_name_ is not None and not isinstance(display_name_, (bytes, str)): raise Exception( - "Expected display_name_ to be a str, received: {}".format( - type(display_name_) - ) + f"Expected display_name_ to be a str, received: {type(display_name_)}" ) if last_connection_ is not None and not isinstance( last_connection_, (bytes, str) ): raise Exception( - "Expected last_connection_ to be a str, received: {}".format( - type(last_connection_) - ) + f"Expected last_connection_ to be a str, received: {type(last_connection_)}" ) if username_ is not None and not isinstance(username_, (bytes, str)): raise Exception( - "Expected username_ to be a str, received: {}".format(type(username_)) + f"Expected username_ to be a str, received: {type(username_)}" ) self.access = access_ @@ -25113,8 +21917,7 @@ class UserInfoRequest(Type): _toPy = {"entities": "entities", "include-disabled": "include_disabled"} def __init__(self, entities=None, include_disabled=None, **unknown_fields): - """ - entities : typing.Sequence[~Entity] + """Entities : typing.Sequence[~Entity] include_disabled : bool """ entities_ = [Entity.from_json(o) for o in entities or []] @@ -25123,16 +21926,12 @@ def __init__(self, entities=None, include_disabled=None, **unknown_fields): # Validate arguments against known Juju API types. if entities_ is not None and not isinstance(entities_, (bytes, str, list)): raise Exception( - "Expected entities_ to be a Sequence, received: {}".format( - type(entities_) - ) + f"Expected entities_ to be a Sequence, received: {type(entities_)}" ) if include_disabled_ is not None and not isinstance(include_disabled_, bool): raise Exception( - "Expected include_disabled_ to be a bool, received: {}".format( - type(include_disabled_) - ) + f"Expected include_disabled_ to be a bool, received: {type(include_disabled_)}" ) self.entities = entities_ @@ -25145,8 +21944,7 @@ class UserInfoResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : UserInfo """ error_ = Error.from_json(error) if error else None @@ -25154,13 +21952,11 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance(result_, (dict, UserInfo)): raise Exception( - "Expected result_ to be a UserInfo, received: {}".format(type(result_)) + f"Expected result_ to be a UserInfo, received: {type(result_)}" ) self.error = error_ @@ -25173,17 +21969,13 @@ class UserInfoResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~UserInfoResult] - """ + """Results : typing.Sequence[~UserInfoResult]""" results_ = [UserInfoResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -25195,8 +21987,7 @@ class UserModel(Type): _toPy = {"last-connection": "last_connection", "model": "model"} def __init__(self, last_connection=None, model=None, **unknown_fields): - """ - last_connection : str + """last_connection : str model : Model """ last_connection_ = last_connection @@ -25207,15 +21998,11 @@ def __init__(self, last_connection=None, model=None, **unknown_fields): last_connection_, (bytes, str) ): raise Exception( - "Expected last_connection_ to be a str, received: {}".format( - type(last_connection_) - ) + f"Expected last_connection_ to be a str, received: {type(last_connection_)}" ) if model_ is not None and not isinstance(model_, (dict, Model)): - raise Exception( - "Expected model_ to be a Model, received: {}".format(type(model_)) - ) + raise Exception(f"Expected model_ to be a Model, received: {type(model_)}") self.last_connection = last_connection_ self.model = model_ @@ -25227,9 +22014,7 @@ class UserModelList(Type): _toPy = {"user-models": "user_models"} def __init__(self, user_models=None, **unknown_fields): - """ - user_models : typing.Sequence[~UserModel] - """ + """user_models : typing.Sequence[~UserModel]""" user_models_ = [UserModel.from_json(o) for o in user_models or []] # Validate arguments against known Juju API types. @@ -25237,9 +22022,7 @@ def __init__(self, user_models=None, **unknown_fields): user_models_, (bytes, str, list) ): raise Exception( - "Expected user_models_ to be a Sequence, received: {}".format( - type(user_models_) - ) + f"Expected user_models_ to be a Sequence, received: {type(user_models_)}" ) self.user_models = user_models_ @@ -25301,8 +22084,7 @@ def __init__( zones=None, **unknown_fields, ): - """ - allocate_public_ip : bool + """allocate_public_ip : bool arch : str container : str cores : int @@ -25339,87 +22121,71 @@ def __init__( allocate_public_ip_, bool ): raise Exception( - "Expected allocate_public_ip_ to be a bool, received: {}".format( - type(allocate_public_ip_) - ) + f"Expected allocate_public_ip_ to be a bool, received: {type(allocate_public_ip_)}" ) if arch_ is not None and not isinstance(arch_, (bytes, str)): - raise Exception( - "Expected arch_ to be a str, received: {}".format(type(arch_)) - ) + raise Exception(f"Expected arch_ to be a str, received: {type(arch_)}") if container_ is not None and not isinstance(container_, (bytes, str)): raise Exception( - "Expected container_ to be a str, received: {}".format(type(container_)) + f"Expected container_ to be a str, received: {type(container_)}" ) if cores_ is not None and not isinstance(cores_, int): - raise Exception( - "Expected cores_ to be a int, received: {}".format(type(cores_)) - ) + raise Exception(f"Expected cores_ to be a int, received: {type(cores_)}") if cpu_power_ is not None and not isinstance(cpu_power_, int): raise Exception( - "Expected cpu_power_ to be a int, received: {}".format(type(cpu_power_)) + f"Expected cpu_power_ to be a int, received: {type(cpu_power_)}" ) if image_id_ is not None and not isinstance(image_id_, (bytes, str)): raise Exception( - "Expected image_id_ to be a str, received: {}".format(type(image_id_)) + f"Expected image_id_ to be a str, received: {type(image_id_)}" ) if instance_role_ is not None and not isinstance(instance_role_, (bytes, str)): raise Exception( - "Expected instance_role_ to be a str, received: {}".format( - type(instance_role_) - ) + f"Expected instance_role_ to be a str, received: {type(instance_role_)}" ) if instance_type_ is not None and not isinstance(instance_type_, (bytes, str)): raise Exception( - "Expected instance_type_ to be a str, received: {}".format( - type(instance_type_) - ) + f"Expected instance_type_ to be a str, received: {type(instance_type_)}" ) if mem_ is not None and not isinstance(mem_, int): - raise Exception( - "Expected mem_ to be a int, received: {}".format(type(mem_)) - ) + raise Exception(f"Expected mem_ to be a int, received: {type(mem_)}") if root_disk_ is not None and not isinstance(root_disk_, int): raise Exception( - "Expected root_disk_ to be a int, received: {}".format(type(root_disk_)) + f"Expected root_disk_ to be a int, received: {type(root_disk_)}" ) if root_disk_source_ is not None and not isinstance( root_disk_source_, (bytes, str) ): raise Exception( - "Expected root_disk_source_ to be a str, received: {}".format( - type(root_disk_source_) - ) + f"Expected root_disk_source_ to be a str, received: {type(root_disk_source_)}" ) if spaces_ is not None and not isinstance(spaces_, (bytes, str, list)): raise Exception( - "Expected spaces_ to be a Sequence, received: {}".format(type(spaces_)) + f"Expected spaces_ to be a Sequence, received: {type(spaces_)}" ) if tags_ is not None and not isinstance(tags_, (bytes, str, list)): - raise Exception( - "Expected tags_ to be a Sequence, received: {}".format(type(tags_)) - ) + raise Exception(f"Expected tags_ to be a Sequence, received: {type(tags_)}") if virt_type_ is not None and not isinstance(virt_type_, (bytes, str)): raise Exception( - "Expected virt_type_ to be a str, received: {}".format(type(virt_type_)) + f"Expected virt_type_ to be a str, received: {type(virt_type_)}" ) if zones_ is not None and not isinstance(zones_, (bytes, str, list)): raise Exception( - "Expected zones_ to be a Sequence, received: {}".format(type(zones_)) + f"Expected zones_ to be a Sequence, received: {type(zones_)}" ) self.allocate_public_ip = allocate_public_ip_ @@ -25471,8 +22237,7 @@ def __init__( read_only=None, **unknown_fields, ): - """ - volumeattachmentinfo : VolumeAttachmentInfo + """Volumeattachmentinfo : VolumeAttachmentInfo bus_address : str device_link : str device_name : str @@ -25499,51 +22264,37 @@ def __init__( volumeattachmentinfo_, (dict, VolumeAttachmentInfo) ): raise Exception( - "Expected volumeattachmentinfo_ to be a VolumeAttachmentInfo, received: {}".format( - type(volumeattachmentinfo_) - ) + f"Expected volumeattachmentinfo_ to be a VolumeAttachmentInfo, received: {type(volumeattachmentinfo_)}" ) if bus_address_ is not None and not isinstance(bus_address_, (bytes, str)): raise Exception( - "Expected bus_address_ to be a str, received: {}".format( - type(bus_address_) - ) + f"Expected bus_address_ to be a str, received: {type(bus_address_)}" ) if device_link_ is not None and not isinstance(device_link_, (bytes, str)): raise Exception( - "Expected device_link_ to be a str, received: {}".format( - type(device_link_) - ) + f"Expected device_link_ to be a str, received: {type(device_link_)}" ) if device_name_ is not None and not isinstance(device_name_, (bytes, str)): raise Exception( - "Expected device_name_ to be a str, received: {}".format( - type(device_name_) - ) + f"Expected device_name_ to be a str, received: {type(device_name_)}" ) if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception( - "Expected life_ to be a str, received: {}".format(type(life_)) - ) + raise Exception(f"Expected life_ to be a str, received: {type(life_)}") if plan_info_ is not None and not isinstance( plan_info_, (dict, VolumeAttachmentPlanInfo) ): raise Exception( - "Expected plan_info_ to be a VolumeAttachmentPlanInfo, received: {}".format( - type(plan_info_) - ) + f"Expected plan_info_ to be a VolumeAttachmentPlanInfo, received: {type(plan_info_)}" ) if read_only_ is not None and not isinstance(read_only_, bool): raise Exception( - "Expected read_only_ to be a bool, received: {}".format( - type(read_only_) - ) + f"Expected read_only_ to be a bool, received: {type(read_only_)}" ) self.volumeattachmentinfo = volumeattachmentinfo_ @@ -25581,8 +22332,7 @@ def __init__( read_only=None, **unknown_fields, ): - """ - bus_address : str + """bus_address : str device_link : str device_name : str plan_info : VolumeAttachmentPlanInfo @@ -25599,39 +22349,29 @@ def __init__( # Validate arguments against known Juju API types. if bus_address_ is not None and not isinstance(bus_address_, (bytes, str)): raise Exception( - "Expected bus_address_ to be a str, received: {}".format( - type(bus_address_) - ) + f"Expected bus_address_ to be a str, received: {type(bus_address_)}" ) if device_link_ is not None and not isinstance(device_link_, (bytes, str)): raise Exception( - "Expected device_link_ to be a str, received: {}".format( - type(device_link_) - ) + f"Expected device_link_ to be a str, received: {type(device_link_)}" ) if device_name_ is not None and not isinstance(device_name_, (bytes, str)): raise Exception( - "Expected device_name_ to be a str, received: {}".format( - type(device_name_) - ) + f"Expected device_name_ to be a str, received: {type(device_name_)}" ) if plan_info_ is not None and not isinstance( plan_info_, (dict, VolumeAttachmentPlanInfo) ): raise Exception( - "Expected plan_info_ to be a VolumeAttachmentPlanInfo, received: {}".format( - type(plan_info_) - ) + f"Expected plan_info_ to be a VolumeAttachmentPlanInfo, received: {type(plan_info_)}" ) if read_only_ is not None and not isinstance(read_only_, bool): raise Exception( - "Expected read_only_ to be a bool, received: {}".format( - type(read_only_) - ) + f"Expected read_only_ to be a bool, received: {type(read_only_)}" ) self.bus_address = bus_address_ @@ -25647,8 +22387,7 @@ class VolumeAttachmentPlanInfo(Type): _toPy = {"device-attributes": "device_attributes", "device-type": "device_type"} def __init__(self, device_attributes=None, device_type=None, **unknown_fields): - """ - device_attributes : typing.Mapping[str, str] + """device_attributes : typing.Mapping[str, str] device_type : str """ device_attributes_ = device_attributes @@ -25657,16 +22396,12 @@ def __init__(self, device_attributes=None, device_type=None, **unknown_fields): # Validate arguments against known Juju API types. if device_attributes_ is not None and not isinstance(device_attributes_, dict): raise Exception( - "Expected device_attributes_ to be a Mapping, received: {}".format( - type(device_attributes_) - ) + f"Expected device_attributes_ to be a Mapping, received: {type(device_attributes_)}" ) if device_type_ is not None and not isinstance(device_type_, (bytes, str)): raise Exception( - "Expected device_type_ to be a str, received: {}".format( - type(device_type_) - ) + f"Expected device_type_ to be a str, received: {type(device_type_)}" ) self.device_attributes = device_attributes_ @@ -25705,8 +22440,7 @@ def __init__( volume_tag=None, **unknown_fields, ): - """ - info : VolumeInfo + """Info : VolumeInfo life : str machine_attachments : typing.Mapping[str, ~VolumeAttachmentDetails] status : EntityStatus @@ -25731,49 +22465,37 @@ def __init__( # Validate arguments against known Juju API types. if info_ is not None and not isinstance(info_, (dict, VolumeInfo)): raise Exception( - "Expected info_ to be a VolumeInfo, received: {}".format(type(info_)) + f"Expected info_ to be a VolumeInfo, received: {type(info_)}" ) if life_ is not None and not isinstance(life_, (bytes, str)): - raise Exception( - "Expected life_ to be a str, received: {}".format(type(life_)) - ) + raise Exception(f"Expected life_ to be a str, received: {type(life_)}") if machine_attachments_ is not None and not isinstance( machine_attachments_, dict ): raise Exception( - "Expected machine_attachments_ to be a Mapping, received: {}".format( - type(machine_attachments_) - ) + f"Expected machine_attachments_ to be a Mapping, received: {type(machine_attachments_)}" ) if status_ is not None and not isinstance(status_, (dict, EntityStatus)): raise Exception( - "Expected status_ to be a EntityStatus, received: {}".format( - type(status_) - ) + f"Expected status_ to be a EntityStatus, received: {type(status_)}" ) if storage_ is not None and not isinstance(storage_, (dict, StorageDetails)): raise Exception( - "Expected storage_ to be a StorageDetails, received: {}".format( - type(storage_) - ) + f"Expected storage_ to be a StorageDetails, received: {type(storage_)}" ) if unit_attachments_ is not None and not isinstance(unit_attachments_, dict): raise Exception( - "Expected unit_attachments_ to be a Mapping, received: {}".format( - type(unit_attachments_) - ) + f"Expected unit_attachments_ to be a Mapping, received: {type(unit_attachments_)}" ) if volume_tag_ is not None and not isinstance(volume_tag_, (bytes, str)): raise Exception( - "Expected volume_tag_ to be a str, received: {}".format( - type(volume_tag_) - ) + f"Expected volume_tag_ to be a str, received: {type(volume_tag_)}" ) self.info = info_ @@ -25791,8 +22513,7 @@ class VolumeDetailsListResult(Type): _toPy = {"error": "error", "result": "result"} def __init__(self, error=None, result=None, **unknown_fields): - """ - error : Error + """Error : Error result : typing.Sequence[~VolumeDetails] """ error_ = Error.from_json(error) if error else None @@ -25800,13 +22521,11 @@ def __init__(self, error=None, result=None, **unknown_fields): # Validate arguments against known Juju API types. if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if result_ is not None and not isinstance(result_, (bytes, str, list)): raise Exception( - "Expected result_ to be a Sequence, received: {}".format(type(result_)) + f"Expected result_ to be a Sequence, received: {type(result_)}" ) self.error = error_ @@ -25819,17 +22538,13 @@ class VolumeDetailsListResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~VolumeDetailsListResult] - """ + """Results : typing.Sequence[~VolumeDetailsListResult]""" results_ = [VolumeDetailsListResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ @@ -25841,17 +22556,13 @@ class VolumeFilter(Type): _toPy = {"machines": "machines"} def __init__(self, machines=None, **unknown_fields): - """ - machines : typing.Sequence[str] - """ + """Machines : typing.Sequence[str]""" machines_ = machines # Validate arguments against known Juju API types. if machines_ is not None and not isinstance(machines_, (bytes, str, list)): raise Exception( - "Expected machines_ to be a Sequence, received: {}".format( - type(machines_) - ) + f"Expected machines_ to be a Sequence, received: {type(machines_)}" ) self.machines = machines_ @@ -25863,17 +22574,13 @@ class VolumeFilters(Type): _toPy = {"filters": "filters"} def __init__(self, filters=None, **unknown_fields): - """ - filters : typing.Sequence[~VolumeFilter] - """ + """Filters : typing.Sequence[~VolumeFilter]""" filters_ = [VolumeFilter.from_json(o) for o in filters or []] # Validate arguments against known Juju API types. if filters_ is not None and not isinstance(filters_, (bytes, str, list)): raise Exception( - "Expected filters_ to be a Sequence, received: {}".format( - type(filters_) - ) + f"Expected filters_ to be a Sequence, received: {type(filters_)}" ) self.filters = filters_ @@ -25908,8 +22615,7 @@ def __init__( wwn=None, **unknown_fields, ): - """ - hardware_id : str + """hardware_id : str persistent : bool pool : str size : int @@ -25926,37 +22632,27 @@ def __init__( # Validate arguments against known Juju API types. if hardware_id_ is not None and not isinstance(hardware_id_, (bytes, str)): raise Exception( - "Expected hardware_id_ to be a str, received: {}".format( - type(hardware_id_) - ) + f"Expected hardware_id_ to be a str, received: {type(hardware_id_)}" ) if persistent_ is not None and not isinstance(persistent_, bool): raise Exception( - "Expected persistent_ to be a bool, received: {}".format( - type(persistent_) - ) + f"Expected persistent_ to be a bool, received: {type(persistent_)}" ) if pool_ is not None and not isinstance(pool_, (bytes, str)): - raise Exception( - "Expected pool_ to be a str, received: {}".format(type(pool_)) - ) + raise Exception(f"Expected pool_ to be a str, received: {type(pool_)}") if size_ is not None and not isinstance(size_, int): - raise Exception( - "Expected size_ to be a int, received: {}".format(type(size_)) - ) + raise Exception(f"Expected size_ to be a int, received: {type(size_)}") if volume_id_ is not None and not isinstance(volume_id_, (bytes, str)): raise Exception( - "Expected volume_id_ to be a str, received: {}".format(type(volume_id_)) + f"Expected volume_id_ to be a str, received: {type(volume_id_)}" ) if wwn_ is not None and not isinstance(wwn_, (bytes, str)): - raise Exception( - "Expected wwn_ to be a str, received: {}".format(type(wwn_)) - ) + raise Exception(f"Expected wwn_ to be a str, received: {type(wwn_)}") self.hardware_id = hardware_id_ self.persistent = persistent_ @@ -25972,8 +22668,7 @@ class ZoneResult(Type): _toPy = {"available": "available", "error": "error", "name": "name"} def __init__(self, available=None, error=None, name=None, **unknown_fields): - """ - available : bool + """Available : bool error : Error name : str """ @@ -25984,20 +22679,14 @@ def __init__(self, available=None, error=None, name=None, **unknown_fields): # Validate arguments against known Juju API types. if available_ is not None and not isinstance(available_, bool): raise Exception( - "Expected available_ to be a bool, received: {}".format( - type(available_) - ) + f"Expected available_ to be a bool, received: {type(available_)}" ) if error_ is not None and not isinstance(error_, (dict, Error)): - raise Exception( - "Expected error_ to be a Error, received: {}".format(type(error_)) - ) + raise Exception(f"Expected error_ to be a Error, received: {type(error_)}") if name_ is not None and not isinstance(name_, (bytes, str)): - raise Exception( - "Expected name_ to be a str, received: {}".format(type(name_)) - ) + raise Exception(f"Expected name_ to be a str, received: {type(name_)}") self.available = available_ self.error = error_ @@ -26010,17 +22699,13 @@ class ZoneResults(Type): _toPy = {"results": "results"} def __init__(self, results=None, **unknown_fields): - """ - results : typing.Sequence[~ZoneResult] - """ + """Results : typing.Sequence[~ZoneResult]""" results_ = [ZoneResult.from_json(o) for o in results or []] # Validate arguments against known Juju API types. if results_ is not None and not isinstance(results_, (bytes, str, list)): raise Exception( - "Expected results_ to be a Sequence, received: {}".format( - type(results_) - ) + f"Expected results_ to be a Sequence, received: {type(results_)}" ) self.results = results_ diff --git a/juju/client/codegen.py b/juju/client/codegen.py index ef97acf43..f8b0a4286 100644 --- a/juju/client/codegen.py +++ b/juju/client/codegen.py @@ -7,8 +7,7 @@ class CodeWriter(StringIO): - """ - Blob of text that, when used in the context of facade.py, ends up + """Blob of text that, when used in the context of facade.py, ends up holding the source code for a Python class and associated methods. """ @@ -30,8 +29,7 @@ def __str__(self): class Capture(defaultdict): - """ - A collection of CodeWriter objects, together representing a Python + """A collection of CodeWriter objects, together representing a Python module. """ @@ -40,8 +38,7 @@ def __init__(self, default_factory=CodeWriter, *args, **kwargs): super(Capture, self).__init__(default_factory, *args, **kwargs) def clear(self, name): - """ - Reset one of the keys in this class, if it exists. + """Reset one of the keys in this class, if it exists. This is necessary, because we don't worry about de-duplicating the schemas for each version of juju up front, and this gives diff --git a/juju/client/connection.py b/juju/client/connection.py index 82f52662b..ae6a59445 100644 --- a/juju/client/connection.py +++ b/juju/client/connection.py @@ -9,24 +9,25 @@ import warnings import weakref from http.client import HTTPSConnection -from dateutil.parser import parse from typing import Dict, Literal, Optional, Sequence import macaroonbakery.bakery as bakery import macaroonbakery.httpbakery as httpbakery import websockets -from juju import errors, tag, utils, jasyncio +from dateutil.parser import parse + +from juju import errors, jasyncio, tag, utils from juju.client import client from juju.utils import IdQueue from juju.version import CLIENT_VERSION + from .facade_versions import client_facade_versions, known_unsupported_facades log = logging.getLogger("juju.client.connection") def facade_versions(name, versions): - """ - facade_versions returns a new object that correctly returns a object in + """facade_versions returns a new object that correctly returns a object in format expected by the connection facades inspection. :param name: name of the facade :param versions: versions to support by the facade @@ -39,8 +40,7 @@ def facade_versions(name, versions): class Monitor: - """ - Monitor helper class for our Connection class. + """Monitor helper class for our Connection class. Contains a reference to an instantiated Connection, along with a reference to the Connection.receiver Future. Upon inspection of @@ -65,8 +65,7 @@ def __init__(self, connection): @property def status(self): - """ - Determine the status of the connection and receiver, and return + """Determine the status of the connection and receiver, and return ERROR, CONNECTED, or DISCONNECTED as appropriate. For simplicity, we only consider ourselves to be connected @@ -107,12 +106,11 @@ def status(self): class Connection: - """ - Usage:: + """Usage:: - # Connect to an arbitrary api server - client = await Connection.connect( - api_endpoint, model_uuid, username, password, cacert) + # Connect to an arbitrary api server + client = await Connection.connect( + api_endpoint, model_uuid, username, password, cacert) """ @@ -256,7 +254,7 @@ async def connect( lastError = e continue except OSError as e: - logging.debug("Cannot access endpoint {}: {}".format(_ep, e.strerror)) + logging.debug(f"Cannot access endpoint {_ep}: {e.strerror}") lastError = e continue if lastError is not None: @@ -303,13 +301,11 @@ def _get_ssl(self, cert=None): async def _open(self, endpoint, cacert): if self.is_debug_log_connection: assert self.uuid - url = "wss://user-{}:{}@{}/model/{}/log".format( - self.username, self.password, endpoint, self.uuid - ) + url = f"wss://user-{self.username}:{self.password}@{endpoint}/model/{self.uuid}/log" elif self.uuid: - url = "wss://{}/model/{}/api".format(endpoint, self.uuid) + url = f"wss://{endpoint}/model/{self.uuid}/api" else: - url = "wss://{}/api".format(endpoint) + url = f"wss://{endpoint}/api" # We need to establish a server_hostname here for TLS sni if we are # connecting through a proxy as the Juju controller certificates will @@ -506,8 +502,7 @@ async def _receiver(self): raise async def _pinger(self): - """ - A Controller can time us out if we are silent for too long. This + """A Controller can time us out if we are silent for too long. This is especially true in JaaS, which has a fairly strict timeout. To prevent timing out, we send a ping every ten seconds. @@ -555,7 +550,7 @@ async def rpc(self, msg, encoder=None): if "version" not in msg: msg["version"] = self.facades[msg["type"]] outgoing = json.dumps(msg, indent=2, cls=encoder) - log.debug("connection id: {} ---> {}".format(id(self), outgoing)) + log.debug(f"connection id: {id(self)} ---> {outgoing}") for attempt in range(3): if self.monitor.status == Monitor.DISCONNECTED: # closed cleanly; shouldn't try to reconnect @@ -581,7 +576,7 @@ async def rpc(self, msg, encoder=None): log.error("RPC: Automatic reconnect failed") raise result = await self._recv(msg["request-id"]) - log.debug("connection id : {} <--- {}".format(id(self), result)) + log.debug(f"connection id : {id(self)} <--- {result}") if not result: return result @@ -624,7 +619,7 @@ def _http_headers(self): creds = "{}:{}".format(self.usertag, self.password or "") token = base64.b64encode(creds.encode()) - return {"Authorization": "Basic {}".format(token.decode())} + return {"Authorization": f"Basic {token.decode()}"} def https_connection(self): """Return an https connection to this Connection's endpoint. @@ -650,7 +645,7 @@ def https_connection(self): context=self._get_ssl(self.cacert), ) - path = "/model/{}".format(self.uuid) if self.uuid else "" + path = f"/model/{self.uuid}" if self.uuid else "" return conn, self._http_headers(), path async def clone(self): @@ -737,15 +732,13 @@ async def _try_endpoint(endpoint, cacert, delay): _endpoints_str = ", ".join([endpoint for endpoint, cacert in endpoints]) if attempt < self._retries: log.debug( - "Retrying connection to endpoints: {}; attempt {} of {}".format( - _endpoints_str, attempt + 1, self._retries + 1 - ) + f"Retrying connection to endpoints: {_endpoints_str}; attempt {attempt + 1} of {self._retries + 1}" ) await jasyncio.sleep((attempt + 1) * self._retry_backoff) continue else: raise errors.JujuConnectionError( - "Unable to connect to any endpoint: {}".format(_endpoints_str) + f"Unable to connect to any endpoint: {_endpoints_str}" ) # only executed if inner loop's else did not continue # (i.e., inner loop did break due to successful connection) @@ -904,7 +897,8 @@ async def login(self): def _macaroons_for_domain(cookies, domain): """Return any macaroons from the given cookie jar that - apply to the given domain name.""" + apply to the given domain name. + """ req = urllib.request.Request("https://" + domain + "/") cookies.add_cookie_header(req) return httpbakery.extract_macaroons(req) diff --git a/juju/client/connector.py b/juju/client/connector.py index 9c366bfc4..d9026b8bc 100644 --- a/juju/client/connector.py +++ b/juju/client/connector.py @@ -4,9 +4,8 @@ import copy import logging -from packaging import version - import macaroonbakery.httpbakery as httpbakery +from packaging import version from juju.client import client from juju.client.connection import Connection @@ -21,7 +20,8 @@ class NoConnectionException(Exception): """Raised by Connector when the connection method is called - and there is no current connection.""" + and there is no current connection. + """ pass @@ -38,7 +38,8 @@ def __init__( jujudata=None, ): """Initialize a connector that will use the given parameters - by default when making a new connection""" + by default when making a new connection + """ self.max_frame_size = max_frame_size self.bakery_client = bakery_client self._connection = None @@ -53,7 +54,8 @@ def is_connected(self): def connection(self): """Return the current connection; raises an exception if there - is no current connection.""" + is no current connection. + """ if not self.is_connected(): raise NoConnectionException("not connected") return self._connection @@ -166,14 +168,13 @@ async def connect_model(self, _model_name=None, **kwargs): :param str model: : """ - try: controller_name, _model_name = self.jujudata.parse_model(_model_name) controller = self.jujudata.controllers().get(controller_name) except JujuError as e: raise JujuConnectionError(e.message) from e if controller is None: - raise JujuConnectionError("Controller {} not found".format(controller_name)) + raise JujuConnectionError(f"Controller {controller_name} not found") endpoints = controller[API_ENDPOINTS_KEY] account = self.jujudata.accounts().get(controller_name, {}) models = self.jujudata.models().get(controller_name, {}).get("models", {}) @@ -195,7 +196,7 @@ async def connect_model(self, _model_name=None, **kwargs): model_uuid = user_model.model.uuid if model_uuid is None: - raise JujuConnectionError("Model not found: {}".format(_model_name)) + raise JujuConnectionError(f"Model not found: {_model_name}") proxy = proxy_from_config(controller.get("proxy-config", None)) diff --git a/juju/client/facade.py b/juju/client/facade.py index 920c49850..97df78191 100644 --- a/juju/client/facade.py +++ b/juju/client/facade.py @@ -224,7 +224,7 @@ def kind_to_py(kind): return name, type_mapping[name], True suffix = name.lstrip("~") - return suffix, "(dict, {})".format(suffix), True + return suffix, f"(dict, {suffix})", True def strcast(kind, keep_builtins=False): @@ -287,7 +287,7 @@ def SchemaToPyMapping(self): def _format(self, name, rtype, typed=True): if typed: - return "{} : {}".format(name_to_py(name), strcast(rtype)) + return f"{name_to_py(name)} : {strcast(rtype)}" else: return name_to_py(name) @@ -307,13 +307,12 @@ def as_kwargs(self): for item in self: var_name = name_to_py(item[0]) var_type = var_type_to_py(item[1]) - parts.append("{}={}".format(var_name, var_type)) + parts.append(f"{var_name}={var_type}") return ", ".join(parts) return "" def as_validation(self): - """ - as_validation returns a series of validation statements for every item + """as_validation returns a series of validation statements for every item in the the Args. """ parts = [] @@ -336,14 +335,9 @@ def get_doc(self): def buildValidation(name, instance_type, instance_sub_type, ident=None): INDENT = ident or " " - source = """{ident}if {name} is not None and not isinstance({name}, {instance_sub_type}): -{ident} raise Exception("Expected {name} to be a {instance_type}, received: {{}}".format(type({name}))) -""".format( - ident=INDENT, - name=name, - instance_type=instance_type, - instance_sub_type=instance_sub_type, - ) + source = f"""{INDENT}if {name} is not None and not isinstance({name}, {instance_sub_type}): +{INDENT} raise Exception("Expected {name} to be a {instance_type}, received: {{}}".format(type({name}))) +""" return source @@ -385,7 +379,7 @@ def __init__(self{}{}, **unknown_fields): ] if not args: - source.append("{}self.unknown_fields = unknown_fields".format(INDENT * 2)) + source.append(f"{INDENT * 2}self.unknown_fields = unknown_fields") else: # do the validation first, before setting the variables for arg in args: @@ -393,12 +387,10 @@ def __init__(self{}{}, **unknown_fields): arg_type = arg[1] arg_type_name = strcast(arg_type) if arg_type in basic_types or arg_type is typing.Any: - source.append("{}{}_ = {}".format(INDENT * 2, arg_name, arg_name)) + source.append(f"{INDENT * 2}{arg_name}_ = {arg_name}") elif type(arg_type) is typing.TypeVar: source.append( - "{}{}_ = {}.from_json({}) if {} else None".format( - INDENT * 2, arg_name, arg_type_name, arg_name, arg_name - ) + f"{INDENT * 2}{arg_name}_ = {arg_type_name}.from_json({arg_name}) if {arg_name} else None" ) elif typing_inspect.is_generic_type(arg_type) and issubclass( typing_inspect.get_origin(arg_type), Sequence @@ -407,14 +399,10 @@ def __init__(self{}{}, **unknown_fields): value_type = parameters[0] if len(parameters) else None if type(value_type) is typing.TypeVar: source.append( - "{}{}_ = [{}.from_json(o) for o in {} or []]".format( - INDENT * 2, arg_name, strcast(value_type), arg_name - ) + f"{INDENT * 2}{arg_name}_ = [{strcast(value_type)}.from_json(o) for o in {arg_name} or []]" ) else: - source.append( - "{}{}_ = {}".format(INDENT * 2, arg_name, arg_name) - ) + source.append(f"{INDENT * 2}{arg_name}_ = {arg_name}") elif typing_inspect.is_generic_type(arg_type) and issubclass( typing_inspect.get_origin(arg_type), Mapping ): @@ -422,25 +410,19 @@ def __init__(self{}{}, **unknown_fields): value_type = parameters[0] if len(parameters) else None if type(value_type) is typing.TypeVar: source.append( - "{}{}_ = {{k: {}.from_json(v) " - "for k, v in ({} or dict()).items()}}".format( - INDENT * 2, arg_name, strcast(value_type), arg_name - ) + f"{INDENT * 2}{arg_name}_ = {{k: {strcast(value_type)}.from_json(v) " + f"for k, v in ({arg_name} or dict()).items()}}" ) else: - source.append( - "{}{}_ = {}".format(INDENT * 2, arg_name, arg_name) - ) + source.append(f"{INDENT * 2}{arg_name}_ = {arg_name}") else: - source.append("{}{}_ = {}".format(INDENT * 2, arg_name, arg_name)) + source.append(f"{INDENT * 2}{arg_name}_ = {arg_name}") if len(args) > 0: source.append( - "\n{}# Validate arguments against known Juju API types.".format( - INDENT * 2 - ) + f"\n{INDENT * 2}# Validate arguments against known Juju API types." ) for arg in args: - arg_name = "{}_".format(name_to_py(arg[0])) + arg_name = f"{name_to_py(arg[0])}_" arg_type, arg_sub_type, ok = kind_to_py(arg[1]) if ok: source.append( @@ -453,10 +435,10 @@ def __init__(self{}{}, **unknown_fields): for arg in args: arg_name = name_to_py(arg[0]) - source.append("{}self.{} = {}_".format(INDENT * 2, arg_name, arg_name)) + source.append(f"{INDENT * 2}self.{arg_name} = {arg_name}_") # Ensure that we take the kwargs (unknown_fields) and put it on the # Results/Params so we can inspect it. - source.append("{}self.unknown_fields = unknown_fields".format(INDENT * 2)) + source.append(f"{INDENT * 2}self.unknown_fields = unknown_fields") source = "\n".join(source) capture.clear(name) @@ -527,7 +509,7 @@ def makeFunc(cls, name, description, params, result, _async=True): assignments = [] toschema = args.PyToSchemaMapping() for arg in args._get_arg_str(False, False): - assignments.append("{}_params['{}'] = {}".format(INDENT, toschema[arg], arg)) + assignments.append(f"{INDENT}_params['{toschema[arg]}'] = {arg}") assignments = "\n".join(assignments) res = retspec(cls.schema, result) source = """ @@ -552,8 +534,8 @@ def makeFunc(cls, name, description, params, result, _async=True): """ if description != "": - description = "{}\n\n".format(description) - doc_string = "{}{}".format(description, args.get_doc()) + description = f"{description}\n\n" + doc_string = f"{description}{args.get_doc()}" fsource = source.format( _async="async " if _async else "", name=name, @@ -600,7 +582,7 @@ def buildMethods(cls, capture): for methodname in sorted(properties): method, source = _buildMethod(cls, methodname) setattr(cls, methodname, method) - capture["{}Facade".format(cls.__name__)].write(source, depth=1) + capture[f"{cls.__name__}Facade"].write(source, depth=1) def _buildMethod(cls, name): @@ -628,8 +610,8 @@ def buildWatcherRPCMethods(cls, capture): properties = cls.schema["properties"] if "Next" in properties and "Stop" in properties: method, source = makeRPCFunc(cls) - setattr(cls, "rpc", method) - capture["{}Facade".format(cls.__name__)].write(source, depth=1) + cls.rpc = method + capture[f"{cls.__name__}Facade"].write(source, depth=1) def buildFacade(schema): @@ -663,7 +645,7 @@ def connect(self, connection): self.connection = connection def __repr__(self): - return "{}({})".format(self.__class__, self.__dict__) + return f"{self.__class__}({self.__dict__})" def __eq__(self, other): if not isinstance(other, Type): @@ -855,16 +837,13 @@ def _getns(schema): def make_factory(name): if name in factories: del factories[name] - factories[name].write("class {}(TypeFactory):\n pass\n\n".format(name)) + factories[name].write(f"class {name}(TypeFactory):\n pass\n\n") def write_facades(captures, options): - """ - Write the Facades to the appropriate _client.py - - """ + """Write the Facades to the appropriate _client.py""" for version in sorted(captures.keys()): - filename = "{}/_client{}.py".format(options.output_dir, version) + filename = f"{options.output_dir}/_client{version}.py" with open(filename, "w") as f: f.write(HEADER) f.write("from juju.client.facade import Type, ReturnMapping\n") @@ -877,14 +856,13 @@ def write_facades(captures, options): def write_definitions(captures, options): - """ - Write auxiliary (non versioned) classes to + """Write auxiliary (non versioned) classes to _definitions.py The auxiliary classes currently get written redudantly into each capture object, so we can look in one of them -- we just use the last one from the loop above. """ - with open("{}/_definitions.py".format(options.output_dir), "w") as f: + with open(f"{options.output_dir}/_definitions.py", "w") as f: f.write(HEADER) f.write("from juju.client.facade import Type, ReturnMapping\n\n") for key in sorted([k for k in captures.keys() if "Facade" not in k]): @@ -892,24 +870,21 @@ def write_definitions(captures, options): def write_client(captures, options): - """ - Write the TypeFactory classes to _client.py, along with some + """Write the TypeFactory classes to _client.py, along with some imports and tables so that we can look up versioned Facades. """ - with open("{}/_client.py".format(options.output_dir), "w") as f: + with open(f"{options.output_dir}/_client.py", "w") as f: f.write(HEADER) f.write("from juju.client._definitions import *\n\n") - clients = ", ".join("_client{}".format(v) for v in captures) + clients = ", ".join(f"_client{v}" for v in captures) # from juju.client import _client2, _client1, _client3 ... f.write("\nfrom juju.client import " + clients + "\n\n") # CLIENTS = { .... f.write( CLIENT_TABLE.format( - clients=",\n ".join([ - '"{}": _client{}'.format(v, v) for v in captures - ]) + clients=",\n ".join([f'"{v}": _client{v}' for v in captures]) ) ) @@ -947,7 +922,7 @@ def generate_facades( for juju_version in sorted(schemas.keys(), key=packaging.version.parse): for schema in schemas[juju_version]: cls, source = buildFacade(schema) - cls_name = "{}Facade".format(schema.name) + cls_name = f"{schema.name}Facade" captures[schema.version].clear(cls_name) # Make the factory class for _client.py @@ -971,7 +946,7 @@ def load_schemas(options): try: juju_version = re.search(JUJU_VERSION, p).group() except AttributeError: - print("Cannot extract a juju version from {}".format(p)) + print(f"Cannot extract a juju version from {p}") print("Schemas must include a juju version in the filename") raise SystemExit(1) new_schemas = json.loads(Path(p).read_text("utf-8")) diff --git a/juju/client/facade_versions.py b/juju/client/facade_versions.py index 8b8268c48..a4f7cf29d 100644 --- a/juju/client/facade_versions.py +++ b/juju/client/facade_versions.py @@ -4,7 +4,6 @@ from typing import Dict, Sequence - # Please keep in alphabetical order # in future this will likely be generated automatically (perhaps at runtime) client_facade_versions = { diff --git a/juju/client/gocookies.py b/juju/client/gocookies.py index d568cc8fd..0c33f0be6 100644 --- a/juju/client/gocookies.py +++ b/juju/client/gocookies.py @@ -12,11 +12,13 @@ class GoCookieJar(cookiejar.FileCookieJar): """A CookieJar implementation that reads and writes cookies to the cookiejar format as understood by the Go package - github.com/juju/persistent-cookiejar.""" + github.com/juju/persistent-cookiejar. + """ def _really_load(self, f, filename, ignore_discard, ignore_expires): """Implement the _really_load method called by FileCookieJar - to implement the actual cookie loading""" + to implement the actual cookie loading + """ data = json.load(f) or [] now = time.time() for cookie in map(go_to_py_cookie, data): diff --git a/juju/client/jujudata.py b/juju/client/jujudata.py index c38d8a306..80f393bee 100644 --- a/juju/client/jujudata.py +++ b/juju/client/jujudata.py @@ -2,7 +2,6 @@ # Licensed under the Apache V2, see LICENCE file for details. import abc -import io import os import pathlib @@ -57,14 +56,10 @@ def parse_model(self, model): # by using the current user for the controller. accounts = self.accounts().get(controller_name) if accounts is None: - raise JujuError( - "No account found for controller {} ".format(controller_name) - ) + raise JujuError(f"No account found for controller {controller_name} ") username = accounts.get("user") if username is None: - raise JujuError( - "No username found for controller {}".format(controller_name) - ) + raise JujuError(f"No username found for controller {controller_name}") model_name = username + "/" + model_name return controller_name, model_name @@ -72,7 +67,8 @@ def parse_model(self, model): class FileJujuData(JujuData): """Provide access to the Juju client configuration files. - Any configuration file is read once and then cached.""" + Any configuration file is read once and then cached. + """ def __init__(self): self.path = juju_config_dir() @@ -178,7 +174,7 @@ def _load_yaml(self, filename, key): return self._loaded[filename].get(key) # TODO use the file lock like Juju does. filepath = os.path.join(self.path, filename) - with io.open(filepath, "rt") as f: + with open(filepath) as f: data = yaml.safe_load(f) self._loaded[filename] = data return data.get(key) diff --git a/juju/client/overrides.py b/juju/client/overrides.py index fdead912c..73f33a120 100644 --- a/juju/client/overrides.py +++ b/juju/client/overrides.py @@ -8,10 +8,10 @@ from .facade import ReturnMapping, Type, TypeEncoder __all__ = [ - "Delta", - "Number", "Binary", "ConfigValue", + "Delta", + "Number", "Resource", ] @@ -43,10 +43,7 @@ class Delta(Type): _toPy = {"deltas": "deltas"} def __init__(self, deltas=None): - """ - :param deltas: [str, str, object] - - """ + """:param deltas: [str, str, object]""" self.deltas = deltas Change = namedtuple("Change", "entity type data") @@ -99,10 +96,7 @@ async def AddPendingResources( class AllWatcherFacade(Type): - """ - Patch rpc method of allwatcher to add in 'id' stuff. - - """ + """Patch rpc method of allwatcher to add in 'id' stuff.""" async def rpc(self, msg): if not hasattr(self, "Id"): @@ -122,8 +116,7 @@ class _FindTagsResults(Type): _toPy = {"matches": "matches"} def __init__(self, matches=None, **unknown_fields): - """ - FindTagsResults wraps the mapping between the requested prefix and the + """FindTagsResults wraps the mapping between the requested prefix and the matching tags for each requested prefix. Matches map[string][]Entity `json:"matches"` @@ -135,8 +128,7 @@ def __init__(self, matches=None, **unknown_fields): @ReturnMapping(_FindTagsResults) async def FindActionTagsByPrefix(self, prefixes): - """ - prefixes : typing.Sequence[str] + """Prefixes : typing.Sequence[str] Returns -> typing.Sequence[~Entity] """ # map input types to rpc msg @@ -150,8 +142,7 @@ async def FindActionTagsByPrefix(self, prefixes): class Number(_definitions.Number): - """ - This type represents a semver string. + """This type represents a semver string. Because it is not standard JSON, the typical from_json parsing fails and the parsing must be handled specially. @@ -161,13 +152,12 @@ class Number(_definitions.Number): numberPat = re.compile( r"^(\d{1,9})\.(\d{1,9})(?:\.|-([a-z]+))(\d{1,9})(\.\d{1,9})?$" - ) # noqa + ) def __init__( self, major=None, minor=None, patch=None, tag=None, build=None, **unknown_fields ): - """ - major : int + """Major : int minor : int patch : int tag : str @@ -180,9 +170,7 @@ def __init__( self.build = int(build or "0") def __repr__(self): - return "".format( - self.major, self.minor, self.patch, self.tag, self.build - ) + return f"" def __str__(self): return self.serialize() @@ -226,7 +214,7 @@ def from_json(cls, data): "build": (match.group(5)[1:] if match.group(5) else 0), } if not parsed: - raise TypeError("Unable to parse Number version string: {}".format(data)) + raise TypeError(f"Unable to parse Number version string: {data}") d = {} for k, v in parsed.items(): d[cls._toPy.get(k, k)] = v @@ -236,11 +224,11 @@ def from_json(cls, data): def serialize(self): s = "" if not self.tag: - s = "{}.{}.{}".format(self.major, self.minor, self.patch) + s = f"{self.major}.{self.minor}.{self.patch}" else: - s = "{}.{}-{}{}".format(self.major, self.minor, self.tag, self.patch) + s = f"{self.major}.{self.minor}-{self.tag}{self.patch}" if self.build: - s = "{}.{}".format(s, self.build) + s = f"{s}.{self.build}" return s def to_json(self): @@ -248,8 +236,7 @@ def to_json(self): class Binary(_definitions.Binary): - """ - This type represents a semver string with additional series and arch info. + """This type represents a semver string with additional series and arch info. Because it is not standard JSON, the typical from_json parsing fails and the parsing must be handled specially. @@ -259,11 +246,10 @@ class Binary(_definitions.Binary): binaryPat = re.compile( r"^(\d{1,9})\.(\d{1,9})(?:\.|-([a-z]+))(\d{1,9})(\.\d{1,9})?-([^-]+)-([^-]+)$" - ) # noqa + ) def __init__(self, number=None, series=None, arch=None, **unknown_fields): - """ - number : Number + """Number : Number series : str arch : str """ @@ -272,9 +258,7 @@ def __init__(self, number=None, series=None, arch=None, **unknown_fields): self.arch = arch def __repr__(self): - return "".format( - self.number, self.series, self.arch - ) + return f"" def __str__(self): return self.serialize() @@ -311,7 +295,7 @@ def from_json(cls, data): "arch": match.group(7), } if parsed is None: - raise TypeError("Unable to parse Binary version string: {}".format(data)) + raise TypeError(f"Unable to parse Binary version string: {data}") d = {} for k, v in parsed.items(): d[cls._toPy.get(k, k)] = v @@ -319,7 +303,7 @@ def from_json(cls, data): return cls(**d) def serialize(self): - return "{}-{}-{}".format(self.number.serialize(), self.series, self.arch) + return f"{self.number.serialize()}-{self.series}-{self.arch}" def to_json(self): return self.serialize() @@ -327,9 +311,7 @@ def to_json(self): class ConfigValue(_definitions.ConfigValue): def __repr__(self): - return "<{} source={} value={}>".format( - type(self).__name__, repr(self.source), repr(self.value) - ) + return f"<{type(self).__name__} source={self.source!r} value={self.value!r}>" class Resource(Type): @@ -366,8 +348,7 @@ def __init__( origin=None, **unknown_fields, ): - """ - charmresource : CharmResource + """Charmresource : CharmResource application : str id_ : str pending_id : str @@ -407,8 +388,7 @@ class Macaroon(Type): def __init__( self, signature="", caveats=None, location=None, identifier="", **unknown_fields ): - """ - signature : str + """Signature : str caveats : typing.Sequence<+T_co>[~RemoteSpace]<~RemoteSpace> location : str identifier : str @@ -425,8 +405,6 @@ class Caveat(Type): _toPy = {"cid": "cid"} def __init__(self, cid="", **unknown_fields): - """ - cid : str - """ + """Cid : str""" self.cid = cid self.unknown_fields = unknown_fields diff --git a/juju/client/proxy/kubernetes/proxy.py b/juju/client/proxy/kubernetes/proxy.py index 22adf7fcd..681c73cef 100644 --- a/juju/client/proxy/kubernetes/proxy.py +++ b/juju/client/proxy/kubernetes/proxy.py @@ -1,13 +1,14 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. +import logging import os import tempfile -import logging -from juju.client.proxy.proxy import Proxy, ProxyNotConnectedError from kubernetes import client from kubernetes.stream import portforward +from juju.client.proxy.proxy import Proxy, ProxyNotConnectedError + log = logging.getLogger("juju.client.connection") @@ -33,7 +34,7 @@ def __init__( try: self.remote_port = int(remote_port) except ValueError: - raise ValueError("Invalid port number: {}".format(remote_port)) + raise ValueError(f"Invalid port number: {remote_port}") if ca_cert: self.temp_ca_file = tempfile.NamedTemporaryFile(delete=False) diff --git a/juju/client/proxy/proxy.py b/juju/client/proxy/proxy.py index 4cc55d7cd..3a521e10a 100644 --- a/juju/client/proxy/proxy.py +++ b/juju/client/proxy/proxy.py @@ -11,9 +11,7 @@ class ProxyNotConnectedError(Exception): class Proxy: - """ - Abstract class to represent a generic controller connection proxy - """ + """Abstract class to represent a generic controller connection proxy""" @abstractmethod def connect(self): diff --git a/juju/constraints.py b/juju/constraints.py index c9b3ab710..885dcfb47 100644 --- a/juju/constraints.py +++ b/juju/constraints.py @@ -20,8 +20,8 @@ import re from typing import Dict, List, Optional, TypedDict, Union -from typing_extensions import Required, NotRequired +from typing_extensions import NotRequired, Required # Matches on a string specifying memory size MEM = re.compile("^[1-9][0-9]*[MGTP]$") @@ -86,8 +86,7 @@ class ConstraintsDict(TypedDict, total=False): def parse(constraints: Union[str, ConstraintsDict]) -> Optional[ConstraintsDict]: - """ - Constraints must be expressed as a string containing only spaces + """Constraints must be expressed as a string containing only spaces and key value pairs joined by an '='. """ diff --git a/juju/controller.py b/juju/controller.py index 351f942e2..b0bd8b054 100644 --- a/juju/controller.py +++ b/juju/controller.py @@ -8,7 +8,7 @@ import websockets -from . import errors, tag, utils, jasyncio +from . import errors, jasyncio, tag, utils from .client import client, connector from .errors import JujuAPIError from .offerendpoints import ParseError as OfferParseError @@ -156,16 +156,14 @@ async def update_endpoints(self): pass async def connect_current(self): - """ - .. deprecated:: 0.7.3 - Use :meth:`.connect()` instead. + """.. deprecated:: 0.7.3 + Use :meth:`.connect()` instead. """ return await self.connect() async def connect_controller(self, controller_name): - """ - .. deprecated:: 0.7.3 - Use :meth:`.connect(controller_name)` instead. + """.. deprecated:: 0.7.3 + Use :meth:`.connect(controller_name)` instead. """ return await self.connect(controller_name) @@ -179,7 +177,8 @@ def is_connected(self): def connection(self): """Return the current Connection object. It raises an exception - if the Controller is disconnected""" + if the Controller is disconnected + """ return self._connector.connection() @property @@ -245,7 +244,7 @@ async def add_credential( if not credential: name, credential = self._connector.jujudata.load_credential(cloud, name) if credential is None: - raise errors.JujuError("Unable to find credential: {}".format(name)) + raise errors.JujuError(f"Unable to find credential: {name}") if credential.auth_type == "jsonfile" and "file" in credential.attrs: # file creds have to be loaded before being sent to the controller @@ -527,9 +526,7 @@ async def get_model_info(self, model_name=None, model_uuid=None): model_uuid = uuids[model_name] except KeyError: raise errors.JujuError( - "{} is not among the models in the controller : {}".format( - model_name, uuids - ) + f"{model_name} is not among the models in the controller : {uuids}" ) entity = client.Entity(tag.model(model_uuid)) _model_info_results = await facade.ModelInfo(entities=[entity]) @@ -564,9 +561,7 @@ async def clouds(self): return await cloud_facade.Clouds() async def get_cloud(self): - """ - Get the name of the cloud that this controller lives on. - """ + """Get the name of the cloud that this controller lives on.""" cloud_facade = client.CloudFacade.from_connection(self.connection()) result = await cloud_facade.Clouds() @@ -574,9 +569,8 @@ async def get_cloud(self): return tag.untag("cloud-", cloud) async def get_models(self, all=False, username=None): - """ - .. deprecated:: 0.7.0 - Use :meth:`.list_models` instead. + """.. deprecated:: 0.7.0 + Use :meth:`.list_models` instead. """ return await self.list_models(username, all) @@ -757,15 +751,13 @@ async def revoke_model(self, username, model_uuid, acl="read"): async def create_offer( self, model_uuid, endpoint, offer_name=None, application_name=None ): - """ - Offer a deployed application using a series of endpoints for use by + """Offer a deployed application using a series of endpoints for use by consumers. @param endpoint: holds the application and endpoint you want to offer @param offer_name: override the offer name to help the consumer @param application_name: overrides the application name in the endpoint """ - # If we have both the offer_name and the application_name # then we're coming from bundle/overlays, so no need to parse the endpoint # Also we accept endpoints without a colon (:) in the overlays @@ -794,8 +786,7 @@ async def create_offer( return await facade.Offer(offers=[params]) async def list_offers(self, model_name): - """ - Offers list information about applications' endpoints that have been + """Offers list information about applications' endpoints that have been shared and who is connected. """ params = client.OfferFilter() @@ -805,8 +796,7 @@ async def list_offers(self, model_name): return await facade.ListApplicationOffers(filters=[params]) async def remove_offer(self, model_uuid, offer, force=False): - """ - Remove offer for an application. + """Remove offer for an application. Offers will also remove relations to those offers, use force to do so, without an error. @@ -832,8 +822,7 @@ async def remove_offer(self, model_uuid, offer, force=False): return await facade.DestroyOffers(force=force, offer_urls=[url.string()]) async def get_consume_details(self, endpoint): - """ - get_consume_details returns the details necessary to pass to another + """get_consume_details returns the details necessary to pass to another model to consume the specified offers represented by the urls. """ facade = client.ApplicationOffersFacade.from_connection(self.connection()) @@ -849,8 +838,7 @@ async def get_consume_details(self, endpoint): return result async def watch_model_summaries(self, callback, as_admin=False): - """ - Watch the controller for model summary updates. + """Watch the controller for model summary updates. If as_admin is true, a call will be made as the admin to watch all models in the controller. If the user isn't a superuser they @@ -869,7 +857,7 @@ async def _watcher(stop_event): watcher.Id = result.watcher_id else: result = await facade.WatchModelSummaries() - log.debug("watcher id: {}".format(result.watcher_id)) + log.debug(f"watcher id: {result.watcher_id}") watcher.Id = result.watcher_id while True: @@ -901,8 +889,7 @@ async def _watcher(stop_event): return stop_event async def add_secret_backends(self, id, name, backend_type, config): - """ - Add a new secret backend. + """Add a new secret backend. Parameters ---------- @@ -918,6 +905,7 @@ async def add_secret_backends(self, id, name, backend_type, config): ------- list a list of errors if any + """ facade = client.SecretBackendsFacade.from_connection(self.connection()) return await facade.AddSecretBackends([ @@ -931,8 +919,7 @@ async def add_secret_backends(self, id, name, backend_type, config): ]) async def list_secret_backends(self, reveal=False): - """ - Return the list of secret backends + """Return the list of secret backends Parameters ---------- @@ -943,13 +930,13 @@ async def list_secret_backends(self, reveal=False): ------- list a list of available secret backends + """ facade = client.SecretBackendsFacade.from_connection(self.connection()) return await facade.ListSecretBackends(None, reveal) async def remove_secret_backends(self, name, force=False): - """ - Remove a secrets backend. + """Remove a secrets backend. Parameters ---------- @@ -959,6 +946,7 @@ async def remove_secret_backends(self, name, force=False): Returns ------- error if any + """ facade = client.SecretBackendsFacade.from_connection(self.connection()) return await facade.RemoveSecretBackends([{"name": name, "force": force}]) @@ -971,8 +959,7 @@ async def update_secret_backends( name_change=None, token_rotate_interval=None, ): - """ - Update a backend. + """Update a backend. Parameters ---------- @@ -986,6 +973,7 @@ async def update_secret_backends( new name for the backend token_rotate_interval : int token rotation interval + """ facade = client.SecretBackendsFacade.from_connection(self.connection()) return await facade.UpdateSecretBackends([ diff --git a/juju/errors.py b/juju/errors.py index f970c4ab7..839941511 100644 --- a/juju/errors.py +++ b/juju/errors.py @@ -62,12 +62,13 @@ class JujuEntityNotFoundError(JujuError): expected that the entity was found in state and this is a terminal condition. To fix this condition, you should disconnect and reconnect to ensure that - any missing entities are correctly picked up.""" + any missing entities are correctly picked up. + """ def __init__(self, entity_name, entity_types=None): self.entity_name = entity_name self.entity_types = entity_types - super().__init__("Entity not found: {}".format(entity_name)) + super().__init__(f"Entity not found: {entity_name}") class JujuModelError(JujuError): diff --git a/juju/jasyncio.py b/juju/jasyncio.py index 75e809e58..f86fb6635 100644 --- a/juju/jasyncio.py +++ b/juju/jasyncio.py @@ -10,37 +10,19 @@ # this layer. import asyncio -import signal import functools -import websockets import logging +import signal + +import websockets ROOT_LOGGER = logging.getLogger() from asyncio import ( - Event, - TimeoutError, - Queue, - ensure_future, - gather, - sleep, - wait_for, - create_subprocess_exec, - subprocess, - wait, - FIRST_COMPLETED, - Lock, - as_completed, - new_event_loop, - get_event_loop_policy, CancelledError, - get_running_loop, create_task, - ALL_COMPLETED, - all_tasks, - current_task, - shield, -) # noqa + wait, +) def create_task_with_handler(coro, task_name, logger=ROOT_LOGGER): @@ -79,10 +61,8 @@ def _task_result_exp_handler(task, task_name=task_name, logger=logger): return task -class SingletonEventLoop(object): - """ - Single instance containing an event loop to be reused. - """ +class SingletonEventLoop: + """Single instance containing an event loop to be reused.""" loop = None @@ -95,13 +75,11 @@ def __new__(cls): def run(*steps): - """ - Helper to run one or more async functions synchronously, with graceful + """Helper to run one or more async functions synchronously, with graceful handling of SIGINT / Ctrl-C. Returns the return value of the last function. """ - if not steps: return diff --git a/juju/juju.py b/juju/juju.py index 69b3ec137..f77ab47ad 100644 --- a/juju/juju.py +++ b/juju/juju.py @@ -1,12 +1,12 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -from juju.controller import Controller from juju.client.jujudata import FileJujuData +from juju.controller import Controller from juju.errors import JujuError -class Juju(object): +class Juju: def __init__(self, jujudata=None): self.jujudata = jujudata or FileJujuData() @@ -22,7 +22,6 @@ async def get_controller(self, name, include_passwords=False): The returned controller will try and connect to be ready to use. """ - # check if name is in the controllers.yaml controllers = self.jujudata.controllers() assert isinstance(controllers, dict) diff --git a/juju/machine.py b/juju/machine.py index 55fd59cb7..3ac75394b 100644 --- a/juju/machine.py +++ b/juju/machine.py @@ -7,11 +7,12 @@ import pyrfc3339 +from juju.utils import block_until, juju_ssh_key_paths + from . import jasyncio, model, tag from .annotationhelper import _get_annotations, _set_annotations from .client import client from .errors import JujuError -from juju.utils import juju_ssh_key_paths, block_until log = logging.getLogger(__name__) @@ -104,7 +105,7 @@ async def scp_to( except ValueError: # otherwise we assume it to be a DNS resolvable string address = self.dns_name - destination = "{}@{}:{}".format(user, address, destination) + destination = f"{user}@{address}:{destination}" await self._scp(source, destination, scp_opts) async def scp_from( @@ -138,7 +139,7 @@ async def scp_from( except ValueError: # otherwise we assume it to be a DNS resolvable string address = self.dns_name - source = "{}@{}:{}".format(user, address, source) + source = f"{user}@{address}:{source}" await self._scp(source, destination, scp_opts) async def _scp(self, source, destination, scp_opts): @@ -188,7 +189,7 @@ async def ssh( if wait_for_active: await block_until(lambda: self.addresses, timeout=timeout) address = self.dns_name - destination = "{}@{}".format(user, address) + destination = f"{user}@{address}" _, id_path = juju_ssh_key_paths() cmd = [ "ssh", diff --git a/juju/model.py b/juju/model.py index 0bc3442d6..404d3ee8f 100644 --- a/juju/model.py +++ b/juju/model.py @@ -7,9 +7,9 @@ import json import logging import os -import sys import re import stat +import sys import tempfile import warnings import weakref @@ -19,27 +19,30 @@ from functools import partial from pathlib import Path -import yaml import websockets +import yaml -from . import provisioner, tag, utils, jasyncio +from . import jasyncio, provisioner, tag, utils from .annotationhelper import _get_annotations, _set_annotations from .bundle import BundleHandler, get_charm_series, is_local_charm from .charmhub import CharmHub from .client import client, connector from .client.overrides import Caveat, Macaroon from .constraints import parse as parse_constraints -from .controller import Controller, ConnectedController +from .controller import ConnectedController, Controller from .delta import get_entity_class, get_entity_delta -from .errors import JujuAPIError, JujuError, JujuModelConfigError, JujuBackupError from .errors import ( - JujuModelError, - JujuAppError, - JujuUnitError, JujuAgentError, + JujuAPIError, + JujuAppError, + JujuBackupError, + JujuError, JujuMachineError, - PylibjujuError, + JujuModelConfigError, + JujuModelError, JujuNotSupportedError, + JujuUnitError, + PylibjujuError, ) from .exceptions import DeadEntityException from .names import is_valid_application @@ -104,12 +107,10 @@ def cares_about(self, delta): class ModelObserver: - """ - Base class for creating observers that react to changes in a model. - """ + """Base class for creating observers that react to changes in a model.""" async def __call__(self, delta, old, new, model): - handler_name = "on_{}_{}".format(delta.entity, delta.type) + handler_name = f"on_{delta.entity}_{delta.type}" method = getattr(self, handler_name, self.on_change) await method(delta, old, new, model) @@ -243,7 +244,6 @@ def get_entity(self, entity_type, entity_id, history_index=-1, connected=True): history_index, an index into the history deque for the entity. """ - if history_index < 0 and history_index != -1: history_index += len(self.entity_history(entity_type, entity_id)) if history_index < 0: @@ -283,7 +283,7 @@ def __init__(self, entity_id, model, history_index=-1, connected=True): self._status = "unknown" def __repr__(self): - return '<{} entity_id="{}">'.format(type(self).__name__, self.entity_id) + return f'<{type(self).__name__} entity_id="{self.entity_id}">' def __getattr__(self, name): """Fetch object attributes from the underlying data dict held in the @@ -381,11 +381,9 @@ def safe_data(self): """ if self.data is None: raise DeadEntityException( - "Entity {}:{} is dead - its attributes can no longer be " + f"Entity {self.entity_type}:{self.entity_id} is dead - its attributes can no longer be " "accessed. Use the .previous() method on this object to get " - "a copy of the object at its previous state.".format( - self.entity_type, self.entity_id - ) + "a copy of the object at its previous state." ) return self.data @@ -472,13 +470,12 @@ async def resolve( force=False, model_conf=None, ): - """resolve attempts to resolve a local charm or bundle using the url + """Resolve attempts to resolve a local charm or bundle using the url and architecture. If information is missing, it will attempt to backfill that information, before sending the result back. -- revision flag is ignored for local charms """ - entity_path = Path(charm_path) if entity_path.suffix == ".yaml": bundle_path = entity_path @@ -487,7 +484,7 @@ async def resolve( origin = client.CharmOrigin(source="local", architecture=architecture) if not (entity_path.is_dir() or entity_path.is_file()): - raise JujuError("{} path not found".format(entity_url)) + raise JujuError(f"{entity_url} path not found") is_bundle = bundle_path.exists() @@ -529,7 +526,7 @@ async def resolve( force=False, model_conf=None, ): - """resolve attempts to resolve charmhub charms or bundles. A request to + """Resolve attempts to resolve charmhub charms or bundles. A request to the charmhub API is required to correctly determine the charm url and underlying origin. """ @@ -578,9 +575,7 @@ async def resolve( class Model: - """ - The main API for interacting with a Juju model. - """ + """The main API for interacting with a Juju model.""" def __init__( self, @@ -628,7 +623,8 @@ def is_connected(self): def connection(self): """Return the current Connection object. It raises an exception - if the Model is disconnected""" + if the Model is disconnected + """ return self._connector.connection() async def get_controller(self): @@ -745,16 +741,14 @@ async def connect(self, *args, **kwargs): await self._after_connect(model_name, model_uuid) async def connect_model(self, model_name, **kwargs): - """ - .. deprecated:: 0.6.2 - Use ``connect(model_name=model_name)`` instead. + """.. deprecated:: 0.6.2 + Use ``connect(model_name=model_name)`` instead. """ return await self.connect(model_name=model_name, **kwargs) async def connect_current(self): - """ - .. deprecated:: 0.6.2 - Use ``connect()`` instead. + """.. deprecated:: 0.6.2 + Use ``connect()`` instead. """ return await self.connect() @@ -1301,9 +1295,7 @@ async def _all_watcher(): entity = get_entity_delta(delta) except KeyError: if self.strict_mode: - raise JujuError( - "unknown delta type '{}'".format(delta.entity) - ) + raise JujuError(f"unknown delta type '{delta.entity}'") if not self.strict_mode and entity is None: continue @@ -1348,8 +1340,7 @@ async def _notify_observers(self, delta, old_obj, new_obj): jasyncio.ensure_future(o(delta, old_obj, new_obj, self)) async def _wait(self, entity_type, entity_id, action, predicate=None): - """ - Block the calling routine until a given action has happened to the + """Block the calling routine until a given action has happened to the given entity :param entity_type: The entity's type. @@ -1389,7 +1380,6 @@ async def _wait_for_new(self, entity_type, entity_id): async def wait_for_action(self, action_id): """Given an action, wait for it to complete.""" - if action_id.startswith("action-"): # if we've been passed action.tag, transform it into the # id that the api deltas will use. @@ -1527,9 +1517,8 @@ async def add_machine(self, spec=None, constraints=None, disks=None, series=None return await self._wait_for_new("machine", machine_id) async def add_relation(self, relation1, relation2): - """ - .. deprecated:: 2.9.9 - Use ``relate()`` instead + """.. deprecated:: 2.9.9 + Use ``relate()`` instead """ return await self.relate(relation1, relation2) @@ -1569,9 +1558,7 @@ async def integrate(self, relation1, relation2): if facade_cls.best_facade_version(self.connection()) < 5: # old clients don't support cross model capability raise JujuError( - "cannot add relation to {}: remote endpoints not supported".format( - remote_endpoint.string() - ) + f"cannot add relation to {remote_endpoint.string()}: remote endpoints not supported" ) if remote_endpoint.has_empty_source(): @@ -1600,9 +1587,7 @@ def _find_relation(*specs): if rel: return rel raise JujuError( - "Relation {} {} exists but not in model".format( - endpoints[0], endpoints[1] - ) + f"Relation {endpoints[0]} {endpoints[1]} exists but not in model" ) specs = [ @@ -1785,21 +1770,16 @@ async def deploy( :param str[] attach_storage: Existing storage to attach to the deployed unit (not available on k8s models) """ - if storage: storage = {k: client.Constraints(**v) for k, v in storage.items()} if trust and (self.info.agent_version < client.Number.from_json("2.4.0")): raise NotImplementedError( - "trusted is not supported on model version {}".format( - self.info.agent_version - ) + f"trusted is not supported on model version {self.info.agent_version}" ) if not all([isinstance(st, str) for st in attach_storage]): raise JujuError( - "Expected attach_storage to be a list of strings, given {}".format( - attach_storage - ) + f"Expected attach_storage to be a list of strings, given {attach_storage}" ) # Ensure what we pass in, is a string. @@ -1822,9 +1802,7 @@ async def deploy( name = url.name if schema not in self.deploy_types: - raise JujuError( - "unknown deploy type {}, expected charmhub or local".format(schema) - ) + raise JujuError(f"unknown deploy type {schema}, expected charmhub or local") model_conf = await self.get_config() res = await self.deploy_types[schema].resolve( @@ -1840,7 +1818,7 @@ async def deploy( ) if res.identifier is None: - raise JujuError("unknown charm or bundle {}".format(entity_url)) + raise JujuError(f"unknown charm or bundle {entity_url}") identifier = res.identifier charm_series = series @@ -1925,7 +1903,7 @@ async def deploy( if base is None and charm_series is None: raise JujuError( "Either series or base is needed to deploy the " - "charm at {}. ".format(charm_dir) + f"charm at {charm_dir}. " ) identifier = await self.add_local_charm_dir(charm_dir, charm_series) @@ -2021,7 +1999,7 @@ async def _resolve_charm( resolve=[{"reference": str(url), "charm-origin": resolve_origin}] ) if len(resp.results) != 1: - raise JujuError("expected one result, received {}".format(resp.results)) + raise JujuError(f"expected one result, received {resp.results}") result = resp.results[0] if result.error: @@ -2143,11 +2121,7 @@ async def add_local_resources(self, application, entity_url, metadata, resources for name, path in resources.items(): resource_type = metadata["resources"][name]["type"] if resource_type not in {"oci-image", "file"}: - log.info( - "Resource {} of type {} is not supported".format( - name, resource_type - ) - ) + log.info(f"Resource {name} of type {resource_type} is not supported") continue charmresource = { @@ -2189,14 +2163,12 @@ async def add_local_resources(self, application, entity_url, metadata, resources def _upload(self, data, path, app_name, res_name, res_type, pending_id): conn, headers, path_prefix = self.connection().https_connection() - query = "?pendingid={}".format(pending_id) - url = "{}/applications/{}/resources/{}{}".format( - path_prefix, app_name, res_name, query - ) + query = f"?pendingid={pending_id}" + url = f"{path_prefix}/applications/{app_name}/resources/{res_name}{query}" if res_type == "oci-image": - disp = 'multipart/form-data; filename="{}"'.format(path) + disp = f'multipart/form-data; filename="{path}"' else: - disp = 'form-data; filename="{}"'.format(path) + disp = f'form-data; filename="{path}"' headers["Content-Type"] = "application/octet-stream" headers["Content-Length"] = len(data) @@ -2355,7 +2327,6 @@ def download_backup(self, archive_id, target_filename=None): :return str: Path to the archive file """ - conn, headers, path_prefix = self.connection().https_connection() path = "%s/backups" % path_prefix headers["Content-Type"] = "application/json" @@ -2382,7 +2353,7 @@ def download_backup(self, archive_id, target_filename=None): with open(str(file_name), "wb") as f: try: f.write(result) - except (OSError, IOError) as e: + except OSError as e: raise JujuBackupError( "backup ID : %s was fetched, but : %s" % (archive_id, e) ) @@ -2537,7 +2508,6 @@ async def set_constraints(self, constraints): :param dict config: Mapping of model constraints """ - facade_cls = client.ModelConfigFacade facade = facade_cls.from_connection(self.connection()) @@ -2653,8 +2623,7 @@ async def get_metrics(self, *tags): return metrics async def create_offer(self, endpoint, offer_name=None, application_name=None): - """ - Offer a deployed application using a series of endpoints for use by + """Offer a deployed application using a series of endpoints for use by consumers. @param endpoint: holds the application and endpoint you want to offer @@ -2669,16 +2638,14 @@ async def create_offer(self, endpoint, offer_name=None, application_name=None): ) async def list_offers(self): - """ - Offers list information about applications' endpoints that have been + """Offers list information about applications' endpoints that have been shared and who is connected. """ async with ConnectedController(self.connection()) as controller: return await controller.list_offers(self.name) async def remove_offer(self, endpoint, force=False): - """ - Remove offer for an application. + """Remove offer for an application. Offers will also remove relations to those offers, use force to do so, without an error. @@ -2689,15 +2656,13 @@ async def remove_offer(self, endpoint, force=False): async def consume( self, endpoint, application_alias="", controller_name=None, controller=None ): - """ - Adds a remote offer to the model. Relations can be created later using + """Adds a remote offer to the model. Relations can be created later using "juju relate". If consuming a relation from a model on different controller the controller name must be included in the endpoint. The controller_name argument is being deprecated. """ - if controller and controller_name: raise JujuError("cannot set both controller_name and controller") try: @@ -2706,9 +2671,7 @@ async def consume( log.error(e.message) raise if offer.has_endpoint(): - raise JujuError( - "remote offer {} should not include an endpoint".format(endpoint) - ) + raise JujuError(f"remote offer {endpoint} should not include an endpoint") if offer.user == "": offer.user = self.info.username endpoint = offer.string() @@ -2740,9 +2703,7 @@ async def consume( if not controller: await source.disconnect() if consume_details is None or consume_details.offer is None: - raise JujuAPIError( - "missing consuming offer url for {}".format(offer.string()) - ) + raise JujuAPIError(f"missing consuming offer url for {offer.string()}") offer_url = parse_offer_url(consume_details.offer.offer_url) offer_url.source = offer.source @@ -2759,9 +2720,7 @@ async def consume( facade = client.ApplicationFacade.from_connection(self.connection()) results = await facade.Consume(args=[arg]) if len(results.results) != 1: - raise JujuAPIError( - "expected 1 result, received {}".format(len(results.results)) - ) + raise JujuAPIError(f"expected 1 result, received {len(results.results)}") if results.results[0].error is not None: raise JujuAPIError(results.results[0].error) local_name = offer_url.application @@ -2770,13 +2729,12 @@ async def consume( return local_name async def remove_saas(self, name): - """ - Removing a consumed (SAAS) application will terminate any relations that + """Removing a consumed (SAAS) application will terminate any relations that application has, potentially leaving any related local applications in a non-functional state. """ if not is_valid_application(name): - raise JujuError("invalid SAAS application name {}".format(name)) + raise JujuError(f"invalid SAAS application name {name}") arg = client.DestroyConsumedApplicationParams() arg.application_tag = application_tag(name) @@ -2785,9 +2743,7 @@ async def remove_saas(self, name): return await facade.DestroyConsumedApplications(applications=[arg]) async def export_bundle(self, filename=None): - """ - Exports the current model configuration as a reusable bundle. - """ + """Exports the current model configuration as a reusable bundle.""" facade = client.BundleFacade.from_connection(self.connection()) result = await facade.ExportBundle() if result.error is not None: @@ -2799,7 +2755,7 @@ async def export_bundle(self, filename=None): try: with open(str(filename), "w") as file: file.write(result.result) - except IOError: + except OSError: raise async def add_secret(self, name, data_args, file="", info=""): @@ -2875,9 +2831,7 @@ async def update_secret(self, name, data_args=[], new_name="", file="", info="") raise JujuAPIError(result_error.error) async def list_secrets(self, filter=None, show_secrets=False): - """ - Returns the list of available secrets. - """ + """Returns the list of available secrets.""" facade = client.SecretsFacade.from_connection(self.connection()) results = await facade.ListSecrets( filter_=filter, @@ -3155,22 +3109,12 @@ def _raise_for_status(entities, status): if now - idle_start < idle_period: busy.append( - "{} [{}] {}: {}".format( - unit.name, - unit.agent_status, - unit.workload_status, - unit.workload_status_message, - ) + f"{unit.name} [{unit.agent_status}] {unit.workload_status}: {unit.workload_status_message}" ) else: idle_times.pop(unit.name, None) busy.append( - "{} [{}] {}: {}".format( - unit.name, - unit.agent_status, - unit.workload_status, - unit.workload_status_message, - ) + f"{unit.name} [{unit.agent_status}] {unit.workload_status}: {unit.workload_status_message}" ) _raise_for_status(errors, "error") _raise_for_status(blocks, "blocked") @@ -3186,8 +3130,7 @@ def _raise_for_status(entities, status): def _create_consume_args(offer, macaroon, controller_info): - """ - Convert a typed object that has been normalised to a overridden typed + """Convert a typed object that has been normalised to a overridden typed definition. @param offer: takes an offer and serialises it into a valid type @@ -3241,8 +3184,7 @@ def _create_consume_args(offer, macaroon, controller_info): class CharmArchiveGenerator: - """ - Create a Zip archive of a local charm directory for upload to a controller. + """Create a Zip archive of a local charm directory for upload to a controller. This is used automatically by `Model.add_local_charm_dir <#juju.model.Model.add_local_charm_dir>`_. diff --git a/juju/names.py b/juju/names.py index 845d8ab80..0e9270fcb 100644 --- a/juju/names.py +++ b/juju/names.py @@ -70,13 +70,9 @@ def match_model_application(val, match_type=None): valid_user_name_snippet = "[a-zA-Z0-9][a-zA-Z0-9.+-]*[a-zA-Z0-9]" -valid_user_snippet = "(?:{}(?:@{})?)".format( - valid_user_name_snippet, valid_user_name_snippet -) +valid_user_snippet = f"(?:{valid_user_name_snippet}(?:@{valid_user_name_snippet})?)" USER = re.compile( - "^(?P{})(?:@(?P{}))?$".format( - valid_user_name_snippet, valid_user_name_snippet - ) + f"^(?P{valid_user_name_snippet})(?:@(?P{valid_user_name_snippet}))?$" ) diff --git a/juju/offerendpoints.py b/juju/offerendpoints.py index 44931ba87..3a39556d6 100644 --- a/juju/offerendpoints.py +++ b/juju/offerendpoints.py @@ -65,16 +65,16 @@ def parse_offer_endpoint(endpoint): model_group = model_group.split("/")[0] if (model_group is not None) and (not match_model(model_group)): - raise ParseError("model name {}".format(model_group)) + raise ParseError(f"model name {model_group}") if not match_application(application_group): - raise ParseError("application name {}".format(application_group)) + raise ParseError(f"application name {application_group}") model = model_group application = application_group endpoints = endpoints_group.split(",") if len(endpoints) == 0 or len(endpoints_group) == 0: - raise ParseError("specify endpoints for {}".format(application)) + raise ParseError(f"specify endpoints for {application}") return OfferEndpoints( application, endpoints, model=model, qualified_model_name=qualified_model_name @@ -114,10 +114,10 @@ def string(self): if self.model != "": parts.append(self.model) path = "/".join(parts) - path = "{}.{}".format(path, self.application) + path = f"{path}.{self.application}" if self.has_empty_source(): return path - return "{}:{}".format(self.source, path) + return f"{self.source}:{path}" def parse_offer_url(url): @@ -127,9 +127,7 @@ def parse_offer_url(url): valid = valid and match_model_application(rest) if not valid: raise ParseError( - "application offer URL has invalid form, must be [.: {}".format( - url - ) + f"application offer URL has invalid form, must be [.: {url}" ) offer_source = source @@ -141,9 +139,7 @@ def parse_offer_url(url): if valid and (("/" in offer_model) or ("/" in offer_application)): raise ParseError( - "application offer URL has invalid form, must be [.: {}".format( - url - ) + f"application offer URL has invalid form, must be [.: {url}" ) if not offer_model: raise ParseError("application offer URL is missing model") @@ -151,13 +147,13 @@ def parse_offer_url(url): raise ParseError("application offer URL is missing application") if offer_user and not match_user(offer_user): - raise ParseError("user name {} not valid".format(offer_user)) + raise ParseError(f"user name {offer_user} not valid") if offer_model and not match_model(offer_model): - raise ParseError("model name {} not valid".format(offer_model)) + raise ParseError(f"model name {offer_model} not valid") app_name = offer_application.split(":")[0] if app_name and not match_application(app_name): - raise ParseError("application name {} not valid".format(app_name)) + raise ParseError(f"application name {app_name} not valid") return OfferURL( source=offer_source, @@ -201,20 +197,20 @@ def parse_local_endpoint(url): if ":" in url: if url[0] == ":" or url[-1] == ":": - raise ParseError("endpoint {} not valid".format(url)) + raise ParseError(f"endpoint {url} not valid") parts = url.split(":") if len(parts) != 2: - raise ParseError("endpoint {} not valid".format(url)) + raise ParseError(f"endpoint {url} not valid") application_name = parts[0] if not match_relation(parts[1]): - raise ParseError("endpoint {} not valid".format(url)) + raise ParseError(f"endpoint {url} not valid") relation = parts[1] if not match_application(application_name): - raise ParseError("endpoint {} not valid".format(application_name)) + raise ParseError(f"endpoint {application_name} not valid") return LocalEndpoint(application=application_name, relation=relation) diff --git a/juju/origin.py b/juju/origin.py index 8561a432d..31c97fa90 100644 --- a/juju/origin.py +++ b/juju/origin.py @@ -2,9 +2,9 @@ # Licensed under the Apache V2, see LICENCE file for details. from enum import Enum -from .errors import JujuError from . import utils +from .errors import JujuError class Source(Enum): @@ -27,9 +27,7 @@ def __init__(self, source, channel, platform): self.platform = platform def __str__(self): - return "origin using source {} for channel {} and platform {}".format( - str(self.source), self.channel, self.platform - ) + return f"origin using source {self.source!s} for channel {self.channel} and platform {self.platform}" class Risk(Enum): @@ -67,14 +65,14 @@ class Channel: def __init__(self, track=None, risk=None): if not Risk.valid(risk): - raise JujuError("unexpected risk {}".format(risk)) + raise JujuError(f"unexpected risk {risk}") self.track = track or "" self.risk = risk @staticmethod def parse(s: str): - """parse a channel from a given string. + """Parse a channel from a given string. Parse does not take into account branches. """ @@ -95,14 +93,12 @@ def parse(s: str): track = p[0] risk = p[1] else: - raise JujuError( - "channel is malformed and has too many components {}".format(s) - ) + raise JujuError(f"channel is malformed and has too many components {s}") if risk is not None and not Risk.valid(risk): - raise JujuError("risk in channel {} is not valid".format(s)) + raise JujuError(f"risk in channel {s} is not valid") if track is not None and track == "": - raise JujuError("track in channel {} is not valid".format(s)) + raise JujuError(f"track in channel {s} is not valid") return Channel(track, risk) @@ -119,7 +115,7 @@ def __eq__(self, other): def __str__(self): path = self.risk if self.track != "": - path = "{}/{}".format(self.track, path) + path = f"{self.track}/{path}" return path def compute_base_channel(self, series): @@ -146,7 +142,6 @@ class Platform: To indicate something is missing `unknown` can be used in place. Examples: - 1. `//` 2. `` 3. `/` @@ -179,16 +174,14 @@ def parse(s): os = p[1] series = p[2] else: - raise JujuError( - "platform is malformed and has too many components {}".format(s) - ) + raise JujuError(f"platform is malformed and has too many components {s}") if not arch: - raise JujuError("architecture in platform {} is not valid".format(s)) + raise JujuError(f"architecture in platform {s} is not valid") if os is not None and os == "": - raise JujuError("os in platform {} is not valid".format(s)) + raise JujuError(f"os in platform {s} is not valid") if series is not None and series == "": - raise JujuError("series in platform {} is not valid".format(s)) + raise JujuError(f"series in platform {s} is not valid") return Platform(arch, series, os) @@ -213,7 +206,7 @@ def __eq__(self, other): def __str__(self): path = self.arch if self.os is not None and self.os != "": - path = "{}/{}".format(path, self.os) + path = f"{path}/{self.os}" if self.series is not None and self.series != "": - path = "{}/{}".format(path, self.series) + path = f"{path}/{self.series}" return path diff --git a/juju/placement.py b/juju/placement.py index 323c70d24..3dbc99a3f 100644 --- a/juju/placement.py +++ b/juju/placement.py @@ -15,8 +15,7 @@ def parse(directive): - """ - Given a string in the format `scope:directive`, or simply `scope` + """Given a string in the format `scope:directive`, or simply `scope` or `directive`, return a Placement object suitable for passing back over the websocket API. diff --git a/juju/provisioner.py b/juju/provisioner.py index ba914878c..36b8f7c18 100644 --- a/juju/provisioner.py +++ b/juju/provisioner.py @@ -81,7 +81,6 @@ def _get_ssh_client(self, host, user, key): :raises: :class:`paramiko.ssh_exception.SSHException` if the connection failed """ - ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) @@ -89,7 +88,7 @@ def _get_ssh_client(self, host, user, key): # Read the private key into a paramiko.RSAKey if os.path.exists(key): - with open(key, "r") as f: + with open(key) as f: pkey = paramiko.RSAKey.from_private_key(f) ####################################################################### @@ -108,7 +107,7 @@ def _get_ssh_client(self, host, user, key): try: ssh.connect(host, port=22, username=user, pkey=pkey) except paramiko.ssh_exception.SSHException as e: - if "Error reading SSH protocol banner" == str(e): + if str(e) == "Error reading SSH protocol banner": # Once more, with feeling ssh.connect(host, port=22, username=user, pkey=pkey) else: @@ -128,7 +127,6 @@ def _run_command(self, ssh, cmd, pty=True): :return: tuple: The stdout and stderr of the command execution :raises: :class:`CalledProcessError` if the command fails """ - if isinstance(cmd, str): cmd = shlex.split(cmd) @@ -154,7 +152,6 @@ def _init_ubuntu_user(self): :raises: :class:`paramiko.ssh_exception.AuthenticationException` if the authentication fails """ - ssh = None try: # Run w/o allocating a pty, so we fail if sudo prompts for a passwd @@ -172,14 +169,12 @@ def _init_ubuntu_user(self): # Infer the public key public_key = None - public_key_path = "{}.pub".format(self.private_key_path) + public_key_path = f"{self.private_key_path}.pub" if not os.path.exists(public_key_path): - raise FileNotFoundError( - "Public key '{}' doesn't exist.".format(public_key_path) - ) + raise FileNotFoundError(f"Public key '{public_key_path}' doesn't exist.") - with open(public_key_path, "r") as f: + with open(public_key_path) as f: public_key = f.readline() script = INITIALIZE_UBUNTU_SCRIPT.format(public_key) @@ -207,7 +202,6 @@ def _detect_hardware_and_os(self, ssh): :param object ssh: The SSHClient :return: str: A raw string containing OS and hardware information. """ - info = { "series": "", "arch": "", @@ -241,7 +235,7 @@ def _detect_hardware_and_os(self, ssh): elif line.find("cpu cores") == 0: cores = line.split(":")[1].strip() - if physical_id not in recorded.keys(): + if physical_id not in recorded: info["cpu-cores"] += cores recorded[physical_id] = True @@ -262,7 +256,7 @@ def provision_machine(self): hw = self._detect_hardware_and_os(ssh) params.series = hw["series"] - params.instance_id = "manual:{}".format(self.host) + params.instance_id = f"manual:{self.host}" params.nonce = "manual:{}:{}".format( self.host, str(uuid.uuid4()), # a nop for Juju w/manual machines @@ -288,14 +282,12 @@ def provision_machine(self): return params async def install_agent(self, connection, nonce, machine_id): - """ - :param object connection: Connection to Juju API + """:param object connection: Connection to Juju API :param str nonce: The nonce machine specification :param str machine_id: The id assigned to the machine :return: bool: If the initialization was successful """ - # The path where the Juju agent should be installed. data_dir = "/var/lib/juju" @@ -325,7 +317,6 @@ def _run_configure_script(self, script): :raises: :class:`paramiko.ssh_exception.AuthenticationException` if the upload fails """ - _, tmpFile = tempfile.mkstemp() with open(tmpFile, "w") as f: f.write(script) @@ -348,7 +339,7 @@ def _run_configure_script(self, script): # run the provisioning script stdout, stderr = self._run_command( ssh, - "sudo /bin/bash {}".format(tmpFile), + f"sudo /bin/bash {tmpFile}", ) except paramiko.ssh_exception.AuthenticationException as e: diff --git a/juju/relation.py b/juju/relation.py index 8ef6468d6..93e80f819 100644 --- a/juju/relation.py +++ b/juju/relation.py @@ -52,7 +52,7 @@ def scope(self): class Relation(model.ModelEntity): def __repr__(self): - return "".format(self.entity_id, self.key) + return f"" @property def endpoints(self): @@ -60,9 +60,7 @@ def endpoints(self): @property def provides(self): - """ - The endpoint on the provides side of this relation, or None. - """ + """The endpoint on the provides side of this relation, or None.""" for endpoint in self.endpoints: if endpoint.role == "provider": return endpoint @@ -70,9 +68,7 @@ def provides(self): @property def requires(self): - """ - The endpoint on the requires side of this relation, or None. - """ + """The endpoint on the requires side of this relation, or None.""" for endpoint in self.endpoints: if endpoint.role == "requirer": return endpoint @@ -80,9 +76,7 @@ def requires(self): @property def peers(self): - """ - The peers endpoint of this relation, or None. - """ + """The peers endpoint of this relation, or None.""" for endpoint in self.endpoints: if endpoint.role == "peer": return endpoint @@ -97,8 +91,7 @@ def is_peer(self): return any(ep.role == "peer" for ep in self.endpoints) def matches(self, *specs): - """ - Check if this relation matches relationship specs. + """Check if this relation matches relationship specs. Relation specs are strings that would be given to Juju to establish a relation, and should be in the form ``[:]`` @@ -150,7 +143,5 @@ def model_application_exists(app_name): @property def applications(self): - """ - All applications involved in this relation. - """ + """All applications involved in this relation.""" return [ep.application for ep in self.endpoints] diff --git a/juju/secrets.py b/juju/secrets.py index b4d31ada9..37a94c6a3 100644 --- a/juju/secrets.py +++ b/juju/secrets.py @@ -1,15 +1,15 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -This module contains utility logic for secrets such as reading secret data from yaml and creating data bag for secrets. -""" +"""This module contains utility logic for secrets such as reading secret data from yaml and creating data bag for secrets.""" import base64 import json import re -import yaml from pathlib import Path + +import yaml + from . import errors file_suffix = "#file" @@ -79,7 +79,7 @@ def read_secret_data(file): raise try: - with open(path, "r", encoding="utf-8") as file: + with open(path, encoding="utf-8") as file: data = file.read() except Exception: raise @@ -104,7 +104,6 @@ def encode_values_base64(data): If a key has the #base64 suffix, then the value is already base64 encoded,otherwise the value is base64 encoded as it is added to the data bag. """ - out = {} content_size = 0 for k, v in data.items(): diff --git a/juju/status.py b/juju/status.py index f6ac08823..a27c1b2ac 100644 --- a/juju/status.py +++ b/juju/status.py @@ -89,7 +89,7 @@ def _print_status_model(result_status): cloud = m.cloud_tag.split("-")[1] timestamp = result_status.controller_timestamp if m.available_version is not None and m.available_version != "": - available_version = "upgrade available: {}".format(m.available_version) + available_version = f"upgrade available: {m.available_version}" else: available_version = "" result_str += "{:<25} {:<25} {:<15} {:<15} {:<30} {:<30}".format( @@ -101,7 +101,8 @@ def _print_status_model(result_status): def _print_status_apps(result_status): """Auxiliary function to print the apps received - in a status result""" + in a status result + """ apps = result_status.applications if apps is None or len(apps) == 0: return "" @@ -129,8 +130,8 @@ def _print_status_apps(result_status): def _print_status_units(result_status): """Auxiliary function to print the units received - in a status result""" - + in a status result + """ apps = result_status.applications if apps is None or len(apps) == 0: return diff --git a/juju/tag.py b/juju/tag.py index 70a78d166..957710288 100644 --- a/juju/tag.py +++ b/juju/tag.py @@ -8,7 +8,7 @@ def _prefix(prefix, s): if s and not s.startswith(prefix): - return "{}{}".format(prefix, s) + return f"{prefix}{s}" return s @@ -27,7 +27,7 @@ def controller(controller_uuid): def credential(cloud, user, credential_name): - credential_string = "{}_{}_{}".format(cloud, user, credential_name) + credential_string = f"{cloud}_{user}_{credential_name}" return _prefix("cloudcred-", credential_string) diff --git a/juju/unit.py b/juju/unit.py index b5098e878..aff97e433 100644 --- a/juju/unit.py +++ b/juju/unit.py @@ -170,7 +170,7 @@ async def add_storage(self, storage_name, pool=None, count=1, size=1024): ) result = res.results[0] if result.error is not None: - raise JujuError("{}".format(result.error)) + raise JujuError(f"{result.error}") storage_details = result.result return storage_details.storage_tags @@ -181,9 +181,7 @@ async def attach_storage(self, storage_ids=[]): :return: """ if not storage_ids: - raise JujuError( - "Expected a storage ID to be attached to unit {}".format(self.name) - ) + raise JujuError(f"Expected a storage ID to be attached to unit {self.name}") storage_facade = client.StorageFacade.from_connection(self.connection) return await storage_facade.Attach( @@ -269,7 +267,7 @@ async def run(self, command, timeout=None, block=False): error = action_result.error if error: - raise JujuError("Action error - {} : {}".format(error.code, error.message)) + raise JujuError(f"Action error - {error.code} : {error.message}") action = await self.model._wait_for_new("action", action_id) if block: @@ -362,8 +360,7 @@ async def ssh(self, command, user="ubuntu", proxy=False, ssh_opts=None): return await self.machine.ssh(command, user, proxy, ssh_opts) async def is_leader_from_status(self): - """ - Check to see if this unit is the leader. Returns True if so, and + """Check to see if this unit is the leader. Returns True if so, and False if it is not, or if leadership does not make sense (e.g., there is no leader in this application.) diff --git a/juju/url.py b/juju/url.py index 5048f1af7..1f915bff0 100644 --- a/juju/url.py +++ b/juju/url.py @@ -2,9 +2,10 @@ # Licensed under the Apache V2, see LICENCE file for details. from enum import Enum -from .errors import JujuError from urllib.parse import urlparse +from .errors import JujuError + class Schema(Enum): LOCAL = "local" @@ -41,7 +42,7 @@ def __init__( @staticmethod def parse(s, default_store=Schema.CHARM_HUB): - """parse parses the provided charm URL string into its respective + """Parse parses the provided charm URL string into its respective structure. A missing schema is assumed to be 'ch'. @@ -49,7 +50,7 @@ def parse(s, default_store=Schema.CHARM_HUB): """ u = urlparse(s) if u.query != "" or u.fragment != "" or u.username or u.password: - raise JujuError("charm or bundle URL {} has unrecognized parts".format(u)) + raise JujuError(f"charm or bundle URL {u} has unrecognized parts") if Schema.CHARM_STORE.matches(u.scheme) or ( u.scheme == "" and Schema.CHARM_STORE.matches(default_store) @@ -59,7 +60,7 @@ def parse(s, default_store=Schema.CHARM_HUB): c = parse_v2_url(u, s, default_store) if not c or not c.schema: - raise JujuError("expected schema for charm or bundle URL {}".format(u)) + raise JujuError(f"expected schema for charm or bundle URL {u}") return c def with_revision(self, rev): @@ -75,13 +76,13 @@ def with_series(self, series): def path(self): parts = [] if self.user is not None: - parts.append("~{}".format(self.user)) + parts.append(f"~{self.user}") if self.architecture is not None: parts.append(self.architecture) if self.series is not None: parts.append(self.series) if self.revision is not None and self.revision >= 0: - parts.append("{}-{}".format(self.name, self.revision)) + parts.append(f"{self.name}-{self.revision}") else: parts.append(self.name) return "/".join(parts) @@ -99,7 +100,7 @@ def __eq__(self, other): return False def __str__(self): - return "{}:{}".format(str(self.schema), self.path()) + return f"{self.schema!s}:{self.path()}" def parse_v1_url(schema, u, s): @@ -107,17 +108,17 @@ def parse_v1_url(schema, u, s): parts = u.path.split("/") if len(parts) < 1 or len(parts) > 4: - raise JujuError("charm or bundle URL has invalid form {}".format(s)) + raise JujuError(f"charm or bundle URL has invalid form {s}") # ~ if parts[0].startswith("~"): if schema == Schema.LOCAL: - raise JujuError("local charm or bundle URL with username {}".format(s)) + raise JujuError(f"local charm or bundle URL with username {s}") c.user = parts[0][1:] parts = parts[1:] if len(parts) > 2: - raise JujuError("charm or bundle URL has invalid form {}".format(s)) + raise JujuError(f"charm or bundle URL has invalid form {s}") # if len(parts) == 2: @@ -126,7 +127,7 @@ def parse_v1_url(schema, u, s): # TODO (stickupkid) - validate the series. if len(parts) < 1: - raise JujuError("URL without charm or bundle name {}".format(s)) + raise JujuError(f"URL without charm or bundle name {s}") (c.name, c.revision) = extract_revision(parts[0]) # TODO (stickupkid) - validate the name. @@ -142,12 +143,12 @@ def parse_v2_url(u, s, default_store): elif Schema.LOCAL.matches(u.scheme): c = URL(Schema.LOCAL) else: - raise JujuError("invalid charm url schema {}".format(u.scheme)) + raise JujuError(f"invalid charm url schema {u.scheme}") parts = u.path.split("/") num = len(parts) if num == 0 or num > 3: - raise JujuError("charm or bundle URL {} malformed".format(s)) + raise JujuError(f"charm or bundle URL {s} malformed") name = "" if num == 3: diff --git a/juju/user.py b/juju/user.py index 06946dfbd..7ff0fcc32 100644 --- a/juju/user.py +++ b/juju/user.py @@ -5,13 +5,13 @@ import pyrfc3339 -from . import tag, errors +from . import errors, tag from .client import client log = logging.getLogger(__name__) -class User(object): +class User: def __init__(self, controller, user_info, secret_key=None): self.controller = controller self._user_info = user_info diff --git a/juju/utils.py b/juju/utils.py index 07e4687b3..52a4a8401 100644 --- a/juju/utils.py +++ b/juju/utils.py @@ -1,27 +1,25 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. +import base64 import os import textwrap +import zipfile from collections import defaultdict from functools import partial from pathlib import Path -import base64 -from pyasn1.type import univ, char -from pyasn1.codec.der.encoder import encode + import yaml -import zipfile +from pyasn1.codec.der.encoder import encode +from pyasn1.type import char, univ -from . import jasyncio, origin, errors +from . import errors, jasyncio, origin from .client import client from .errors import JujuError async def execute_process(*cmd, log=None): - """ - Wrapper around asyncio.create_subprocess_exec. - - """ + """Wrapper around asyncio.create_subprocess_exec.""" p = await jasyncio.create_subprocess_exec( *cmd, stdin=jasyncio.subprocess.PIPE, @@ -74,8 +72,7 @@ def juju_ssh_key_paths(): def _read_ssh_key(): - """ - Inner function for read_ssh_key, suitable for passing to our + """Inner function for read_ssh_key, suitable for passing to our Executor. """ @@ -87,8 +84,7 @@ def _read_ssh_key(): async def read_ssh_key(): - """ - Attempt to read the local juju admin's public ssh key, so that it + """Attempt to read the local juju admin's public ssh key, so that it can be passed on to a model. """ @@ -97,9 +93,7 @@ async def read_ssh_key(): class IdQueue: - """ - Wrapper around asyncio.Queue that maintains a separate queue for each ID. - """ + """Wrapper around asyncio.Queue that maintains a separate queue for each ID.""" def __init__(self, maxsize=0): self._queues = defaultdict(partial(jasyncio.Queue, maxsize)) @@ -169,8 +163,7 @@ async def wait_for_bundle(model, bundle, **kwargs): async def run_with_interrupt(task, *events, log=None): - """ - Awaits a task while allowing it to be interrupted by one or more + """Awaits a task while allowing it to be interrupted by one or more `asyncio.Event`s. If the task finishes without the events becoming set, the results of the @@ -206,8 +199,7 @@ class Addrs(univ.SequenceOf): class RegistrationInfo(univ.Sequence): - """ - ASN.1 representation of: + """ASN.1 representation of: type RegistrationInfo struct { User string @@ -234,7 +226,6 @@ def generate_user_controller_access_token( :param secret_key: base64 encoded string of the secret-key generated by juju :param controller_name: name of the controller to register to. """ - # Secret key is returned as base64 encoded string in: # https://websockets.readthedocs.io/en/stable/_modules/websockets/protocol.html#WebSocketCommonProtocol.recv # Decoding it before marshalling into the ASN.1 message @@ -381,7 +372,6 @@ def get_local_charm_base(series, charm_path, base_class): :param class base_class: :return: Instance of the baseCls with channel/osname information """ - channel_for_base = "" os_name_for_base = "" @@ -509,8 +499,7 @@ def user_requested(series_arg, supported_series, force): def series_selector( series_arg="", charm_url=None, model_config=None, supported_series=[], force=False ): - """ - series_selector corresponds to the CharmSeries() in + """series_selector corresponds to the CharmSeries() in https://github.com/juju/juju/blob/develop/core/charm/series_selector.go determines what series to use with a charm. @@ -521,7 +510,6 @@ def series_selector( - default from charm metadata supported series / series in url - default LTS """ - # User has requested a series with --series. if series_arg: return user_requested(series_arg, supported_series, force) @@ -566,7 +554,6 @@ def should_upgrade_resource(available_resource, existing_resources, arg_resource :result bool: The decision to refresh the given resource """ - # should upgrade resource? res_name = available_resource.get("Name", available_resource.get("name")) diff --git a/setup.py b/setup.py index b982170c7..705f2bca8 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ here = Path(__file__).absolute().parent readme = here / "docs" / "readme.rst" changelog = here / "docs" / "changelog.rst" -long_description = "{}\n\n{}".format(readme.read_text(), changelog.read_text()) +long_description = f"{readme.read_text()}\n\n{changelog.read_text()}" long_description_content_type = "text/x-rst" setup( @@ -41,13 +41,17 @@ url="https://github.com/juju/python-libjuju", license="Apache 2", classifiers=[ - "Development Status :: 3 - Alpha", + "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ], entry_points={ "console_scripts": [], diff --git a/tests/base.py b/tests/base.py index 0d5dac8ac..b2ef9f175 100644 --- a/tests/base.py +++ b/tests/base.py @@ -8,6 +8,7 @@ from pathlib import Path import pytest + from juju.client.jujudata import FileJujuData from juju.controller import Controller @@ -28,8 +29,7 @@ def is_bootstrapped(): class CleanController: - """ - Context manager that automatically connects and disconnects from + """Context manager that automatically connects and disconnects from the currently active controller. Note: Unlike CleanModel, this will not create a new controller for you, @@ -49,8 +49,7 @@ async def __aexit__(self, exc_type, exc, tb): class CleanModel: - """ - Context manager that automatically connects to the currently active + """Context manager that automatically connects to the currently active controller, adds a fresh model, returns the connection to that model, and automatically disconnects and cleans up the model. @@ -77,11 +76,7 @@ async def __aenter__(self): user_name = jujudata.accounts()[controller_name]["user"] await self._controller.connect(controller_name) - model_name = "test-{}-{}-{}".format( - test_run_nonce, - test_name, - model_nonce, - ) + model_name = f"test-{test_run_nonce}-{test_name}-{model_nonce}" self._model = await self._controller.add_model(model_name) # Change the JujuData instance so that it will return the new @@ -133,8 +128,7 @@ def models(self): @contextmanager def patch_file(filename): - """ - "Patch" a file so that its current contents are automatically restored + """ "Patch" a file so that its current contents are automatically restored when the context is exited. """ filepath = Path(filename).expanduser() diff --git a/tests/integration/test_application.py b/tests/integration/test_application.py index 889a3de87..5090c9768 100644 --- a/tests/integration/test_application.py +++ b/tests/integration/test_application.py @@ -1,9 +1,9 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. +import asyncio import logging from pathlib import Path -import asyncio import pytest @@ -390,7 +390,7 @@ async def test_app_charm_name(): app = await model.deploy("ubuntu") await model.wait_for_idle(status="active") assert "ubuntu" in app.charm_url - assert "ubuntu" == app.charm_name + assert app.charm_name == "ubuntu" @base.bootstrapped diff --git a/tests/integration/test_charmhub.py b/tests/integration/test_charmhub.py index 4cf17708f..b09dda053 100644 --- a/tests/integration/test_charmhub.py +++ b/tests/integration/test_charmhub.py @@ -3,9 +3,10 @@ import pytest -from .. import base -from juju.errors import JujuError from juju import jasyncio +from juju.errors import JujuError + +from .. import base @base.bootstrapped diff --git a/tests/integration/test_connection.py b/tests/integration/test_connection.py index 8d4592059..a47f96d0c 100644 --- a/tests/integration/test_connection.py +++ b/tests/integration/test_connection.py @@ -8,19 +8,18 @@ from contextlib import closing from pathlib import Path +import pytest +import websockets + +from juju import jasyncio from juju.client import client from juju.client.connection import Connection from juju.client.jujudata import FileJujuData from juju.controller import Controller from juju.utils import run_with_interrupt -from juju import jasyncio - -import pytest -import websockets from .. import base - logger = logging.getLogger(__name__) @@ -110,14 +109,14 @@ async def test_redirect(): server = RedirectServer(destination) try: for status in redirect_statuses: - logger.debug("test: starting {}".format(status)) + logger.debug(f"test: starting {status}") server.start(status) await run_with_interrupt(server.running.wait(), server.terminated) if server.exception: raise server.exception assert not server.terminated.is_set() logger.debug("test: started") - kwargs_copy = dict(kwargs, endpoint="localhost:{}".format(server.port)) + kwargs_copy = dict(kwargs, endpoint=f"localhost:{server.port}") logger.debug("test: connecting") conn = await Connection.connect(**kwargs_copy) logger.debug("test: connected") @@ -185,7 +184,7 @@ async def redirect(path, request_headers): if self._terminate.is_set(): break self._start.clear() - logger.debug("server: starting {}".format(self.status)) + logger.debug(f"server: starting {self.status}") try: async with websockets.serve( ws_handler=hello, diff --git a/tests/integration/test_controller.py b/tests/integration/test_controller.py index 054bb6bd7..de09189ad 100644 --- a/tests/integration/test_controller.py +++ b/tests/integration/test_controller.py @@ -3,22 +3,22 @@ import asyncio import uuid + import hvac +import pytest from juju import access, controller -from juju.client.connection import Connection from juju.client import client +from juju.client.connection import Connection from juju.errors import JujuAPIError, JujuError -import pytest - from .. import base @base.bootstrapped async def test_add_remove_user(): async with base.CleanController() as controller: - username = "test{}".format(uuid.uuid4()) + username = f"test{uuid.uuid4()}" user = await controller.get_user(username) assert user is None user = await controller.add_user(username) @@ -37,7 +37,7 @@ async def test_add_remove_user(): @base.bootstrapped async def test_disable_enable_user(): async with base.CleanController() as controller: - username = "test-disable{}".format(uuid.uuid4()) + username = f"test-disable{uuid.uuid4()}" user = await controller.add_user(username) await user.disable() @@ -60,7 +60,7 @@ async def test_disable_enable_user(): @base.bootstrapped async def test_change_user_password(): async with base.CleanController() as controller: - username = "test-password{}".format(uuid.uuid4()) + username = f"test-password{uuid.uuid4()}" user = await controller.add_user(username) await user.set_password("password") # Check that we can connect with the new password. @@ -80,7 +80,7 @@ async def test_change_user_password(): @base.bootstrapped async def test_reset_user_password(): async with base.CleanController() as controller: - username = "test{}".format(uuid.uuid4()) + username = f"test{uuid.uuid4()}" user = await controller.add_user(username) origin_secret_key = user.secret_key await user.set_password("password") @@ -117,7 +117,7 @@ async def test_list_models(): async def test_get_model(): async with base.CleanController() as controller: by_name, by_uuid = None, None - model_name = "test-{}".format(uuid.uuid4()) + model_name = f"test-{uuid.uuid4()}" model = await controller.add_model(model_name) model_uuid = model.info.uuid await model.disconnect() @@ -149,7 +149,7 @@ async def _wait_for_model_gone(controller, model_name): @base.bootstrapped async def test_destroy_model_by_name(): async with base.CleanController() as controller: - model_name = "test-{}".format(uuid.uuid4()) + model_name = f"test-{uuid.uuid4()}" model = await controller.add_model(model_name) await model.disconnect() await asyncio.wait_for(_wait_for_model(controller, model_name), timeout=60) @@ -162,7 +162,7 @@ async def test_destroy_model_by_name(): @base.bootstrapped async def test_add_destroy_model_by_uuid(): async with base.CleanController() as controller: - model_name = "test-{}".format(uuid.uuid4()) + model_name = f"test-{uuid.uuid4()}" model = await controller.add_model(model_name) model_uuid = model.info.uuid await model.disconnect() @@ -174,7 +174,7 @@ async def test_add_destroy_model_by_uuid(): @base.bootstrapped async def test_add_remove_cloud(): async with base.CleanController() as controller: - cloud_name = "test-{}".format(uuid.uuid4()) + cloud_name = f"test-{uuid.uuid4()}" cloud = client.Cloud( auth_types=["userpass"], endpoint="http://localhost:1234", @@ -194,7 +194,8 @@ async def test_secrets_backend_lifecycle(): """Testing the add_secret_backends is particularly costly in term of resources. This test sets a vault charm, add it to the controller and plays with the - list, removal, and update.""" + list, removal, and update. + """ async with base.CleanModel() as m: controller = await m.get_controller() # deploy postgresql @@ -280,7 +281,7 @@ async def test_secrets_backend_lifecycle(): @base.bootstrapped async def test_grant_revoke_controller_access(): async with base.CleanController() as controller: - username = "test-grant{}".format(uuid.uuid4()) + username = f"test-grant{uuid.uuid4()}" user = await controller.add_user(username) await user.grant("superuser") assert user.access == "superuser" @@ -324,10 +325,10 @@ async def test_connection_lazy_jujudata(): @base.bootstrapped async def test_grant_revoke_model_access(): async with base.CleanController() as controller: - username = "test-grant{}".format(uuid.uuid4()) + username = f"test-grant{uuid.uuid4()}" user = await controller.add_user(username) - model_name = "test-{}".format(uuid.uuid4()) + model_name = f"test-{uuid.uuid4()}" model = await controller.add_model(model_name) with pytest.raises(JujuError): diff --git a/tests/integration/test_crossmodel.py b/tests/integration/test_crossmodel.py index 894e07796..6d2eef437 100644 --- a/tests/integration/test_crossmodel.py +++ b/tests/integration/test_crossmodel.py @@ -6,9 +6,10 @@ import pytest -from .. import base from juju import jasyncio +from .. import base + @base.bootstrapped @pytest.mark.skip("Update charm") @@ -28,7 +29,7 @@ async def test_offer(): await model.block_until( lambda: all(offer.application_name == "ubuntu" for offer in offers.results) ) - await model.remove_offer("admin/{}.ubuntu".format(model.name), force=True) + await model.remove_offer(f"admin/{model.name}.ubuntu", force=True) @base.bootstrapped @@ -52,13 +53,13 @@ async def test_consume(): # farm off a new model to test the consumption async with base.CleanModel() as model_2: - await model_2.consume("admin/{}.ubuntu".format(model_1.name)) + await model_2.consume(f"admin/{model_1.name}.ubuntu") status = await model_2.get_status() if "ubuntu" not in status.remote_applications: raise Exception("Expected ubuntu in saas") - await model_1.remove_offer("admin/{}.ubuntu".format(model_1.name), force=True) + await model_1.remove_offer(f"admin/{model_1.name}.ubuntu", force=True) @base.bootstrapped @@ -82,7 +83,7 @@ async def test_remove_saas(): # farm off a new model to test the consumption async with base.CleanModel() as model_2: - await model_2.consume("admin/{}.ubuntu".format(model_1.name)) + await model_2.consume(f"admin/{model_1.name}.ubuntu") await model_2.remove_saas("ubuntu") await jasyncio.sleep(5) @@ -91,7 +92,7 @@ async def test_remove_saas(): if "ubuntu" in status.remote_applications: raise Exception("Expected ubuntu not to be in saas") - await model_1.remove_offer("admin/{}.ubuntu".format(model_1.name), force=True) + await model_1.remove_offer(f"admin/{model_1.name}.ubuntu", force=True) @base.bootstrapped @@ -130,9 +131,7 @@ async def test_relate_with_offer(): lambda: all(unit.agent_status == "idle" for unit in application.units) ) - await model_2.relate( - "hello-juju:db", "admin/{}.postgresql".format(model_1.name) - ) + await model_2.relate("hello-juju:db", f"admin/{model_1.name}.postgresql") status = await model_2.get_status() if "postgresql" not in status.remote_applications: raise Exception("Expected postgresql in saas") @@ -144,9 +143,7 @@ async def test_relate_with_offer(): if "postgresql" in status.remote_applications: raise Exception("Expected mysql not to be in saas") - await model_1.remove_offer( - "admin/{}.postgresql".format(model_1.name), force=True - ) + await model_1.remove_offer(f"admin/{model_1.name}.postgresql", force=True) @base.bootstrapped @@ -159,9 +156,9 @@ async def test_add_bundle(): file_contents = None try: - with open(cmr_bundle_path, "r") as file: + with open(cmr_bundle_path) as file: file_contents = file.read() - except IOError: + except OSError: raise async with base.CleanModel() as model_1: @@ -173,7 +170,7 @@ async def test_add_bundle(): tmp_path = str(Path(dirpath) / "bundle.yaml") with open(tmp_path, "w") as file: file.write(file_contents.format(model_1.name)) - except IOError: + except OSError: raise await model_1.deploy( @@ -197,9 +194,7 @@ async def test_add_bundle(): # farm off a new model to test the consumption async with base.CleanModel() as model_2: - await model_2.deploy("local:{}".format(tmp_path)) + await model_2.deploy(f"local:{tmp_path}") await model_2.wait_for_idle(status="active") - await model_1.remove_offer( - "admin/{}.influxdb".format(model_1.name), force=True - ) + await model_1.remove_offer(f"admin/{model_1.name}.influxdb", force=True) diff --git a/tests/integration/test_errors.py b/tests/integration/test_errors.py index 02df87f9b..564e248b3 100644 --- a/tests/integration/test_errors.py +++ b/tests/integration/test_errors.py @@ -11,8 +11,7 @@ @base.bootstrapped async def test_juju_api_error(): - """ - Verify that we raise a JujuAPIError for responses with an error in + """Verify that we raise a JujuAPIError for responses with an error in a top level key (for completely invalid requests). """ @@ -25,8 +24,7 @@ async def test_juju_api_error(): @base.bootstrapped async def test_juju_error_in_results_list(): - """ - Replicate the code that caused + """Replicate the code that caused https://github.com/juju/python-libjuju/issues/67, and verify that we get a JujuError instead of passing silently by the failure. @@ -37,8 +35,8 @@ async def test_juju_error_in_results_list(): is an error in one of a list of results. """ - from juju.errors import JujuError from juju.client import client + from juju.errors import JujuError async with base.CleanModel() as model: ann_facade = client.AnnotationsFacade.from_connection(model.connection()) @@ -53,13 +51,12 @@ async def test_juju_error_in_results_list(): @base.bootstrapped async def test_juju_error_in_result(): - """ - Verify that we raise a JujuError when appropriate when we are + """Verify that we raise a JujuError when appropriate when we are looking at a single result coming back. """ - from juju.errors import JujuError from juju.client import client + from juju.errors import JujuError async with base.CleanModel() as model: app_facade = client.ApplicationFacade.from_connection(model.connection()) diff --git a/tests/integration/test_juju.py b/tests/integration/test_juju.py index 8537d7417..6ee0182a5 100644 --- a/tests/integration/test_juju.py +++ b/tests/integration/test_juju.py @@ -3,6 +3,7 @@ from juju.controller import Controller from juju.juju import Juju + from .. import base diff --git a/tests/integration/test_macaroon_auth.py b/tests/integration/test_macaroon_auth.py index 280b9bcec..5f5385ad8 100644 --- a/tests/integration/test_macaroon_auth.py +++ b/tests/integration/test_macaroon_auth.py @@ -2,18 +2,18 @@ # Licensed under the Apache V2, see LICENCE file for details. import logging -import subprocess import os +import subprocess import macaroonbakery.bakery as bakery import macaroonbakery.httpbakery as httpbakery import macaroonbakery.httpbakery.agent as agent -from juju.errors import JujuAPIError -from juju.model import Model +import pytest + from juju.client.jujudata import FileJujuData from juju.controller import Controller - -import pytest +from juju.errors import JujuAPIError +from juju.model import Model from .. import base @@ -33,12 +33,10 @@ async def test_macaroon_auth_serial(): result = subprocess.run( ["juju", "change-user-password"], input="{0}\n{0}\n".format(account["password"]), - universal_newlines=True, + text=True, stderr=subprocess.PIPE, ) - assert result.returncode == 0, "Failed to change password: {}".format( - result.stderr - ) + assert result.returncode == 0, f"Failed to change password: {result.stderr}" controller = Controller() try: await controller.connect() diff --git a/tests/integration/test_machine.py b/tests/integration/test_machine.py index 7f4b8111a..fd0ab1a69 100644 --- a/tests/integration/test_machine.py +++ b/tests/integration/test_machine.py @@ -5,9 +5,10 @@ import pytest -from .. import base from juju.machine import Machine +from .. import base + @base.bootstrapped @pytest.mark.skip("Update charm") diff --git a/tests/integration/test_model.py b/tests/integration/test_model.py index 1e744972d..25c4fd920 100644 --- a/tests/integration/test_model.py +++ b/tests/integration/test_model.py @@ -7,26 +7,26 @@ import string import time import uuid +from unittest import mock -import mock import paramiko - import pylxd import pytest + from juju import jasyncio, tag, url from juju.client import client from juju.client._definitions import FullStatus -from juju.errors import JujuError, JujuModelError, JujuUnitError, JujuConnectionError +from juju.errors import JujuConnectionError, JujuError, JujuModelError, JujuUnitError from juju.model import Model, ModelObserver from juju.utils import ( + base_channel_to_series, block_until, run_with_interrupt, wait_for_bundle, - base_channel_to_series, ) from .. import base -from ..utils import MB, GB, TESTS_DIR, OVERLAYS_DIR, SSH_KEY, INTEGRATION_TEST_DIR +from ..utils import GB, INTEGRATION_TEST_DIR, MB, OVERLAYS_DIR, SSH_KEY, TESTS_DIR @base.bootstrapped @@ -389,8 +389,8 @@ async def test_deploy_bundle_with_multiple_overlays_with_include_files(): assert "memcached" not in model.applications assert "grafana" in model.applications assert "grafana" in model.application_offers - assert "grafana" == model.application_offers["grafana"].application_name - assert "dashboards" == model.application_offers["grafana"].offer_name + assert model.application_offers["grafana"].application_name == "grafana" + assert model.application_offers["grafana"].offer_name == "dashboards" @base.bootstrapped @@ -453,7 +453,7 @@ async def test_deploy_from_ch_with_series(): charm = "ch:ubuntu" for series in ["focal"]: async with base.CleanModel() as model: - app_name = "ubuntu-{}".format(series) + app_name = f"ubuntu-{series}" await model.deploy(charm, application_name=app_name, series=series) status = await model.get_status() app_status = status["applications"][app_name] @@ -517,7 +517,7 @@ async def test_add_machine(): ) # add a lxd container to machine2 - machine3 = await model.add_machine("lxd:{}".format(machine2.id)) + machine3 = await model.add_machine(f"lxd:{machine2.id}") for m in (machine1, machine2, machine3): assert isinstance(m, Machine) @@ -546,7 +546,7 @@ async def add_manual_machine_ssh(is_root=False): # connect using the local unix socket client = pylxd.Client() - test_name = "test-{}-add-manual-machine-ssh".format(uuid.uuid4().hex[-4:]) + test_name = f"test-{uuid.uuid4().hex[-4:]}-add-manual-machine-ssh" if is_root: test_user = "root" @@ -558,28 +558,28 @@ async def add_manual_machine_ssh(is_root=False): # create profile w/cloud-init and juju ssh key public_key = "" - with open(public_key_path, "r") as f: + with open(public_key_path) as f: public_key = f.readline() - cloud_init = """ + cloud_init = f""" #cloud-config users: - - name: {} + - name: {test_user} ssh_pwauth: False ssh_authorized_keys: - - {} + - {public_key} sudo: ["ALL=(ALL) NOPASSWD:ALL"] groups: adm, sudoers - """.format(test_user, public_key) + """ if is_root: - cloud_init = """ + cloud_init = f""" #cloud-config users: - - name: {} + - name: {test_user} ssh_authorized_keys: - - {} - """.format(test_user, public_key) + - {public_key} + """ profile = client.profiles.create( test_name, @@ -688,7 +688,6 @@ async def test_add_manual_machine_ssh(): @base.bootstrapped async def test_add_manual_machine_ssh_root(): """Test manual machine provisioning with the root user""" - await add_manual_machine_ssh(is_root=True) diff --git a/tests/integration/test_secrets.py b/tests/integration/test_secrets.py index e989e7680..af1325e9b 100644 --- a/tests/integration/test_secrets.py +++ b/tests/integration/test_secrets.py @@ -2,6 +2,7 @@ # Licensed under the Apache V2, see LICENCE file for details. import pytest + from .. import base from ..utils import TESTS_DIR @@ -29,8 +30,8 @@ async def test_add_secret(): @base.bootstrapped async def test_list_secrets(): """Use the charm-secret charm definition and see if the - arguments defined in the secret are correct or not.""" - + arguments defined in the secret are correct or not. + """ charm_path = TESTS_DIR / "charm-secret/charm-secret_ubuntu-22.04-amd64.charm" async with base.CleanModel() as model: diff --git a/tests/integration/test_unit.py b/tests/integration/test_unit.py index a510f3315..4f7be5468 100644 --- a/tests/integration/test_unit.py +++ b/tests/integration/test_unit.py @@ -4,9 +4,10 @@ import asyncio from pathlib import Path from tempfile import NamedTemporaryFile + import pytest -from juju import utils, jasyncio +from juju import jasyncio, utils from .. import base diff --git a/tests/unit/test_application.py b/tests/unit/test_application.py index 5e8fc994d..f13bbc1e0 100644 --- a/tests/unit/test_application.py +++ b/tests/unit/test_application.py @@ -1,14 +1,14 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -import unittest -import mock import asyncio +import unittest +from unittest import mock -from juju.model import Model from juju.application import Application, ExposedEndpoint, _refresh_origin -from juju.errors import JujuError from juju.client import client +from juju.errors import JujuError +from juju.model import Model from juju.origin import Source diff --git a/tests/unit/test_bundle.py b/tests/unit/test_bundle.py index 268a0d73a..91c3181e0 100644 --- a/tests/unit/test_bundle.py +++ b/tests/unit/test_bundle.py @@ -3,12 +3,14 @@ import unittest from pathlib import Path -from unittest import mock -from mock import patch, Mock, ANY from typing import Dict, List, Tuple +from unittest import mock +from unittest.mock import ANY, Mock, patch import yaml +from toposort import CircularDependencyError +from juju import charmhub, constraints from juju.bundle import ( AddApplicationChange, AddCharmChange, @@ -23,10 +25,7 @@ ScaleChange, SetAnnotationsChange, ) -from juju import charmhub -from juju import constraints from juju.client import client -from toposort import CircularDependencyError class TestChangeSet(unittest.TestCase): diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index 5f3cd5596..833faf725 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -1,12 +1,9 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -Tests for generated client code +"""Tests for generated client code""" -""" - -import mock +from unittest import mock from juju.client import client diff --git a/tests/unit/test_connection.py b/tests/unit/test_connection.py index c916960ef..c1e632933 100644 --- a/tests/unit/test_connection.py +++ b/tests/unit/test_connection.py @@ -4,13 +4,13 @@ import asyncio import json from collections import deque +from unittest import mock -import mock -from juju.errors import JujuRedirectException -from juju.client.connection import Connection +import pytest from websockets.exceptions import ConnectionClosed -import pytest +from juju.client.connection import Connection +from juju.errors import JujuRedirectException class WebsocketMock: diff --git a/tests/unit/test_controller.py b/tests/unit/test_controller.py index 1cbe9efe4..3ad6ca095 100644 --- a/tests/unit/test_controller.py +++ b/tests/unit/test_controller.py @@ -1,11 +1,10 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. +import unittest from pathlib import Path from tempfile import NamedTemporaryFile -import unittest - -import mock +from unittest import mock from juju.client import client from juju.controller import Controller diff --git a/tests/unit/test_flags.py b/tests/unit/test_flags.py index 8e9aeda45..65eb0b403 100644 --- a/tests/unit/test_flags.py +++ b/tests/unit/test_flags.py @@ -13,8 +13,8 @@ def test_default_flag(self): self.assertTrue(flags.feature_enabled(flags.DEFAULT_VALUES_FLAG)) def test_multiple_flag(self): - os.environ[flags.PYLIBJUJU_DEV_FEATURE_FLAG] = "xxx, {},foo, bar".format( - flags.DEFAULT_VALUES_FLAG + os.environ[flags.PYLIBJUJU_DEV_FEATURE_FLAG] = ( + f"xxx, {flags.DEFAULT_VALUES_FLAG},foo, bar" ) self.assertTrue(flags.feature_enabled(flags.DEFAULT_VALUES_FLAG)) diff --git a/tests/unit/test_gocookies.py b/tests/unit/test_gocookies.py index 429bab3b7..f3d5542a2 100644 --- a/tests/unit/test_gocookies.py +++ b/tests/unit/test_gocookies.py @@ -1,9 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -""" -Tests for the gocookies code. -""" +"""Tests for the gocookies code.""" import os import shutil @@ -12,6 +10,7 @@ import urllib.request import pyrfc3339 + from juju.client.gocookies import GoCookieJar # cookie_content holds the JSON contents of a Go-produced @@ -264,5 +263,5 @@ def assert_jar_queries(self, jar, queries): self.assertEqual( got_cookies, want_cookies, - msg="query {}; got {}; want {}".format(url, got_cookies, want_cookies), + msg=f"query {url}; got {got_cookies}; want {want_cookies}", ) diff --git a/tests/unit/test_jujudata.py b/tests/unit/test_jujudata.py index 5d7e7312f..fd1ec66d6 100644 --- a/tests/unit/test_jujudata.py +++ b/tests/unit/test_jujudata.py @@ -2,8 +2,8 @@ # Licensed under the Apache V2, see LICENCE file for details. import unittest +from unittest import mock -import mock import pytest from juju.client.jujudata import FileJujuData diff --git a/tests/unit/test_machine.py b/tests/unit/test_machine.py index 4da67f726..66eb97eda 100644 --- a/tests/unit/test_machine.py +++ b/tests/unit/test_machine.py @@ -1,10 +1,10 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -import mock +from unittest import mock -from juju.model import Model from juju.machine import Machine +from juju.model import Model @mock.patch("juju.client.client.ClientFacade") diff --git a/tests/unit/test_model.py b/tests/unit/test_model.py index 252872284..c365d8954 100644 --- a/tests/unit/test_model.py +++ b/tests/unit/test_model.py @@ -1,19 +1,18 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. +import datetime import unittest -from unittest.mock import patch, PropertyMock - -import mock +from unittest import mock +from unittest.mock import PropertyMock, patch import pytest -import datetime -from juju.client.jujudata import FileJujuData -from juju.model import Model -from juju.application import Application from juju import jasyncio +from juju.application import Application +from juju.client.jujudata import FileJujuData from juju.errors import JujuConnectionError, JujuError +from juju.model import Model def _make_delta(entity, type_, data=None): diff --git a/tests/unit/test_offerendpoint.py b/tests/unit/test_offerendpoint.py index 80b376bb3..ec637b3ba 100644 --- a/tests/unit/test_offerendpoint.py +++ b/tests/unit/test_offerendpoint.py @@ -6,10 +6,10 @@ # import unittest -import mock -from juju.model import Model -from juju.controller import Controller +from unittest import mock +from juju.controller import Controller +from juju.model import Model from juju.offerendpoints import ( LocalEndpoint, OfferEndpoints, @@ -145,7 +145,6 @@ async def test_external_controller_consume( better suited as an integration test however pylibjuju does not allow for bootstrapping of extra controllers. """ - mock_create_consume_args.return_value = None mock_connection.return_value = None diff --git a/tests/unit/test_proxy.py b/tests/unit/test_proxy.py index c341432fa..b5d5f3d03 100644 --- a/tests/unit/test_proxy.py +++ b/tests/unit/test_proxy.py @@ -9,8 +9,7 @@ class TestJujuDataFactory(unittest.TestCase): def test_proxy_from_config_unknown_type(self): - """ - Test that a unknown proxy type results in a UnknownProxyTypeError + """Test that a unknown proxy type results in a UnknownProxyTypeError exception """ self.assertRaises( @@ -23,9 +22,7 @@ def test_proxy_from_config_unknown_type(self): ) def test_proxy_from_config_missing_type(self): - """ - Test that a nil proxy type returns None - """ + """Test that a nil proxy type returns None""" self.assertIsNone( proxy_from_config({ "config": {}, @@ -33,15 +30,11 @@ def test_proxy_from_config_missing_type(self): ) def test_proxy_from_config_non_arg(self): - """ - Tests that providing an empty proxy config results in a None proxy - """ + """Tests that providing an empty proxy config results in a None proxy""" self.assertIsNone(proxy_from_config(None)) def test_proxy_from_config_kubernetes(self): - """ - Tests that a Kubernetes proxy is correctly created from config - """ + """Tests that a Kubernetes proxy is correctly created from config""" proxy = proxy_from_config({ "type": "kubernetes-port-forward", "config": { diff --git a/tests/unit/test_proxy_kubernetes.py b/tests/unit/test_proxy_kubernetes.py index 3798b257e..a0610e380 100644 --- a/tests/unit/test_proxy_kubernetes.py +++ b/tests/unit/test_proxy_kubernetes.py @@ -2,6 +2,7 @@ # Licensed under the Apache V2, see LICENCE file for details. import unittest + from juju.client.proxy.kubernetes.proxy import KubernetesProxy diff --git a/tests/unit/test_relation.py b/tests/unit/test_relation.py index 5014b37ac..271fbf2bf 100644 --- a/tests/unit/test_relation.py +++ b/tests/unit/test_relation.py @@ -2,8 +2,7 @@ # Licensed under the Apache V2, see LICENCE file for details. import unittest - -import mock +from unittest import mock from juju.model import Model from juju.relation import Relation diff --git a/tests/unit/test_secrets.py b/tests/unit/test_secrets.py index 1abca5483..5cb130cd3 100644 --- a/tests/unit/test_secrets.py +++ b/tests/unit/test_secrets.py @@ -2,9 +2,10 @@ # Licensed under the Apache V2, see LICENCE file for details. import os -from pathlib import Path import tempfile import unittest +from pathlib import Path + import pytest from juju.secrets import create_secret_data, read_secret_data diff --git a/tests/unit/test_status.py b/tests/unit/test_status.py index caf0bcb4e..685a0ea5b 100644 --- a/tests/unit/test_status.py +++ b/tests/unit/test_status.py @@ -2,10 +2,9 @@ # Licensed under the Apache V2, see LICENCE file for details. import unittest - +from random import sample from juju.status import derive_status -from random import sample class TestStatus(unittest.TestCase): diff --git a/tests/unit/test_unit.py b/tests/unit/test_unit.py index 4504f21f4..432b5fd1f 100644 --- a/tests/unit/test_unit.py +++ b/tests/unit/test_unit.py @@ -1,7 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -import mock +from unittest import mock from juju.client._definitions import FullStatus from juju.model import Model diff --git a/tests/unit/test_url.py b/tests/unit/test_url.py index 9c3514b77..9cacf0c45 100644 --- a/tests/unit/test_url.py +++ b/tests/unit/test_url.py @@ -3,7 +3,7 @@ import unittest -from juju.url import Schema, URL +from juju.url import URL, Schema class TestURLV1(unittest.TestCase): diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index 6459970f9..d0c5b15ce 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -2,23 +2,24 @@ # Licensed under the Apache V2, see LICENCE file for details. import unittest + import pytest +from juju import utils +from juju.client import client +from juju.errors import JujuError +from juju.url import URL from juju.utils import ( - series_selector, - get_base_from_origin_or_channel, - parse_base_arg, DEFAULT_SUPPORTED_LTS, - get_series_version, - get_version_series, - base_channel_to_series, base_channel_from_series, + base_channel_to_series, + get_base_from_origin_or_channel, get_os_from_series, + get_series_version, + get_version_series, + parse_base_arg, + series_selector, ) -from juju.errors import JujuError -from juju.url import URL -from juju import utils -from juju.client import client class TestDirResolve(unittest.TestCase): From fb8897e8832588c0395e9d922018b5beadbec5c3 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Tue, 12 Nov 2024 17:18:13 +0900 Subject: [PATCH 03/34] chore: manual fixes --- tests/unit/test_overrides.py | 24 ++++++++++++------------ tests/unit/test_registration_string.py | 2 +- tests/unit/test_secrets.py | 6 ++---- tests/validate/test_facade_versions.py | 4 ++-- 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/tests/unit/test_overrides.py b/tests/unit/test_overrides.py index 9d6e16fb8..dcdb3b924 100644 --- a/tests/unit/test_overrides.py +++ b/tests/unit/test_overrides.py @@ -9,7 +9,7 @@ # test cases ported from: # https://github.com/juju/version/blob/master/version_test.go @pytest.mark.parametrize( - "input,expected", + "value,expected", ( (None, Number(major=0, minor=0, patch=0, tag="", build=0)), (Number(major=1, minor=0, patch=0), Number(major=1, minor=0, patch=0)), @@ -37,21 +37,21 @@ ("1.21-alpha123dev3", TypeError), ), ) -def test_number(input, expected): +def test_number(value, expected): if expected is TypeError: with pytest.raises(expected): - Number.from_json(input) + Number.from_json(value) else: - result = Number.from_json(input) + result = Number.from_json(value) assert result == expected - if isinstance(input, str): - assert result.to_json() == input + if isinstance(value, str): + assert result.to_json() == value # test cases ported from: # https://github.com/juju/version/blob/master/version_test.go @pytest.mark.parametrize( - "input,expected", + "value,expected", ( (None, Binary(Number(), None, None)), (Binary(Number(1), "trusty", "amd64"), Binary(Number(1), "trusty", "amd64")), @@ -75,12 +75,12 @@ def test_number(input, expected): ("1.2.3-trusty-", TypeError), ), ) -def test_binary(input, expected): +def test_binary(value, expected): if expected is TypeError: with pytest.raises(expected): - Binary.from_json(input) + Binary.from_json(value) else: - result = Binary.from_json(input) + result = Binary.from_json(value) assert result == expected - if isinstance(input, str): - assert result.to_json() == input + if isinstance(value, str): + assert result.to_json() == value diff --git a/tests/unit/test_registration_string.py b/tests/unit/test_registration_string.py index 1713e9d61..82065d31c 100644 --- a/tests/unit/test_registration_string.py +++ b/tests/unit/test_registration_string.py @@ -21,6 +21,6 @@ def test_generate_user_controller_access_token(self): ) assert ( reg_string - == b"MH4TCnRlc3QtMDEyMzQwORMRMTkyLjE2OC4xLjE6MTcwNzATETE5Mi4xNjguMS4yOjE3MDcwExExOTIuMTY4" + == b"MH4TCnRlc3QtMDEyMzQwORMRMTkyLjE2OC4xLjE6MTcwNzATETE5Mi4xNjguMS4yOjE3MDcwExExOTIuMTY4" # noqa: E501 b"LjEuMzoxNzA3MAQgpaNZrqOw51ONk1kTER6rkm4hdPcg5VgC_dzXYxtUZaMTE2xvY2FsaG9zdC1sb2NhbGhvc3QA" ) diff --git a/tests/unit/test_secrets.py b/tests/unit/test_secrets.py index 5cb130cd3..281002dd1 100644 --- a/tests/unit/test_secrets.py +++ b/tests/unit/test_secrets.py @@ -29,10 +29,8 @@ def test_key_content_too_large(self): create_secret_data(["foo=" + ("a" * 8 * 1024)]) def test_total_content_too_large(self): - args = [] content = "a" * 4 * 1024 - for i in range(20): - args.append(f"key{i}={content}") + args = [f"key{i}={content}" for i in range(20)] with pytest.raises(ValueError): create_secret_data(args) @@ -87,7 +85,7 @@ def test_yaml_file(self): { "hello": "d29ybGQ=", "goodbye": "world", - "another-key": "YiJHSUY4OWFceDBjXHgwMFx4MGNceDAwXHg4NFx4MDBceDAwXHhmZlx4ZmZceGY3XHhmNVx4ZjVceGVlXHhlOVx4ZTlceGU1ZmZmXHgwMFx4MDBceDAwXHhlN1x4ZTdceGU3Xl5eXHhmM1x4ZjNceGVkXHg4ZVx4OGVceDhlXHhlMFx4ZTBceGUwXHg5Zlx4OWZceDlmXHg5M1x4OTNceDkzXHhhN1x4YTdceGE3XHg5ZVx4OWVceDllaWlpY2NjXHhhM1x4YTNceGEzXHg4NFx4ODRceDg0XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5IVx4ZmVceDBlTWFkZSB3aXRoIEdJTVBceDAwLFx4MDBceDAwXHgwMFx4MDBceDBjXHgwMFx4MGNceDAwXHgwMFx4MDUsICBceDhlXHg4MTBceDllXHhlM0BceDE0XHhlOGlceDEwXHhjNFx4ZDFceDhhXHgwOFx4MWNceGNmXHg4ME0kelx4ZWZceGZmMFx4ODVwXHhiOFx4YjAxZlxyXHgxYlx4Y2VceDAxXHhjM1x4MDFceDFlXHgxMCcgXHg4MlxuXHgwMVx4MDA7Ig==", + "another-key": "YiJHSUY4OWFceDBjXHgwMFx4MGNceDAwXHg4NFx4MDBceDAwXHhmZlx4ZmZceGY3XHhmNVx4ZjVceGVlXHhlOVx4ZTlceGU1ZmZmXHgwMFx4MDBceDAwXHhlN1x4ZTdceGU3Xl5eXHhmM1x4ZjNceGVkXHg4ZVx4OGVceDhlXHhlMFx4ZTBceGUwXHg5Zlx4OWZceDlmXHg5M1x4OTNceDkzXHhhN1x4YTdceGE3XHg5ZVx4OWVceDllaWlpY2NjXHhhM1x4YTNceGEzXHg4NFx4ODRceDg0XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5IVx4ZmVceDBlTWFkZSB3aXRoIEdJTVBceDAwLFx4MDBceDAwXHgwMFx4MDBceDBjXHgwMFx4MGNceDAwXHgwMFx4MDUsICBceDhlXHg4MTBceDllXHhlM0BceDE0XHhlOGlceDEwXHhjNFx4ZDFceDhhXHgwOFx4MWNceGNmXHg4ME0kelx4ZWZceGZmMFx4ODVwXHhiOFx4YjAxZlxyXHgxYlx4Y2VceDAxXHhjM1x4MDFceDFlXHgxMCcgXHg4MlxuXHgwMVx4MDA7Ig==", # noqa: E501 }, ) diff --git a/tests/validate/test_facade_versions.py b/tests/validate/test_facade_versions.py index 0ed4bb586..5638d8e6d 100644 --- a/tests/validate/test_facade_versions.py +++ b/tests/validate/test_facade_versions.py @@ -35,8 +35,8 @@ def generated_code_facades(project_root: Path) -> Dict[str, Sequence[int]]: for cls_name in dir(module): cls = getattr(module, cls_name) try: # duck typing check for facade types - cls.name - cls.version + assert cls.name + assert cls.version except AttributeError: continue if cls.version in excluded_facade_versions.get(cls.name, []): From 7006d61a60eb6daefb8a7d0e1e242a531c819b57 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Tue, 12 Nov 2024 17:19:31 +0900 Subject: [PATCH 04/34] chore: docformatter over tests --- tests/base.py | 13 ++++++------- tests/integration/test_controller.py | 9 +++++---- tests/integration/test_errors.py | 12 ++++-------- tests/integration/test_model.py | 23 +++++++++-------------- tests/integration/test_secrets.py | 5 ++--- tests/unit/test_bundle.py | 12 +++++++----- tests/unit/test_client.py | 3 +-- tests/unit/test_gocookies.py | 6 +++--- tests/unit/test_offerendpoint.py | 7 ++++--- tests/unit/test_proxy.py | 10 +++++----- tests/validate/test_facade_versions.py | 12 +++++++----- 11 files changed, 53 insertions(+), 59 deletions(-) diff --git a/tests/base.py b/tests/base.py index b2ef9f175..ea37b1453 100644 --- a/tests/base.py +++ b/tests/base.py @@ -29,8 +29,8 @@ def is_bootstrapped(): class CleanController: - """Context manager that automatically connects and disconnects from - the currently active controller. + """Context manager that automatically connects and disconnects from the + currently active controller. Note: Unlike CleanModel, this will not create a new controller for you, and an active controller must already be available. @@ -50,8 +50,8 @@ async def __aexit__(self, exc_type, exc, tb): class CleanModel: """Context manager that automatically connects to the currently active - controller, adds a fresh model, returns the connection to that model, - and automatically disconnects and cleans up the model. + controller, adds a fresh model, returns the connection to that model, and + automatically disconnects and cleans up the model. The new model is also set as the current default for the controller connection. @@ -128,9 +128,8 @@ def models(self): @contextmanager def patch_file(filename): - """ "Patch" a file so that its current contents are automatically restored - when the context is exited. - """ + """"Patch" a file so that its current contents are automatically restored + when the context is exited.""" filepath = Path(filename).expanduser() data = filepath.read_bytes() try: diff --git a/tests/integration/test_controller.py b/tests/integration/test_controller.py index de09189ad..d06a9713a 100644 --- a/tests/integration/test_controller.py +++ b/tests/integration/test_controller.py @@ -191,10 +191,11 @@ async def test_add_remove_cloud(): @base.bootstrapped async def test_secrets_backend_lifecycle(): - """Testing the add_secret_backends is particularly - costly in term of resources. This test sets a vault - charm, add it to the controller and plays with the - list, removal, and update. + """Testing the add_secret_backends is particularly costly in term of + resources. + + This test sets a vault charm, add it to the controller and plays + with the list, removal, and update. """ async with base.CleanModel() as m: controller = await m.get_controller() diff --git a/tests/integration/test_errors.py b/tests/integration/test_errors.py index 564e248b3..8ca99e3e4 100644 --- a/tests/integration/test_errors.py +++ b/tests/integration/test_errors.py @@ -11,10 +11,8 @@ @base.bootstrapped async def test_juju_api_error(): - """Verify that we raise a JujuAPIError for responses with an error in - a top level key (for completely invalid requests). - - """ + """Verify that we raise a JujuAPIError for responses with an error in a top + level key (for completely invalid requests).""" from juju.errors import JujuAPIError async with base.CleanModel() as model: @@ -51,10 +49,8 @@ async def test_juju_error_in_results_list(): @base.bootstrapped async def test_juju_error_in_result(): - """Verify that we raise a JujuError when appropriate when we are - looking at a single result coming back. - - """ + """Verify that we raise a JujuError when appropriate when we are looking at + a single result coming back.""" from juju.client import client from juju.errors import JujuError diff --git a/tests/integration/test_model.py b/tests/integration/test_model.py index 25c4fd920..46549bddf 100644 --- a/tests/integration/test_model.py +++ b/tests/integration/test_model.py @@ -678,16 +678,17 @@ def wait_for_network(container, timeout=30): @base.bootstrapped async def test_add_manual_machine_ssh(): - """Test manual machine provisioning with a non-root user + """Test manual machine provisioning with a non-root user. - Tests manual machine provisioning using a randomized username with sudo access. + Tests manual machine provisioning using a randomized username with + sudo access. """ await add_manual_machine_ssh(is_root=False) @base.bootstrapped async def test_add_manual_machine_ssh_root(): - """Test manual machine provisioning with the root user""" + """Test manual machine provisioning with the root user.""" await add_manual_machine_ssh(is_root=True) @@ -968,10 +969,8 @@ async def test_wait_for_idle_with_exact_units(): @base.bootstrapped @pytest.mark.wait_for_idle async def test_wait_for_idle_with_exact_units_scale_down(): - """Deploys 3 units, waits for them to be idle, then removes 2 of them, - then waits for exactly 1 unit to be left. - - """ + """Deploys 3 units, waits for them to be idle, then removes 2 of them, then + waits for exactly 1 unit to be left.""" pytest.skip("This is testing juju functionality") async with base.CleanModel() as model: app = await model.deploy( @@ -997,10 +996,8 @@ async def test_wait_for_idle_with_exact_units_scale_down(): @base.bootstrapped async def test_wait_for_idle_with_exact_units_scale_down_zero(): - """Deploys 3 units, waits for them to be idle, then removes 3 of them, - then waits for exactly 0 unit to be left. - - """ + """Deploys 3 units, waits for them to be idle, then removes 3 of them, then + waits for exactly 0 unit to be left.""" pytest.skip("This is testing juju functionality") async with base.CleanModel() as model: app = await model.deploy( @@ -1221,9 +1218,7 @@ async def test_connect_current(): @base.bootstrapped async def test_model_cache_update(): """Connecting to a new model shouldn't fail because the cache is not - updated yet - - """ + updated yet.""" async with base.CleanController() as controller: await controller.connect_current() diff --git a/tests/integration/test_secrets.py b/tests/integration/test_secrets.py index af1325e9b..047a1bb30 100644 --- a/tests/integration/test_secrets.py +++ b/tests/integration/test_secrets.py @@ -29,9 +29,8 @@ async def test_add_secret(): # with the corresponding logic :) @base.bootstrapped async def test_list_secrets(): - """Use the charm-secret charm definition and see if the - arguments defined in the secret are correct or not. - """ + """Use the charm-secret charm definition and see if the arguments defined + in the secret are correct or not.""" charm_path = TESTS_DIR / "charm-secret/charm-secret_ubuntu-22.04-amd64.charm" async with base.CleanModel() as model: diff --git a/tests/unit/test_bundle.py b/tests/unit/test_bundle.py index 91c3181e0..87ff0f2d3 100644 --- a/tests/unit/test_bundle.py +++ b/tests/unit/test_bundle.py @@ -199,9 +199,11 @@ async def test_run_with_charmhub_charm(self): ) async def test_run_with_storage_variations(self): - """Test that various valid storage constraints are parsed as expected before model._deploy is called. + """Test that various valid storage constraints are parsed as expected + before model._deploy is called. - Uses the mock call logic from test_run_with_charmhub_charm, which will run before this test. + Uses the mock call logic from test_run_with_charmhub_charm, + which will run before this test. """ storage_arg_pairs: List[ Tuple[Dict[str, str], Dict[str, constraints.StorageConstraintDict]] @@ -295,9 +297,9 @@ async def test_run_with_storage_variations(self): ) async def test_run_with_charmhub_charm_no_channel(self): - """Test to verify if when the given channel is None, the channel defaults to "local/stable", which - is the default channel value for the Charm Hub - """ + """Test to verify if when the given channel is None, the channel + defaults to "local/stable", which is the default channel value for the + Charm Hub.""" storage_label = "some-label" storage_constraint = "ebs,100G,1" change = AddApplicationChange( diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index 833faf725..24cc062e2 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -1,7 +1,6 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. - -"""Tests for generated client code""" +"""Tests for generated client code.""" from unittest import mock diff --git a/tests/unit/test_gocookies.py b/tests/unit/test_gocookies.py index f3d5542a2..7f04f67fa 100644 --- a/tests/unit/test_gocookies.py +++ b/tests/unit/test_gocookies.py @@ -1,6 +1,5 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. - """Tests for the gocookies code.""" import os @@ -236,8 +235,9 @@ def load_jar(self, content): return jar def assert_jar_queries(self, jar, queries): - """Assert that all the given queries (see cookie_content_queries) - are satisfied when run on the given cookie jar. + """Assert that all the given queries (see cookie_content_queries) are + satisfied when run on the given cookie jar. + :param jar CookieJar: the cookie jar to query :param queries: the queries to run. """ diff --git a/tests/unit/test_offerendpoint.py b/tests/unit/test_offerendpoint.py index ec637b3ba..04fd3eae5 100644 --- a/tests/unit/test_offerendpoint.py +++ b/tests/unit/test_offerendpoint.py @@ -141,9 +141,10 @@ async def test_external_controller_consume( mock_connection, mock_create_consume_args, ): - """Test consuming an offer from an external controller. This would be - better suited as an integration test however pylibjuju does not allow - for bootstrapping of extra controllers. + """Test consuming an offer from an external controller. + + This would be better suited as an integration test however + pylibjuju does not allow for bootstrapping of extra controllers. """ mock_create_consume_args.return_value = None mock_connection.return_value = None diff --git a/tests/unit/test_proxy.py b/tests/unit/test_proxy.py index b5d5f3d03..8ee7903c2 100644 --- a/tests/unit/test_proxy.py +++ b/tests/unit/test_proxy.py @@ -10,8 +10,7 @@ class TestJujuDataFactory(unittest.TestCase): def test_proxy_from_config_unknown_type(self): """Test that a unknown proxy type results in a UnknownProxyTypeError - exception - """ + exception.""" self.assertRaises( ValueError, proxy_from_config, @@ -22,7 +21,7 @@ def test_proxy_from_config_unknown_type(self): ) def test_proxy_from_config_missing_type(self): - """Test that a nil proxy type returns None""" + """Test that a nil proxy type returns None.""" self.assertIsNone( proxy_from_config({ "config": {}, @@ -30,11 +29,12 @@ def test_proxy_from_config_missing_type(self): ) def test_proxy_from_config_non_arg(self): - """Tests that providing an empty proxy config results in a None proxy""" + """Tests that providing an empty proxy config results in a None + proxy.""" self.assertIsNone(proxy_from_config(None)) def test_proxy_from_config_kubernetes(self): - """Tests that a Kubernetes proxy is correctly created from config""" + """Tests that a Kubernetes proxy is correctly created from config.""" proxy = proxy_from_config({ "type": "kubernetes-port-forward", "config": { diff --git a/tests/validate/test_facade_versions.py b/tests/validate/test_facade_versions.py index 5638d8e6d..d1e722836 100644 --- a/tests/validate/test_facade_versions.py +++ b/tests/validate/test_facade_versions.py @@ -24,10 +24,11 @@ def project_root(pytestconfig: pytest.Config) -> Path: def generated_code_facades(project_root: Path) -> Dict[str, Sequence[int]]: """Return a {facade_name: (versions,)} dictionary from the generated code. - Iterates through all the generated files matching juju/client/_client*.py, - extracting facade types (those that have .name and .version properties). - Excludes facades in juju.client.connection.excluded_facades, as these are - manually marked as incompatible with the current version of python-libjuju. + Iterates through all the generated files matching + juju/client/_client*.py, extracting facade types (those that have + .name and .version properties). Excludes facades in + juju.client.connection.excluded_facades, as these are manually + marked as incompatible with the current version of python-libjuju. """ facades: Dict[str, List[int]] = defaultdict(list) for file in project_root.glob("juju/client/_client*.py"): @@ -46,7 +47,8 @@ def generated_code_facades(project_root: Path) -> Dict[str, Sequence[int]]: def test_client_facades(generated_code_facades: Dict[str, Sequence[int]]) -> None: - """Ensure that juju.client.facade_versions.client_facade_versions matches expected facades. + """Ensure that juju.client.facade_versions.client_facade_versions matches + expected facades. See generated_code_facades for how expected facades are computed. """ From 6422645cb56d83506963454b6855d38c99e9b821 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Tue, 12 Nov 2024 17:21:46 +0900 Subject: [PATCH 05/34] chore: docformatter + ruff --- tests/base.py | 5 +++-- tests/charm-secret/pyproject.toml | 2 -- tests/integration/test_errors.py | 6 ++++-- tests/integration/test_model.py | 9 ++++++--- tests/integration/test_secrets.py | 3 ++- tests/unit/test_bundle.py | 3 ++- tests/unit/test_proxy.py | 6 ++++-- 7 files changed, 21 insertions(+), 13 deletions(-) diff --git a/tests/base.py b/tests/base.py index ea37b1453..d409b5d24 100644 --- a/tests/base.py +++ b/tests/base.py @@ -128,8 +128,9 @@ def models(self): @contextmanager def patch_file(filename): - """"Patch" a file so that its current contents are automatically restored - when the context is exited.""" + """ "Patch" a file so that its current contents are automatically restored + when the context is exited. + """ filepath = Path(filename).expanduser() data = filepath.read_bytes() try: diff --git a/tests/charm-secret/pyproject.toml b/tests/charm-secret/pyproject.toml index 3f5144274..bfbb0be6e 100644 --- a/tests/charm-secret/pyproject.toml +++ b/tests/charm-secret/pyproject.toml @@ -19,9 +19,7 @@ target-version = ["py38"] line-length = 99 select = ["E", "W", "F", "C", "N", "D", "I001"] extend-ignore = [ - "D203", "D204", - "D213", "D215", "D400", "D404", diff --git a/tests/integration/test_errors.py b/tests/integration/test_errors.py index 8ca99e3e4..3ecc6323d 100644 --- a/tests/integration/test_errors.py +++ b/tests/integration/test_errors.py @@ -12,7 +12,8 @@ @base.bootstrapped async def test_juju_api_error(): """Verify that we raise a JujuAPIError for responses with an error in a top - level key (for completely invalid requests).""" + level key (for completely invalid requests). + """ from juju.errors import JujuAPIError async with base.CleanModel() as model: @@ -50,7 +51,8 @@ async def test_juju_error_in_results_list(): @base.bootstrapped async def test_juju_error_in_result(): """Verify that we raise a JujuError when appropriate when we are looking at - a single result coming back.""" + a single result coming back. + """ from juju.client import client from juju.errors import JujuError diff --git a/tests/integration/test_model.py b/tests/integration/test_model.py index 46549bddf..3a49cef10 100644 --- a/tests/integration/test_model.py +++ b/tests/integration/test_model.py @@ -970,7 +970,8 @@ async def test_wait_for_idle_with_exact_units(): @pytest.mark.wait_for_idle async def test_wait_for_idle_with_exact_units_scale_down(): """Deploys 3 units, waits for them to be idle, then removes 2 of them, then - waits for exactly 1 unit to be left.""" + waits for exactly 1 unit to be left. + """ pytest.skip("This is testing juju functionality") async with base.CleanModel() as model: app = await model.deploy( @@ -997,7 +998,8 @@ async def test_wait_for_idle_with_exact_units_scale_down(): @base.bootstrapped async def test_wait_for_idle_with_exact_units_scale_down_zero(): """Deploys 3 units, waits for them to be idle, then removes 3 of them, then - waits for exactly 0 unit to be left.""" + waits for exactly 0 unit to be left. + """ pytest.skip("This is testing juju functionality") async with base.CleanModel() as model: app = await model.deploy( @@ -1218,7 +1220,8 @@ async def test_connect_current(): @base.bootstrapped async def test_model_cache_update(): """Connecting to a new model shouldn't fail because the cache is not - updated yet.""" + updated yet. + """ async with base.CleanController() as controller: await controller.connect_current() diff --git a/tests/integration/test_secrets.py b/tests/integration/test_secrets.py index 047a1bb30..cc65bbc01 100644 --- a/tests/integration/test_secrets.py +++ b/tests/integration/test_secrets.py @@ -30,7 +30,8 @@ async def test_add_secret(): @base.bootstrapped async def test_list_secrets(): """Use the charm-secret charm definition and see if the arguments defined - in the secret are correct or not.""" + in the secret are correct or not. + """ charm_path = TESTS_DIR / "charm-secret/charm-secret_ubuntu-22.04-amd64.charm" async with base.CleanModel() as model: diff --git a/tests/unit/test_bundle.py b/tests/unit/test_bundle.py index 87ff0f2d3..b5f92756e 100644 --- a/tests/unit/test_bundle.py +++ b/tests/unit/test_bundle.py @@ -299,7 +299,8 @@ async def test_run_with_storage_variations(self): async def test_run_with_charmhub_charm_no_channel(self): """Test to verify if when the given channel is None, the channel defaults to "local/stable", which is the default channel value for the - Charm Hub.""" + Charm Hub. + """ storage_label = "some-label" storage_constraint = "ebs,100G,1" change = AddApplicationChange( diff --git a/tests/unit/test_proxy.py b/tests/unit/test_proxy.py index 8ee7903c2..5af4b8cbe 100644 --- a/tests/unit/test_proxy.py +++ b/tests/unit/test_proxy.py @@ -10,7 +10,8 @@ class TestJujuDataFactory(unittest.TestCase): def test_proxy_from_config_unknown_type(self): """Test that a unknown proxy type results in a UnknownProxyTypeError - exception.""" + exception. + """ self.assertRaises( ValueError, proxy_from_config, @@ -30,7 +31,8 @@ def test_proxy_from_config_missing_type(self): def test_proxy_from_config_non_arg(self): """Tests that providing an empty proxy config results in a None - proxy.""" + proxy. + """ self.assertIsNone(proxy_from_config(None)) def test_proxy_from_config_kubernetes(self): From 61f346bb8bd134991f56787df5de28f0328d8980 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Tue, 12 Nov 2024 17:39:24 +0900 Subject: [PATCH 06/34] chore: manual ruff fixes --- tests/integration/test_controller.py | 14 +++++++------- tests/integration/test_model.py | 6 +++--- tests/unit/test_connection.py | 8 ++++---- tests/unit/test_model.py | 6 +++--- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/integration/test_controller.py b/tests/integration/test_controller.py index d06a9713a..a6b9a3d15 100644 --- a/tests/integration/test_controller.py +++ b/tests/integration/test_controller.py @@ -245,10 +245,10 @@ async def test_secrets_backend_lifecycle(): assert response["results"][0]["error"] is None # List the secrets backend - list = await controller.list_secret_backends() - assert len(list["results"]) == 2 + alist = await controller.list_secret_backends() + assert len(alist["results"]) == 2 # consider the internal secrets backend - for entry in list["results"]: + for entry in alist["results"]: assert ( entry["result"].name == "internal" or entry["result"].name == "myvault" ) @@ -261,10 +261,10 @@ async def test_secrets_backend_lifecycle(): assert resp["results"][0]["error"] is None # List the secrets backend - list = await controller.list_secret_backends() - assert len(list["results"]) == 2 + alist = await controller.list_secret_backends() + assert len(alist["results"]) == 2 # consider the internal secrets backend - for entry in list["results"]: + for entry in alist["results"]: assert ( entry["result"].name == "internal" or entry["result"].name == "changed_name" @@ -318,7 +318,7 @@ async def test_connection_lazy_jujudata(): password=conn.password, ) assert new_controller._controller_name is None - new_controller.controller_name + assert new_controller.controller_name assert new_controller._controller_name is not None await new_controller.disconnect() diff --git a/tests/integration/test_model.py b/tests/integration/test_model.py index 3a49cef10..70589c0b1 100644 --- a/tests/integration/test_model.py +++ b/tests/integration/test_model.py @@ -53,7 +53,7 @@ async def test_deploy_local_bundle_dir(): app2 = model.applications.get("nrpe") with open("/tmp/output", "w") as writer: writer.write(str(bundle_path) + "\n") - for k, v in model.applications.items(): + for k in model.applications: writer.write(k) assert app1 and app2 # import pdb;pdb.set_trace() @@ -726,14 +726,14 @@ async def on_relation_add(self, delta, old, new, model): real_app_facade = client.ApplicationFacade.from_connection(model.connection()) mock_app_facade = mock.MagicMock() - async def mock_AddRelation(*args, **kwargs): + async def mock_add_relation(*args, **kwargs): # force response delay from AddRelation to test race condition # (see https://github.com/juju/python-libjuju/issues/191) result = await real_app_facade.AddRelation(*args, **kwargs) await relation_added.wait() return result - mock_app_facade.AddRelation = mock_AddRelation + mock_app_facade.AddRelation = mock_add_relation with mock.patch.object( client.ApplicationFacade, "from_connection", return_value=mock_app_facade diff --git a/tests/unit/test_connection.py b/tests/unit/test_connection.py index c1e632933..a7cc808cb 100644 --- a/tests/unit/test_connection.py +++ b/tests/unit/test_connection.py @@ -65,7 +65,7 @@ async def test_out_of_order(): ): con = await Connection.connect("0.1.2.3:999") actual_responses = [] - for i in range(3): + for _ in range(3): actual_responses.append(await con.rpc({"version": 1})) assert actual_responses == expected_responses finally: @@ -123,7 +123,7 @@ async def test_follow_redirect(): -----BEGIN CERTIFICATE----- SOMECERT -----END CERTIFICATE-----""" - wsForCont1 = WebsocketMock([ + cont1 = WebsocketMock([ { "request-id": 1, "error": "redirection to alternative server required", @@ -154,7 +154,7 @@ async def test_follow_redirect(): }, ]) minimal_facades = [{"name": "Pinger", "versions": [1]}] - wsForCont2 = WebsocketMock([ + cont2 = WebsocketMock([ {"request-id": 1}, {"request-id": 2}, { @@ -169,7 +169,7 @@ async def test_follow_redirect(): con = None try: with mock.patch( - "websockets.connect", mock.AsyncMock(side_effect=[wsForCont1, wsForCont2]) + "websockets.connect", mock.AsyncMock(side_effect=[cont1, cont2]) ), mock.patch("juju.client.connection.Connection._get_ssl"), mock.patch( "juju.client.connection.Connection._pinger", mock.AsyncMock() ): diff --git a/tests/unit/test_model.py b/tests/unit/test_model.py index c365d8954..0ec452d16 100644 --- a/tests/unit/test_model.py +++ b/tests/unit/test_model.py @@ -107,12 +107,12 @@ async def test_normal_use(self, mock_connect, mock_disconnect): @mock.patch("juju.model.Model.disconnect") @mock.patch("juju.model.Model.connect") async def test_exception(self, mock_connect, mock_disconnect): - class SomeException(Exception): + class SomeError(Exception): pass - with self.assertRaises(SomeException): + with self.assertRaises(SomeError): async with Model(): - raise SomeException() + raise SomeError() self.assertTrue(mock_connect.called) self.assertTrue(mock_disconnect.called) From e21d3c10d3274be6cb730e985982c822c2286601 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Tue, 12 Nov 2024 17:48:26 +0900 Subject: [PATCH 07/34] chore: manual ruff fixes --- juju/status.py | 2 +- tests/base.py | 2 +- tests/integration/test_application.py | 5 ++--- tests/integration/test_macaroon_auth.py | 2 +- tests/integration/test_model.py | 2 +- tests/unit/test_registration_string.py | 2 +- tests/unit/test_secrets.py | 2 +- tests/utils.py | 2 +- 8 files changed, 9 insertions(+), 10 deletions(-) diff --git a/juju/status.py b/juju/status.py index a27c1b2ac..c78603215 100644 --- a/juju/status.py +++ b/juju/status.py @@ -50,7 +50,7 @@ async def formatted_status(model, target=None, raw=False, filters=None): :param bool raw: if `true` this functions returns the raw `FullStatus` object returned by Juju. This is similar to invoking `get_status`. - :param str fileters: Optional list of applications, units, or machines + :param str filters: Optional list of applications, units, or machines to include, which can use wildcards ('*'). """ client_facade = client.ClientFacade.from_connection(model.connection()) diff --git a/tests/base.py b/tests/base.py index d409b5d24..72151c2a9 100644 --- a/tests/base.py +++ b/tests/base.py @@ -128,7 +128,7 @@ def models(self): @contextmanager def patch_file(filename): - """ "Patch" a file so that its current contents are automatically restored + """Patch a file so that its current contents are automatically restored when the context is exited. """ filepath = Path(filename).expanduser() diff --git a/tests/integration/test_application.py b/tests/integration/test_application.py index 5090c9768..06b48cd2d 100644 --- a/tests/integration/test_application.py +++ b/tests/integration/test_application.py @@ -13,13 +13,12 @@ from juju.url import URL, Schema from .. import base +from ..utils import INTEGRATION_TEST_DIR MB = 1 logger = logging.getLogger(__name__) -from ..utils import INTEGRATION_TEST_DIR - @base.bootstrapped async def test_action(): @@ -27,7 +26,7 @@ async def test_action(): app = await model.deploy("juju-qa-test") await jasyncio.sleep(10) actions = await app.get_actions(schema=True) - assert "fortune" in actions.keys(), 'mis"fortune" in charm actions' + assert "fortune" in actions @base.bootstrapped diff --git a/tests/integration/test_macaroon_auth.py b/tests/integration/test_macaroon_auth.py index 5f5385ad8..d588e3820 100644 --- a/tests/integration/test_macaroon_auth.py +++ b/tests/integration/test_macaroon_auth.py @@ -101,7 +101,7 @@ async def test_macaroon_auth_with_bad_key(): # @pytest.mark.xfail @pytest.mark.skip("one of old macaroon_auth tests, needs to be revised") async def test_macaroon_auth_with_unauthorized_user(): - auth_info, username = agent_auth_info() + auth_info, _ = agent_auth_info() # Create a bakery client can do agent authentication. client = httpbakery.Client( key=auth_info.key, diff --git a/tests/integration/test_model.py b/tests/integration/test_model.py index 70589c0b1..e843a774d 100644 --- a/tests/integration/test_model.py +++ b/tests/integration/test_model.py @@ -33,7 +33,7 @@ async def test_model_name(): model = Model() with pytest.raises(JujuModelError): - model.name + assert model.name async with base.CleanModel() as new_model: await model.connect(new_model.name) diff --git a/tests/unit/test_registration_string.py b/tests/unit/test_registration_string.py index 82065d31c..1713e9d61 100644 --- a/tests/unit/test_registration_string.py +++ b/tests/unit/test_registration_string.py @@ -21,6 +21,6 @@ def test_generate_user_controller_access_token(self): ) assert ( reg_string - == b"MH4TCnRlc3QtMDEyMzQwORMRMTkyLjE2OC4xLjE6MTcwNzATETE5Mi4xNjguMS4yOjE3MDcwExExOTIuMTY4" # noqa: E501 + == b"MH4TCnRlc3QtMDEyMzQwORMRMTkyLjE2OC4xLjE6MTcwNzATETE5Mi4xNjguMS4yOjE3MDcwExExOTIuMTY4" b"LjEuMzoxNzA3MAQgpaNZrqOw51ONk1kTER6rkm4hdPcg5VgC_dzXYxtUZaMTE2xvY2FsaG9zdC1sb2NhbGhvc3QA" ) diff --git a/tests/unit/test_secrets.py b/tests/unit/test_secrets.py index 281002dd1..f22217fd8 100644 --- a/tests/unit/test_secrets.py +++ b/tests/unit/test_secrets.py @@ -85,7 +85,7 @@ def test_yaml_file(self): { "hello": "d29ybGQ=", "goodbye": "world", - "another-key": "YiJHSUY4OWFceDBjXHgwMFx4MGNceDAwXHg4NFx4MDBceDAwXHhmZlx4ZmZceGY3XHhmNVx4ZjVceGVlXHhlOVx4ZTlceGU1ZmZmXHgwMFx4MDBceDAwXHhlN1x4ZTdceGU3Xl5eXHhmM1x4ZjNceGVkXHg4ZVx4OGVceDhlXHhlMFx4ZTBceGUwXHg5Zlx4OWZceDlmXHg5M1x4OTNceDkzXHhhN1x4YTdceGE3XHg5ZVx4OWVceDllaWlpY2NjXHhhM1x4YTNceGEzXHg4NFx4ODRceDg0XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5IVx4ZmVceDBlTWFkZSB3aXRoIEdJTVBceDAwLFx4MDBceDAwXHgwMFx4MDBceDBjXHgwMFx4MGNceDAwXHgwMFx4MDUsICBceDhlXHg4MTBceDllXHhlM0BceDE0XHhlOGlceDEwXHhjNFx4ZDFceDhhXHgwOFx4MWNceGNmXHg4ME0kelx4ZWZceGZmMFx4ODVwXHhiOFx4YjAxZlxyXHgxYlx4Y2VceDAxXHhjM1x4MDFceDFlXHgxMCcgXHg4MlxuXHgwMVx4MDA7Ig==", # noqa: E501 + "another-key": "YiJHSUY4OWFceDBjXHgwMFx4MGNceDAwXHg4NFx4MDBceDAwXHhmZlx4ZmZceGY3XHhmNVx4ZjVceGVlXHhlOVx4ZTlceGU1ZmZmXHgwMFx4MDBceDAwXHhlN1x4ZTdceGU3Xl5eXHhmM1x4ZjNceGVkXHg4ZVx4OGVceDhlXHhlMFx4ZTBceGUwXHg5Zlx4OWZceDlmXHg5M1x4OTNceDkzXHhhN1x4YTdceGE3XHg5ZVx4OWVceDllaWlpY2NjXHhhM1x4YTNceGEzXHg4NFx4ODRceDg0XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5XHhmZlx4ZmVceGY5IVx4ZmVceDBlTWFkZSB3aXRoIEdJTVBceDAwLFx4MDBceDAwXHgwMFx4MDBceDBjXHgwMFx4MGNceDAwXHgwMFx4MDUsICBceDhlXHg4MTBceDllXHhlM0BceDE0XHhlOGlceDEwXHhjNFx4ZDFceDhhXHgwOFx4MWNceGNmXHg4ME0kelx4ZWZceGZmMFx4ODVwXHhiOFx4YjAxZlxyXHgxYlx4Y2VceDAxXHhjM1x4MDFceDFlXHgxMCcgXHg4MlxuXHgwMVx4MDA7Ig==", }, ) diff --git a/tests/utils.py b/tests/utils.py index d328e7ee5..b4fa78c96 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -7,7 +7,7 @@ MB = 1 GB = 1024 -SSH_KEY = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsYMJGNGG74HAJha3n2CFmWYsOOaORnJK6VqNy86pj0MIpvRXBzFzVy09uPQ66GOQhTEoJHEqE77VMui7+62AcMXT+GG7cFHcnU8XVQsGM6UirCcNyWNysfiEMoAdZScJf/GvoY87tMEszhZIUV37z8PUBx6twIqMdr31W1J0IaPa+sV6FEDadeLaNTvancDcHK1zuKsL39jzAg7+LYjKJfEfrsQP+lj/EQcjtKqlhVS5kzsJVfx8ZEd0xhW5G7N6bCdKNalS8mKCMaBXJpijNQ82AiyqCIDCRrre2To0/i7pTjRiL0U9f9mV3S4NJaQaokR050w/ZLySFf6F7joJT mathijs@Qrama-Mathijs" # noqa +SSH_KEY = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsYMJGNGG74HAJha3n2CFmWYsOOaORnJK6VqNy86pj0MIpvRXBzFzVy09uPQ66GOQhTEoJHEqE77VMui7+62AcMXT+GG7cFHcnU8XVQsGM6UirCcNyWNysfiEMoAdZScJf/GvoY87tMEszhZIUV37z8PUBx6twIqMdr31W1J0IaPa+sV6FEDadeLaNTvancDcHK1zuKsL39jzAg7+LYjKJfEfrsQP+lj/EQcjtKqlhVS5kzsJVfx8ZEd0xhW5G7N6bCdKNalS8mKCMaBXJpijNQ82AiyqCIDCRrre2To0/i7pTjRiL0U9f9mV3S4NJaQaokR050w/ZLySFf6F7joJT mathijs@Qrama-Mathijs" HERE_DIR = Path(__file__).absolute() # tests/integration TESTS_DIR = HERE_DIR.parent # tests/ INTEGRATION_TEST_DIR = TESTS_DIR / "integration" From 70e3a7425424c775945366f62c940e1713e5d18e Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Tue, 12 Nov 2024 17:49:35 +0900 Subject: [PATCH 08/34] chore: pre-commit and its settings --- .pre-commit-config.yaml | 34 +++++++++ pyproject.toml | 153 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 187 insertions(+) create mode 100644 .pre-commit-config.yaml create mode 100644 pyproject.toml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..ff64eff22 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,34 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: check-added-large-files + - id: check-ast + - id: check-case-conflict + - id: check-executables-have-shebangs + - id: check-shebang-scripts-are-executable + - id: check-merge-conflict + - id: check-symlinks + - id: check-json + - id: check-yaml + - id: check-toml + - id: mixed-line-ending + - id: end-of-file-fixer + - id: trailing-whitespace + - id: detect-private-key + # Run the Ruff linter. + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.7.3 + hooks: + - id: ruff + args: [ --preview, --fix ] + - id: ruff-format + args: [ --preview ] + # Spellcheck the code. + - repo: https://github.com/codespell-project/codespell + rev: v2.3.0 + hooks: + - id: codespell + additional_dependencies: + - tomli + exclude: "^juju/client/schemas-juju.*json$" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..4253d9232 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,153 @@ +[project] +name = "juju" +description = "Python library for Juju" +readme = "docs/readme.rst" +license = "Apache-2.0" +maintainers = [{name = "Juju Ecosystem Engineering", email = "juju@lists.ubuntu.com"}] +requires-python = ">=3.8" +homepage = "https://github.com/juju/python-libjuju" +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Operating System :: MacOS :: MacOS X", + "Operating System :: POSIX :: Linux", +] + +[project.dependencies] +macaroonbakery = ">=1.1,<2.0" +pyRFC3339 = ">=1.0,<2.0" +pyyaml = ">=5.1.2" +websockets = ">=8.1,<14.0" +paramiko = ">=2.4.0" +pyasn1 = ">=0.4.4" +toposort = ">=1.5,<2" +typing_inspect = ">=0.6.0" +kubernetes = ">=12.0.1,<31.0.0" +hvac = "*" +packaging = "*" +typing-extensions = ">=4.5.0" + +[project.urls] +"Homepage" = "https://juju.is/docs/sdk" +"Repository" = "https://github.com/juju/python-libjuju" +"Issues" = "https://github.com/juju/python-libjuju/issues" +"Documentation" = "https://pythonlibjuju.readthedocs.io/en/latest/" +"Changelog" = "https://pythonlibjuju.readthedocs.io/en/latest/changelog.html#changelog" + +[tool.setuptools.dynamic] +version = {attr = "juju.version.CLIENT_VERSION"} + +# Linting tools configuration +[tool.ruff] +target-version = "py38" + +[tool.ruff.lint] +select = [ + # Pyflakes + "F", + # Pycodestyle + "E", + "W", + # isort + "I001", + # pep8-naming + "N", + # flake8-builtins + "A", + # flake8-copyright + "CPY", + # pyupgrade + "UP", + # flake8-2020 + "YTT", + # flake8-bandit + "S", + # flake8-bugbear + "B", + # flake8-simplify + "SIM", + # Ruff specific + "RUF", + # Perflint + "PERF", + # pyflakes-docstrings + "D", +] +ignore = [ + # FIXME: change the codegen to remove the schema from auto-generate classes + "RUF012", + # FIXME: change the codegen to insert a period at the end of the docstring + "D415", +] + +[tool.ruff.lint.per-file-ignores] +"tests/*" = [ + # assert False to fail + "B011", + # raise from + "B904", + # Don't require docstrings + "D100", + "D101", + "D102", + "D103", + "D104", + "D105", + "D107", + # Copyright + "CPY001", + # Docstring format + "D205", + "D400", + # FIXME do something about long lines in assert v == "aaa..." + "E501", + # Performance overhead + "PERF203", + # async function without await + "RUF029", + # index[0] + "RUF015", + # Allow asserts + "S101", + # Hardcoded passwords and secret keys + "S105", + "S106", + # FIXME Hardcoded /tmp path, prevents parallel tests + "S108", + # Weird URL scheme + "S310", + # Weak random source + "S311", + # subprocess + "S404", + "S603", + "S607", + # FIXME YAML loader + "S506", + # FIXME refactor nested if statements + "SIM102", + # FIXME refactor nested with statements + "SIM117", + # FIXME refactor to use list comprehensions + "PERF401", + # FIXME new-style super() + "UP008", + # %-format + "UP031", +] + +[tool.pyright] +# These are tentative +# include = ["**/*.py"] +pythonVersion = "3.8" # check no python > 3.8 features are used +pythonPlatform = "All" +typeCheckingMode = "strict" From ac9947446e435a56baf9b516c300b1a7cfc506fb Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Wed, 13 Nov 2024 12:29:58 +0900 Subject: [PATCH 09/34] chore: verbatim copies of json files from juju --- juju/client/schemas-juju-3.1.0.json | 2 +- juju/client/schemas-juju-3.1.10.json | 2 +- juju/client/schemas-juju-3.1.5.json | 2 +- juju/client/schemas-juju-3.3.0.json | 2 +- juju/client/schemas-juju-3.3.7.json | 2 +- juju/client/schemas-juju-3.4.6.json | 2 +- juju/client/schemas-juju-3.5.4.json | 2 +- juju/client/schemas-juju-3.6-rc1.json | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/juju/client/schemas-juju-3.1.0.json b/juju/client/schemas-juju-3.1.0.json index 5f6f003f3..b33d9e459 100644 --- a/juju/client/schemas-juju-3.1.0.json +++ b/juju/client/schemas-juju-3.1.0.json @@ -17429,4 +17429,4 @@ } } } -] +] \ No newline at end of file diff --git a/juju/client/schemas-juju-3.1.10.json b/juju/client/schemas-juju-3.1.10.json index fb47c9d77..bd18742b3 100644 --- a/juju/client/schemas-juju-3.1.10.json +++ b/juju/client/schemas-juju-3.1.10.json @@ -17403,4 +17403,4 @@ } } } -] +] \ No newline at end of file diff --git a/juju/client/schemas-juju-3.1.5.json b/juju/client/schemas-juju-3.1.5.json index 37c1d514f..302cf2074 100644 --- a/juju/client/schemas-juju-3.1.5.json +++ b/juju/client/schemas-juju-3.1.5.json @@ -17409,4 +17409,4 @@ } } } -] +] \ No newline at end of file diff --git a/juju/client/schemas-juju-3.3.0.json b/juju/client/schemas-juju-3.3.0.json index 0da05ac0c..6cc880648 100644 --- a/juju/client/schemas-juju-3.3.0.json +++ b/juju/client/schemas-juju-3.3.0.json @@ -18201,4 +18201,4 @@ } } } -] +] \ No newline at end of file diff --git a/juju/client/schemas-juju-3.3.7.json b/juju/client/schemas-juju-3.3.7.json index 9fd15a94c..88e8102d4 100644 --- a/juju/client/schemas-juju-3.3.7.json +++ b/juju/client/schemas-juju-3.3.7.json @@ -18227,4 +18227,4 @@ } } } -] +] \ No newline at end of file diff --git a/juju/client/schemas-juju-3.4.6.json b/juju/client/schemas-juju-3.4.6.json index 9fd15a94c..88e8102d4 100644 --- a/juju/client/schemas-juju-3.4.6.json +++ b/juju/client/schemas-juju-3.4.6.json @@ -18227,4 +18227,4 @@ } } } -] +] \ No newline at end of file diff --git a/juju/client/schemas-juju-3.5.4.json b/juju/client/schemas-juju-3.5.4.json index 06c042866..e9c69b086 100644 --- a/juju/client/schemas-juju-3.5.4.json +++ b/juju/client/schemas-juju-3.5.4.json @@ -18020,4 +18020,4 @@ } } } -] +] \ No newline at end of file diff --git a/juju/client/schemas-juju-3.6-rc1.json b/juju/client/schemas-juju-3.6-rc1.json index 8c46189b0..9aa310a17 100644 --- a/juju/client/schemas-juju-3.6-rc1.json +++ b/juju/client/schemas-juju-3.6-rc1.json @@ -17832,4 +17832,4 @@ } } } -] +] \ No newline at end of file From 83a3cd4dee1f43ccea7b838a78f4897c406a1720 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Wed, 13 Nov 2024 12:31:25 +0900 Subject: [PATCH 10/34] chore: exempt json files copied from juju from specific checks --- .pre-commit-config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ff64eff22..1609e7e0e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,6 +14,7 @@ repos: - id: check-toml - id: mixed-line-ending - id: end-of-file-fixer + exclude: "^juju/client/schemas-juju.*json$" - id: trailing-whitespace - id: detect-private-key # Run the Ruff linter. From 04e64462ce3cf9723bfa9956198b3fbd17d362e4 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Wed, 13 Nov 2024 12:49:01 +0900 Subject: [PATCH 11/34] chore: ruff format after codegen --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 81b1cbb3f..11677f6d6 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,7 @@ clean: client: tox -r --notest -e lint,py3 $(PY) -m juju.client.facade -s "juju/client/schemas*" -o juju/client/ + pre-commit run --files $(shell echo juju/client/_[cd]*.py) .PHONY: run-unit-tests run-unit-tests: .tox lint From 7ae385898531c872cd640d59e9192bd23eea0f06 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Wed, 13 Nov 2024 12:59:47 +0900 Subject: [PATCH 12/34] chore: fix up arg that's not optional --- juju/utils.py | 104 +++++++++++++++++++++------------------ juju/version.py | 1 + pyproject.toml | 2 + setup.py | 1 + tests/unit/test_utils.py | 6 +-- 5 files changed, 63 insertions(+), 51 deletions(-) diff --git a/juju/utils.py b/juju/utils.py index 52a4a8401..dedf72dab 100644 --- a/juju/utils.py +++ b/juju/utils.py @@ -37,14 +37,13 @@ async def execute_process(*cmd, log=None): def juju_config_dir(): - """Resolves and returns the path string to the juju configuration - folder for the juju CLI tool. Of the following items, returns the - first option that works (top to bottom): + """Resolves and returns the path string to the juju configuration folder + for the juju CLI tool. Of the following items, returns the first option + that works (top to bottom): * $JUJU_DATA * $XDG_DATA_HOME/juju * ~/.local/share/juju - """ # Set it to ~/.local/share/juju as default config_dir = Path("~/.local/share/juju") @@ -60,9 +59,8 @@ def juju_config_dir(): def juju_ssh_key_paths(): - """Resolves and returns the path strings for public and private ssh - keys for juju CLI. - + """Resolves and returns the path strings for public and private ssh keys + for juju CLI. """ config_dir = juju_config_dir() public_key_path = os.path.join(config_dir, "ssh", "juju_id_rsa.pub") @@ -74,7 +72,6 @@ def juju_ssh_key_paths(): def _read_ssh_key(): """Inner function for read_ssh_key, suitable for passing to our Executor. - """ public_key_path_str, _ = juju_ssh_key_paths() ssh_key_path = Path(public_key_path_str) @@ -84,16 +81,17 @@ def _read_ssh_key(): async def read_ssh_key(): - """Attempt to read the local juju admin's public ssh key, so that it - can be passed on to a model. - + """Attempt to read the local juju admin's public ssh key, so that it can be + passed on to a model. """ loop = jasyncio.get_running_loop() return await loop.run_in_executor(None, _read_ssh_key) class IdQueue: - """Wrapper around asyncio.Queue that maintains a separate queue for each ID.""" + """Wrapper around asyncio.Queue that maintains a separate queue for each + ID. + """ def __init__(self, maxsize=0): self._queues = defaultdict(partial(jasyncio.Queue, maxsize)) @@ -115,9 +113,9 @@ async def put_all(self, value): async def block_until(*conditions, timeout=None, wait_period=0.5): """Return only after all conditions are true. + If a timeout occurs, it cancels the task and raises asyncio.TimeoutError. - """ async def _block(): @@ -131,6 +129,7 @@ async def block_until_with_coroutine( condition_coroutine, timeout=None, wait_period=0.5 ): """Return only after the given coroutine returns True. + If a timeout occurs, it cancels the task and raises asyncio.TimeoutError. """ @@ -201,15 +200,13 @@ class Addrs(univ.SequenceOf): class RegistrationInfo(univ.Sequence): """ASN.1 representation of: - type RegistrationInfo struct { - User string + type RegistrationInfo struct { User string - Addrs []string + Addrs []string - SecretKey []byte + SecretKey []byte - ControllerName string - } + ControllerName string } """ pass @@ -219,7 +216,7 @@ def generate_user_controller_access_token( username, controller_endpoints, secret_key, controller_name ): """ " Implement in python what is currently done in GO - https://github.com/juju/juju/blob/a5ab92ec9b7f5da3678d9ac603fe52d45af24412/cmd/juju/user/utils.go#L16 + https://github.com/juju/juju/blob/a5ab92e/cmd/juju/user/utils.go#L16 :param username: name of the user to register :param controller_endpoints: juju controller endpoints list in the format : @@ -246,11 +243,13 @@ def generate_user_controller_access_token( def get_local_charm_data(path, yaml_file): - """Retrieve Metadata of a Charm from its path + """Retrieve Metadata of a Charm from its path. - :patam str path: Path of charm directory or .charm file - :patam str yaml_file: name of the yaml file, can be either - "metadata.yaml", or "manifest.yaml", or "charmcraft.yaml" + :patam str path: Path of charm directory or .charm file :patam str + yaml_ + file: + name of the yaml file, can be either "metadata.yaml", or + "manifest.yaml", or "charmcraft.yaml" :return: Object of charm metadata """ @@ -340,8 +339,8 @@ def get_local_charm_charmcraft_yaml(path): def get_series_version(series_name): - """get_series_version outputs the version of the OS based on the given series - e.g. jammy -> 22.04, kubernetes -> kubernetes + """get_series_version outputs the version of the OS based on the given + series e.g. jammy -> 22.04, kubernetes -> kubernetes. :param str series_name: name of the series :return str: os version @@ -352,8 +351,8 @@ def get_series_version(series_name): def get_version_series(version): - """get_version_series is the opposite of the get_series_version. It outputs the series based - on given OS version + """get_version_series is the opposite of the get_series_version. It outputs + the series based on given OS version. :param str version: version of the OS return str: name of the series corresponding to the given version @@ -364,10 +363,11 @@ def get_version_series(version): def get_local_charm_base(series, charm_path, base_class): - """Deduce the base [channel/osname] of a local charm based on what we - know already + """Deduce the base [channel/osname] of a local charm based on what we know + already. - :param str series: This may come from the argument or the metadata.yaml + :param str series: This may come from the argument or the + metadata.yaml :param str charm_path: Path of charm directory/.charm file :param class base_class: :return: Instance of the baseCls with channel/osname information @@ -413,7 +413,7 @@ def get_local_charm_base(series, charm_path, base_class): def base_channel_to_series(channel): - """Returns the series string using the track inside the base channel + """Returns the series string using the track inside the base channel. :param str channel: is track/risk (e.g. 20.04/stable) :return: str series (e.g. focal) @@ -422,8 +422,8 @@ def base_channel_to_series(channel): def parse_base_arg(base): - """Parses a given base into a Client.Base object - :param base str : The base to deploy a charm (e.g. ubuntu@22.04) + """Parses a given base into a Client.Base object :param base str : The base + to deploy a charm (e.g. ubuntu@22.04) """ client.CharmBase() if not (isinstance(base, str) and "@" in base): @@ -464,10 +464,12 @@ def get_base_from_origin_or_channel(origin_or_channel, series=None): def series_for_charm(requested_series, supported_series): - """series_for_charm takes a requested series and a list of series supported by a - charm and returns the series which is relevant. - If the requested series is empty, then the first supported series is used, - otherwise the requested series is validated against the supported series. + """series_for_charm takes a requested series and a list of series supported + by a charm and returns the series which is relevant. + + If the requested series is empty, then the first supported series is + used, otherwise the requested series is validated against the + supported series. """ if len(supported_series) == 1 and supported_series[0] == "": raise JujuError("invalid supported series reported by charm : ['']") @@ -492,7 +494,8 @@ def user_requested(series_arg, supported_series, force): series = series_for_charm(series_arg, supported_series) if force: series = series_arg - # Todo (cderici): validate the series with workload_series to see if juju is supporting that + # Todo (cderici): validate the series with workload_series to see if juju is + # supporting that return series @@ -542,15 +545,19 @@ def series_selector( return DEFAULT_SUPPORTED_LTS -def should_upgrade_resource(available_resource, existing_resources, arg_resources={}): - """Called in the context of upgrade_charm. Given a resource R, takes a look at the resources we - already have and decides if we need to refresh R. +def should_upgrade_resource(available_resource, existing_resources, arg_resources): + """Determine if the given resource should be upgraded. + + Called in the context of upgrade_charm. Given a resource R, takes a look + at the resources we already have and decides if we need to refresh R. - :param dict[str] available_resource: The dict representing the client.Resource coming from the - charmhub api. We're considering if we need to refresh this during upgrade_charm. - :param dict[str] existing_resources: The dict coming from resources_facade.ListResources - representing the resources of the currently deployed charm. - :param dict[str] arg_resources: user provided resources to be refreshed + :param dict[str] available_resource: The dict representing the + client.Resource coming from the charmhub api. We're considering if + we need to refresh this during upgrade_charm. :param dict[str] + existing_resources: The dict coming from + resources_facade.ListResources representing the resources of the + currently deployed charm. :param dict[str] arg_resources: user + provided resources to be refreshed :result bool: The decision to refresh the given resource """ @@ -565,7 +572,8 @@ def should_upgrade_resource(available_resource, existing_resources, arg_resource # no upgrade, if it's upload if existing_resources[res_name].origin == "upload": return False - # no upgrade, if upstream doesn't have a newer revision of the resource available + # no upgrade, if upstream doesn't have a newer revision of the resource + # available available_rev = available_resource.get( "Revision", available_resource.get("revision", -1) ) diff --git a/juju/version.py b/juju/version.py index f99462925..a0022b094 100644 --- a/juju/version.py +++ b/juju/version.py @@ -1,5 +1,6 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. +"""Client version definitions.""" LTS_RELEASES = ["jammy", "focal", "bionic", "xenial", "trusty", "precise"] diff --git a/pyproject.toml b/pyproject.toml index 4253d9232..8a2734f83 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -87,6 +87,8 @@ ignore = [ "RUF012", # FIXME: change the codegen to insert a period at the end of the docstring "D415", + # FIXME: manually rewrite docstring headlines to git on one line + "D400", ] [tool.ruff.lint.per-file-ignores] diff --git a/setup.py b/setup.py index 705f2bca8..0c22a6e05 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,6 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. +"""Building this package.""" from pathlib import Path diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index d0c5b15ce..3364d39c1 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -137,7 +137,7 @@ def test_should_upgrade_resource_no_same_rev(self): size=0, ) } - assert not utils.should_upgrade_resource(res, existing) + assert not utils.should_upgrade_resource(res, existing, {}) def test_should_upgrade_resource_no_local_upload(self): # fields are trimmed for readability @@ -176,7 +176,7 @@ def test_should_upgrade_resource_no_local_upload(self): size=0, ) } - assert not utils.should_upgrade_resource(res, existing) + assert not utils.should_upgrade_resource(res, existing, {}) def test_should_upgrade_resource_yes_new_revision(self): # fields are trimmed for readability @@ -215,4 +215,4 @@ def test_should_upgrade_resource_yes_new_revision(self): size=0, ) } - assert utils.should_upgrade_resource(res, existing) + assert utils.should_upgrade_resource(res, existing, {}) From 05dfde5ae8dff434b0e36f6e61d60bb622e82768 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Wed, 13 Nov 2024 13:35:27 +0900 Subject: [PATCH 13/34] chore: fix up utils, secrets, provisioner --- juju/provisioner.py | 37 +++++++++++++++---------------------- juju/secrets.py | 2 +- juju/status.py | 10 ++++++++-- juju/unit.py | 8 ++++---- juju/utils.py | 21 +++++++++++++-------- pyproject.toml | 32 ++++++++++++++++++++++++++++++++ 6 files changed, 73 insertions(+), 37 deletions(-) diff --git a/juju/provisioner.py b/juju/provisioner.py index 36b8f7c18..32d092ccf 100644 --- a/juju/provisioner.py +++ b/juju/provisioner.py @@ -317,11 +317,10 @@ def _run_configure_script(self, script): :raises: :class:`paramiko.ssh_exception.AuthenticationException` if the upload fails """ - _, tmpFile = tempfile.mkstemp() - with open(tmpFile, "w") as f: - f.write(script) + with tempfile.NamedTemporaryFile("w") as tmp_file: + tmp_file.write(script) + tmp_file.flush() - try: # get ssh client ssh = self._get_ssh_client( self.host, @@ -329,21 +328,15 @@ def _run_configure_script(self, script): self.private_key_path, ) - # copy the local copy of the script to the remote machine - sftp = paramiko.SFTPClient.from_transport(ssh.get_transport()) - sftp.put( - tmpFile, - tmpFile, - ) - - # run the provisioning script - stdout, stderr = self._run_command( - ssh, - f"sudo /bin/bash {tmpFile}", - ) - - except paramiko.ssh_exception.AuthenticationException as e: - raise e - finally: - os.remove(tmpFile) - ssh.close() + try: + # copy the local copy of the script to the remote machine + sftp = paramiko.SFTPClient.from_transport(ssh.get_transport()) + sftp.put(tmp_file.name, tmp_file.name) + + # run the provisioning script + _stdout, _stderr = self._run_command( + ssh, + f"sudo /bin/bash {tmp_file.name}", + ) + finally: + ssh.close() diff --git a/juju/secrets.py b/juju/secrets.py index 37a94c6a3..5a47f1ef9 100644 --- a/juju/secrets.py +++ b/juju/secrets.py @@ -1,7 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -"""This module contains utility logic for secrets such as reading secret data from yaml and creating data bag for secrets.""" +"""A utility module for secrets such as reading secret data from yaml and creating data bag for secrets.""" import base64 import json diff --git a/juju/status.py b/juju/status.py index c78603215..6d9efbde6 100644 --- a/juju/status.py +++ b/juju/status.py @@ -2,6 +2,7 @@ # Licensed under the Apache V2, see LICENCE file for details. import logging +import warnings from .client import client @@ -53,6 +54,11 @@ async def formatted_status(model, target=None, raw=False, filters=None): :param str filters: Optional list of applications, units, or machines to include, which can use wildcards ('*'). """ + warnings.warn( + "juju.status.formatted_status is deprecated, the implementation is likely broken", + DeprecationWarning, + stacklevel=1, + ) client_facade = client.ClientFacade.from_connection(model.connection()) result_status = await client_facade.FullStatus(patterns=filters) @@ -138,10 +144,10 @@ def _print_status_units(result_status): limits = "{:<15} {:<15} {:<20} {:<10} {:<15} {:<10} {:<30}" summary = "" - for app_name, app in apps.items(): + for app in apps.values(): units = app.units if units is None or len(units) == 0: - next + continue for name, unit in units.items(): addr = unit.public_address diff --git a/juju/unit.py b/juju/unit.py index aff97e433..b0d66a49e 100644 --- a/juju/unit.py +++ b/juju/unit.py @@ -121,10 +121,10 @@ async def get_public_address(self): return addr app_facade = client.ApplicationFacade.from_connection(self.connection) - defResult = await app_facade.UnitsInfo(entities=[client.Entity(self.tag)]) - if defResult is not None and len(defResult.results) > 1: + def_result = await app_facade.UnitsInfo(entities=[client.Entity(self.tag)]) + if def_result is not None and len(def_result.results) > 1: raise JujuAPIError("expected one result") - return defResult.results[0].result.get("public-address", None) + return def_result.results[0].result.get("public-address", None) async def resolved(self, retry=False): """Mark unit errors resolved. @@ -411,7 +411,7 @@ async def is_leader_from_status(self): if not is_subordinate: continue - for key, unit in app_data.units.items(): + for unit in app_data.units.values(): if unit.subordinates and unit.subordinates.get(self.name): is_leader = unit.subordinates[self.name].leader return is_leader if is_leader else False diff --git a/juju/utils.py b/juju/utils.py index dedf72dab..1692816f1 100644 --- a/juju/utils.py +++ b/juju/utils.py @@ -96,15 +96,15 @@ class IdQueue: def __init__(self, maxsize=0): self._queues = defaultdict(partial(jasyncio.Queue, maxsize)) - async def get(self, id): - value = await self._queues[id].get() - del self._queues[id] + async def get(self, id_): + value = await self._queues[id_].get() + del self._queues[id_] if isinstance(value, Exception): raise value return value - async def put(self, id, value): - await self._queues[id].put(value) + async def put(self, id_, value): + await self._queues[id_].put(value) async def put_all(self, value): for queue in self._queues.values(): @@ -176,7 +176,7 @@ async def run_with_interrupt(task, *events, log=None): task = jasyncio.create_task_with_handler(task, "tmp", log) event_tasks = [jasyncio.ensure_future(event.wait()) for event in events] done, pending = await jasyncio.wait( - [task] + event_tasks, return_when=jasyncio.FIRST_COMPLETED + [task, *event_tasks], return_when=jasyncio.FIRST_COMPLETED ) for f in pending: f.cancel() # cancel unfinished tasks @@ -194,6 +194,8 @@ async def run_with_interrupt(task, *events, log=None): class Addrs(univ.SequenceOf): + """Internal.""" + componentType = char.PrintableString() @@ -215,7 +217,8 @@ class RegistrationInfo(univ.Sequence): def generate_user_controller_access_token( username, controller_endpoints, secret_key, controller_name ): - """ " Implement in python what is currently done in GO + """Implement in python what is currently done in GO. + https://github.com/juju/juju/blob/a5ab92e/cmd/juju/user/utils.go#L16 :param username: name of the user to register @@ -502,7 +505,9 @@ def user_requested(series_arg, supported_series, force): def series_selector( series_arg="", charm_url=None, model_config=None, supported_series=[], force=False ): - """series_selector corresponds to the CharmSeries() in + """Select series to deploy on. + + series_selector corresponds to the CharmSeries() in https://github.com/juju/juju/blob/develop/core/charm/series_selector.go determines what series to use with a charm. diff --git a/pyproject.toml b/pyproject.toml index 8a2734f83..0b320c630 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -83,12 +83,44 @@ select = [ "D", ] ignore = [ + # juju.secrets is a part of public API, can't rename or remove it now + "A005", # FIXME: change the codegen to remove the schema from auto-generate classes "RUF012", # FIXME: change the codegen to insert a period at the end of the docstring "D415", + # FIXME: quite a few mutable default arguments should be refactored + "B006", + # FIXME: raise from + "B904", + # FIXME: a bunch of missing docstrings + "D100", + "D101", + "D102", + "D103", + "D105", + "D107", + # FIXME: a bunch of docstrings without headlines + "D205", # FIXME: manually rewrite docstring headlines to git on one line "D400", + "D401", + # FIXME: run `uvx docformatter` to reformat docstrings + # Manual fixes are needed for string literals and f-strings + "E501", + # FIXME: there are some mixedCase members + "N815", + # try-except in a loop; hardly an issue in async functions + "PERF203", + # FIXME: validate that we use yaml safely + "S506", + # FIXME: try/except: pass is OK + # Note: swallowing CancelledError is most likely a bug + "SIM105", + # FIXME: refactor if-else + "SIM108", + # % format is just fine + "UP031", ] [tool.ruff.lint.per-file-ignores] From d79029d0e9d9736c0e7a967adc09474ba51f3df4 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Wed, 13 Nov 2024 14:49:27 +0900 Subject: [PATCH 14/34] chore: fix model; restore jasyncio re-export --- juju/client/facade.py | 6 ++ juju/controller.py | 9 +-- juju/delta.py | 22 ++++---- juju/errors.py | 2 +- juju/jasyncio.py | 33 +++++++++-- juju/loop.py | 6 +- juju/machine.py | 12 ++-- juju/model.py | 127 ++++++++++++++++++++---------------------- juju/origin.py | 2 +- juju/provisioner.py | 38 +++++++------ pyproject.toml | 8 +++ 11 files changed, 150 insertions(+), 115 deletions(-) diff --git a/juju/client/facade.py b/juju/client/facade.py index 97df78191..7eb92ec15 100644 --- a/juju/client/facade.py +++ b/juju/client/facade.py @@ -713,6 +713,12 @@ def serialize(self): def to_json(self): return json.dumps(self.serialize(), cls=TypeEncoder, sort_keys=True) + def __contains__(self, key): + return key in self._toPy + + def get(self, key, default=None): + return self[key] if key in self else default + # treat subscript gets as JSON representation def __getitem__(self, key): attr = self._toPy[key] diff --git a/juju/controller.py b/juju/controller.py index b0bd8b054..64b4035cf 100644 --- a/juju/controller.py +++ b/juju/controller.py @@ -565,10 +565,10 @@ async def get_cloud(self): cloud_facade = client.CloudFacade.from_connection(self.connection()) result = await cloud_facade.Clouds() - cloud = list(result.clouds.keys())[0] # only lives on one cloud + cloud = next(iter(result.clouds)) return tag.untag("cloud-", cloud) - async def get_models(self, all=False, username=None): + async def get_models(self, all=False, username=None): # noqa: A002 """.. deprecated:: 0.7.0 Use :meth:`.list_models` instead. """ @@ -630,10 +630,7 @@ async def get_model(self, model): :returns Model: Connected Model instance. """ uuids = await self.model_uuids() - if model in uuids: - uuid = uuids[model] - else: - uuid = model + uuid = uuids.get(model) or model from juju.model import Model diff --git a/juju/delta.py b/juju/delta.py index a2ac374fe..b32464e65 100644 --- a/juju/delta.py +++ b/juju/delta.py @@ -17,13 +17,13 @@ def get_id(self): return self.data["id"] @classmethod - def get_entity_class(self): + def get_entity_class(cls): return None class ActionDelta(EntityDelta): @classmethod - def get_entity_class(self): + def get_entity_class(cls): from .action import Action return Action @@ -34,7 +34,7 @@ def get_id(self): return self.data["name"] @classmethod - def get_entity_class(self): + def get_entity_class(cls): from .application import Application return Application @@ -45,7 +45,7 @@ def get_id(self): return self.data["tag"] @classmethod - def get_entity_class(self): + def get_entity_class(cls): from .annotation import Annotation return Annotation @@ -56,7 +56,7 @@ def get_id(self): return self.data["model-uuid"] @classmethod - def get_entity_class(self): + def get_entity_class(cls): from .model import ModelInfo return ModelInfo @@ -64,7 +64,7 @@ def get_entity_class(self): class MachineDelta(EntityDelta): @classmethod - def get_entity_class(self): + def get_entity_class(cls): from .machine import Machine return Machine @@ -75,7 +75,7 @@ def get_id(self): return self.data["name"] @classmethod - def get_entity_class(self): + def get_entity_class(cls): from .unit import Unit return Unit @@ -83,7 +83,7 @@ def get_entity_class(self): class RelationDelta(EntityDelta): @classmethod - def get_entity_class(self): + def get_entity_class(cls): from .relation import Relation return Relation @@ -94,7 +94,7 @@ def get_id(self): return self.data["name"] @classmethod - def get_entity_class(self): + def get_entity_class(cls): from .remoteapplication import RemoteApplication return RemoteApplication @@ -105,7 +105,7 @@ def get_id(self): return self.data["charm-url"] @classmethod - def get_entity_class(self): + def get_entity_class(cls): from .charm import Charm return Charm @@ -116,7 +116,7 @@ def get_id(self): return self.data["application-name"] @classmethod - def get_entity_class(self): + def get_entity_class(cls): from .remoteapplication import ApplicationOffer return ApplicationOffer diff --git a/juju/errors.py b/juju/errors.py index 839941511..92418703f 100644 --- a/juju/errors.py +++ b/juju/errors.py @@ -24,7 +24,7 @@ def __init__(self, result): self.error_code = result.get("error-code") self.response = result["response"] self.request_id = result["request-id"] - self.error_info = result["error-info"] if "error-info" in result else None + self.error_info = result.get("error-info") super().__init__(self.message) diff --git a/juju/jasyncio.py b/juju/jasyncio.py index f86fb6635..c77827f6e 100644 --- a/juju/jasyncio.py +++ b/juju/jasyncio.py @@ -13,17 +13,38 @@ import functools import logging import signal - -import websockets - -ROOT_LOGGER = logging.getLogger() - from asyncio import ( CancelledError, create_task, wait, + Event as Event, TimeoutError as TimeoutError, Queue as Queue, ensure_future as ensure_future, + gather as gather, + sleep as sleep, + wait_for as wait_for, + create_subprocess_exec as create_subprocess_exec, + subprocess as subprocess, + + FIRST_COMPLETED as FIRST_COMPLETED, + Lock as Lock, + as_completed as as_completed, + new_event_loop as new_event_loop, + + get_event_loop_policy as get_event_loop_policy, + get_running_loop as + get_running_loop, + ALL_COMPLETED as + ALL_COMPLETED, + all_tasks as + all_tasks, + current_task as + current_task, + shield as shield, ) +import websockets + +ROOT_LOGGER = logging.getLogger() + def create_task_with_handler(coro, task_name, logger=ROOT_LOGGER): """Wrapper around "asyncio.create_task" to make sure the task @@ -68,7 +89,7 @@ class SingletonEventLoop: def __new__(cls): if not hasattr(cls, "instance"): - cls.instance = super(SingletonEventLoop, cls).__new__(cls) + cls.instance = super().__new__(cls) cls.instance.loop = asyncio.new_event_loop() return cls.instance diff --git a/juju/loop.py b/juju/loop.py index 560c825dc..bed54a11d 100644 --- a/juju/loop.py +++ b/juju/loop.py @@ -5,4 +5,8 @@ import warnings -warnings.warn("juju.loop module is being deprecated by 3.0, use juju.jasyncio instead") +warnings.warn( + "juju.loop module is being deprecated by 3.0, use juju.jasyncio instead", + DeprecationWarning, + stacklevel=1, +) diff --git a/juju/machine.py b/juju/machine.py index 3ac75394b..70b7327bd 100644 --- a/juju/machine.py +++ b/juju/machine.py @@ -274,12 +274,14 @@ def dns_name(self): May return None if no suitable address is found. """ - ordered_addresses = [] ordered_scopes = ["public", "local-cloud", "local-fan"] - for scope in ordered_scopes: - for address in self.addresses: - if scope == address["scope"]: - ordered_addresses.append(address) + ordered_addresses = [ + address + for scope in ordered_scopes + for address in self.addresses + if scope == address["scope"] + ] + for address in ordered_addresses: scope = address["scope"] for check_scope in ordered_scopes: diff --git a/juju/model.py b/juju/model.py index 404d3ee8f..1190b86af 100644 --- a/juju/model.py +++ b/juju/model.py @@ -1,5 +1,6 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. +from __future__ import annotations import base64 import collections @@ -87,23 +88,16 @@ def cares_about(self, delta): called) for a this delta. """ - if ( - self.entity_id - and delta.get_id() - and not re.match(self.entity_id, str(delta.get_id())) - ): - return False - - if self.entity_type and self.entity_type != delta.entity: - return False - - if self.action and self.action != delta.type: - return False - - if self.predicate and not self.predicate(delta): - return False - - return True + return not ( + ( + self.entity_id + and delta.get_id() + and not re.match(self.entity_id, str(delta.get_id())) + ) + or (self.entity_type and self.entity_type != delta.entity) + or (self.action and self.action != delta.type) + or (self.predicate and not self.predicate(delta)) + ) class ModelObserver: @@ -788,7 +782,7 @@ async def watch_received_waiter(): # If _all_watcher is done before the _watch_received, then we should see # (and raise) an exception coming from the _all_watcher # Otherwise (i.e. _watch_received is set), then we're good to go - done, pending = await jasyncio.wait( + done, _pending = await jasyncio.wait( [waiter, self._watcher_task], return_when=jasyncio.FIRST_COMPLETED ) if self._watcher_task in done: @@ -844,7 +838,8 @@ async def add_local_charm_dir(self, charm_dir, series): if charm_dir.suffix == ".charm": fn = charm_dir else: - fn = tempfile.NamedTemporaryFile().name + # FIXME this is probably a bug, the file is never removed + fn = tempfile.NamedTemporaryFile().name # noqa: SIM115 CharmArchiveGenerator(str(charm_dir)).make_archive(fn) with open(str(fn), "rb") as fh: func = partial(self.add_local_charm, fh, series, os.stat(str(fn)).st_size) @@ -1406,7 +1401,9 @@ async def set_annotations(self, annotations): """ return await _set_annotations(self.tag, annotations, self.connection()) - async def add_machine(self, spec=None, constraints=None, disks=None, series=None): + async def add_machine( + self, spec: str | None = None, constraints=None, disks=None, series=None + ): """Start a new, empty machine and optionally a container, or add a container to a machine. @@ -1472,13 +1469,13 @@ async def add_machine(self, spec=None, constraints=None, disks=None, series=None placement, target, private_key_path = spec.split(":") user, host = target.split("@") - sshProvisioner = provisioner.SSHProvisioner( + prov = provisioner.SSHProvisioner( host=host, user=user, private_key_path=private_key_path, ) - params = sshProvisioner.provision_machine() + params = prov.provision_machine() else: placement = parse_placement(spec) if placement: @@ -1503,15 +1500,14 @@ async def add_machine(self, spec=None, constraints=None, disks=None, series=None raise ValueError("Error adding machine: %s" % error.message) machine_id = results.machines[0].machine - if spec: - if spec.startswith("ssh:"): - # Need to run this after AddMachines has been called, - # as we need the machine_id - await sshProvisioner.install_agent( - self.connection(), - params.nonce, - machine_id, - ) + if spec and spec.startswith("ssh:"): + # Need to run this after AddMachines has been called, + # as we need the machine_id + await prov.install_agent( + self.connection(), + params.nonce, + machine_id, + ) log.debug("Added new machine %s", machine_id) return await self._wait_for_new("machine", machine_id) @@ -2057,16 +2053,17 @@ async def _add_charmhub_resources( charm_facade = client.CharmsFacade.from_connection(self.connection()) res = await charm_facade.CharmInfo(entity_url) - resources = [] - for resource in res.meta.resources.values(): - resources.append({ + resources = [ + { "description": resource.description, "name": resource.name, "path": resource.path, "type_": resource.type_, "origin": "store", "revision": -1, - }) + } + for resource in res.meta.resources.values() + ] if overrides: names = {r["name"] for r in resources} @@ -2393,7 +2390,7 @@ async def get_constraints(self): # set. if result.constraints: constraint_types = [ - a for a in dir(result.constraints) if a in client.Value._toSchema.keys() + a for a in dir(result.constraints) if a in client.Value._toSchema ] for constraint in constraint_types: value = getattr(result.constraints, constraint) @@ -2454,7 +2451,7 @@ async def remove_ssh_key(self, user, key): """ key_facade = client.KeyManagerFacade.from_connection(self.connection()) key = base64.b64decode(bytes(key.strip().split()[1].encode("ascii"))) - key = hashlib.md5(key).hexdigest() + key = hashlib.md5(key).hexdigest() # noqa: S324 key = ":".join(a + b for a, b in zip(key[::2], key[1::2])) await key_facade.DeleteKeys(ssh_keys=[key], user=user) @@ -2780,8 +2777,8 @@ async def add_secret(self, name, data_args, file="", info=""): if client.SecretsFacade.best_facade_version(self.connection()) < 2: raise JujuNotSupportedError("user secrets") - secretsFacade = client.SecretsFacade.from_connection(self.connection()) - results = await secretsFacade.CreateSecrets([ + secrets_facade = client.SecretsFacade.from_connection(self.connection()) + results = await secrets_facade.CreateSecrets([ { "content": {"data": data}, "description": info, @@ -2815,8 +2812,8 @@ async def update_secret(self, name, data_args=[], new_name="", file="", info="") if client.SecretsFacade.best_facade_version(self.connection()) < 2: raise JujuNotSupportedError("user secrets") - secretsFacade = client.SecretsFacade.from_connection(self.connection()) - results = await secretsFacade.UpdateSecrets([ + secrets_facade = client.SecretsFacade.from_connection(self.connection()) + results = await secrets_facade.UpdateSecrets([ { "content": {"data": data}, "description": info, @@ -2830,7 +2827,7 @@ async def update_secret(self, name, data_args=[], new_name="", file="", info="") if result_error.error is not None: raise JujuAPIError(result_error.error) - async def list_secrets(self, filter=None, show_secrets=False): + async def list_secrets(self, filter=None, show_secrets=False): # noqa: A002 """Returns the list of available secrets.""" facade = client.SecretsFacade.from_connection(self.connection()) results = await facade.ListSecrets( @@ -2853,8 +2850,8 @@ async def remove_secret(self, secret_name, revision=-1): if revision >= 0: remove_secret_arg["revisions"] = [revision] - secretsFacade = client.SecretsFacade.from_connection(self.connection()) - results = await secretsFacade.RemoveSecrets([remove_secret_arg]) + secrets_facade = client.SecretsFacade.from_connection(self.connection()) + results = await secrets_facade.RemoveSecrets([remove_secret_arg]) if len(results.results) != 1: raise JujuAPIError(f"expected 1 result, got {len(results.results)}") result_error = results.results[0] @@ -2870,9 +2867,9 @@ async def grant_secret(self, secret_name, application, *applications): """ if client.SecretsFacade.best_facade_version(self.connection()) < 2: raise JujuNotSupportedError("user secrets") - secretsFacade = client.SecretsFacade.from_connection(self.connection()) - results = await secretsFacade.GrantSecret( - applications=[application] + list(applications), label=secret_name + secrets_facade = client.SecretsFacade.from_connection(self.connection()) + results = await secrets_facade.GrantSecret( + applications=[application, *applications], label=secret_name ) if len(results.results) != 1: raise JujuAPIError(f"expected 1 result, got {len(results.results)}") @@ -2891,9 +2888,9 @@ async def revoke_secret(self, secret_name, application, *applications): """ if client.SecretsFacade.best_facade_version(self.connection()) < 2: raise JujuNotSupportedError("user secrets") - secretsFacade = client.SecretsFacade.from_connection(self.connection()) - results = await secretsFacade.RevokeSecret( - applications=[application] + list(applications), label=secret_name + secrets_facade = client.SecretsFacade.from_connection(self.connection()) + results = await secrets_facade.RevokeSecret( + applications=[application, *applications], label=secret_name ) if len(results.results) != 1: raise JujuAPIError(f"expected 1 result, got {len(results.results)}") @@ -2972,7 +2969,9 @@ async def wait_for_idle( """ if wait_for_active: warnings.warn( - "wait_for_active is deprecated; use status", DeprecationWarning + "wait_for_active is deprecated; use status", + DeprecationWarning, + stacklevel=1, ) status = "active" @@ -3138,29 +3137,25 @@ def _create_consume_args(offer, macaroon, controller_info): @param controller_info: takes a controller information and serialises it into a valid type. """ - endpoints = [] - for ep in offer.endpoints: - endpoints.append( - client.RemoteEndpoint( - interface=ep.interface, limit=ep.limit, name=ep.name, role=ep.role - ) + endpoints = [ + client.RemoteEndpoint( + interface=ep.interface, limit=ep.limit, name=ep.name, role=ep.role ) - users = [] - for u in offer.users: - users.append( - client.OfferUserDetails( - access=u.access, display_name=u.display_name, user=u.user - ) + for ep in offer.endpoints + ] + users = [ + client.OfferUserDetails( + access=u.access, display_name=u.display_name, user=u.user ) + for u in offer.users + ] external_controller = client.ExternalControllerInfo( addrs=controller_info.addrs, ca_cert=controller_info.ca_cert, controller_alias=controller_info.controller_alias, controller_tag=controller_info.controller_tag, ) - caveats = [] - for c in macaroon.unknown_fields["caveats"]: - caveats.append(Caveat(cid=c["cid"])) + caveats = [Caveat(cid=c["cid"]) for c in macaroon.unknown_fields["caveats"]] macaroon = Macaroon( signature=macaroon.unknown_fields["signature"], caveats=caveats, diff --git a/juju/origin.py b/juju/origin.py index 31c97fa90..6d87ef627 100644 --- a/juju/origin.py +++ b/juju/origin.py @@ -126,7 +126,7 @@ def compute_base_channel(self, series): _ch = [self.risk] tr = utils.get_series_version(series) if tr: - _ch = [tr] + _ch + _ch = [tr, *_ch] return "/".join(_ch) diff --git a/juju/provisioner.py b/juju/provisioner.py index 32d092ccf..9f034234a 100644 --- a/juju/provisioner.py +++ b/juju/provisioner.py @@ -1,5 +1,6 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. +from __future__ import annotations import os import re @@ -22,10 +23,10 @@ ] -def normalize_arch(rawArch): +def normalize_arch(raw_arch): """Normalize the architecture string.""" for arch in arches: - if arch[0].match(rawArch): + if arch[0].match(raw_arch): return arch[1] @@ -70,7 +71,7 @@ def __init__(self, user, host, private_key_path): self.user = user self.private_key_path = private_key_path - def _get_ssh_client(self, host, user, key): + def _get_ssh_client(self, host: str, user: str, key: str) -> paramiko.SSHClient: """Return a connected Paramiko ssh object. :param str host: The host to connect to. @@ -82,7 +83,8 @@ def _get_ssh_client(self, host, user, key): connection failed """ ssh = paramiko.SSHClient() - ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + # Ruff warns about insecure policy of automatically accepting unknown keys + ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # noqa: S507 pkey = None @@ -116,7 +118,9 @@ def _get_ssh_client(self, host, user, key): return ssh - def _run_command(self, ssh, cmd, pty=True): + def _run_command( + self, ssh: paramiko.SSHClient, cmd: str | list[str], pty: bool = True + ) -> tuple[str, str]: """Run a command remotely via SSH. :param object ssh: The SSHClient @@ -130,11 +134,12 @@ def _run_command(self, ssh, cmd, pty=True): if isinstance(cmd, str): cmd = shlex.split(cmd) - if type(cmd) is not list: - cmd = [cmd] + if isinstance(cmd, str): + cmds = cmd + else: + cmds = " ".join(cmd) - cmds = " ".join(cmd) - stdin, stdout, stderr = ssh.exec_command(cmds, get_pty=pty) + _stdin, stdout, stderr = ssh.exec_command(cmds, get_pty=pty) retcode = stdout.channel.recv_exit_status() if retcode > 0: @@ -160,7 +165,7 @@ def _init_ubuntu_user(self): self.user, self.private_key_path, ) - stdout, stderr = self._run_command(ssh, "sudo -n true", pty=False) + _stdout, _stderr = self._run_command(ssh, "sudo -n true", pty=False) except paramiko.ssh_exception.AuthenticationException as e: raise e finally: @@ -209,7 +214,7 @@ def _detect_hardware_and_os(self, ssh): "mem": "", } - stdout, stderr = self._run_command( + stdout, _stderr = self._run_command( ssh, ["sudo", "/bin/bash -c " + shlex.quote(DETECTION_SCRIPT)], pty=True, @@ -219,10 +224,10 @@ def _detect_hardware_and_os(self, ssh): info["series"] = lines[0].strip() info["arch"] = normalize_arch(lines[1].strip()) - memKb = re.split(r"\s+", lines[2])[1] + mem_kb = re.split(r"\s+", lines[2])[1] - # Convert megabytes -> kilobytes - info["mem"] = round(int(memKb) / 1024) + # Convert to MB + info["mem"] = int(mem_kb) // 1024 # Detect available CPUs recorded = {} @@ -257,10 +262,7 @@ def provision_machine(self): hw = self._detect_hardware_and_os(ssh) params.series = hw["series"] params.instance_id = f"manual:{self.host}" - params.nonce = "manual:{}:{}".format( - self.host, - str(uuid.uuid4()), # a nop for Juju w/manual machines - ) + params.nonce = f"manual:{self.host}:{uuid.uuid4()}" params.hardware_characteristics = { "arch": hw["arch"], "mem": int(hw["mem"]), diff --git a/pyproject.toml b/pyproject.toml index 0b320c630..5755b181f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -105,13 +105,21 @@ ignore = [ # FIXME: manually rewrite docstring headlines to git on one line "D400", "D401", + # Some arguments are not documented + "D417", # FIXME: run `uvx docformatter` to reformat docstrings # Manual fixes are needed for string literals and f-strings "E501", # FIXME: there are some mixedCase members "N815", + # Existing exception classes are part of the API, cannot rename now + "N818", # try-except in a loop; hardly an issue in async functions "PERF203", + # assert + "S101", + # subprocess module + "S404", # FIXME: validate that we use yaml safely "S506", # FIXME: try/except: pass is OK From a8640247ae8dbc1aef4546da20c35c0e1d1f51e7 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Wed, 13 Nov 2024 15:00:50 +0900 Subject: [PATCH 15/34] chore: fix k8s proxy; re-export in jasyncio --- juju/client/proxy/kubernetes/proxy.py | 17 +++--- juju/controller.py | 10 ++-- juju/jasyncio.py | 76 ++++++++++++++++++++------- 3 files changed, 71 insertions(+), 32 deletions(-) diff --git a/juju/client/proxy/kubernetes/proxy.py b/juju/client/proxy/kubernetes/proxy.py index 681c73cef..3d4153b13 100644 --- a/juju/client/proxy/kubernetes/proxy.py +++ b/juju/client/proxy/kubernetes/proxy.py @@ -1,7 +1,6 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. import logging -import os import tempfile from kubernetes import client @@ -36,11 +35,15 @@ def __init__( except ValueError: raise ValueError(f"Invalid port number: {remote_port}") + self.port_forwarder = None + if ca_cert: - self.temp_ca_file = tempfile.NamedTemporaryFile(delete=False) + self.temp_ca_file = tempfile.NamedTemporaryFile() # noqa: SIM115 self.temp_ca_file.write(bytes(ca_cert, "utf-8")) self.temp_ca_file.flush() config.ssl_ca_cert = self.temp_ca_file.name + else: + self.temp_ca_file = None self.api_client = client.ApiClient(config) @@ -64,15 +67,13 @@ def connect(self): def __del__(self): self.close() - try: - os.unlink(self.temp_ca_file.name) - except FileNotFoundError: - log.debug(f"file {self.temp_ca_file.name} not found") def close(self): try: - self.port_forwarder.close() - self.temp_ca_file.close() + if self.port_forwarder: + self.port_forwarder.close() + if self.temp_ca_file: + self.temp_ca_file.close() except AttributeError: pass diff --git a/juju/controller.py b/juju/controller.py index 64b4035cf..c5b077daa 100644 --- a/juju/controller.py +++ b/juju/controller.py @@ -397,7 +397,7 @@ async def destroy_models( """ uuids = await self.model_uuids() - models = [uuids[model] if model in uuids else model for model in models] + models = [uuids.get(model) or model for model in models] model_facade = client.ModelManagerFacade.from_connection(self.connection()) @@ -574,7 +574,7 @@ async def get_models(self, all=False, username=None): # noqa: A002 """ return await self.list_models(username, all) - async def model_uuids(self, username=None, all=False): + async def model_uuids(self, username=None, all=False): # noqa: A002 """Return a mapping of model names to UUIDs the given user can access. :param str username: Optional username argument, defaults to @@ -599,7 +599,7 @@ async def model_uuids(self, username=None, all=False): model_summary.name: model_summary.uuid for model_summary in model_summaries } - async def list_models(self, username=None, all=False): + async def list_models(self, username=None, all=False): # noqa: A002 """Return list of names of the available models on this controller. Equivalent to ``sorted((await self.model_uuids()).keys())`` @@ -885,7 +885,7 @@ async def _watcher(stop_event): jasyncio.ensure_future(_watcher(stop_event)) return stop_event - async def add_secret_backends(self, id, name, backend_type, config): + async def add_secret_backends(self, id_, name, backend_type, config): """Add a new secret backend. Parameters @@ -907,7 +907,7 @@ async def add_secret_backends(self, id, name, backend_type, config): facade = client.SecretBackendsFacade.from_connection(self.connection()) return await facade.AddSecretBackends([ { - "id": id, + "id": id_, "backend-type": backend_type, "config": config, "name": name, diff --git a/juju/jasyncio.py b/juju/jasyncio.py index c77827f6e..3590e9390 100644 --- a/juju/jasyncio.py +++ b/juju/jasyncio.py @@ -13,33 +13,71 @@ import functools import logging import signal +from asyncio import ( + ALL_COMPLETED as ALL_COMPLETED, +) +from asyncio import ( + FIRST_COMPLETED as FIRST_COMPLETED, +) from asyncio import ( CancelledError, create_task, wait, - Event as Event, TimeoutError as TimeoutError, Queue as Queue, ensure_future as ensure_future, - gather as gather, - sleep as sleep, - wait_for as wait_for, - create_subprocess_exec as create_subprocess_exec, - subprocess as subprocess, - - FIRST_COMPLETED as FIRST_COMPLETED, - Lock as Lock, - as_completed as as_completed, - new_event_loop as new_event_loop, +) +# FIXME: integration tests don't use these, but some are used in this repo +# Use primitives from asyncio within this repo and remove these re-exports +from asyncio import ( + Event as Event, +) +from asyncio import ( + Lock as Lock, +) +from asyncio import ( + Queue as Queue, +) +from asyncio import ( + TimeoutError as TimeoutError, # noqa: A004 +) +from asyncio import ( + all_tasks as all_tasks, +) +from asyncio import ( + as_completed as as_completed, +) +from asyncio import ( + create_subprocess_exec as create_subprocess_exec, +) +from asyncio import ( + current_task as current_task, +) +from asyncio import ( + ensure_future as ensure_future, +) +from asyncio import ( + gather as gather, +) +from asyncio import ( get_event_loop_policy as get_event_loop_policy, - get_running_loop as - get_running_loop, - ALL_COMPLETED as - ALL_COMPLETED, - all_tasks as - all_tasks, - current_task as - current_task, +) +from asyncio import ( + get_running_loop as get_running_loop, +) +from asyncio import ( + new_event_loop as new_event_loop, +) +from asyncio import ( shield as shield, ) +from asyncio import ( + sleep as sleep, +) +from asyncio import ( + subprocess as subprocess, +) +from asyncio import ( + wait_for as wait_for, +) import websockets From f5465389636b0407b1543e5ead9cef44ccd4cbc8 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Wed, 13 Nov 2024 15:39:57 +0900 Subject: [PATCH 16/34] chore: fix up the codegen --- juju/client/_client11.py | 10 ------ juju/client/_client12.py | 9 ----- juju/client/_client3.py | 3 -- juju/client/_client4.py | 3 -- juju/client/_client5.py | 1 - juju/client/_client7.py | 1 - juju/client/facade.py | 72 ++++++++++++++++++++-------------------- juju/client/jujudata.py | 2 +- juju/client/overrides.py | 10 +++--- juju/model.py | 1 + 10 files changed, 44 insertions(+), 68 deletions(-) diff --git a/juju/client/_client11.py b/juju/client/_client11.py index 9fa3fae84..b40610fe0 100644 --- a/juju/client/_client11.py +++ b/juju/client/_client11.py @@ -874,7 +874,6 @@ async def AllModels(self): """AllModels allows controller administrators to get the list of all the models in the controller. - Returns -> UserModelList """ # map input types to rpc msg @@ -971,7 +970,6 @@ async def ControllerVersion(self): NOTE: the implementation intentionally does not check for SuperuserAccess as the Version is known even to users with login access. - Returns -> ControllerVersionResults """ # map input types to rpc msg @@ -988,7 +986,6 @@ async def DashboardConnectionInfo(self): """DashboardConnectionInfo returns the connection information for a client to connect to the Juju Dashboard including any proxying information. - Returns -> DashboardConnectionInfo """ # map input types to rpc msg @@ -1105,7 +1102,6 @@ async def HostedModelConfigs(self): order to connect directly with the host model's provider and destroy it directly. - Returns -> HostedModelConfigsResults """ # map input types to rpc msg @@ -1126,7 +1122,6 @@ async def IdentityProviderURL(self): NOTE: the implementation intentionally does not check for SuperuserAccess as the URL is known even to users with login access. - Returns -> StringResult """ # map input types to rpc msg @@ -1165,7 +1160,6 @@ async def ListBlockedModels(self): name, then owner. Callers must be controller administrators to retrieve the list. - Returns -> ModelBlockInfoList """ # map input types to rpc msg @@ -1183,7 +1177,6 @@ async def ModelConfig(self): model. For information on the current model, use client.ModelGet - Returns -> ModelConfigResults """ # map input types to rpc msg @@ -1276,7 +1269,6 @@ async def WatchAllModelSummaries(self): This method is superuser access only, and watches all models in the controller. - Returns -> SummaryWatcherID """ # map input types to rpc msg @@ -1297,7 +1289,6 @@ async def WatchAllModels(self): controller. The returned AllWatcherId should be used with Next on the AllModelWatcher endpoint to receive deltas. - Returns -> AllWatcherId """ # map input types to rpc msg @@ -1338,7 +1329,6 @@ async def WatchModelSummaries(self): """WatchModelSummaries starts watching the summary updates from the cache. Only models that the user has access to are returned. - Returns -> SummaryWatcherID """ # map input types to rpc msg diff --git a/juju/client/_client12.py b/juju/client/_client12.py index d53884bd0..28d06adfe 100644 --- a/juju/client/_client12.py +++ b/juju/client/_client12.py @@ -843,7 +843,6 @@ async def AllModels(self): """AllModels allows controller administrators to get the list of all the models in the controller. - Returns -> UserModelList """ # map input types to rpc msg @@ -940,7 +939,6 @@ async def ControllerVersion(self): NOTE: the implementation intentionally does not check for SuperuserAccess as the Version is known even to users with login access. - Returns -> ControllerVersionResults """ # map input types to rpc msg @@ -957,7 +955,6 @@ async def DashboardConnectionInfo(self): """DashboardConnectionInfo returns the connection information for a client to connect to the Juju Dashboard including any proxying information. - Returns -> DashboardConnectionInfo """ # map input types to rpc msg @@ -1074,7 +1071,6 @@ async def HostedModelConfigs(self): order to connect directly with the host model's provider and destroy it directly. - Returns -> HostedModelConfigsResults """ # map input types to rpc msg @@ -1095,7 +1091,6 @@ async def IdentityProviderURL(self): NOTE: the implementation intentionally does not check for SuperuserAccess as the URL is known even to users with login access. - Returns -> StringResult """ # map input types to rpc msg @@ -1134,7 +1129,6 @@ async def ListBlockedModels(self): name, then owner. Callers must be controller administrators to retrieve the list. - Returns -> ModelBlockInfoList """ # map input types to rpc msg @@ -1229,7 +1223,6 @@ async def WatchAllModelSummaries(self): This method is superuser access only, and watches all models in the controller. - Returns -> SummaryWatcherID """ # map input types to rpc msg @@ -1250,7 +1243,6 @@ async def WatchAllModels(self): controller. The returned AllWatcherId should be used with Next on the AllModelWatcher endpoint to receive deltas. - Returns -> AllWatcherId """ # map input types to rpc msg @@ -1291,7 +1283,6 @@ async def WatchModelSummaries(self): """WatchModelSummaries starts watching the summary updates from the cache. Only models that the user has access to are returned. - Returns -> SummaryWatcherID """ # map input types to rpc msg diff --git a/juju/client/_client3.py b/juju/client/_client3.py index 68152f5f6..b3e8ad3d5 100644 --- a/juju/client/_client3.py +++ b/juju/client/_client3.py @@ -257,7 +257,6 @@ async def RedirectInfo(self): In Juju it always returns an error because the Juju controller does not multiplex controllers. - Returns -> RedirectInfoResult """ # map input types to rpc msg @@ -314,7 +313,6 @@ async def Next(self): """Next will return the current state of everything on the first call and subsequent calls will - Returns -> AllWatcherNextResults """ # map input types to rpc msg @@ -683,7 +681,6 @@ async def ModelGet(self): """ModelGet implements the server-side part of the model-config CLI command. - Returns -> ModelConfigResults """ # map input types to rpc msg diff --git a/juju/client/_client4.py b/juju/client/_client4.py index e66612aea..7cb415b99 100644 --- a/juju/client/_client4.py +++ b/juju/client/_client4.py @@ -51,7 +51,6 @@ async def Next(self): """Next will return the current state of everything on the first call and subsequent calls will - Returns -> AllWatcherNextResults """ # map input types to rpc msg @@ -1557,7 +1556,6 @@ async def ModelCredentialForSSH(self): """ModelCredentialForSSH returns a cloud spec for ssh purpose. This facade call is only used for k8s model. - Returns -> CloudSpecResult """ # map input types to rpc msg @@ -1596,7 +1594,6 @@ async def Proxy(self): """Proxy returns whether SSH connections should be proxied through the controller hosts for the model associated with the API connection. - Returns -> SSHProxyResult """ # map input types to rpc msg diff --git a/juju/client/_client5.py b/juju/client/_client5.py index e99362844..418732912 100644 --- a/juju/client/_client5.py +++ b/juju/client/_client5.py @@ -912,7 +912,6 @@ async def AllZones(self): zone is unusable, unavailable, or deprecated the Available field will be false. - Returns -> ZoneResults """ # map input types to rpc msg diff --git a/juju/client/_client7.py b/juju/client/_client7.py index f181971a9..c5790ab45 100644 --- a/juju/client/_client7.py +++ b/juju/client/_client7.py @@ -3465,7 +3465,6 @@ async def Clouds(self): """Clouds returns the definitions of all clouds supported by the controller that the logged in user can see. - Returns -> CloudsResult """ # map input types to rpc msg diff --git a/juju/client/facade.py b/juju/client/facade.py index 7eb92ec15..5017f4e09 100644 --- a/juju/client/facade.py +++ b/juju/client/facade.py @@ -149,7 +149,7 @@ def __init__(self, schema): def get(self, name): # Two way mapping - refname = self.schema.referenceName(name) + refname = self.schema.reference_name(name) if refname not in self: result = typing.TypeVar(refname) self[refname] = result @@ -293,9 +293,7 @@ def _format(self, name, rtype, typed=True): def _get_arg_str(self, typed=False, joined=", "): if self: - parts = [] - for item in self: - parts.append(self._format(item[0], item[1], typed)) + parts = [self._format(item[0], item[1], typed) for item in self] if joined: return joined.join(parts) return parts @@ -320,7 +318,7 @@ def as_validation(self): var_name = name_to_py(item[0]) var_type, var_sub_type, ok = kind_to_py(item[1]) if ok: - parts.append(buildValidation(var_name, var_type, var_sub_type)) + parts.append(build_validation(var_name, var_type, var_sub_type)) return "\n".join(parts) def typed(self): @@ -333,7 +331,7 @@ def get_doc(self): return self._get_arg_str(True, "\n") -def buildValidation(name, instance_type, instance_sub_type, ident=None): +def build_validation(name, instance_type, instance_sub_type, ident=None): INDENT = ident or " " source = f"""{INDENT}if {name} is not None and not isinstance({name}, {instance_sub_type}): {INDENT} raise Exception("Expected {name} to be a {instance_type}, received: {{}}".format(type({name}))) @@ -341,7 +339,7 @@ def buildValidation(name, instance_type, instance_sub_type, ident=None): return source -def buildTypes(schema, capture): +def build_types(schema, capture): INDENT = " " for kind in sorted( (k for k in schema.types if not isinstance(k, str)), key=lambda x: str(x) @@ -427,7 +425,7 @@ def __init__(self{}{}, **unknown_fields): if ok: source.append( "{}".format( - buildValidation( + build_validation( arg_name, arg_type, arg_sub_type, ident=INDENT * 2 ) ) @@ -503,7 +501,7 @@ async def wrapper(*args, **kwargs): return decorator -def makeFunc(cls, name, description, params, result, _async=True): +def make_func(cls, name, description, params, result, _async=True): INDENT = " " args = Args(cls.schema, params) assignments = [] @@ -534,8 +532,10 @@ def makeFunc(cls, name, description, params, result, _async=True): """ if description != "": - description = f"{description}\n\n" - doc_string = f"{description}{args.get_doc()}" + description = f"{description}\n" + if args_doc := args.get_doc(): + args_doc = f"\n{args_doc}" + doc_string = f"{description}{args_doc}" fsource = source.format( _async="async " if _async else "", name=name, @@ -555,7 +555,7 @@ def makeFunc(cls, name, description, params, result, _async=True): return func, fsource -def makeRPCFunc(cls): +def make_rpc_func(cls): source = """ async def rpc(self, msg): @@ -577,15 +577,15 @@ async def rpc(self, msg): return func, source -def buildMethods(cls, capture): +def build_methods(cls, capture): properties = cls.schema["properties"] for methodname in sorted(properties): - method, source = _buildMethod(cls, methodname) + method, source = _build_method(cls, methodname) setattr(cls, methodname, method) capture[f"{cls.__name__}Facade"].write(source, depth=1) -def _buildMethod(cls, name): +def _build_method(cls, name): params = None result = None method = cls.schema["properties"][name] @@ -603,18 +603,18 @@ def _buildMethod(cls, name): result = cls.schema.types.get(spec["$ref"]) else: result = SCHEMA_TO_PYTHON[spec["type"]] - return makeFunc(cls, name, description, params, result) + return make_func(cls, name, description, params, result) -def buildWatcherRPCMethods(cls, capture): +def build_watcher_methods(cls, capture): properties = cls.schema["properties"] if "Next" in properties and "Stop" in properties: - method, source = makeRPCFunc(cls) + method, source = make_rpc_func(cls) cls.rpc = method capture[f"{cls.__name__}Facade"].write(source, depth=1) -def buildFacade(schema): +def build_facade(schema): cls = type( schema.name, (Type,), @@ -749,12 +749,12 @@ def __init__(self, schema): self.registry = KindRegistry() self.types = TypeRegistry(self) - def referenceName(self, ref): + def reference_name(self, ref): if ref.startswith("#/definitions/"): ref = ref.rsplit("/", 1)[-1] return ref - def buildDefinitions(self): + def build_definitions(self): # here we are building the types out # anything in definitions is a type # but these may contain references themselves @@ -771,11 +771,11 @@ def buildDefinitions(self): continue definitions[d] = data for d, definition in definitions.items(): - node = self.buildObject(definition, d) + node = self.build_object(definition, d) self.registry.register(d, self.version, node) self.types.getRefType(d) - def buildObject(self, node, name=None): + def build_object(self, node, name=None): # we don't need to build types recursively here # they are all in definitions already # we only want to include the type reference @@ -794,9 +794,9 @@ def buildObject(self, node, name=None): else: kind = prop["type"] if kind == "array": - add((p, self.buildArray(prop))) + add((p, self.build_array(prop))) elif kind == "object": - struct.extend(self.buildObject(prop, p)) + struct.extend(self.build_object(prop, p)) else: add((p, self.types.objType(prop))) if pprops: @@ -810,7 +810,7 @@ def buildObject(self, node, name=None): return struct ppkind = pprop["type"] if ppkind == "array": - add((name, Mapping[str, self.buildArray(pprop)])) + add((name, Mapping[str, self.build_array(pprop)])) else: add((name, Mapping[str, SCHEMA_TO_PYTHON[ppkind]])) @@ -819,7 +819,7 @@ def buildObject(self, node, name=None): return struct - def buildArray(self, obj): + def build_array(self, obj): # return a sequence from an array in the schema if "$ref" in obj: return Sequence[self.types.refType(obj)] @@ -827,7 +827,7 @@ def buildArray(self, obj): kind = obj.get("type") if kind and kind == "array": items = obj["items"] - return self.buildArray(items) + return self.build_array(items) else: return Sequence[self.types.objType(obj)] @@ -854,7 +854,7 @@ def write_facades(captures, options): f.write(HEADER) f.write("from juju.client.facade import Type, ReturnMapping\n") f.write("from juju.client._definitions import *\n\n") - for key in sorted([k for k in captures[version].keys() if "Facade" in k]): + for key in sorted([k for k in captures[version] if "Facade" in k]): print(captures[version][key], file=f) # Return the last (most recent) version for use in other routines. @@ -871,7 +871,7 @@ def write_definitions(captures, options): with open(f"{options.output_dir}/_definitions.py", "w") as f: f.write(HEADER) f.write("from juju.client.facade import Type, ReturnMapping\n\n") - for key in sorted([k for k in captures.keys() if "Facade" not in k]): + for key in sorted([k for k in captures if "Facade" not in k]): print(captures[key], file=f) @@ -896,7 +896,7 @@ def write_client(captures, options): f.write(LOOKUP_FACADE) f.write(TYPE_FACTORY) - for key in sorted([k for k in factories.keys() if "Facade" in k]): + for key in sorted([k for k in factories if "Facade" in k]): print(factories[key], file=f) @@ -908,13 +908,13 @@ def generate_definitions(schemas): for juju_version in sorted(schemas.keys()): for schema in schemas[juju_version]: - schema.buildDefinitions() + schema.build_definitions() # ensure we write the latest ones first, so that earlier revisions # get dropped. for juju_version in sorted(schemas.keys(), reverse=True): for schema in schemas[juju_version]: - buildTypes(schema, definitions) + build_types(schema, definitions) return definitions @@ -927,7 +927,7 @@ def generate_facades( # Build the Facade classes for juju_version in sorted(schemas.keys(), key=packaging.version.parse): for schema in schemas[juju_version]: - cls, source = buildFacade(schema) + cls, source = build_facade(schema) cls_name = f"{schema.name}Facade" captures[schema.version].clear(cls_name) @@ -936,9 +936,9 @@ def generate_facades( # Make the actual class captures[schema.version][cls_name].write(source) # Build the methods for each Facade class. - buildMethods(cls, captures[schema.version]) + build_methods(cls, captures[schema.version]) # Build the override RPC method if the Facade is a watcher. - buildWatcherRPCMethods(cls, captures[schema.version]) + build_watcher_methods(cls, captures[schema.version]) # Mark this Facade class as being done for this version -- # helps mitigate some excessive looping. CLASSES[schema.name] = cls diff --git a/juju/client/jujudata.py b/juju/client/jujudata.py index 80f393bee..5742985b2 100644 --- a/juju/client/jujudata.py +++ b/juju/client/jujudata.py @@ -127,7 +127,7 @@ def load_credential(self, cloud, name=None): if default_credential: name = creds_data["default-credential"] elif len(creds_data) == 1: - name = list(creds_data)[0] + name = next(iter(creds_data)) else: return None, None cred_data = creds_data[name] diff --git a/juju/client/overrides.py b/juju/client/overrides.py index 73f33a120..4b9446a13 100644 --- a/juju/client/overrides.py +++ b/juju/client/overrides.py @@ -61,8 +61,9 @@ def from_json(cls, data): class ResourcesFacade(Type): """Patch parts of ResourcesFacade to make it work.""" + # FIXME: a facade method from codegen can be used instead @ReturnMapping(_client.AddPendingResourcesResult) - async def AddPendingResources( + async def AddPendingResources( # noqa: N802 self, application_tag="", charm_url="", charm_origin=None, resources=None ): """Fix the calling signature of AddPendingResources. @@ -126,8 +127,9 @@ def __init__(self, matches=None, **unknown_fields): for prefix, tags in matches.items(): self.matches[prefix] = [_definitions.Entity.from_json(r) for r in tags] + # FIXME: This seems internal, can be renamed @ReturnMapping(_FindTagsResults) - async def FindActionTagsByPrefix(self, prefixes): + async def FindActionTagsByPrefix(self, prefixes): # noqa: N802 """Prefixes : typing.Sequence[str] Returns -> typing.Sequence[~Entity] """ @@ -142,7 +144,7 @@ async def FindActionTagsByPrefix(self, prefixes): class Number(_definitions.Number): - """This type represents a semver string. + """Represent a semver string. Because it is not standard JSON, the typical from_json parsing fails and the parsing must be handled specially. @@ -236,7 +238,7 @@ def to_json(self): class Binary(_definitions.Binary): - """This type represents a semver string with additional series and arch info. + """Represent a semver string with additional series and arch info. Because it is not standard JSON, the typical from_json parsing fails and the parsing must be handled specially. diff --git a/juju/model.py b/juju/model.py index 1190b86af..207eaf808 100644 --- a/juju/model.py +++ b/juju/model.py @@ -2550,6 +2550,7 @@ async def _wait_for_action_status(): action_results = await action_facade.Actions(entities=entity) return action_results.results[0] + # FIXME: this function seems dead, the facade methods don't seem to exist async def get_action_status(self, uuid_or_prefix=None, name=None): """Get the status of all actions, filtered by ID, ID prefix, or name. From 9b45d8a81e53ad13e62d4488c0aa27f925ab36ed Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Wed, 13 Nov 2024 15:51:47 +0900 Subject: [PATCH 17/34] chore: fix up the codegen --- juju/client/facade.py | 103 ++++++++++++++++++++---------------------- 1 file changed, 50 insertions(+), 53 deletions(-) diff --git a/juju/client/facade.py b/juju/client/facade.py index 5017f4e09..08c7a5242 100644 --- a/juju/client/facade.py +++ b/juju/client/facade.py @@ -135,7 +135,7 @@ def lookup(self, name, version=None): return versions[version] return versions[max(versions)] - def getObj(self, name, version=None): + def get_obj(self, name, version=None): result = self.lookup(name, version) if result: obj = result["object"] @@ -157,10 +157,10 @@ def get(self, name): return self[refname] - def getRefType(self, ref): + def get_ref_type(self, ref): return self.get(ref) - def objType(self, obj): + def obj_type(self, obj): kind = obj.get("type") if not kind: raise ValueError("%s has no type" % obj) @@ -169,8 +169,8 @@ def objType(self, obj): raise ValueError("%s has type %s" % (obj, kind)) return result - def refType(self, obj): - return self.getRefType(obj["$ref"]) + def ref_type(self, obj): + return self.get_ref_type(obj["$ref"]) CLASSES = {} @@ -178,9 +178,8 @@ def refType(self, obj): def booler(v): - if isinstance(v, str): - if v == "false": - return False + if v == "false": + return False return bool(v) @@ -247,7 +246,7 @@ def __init__(self, schema, defs): self.schema = schema self.defs = defs if defs: - rtypes = schema.registry.getObj(schema.types[defs]) + rtypes = schema.registry.get_obj(schema.types[defs]) if len(rtypes) == 1: if not self.do_explode(rtypes[0][1]): for name, rtype in rtypes: @@ -273,15 +272,15 @@ def do_explode(self, kind): self.extend(Args(self.schema, kind)) return True - def PyToSchemaMapping(self): + def py_to_schema_mapping(self): m = {} - for n, rt in self: + for n, _ in self: m[name_to_py(n)] = n return m - def SchemaToPyMapping(self): + def schema_to_py_mapping(self): m = {} - for n, tr in self: + for n, _ in self: m[n] = name_to_py(n) return m @@ -332,15 +331,15 @@ def get_doc(self): def build_validation(name, instance_type, instance_sub_type, ident=None): - INDENT = ident or " " - source = f"""{INDENT}if {name} is not None and not isinstance({name}, {instance_sub_type}): -{INDENT} raise Exception("Expected {name} to be a {instance_type}, received: {{}}".format(type({name}))) + indent = ident or " " + source = f"""{indent}if {name} is not None and not isinstance({name}, {instance_sub_type}): +{indent} raise Exception("Expected {name} to be a {instance_type}, received: {{}}".format(type({name}))) """ return source def build_types(schema, capture): - INDENT = " " + indent = " " for kind in sorted( (k for k in schema.types if not isinstance(k, str)), key=lambda x: str(x) ): @@ -368,16 +367,16 @@ def __init__(self{}{}, **unknown_fields): '''""".format( name, # pprint these to get stable ordering across regens - pprint.pformat(args.PyToSchemaMapping(), width=999), - pprint.pformat(args.SchemaToPyMapping(), width=999), + pprint.pformat(args.py_to_schema_mapping(), width=999), + pprint.pformat(args.schema_to_py_mapping(), width=999), ", " if args else "", args.as_kwargs(), - textwrap.indent(args.get_doc(), INDENT * 2), + textwrap.indent(args.get_doc(), indent * 2), ) ] if not args: - source.append(f"{INDENT * 2}self.unknown_fields = unknown_fields") + source.append(f"{indent * 2}self.unknown_fields = unknown_fields") else: # do the validation first, before setting the variables for arg in args: @@ -385,10 +384,10 @@ def __init__(self{}{}, **unknown_fields): arg_type = arg[1] arg_type_name = strcast(arg_type) if arg_type in basic_types or arg_type is typing.Any: - source.append(f"{INDENT * 2}{arg_name}_ = {arg_name}") + source.append(f"{indent * 2}{arg_name}_ = {arg_name}") elif type(arg_type) is typing.TypeVar: source.append( - f"{INDENT * 2}{arg_name}_ = {arg_type_name}.from_json({arg_name}) if {arg_name} else None" + f"{indent * 2}{arg_name}_ = {arg_type_name}.from_json({arg_name}) if {arg_name} else None" ) elif typing_inspect.is_generic_type(arg_type) and issubclass( typing_inspect.get_origin(arg_type), Sequence @@ -397,10 +396,10 @@ def __init__(self{}{}, **unknown_fields): value_type = parameters[0] if len(parameters) else None if type(value_type) is typing.TypeVar: source.append( - f"{INDENT * 2}{arg_name}_ = [{strcast(value_type)}.from_json(o) for o in {arg_name} or []]" + f"{indent * 2}{arg_name}_ = [{strcast(value_type)}.from_json(o) for o in {arg_name} or []]" ) else: - source.append(f"{INDENT * 2}{arg_name}_ = {arg_name}") + source.append(f"{indent * 2}{arg_name}_ = {arg_name}") elif typing_inspect.is_generic_type(arg_type) and issubclass( typing_inspect.get_origin(arg_type), Mapping ): @@ -408,16 +407,16 @@ def __init__(self{}{}, **unknown_fields): value_type = parameters[0] if len(parameters) else None if type(value_type) is typing.TypeVar: source.append( - f"{INDENT * 2}{arg_name}_ = {{k: {strcast(value_type)}.from_json(v) " + f"{indent * 2}{arg_name}_ = {{k: {strcast(value_type)}.from_json(v) " f"for k, v in ({arg_name} or dict()).items()}}" ) else: - source.append(f"{INDENT * 2}{arg_name}_ = {arg_name}") + source.append(f"{indent * 2}{arg_name}_ = {arg_name}") else: - source.append(f"{INDENT * 2}{arg_name}_ = {arg_name}") + source.append(f"{indent * 2}{arg_name}_ = {arg_name}") if len(args) > 0: source.append( - f"\n{INDENT * 2}# Validate arguments against known Juju API types." + f"\n{indent * 2}# Validate arguments against known Juju API types." ) for arg in args: arg_name = f"{name_to_py(arg[0])}_" @@ -426,17 +425,17 @@ def __init__(self{}{}, **unknown_fields): source.append( "{}".format( build_validation( - arg_name, arg_type, arg_sub_type, ident=INDENT * 2 + arg_name, arg_type, arg_sub_type, ident=indent * 2 ) ) ) for arg in args: arg_name = name_to_py(arg[0]) - source.append(f"{INDENT * 2}self.{arg_name} = {arg_name}_") + source.append(f"{indent * 2}self.{arg_name} = {arg_name}_") # Ensure that we take the kwargs (unknown_fields) and put it on the # Results/Params so we can inspect it. - source.append(f"{INDENT * 2}self.unknown_fields = unknown_fields") + source.append(f"{indent * 2}self.unknown_fields = unknown_fields") source = "\n".join(source) capture.clear(name) @@ -446,7 +445,7 @@ def __init__(self{}{}, **unknown_fields): print(source) co = compile(source, __name__, "exec") ns = _getns(schema) - exec(co, ns) + exec(co, ns) # noqa: S102 cls = ns[name] CLASSES[name] = cls @@ -464,7 +463,7 @@ def retspec(schema, defs): return strcast(defs, False) -def ReturnMapping(cls): +def ReturnMapping(cls): # noqa: N802 # Annotate the method with a return Type # so the value can be cast def decorator(f): @@ -502,12 +501,13 @@ async def wrapper(*args, **kwargs): def make_func(cls, name, description, params, result, _async=True): - INDENT = " " + indent = " " args = Args(cls.schema, params) - assignments = [] - toschema = args.PyToSchemaMapping() - for arg in args._get_arg_str(False, False): - assignments.append(f"{INDENT}_params['{toschema[arg]}'] = {arg}") + toschema = args.py_to_schema_mapping() + assignments = [ + f"{indent}_params['{toschema[arg]}'] = {arg}" + for arg in args._get_arg_str(False, False) + ] assignments = "\n".join(assignments) res = retspec(cls.schema, result) source = """ @@ -544,13 +544,13 @@ def make_func(cls, name, description, params, result, _async=True): res=res, validation=args.as_validation(), rettype=result.__name__ if result else None, - docstring=textwrap.indent(doc_string, INDENT), + docstring=textwrap.indent(doc_string, indent), cls=cls, assignments=assignments, _await="await " if _async else "", ) ns = _getns(cls.schema) - exec(fsource, ns) + exec(fsource, ns) # noqa: S102 func = ns[name] return func, fsource @@ -572,7 +572,7 @@ async def rpc(self, msg): """ ns = _getns(cls.schema) - exec(source, ns) + exec(source, ns) # noqa: S102 func = ns["rpc"] return func, source @@ -671,7 +671,7 @@ def _parse_nested_list_entry(expr, result_dict): # this is a simple entry result_dict[expr] = "" elif isinstance(expr, dict): - for _, v in expr.items(): + for v in expr.values(): _parse_nested_list_entry(v, result_dict) elif isinstance(expr, list): for v in expr: @@ -716,9 +716,6 @@ def to_json(self): def __contains__(self, key): return key in self._toPy - def get(self, key, default=None): - return self[key] if key in self else default - # treat subscript gets as JSON representation def __getitem__(self, key): attr = self._toPy[key] @@ -773,7 +770,7 @@ def build_definitions(self): for d, definition in definitions.items(): node = self.build_object(definition, d) self.registry.register(d, self.version, node) - self.types.getRefType(d) + self.types.get_ref_type(d) def build_object(self, node, name=None): # we don't need to build types recursively here @@ -790,7 +787,7 @@ def build_object(self, node, name=None): for p in sorted(props): prop = props[p] if "$ref" in prop: - add((p, self.types.refType(prop))) + add((p, self.types.ref_type(prop))) else: kind = prop["type"] if kind == "array": @@ -798,7 +795,7 @@ def build_object(self, node, name=None): elif kind == "object": struct.extend(self.build_object(prop, p)) else: - add((p, self.types.objType(prop))) + add((p, self.types.obj_type(prop))) if pprops: if ".*" not in pprops: raise ValueError( @@ -806,7 +803,7 @@ def build_object(self, node, name=None): ) pprop = pprops[".*"] if "$ref" in pprop: - add((name, Mapping[str, self.types.refType(pprop)])) + add((name, Mapping[str, self.types.ref_type(pprop)])) return struct ppkind = pprop["type"] if ppkind == "array": @@ -822,21 +819,21 @@ def build_object(self, node, name=None): def build_array(self, obj): # return a sequence from an array in the schema if "$ref" in obj: - return Sequence[self.types.refType(obj)] + return Sequence[self.types.ref_type(obj)] else: kind = obj.get("type") if kind and kind == "array": items = obj["items"] return self.build_array(items) else: - return Sequence[self.types.objType(obj)] + return Sequence[self.types.obj_type(obj)] def _getns(schema): ns = {"Type": Type, "typing": typing, "ReturnMapping": ReturnMapping} # Copy our types into the globals of the method for facade in schema.registry: - ns[facade] = schema.registry.getObj(facade) + ns[facade] = schema.registry.get_obj(facade) return ns From 50199e2c1e0d3155a96a449cf09d261efd0228af Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Wed, 13 Nov 2024 16:10:18 +0900 Subject: [PATCH 18/34] chore: fix client and connection, disable warnings for the generated code --- juju/client/client.py | 2 +- juju/client/codegen.py | 6 +++--- juju/client/connection.py | 29 +++++++++++++++-------------- juju/client/connector.py | 2 +- pyproject.toml | 17 +++++++++++++++++ 5 files changed, 37 insertions(+), 19 deletions(-) diff --git a/juju/client/client.py b/juju/client/client.py index a06ecb846..e7e073b27 100644 --- a/juju/client/client.py +++ b/juju/client/client.py @@ -32,4 +32,4 @@ if not a.startswith("_"): setattr(c_type, a, getattr(o_type, a)) -from ._client import * # noqa, isort:skip +from ._client import * # noqa: F403,E402, isort:skip diff --git a/juju/client/codegen.py b/juju/client/codegen.py index f8b0a4286..eda73d027 100644 --- a/juju/client/codegen.py +++ b/juju/client/codegen.py @@ -22,10 +22,10 @@ def write(self, msg, depth=0): prefix = self.INDENT * depth msg = indent(msg, prefix) - return super(CodeWriter, self).write(msg) + return super().write(msg) def __str__(self): - return super(CodeWriter, self).getvalue() + return super().getvalue() class Capture(defaultdict): @@ -35,7 +35,7 @@ class Capture(defaultdict): """ def __init__(self, default_factory=CodeWriter, *args, **kwargs): - super(Capture, self).__init__(default_factory, *args, **kwargs) + super().__init__(default_factory, *args, **kwargs) def clear(self, name): """Reset one of the keys in this class, if it exists. diff --git a/juju/client/connection.py b/juju/client/connection.py index ae6a59445..c842311c8 100644 --- a/juju/client/connection.py +++ b/juju/client/connection.py @@ -23,6 +23,7 @@ from .facade_versions import client_facade_versions, known_unsupported_facades +LEVELS = ["TRACE", "DEBUG", "INFO", "WARNING", "ERROR"] log = logging.getLogger("juju.client.connection") @@ -240,7 +241,7 @@ async def connect( if isinstance(endpoint, str) else [(e, cacert) for e in endpoint] ) - lastError = None + last_error = None for _ep in _endpoints: try: if self.is_debug_log_connection: @@ -251,14 +252,14 @@ async def connect( await self._connect_with_redirect([_ep]) return self except ssl.SSLError as e: - lastError = e + last_error = e continue except OSError as e: logging.debug(f"Cannot access endpoint {_ep}: {e.strerror}") - lastError = e + last_error = e continue - if lastError is not None: - raise lastError + if last_error is not None: + raise last_error raise Exception("Unable to connect to websocket") @property @@ -407,7 +408,6 @@ def debug_log_filter_write(self, result): and (included_entities == [] or entity in included_entities) ) - LEVELS = ["TRACE", "DEBUG", "INFO", "WARNING", "ERROR"] log_level = self.debug_log_params["level"] if log_level != "" and log_level not in LEVELS: @@ -595,10 +595,11 @@ async def rpc(self, msg, encoder=None): # Perhaps JujuError should return all the results including # errors, or perhaps a keyword parameter to the rpc method # could be added to trigger this behaviour. - err_results = [] - for res in result["response"]["results"] or []: - if res.get("error", {}).get("message"): - err_results.append(res["error"]["message"]) + err_results = [ + res["error"]["message"] + for res in (result["response"]["results"] or []) + if res.get("error", {}).get("message") + ] if err_results: raise errors.JujuError(err_results) @@ -781,14 +782,14 @@ async def _connect_with_login(self, endpoints): # It's possible that we may get several discharge-required errors, # corresponding to different levels of authentication, so retry # a few times. - for i in range(0, 2): + for _ in range(0, 2): result = (await self.login())["response"] - macaroonJSON = result.get("discharge-required") - if macaroonJSON is None: + macaroon_json = result.get("discharge-required") + if macaroon_json is None: self.info = result success = True return result - macaroon = bakery.Macaroon.from_dict(macaroonJSON) + macaroon = bakery.Macaroon.from_dict(macaroon_json) self.bakery_client.handle_error( httpbakery.Error( code=httpbakery.ERR_DISCHARGE_REQUIRED, diff --git a/juju/client/connector.py b/juju/client/connector.py index d9026b8bc..feb650d8c 100644 --- a/juju/client/connector.py +++ b/juju/client/connector.py @@ -27,7 +27,7 @@ class NoConnectionException(Exception): class Connector: - """This class abstracts out a reconnectable client that can connect + """Abstracts out a reconnectable client that can connect to controllers and models found in the Juju data files. """ diff --git a/pyproject.toml b/pyproject.toml index 5755b181f..6b2fe31e0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -131,7 +131,24 @@ ignore = [ "UP031", ] + [tool.ruff.lint.per-file-ignores] +"juju/client/_*.py" = [ + # Copyright + "CPY001", + # Codegen limitation: empty structs have empty docstrings. + "D419", + # CamelCase + "N802", + # star imports + "F403", + "F405", + # FIXME: undefined FacadeVersions... + # Is the class from _client.py intended? + # How does login even work? + "F821", +] + "tests/*" = [ # assert False to fail "B011", From 5492c30720bc04e00b606abbc8832d5bff08469b Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Wed, 13 Nov 2024 16:46:08 +0900 Subject: [PATCH 19/34] chore: clean pre-commit --- .pre-commit-config.yaml | 3 +++ docs/_extensions/automembersummary.py | 4 ++-- docs/conf.py | 4 ++-- examples/add_k8s.py | 6 +++--- examples/add_secrets_backend.py | 8 ++++---- examples/formatted_status.py | 4 ++-- examples/future.py | 4 +++- examples/livemodel.py | 2 +- examples/machine_hostname.py | 2 -- examples/model.py | 8 +++++--- examples/relate.py | 2 +- examples/scp.py | 2 +- examples/status.py | 2 +- juju/__init__.py | 3 +++ juju/application.py | 29 +++++++++++++-------------- juju/bundle.py | 12 +++++------ juju/charmhub.py | 10 ++++----- juju/client/__init__.py | 3 +++ pyproject.toml | 5 +++++ 19 files changed, 64 insertions(+), 49 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1609e7e0e..5f37f3c57 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,12 +11,15 @@ repos: - id: check-symlinks - id: check-json - id: check-yaml + # Overlays are deliberately multi-doc + exclude: "^tests/integration/bundle/test-overlays/.*multi.*yaml$" - id: check-toml - id: mixed-line-ending - id: end-of-file-fixer exclude: "^juju/client/schemas-juju.*json$" - id: trailing-whitespace - id: detect-private-key + exclude: "^tests/.*$" # Run the Ruff linter. - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.7.3 diff --git a/docs/_extensions/automembersummary.py b/docs/_extensions/automembersummary.py index cc29e8342..65d910d91 100644 --- a/docs/_extensions/automembersummary.py +++ b/docs/_extensions/automembersummary.py @@ -58,12 +58,12 @@ def run(self): lines.append(row(link)) lines.append(divider) for line in summary: - lines.append(row(line)) + lines.append(row(line)) # noqa: PERF401 if methods: lines.append(row("")) lines.append(row("Methods:")) lines.append(row("")) - for i, method in enumerate(methods): + for _, method in enumerate(methods): lines.append(row(method)) lines.append(divider) content = "\n".join(lines) diff --git a/docs/conf.py b/docs/conf.py index 2961a3a16..a21bbfed6 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -27,7 +27,7 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. sys.path.insert(0, os.path.abspath("..")) -from juju.version import CLIENT_VERSION +from juju.version import CLIENT_VERSION # noqa: E402 version = CLIENT_VERSION @@ -66,7 +66,7 @@ # General information about the project. project = "juju" -copyright = "2016, Canonical Ltd." +copyright = "2016, Canonical Ltd." # noqa: A001 author = "Canonical" # The version info for the project you're documenting, acts as replacement for diff --git a/examples/add_k8s.py b/examples/add_k8s.py index 912d2e65d..fdd67ac6d 100644 --- a/examples/add_k8s.py +++ b/examples/add_k8s.py @@ -22,21 +22,21 @@ async def main(): - kubecfg = os.popen("microk8s.config").read() + kubecfg = os.popen("microk8s.config").read() # noqa: S607,S605 cfg = yaml.safe_load(kubecfg) ctx = {v["name"]: v["context"] for v in cfg["contexts"]}[cfg["current-context"]] cluster = {v["name"]: v["cluster"] for v in cfg["clusters"]}[ctx["cluster"]] user = {v["name"]: v["user"] for v in cfg["users"]}[ctx["user"]] ep = cluster["server"] - caCert = base64.b64decode(cluster["certificate-authority-data"]).decode("utf-8") + ca_cert = base64.b64decode(cluster["certificate-authority-data"]).decode("utf-8") controller = Controller() await controller.connect() cloud = client.Cloud( auth_types=["userpass"], - ca_certificates=[caCert], + ca_certificates=[ca_cert], endpoint=ep, host_cloud_region="microk8s/localhost", regions=[client.CloudRegion(endpoint=ep, name="localhost")], diff --git a/examples/add_secrets_backend.py b/examples/add_secrets_backend.py index 6de59acd1..55ed4d596 100644 --- a/examples/add_secrets_backend.py +++ b/examples/add_secrets_backend.py @@ -59,17 +59,17 @@ async def main(): print(response["results"]) # List the secrets backend - list = await c.list_secret_backends() + result = await c.list_secret_backends() print("Output from list secret backends") - print(list["results"]) + print(result["results"]) # Remove it await c.remove_secret_backends("examplevault") # # Finally after removing - list = await c.list_secret_backends() + result = await c.list_secret_backends() print("Output from list secret backends after removal") - print(list["results"]) + print(result["results"]) await m.disconnect() diff --git a/examples/formatted_status.py b/examples/formatted_status.py index 4fc2865d0..d772d7923 100644 --- a/examples/formatted_status.py +++ b/examples/formatted_status.py @@ -31,10 +31,10 @@ async def main(): ) await jasyncio.sleep(10) - tmp = tempfile.NamedTemporaryFile(delete=False) + tmp = tempfile.NamedTemporaryFile(delete=False) # noqa: SIM115 LOG.info("status dumped to %s", tmp.name) with open(tmp.name, "w") as f: - for i in range(10): + for _ in range(10): # Uncomment this line to get the full status # using the standard output. # await formatted_status(model, target=sys.stdout) diff --git a/examples/future.py b/examples/future.py index ffb7d9f8c..f69775522 100644 --- a/examples/future.py +++ b/examples/future.py @@ -35,7 +35,9 @@ async def main(): "nrpe", ) - result, ok = await model.block_until(lambda: model.matches(goal_state), timeout=600) + _result, _ok = await model.block_until( + lambda: model.matches(goal_state), timeout=600 + ) if __name__ == "__main__": diff --git a/examples/livemodel.py b/examples/livemodel.py index 96609286d..268ac4a0d 100644 --- a/examples/livemodel.py +++ b/examples/livemodel.py @@ -13,7 +13,7 @@ from juju.model import Model -async def on_model_change(delta, old, new, model): +async def on_model_change(delta, old, new, model): # noqa: RUF029 print(delta.entity, delta.type, delta.data) print(old) print(new) diff --git a/examples/machine_hostname.py b/examples/machine_hostname.py index 3dca3f4ef..5ac74d37b 100644 --- a/examples/machine_hostname.py +++ b/examples/machine_hostname.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. diff --git a/examples/model.py b/examples/model.py index d15befb02..8a53f6973 100755 --- a/examples/model.py +++ b/examples/model.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. @@ -17,11 +19,11 @@ async def main(): model = Model() - retryCount = 3 - for i in range(0, retryCount): + retries = 3 + for _ in range(0, retries): await model.connect_current() try: - model.applications["foo"].relations + print(model.applications["foo"].relations) except JujuEntityNotFoundError as e: print(e.entity_name) finally: diff --git a/examples/relate.py b/examples/relate.py index f9f24b6bc..1d5f43814 100644 --- a/examples/relate.py +++ b/examples/relate.py @@ -85,7 +85,7 @@ async def main(): ) ) ) - unit_a, unit_b = await ubuntu_app.add_units(count=2) + 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( diff --git a/examples/scp.py b/examples/scp.py index 664bb6447..9660282f2 100644 --- a/examples/scp.py +++ b/examples/scp.py @@ -26,7 +26,7 @@ async def main(): machine = model.machines["0"] # This roughly expands to the following: # scp -i ~/.local/share/juju/ssh/juju_id_rsa -o StrictHostKeyChecking=no -q -B ubuntu@10.132.183.88:/home/ubuntu/.profile /tmp/profile - await machine.scp_from("/home/ubuntu/.profile", "/tmp/profile") + await machine.scp_from("/home/ubuntu/.profile", "/tmp/profile") # noqa: S108 finally: if model.is_connected(): print("Disconnecting from model") diff --git a/examples/status.py b/examples/status.py index 5c6328280..ba617f66d 100644 --- a/examples/status.py +++ b/examples/status.py @@ -28,7 +28,7 @@ async def main(): await jasyncio.sleep(10) # Print the status to observe the evolution # during a minute - for i in range(12): + for _ in range(12): try: # By setting raw to True, the returned # entry contains a FullStatus object with diff --git a/juju/__init__.py b/juju/__init__.py index e69de29bb..9da2b17aa 100644 --- a/juju/__init__.py +++ b/juju/__init__.py @@ -0,0 +1,3 @@ +# Copyright 2024 Canonical Ltd. +# Licensed under the Apache V2, see LICENCE file for details. +"""Python Library for Juju.""" diff --git a/juju/application.py b/juju/application.py index 2dbd8f1da..a57e336c6 100644 --- a/juju/application.py +++ b/juju/application.py @@ -139,9 +139,7 @@ def status(self): """ status = self.safe_data["status"]["current"] if status == "unset": - known_statuses = [] - for unit in self.units: - known_statuses.append(unit.workload_status) + known_statuses = [unit.workload_status for unit in self.units] # If the self.get_status() is called (i.e. the status # is received by FullStatus from the API) then add # that into this computation as it might be more up @@ -452,11 +450,11 @@ async def get_series(self): log.debug("Getting series for %s", self.name) - appGetResults = await app_facade.Get(application=self.name) + results = await app_facade.Get(application=self.name) if self._facade_version() >= 15: - base_channel = appGetResults.base.channel + base_channel = results.base.channel return utils.base_channel_to_series(base_channel) - return appGetResults.series + return results.series async def get_config(self): """Return the configuration settings dict for this application.""" @@ -484,7 +482,7 @@ async def get_trusted(self): app_config = config.application_config return app_config["trust"]["value"] is True - async def set_trusted(self, trust): + async def set_trusted(self, trust: bool): """Set the trusted configuration of the application. :param bool trust: Trust the application or not @@ -498,7 +496,7 @@ async def set_trusted(self, trust): # anything in the config. app_facade = self._facade() - config = {"trust": json.dumps(True if trust is True else False)} + config = {"trust": json.dumps(trust)} log.debug("Setting config for %s: %s", self.name, config) # Unfortunately we have to do this in a lazy fashion, attempting to use @@ -812,7 +810,7 @@ async def refresh( resolve=[ client.ResolveCharmWithChannel( charm_origin=origin, - switch_charm=True if switch else False, # rpc expects boolean type + switch_charm=bool(switch), reference=charm_url, ) ] @@ -862,12 +860,13 @@ async def refresh( charm_resources = await charmhub.list_resources(charm_name) # Compute the difference btw resources needed and the existing resources - resources_to_update = [] - for resource in charm_resources: + resources_to_update = [ + resource + for resource in charm_resources if utils.should_upgrade_resource( resource, existing_resources, arg_resources - ): - resources_to_update.append(resource) + ) + ] # Update the resources if resources_to_update: @@ -897,8 +896,8 @@ async def refresh( ) pending_ids = response.pending_ids resource_ids = { - resource.get("Name", resource.get("name")): id - for resource, id in zip(resources_to_update, pending_ids) + resource.get("Name", resource.get("name")): id_ + for resource, id_ in zip(resources_to_update, pending_ids) } else: resource_ids = None diff --git a/juju/bundle.py b/juju/bundle.py index 26c82c005..6f136ec77 100644 --- a/juju/bundle.py +++ b/juju/bundle.py @@ -322,7 +322,7 @@ async def fetch_plan(self, bundle, origin, overlays=[]): _yaml_data = [yaml.dump(self.bundle)] for overlay in self.overlays: - _yaml_data.append(yaml.dump(overlay).replace("null", "")) + _yaml_data.append(yaml.dump(overlay).replace("null", "")) # noqa: PERF401 yaml_data = "---\n".join(_yaml_data) self.plan = await self.bundle_facade.GetChangesMapArgs( @@ -338,13 +338,13 @@ async def _download_bundle(self, charm_url, origin): f"unable to download bundle for {charm_url} using the new charms facade. Upgrade controller to proceed." ) - id = origin.id_ if origin.id_ else "" - hash = origin.hash_ if origin.hash_ else "" + id_ = origin.id_ if origin.id_ else "" + hash_ = origin.hash_ if origin.hash_ else "" charm_origin = { "source": origin.source, "type": origin.type_, - "id": id, - "hash": hash, + "id": id_, + "hash": hash_, "revision": origin.revision, "risk": origin.risk, "track": origin.track, @@ -366,7 +366,7 @@ async def _download_bundle(self, charm_url, origin): if not result.url: raise JujuError(f"no url found for bundle {charm_url.name}") - bundle_resp = requests.get(result.url) + bundle_resp = requests.get(result.url) # noqa: S113 bundle_resp.raise_for_status() with closing(bundle_resp), zipfile.ZipFile( diff --git a/juju/charmhub.py b/juju/charmhub.py index 9288287db..61cbfcca6 100644 --- a/juju/charmhub.py +++ b/juju/charmhub.py @@ -20,15 +20,15 @@ async def _charmhub_url(self): return model_conf["charmhub-url"] async def request_charmhub_with_retry(self, url, retries): - for attempt in range(retries): - _response = requests.get(url) + for _ in range(retries): + _response = requests.get(url) # noqa: S113 if _response.status_code == 200: return _response await jasyncio.sleep(5) raise JujuError(f"Got {_response.status_code} from {url}") async def get_charm_id(self, charm_name): - conn, headers, path_prefix = self.model.connection().https_connection() + _conn, _headers, _path_prefix = self.model.connection().https_connection() charmhub_url = await self._charmhub_url() url = f"{charmhub_url.value}/v2/charms/info/{charm_name}" @@ -37,7 +37,7 @@ async def get_charm_id(self, charm_name): return response["id"], response["name"] async def is_subordinate(self, charm_name): - conn, headers, path_prefix = self.model.connection().https_connection() + _conn, _headers, _path_prefix = self.model.connection().https_connection() charmhub_url = await self._charmhub_url() url = f"{charmhub_url.value}/v2/charms/info/{charm_name}?fields=default-release.revision.subordinate" @@ -50,7 +50,7 @@ async def is_subordinate(self, charm_name): # api call without needing the CharmHub facade async def list_resources(self, charm_name): - conn, headers, path_prefix = self.model.connection().https_connection() + _conn, _headers, __path_prefix = self.model.connection().https_connection() charmhub_url = await self._charmhub_url() url = f"{charmhub_url.value}/v2/charms/info/{charm_name}?fields=default-release.resources" diff --git a/juju/client/__init__.py b/juju/client/__init__.py index e69de29bb..4b9e20c55 100644 --- a/juju/client/__init__.py +++ b/juju/client/__init__.py @@ -0,0 +1,3 @@ +# Copyright 2024 Canonical Ltd. +# Licensed under the Apache V2, see LICENCE file for details. +"""Juju client.""" diff --git a/pyproject.toml b/pyproject.toml index 6b2fe31e0..8d51586ed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -149,6 +149,11 @@ ignore = [ "F821", ] +"examples/*" = [ + # Docstring format + "D404", +] + "tests/*" = [ # assert False to fail "B011", From 5f119ecf0762e3e77f1ab2371c797e03e9bee36b Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Wed, 13 Nov 2024 17:50:02 +0900 Subject: [PATCH 20/34] chore: remove old linter --- .github/workflows/test.yaml | 25 +------------------ Makefile | 12 +++------ scripts/copyright.sh | 50 ------------------------------------- tox.ini | 8 +----- 4 files changed, 5 insertions(+), 90 deletions(-) delete mode 100755 scripts/copyright.sh diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 80e619340..dd60a0d6d 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -7,28 +7,6 @@ concurrency: cancel-in-progress: true jobs: - lint: - name: Linter - runs-on: ubuntu-latest - strategy: - matrix: - python: - - "3.9" - - "3.10" - steps: - - name: Check out code - uses: actions/checkout@v4 - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python }} - - name: Install dependencies - run: pip install tox - - name: Run linter - run: | - tox -e lint - ./scripts/copyright.sh - build-test: name: Build test runs-on: ubuntu-latest @@ -67,7 +45,6 @@ jobs: run: tox -e validate unit-tests: - needs: lint name: Unit tests runs-on: ubuntu-latest strategy: @@ -161,7 +138,7 @@ jobs: integration-quarantine: name: Quarantined Integration Tests - needs: [lint, unit-tests] + needs: [unit-tests] timeout-minutes: 150 runs-on: ubuntu-latest strategy: diff --git a/Makefile b/Makefile index 11677f6d6..b2dbfc295 100644 --- a/Makefile +++ b/Makefile @@ -16,27 +16,21 @@ clean: .PHONY: client client: - tox -r --notest -e lint,py3 + tox -r --notest -e py3 $(PY) -m juju.client.facade -s "juju/client/schemas*" -o juju/client/ pre-commit run --files $(shell echo juju/client/_[cd]*.py) .PHONY: run-unit-tests -run-unit-tests: .tox lint +run-unit-tests: .tox tox -e py3 .PHONY: run-integration-tests -run-integration-tests: .tox lint +run-integration-tests: .tox tox -e integration .PHONY: run-all-tests test: run-unit-tests run-integration-tests -.PHONY: lint -lint: - @./scripts/copyright.sh - @echo "==> Running flake8 linter" - tox -e lint - .PHONY: docs docs: tox -e docs diff --git a/scripts/copyright.sh b/scripts/copyright.sh deleted file mode 100755 index d6b01af9d..000000000 --- a/scripts/copyright.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/bash - -supports_colors() { - if [[ -z ${TERM} ]] || [[ ${TERM} == "" ]] || [[ ${TERM} == "dumb" ]]; then - echo "NO" - return - fi - if which tput >/dev/null 2>&1; then - # shellcheck disable=SC2046 - if [[ $(tput colors) -gt 1 ]]; then - echo "YES" - return - fi - fi - echo "NO" -} - -red() { - if [[ "$(supports_colors)" == "YES" ]]; then - tput sgr0 - echo "$(tput setaf 1)${1}$(tput sgr0)" - return - fi - echo "${1}" -} - -run_copyright() { - OUT=$(find . -name '*.py' | grep -v -E "./(docs|scripts|debian|juju-egg-info|.tox|.git|juju/client|tests/charm)|__init__" | sort | xargs grep -L -E '# (Copyright|Code generated)' || true) - LINES=$(echo "${OUT}" | wc -w) - if [ "$LINES" != 0 ]; then - echo "" - echo "$(red 'Found some issues:')" - echo -e '\nThe following files are missing copyright headers' - echo "${OUT}" - exit 1 - fi -} - -test_copyright() { - echo "==> Copyright analysis" - - ( - # cd .. || exit - - # Check for copyright notices - run_copyright - ) -} - -test_copyright diff --git a/tox.ini b/tox.ini index ea44b0a37..747e4a3d0 100644 --- a/tox.ini +++ b/tox.ini @@ -5,7 +5,7 @@ # and then run "tox" from this directory. [tox] -envlist = lint,py3,py38,py39,py310,py311,docs +envlist = py3,py38,py39,py310,py311,docs skipsdist=True [pytest] @@ -53,12 +53,6 @@ commands = rm -rf docs/_build/ sphinx-build -b html docs/ docs/_build/ -[testenv:lint] -commands = - flake8 {posargs} juju tests examples -deps = - flake8 - [testenv:integration] envdir = {toxworkdir}/py3 commands = From a8399b485a601533a3a32bb8f94ff98d049c97de Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Thu, 14 Nov 2024 12:23:47 +0900 Subject: [PATCH 21/34] chore: don't let pre-commit autofix pull requests, it doesn't pass CLA --- .pre-commit-config.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5f37f3c57..beadb697d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,3 +36,5 @@ repos: additional_dependencies: - tomli exclude: "^juju/client/schemas-juju.*json$" +ci: + autofix_prs: false From 1217ef1e95bcbfd3dc4f0053fd4078726b13b4f9 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Thu, 14 Nov 2024 13:23:25 +0900 Subject: [PATCH 22/34] chore: exclude known large file patterns --- .pre-commit-config.yaml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index beadb697d..9fe2bdcd9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,6 +3,11 @@ repos: rev: v4.5.0 hooks: - id: check-added-large-files + exclude: | + (?x) # Verbose mode + ^juju/client/schemas-juju-.*[.]json$ | + ^tests/.*[.]charm$ | + ^examples/.*[.]charm$ - id: check-ast - id: check-case-conflict - id: check-executables-have-shebangs @@ -11,16 +16,16 @@ repos: - id: check-symlinks - id: check-json - id: check-yaml - # Overlays are deliberately multi-doc + # Overlays deliberately comprise multiple YAML documents per file exclude: "^tests/integration/bundle/test-overlays/.*multi.*yaml$" - id: check-toml - id: mixed-line-ending - id: end-of-file-fixer - exclude: "^juju/client/schemas-juju.*json$" + exclude: "^juju/client/schemas-juju-.*[.]json$" - id: trailing-whitespace - id: detect-private-key exclude: "^tests/.*$" - # Run the Ruff linter. + - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.7.3 hooks: @@ -28,13 +33,14 @@ repos: args: [ --preview, --fix ] - id: ruff-format args: [ --preview ] - # Spellcheck the code. + - repo: https://github.com/codespell-project/codespell rev: v2.3.0 hooks: - id: codespell additional_dependencies: - tomli - exclude: "^juju/client/schemas-juju.*json$" + exclude: "^juju/client/schemas-juju-.*[.]json$" + ci: autofix_prs: false From a3b241d2cdcf19fce349d56e08da48869b4af089 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Thu, 14 Nov 2024 13:25:52 +0900 Subject: [PATCH 23/34] chore: document pre-commit --- docs/CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index eca7fe260..f55afb2a2 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -40,6 +40,7 @@ The process is very simple. - Check with `git remote -v`, origin should point to your fork, upstream should point to ours. - If your changes are going to be on top of a specific branch (e.g., `2.9`), then fetch and switch to that. - `git switch -c your-branch-name` +- Make sure that you have run `pre-commit install` - Make your changes, create your commits. - `git push -u origin your-branch-name` From 4ccd82d460c541dcafd5387c0b108d2d594609a5 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Thu, 14 Nov 2024 13:29:03 +0900 Subject: [PATCH 24/34] chore: remove lint from GHA job deps --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index dd60a0d6d..697779c33 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -70,7 +70,7 @@ jobs: integration: name: Integration - needs: [lint, unit-tests] + needs: [unit-tests] timeout-minutes: 150 runs-on: ubuntu-latest strategy: From 6de9a5b9e5b6a88eed8686179bd31de429bc4aad Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Thu, 14 Nov 2024 13:44:06 +0900 Subject: [PATCH 25/34] chore: fix package build --- pyproject.toml | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 8d51586ed..853c24086 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,11 +1,11 @@ [project] name = "juju" +version = "3.5.2.1" # Stop-gap until dynamic versioning is done; must be in sync with juju/version.py:CLIENT_VERSION description = "Python library for Juju" readme = "docs/readme.rst" -license = "Apache-2.0" +license = { file = "LICENSE" } maintainers = [{name = "Juju Ecosystem Engineering", email = "juju@lists.ubuntu.com"}] requires-python = ">=3.8" -homepage = "https://github.com/juju/python-libjuju" classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", @@ -21,20 +21,20 @@ classifiers = [ "Operating System :: MacOS :: MacOS X", "Operating System :: POSIX :: Linux", ] - -[project.dependencies] -macaroonbakery = ">=1.1,<2.0" -pyRFC3339 = ">=1.0,<2.0" -pyyaml = ">=5.1.2" -websockets = ">=8.1,<14.0" -paramiko = ">=2.4.0" -pyasn1 = ">=0.4.4" -toposort = ">=1.5,<2" -typing_inspect = ">=0.6.0" -kubernetes = ">=12.0.1,<31.0.0" -hvac = "*" -packaging = "*" -typing-extensions = ">=4.5.0" +dependencies = [ + "macaroonbakery>=1.1,<2.0", + "pyRFC3339>=1.0,<2.0", + "pyyaml>=5.1.2", + "websockets>=8.1,<14.0", + "paramiko>=2.4.0", + "pyasn1>=0.4.4", + "toposort>=1.5,<2", + "typing_inspect>=0.6.0", + "kubernetes>=12.0.1,<31.0.0", + "hvac", + "packaging", + "typing-extensions>=4.5.0" +] [project.urls] "Homepage" = "https://juju.is/docs/sdk" From cb4a962f99c9f265da2300380a7d04330ee2c904 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Thu, 14 Nov 2024 14:12:27 +0900 Subject: [PATCH 26/34] chore: publish wheels in addition to sdist --- Makefile | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index b2dbfc295..87b3c26af 100644 --- a/Makefile +++ b/Makefile @@ -38,20 +38,20 @@ docs: .PHONY: build-test build-test: rm -rf venv + uvx --from build pyproject-build python3 -m venv venv . venv/bin/activate - python3 setup.py sdist - pip install ./dist/juju-${VERSION}.tar.gz + pip install dist/juju-${VERSION}.tar.gz python3 -c "from juju.controller import Controller" - rm ./dist/juju-${VERSION}.tar.gz + rm dist/juju-${VERSION}.tar.gz dist/juju-${VERSION}-*.whl .PHONY: release release: git fetch --tags - rm dist/*.tar.gz || true - $(PY) setup.py sdist - $(BIN)/twine check dist/* - $(BIN)/twine upload --repository juju dist/* + rm dist/*.tar.gz dist/*.whl || true + uvx --from build pyproject-build + uvx twine check dist/* + uvx twine upload --repository juju dist/* git tag ${VERSION} git push --tags From 3ea32bfaaf638059fcb72c9f3a2a54910f1c0f4d Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Thu, 14 Nov 2024 14:17:59 +0900 Subject: [PATCH 27/34] chore: add tooling to the contributor guide --- docs/CONTRIBUTING.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index f55afb2a2..caa2d186e 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -29,6 +29,12 @@ Check to see what [types of contributions](/contributing/types-of-contributions. --> +## Tooling + +- `uv`, https://docs.astral.sh/uv/ +- `pre-commit`, https://pre-commit.com/ +- Python 3.8 ~ 3.13, https://www.python.org/downloads/ + ## Pull Request Thanks for considering to contribute code to our project! We accept and welcome all kinds of PRs! :tada: From 7cd3743c8999182e535654131346cf7221341927 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Thu, 14 Nov 2024 14:20:28 +0900 Subject: [PATCH 28/34] chore: uvx in gha --- .github/workflows/test.yaml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 697779c33..c98275122 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -15,14 +15,12 @@ jobs: python: - "3.10" steps: - - name: Check out code - uses: actions/checkout@v4 - - name: Setup Python - uses: actions/setup-python@v5 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} - - name: Run build test target - run: | + - uses: astral-sh/setup-uv@v3.2.2 + - run: | make build-test validate: From 45c5b991e42dc0e683fb7e08ee1e1b4395f93b0c Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Thu, 14 Nov 2024 14:24:04 +0900 Subject: [PATCH 29/34] chore: weirdly my local build both sdist and wheel, while GHA build a wheel only --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 87b3c26af..51b1769a3 100644 --- a/Makefile +++ b/Makefile @@ -41,9 +41,9 @@ build-test: uvx --from build pyproject-build python3 -m venv venv . venv/bin/activate - pip install dist/juju-${VERSION}.tar.gz + pip install dist/juju-${VERSION}-py3-none-any.whl python3 -c "from juju.controller import Controller" - rm dist/juju-${VERSION}.tar.gz dist/juju-${VERSION}-*.whl + rm dist/*.tar.gz dist/*.whl .PHONY: release release: From e3cecc3b93bc006632c2a4e1312a6316f4b52b72 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Thu, 14 Nov 2024 14:28:42 +0900 Subject: [PATCH 30/34] chore: main is still on .0, not .1 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 853c24086..7b9e36e91 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "juju" -version = "3.5.2.1" # Stop-gap until dynamic versioning is done; must be in sync with juju/version.py:CLIENT_VERSION +version = "3.5.2.0" # Stop-gap until dynamic versioning is done; must be in sync with juju/version.py:CLIENT_VERSION description = "Python library for Juju" readme = "docs/readme.rst" license = { file = "LICENSE" } From d8c46885ad8485b22d3ba54f1c8daf3dc47338ca Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Thu, 14 Nov 2024 16:34:55 +0900 Subject: [PATCH 31/34] chore: sensible stacklevel on deprecation warnings --- juju/loop.py | 2 +- juju/model.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/juju/loop.py b/juju/loop.py index bed54a11d..d9d2e8f8a 100644 --- a/juju/loop.py +++ b/juju/loop.py @@ -8,5 +8,5 @@ warnings.warn( "juju.loop module is being deprecated by 3.0, use juju.jasyncio instead", DeprecationWarning, - stacklevel=1, + stacklevel=2, ) diff --git a/juju/model.py b/juju/model.py index 207eaf808..12f9edced 100644 --- a/juju/model.py +++ b/juju/model.py @@ -2972,7 +2972,7 @@ async def wait_for_idle( warnings.warn( "wait_for_active is deprecated; use status", DeprecationWarning, - stacklevel=1, + stacklevel=2, ) status = "active" From 3cba1b69cf141d22d5fe6a42a9af2811f98e9ea3 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Thu, 14 Nov 2024 16:38:42 +0900 Subject: [PATCH 32/34] chore: sensible stacklevel on deprecation warnings --- juju/status.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/juju/status.py b/juju/status.py index 6d9efbde6..81ebbd9b4 100644 --- a/juju/status.py +++ b/juju/status.py @@ -57,7 +57,7 @@ async def formatted_status(model, target=None, raw=False, filters=None): warnings.warn( "juju.status.formatted_status is deprecated, the implementation is likely broken", DeprecationWarning, - stacklevel=1, + stacklevel=2, ) client_facade = client.ClientFacade.from_connection(model.connection()) result_status = await client_facade.FullStatus(patterns=filters) From 62585d28245a444548b8facf80a703b157793704 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Fri, 15 Nov 2024 10:31:04 +0900 Subject: [PATCH 33/34] chore: pre-commit via github action --- .github/workflows/pre-commit.yaml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/workflows/pre-commit.yaml diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml new file mode 100644 index 000000000..f9e969603 --- /dev/null +++ b/.github/workflows/pre-commit.yaml @@ -0,0 +1,17 @@ +--- +name: pre-commit + +on: + pull_request: + push: + branches: [main] + +jobs: + pre-commit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.13" + - uses: pre-commit/action@v3.0.1 From f5b93e79873f66907522800ce7d24db29fb4cd19 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Fri, 15 Nov 2024 14:50:12 +0900 Subject: [PATCH 34/34] chore: simpler build --- Makefile | 4 ++-- juju/client/proxy/__init__.py | 3 +++ juju/client/proxy/kubernetes/__init__.py | 3 +++ 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 juju/client/proxy/__init__.py create mode 100644 juju/client/proxy/kubernetes/__init__.py diff --git a/Makefile b/Makefile index 51b1769a3..95c5fd58f 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ docs: .PHONY: build-test build-test: rm -rf venv - uvx --from build pyproject-build + uv build python3 -m venv venv . venv/bin/activate pip install dist/juju-${VERSION}-py3-none-any.whl @@ -49,7 +49,7 @@ build-test: release: git fetch --tags rm dist/*.tar.gz dist/*.whl || true - uvx --from build pyproject-build + uv build uvx twine check dist/* uvx twine upload --repository juju dist/* git tag ${VERSION} diff --git a/juju/client/proxy/__init__.py b/juju/client/proxy/__init__.py new file mode 100644 index 000000000..f59d24d57 --- /dev/null +++ b/juju/client/proxy/__init__.py @@ -0,0 +1,3 @@ +# Copyright 2024 Canonical Ltd. +# Licensed under the Apache V2, see LICENCE file for details. +"""Juju client proxy.""" diff --git a/juju/client/proxy/kubernetes/__init__.py b/juju/client/proxy/kubernetes/__init__.py new file mode 100644 index 000000000..0b3faa2da --- /dev/null +++ b/juju/client/proxy/kubernetes/__init__.py @@ -0,0 +1,3 @@ +# Copyright 2024 Canonical Ltd. +# Licensed under the Apache V2, see LICENCE file for details. +"""Juju client proxy for k8s."""