Generate gse topology module for each alarm cluster
diff --git a/heka/_service.sls b/heka/_service.sls
index a571d16..5febf5c 100644
--- a/heka/_service.sls
+++ b/heka/_service.sls
@@ -79,6 +79,7 @@
     'input': {},
     'trigger': {},
     'alarm': {},
+    'alarm_cluster': {},
     'filter': {},
     'splitter': {},
     'encoder': {},
@@ -89,6 +90,7 @@
     'input': {},
     'trigger': {},
     'alarm': {},
+    'alarm_cluster': {},
     'filter': {},
     'splitter': {},
     'encoder': {},
@@ -99,6 +101,7 @@
     'input': {},
     'trigger': {},
     'alarm': {},
+    'alarm_cluster': {},
     'filter': {},
     'splitter': {},
     'encoder': {},
@@ -109,6 +112,7 @@
     'input': {},
     'trigger': {},
     'alarm': {},
+    'alarm_cluster': {},
     'filter': {},
     'splitter': {},
     'encoder': {},
@@ -293,6 +297,24 @@
     policy: {{ policy|yaml }}
 {%- endif %}
 
+{%- for alarm_cluster_name, alarm_cluster in service_metadata.get('alarm_cluster', {}).iteritems() %}
+
+/usr/share/lma_collector/common/gse_{{ alarm_cluster_name|replace('-', '_') }}_topology.lua:
+  file.managed:
+  - source: salt://heka/files/gse_topology.lua
+  - template: jinja
+  - mode: 640
+  - group: heka
+  - require:
+    - file: /usr/share/lma_collector
+  - watch_in:
+    - service: heka_{{ service_name }}_service
+  - defaults:
+      alarm_cluster_name: {{ alarm_cluster_name }}
+      alarm_cluster: {{ alarm_cluster|yaml }}
+
+{%- endfor %}
+
 {%- for filter_name, filter in service_metadata.get('filter', {}).iteritems() %}
 
 /etc/{{ service_name }}/filter_{{ filter_name }}.toml:
diff --git a/heka/files/gse_topology.lua b/heka/files/gse_topology.lua
new file mode 100644
index 0000000..e161ad6
--- /dev/null
+++ b/heka/files/gse_topology.lua
@@ -0,0 +1,31 @@
+-- Copyright 2015-2016 Mirantis, Inc.
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- 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.
+
+local M = {}
+setfenv(1, M) -- Remove external access to contain everything in the module
+
+clusters = {
+    ['{{ alarm_cluster_name|replace("'","\\'") }}'] = {
+{%- set comma = joiner(",") %}
+        ['members'] = {
+{%- for _member in alarm_cluster["members"]|sort -%}
+        {{ comma() }}'{{ _member|replace("'","\\'") }}'
+{%- endfor -%}
+        },
+        ['group_by'] = '{{ alarm_cluster["group_by"]|default("member") }}',
+        ['policy'] = '{{ alarm_cluster["policy"]|replace("'","\\'") }}',
+    },
+}
+
+return M