Merge ~martin-kalcok/juju-lint:warn_on_missing_binding into juju-lint:master

Proposed by Martin Kalcok
Status: Merged
Approved by: Gabriel Cocenza
Approved revision: ce3847ea4d990884ee1d343d02e1e4c80b6fafc1
Merged at revision: e5d34a5b3d630954cfaeed061591ebc7f358d5d1
Proposed branch: ~martin-kalcok/juju-lint:warn_on_missing_binding
Merge into: juju-lint:master
Diff against target: 144 lines (+92/-5)
3 files modified
jujulint/check_spaces.py (+9/-1)
jujulint/lint.py (+13/-4)
tests/test_jujulint.py (+70/-0)
Reviewer Review Type Date Requested Status
Gabriel Cocenza Approve
Review via email: mp+424775@code.launchpad.net

Commit message

Add warnings if bundle does not specify explicit bindings

Description of the change

Added warnings if bundle does not contain explicit bindings for application endpoints.

3 types of warnings added:

* When there are relationships but no application specifies bindings
* When some application specify bindings but others don't
* when application specify bindings but do not include binding for default endpoint ("")

To post a comment you must log in.
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
Gabriel Cocenza (gabrielcocenza) wrote :

Hi Martin.
I've left some comments for you in the code.

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

I left two comments about nit things. I recommend rebase the master branch that is already fixing test_check_spaces_detect_mismatches. Otherwise, LGTM.

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

LGTM.

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

Change successfully merged at revision e5d34a5b3d630954cfaeed061591ebc7f358d5d1

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/jujulint/check_spaces.py b/jujulint/check_spaces.py
index 17b8d8c..337f9b2 100644
--- a/jujulint/check_spaces.py
+++ b/jujulint/check_spaces.py
@@ -1,5 +1,8 @@
1#!/usr/bin/python31#!/usr/bin/python3
2"""Checks for space mismatches between relation endpoints."""2"""Checks for space mismatches between relation endpoints."""
3from logging import getLogger
4
5LOGGER = getLogger(__name__)
36
47
5class Relation:8class Relation:
@@ -116,8 +119,13 @@ def get_application_spaces(application_list, parsed_yaml):
116 """Return a dictionary with app.binding=space mappings."""119 """Return a dictionary with app.binding=space mappings."""
117 app_spaces = {}120 app_spaces = {}
118 for app in application_list:121 for app in application_list:
122 bindings = parsed_yaml["applications"][app].get('bindings', {})
123 if not bindings:
124 LOGGER.warning("Application %s is missing explicit bindings", app)
125 continue
126 if not bindings.get(""):
127 LOGGER.warning("Application %s does not define explicit default binding", app)
119 app_spaces[app] = {}128 app_spaces[app] = {}
120 bindings = parsed_yaml["applications"][app]["bindings"]
121 for name, value in bindings.items():129 for name, value in bindings.items():
122 app_spaces[app][name] = value130 app_spaces[app][name] = value
123 return app_spaces131 return app_spaces
diff --git a/jujulint/lint.py b/jujulint/lint.py
index e908b7a..748fc8a 100755
--- a/jujulint/lint.py
+++ b/jujulint/lint.py
@@ -1106,13 +1106,22 @@ class Linter:
1106 if "relations" in parsed_yaml:1106 if "relations" in parsed_yaml:
1107 # "bindings" *should* be in exported bundles, *unless* no custom bindings exist,1107 # "bindings" *should* be in exported bundles, *unless* no custom bindings exist,
1108 # in which case "juju export-bundle" omits them. See LP#1949883.1108 # in which case "juju export-bundle" omits them. See LP#1949883.
1109 if "bindings" in list(parsed_yaml[applications].values())[0]:1109 bindings = any(
1110 "bindings" in app for app in parsed_yaml[applications].values()
1111 )
1112 if bindings:
1113 # try:
1110 self.check_spaces(parsed_yaml)1114 self.check_spaces(parsed_yaml)
11111115 # except Exception as e:
1116 # self._log_with_header(
1117 # "Encountered error while checking spaces: {}".format(e),
1118 # level=logging.WARN
1119 # )
1112 else:1120 else:
1113 self._log_with_header(1121 self._log_with_header(
1114 "Relations detected but custom bindings not found; "1122 "Relations detected but explicit bindings not found; "
1115 "skipping space binding checks."1123 "Not specifying explicit bindings may cause problems on models"
1124 " with multiple network spaces.", level=logging.WARNING
1116 )1125 )
1117 else:1126 else:
1118 self._log_with_header(1127 self._log_with_header(
diff --git a/tests/test_jujulint.py b/tests/test_jujulint.py
index cff1d6b..11cc514 100644
--- a/tests/test_jujulint.py
+++ b/tests/test_jujulint.py
@@ -6,6 +6,8 @@ from unittest import mock
66
7import pytest7import pytest
88
9from jujulint import check_spaces
10
911
10class TestUtils:12class TestUtils:
11 """Test the jujulint utilities."""13 """Test the jujulint utilities."""
@@ -820,3 +822,71 @@ applications:
820 errors = linter.output_collector["errors"]822 errors = linter.output_collector["errors"]
821 assert len(errors) == 0823 assert len(errors) == 0
822 assert mock_log.call_count == 0824 assert mock_log.call_count == 0
825
826 def test_check_spaces_missing_explicit_bindings(self, linter, mocker):
827 """Test that check_spaces shows warning if some application are missing bindings
828
829 This warning should be triggerred if some applications have bindings and some
830 dont.
831 """
832 logger_mock = mocker.patch.object(check_spaces, "LOGGER")
833
834 app_without_binding = "prometheus-app"
835 bundle = {
836 "applications": {
837 app_without_binding: {},
838 "telegraf-app": {
839 "bindings": {
840 "": "alpha",
841 "prometheus-client": "alpha",
842 },
843 },
844 },
845 "relations": [
846 ["telegraf-app:prometheus-client", "prometheus-app:target"],
847 ],
848 }
849
850 expected_warning = "Application %s is missing explicit bindings"
851
852 linter.check_spaces(bundle)
853
854 logger_mock.warning.assert_called_once_with(expected_warning,
855 app_without_binding)
856
857 def test_check_spaces_missing_default_endpoint_binding(self, linter, mocker):
858 """Raise warning if application is missing explicit default binding.
859
860 Aside from specifying binding for each endpoint explicitly, bundle can also
861 specify default space (represented by empty string ""). Any endpoint that's not
862 mentioned explicitly will be bound to this default space.
863 Juju lint should raise warning if bundles do not define default space.
864 """
865 logger_mock = mocker.patch.object(check_spaces, "LOGGER")
866 app_without_default_space = "telegraf-app"
867
868 bundle = {
869 "applications": {
870 "prometheus-app": {
871 "bindings": {
872 "": "alpha",
873 "target": "alpha",
874 },
875 },
876 app_without_default_space: {
877 "bindings": {
878 "prometheus-client": "alpha",
879 },
880 },
881 },
882 "relations": [
883 ["telegraf-app:prometheus-client", "prometheus-app:target"],
884 ],
885 }
886
887 expected_warning = "Application %s does not define explicit default binding"
888
889 linter.check_spaces(bundle)
890
891 logger_mock.warning.assert_called_once_with(expected_warning,
892 app_without_default_space)

Subscribers

People subscribed via source and target branches