Repository: weaveworks/grafanalib (language: python)

Issue:
AlertCondition object missing useNewAlerts attribute
looking at https://github.com/weaveworks/grafanalib/blob/c9a77d481da8d76a91ad92efb1a155d6dae8a34d/grafanalib/core.py#L1192
and https://github.com/weaveworks/grafanalib/blob/c9a77d481da8d76a91ad92efb1a155d6dae8a34d/grafanalib/core.py#L1215 its possible to see there is use of self.useNewAlerts but AlertExpression don't have this attribute 


Discussion / hints:
This field is added dynamically when you use the AlertExpression class.

https://github.com/weaveworks/grafanalib/blob/c9a77d481da8d76a91ad92efb1a155d6dae8a34d/grafanalib/core.py#L1312

Adding a new variable to an instance of a class is possible in python
https://docs.python.org/2/tutorial/classes.html#odds-and-ends

We could add `useNewAlerts` as a variable to the AlertCondition class to avoid confusion, if there is an actual issue you are facing?

Thanks for the tip, @JamesGibo. My current workaround is to declare AlertCondition as a variable then set `useNewAlerts` directly:

```
alertCond = AlertCondition( <stuff> )
alertCond.useNewAlerts = False
```

Use case is to generate something for the extraJson field in my dashboard panels so I have the alerts show up there.
@JamesGibo if you can add `useNewAlerts` as a variable to the `AlertCondition` class with the default value for the latest Grafana - it would be very helpful for us. We are using `AlertCondition` outside of `AlertExpression ` as the parameter to [`Alert`]( https://grafanalib.readthedocs.io/en/stable/api/grafanalib.html#grafanalib.core.Alert)

Fix patch:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 7b18f65b..2da345a6 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -2,7 +2,6 @@
 Changelog
 =========
 
-
 0.x.x (?)
 ==================
 
@@ -11,6 +10,7 @@ Changelog
 * Added Maximum option for Timeseries
 * Added Number of decimals displays option for Timeseries* Added Bar_Chart_ panel support
 * Extended SqlTarget to support parsing queries from files
+* Fix AlertCondition backwards compatibility (``useNewAlerts`` default to ``False``)
 
 .. _Bar_Chart: basehttps://grafana.com/docs/grafana/latest/panels-visualizations/visualizations/bar-chart/
 
diff --git a/grafanalib/core.py b/grafanalib/core.py
index e10552ae..aeb1cb33 100644
--- a/grafanalib/core.py
+++ b/grafanalib/core.py
@@ -1197,6 +1197,9 @@ class AlertCondition(object):
         RTYPE_DIFF = 'diff'
         RTYPE_PERCENT_DIFF = 'percent_diff'
         RTYPE_COUNT_NON_NULL = 'count_non_null'
+    :param useNewAlerts: Whether or not the alert condition is used as part of the Grafana 8.x alerts.
+        Defaults to False for compatibility with old Grafana alerts, but automatically overridden to true
+        when used inside ``AlertExpression`` or ``AlertRulev8``
     :param type: CTYPE_*
     """
 
@@ -1205,6 +1208,7 @@ class AlertCondition(object):
     timeRange = attr.ib(default=None, validator=attr.validators.optional(attr.validators.instance_of(TimeRange)))
     operator = attr.ib(default=OP_AND)
     reducerType = attr.ib(default=RTYPE_LAST)
+    useNewAlerts = attr.ib(default=False)
 
     type = attr.ib(default=CTYPE_QUERY, kw_only=True)
 


Test patch:
diff --git a/grafanalib/tests/test_core.py b/grafanalib/tests/test_core.py
index f8178e87..2b03610b 100644
--- a/grafanalib/tests/test_core.py
+++ b/grafanalib/tests/test_core.py
@@ -954,6 +954,33 @@ def test_alertfilefasedfrovisioning():
     assert data['groups'] == groups
 
 
+def test_alertCondition_useNewAlerts_default():
+    alert_condition = G.AlertCondition(
+        G.Target(refId="A"),
+        G.Evaluator('a', 'b'),
+        G.TimeRange('5', '6'),
+        'd',
+        'e'
+    )
+    data = alert_condition.to_json_data()
+    assert data['query']['model'] is not None
+    assert len(data['query']['params']) == 3
+
+
+def test_alertCondition_useNewAlerts_true():
+    alert_condition = G.AlertCondition(
+        G.Target(refId="A"),
+        G.Evaluator('a', 'b'),
+        G.TimeRange('5', '6'),
+        'd',
+        'e',
+        useNewAlerts=True
+    )
+    data = alert_condition.to_json_data()
+    assert 'model' not in data['query']
+    assert len(data['query']['params']) == 1
+
+
 def test_worldmap():
     data_source = 'dummy data source'
     targets = ['dummy_prom_query']