Skip to content

Commit

Permalink
jupyter-controller upgrade 1.4->1.6 (#37)
Browse files Browse the repository at this point in the history
* build: notebook-controller version bump 1.4-1.6.0-rc0

* feat: upgrades template files 1.4->1.6

* build: libraries version bump

* fix: correct image registry
  • Loading branch information
DnPlas authored Jul 12, 2022
1 parent 2e06dc8 commit 1a9745f
Show file tree
Hide file tree
Showing 4 changed files with 9,341 additions and 2,539 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@
use case of a charm which bundles dashboards and provides a
`provides: grafana-dashboard` interface,
grafana-dashboard:
interface: grafana_dashboard
requires:
grafana-dashboard:
interface: grafana_dashboard
creation of a `GrafanaDashboardProvider` object with the default arguments is
sufficient.
Expand All @@ -31,12 +32,10 @@
be included in your charm with a default path of:
path/to/charm.py
path/to/src/grafana_dashboards/*.tmpl
path/to/src/grafana_dashboards/*.{json|json.tmpl|.tmpl}
Where the `*.tmpl` files are Grafana dashboard JSON data either from the
Where the files are Grafana dashboard JSON data either from the
Grafana marketplace, or directly exported from a Grafana instance.
Dashboards obtain via export or via the marketplace would need to be renamed to have the `*.tmpl`
suffix, otherwise they will not be read.
Refer to the [official docs](https://grafana.com/tutorials/provision-dashboards-and-data-sources/)
for more information.
Expand Down Expand Up @@ -214,7 +213,7 @@ def __init__(self, *args):

# Increment this PATCH version before using `charmcraft publish-lib` or reset
# to 0 if you are raising the major API version
LIBPATCH = 10
LIBPATCH = 12

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -564,7 +563,7 @@ def _convert_dashboard_fields(content: str) -> str:
return json.dumps(dict_content)


def _replace_template_fields(
def _replace_template_fields( # noqa: C901
dict_content: dict, datasources: dict, existing_templates: bool
) -> dict:
"""Make templated fields get cleaned up afterwards.
Expand All @@ -587,11 +586,17 @@ def _replace_template_fields(
#
# COS only knows about Prometheus and Loki.
for panel in panels:
if "datasource" not in panel:
if "datasource" not in panel or not panel.get("datasource", ""):
continue
if not existing_templates:
panel["datasource"] = "${prometheusds}"
else:
if panel["datasource"] in replacements.values():
# Already a known template variable
continue
if not panel["datasource"]:
# Don't worry about null values
continue
# Strip out variable characters and maybe braces
ds = re.sub(r"(\$|\{|\})", "", panel["datasource"])
replacement = replacements.get(datasources[ds], "")
Expand Down Expand Up @@ -655,19 +660,25 @@ class GrafanaDashboardEvent(EventBase):
Enables us to set a clear status on the provider.
"""

def __init__(self, handle, error_message: str = "", valid: bool = False):
def __init__(self, handle, errors: List[Dict[str, str]] = [], valid: bool = False):
super().__init__(handle)
self.error_message = error_message
self.errors = errors
self.error_message = "; ".join([error["error"] for error in errors if "error" in error])
self.valid = valid

def snapshot(self) -> Dict:
"""Save grafana source information."""
return {"error_message": self.error_message, "valid": self.valid}
return {
"error_message": self.error_message,
"valid": self.valid,
"errors": json.dumps(self.errors),
}

def restore(self, snapshot):
"""Restore grafana source information."""
self.error_message = snapshot["error_message"]
self.valid = snapshot["valid"]
self.errors = json.loads(snapshot["errors"])


class GrafanaProviderEvents(ObjectEvents):
Expand Down Expand Up @@ -830,7 +841,13 @@ def _update_all_dashboards_from_dir(self, _: Optional[HookEvent] = None) -> None
if dashboard_id.startswith("file:"):
del stored_dashboard_templates[dashboard_id]

for path in filter(Path.is_file, Path(self._dashboards_path).glob("*.tmpl")):
# Path.glob uses fnmatch on the backend, which is pretty limited, so use a
# custom function for the filter
def _is_dashbaord(p: Path) -> bool:
return p.is_file and p.name.endswith((".json", ".json.tmpl", ".tmpl"))

for path in filter(_is_dashbaord, Path(self._dashboards_path).glob("*")):
# path = Path(path)
id = "file:{}".format(path.stem)
stored_dashboard_templates[id] = self._content_to_dashboard_object(
_encode_dashboard_content(path.read_bytes())
Expand Down Expand Up @@ -1118,16 +1135,20 @@ def _render_dashboards_and_signal_changed(self, relation: Relation) -> bool: #
relation_has_invalid_dashboards = False

for _, (fname, template) in enumerate(templates.items()):
decoded_content = _decode_dashboard_content(template["content"])

decoded_content = None
content = None
error = None
try:
decoded_content = _decode_dashboard_content(template["content"])
content = Template(decoded_content).render()
content = _encode_dashboard_content(_convert_dashboard_fields(content))
except lzma.LZMAError as e:
error = str(e)
relation_has_invalid_dashboards = True
except json.JSONDecodeError as e:
error = str(e.msg)
relation_has_invalid_dashboards = True
logger.warning("Invalid JSON in Grafana dashboard: {}".format(fname))
continue
except TemplateSyntaxError as e:
error = str(e)
relation_has_invalid_dashboards = True
Expand Down Expand Up @@ -1490,7 +1511,12 @@ def _maybe_get_builtin_dashboards(self, event: RelationEvent) -> Dict:
)

if dashboards_path:
for path in filter(Path.is_file, Path(dashboards_path).glob("*.tmpl")):

def _is_dashbaord(p: Path) -> bool:
return p.is_file and p.name.endswith((".json", ".json.tmpl", ".tmpl"))

for path in filter(_is_dashbaord, Path(dashboards_path).glob("*")):
# path = Path(path)
if event.app.name in path.name:
id = "file:{}".format(path.stem)
builtins[id] = self._content_to_dashboard_object(
Expand Down
Loading

0 comments on commit 1a9745f

Please sign in to comment.