|
52 | 52 | grafanaDashboards+:: std.foldr(
|
53 | 53 | function(mixinName, acc)
|
54 | 54 | local mixin = $.mixins[mixinName] + mixinProto;
|
55 |
| - if !std.objectHas(mixin, 'grafanaDashboardFolder') |
| 55 | + if !$.isFolderedMixin(mixin) |
56 | 56 | then acc + mixin.grafanaDashboards
|
57 | 57 | else acc,
|
58 | 58 | std.objectFields($.mixins),
|
59 | 59 | {}
|
60 | 60 | ),
|
61 | 61 |
|
62 |
| - dashboardsByFolder+:: std.foldr( |
63 |
| - function(mixinName, acc) |
64 |
| - local mixin = $.mixins[mixinName] + mixinProto; |
65 |
| - if std.objectHas(mixin, 'grafanaDashboardFolder') |
66 |
| - then acc { |
67 |
| - [mixin.grafanaDashboardFolder]: mixin.grafanaDashboards, |
68 |
| - } |
69 |
| - else acc, |
70 |
| - std.objectFields($.mixins), |
71 |
| - {} |
72 |
| - ), |
| 62 | + // Config map names can't contain special chars, this is a hack but will |
| 63 | + // do for now. |
| 64 | + folderID(folder):: |
| 65 | + local lower = std.asciiLower(folder); |
| 66 | + local underscore = std.strReplace(lower, '_', '-'); |
| 67 | + local space = std.strReplace(underscore, ' ', '-'); |
| 68 | + space, |
73 | 69 |
|
74 |
| - local materialise_config_map(config_map_name, dashboards) = |
75 |
| - configMap.new(config_map_name) + |
76 |
| - configMap.withDataMixin({ |
77 |
| - [name]: std.toString(dashboards[name]) |
78 |
| - for name in std.objectFields(dashboards) |
79 |
| - }) + |
80 |
| - configMap.mixin.metadata.withLabels($._config.grafana_dashboard_labels), |
| 70 | + // Helper to decide is a mixin should go in a folder or not. |
| 71 | + isFolderedMixin(m):: |
| 72 | + local mixin = m + mixinProto; |
| 73 | + std.objectHas(mixin, 'grafanaDashboardFolder') && |
| 74 | + std.length(mixin.grafanaDashboards) > 0, |
81 | 75 |
|
82 |
| - // When sharding is enabled, this is a map of config maps, each map named |
83 |
| - // "dashboard-0" ... "dashboard-N" and containing dashboards whose name |
84 |
| - // hashes to that shard. |
85 |
| - dashboards_config_maps: { |
86 |
| - ['dashboard-%d' % shard]: |
87 |
| - materialise_config_map('dashboards-%d' % shard, { |
88 |
| - [name]: $.grafanaDashboards[name] |
89 |
| - for name in std.objectFields($.grafanaDashboards) |
90 |
| - if std.codepoint(std.md5(name)[1]) % $._config.dashboard_config_maps == shard |
91 |
| - }) |
92 |
| - for shard in std.range(0, $._config.dashboard_config_maps - 1) |
| 76 | + // Its super common for a single mixin's worth of dashboards to not even fit |
| 77 | + // in a single config map. So we split each mixin's dashboards up over |
| 78 | + // multiple config maps, depending on the hash of dashboards name. |
| 79 | + local sharded_config_maps(name_prefix, shards, dashboards) = { |
| 80 | + ['%s-%d' % [name_prefix, shard]]: |
| 81 | + configMap.new('%s-%d' % [name_prefix, shard]) + |
| 82 | + configMap.withDataMixin({ |
| 83 | + [name]: std.toString(dashboards[name]) |
| 84 | + for name in std.objectFields(dashboards) |
| 85 | + if std.codepoint(std.md5(name)[1]) % shards == shard |
| 86 | + }) + |
| 87 | + configMap.mixin.metadata.withLabels($._config.grafana_dashboard_labels) |
| 88 | + for shard in std.range(0, shards - 1) |
93 | 89 | },
|
94 | 90 |
|
95 |
| - // A map of config maps, one per folder, for dashboards in folders. |
96 |
| - dashboard_folders_config_maps: { |
97 |
| - ['dashboard-%s' % std.asciiLower(folder)]: |
98 |
| - materialise_config_map( |
99 |
| - 'dashboards-%s' % std.asciiLower(folder), |
100 |
| - $.dashboardsByFolder[folder] |
101 |
| - ) |
102 |
| - for folder in std.objectFields($.dashboardsByFolder) |
103 |
| - }, |
| 91 | + // Map containing all the sharded config maps for dashboards in no folder. |
| 92 | + // ie dashboards_config_maps[dashboard name] -> dashboard |
| 93 | + dashboards_config_maps: |
| 94 | + sharded_config_maps( |
| 95 | + 'dashboards', |
| 96 | + $._config.dashboard_config_maps, |
| 97 | + $.grafanaDashboards, |
| 98 | + ), |
| 99 | + |
| 100 | + // Map containing maps of all the sharded config maps for each folder. |
| 101 | + // ie dashboard_folders_config_maps[dashboard folder][dashboard name] -> dashboard |
| 102 | + dashboard_folders_config_maps: std.foldr( |
| 103 | + function(mixinName, acc) |
| 104 | + local mixin = $.mixins[mixinName] + mixinProto; |
| 105 | + if !$.isFolderedMixin(mixin) |
| 106 | + then acc |
| 107 | + else |
| 108 | + local config_map_name = 'dashboards-%s' % $.folderID(mixin.grafanaDashboardFolder); |
| 109 | + acc { |
| 110 | + [config_map_name]: |
| 111 | + sharded_config_maps( |
| 112 | + config_map_name, |
| 113 | + if std.objectHas(mixin, 'grafanaDashboardShards') |
| 114 | + then mixin.grafanaDashboardShards |
| 115 | + else 1, |
| 116 | + mixin.grafanaDashboards |
| 117 | + ), |
| 118 | + }, |
| 119 | + std.objectFields($.mixins), |
| 120 | + {}, |
| 121 | + ), |
104 | 122 |
|
105 | 123 | // Config map containing the dashboard provisioning YAML, telling
|
106 | 124 | // Grafana where to find the dashboard JSONs.
|
|
123 | 141 | },
|
124 | 142 | ] + [
|
125 | 143 | {
|
126 |
| - name: 'dashboards-%s' % std.asciiLower(folder), |
| 144 | + name: 'dashboards-%s' % $.folderID($.mixins[mixinName].grafanaDashboardFolder), |
127 | 145 | orgId: 1,
|
128 |
| - folder: folder, |
| 146 | + folder: $.mixins[mixinName].grafanaDashboardFolder, |
129 | 147 | type: 'file',
|
130 | 148 | disableDeletion: true,
|
131 | 149 | editable: false,
|
132 | 150 | options: {
|
133 |
| - path: '/grafana/dashboard-folders/%s' % std.asciiLower(folder), |
| 151 | + path: '/grafana/dashboards-%s' % $.folderID($.mixins[mixinName].grafanaDashboardFolder), |
134 | 152 | },
|
135 | 153 | }
|
136 |
| - for folder in std.objectFields($.dashboardsByFolder) |
| 154 | + for mixinName in std.objectFields($.mixins) |
| 155 | + if $.isFolderedMixin($.mixins[mixinName]) |
137 | 156 | ],
|
138 | 157 | }),
|
139 | 158 | }),
|
|
0 commit comments