Merge ~mertkirpici/juju-lint:lp/1979686 into juju-lint:master

Proposed by Mert Kirpici
Status: Merged
Approved by: Gabriel Cocenza
Approved revision: 55c3ce784a39196b2e1317c45f15ba1b8b2d58df
Merged at revision: 832f001796ca2e1b15777dfc01d47b6260caa0c2
Proposed branch: ~mertkirpici/juju-lint:lp/1979686
Merge into: juju-lint:master
Diff against target: 1844 lines (+1690/-11)
9 files modified
.gitignore (+1/-1)
CONTRIBUTING.md (+11/-0)
Makefile (+6/-2)
rename.sh (+13/-0)
tests/functional/conftest.py (+129/-0)
tests/functional/requirements.txt (+1/-0)
tests/functional/test_jujulint.py (+49/-0)
tests/resources/fcb-yoga-focal-bundle.yaml (+1442/-0)
tox.ini (+38/-8)
Reviewer Review Type Date Requested Status
Gabriel Cocenza Approve
Eric Chen Needs Information
BootStack Reviewers Pending
Martin Kalcok Pending
Review via email: mp+428809@code.launchpad.net

Commit message

Close LP #1979686

Description of the change

Since the functional tests require the juju-lint application to be
installed to the system, there are two modes of running the tests:
installing the python package to the .tox environment or installing the
snap directly into the system and removing it afterwards. It is worth
mentioning that since `snap install` requires elevated privileges, in
the snap installation case, the pytest fixture install_package() that is
responsible for installing the package will call `sudo install...` and
`sudo remove ...` __requiring passwordless sudo access for the current
user__. The reason for this behaviour rather than enforcing an EUID of
zero is due to the fact that we need access to the user's juju
environment, not root's. Here are examples of both use cases.

Installing the python package:

  $ make functional

Installing the snap:

  $ JUJULINT_TEST_SNAP=./juju-lint_1.0.3_amd64.snap make functional

note the environment variable here. Also note that when the tests are
running against the python package, a WARNING level log will be printed
during the test run to indicate this fact, however when the snap package
is installed, there will be no WARNING printed.

Currently tests are divided into two cases and accompanying markers to
be able to run a subset of them. This might especially come in handy for
skipping the cloud tests during a development cycle since they involve
spinning up a model, deploying an application and destruction of the
model each time the tests are run.

Here is a summary of the two test cases.

- smoke
  - post-build tests as well as tests running against the
    fcb-yoga-focal-bundle.yaml file generated using the
    fcb/sku/stable-yoga-focal branch of the fce-templates repository
- cloud
  - tests that are running against a live model deployed on the local
    cloud via pytest-operator

Combined with the FUNC_ARGS environment variable, these markers could be
used to select tests. Here is an example that runs only the smoke tests:

  $ FUNC_ARGS="-m smoke" make functional

Here is another example utilizing exclusion, since the number of cases
might increase in the future:

  $ FUNC_ARGS="-m 'not cloud'" make functional

To post a comment you must log in.
Revision history for this message
Robert Gildein (rgildein) wrote :

Couple of comments.

Revision history for this message
Mert Kirpici (mertkirpici) wrote :

Addressed Robert's comments and submitting for review.

Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

This merge proposal is being monitored by mergebot. Change the status to Approved to merge.

Revision history for this message
Mert Kirpici (mertkirpici) wrote :

Here is the very first run of the functional tests:
https://pastebin.ubuntu.com/p/3JbcT8F9vk/

Revision history for this message
Eric Chen (eric-chen) wrote :

This is a big commit. Could you provide summary of modification? I think we also need to provide this kind of information in launchpad.

e.g.

1. What is the scope of functional tests you focus on? How did you design it?2.
2. Design detail - How to decide the bundle file?

review: Needs Information
Revision history for this message
Mert Kirpici (mertkirpici) wrote :

Resubmitting with these changes:

- Updated the commit message and description
- Introduced pytest marks and FUNC_ARGS variable
- Squashed commits for tidiness

Here is the functest run:
https://pastebin.ubuntu.com/p/QztnK5kmcH/

it includes both snap and python package use cases.

Revision history for this message
Gabriel Cocenza (gabrielcocenza) wrote :

Great job. Thanks for this patch.
Here are some suggestions:

- I think it would be beneficial if some commands are encapsulated into the .tox and/or makefile.

- I see as possible enhancement is to have more than one option as functional tests in the .tox file. E.g: [testenv:func] to build and install the snap locally and run all functional tests, [testenv:func-smoke] to run tests marked as smoke, [testenv:func-dev] run tests using the python package.

- It will be good to have a small session under Developing in the CONTRIBUTING.md with some explanation on how to run the different functional tests (python package, snap, smoke etc).

I also detected a strange behavior [0] when passing the JUJULINT_TEST_SNAP is returning 120 on subprocess check_call, but check_output seems to work normally.

[0] https://pastebin.canonical.com/p/YDYXwwRH4v/

review: Needs Fixing
Revision history for this message
Eric Chen (eric-chen) wrote :

LTGM, just have a question below.

Revision history for this message
Mert Kirpici (mertkirpici) wrote :

Rebased the branch on master after the unit test changes. Resolved conflicts. Addressed the review comments.
Updates include:

- add tox environments func-dev and func-smoke for development purposes
- introduce rename.sh like the charms, `make functional` installs snap and runs the functional tests now
- update CONTRIBUTING.md with functional test info
- fixtures not-requiring cleanup return, do not yield anymore
- move the fcb bundle file under common resources for testing
- fix test_audit_local_cloud. there was an invocation error.

See commit messages for more info.

`make test` output:
https://pastebin.ubuntu.com/p/HVrZzpCnBB/

Revision history for this message
Gabriel Cocenza (gabrielcocenza) wrote :

LGTM. Thanks!

review: Approve
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

Change successfully merged at revision 832f001796ca2e1b15777dfc01d47b6260caa0c2

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/.gitignore b/.gitignore
index 6b085ea..764c99f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,7 +13,7 @@ __pycache__
13*.egg-info13*.egg-info
1414
15# test artefacts15# test artefacts
16tests/report16tests/unit/report
17.coverage17.coverage
1818
19# debuild cruft19# debuild cruft
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 1e5c9b9..ef0a32c 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -53,6 +53,17 @@ make test # run lint, unittests and functional
53make build # build the snap53make build # build the snap
54make clean # clean the snapcraft lxd containers and the snap files created54make clean # clean the snapcraft lxd containers and the snap files created
55```55```
56### Functional Tests
57
58`make functional` will build the snap, rename it, install it locally and run the tests against the installed snap package. Since this action involves installing a snap package, passwordless `sudo` privileges are needed.
59However for development purposes, the testing infrastructure also allows for installing `juju-lint` as a python package to a tox environment
60and running tests against it.
61In order to invoke:
62- development smoke suite, which deselects tests running against a live lxd cloud
63 - `$ tox -e func-smoke`
64- development full suite, which runs all the functional tests
65 - `$ tox -e func-dev`
66
5667
57## Canonical Contributor Agreement68## Canonical Contributor Agreement
5869
diff --git a/Makefile b/Makefile
index 49303b3..4857f3f 100644
--- a/Makefile
+++ b/Makefile
@@ -1,3 +1,7 @@
1PROJECTPATH=$(dir $(realpath ${MAKEFILE_LIST}))
2SNAP_NAME=$(shell cat ${PROJECTPATH}/snap/snapcraft.yaml | grep -E '^name:' | awk '{print $$2}')
3SNAP_FILE=${PROJECTPATH}/${SNAP_NAME}.snap
4
1help:5help:
2 @echo "This project supports the following targets"6 @echo "This project supports the following targets"
3 @echo ""7 @echo ""
@@ -13,7 +17,6 @@ help:
13 @echo " make pre-commit - run pre-commit checks on all the files"17 @echo " make pre-commit - run pre-commit checks on all the files"
14 @echo ""18 @echo ""
1519
16
17lint:20lint:
18 @echo "Running lint checks"21 @echo "Running lint checks"
19 @tox -e lint22 @tox -e lint
@@ -32,6 +35,7 @@ reformat:
32build:35build:
33 @echo "Building the snap"36 @echo "Building the snap"
34 @snapcraft --use-lxd37 @snapcraft --use-lxd
38 @bash -c ./rename.sh
3539
36clean:40clean:
37 @echo "Cleaning snap"41 @echo "Cleaning snap"
@@ -47,7 +51,7 @@ dev-environment:
4751
48functional: build52functional: build
49 @echo "Executing functional tests using built snap"53 @echo "Executing functional tests using built snap"
50 @tox -e func54 @JUJULINT_TEST_SNAP=${SNAP_FILE} tox -e func -- ${FUNC_ARGS}
5155
52pre-commit:56pre-commit:
53 @tox -e pre-commit57 @tox -e pre-commit
diff --git a/rename.sh b/rename.sh
54new file mode 10075558new file mode 100755
index 0000000..f7316d0
--- /dev/null
+++ b/rename.sh
@@ -0,0 +1,13 @@
1#!/bin/bash
2snap=$(grep -E "^name:" snap/snapcraft.yaml | awk '{print $2}')
3echo "renaming ${snap}_*.snap to ${snap}.snap"
4echo -n "pwd: "
5pwd
6ls -al
7echo "Removing previous snap if it exists"
8if [[ -e "${snap}.snap" ]];
9then
10 rm "${snap}.snap"
11fi
12echo "Renaming charm here."
13mv ${snap}_*.snap ${snap}.snap
diff --git a/tests/functional/conftest.py b/tests/functional/conftest.py
0new file mode 10064414new file mode 100644
index 0000000..d26b318
--- /dev/null
+++ b/tests/functional/conftest.py
@@ -0,0 +1,129 @@
1"""Pytest configuration file for juju-lint tests."""
2import logging
3import os
4import shutil
5from subprocess import check_call, check_output
6from textwrap import dedent
7
8import pytest
9
10
11def pytest_configure(config):
12 """Pytest configuration."""
13 config.addinivalue_line("markers", "smoke: mark test as a smoke test")
14 config.addinivalue_line("markers", "cloud: mark test as a cloud test")
15
16
17@pytest.fixture(scope="session", autouse=True)
18def install_package():
19 """Install the package to the system and cleanup afterwards.
20
21 Depending on the environment variable JUJULINT_TEST_SNAP,
22 it will install the snap or the python package.
23 """
24 jujulint_test_snap = os.environ.get("JUJULINT_TEST_SNAP", None)
25 if jujulint_test_snap:
26 logging.info(f"Installing {jujulint_test_snap}")
27 assert os.path.isfile(jujulint_test_snap)
28 assert (
29 check_call(
30 f"sudo snap install --dangerous --classic {jujulint_test_snap}".split()
31 )
32 == 0 # noqa
33 )
34 assert check_output("which juju-lint".split()).decode().strip() == os.path.join(
35 "/snap/bin/juju-lint"
36 )
37 else:
38 logging.warning("Installing python package")
39 assert check_call("python3 -m pip install .".split()) == 0
40 assert (
41 check_output("which juju-lint".split())
42 .decode()
43 .strip()
44 .startswith(os.path.join(os.getcwd(), ".tox"))
45 )
46
47 yield jujulint_test_snap
48
49 if jujulint_test_snap:
50 logging.info("Removing snap package juju-lint")
51 check_call("sudo snap remove juju-lint".split())
52 else:
53 logging.info("Uninstalling python package jujulint")
54 check_call("python3 -m pip uninstall --yes jujulint".split())
55
56
57@pytest.fixture
58def basedir():
59 """Return the basedir for the installation.
60
61 This will ease testing the rules files that we ship
62 with the juju-lint snap.
63 """
64 if os.environ.get("JUJULINT_TEST_SNAP", None):
65 basedir = "/snap/juju-lint/current/"
66 else:
67 basedir = os.getcwd()
68 return basedir
69
70
71@pytest.fixture
72def rules_file(basedir):
73 """Return the rules file for testing."""
74 return os.path.join(basedir, "contrib/fcb-yoga-focal.yaml")
75
76
77@pytest.fixture
78def manual_file():
79 """Return the bundle file for testing."""
80 return os.path.join(
81 os.path.dirname(__file__), "../resources/fcb-yoga-focal-bundle.yaml"
82 )
83
84
85@pytest.fixture
86def lint_rules_yaml(basedir, rules_file):
87 """Return the default lint-rules.yaml file and cleanup."""
88 lint_rules_yaml_file = os.path.join(os.getcwd(), "lint-rules.yaml")
89 shutil.copy(rules_file, lint_rules_yaml_file)
90
91 includes_dir = os.path.join(os.getcwd(), "includes")
92 os.symlink(os.path.join(basedir, "contrib/includes"), includes_dir)
93
94 yield lint_rules_yaml_file
95
96 os.unlink(lint_rules_yaml_file)
97 os.unlink(includes_dir)
98
99
100@pytest.fixture
101def local_cloud():
102 """Prepare the local configuration file for juju-lint.
103
104 If there's an existing configuration directory, back it up
105 first and then recover.
106 """
107 local_cloud_name = "test"
108 backup = False
109 local_config_dir = os.path.join(os.path.expanduser("~"), ".config/juju-lint")
110 local_config_file = os.path.join(local_config_dir, "config.yaml")
111 if os.path.isdir(local_config_dir):
112 logging.info("Backing up existing config directory")
113 shutil.move(local_config_dir, local_config_dir + ".bak")
114 backup = True
115 os.makedirs(local_config_dir)
116 with open(local_config_file, "w") as config_yaml:
117 config_yaml_str = f"""\
118 clouds:
119 {local_cloud_name}:
120 type: openstack
121 """
122 config_yaml.write(dedent(config_yaml_str))
123
124 yield local_cloud_name
125
126 shutil.rmtree(local_config_dir)
127 if backup:
128 logging.info("Restoring backup")
129 shutil.move(local_config_dir + ".bak", local_config_dir)
diff --git a/tests/functional/requirements.txt b/tests/functional/requirements.txt
0new file mode 100644130new file mode 100644
index 0000000..2220b6c
--- /dev/null
+++ b/tests/functional/requirements.txt
@@ -0,0 +1 @@
1pytest-operator
0\ No newline at end of file2\ No newline at end of file
diff --git a/tests/functional/test_jujulint.py b/tests/functional/test_jujulint.py
1new file mode 1006443new file mode 100644
index 0000000..e15e9b6
--- /dev/null
+++ b/tests/functional/test_jujulint.py
@@ -0,0 +1,49 @@
1"""Functional tests for juju-lint."""
2import json
3import socket
4from subprocess import check_call, check_output
5
6import pytest
7
8
9@pytest.mark.smoke
10def test_juju_lint_startup():
11 """Test starting juju-lint and print help string."""
12 assert check_call("juju-lint --help".split()) == 0
13
14
15@pytest.mark.smoke
16def test_load_rules_file_from_path(rules_file, manual_file):
17 """Test loading the rules file via command line argument."""
18 assert check_call(f"juju-lint -c {rules_file} {manual_file}".split()) == 0
19
20
21@pytest.mark.smoke
22def test_load_default_rules_file(lint_rules_yaml, manual_file):
23 """Test loading the default rules file."""
24 assert check_call(f"juju-lint {manual_file}".split()) == 0
25
26
27@pytest.mark.smoke
28def test_json_output(rules_file, manual_file):
29 """Test json output."""
30 assert json.loads(
31 check_output(
32 f"juju-lint --format json -c {rules_file} {manual_file}".split()
33 ).decode()
34 )
35
36
37@pytest.mark.cloud
38async def test_audit_local_cloud(ops_test, local_cloud, rules_file):
39 """Test running juju-lint against a live local cloud."""
40 await ops_test.model.deploy("ubuntu")
41 await ops_test.model.wait_for_idle()
42 returncode, stdout, stderr = await ops_test.run(
43 *f"juju-lint -c {rules_file}".split()
44 )
45 assert (
46 f"[{local_cloud}] Linting model information for {socket.getfqdn()}, "
47 f"controller {ops_test.controller_name}, model {ops_test.model_name}" in stderr
48 )
49 assert returncode == 0
diff --git a/tests/resources/fcb-yoga-focal-bundle.yaml b/tests/resources/fcb-yoga-focal-bundle.yaml
0new file mode 10064450new file mode 100644
index 0000000..de6364c
--- /dev/null
+++ b/tests/resources/fcb-yoga-focal-bundle.yaml
@@ -0,0 +1,1442 @@
1applications:
2 aodh:
3 bindings:
4 ? ''
5 : oam-space
6 admin: internal-space
7 amqp: internal-space
8 certificates: internal-space
9 identity-service: internal-space
10 internal: internal-space
11 public: public-space
12 shared-db: internal-space
13 channel: yoga/stable
14 charm: aodh
15 num_units: 3
16 options:
17 openstack-origin: cloud:focal-yoga
18 region: RegionOne
19 use-internal-endpoints: true
20 to:
21 - lxd:1
22 - lxd:4
23 - lxd:7
24 aodh-mysql-router:
25 bindings:
26 ? ''
27 : oam-space
28 db-router: internal-space
29 shared-db: internal-space
30 channel: latest/edge
31 charm: mysql-router
32 barbican:
33 bindings:
34 ? ''
35 : oam-space
36 admin: internal-space
37 amqp: internal-space
38 certificates: internal-space
39 identity-service: internal-space
40 internal: internal-space
41 public: public-space
42 secrets: internal-space
43 shared-db: internal-space
44 channel: yoga/stable
45 charm: barbican
46 num_units: 3
47 options:
48 openstack-origin: cloud:focal-yoga
49 region: RegionOne
50 use-internal-endpoints: true
51 to:
52 - lxd:2
53 - lxd:5
54 - lxd:8
55 barbican-mysql-router:
56 bindings:
57 ? ''
58 : oam-space
59 db-router: internal-space
60 shared-db: internal-space
61 channel: latest/edge
62 charm: mysql-router
63 barbican-vault:
64 bindings:
65 ? ''
66 : oam-space
67 certificates: internal-space
68 secrets: internal-space
69 secrets-storage: internal-space
70 channel: yoga/stable
71 charm: barbican-vault
72 bcache-tuning:
73 bindings:
74 ? ''
75 : oam-space
76 charm: bcache-tuning
77 canonical-livepatch:
78 bindings:
79 ? ''
80 : oam-space
81 charm: canonical-livepatch
82 options:
83 livepatch_key: FCE_TEMPLATE
84 ceilometer:
85 bindings:
86 ? ''
87 : oam-space
88 admin: internal-space
89 amqp: internal-space
90 certificates: internal-space
91 identity-credentials: internal-space
92 internal: internal-space
93 public: public-space
94 shared-db: internal-space
95 channel: yoga/stable
96 charm: ceilometer
97 num_units: 3
98 options:
99 openstack-origin: cloud:focal-yoga
100 region: RegionOne
101 use-internal-endpoints: true
102 to:
103 - lxd:0
104 - lxd:3
105 - lxd:6
106 ceilometer-agent:
107 bindings:
108 ? ''
109 : oam-space
110 amqp: internal-space
111 channel: yoga/stable
112 charm: ceilometer-agent
113 options:
114 use-internal-endpoints: true
115 ceph-dashboard:
116 bindings:
117 ? ''
118 : oam-space
119 certificates: internal-space
120 channel: quincy/stable
121 charm: ceph-dashboard
122 options:
123 grafana-api-url: https://grafana.maas:3000
124 ceph-mon:
125 bindings:
126 ? ''
127 : oam-space
128 admin: ceph-access-space
129 client: ceph-access-space
130 cluster: ceph-replica-space
131 osd: ceph-access-space
132 public: ceph-access-space
133 radosgw: ceph-access-space
134 channel: quincy/stable
135 charm: ceph-mon
136 num_units: 3
137 options:
138 customize-failure-domain: true
139 expected-osd-count: FCE_TEMPLATE
140 source: cloud:focal-yoga
141 to:
142 - lxd:1
143 - lxd:4
144 - lxd:7
145 ceph-osd:
146 bindings:
147 ? ''
148 : oam-space
149 cluster: ceph-replica-space
150 mon: ceph-access-space
151 public: ceph-access-space
152 secrets-storage: internal-space
153 channel: quincy/stable
154 charm: ceph-osd
155 num_units: 9
156 options:
157 aa-profile-mode: complain
158 autotune: false
159 bluestore: true
160 customize-failure-domain: true
161 osd-devices: /dev/disk/by-dname/FCE_TEMPLATE
162 osd-encrypt: true
163 osd-encrypt-keymanager: vault
164 source: cloud:focal-yoga
165 to:
166 - '0'
167 - '1'
168 - '2'
169 - '3'
170 - '4'
171 - '5'
172 - '6'
173 - '7'
174 - '8'
175 ceph-radosgw:
176 bindings:
177 ? ''
178 : oam-space
179 admin: internal-space
180 certificates: internal-space
181 identity-service: internal-space
182 internal: internal-space
183 mon: ceph-access-space
184 public: public-space
185 channel: quincy/stable
186 charm: ceph-radosgw
187 constraints: spaces=ceph-access-space
188 num_units: 3
189 options:
190 region: RegionOne
191 source: cloud:focal-yoga
192 to:
193 - lxd:2
194 - lxd:5
195 - lxd:8
196 cinder:
197 bindings:
198 ? ''
199 : oam-space
200 admin: internal-space
201 amqp: internal-space
202 certificates: internal-space
203 identity-service: internal-space
204 internal: internal-space
205 public: public-space
206 shared-db: internal-space
207 channel: yoga/stable
208 charm: cinder
209 constraints: spaces=ceph-access-space
210 num_units: 3
211 options:
212 block-device: None
213 glance-api-version: 2
214 openstack-origin: cloud:focal-yoga
215 region: RegionOne
216 use-internal-endpoints: true
217 to:
218 - lxd:0
219 - lxd:3
220 - lxd:6
221 cinder-ceph:
222 bindings:
223 ? ''
224 : oam-space
225 ceph: ceph-access-space
226 channel: yoga/stable
227 charm: cinder-ceph
228 cinder-mysql-router:
229 bindings:
230 ? ''
231 : oam-space
232 db-router: internal-space
233 shared-db: internal-space
234 channel: latest/edge
235 charm: mysql-router
236 designate:
237 bindings:
238 ? ''
239 : oam-space
240 admin: internal-space
241 amqp: internal-space
242 certificates: internal-space
243 coordinator-memcached: internal-space
244 dns-backend: internal-space
245 identity-service: internal-space
246 internal: internal-space
247 public: public-space
248 shared-db: internal-space
249 channel: yoga/stable
250 charm: designate
251 num_units: 3
252 options:
253 nameservers: FCE_TEMPLATE
254 openstack-origin: cloud:focal-yoga
255 region: RegionOne
256 use-internal-endpoints: true
257 to:
258 - lxd:1
259 - lxd:4
260 - lxd:7
261 designate-bind:
262 bindings:
263 ? ''
264 : oam-space
265 certificates: internal-space
266 dns-backend: internal-space
267 dns-frontend: oam-space
268 channel: yoga/stable
269 charm: designate-bind
270 num_units: 2
271 options:
272 allowed_nets: FCE_TEMPLATE
273 disable-dnssec-validation: true
274 forwarders: FCE_TEMPLATE
275 recursion: true
276 use-internal-endpoints: true
277 to:
278 - memcached/0
279 - memcached/1
280 designate-mysql-router:
281 bindings:
282 ? ''
283 : oam-space
284 db-router: internal-space
285 shared-db: internal-space
286 channel: latest/edge
287 charm: mysql-router
288 easyrsa:
289 bindings:
290 ? ''
291 : oam-space
292 client: internal-space
293 charm: easyrsa
294 num_units: 1
295 to:
296 - lxd:6
297 etcd:
298 bindings:
299 ? ''
300 : oam-space
301 certificates: internal-space
302 db: internal-space
303 charm: etcd
304 num_units: 3
305 options:
306 channel: 3.4/stable
307 to:
308 - lxd:2
309 - lxd:5
310 - lxd:8
311 filebeat:
312 bindings:
313 ? ''
314 : oam-space
315 charm: filebeat
316 options:
317 logpath: /var/log/*.log
318 glance:
319 bindings:
320 ? ''
321 : oam-space
322 admin: internal-space
323 amqp: internal-space
324 ceph: ceph-access-space
325 certificates: internal-space
326 identity-service: internal-space
327 internal: internal-space
328 public: public-space
329 shared-db: internal-space
330 channel: yoga/stable
331 charm: glance
332 constraints: spaces=ceph-access-space
333 num_units: 3
334 options:
335 openstack-origin: cloud:focal-yoga
336 region: RegionOne
337 use-internal-endpoints: true
338 to:
339 - lxd:0
340 - lxd:3
341 - lxd:6
342 glance-mysql-router:
343 bindings:
344 ? ''
345 : oam-space
346 db-router: internal-space
347 shared-db: internal-space
348 channel: latest/edge
349 charm: mysql-router
350 glance-simplestreams-sync:
351 bindings:
352 ? ''
353 : oam-space
354 certificates: internal-space
355 identity-service: internal-space
356 channel: yoga/stable
357 charm: glance-simplestreams-sync
358 num_units: 1
359 options:
360 mirror_list: '[{ url: "http://cloud-images.ubuntu.com/releases/", name_prefix:
361 "ubuntu:released", path: "streams/v1/index.sjson", max: 1, item_filters: ["release~(bionic|focal)",
362 "arch~(x86_64|amd64)", "ftype~(disk1.img|disk.img)"] }]'
363 region: RegionOne
364 to:
365 - lxd:7
366 gnocchi:
367 bindings:
368 ? ''
369 : oam-space
370 admin: internal-space
371 amqp: internal-space
372 certificates: internal-space
373 coordinator-memcached: internal-space
374 identity-service: internal-space
375 internal: internal-space
376 public: public-space
377 shared-db: internal-space
378 storage-ceph: ceph-access-space
379 channel: yoga/stable
380 charm: gnocchi
381 num_units: 3
382 options:
383 openstack-origin: cloud:focal-yoga
384 region: RegionOne
385 use-internal-endpoints: true
386 to:
387 - lxd:1
388 - lxd:4
389 - lxd:7
390 gnocchi-mysql-router:
391 bindings:
392 ? ''
393 : oam-space
394 db-router: internal-space
395 shared-db: internal-space
396 channel: latest/edge
397 charm: mysql-router
398 hacluster-aodh:
399 bindings:
400 ? ''
401 : oam-space
402 channel: 2.0.3/stable
403 charm: hacluster
404 options:
405 cluster_count: 3
406 hacluster-barbican:
407 bindings:
408 ? ''
409 : oam-space
410 channel: 2.0.3/stable
411 charm: hacluster
412 options:
413 cluster_count: 3
414 hacluster-ceilometer:
415 bindings:
416 ? ''
417 : oam-space
418 channel: 2.0.3/stable
419 charm: hacluster
420 options:
421 cluster_count: 3
422 hacluster-ceph-radosgw:
423 bindings:
424 ? ''
425 : oam-space
426 channel: 2.0.3/stable
427 charm: hacluster
428 options:
429 cluster_count: 3
430 hacluster-cinder:
431 bindings:
432 ? ''
433 : oam-space
434 channel: 2.0.3/stable
435 charm: hacluster
436 options:
437 cluster_count: 3
438 hacluster-designate:
439 bindings:
440 ? ''
441 : oam-space
442 channel: 2.0.3/stable
443 charm: hacluster
444 options:
445 cluster_count: 3
446 hacluster-glance:
447 bindings:
448 ? ''
449 : oam-space
450 channel: 2.0.3/stable
451 charm: hacluster
452 options:
453 cluster_count: 3
454 hacluster-gnocchi:
455 bindings:
456 ? ''
457 : oam-space
458 channel: 2.0.3/stable
459 charm: hacluster
460 options:
461 cluster_count: 3
462 hacluster-heat:
463 bindings:
464 ? ''
465 : oam-space
466 channel: 2.0.3/stable
467 charm: hacluster
468 options:
469 cluster_count: 3
470 hacluster-keystone:
471 bindings:
472 ? ''
473 : oam-space
474 channel: 2.0.3/stable
475 charm: hacluster
476 options:
477 cluster_count: 3
478 hacluster-neutron-api:
479 bindings:
480 ? ''
481 : oam-space
482 channel: 2.0.3/stable
483 charm: hacluster
484 options:
485 cluster_count: 3
486 hacluster-nova-cloud-controller:
487 bindings:
488 ? ''
489 : oam-space
490 channel: 2.0.3/stable
491 charm: hacluster
492 options:
493 cluster_count: 3
494 hacluster-octavia:
495 bindings:
496 ? ''
497 : oam-space
498 channel: 2.0.3/stable
499 charm: hacluster
500 options:
501 cluster_count: 3
502 hacluster-openstack-dashboard:
503 bindings:
504 ? ''
505 : oam-space
506 channel: 2.0.3/stable
507 charm: hacluster
508 options:
509 cluster_count: 3
510 hacluster-placement:
511 bindings:
512 ? ''
513 : oam-space
514 channel: 2.0.3/stable
515 charm: hacluster
516 options:
517 cluster_count: 3
518 hacluster-vault:
519 bindings:
520 ? ''
521 : oam-space
522 channel: 2.0.3/stable
523 charm: hacluster
524 options:
525 cluster_count: 3
526 heat:
527 bindings:
528 ? ''
529 : oam-space
530 admin: internal-space
531 amqp: internal-space
532 certificates: internal-space
533 identity-service: internal-space
534 internal: internal-space
535 public: public-space
536 shared-db: internal-space
537 channel: yoga/stable
538 charm: heat
539 num_units: 3
540 options:
541 openstack-origin: cloud:focal-yoga
542 region: RegionOne
543 use-internal-endpoints: true
544 to:
545 - lxd:2
546 - lxd:5
547 - lxd:8
548 heat-mysql-router:
549 bindings:
550 ? ''
551 : oam-space
552 db-router: internal-space
553 shared-db: internal-space
554 channel: latest/edge
555 charm: mysql-router
556 homer-dashboard:
557 bindings:
558 ? ''
559 : oam-space
560 application-dashboard: public-space
561 charm: bootstack-charmers-homer-dashboard
562 num_units: 1
563 to:
564 - lxd:8
565 keystone:
566 bindings:
567 ? ''
568 : oam-space
569 admin: internal-space
570 certificates: internal-space
571 identity-credentials: internal-space
572 identity-service: internal-space
573 internal: internal-space
574 public: public-space
575 shared-db: internal-space
576 channel: yoga/stable
577 charm: keystone
578 num_units: 3
579 options:
580 openstack-origin: cloud:focal-yoga
581 preferred-api-version: 3
582 region: RegionOne
583 token-expiration: 86400
584 to:
585 - lxd:0
586 - lxd:3
587 - lxd:6
588 keystone-ldap:
589 bindings:
590 ? ''
591 : oam-space
592 certificates: internal-space
593 channel: yoga/stable
594 charm: keystone-ldap
595 options:
596 domain-name: FCE_TEMPLATE
597 ldap-config-flags: FCE_TEMPLATE
598 ldap-password: FCE_TEMPLATE
599 ldap-server: FCE_TEMPLATE
600 ldap-suffix: FCE_TEMPLATE
601 ldap-user: FCE_TEMPLATE
602 keystone-mysql-router:
603 bindings:
604 ? ''
605 : oam-space
606 db-router: internal-space
607 shared-db: internal-space
608 channel: latest/edge
609 charm: mysql-router
610 landscape-client:
611 bindings:
612 ? ''
613 : oam-space
614 charm: landscape-client
615 options:
616 account-name: standalone
617 disable-unattended-upgrades: true
618 ping-url: FCE_TEMPLATE
619 ssl-public-key: FCE_TEMPLATE
620 url: FCE_TEMPLATE
621 lldpd:
622 bindings:
623 ? ''
624 : oam-space
625 charm: lldpd
626 options:
627 interfaces-regex: en*
628 logrotated:
629 bindings:
630 ? ''
631 : oam-space
632 charm: logrotated
633 options:
634 logrotate-retention: 60
635 memcached:
636 bindings:
637 ? ''
638 : oam-space
639 cache: internal-space
640 charm: memcached
641 num_units: 2
642 options:
643 allow-ufw-ip6-softfail: true
644 to:
645 - lxd:3
646 - lxd:6
647 mysql-innodb-cluster:
648 bindings:
649 ? ''
650 : oam-space
651 cluster: internal-space
652 db-router: internal-space
653 channel: 8.0/stable
654 charm: mysql-innodb-cluster
655 num_units: 3
656 options:
657 enable-binlogs: true
658 innodb-buffer-pool-size: 8G
659 max-connections: 4000
660 wait-timeout: 3600
661 to:
662 - lxd:1
663 - lxd:4
664 - lxd:7
665 neutron-api:
666 bindings:
667 ? ''
668 : oam-space
669 admin: internal-space
670 amqp: internal-space
671 certificates: internal-space
672 identity-service: internal-space
673 internal: internal-space
674 public: public-space
675 shared-db: internal-space
676 channel: yoga/stable
677 charm: neutron-api
678 num_units: 3
679 options:
680 dns-domain: FCE_TEMPLATE
681 enable-ml2-dns: true
682 enable-ml2-port-security: true
683 flat-network-providers: ''
684 global-physnet-mtu: 9000
685 manage-neutron-plugin-legacy-mode: false
686 neutron-security-groups: true
687 openstack-origin: cloud:focal-yoga
688 path-mtu: 1558
689 physical-network-mtus: FCE_TEMPLATE
690 region: RegionOne
691 use-internal-endpoints: true
692 vlan-ranges: FCE_TEMPLATE
693 to:
694 - lxd:2
695 - lxd:5
696 - lxd:8
697 neutron-api-mysql-router:
698 bindings:
699 ? ''
700 : oam-space
701 db-router: internal-space
702 shared-db: internal-space
703 channel: latest/edge
704 charm: mysql-router
705 neutron-api-plugin-ovn:
706 bindings:
707 ? ''
708 : oam-space
709 certificates: internal-space
710 channel: yoga/stable
711 charm: neutron-api-plugin-ovn
712 nova-cloud-controller:
713 bindings:
714 ? ''
715 : oam-space
716 admin: internal-space
717 amqp: internal-space
718 certificates: internal-space
719 cloud-compute: internal-space
720 identity-service: internal-space
721 internal: internal-space
722 memcache: internal-space
723 public: public-space
724 shared-db: internal-space
725 channel: yoga/stable
726 charm: nova-cloud-controller
727 num_units: 3
728 options:
729 console-access-protocol: spice
730 cpu-allocation-ratio: 16
731 network-manager: Neutron
732 openstack-origin: cloud:focal-yoga
733 ram-allocation-ratio: 1.0
734 region: RegionOne
735 use-internal-endpoints: true
736 to:
737 - lxd:0
738 - lxd:3
739 - lxd:6
740 nova-cloud-controller-mysql-router:
741 bindings:
742 ? ''
743 : oam-space
744 db-router: internal-space
745 shared-db: internal-space
746 channel: latest/edge
747 charm: mysql-router
748 nova-compute:
749 bindings:
750 ? ''
751 : oam-space
752 amqp: internal-space
753 ceph: ceph-access-space
754 cloud-compute: internal-space
755 internal: internal-space
756 migration: internal-space
757 secrets-storage: internal-space
758 channel: yoga/stable
759 charm: nova-compute
760 num_units: 9
761 options:
762 aa-profile-mode: enforce
763 cpu-mode: custom
764 cpu-model: FCE_TEMPLATE
765 customize-failure-domain: true
766 enable-live-migration: true
767 enable-resize: true
768 encrypt: true
769 ephemeral-device: /dev/disk/by-dname/FCE_TEMPLATE
770 openstack-origin: cloud:focal-yoga
771 reserved-host-memory: 16384
772 use-internal-endpoints: true
773 to:
774 - '0'
775 - '1'
776 - '2'
777 - '3'
778 - '4'
779 - '5'
780 - '6'
781 - '7'
782 - '8'
783 nrpe:
784 bindings:
785 ? ''
786 : oam-space
787 charm: nrpe
788 ntp:
789 bindings:
790 ? ''
791 : oam-space
792 charm: ntp
793 options:
794 pools: 0.ubuntu.pool.ntp.org 1.ubuntu.pool.ntp.org 2.ubuntu.pool.ntp.org 3.ubuntu.pool.ntp.org
795 ntp.ubuntu.com
796 source: ''
797 verify_ntp_servers: true
798 octavia:
799 bindings:
800 ? ''
801 : oam-space
802 admin: internal-space
803 amqp: internal-space
804 certificates: internal-space
805 identity-service: internal-space
806 internal: internal-space
807 public: public-space
808 shared-db: internal-space
809 channel: yoga/stable
810 charm: octavia
811 num_units: 3
812 options:
813 lb-mgmt-controller-cacert: FCE_TEMPLATE
814 lb-mgmt-controller-cert: FCE_TEMPLATE
815 lb-mgmt-issuing-ca-key-passphrase: FCE_TEMPLATE
816 lb-mgmt-issuing-ca-private-key: FCE_TEMPLATE
817 lb-mgmt-issuing-cacert: FCE_TEMPLATE
818 loadbalancer-topology: ACTIVE_STANDBY
819 openstack-origin: cloud:focal-yoga
820 region: RegionOne
821 use-internal-endpoints: true
822 to:
823 - lxd:1
824 - lxd:4
825 - lxd:7
826 octavia-dashboard:
827 bindings:
828 ? ''
829 : oam-space
830 certificates: internal-space
831 dashboard: public-space
832 channel: yoga/stable
833 charm: octavia-dashboard
834 octavia-diskimage-retrofit:
835 bindings:
836 ? ''
837 : oam-space
838 certificates: internal-space
839 identity-credentials: internal-space
840 channel: yoga/stable
841 charm: octavia-diskimage-retrofit
842 options:
843 amp-image-tag: octavia-amphora
844 retrofit-uca-pocket: ussuri
845 octavia-mysql-router:
846 bindings:
847 ? ''
848 : oam-space
849 db-router: internal-space
850 shared-db: internal-space
851 channel: latest/edge
852 charm: mysql-router
853 octavia-ovn-chassis:
854 bindings:
855 ? ''
856 : oam-space
857 certificates: internal-space
858 data: internal-space
859 channel: 22.03/stable
860 charm: ovn-chassis
861 options:
862 disable-mlockall: true
863 ovn-bridge-mappings: FCE_TEMPLATE
864 openstack-dashboard:
865 bindings:
866 ? ''
867 : oam-space
868 certificates: internal-space
869 dashboard-plugin: public-space
870 identity-service: internal-space
871 shared-db: internal-space
872 channel: yoga/stable
873 charm: openstack-dashboard
874 num_units: 3
875 options:
876 endpoint-type: publicURL
877 neutron-network-l3ha: true
878 neutron-network-lb: true
879 openstack-origin: cloud:focal-yoga
880 password-retrieve: true
881 secret: FCE_TEMPLATE
882 webroot: /
883 to:
884 - lxd:2
885 - lxd:5
886 - lxd:8
887 openstack-dashboard-mysql-router:
888 bindings:
889 ? ''
890 : oam-space
891 db-router: internal-space
892 shared-db: internal-space
893 channel: latest/edge
894 charm: mysql-router
895 openstack-service-checks:
896 bindings:
897 ? ''
898 : oam-space
899 identity-credentials: internal-space
900 charm: openstack-service-checks
901 num_units: 1
902 options:
903 s3_check_params: /
904 to:
905 - lxd:1
906 ovn-central:
907 bindings:
908 ? ''
909 : oam-space
910 certificates: internal-space
911 channel: 22.03/stable
912 charm: ovn-central
913 num_units: 3
914 options:
915 source: cloud:focal-yoga
916 to:
917 - lxd:0
918 - lxd:3
919 - lxd:6
920 ovn-chassis:
921 bindings:
922 ? ''
923 : oam-space
924 certificates: internal-space
925 data: internal-space
926 channel: 22.03/stable
927 charm: ovn-chassis
928 options:
929 bridge-interface-mappings: br-data:FCE_TEMPLATE
930 ovn-bridge-mappings: FCE_TEMPLATE
931 placement:
932 bindings:
933 ? ''
934 : oam-space
935 admin: internal-space
936 amqp: internal-space
937 certificates: internal-space
938 identity-service: internal-space
939 internal: internal-space
940 public: public-space
941 shared-db: internal-space
942 channel: yoga/stable
943 charm: placement
944 num_units: 3
945 options:
946 openstack-origin: cloud:focal-yoga
947 region: RegionOne
948 use-internal-endpoints: true
949 to:
950 - lxd:1
951 - lxd:4
952 - lxd:7
953 placement-mysql-router:
954 bindings:
955 ? ''
956 : oam-space
957 db-router: internal-space
958 shared-db: internal-space
959 channel: latest/edge
960 charm: mysql-router
961 prometheus-libvirt-exporter:
962 bindings:
963 ? ''
964 : oam-space
965 charm: prometheus-libvirt-exporter
966 prometheus-openstack-exporter:
967 bindings:
968 ? ''
969 : oam-space
970 identity-credentials: internal-space
971 prometheus-openstack-exporter-service: oam-space
972 charm: prometheus-openstack-exporter
973 num_units: 1
974 options:
975 cpu-allocation-ratio: 16
976 ram-allocation-ratio: 1.0
977 to:
978 - lxd:0
979 public-policy-routing:
980 bindings:
981 ? ''
982 : oam-space
983 charm: advanced-routing
984 options:
985 action-managed-update: false
986 advanced-routing-config: "[{\n # NOTE: remove comments afterwards, result\
987 \ must be a valid JSON\n \"type\": \"table\",\n \"table\": \"public\"\
988 \n},{\n \"type\": \"route\",\n \"default_route\": true,\n \"gateway\"\
989 : \"FCE_TEMPLATE\", # Replace to gateway address of public network\n \"\
990 table\": \"public\",\n \"metric\": \"101\"\n},{\n \"type\": \"rule\"\
991 ,\n \"from-net\": \"FCE_TEMPLATE\", # Replace to CIDR of public network\n\
992 \ \"table\": \"public\",\n \"priority\": \"101\"\n},{\n \"type\"\
993 : \"rule\",\n \"from-net\": \"FCE_TEMPLATE\", # Replace to CIDR of public\
994 \ network\n \"to-net\": \"FCE_TEMPLATE\" # Replace to CIDR of public\
995 \ network\n}]"
996 enable-advanced-routing: true
997 rabbitmq-server:
998 bindings:
999 ? ''
1000 : oam-space
1001 amqp: internal-space
1002 cluster: internal-space
1003 channel: 3.9/stable
1004 charm: rabbitmq-server
1005 num_units: 3
1006 options:
1007 cluster-partition-handling: pause_minority
1008 min-cluster-size: 3
1009 source: cloud:focal-yoga
1010 to:
1011 - lxd:2
1012 - lxd:5
1013 - lxd:8
1014 telegraf:
1015 bindings:
1016 ? ''
1017 : oam-space
1018 charm: telegraf
1019 vault:
1020 bindings:
1021 ? ''
1022 : oam-space
1023 certificates: internal-space
1024 etcd: internal-space
1025 secrets: internal-space
1026 shared-db: internal-space
1027 channel: 1.7/stable
1028 charm: vault
1029 num_units: 3
1030 to:
1031 - '10'
1032 - '11'
1033 - '9'
1034 vault-mysql-router:
1035 bindings:
1036 ? ''
1037 : oam-space
1038 db-router: internal-space
1039 shared-db: internal-space
1040 channel: latest/edge
1041 charm: mysql-router
1042machines:
1043 '0':
1044 constraints: tags=foundation-nodes zones=zone1
1045 '1':
1046 constraints: tags=foundation-nodes zones=zone1
1047 '10':
1048 constraints: tags=vault zones=zone2
1049 '11':
1050 constraints: tags=vault zones=zone3
1051 '2':
1052 constraints: tags=foundation-nodes zones=zone1
1053 '3':
1054 constraints: tags=foundation-nodes zones=zone2
1055 '4':
1056 constraints: tags=foundation-nodes zones=zone2
1057 '5':
1058 constraints: tags=foundation-nodes zones=zone2
1059 '6':
1060 constraints: tags=foundation-nodes zones=zone3
1061 '7':
1062 constraints: tags=foundation-nodes zones=zone3
1063 '8':
1064 constraints: tags=foundation-nodes zones=zone3
1065 '9':
1066 constraints: tags=vault zones=zone1
1067saas:
1068 grafana:
1069 url: foundations-maas:admin/lma-maas.grafana
1070 graylog:
1071 url: foundations-maas:admin/lma-maas.graylog
1072 landscape-server:
1073 url: foundations-maas:admin/lma-maas.landscape-server
1074 nagios:
1075 url: foundations-maas:admin/lma-maas.nagios
1076 prometheus:
1077 url: foundations-maas:admin/lma-maas.prometheus
1078series: focal
1079relations:
1080- ['aodh-mysql-router:db-router', 'mysql-innodb-cluster:db-router']
1081- ['aodh-mysql-router:shared-db', 'aodh:shared-db']
1082- ['aodh:amqp', 'rabbitmq-server:amqp']
1083- ['aodh:certificates', 'vault:certificates']
1084- ['aodh:ha', 'hacluster-aodh:ha']
1085- ['aodh:identity-service', 'keystone:identity-service']
1086- ['aodh:juju-info', 'filebeat:beats-host']
1087- ['aodh:juju-info', 'landscape-client:container']
1088- ['aodh:juju-info', 'logrotated:juju-info']
1089- ['aodh:juju-info', 'nrpe:general-info']
1090- ['aodh:juju-info', 'public-policy-routing:juju-info']
1091- ['aodh:juju-info', 'telegraf:juju-info']
1092- ['aodh:nrpe-external-master', 'nrpe:nrpe-external-master']
1093- ['barbican-mysql-router:db-router', 'mysql-innodb-cluster:db-router']
1094- ['barbican-mysql-router:shared-db', 'barbican:shared-db']
1095- ['barbican-vault:certificates', 'vault:certificates']
1096- ['barbican-vault:secrets-storage', 'vault:secrets']
1097- ['barbican-vault:secrets', 'barbican:secrets']
1098- ['barbican:amqp', 'rabbitmq-server:amqp']
1099- ['barbican:certificates', 'vault:certificates']
1100- ['barbican:ha', 'hacluster-barbican:ha']
1101- ['barbican:identity-service', 'keystone:identity-service']
1102- ['barbican:juju-info', 'filebeat:beats-host']
1103- ['barbican:juju-info', 'landscape-client:container']
1104- ['barbican:juju-info', 'logrotated:juju-info']
1105- ['barbican:juju-info', 'nrpe:general-info']
1106- ['barbican:juju-info', 'public-policy-routing:juju-info']
1107- ['barbican:juju-info', 'telegraf:juju-info']
1108- ['bcache-tuning:juju-info', 'ceph-osd:juju-info']
1109- ['canonical-livepatch:juju-info', 'ceph-osd:juju-info']
1110- ['canonical-livepatch:juju-info', 'vault:juju-info']
1111- ['canonical-livepatch:nrpe-external-master', 'nrpe:nrpe-external-master']
1112- ['ceilometer-agent:amqp', 'rabbitmq-server:amqp']
1113- ['ceilometer-agent:ceilometer-service', 'ceilometer:ceilometer-service']
1114- ['ceilometer-agent:nova-ceilometer', 'nova-compute:nova-ceilometer']
1115- ['ceilometer:amqp', 'rabbitmq-server:amqp']
1116- ['ceilometer:certificates', 'vault:certificates']
1117- ['ceilometer:ha', 'hacluster-ceilometer:ha']
1118- ['ceilometer:identity-credentials', 'keystone:identity-credentials']
1119- ['ceilometer:identity-notifications', 'keystone:identity-notifications']
1120- ['ceilometer:juju-info', 'filebeat:beats-host']
1121- ['ceilometer:juju-info', 'landscape-client:container']
1122- ['ceilometer:juju-info', 'logrotated:juju-info']
1123- ['ceilometer:juju-info', 'nrpe:general-info']
1124- ['ceilometer:juju-info', 'public-policy-routing:juju-info']
1125- ['ceilometer:juju-info', 'telegraf:juju-info']
1126- ['ceilometer:metric-service', 'gnocchi:metric-service']
1127- ['ceilometer:nrpe-external-master', 'nrpe:nrpe-external-master']
1128- ['ceph-dashboard:certificates', 'vault:certificates']
1129- ['ceph-dashboard:dashboard', 'ceph-mon:dashboard']
1130- ['ceph-dashboard:grafana-dashboard', 'grafana:dashboards']
1131- ['ceph-dashboard:prometheus', 'prometheus:website']
1132- ['ceph-mon:client', 'cinder-ceph:ceph']
1133- ['ceph-mon:client', 'glance:ceph']
1134- ['ceph-mon:client', 'gnocchi:storage-ceph']
1135- ['ceph-mon:client', 'nova-compute:ceph']
1136- ['ceph-mon:juju-info', 'filebeat:beats-host']
1137- ['ceph-mon:juju-info', 'landscape-client:container']
1138- ['ceph-mon:juju-info', 'logrotated:juju-info']
1139- ['ceph-mon:juju-info', 'nrpe:general-info']
1140- ['ceph-mon:juju-info', 'telegraf:juju-info']
1141- ['ceph-mon:nrpe-external-master', 'nrpe:nrpe-external-master']
1142- ['ceph-mon:osd', 'ceph-osd:mon']
1143- ['ceph-mon:prometheus', 'prometheus:target']
1144- ['ceph-mon:radosgw', 'ceph-radosgw:mon']
1145- ['ceph-osd:juju-info', 'filebeat:beats-host']
1146- ['ceph-osd:juju-info', 'landscape-client:container']
1147- ['ceph-osd:juju-info', 'nrpe:general-info']
1148- ['ceph-osd:juju-info', 'ntp:juju-info']
1149- ['ceph-osd:juju-info', 'telegraf:juju-info']
1150- ['ceph-osd:nrpe-external-master', 'nrpe:nrpe-external-master']
1151- ['ceph-osd:secrets-storage', 'vault:secrets']
1152- ['ceph-radosgw:certificates', 'vault:certificates']
1153- ['ceph-radosgw:ha', 'hacluster-ceph-radosgw:ha']
1154- ['ceph-radosgw:identity-service', 'keystone:identity-service']
1155- ['ceph-radosgw:juju-info', 'filebeat:beats-host']
1156- ['ceph-radosgw:juju-info', 'landscape-client:container']
1157- ['ceph-radosgw:juju-info', 'logrotated:juju-info']
1158- ['ceph-radosgw:juju-info', 'nrpe:general-info']
1159- ['ceph-radosgw:juju-info', 'public-policy-routing:juju-info']
1160- ['ceph-radosgw:juju-info', 'telegraf:juju-info']
1161- ['ceph-radosgw:nrpe-external-master', 'nrpe:nrpe-external-master']
1162- ['cinder-ceph:ceph-access', 'nova-compute:ceph-access']
1163- ['cinder-ceph:storage-backend', 'cinder:storage-backend']
1164- ['cinder-mysql-router:db-router', 'mysql-innodb-cluster:db-router']
1165- ['cinder-mysql-router:shared-db', 'cinder:shared-db']
1166- ['cinder:amqp', 'rabbitmq-server:amqp']
1167- ['cinder:certificates', 'vault:certificates']
1168- ['cinder:ha', 'hacluster-cinder:ha']
1169- ['cinder:identity-service', 'keystone:identity-service']
1170- ['cinder:image-service', 'glance:image-service']
1171- ['cinder:juju-info', 'filebeat:beats-host']
1172- ['cinder:juju-info', 'landscape-client:container']
1173- ['cinder:juju-info', 'logrotated:juju-info']
1174- ['cinder:juju-info', 'nrpe:general-info']
1175- ['cinder:juju-info', 'public-policy-routing:juju-info']
1176- ['cinder:juju-info', 'telegraf:juju-info']
1177- ['cinder:nrpe-external-master', 'nrpe:nrpe-external-master']
1178- ['designate-bind:certificates', 'vault:certificates']
1179- ['designate-bind:dns-backend', 'designate:dns-backend']
1180- ['designate-bind:juju-info', 'public-policy-routing:juju-info']
1181- ['designate-mysql-router:db-router', 'mysql-innodb-cluster:db-router']
1182- ['designate-mysql-router:shared-db', 'designate:shared-db']
1183- ['designate:amqp', 'rabbitmq-server:amqp']
1184- ['designate:certificates', 'vault:certificates']
1185- ['designate:coordinator-memcached', 'memcached:cache']
1186- ['designate:dnsaas', 'neutron-api:external-dns']
1187- ['designate:ha', 'hacluster-designate:ha']
1188- ['designate:identity-service', 'keystone:identity-service']
1189- ['designate:juju-info', 'filebeat:beats-host']
1190- ['designate:juju-info', 'landscape-client:container']
1191- ['designate:juju-info', 'logrotated:juju-info']
1192- ['designate:juju-info', 'nrpe:general-info']
1193- ['designate:juju-info', 'public-policy-routing:juju-info']
1194- ['designate:juju-info', 'telegraf:juju-info']
1195- ['designate:nrpe-external-master', 'nrpe:nrpe-external-master']
1196- ['easyrsa:client', 'etcd:certificates']
1197- ['easyrsa:juju-info', 'filebeat:beats-host']
1198- ['easyrsa:juju-info', 'landscape-client:container']
1199- ['easyrsa:juju-info', 'logrotated:juju-info']
1200- ['easyrsa:juju-info', 'nrpe:general-info']
1201- ['easyrsa:juju-info', 'telegraf:juju-info']
1202- ['etcd:db', 'vault:etcd']
1203- ['etcd:grafana', 'grafana:dashboards']
1204- ['etcd:juju-info', 'filebeat:beats-host']
1205- ['etcd:juju-info', 'landscape-client:container']
1206- ['etcd:juju-info', 'logrotated:juju-info']
1207- ['etcd:juju-info', 'nrpe:general-info']
1208- ['etcd:juju-info', 'telegraf:juju-info']
1209- ['etcd:nrpe-external-master', 'nrpe:nrpe-external-master']
1210- ['etcd:prometheus', 'prometheus:manual-jobs']
1211- ['filebeat:beats-host', 'glance-simplestreams-sync:juju-info']
1212- ['filebeat:beats-host', 'glance:juju-info']
1213- ['filebeat:beats-host', 'gnocchi:juju-info']
1214- ['filebeat:beats-host', 'heat:juju-info']
1215- ['filebeat:beats-host', 'homer-dashboard:juju-info']
1216- ['filebeat:beats-host', 'keystone:juju-info']
1217- ['filebeat:beats-host', 'memcached:juju-info']
1218- ['filebeat:beats-host', 'mysql-innodb-cluster:juju-info']
1219- ['filebeat:beats-host', 'neutron-api:juju-info']
1220- ['filebeat:beats-host', 'nova-cloud-controller:juju-info']
1221- ['filebeat:beats-host', 'octavia:juju-info']
1222- ['filebeat:beats-host', 'openstack-dashboard:juju-info']
1223- ['filebeat:beats-host', 'openstack-service-checks:juju-info']
1224- ['filebeat:beats-host', 'ovn-central:juju-info']
1225- ['filebeat:beats-host', 'placement:juju-info']
1226- ['filebeat:beats-host', 'prometheus-openstack-exporter:juju-info']
1227- ['filebeat:beats-host', 'rabbitmq-server:juju-info']
1228- ['filebeat:beats-host', 'vault:juju-info']
1229- ['filebeat:logstash', 'graylog:beats']
1230- ['glance-mysql-router:db-router', 'mysql-innodb-cluster:db-router']
1231- ['glance-mysql-router:shared-db', 'glance:shared-db']
1232- ['glance-simplestreams-sync:certificates', 'vault:certificates']
1233- ['glance-simplestreams-sync:identity-service', 'keystone:identity-service']
1234- ['glance-simplestreams-sync:juju-info', 'landscape-client:container']
1235- ['glance-simplestreams-sync:juju-info', 'logrotated:juju-info']
1236- ['glance-simplestreams-sync:juju-info', 'nrpe:general-info']
1237- ['glance-simplestreams-sync:juju-info', 'octavia-diskimage-retrofit:juju-info']
1238- ['glance-simplestreams-sync:juju-info', 'telegraf:juju-info']
1239- ['glance-simplestreams-sync:nrpe-external-master', 'nrpe:nrpe-external-master']
1240- ['glance:amqp', 'rabbitmq-server:amqp']
1241- ['glance:certificates', 'vault:certificates']
1242- ['glance:ha', 'hacluster-glance:ha']
1243- ['glance:identity-service', 'keystone:identity-service']
1244- ['glance:image-service', 'nova-cloud-controller:image-service']
1245- ['glance:image-service', 'nova-compute:image-service']
1246- ['glance:juju-info', 'landscape-client:container']
1247- ['glance:juju-info', 'logrotated:juju-info']
1248- ['glance:juju-info', 'nrpe:general-info']
1249- ['glance:juju-info', 'public-policy-routing:juju-info']
1250- ['glance:juju-info', 'telegraf:juju-info']
1251- ['glance:nrpe-external-master', 'nrpe:nrpe-external-master']
1252- ['gnocchi-mysql-router:db-router', 'mysql-innodb-cluster:db-router']
1253- ['gnocchi-mysql-router:shared-db', 'gnocchi:shared-db']
1254- ['gnocchi:amqp', 'rabbitmq-server:amqp']
1255- ['gnocchi:certificates', 'vault:certificates']
1256- ['gnocchi:coordinator-memcached', 'memcached:cache']
1257- ['gnocchi:ha', 'hacluster-gnocchi:ha']
1258- ['gnocchi:identity-service', 'keystone:identity-service']
1259- ['gnocchi:juju-info', 'landscape-client:container']
1260- ['gnocchi:juju-info', 'logrotated:juju-info']
1261- ['gnocchi:juju-info', 'nrpe:general-info']
1262- ['gnocchi:juju-info', 'public-policy-routing:juju-info']
1263- ['gnocchi:juju-info', 'telegraf:juju-info']
1264- ['grafana:application-dashboard', 'homer-dashboard:application-dashboard']
1265- ['grafana:dashboards', 'prometheus-openstack-exporter:dashboards']
1266- ['graylog:application-dashboard', 'homer-dashboard:application-dashboard']
1267- ['hacluster-aodh:nrpe-external-master', 'nrpe:nrpe-external-master']
1268- ['hacluster-barbican:nrpe-external-master', 'nrpe:nrpe-external-master']
1269- ['hacluster-ceilometer:nrpe-external-master', 'nrpe:nrpe-external-master']
1270- ['hacluster-ceph-radosgw:nrpe-external-master', 'nrpe:nrpe-external-master']
1271- ['hacluster-cinder:nrpe-external-master', 'nrpe:nrpe-external-master']
1272- ['hacluster-designate:nrpe-external-master', 'nrpe:nrpe-external-master']
1273- ['hacluster-glance:nrpe-external-master', 'nrpe:nrpe-external-master']
1274- ['hacluster-gnocchi:nrpe-external-master', 'nrpe:nrpe-external-master']
1275- ['hacluster-heat:ha', 'heat:ha']
1276- ['hacluster-heat:nrpe-external-master', 'nrpe:nrpe-external-master']
1277- ['hacluster-keystone:ha', 'keystone:ha']
1278- ['hacluster-keystone:nrpe-external-master', 'nrpe:nrpe-external-master']
1279- ['hacluster-neutron-api:ha', 'neutron-api:ha']
1280- ['hacluster-neutron-api:nrpe-external-master', 'nrpe:nrpe-external-master']
1281- ['hacluster-nova-cloud-controller:ha', 'nova-cloud-controller:ha']
1282- ['hacluster-nova-cloud-controller:nrpe-external-master', 'nrpe:nrpe-external-master']
1283- ['hacluster-octavia:ha', 'octavia:ha']
1284- ['hacluster-octavia:nrpe-external-master', 'nrpe:nrpe-external-master']
1285- ['hacluster-openstack-dashboard:ha', 'openstack-dashboard:ha']
1286- ['hacluster-openstack-dashboard:nrpe-external-master', 'nrpe:nrpe-external-master']
1287- ['hacluster-placement:ha', 'placement:ha']
1288- ['hacluster-placement:nrpe-external-master', 'nrpe:nrpe-external-master']
1289- ['hacluster-vault:ha', 'vault:ha']
1290- ['hacluster-vault:nrpe-external-master', 'nrpe:nrpe-external-master']
1291- ['heat-mysql-router:db-router', 'mysql-innodb-cluster:db-router']
1292- ['heat-mysql-router:shared-db', 'heat:shared-db']
1293- ['heat:amqp', 'rabbitmq-server:amqp']
1294- ['heat:certificates', 'vault:certificates']
1295- ['heat:identity-service', 'keystone:identity-service']
1296- ['heat:juju-info', 'landscape-client:container']
1297- ['heat:juju-info', 'logrotated:juju-info']
1298- ['heat:juju-info', 'nrpe:general-info']
1299- ['heat:juju-info', 'public-policy-routing:juju-info']
1300- ['heat:juju-info', 'telegraf:juju-info']
1301- ['heat:nrpe-external-master', 'nrpe:nrpe-external-master']
1302- ['homer-dashboard:application-dashboard', 'landscape-server:application-dashboard']
1303- ['homer-dashboard:application-dashboard', 'nagios:application-dashboard']
1304- ['homer-dashboard:juju-info', 'landscape-client:container']
1305- ['homer-dashboard:juju-info', 'logrotated:juju-info']
1306- ['homer-dashboard:juju-info', 'nrpe:general-info']
1307- ['homer-dashboard:juju-info', 'telegraf:juju-info']
1308- ['keystone-ldap:certificates', 'vault:certificates']
1309- ['keystone-ldap:domain-backend', 'keystone:domain-backend']
1310- ['keystone-mysql-router:db-router', 'mysql-innodb-cluster:db-router']
1311- ['keystone-mysql-router:shared-db', 'keystone:shared-db']
1312- ['keystone:certificates', 'vault:certificates']
1313- ['keystone:identity-credentials', 'octavia-diskimage-retrofit:identity-credentials']
1314- ['keystone:identity-credentials', 'openstack-service-checks:identity-credentials']
1315- ['keystone:identity-credentials', 'prometheus-openstack-exporter:identity-credentials']
1316- ['keystone:identity-notifications', 'openstack-service-checks:identity-notifications']
1317- ['keystone:identity-service', 'neutron-api:identity-service']
1318- ['keystone:identity-service', 'nova-cloud-controller:identity-service']
1319- ['keystone:identity-service', 'octavia:identity-service']
1320- ['keystone:identity-service', 'openstack-dashboard:identity-service']
1321- ['keystone:identity-service', 'placement:identity-service']
1322- ['keystone:juju-info', 'landscape-client:container']
1323- ['keystone:juju-info', 'logrotated:juju-info']
1324- ['keystone:juju-info', 'nrpe:general-info']
1325- ['keystone:juju-info', 'public-policy-routing:juju-info']
1326- ['keystone:juju-info', 'telegraf:juju-info']
1327- ['keystone:nrpe-external-master', 'nrpe:nrpe-external-master']
1328- ['landscape-client:container', 'memcached:juju-info']
1329- ['landscape-client:container', 'mysql-innodb-cluster:juju-info']
1330- ['landscape-client:container', 'neutron-api:juju-info']
1331- ['landscape-client:container', 'nova-cloud-controller:juju-info']
1332- ['landscape-client:container', 'octavia:juju-info']
1333- ['landscape-client:container', 'openstack-dashboard:juju-info']
1334- ['landscape-client:container', 'openstack-service-checks:juju-info']
1335- ['landscape-client:container', 'ovn-central:juju-info']
1336- ['landscape-client:container', 'placement:juju-info']
1337- ['landscape-client:container', 'prometheus-openstack-exporter:juju-info']
1338- ['landscape-client:container', 'rabbitmq-server:juju-info']
1339- ['landscape-client:container', 'vault:juju-info']
1340- ['lldpd:juju-info', 'nova-compute:juju-info']
1341- ['logrotated:juju-info', 'memcached:juju-info']
1342- ['logrotated:juju-info', 'mysql-innodb-cluster:juju-info']
1343- ['logrotated:juju-info', 'neutron-api:juju-info']
1344- ['logrotated:juju-info', 'nova-cloud-controller:juju-info']
1345- ['logrotated:juju-info', 'octavia:juju-info']
1346- ['logrotated:juju-info', 'openstack-dashboard:juju-info']
1347- ['logrotated:juju-info', 'openstack-service-checks:juju-info']
1348- ['logrotated:juju-info', 'ovn-central:juju-info']
1349- ['logrotated:juju-info', 'placement:juju-info']
1350- ['logrotated:juju-info', 'prometheus-openstack-exporter:juju-info']
1351- ['logrotated:juju-info', 'rabbitmq-server:juju-info']
1352- ['logrotated:juju-info', 'vault:juju-info']
1353- ['memcached:cache', 'nova-cloud-controller:memcache']
1354- ['memcached:juju-info', 'nrpe:general-info']
1355- ['memcached:juju-info', 'telegraf:juju-info']
1356- ['memcached:nrpe-external-master', 'nrpe:nrpe-external-master']
1357- ['mysql-innodb-cluster:db-router', 'neutron-api-mysql-router:db-router']
1358- ['mysql-innodb-cluster:db-router', 'nova-cloud-controller-mysql-router:db-router']
1359- ['mysql-innodb-cluster:db-router', 'octavia-mysql-router:db-router']
1360- ['mysql-innodb-cluster:db-router', 'openstack-dashboard-mysql-router:db-router']
1361- ['mysql-innodb-cluster:db-router', 'placement-mysql-router:db-router']
1362- ['mysql-innodb-cluster:db-router', 'vault-mysql-router:db-router']
1363- ['mysql-innodb-cluster:juju-info', 'nrpe:general-info']
1364- ['mysql-innodb-cluster:juju-info', 'telegraf:juju-info']
1365- ['nagios:monitors', 'nrpe:monitors']
1366- ['neutron-api-mysql-router:shared-db', 'neutron-api:shared-db']
1367- ['neutron-api-plugin-ovn:certificates', 'vault:certificates']
1368- ['neutron-api-plugin-ovn:neutron-plugin', 'neutron-api:neutron-plugin-api-subordinate']
1369- ['neutron-api-plugin-ovn:ovsdb-cms', 'ovn-central:ovsdb-cms']
1370- ['neutron-api:amqp', 'rabbitmq-server:amqp']
1371- ['neutron-api:certificates', 'vault:certificates']
1372- ['neutron-api:juju-info', 'nrpe:general-info']
1373- ['neutron-api:juju-info', 'public-policy-routing:juju-info']
1374- ['neutron-api:juju-info', 'telegraf:juju-info']
1375- ['neutron-api:neutron-api', 'nova-cloud-controller:neutron-api']
1376- ['neutron-api:neutron-load-balancer', 'octavia:neutron-api']
1377- ['neutron-api:nrpe-external-master', 'nrpe:nrpe-external-master']
1378- ['nova-cloud-controller-mysql-router:shared-db', 'nova-cloud-controller:shared-db']
1379- ['nova-cloud-controller:amqp', 'rabbitmq-server:amqp']
1380- ['nova-cloud-controller:certificates', 'vault:certificates']
1381- ['nova-cloud-controller:cloud-compute', 'nova-compute:cloud-compute']
1382- ['nova-cloud-controller:juju-info', 'nrpe:general-info']
1383- ['nova-cloud-controller:juju-info', 'public-policy-routing:juju-info']
1384- ['nova-cloud-controller:juju-info', 'telegraf:juju-info']
1385- ['nova-cloud-controller:nrpe-external-master', 'nrpe:nrpe-external-master']
1386- ['nova-cloud-controller:placement', 'placement:placement']
1387- ['nova-compute:amqp', 'rabbitmq-server:amqp']
1388- ['nova-compute:juju-info', 'prometheus-libvirt-exporter:juju-info']
1389- ['nova-compute:neutron-plugin', 'ovn-chassis:nova-compute']
1390- ['nova-compute:nrpe-external-master', 'nrpe:nrpe-external-master']
1391- ['nova-compute:secrets-storage', 'vault:secrets']
1392- ['nrpe:general-info', 'octavia:juju-info']
1393- ['nrpe:general-info', 'openstack-dashboard:juju-info']
1394- ['nrpe:general-info', 'openstack-service-checks:juju-info']
1395- ['nrpe:general-info', 'ovn-central:juju-info']
1396- ['nrpe:general-info', 'placement:juju-info']
1397- ['nrpe:general-info', 'prometheus-openstack-exporter:juju-info']
1398- ['nrpe:general-info', 'rabbitmq-server:juju-info']
1399- ['nrpe:general-info', 'vault:juju-info']
1400- ['nrpe:nrpe-external-master', 'ntp:nrpe-external-master']
1401- ['nrpe:nrpe-external-master', 'octavia:nrpe-external-master']
1402- ['nrpe:nrpe-external-master', 'openstack-dashboard:nrpe-external-master']
1403- ['nrpe:nrpe-external-master', 'openstack-service-checks:nrpe-external-master']
1404- ['nrpe:nrpe-external-master', 'ovn-central:nrpe-external-master']
1405- ['nrpe:nrpe-external-master', 'prometheus-libvirt-exporter:nrpe-external-master']
1406- ['nrpe:nrpe-external-master', 'prometheus-openstack-exporter:nrpe-external-master']
1407- ['nrpe:nrpe-external-master', 'rabbitmq-server:nrpe-external-master']
1408- ['nrpe:nrpe-external-master', 'vault:nrpe-external-master']
1409- ['ntp:juju-info', 'vault:juju-info']
1410- ['octavia-dashboard:certificates', 'vault:certificates']
1411- ['octavia-dashboard:dashboard', 'openstack-dashboard:dashboard-plugin']
1412- ['octavia-diskimage-retrofit:certificates', 'vault:certificates']
1413- ['octavia-mysql-router:shared-db', 'octavia:shared-db']
1414- ['octavia-ovn-chassis:certificates', 'vault:certificates']
1415- ['octavia-ovn-chassis:ovsdb-subordinate', 'octavia:ovsdb-subordinate']
1416- ['octavia-ovn-chassis:ovsdb', 'ovn-central:ovsdb']
1417- ['octavia:amqp', 'rabbitmq-server:amqp']
1418- ['octavia:certificates', 'vault:certificates']
1419- ['octavia:juju-info', 'public-policy-routing:juju-info']
1420- ['octavia:juju-info', 'telegraf:juju-info']
1421- ['octavia:ovsdb-cms', 'ovn-central:ovsdb-cms']
1422- ['openstack-dashboard-mysql-router:shared-db', 'openstack-dashboard:shared-db']
1423- ['openstack-dashboard:certificates', 'vault:certificates']
1424- ['openstack-dashboard:juju-info', 'public-policy-routing:juju-info']
1425- ['openstack-dashboard:juju-info', 'telegraf:juju-info']
1426- ['openstack-service-checks:juju-info', 'telegraf:juju-info']
1427- ['ovn-central:certificates', 'vault:certificates']
1428- ['ovn-central:juju-info', 'telegraf:juju-info']
1429- ['ovn-central:ovsdb', 'ovn-chassis:ovsdb']
1430- ['ovn-chassis:certificates', 'vault:certificates']
1431- ['placement-mysql-router:shared-db', 'placement:shared-db']
1432- ['placement:amqp', 'rabbitmq-server:amqp']
1433- ['placement:certificates', 'vault:certificates']
1434- ['placement:juju-info', 'public-policy-routing:juju-info']
1435- ['placement:juju-info', 'telegraf:juju-info']
1436- ['prometheus-libvirt-exporter:scrape', 'prometheus:target']
1437- ['prometheus-openstack-exporter:juju-info', 'telegraf:juju-info']
1438- ['prometheus-openstack-exporter:prometheus-openstack-exporter-service', 'prometheus:target']
1439- ['prometheus:target', 'telegraf:prometheus-client']
1440- ['rabbitmq-server:juju-info', 'telegraf:juju-info']
1441- ['telegraf:juju-info', 'vault:juju-info']
1442- ['vault-mysql-router:shared-db', 'vault:shared-db']
diff --git a/tests/conftest.py b/tests/unit/conftest.py
0similarity index 100%1443similarity index 100%
1rename from tests/conftest.py1444rename from tests/conftest.py
2rename to tests/unit/conftest.py1445rename to tests/unit/conftest.py
diff --git a/tests/requirements.txt b/tests/unit/requirements.txt
3similarity index 100%1446similarity index 100%
4rename from tests/requirements.txt1447rename from tests/requirements.txt
5rename to tests/unit/requirements.txt1448rename to tests/unit/requirements.txt
diff --git a/tests/test_check_spaces.py b/tests/unit/test_check_spaces.py
6similarity index 100%1449similarity index 100%
7rename from tests/test_check_spaces.py1450rename from tests/test_check_spaces.py
8rename to tests/unit/test_check_spaces.py1451rename to tests/unit/test_check_spaces.py
diff --git a/tests/test_cli.py b/tests/unit/test_cli.py
9similarity index 100%1452similarity index 100%
10rename from tests/test_cli.py1453rename from tests/test_cli.py
11rename to tests/unit/test_cli.py1454rename to tests/unit/test_cli.py
diff --git a/tests/test_cloud.py b/tests/unit/test_cloud.py
12similarity index 100%1455similarity index 100%
13rename from tests/test_cloud.py1456rename from tests/test_cloud.py
14rename to tests/unit/test_cloud.py1457rename to tests/unit/test_cloud.py
diff --git a/tests/test_jujulint.py b/tests/unit/test_jujulint.py
15similarity index 100%1458similarity index 100%
16rename from tests/test_jujulint.py1459rename from tests/test_jujulint.py
17rename to tests/unit/test_jujulint.py1460rename to tests/unit/test_jujulint.py
diff --git a/tests/test_k8s.py b/tests/unit/test_k8s.py
18similarity index 100%1461similarity index 100%
19rename from tests/test_k8s.py1462rename from tests/test_k8s.py
20rename to tests/unit/test_k8s.py1463rename to tests/unit/test_k8s.py
diff --git a/tests/test_logging.py b/tests/unit/test_logging.py
21similarity index 100%1464similarity index 100%
22rename from tests/test_logging.py1465rename from tests/test_logging.py
23rename to tests/unit/test_logging.py1466rename to tests/unit/test_logging.py
diff --git a/tests/test_openstack.py b/tests/unit/test_openstack.py
24similarity index 100%1467similarity index 100%
25rename from tests/test_openstack.py1468rename from tests/test_openstack.py
26rename to tests/unit/test_openstack.py1469rename to tests/unit/test_openstack.py
diff --git a/tox.ini b/tox.ini
index e37275c..31ae64d 100644
--- a/tox.ini
+++ b/tox.ini
@@ -18,7 +18,7 @@ skip_missing_interpreters = True
18[testenv]18[testenv]
19basepython = python3.819basepython = python3.8
20deps =20deps =
21 -r{toxinidir}/tests/requirements.txt21 -r{toxinidir}/tests/unit/requirements.txt
22 -r{toxinidir}/requirements.txt22 -r{toxinidir}/requirements.txt
2323
24[testenv:unit]24[testenv:unit]
@@ -30,11 +30,43 @@ commands =
30 --last-failed-no-failures all \30 --last-failed-no-failures all \
31 --cov-fail-under=100 \31 --cov-fail-under=100 \
32 --cov-report=term-missing \32 --cov-report=term-missing \
33 --cov-report=annotate:tests/report/coverage-annotated \33 --cov-report=annotate:tests/unit/report/coverage-annotated \
34 --cov-report=html:tests/report/coverage-html \34 --cov-report=html:tests/unit/report/coverage-html \
35 --html=tests/report/index.html \35 --html=tests/unit/report/index.html \
36 --junitxml=tests/report/junit.xml36 --junitxml=tests/unit/report/junit.xml \
37setenv = PYTHONPATH={toxinidir}/lib37 --ignore={toxinidir}/tests/functional
38setenv = PYTHONPATH={toxinidir}
39
40[testenv:func]
41passenv =
42 JUJULINT_TEST_*
43deps =
44 {[testenv]deps}
45 -r{toxinidir}/tests/functional/requirements.txt
46commands =
47 pytest -v \
48 --log-cli-level=WARNING \
49 --ignore={toxinidir}/tests/unit \
50 {posargs}
51
52[testenv:func-smoke]
53deps =
54 {[testenv]deps}
55 -r{toxinidir}/tests/functional/requirements.txt
56commands =
57 pytest -v \
58 --log-cli-level=WARNING \
59 --ignore={toxinidir}/tests/unit \
60 -m smoke
61
62[testenv:func-dev]
63deps =
64 {[testenv]deps}
65 -r{toxinidir}/tests/functional/requirements.txt
66commands =
67 pytest -v \
68 --log-cli-level=WARNING \
69 --ignore={toxinidir}/tests/unit
3870
39[testenv:lint]71[testenv:lint]
40commands =72commands =
@@ -48,8 +80,6 @@ commands =
48 black .80 black .
49 isort .81 isort .
5082
51[testenv:func]
52#TODO(gabrielcocenza) add func tests
5383
54[pytest]84[pytest]
55filterwarnings =85filterwarnings =

Subscribers

People subscribed via source and target branches