├── .gitignore ├── LICENSE ├── README.md ├── index.coffee ├── package.json └── src └── elasticsearch.coffee /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | .DS_Store* 4 | .idea 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Paul Stack 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | hubot-elasticsearch 2 | == 3 | 4 | A Hubot script for interacting with an [elasticsearch](http://www.elasticsearch.org/x) cluster 5 | 6 | Installation 7 | --- 8 | 9 | In hubot project repo, run: 10 | 11 | npm install hubot-elasticsearch --save 12 | 13 | Then add hubot-etcd to your external-scripts.json: 14 | 15 | ``` 16 | [ 17 | "hubot-elasticsearch" 18 | ] 19 | ``` 20 | 21 | Commands 22 | --- 23 | 24 | * hubot: elasticsearch cluster health [cluster] - Gets the cluster health for the given server or alias 25 | * hubot: elasticsearch cat nodes [cluster] - Gets the information from the cat nodes endpoint for the given server or alias 26 | * hubot: elasticsearch cat indexes [cluster] - Gets the information from the cat indexes endpoint for the given server or alias 27 | * hubot: elasticsearch cat allocation [cluster] - Gets the information from the cat allocation endpoint for the given server or alias 28 | * hubot: elasticsearch clear cache [cluster] - Clears the cache for the specified cluster 29 | * hubot: elasticsearch cluster settings [cluster] - Gets a list of all of the settings stored for the cluster 30 | * hubot: elasticsearch index settings [cluster] [index] - Gets a list of all of the settings stored for a particular index 31 | * hubot: elasticsearch disable allocation [cluster] - disables shard allocation to allow nodes to be taken offline 32 | * hubot: elasticsearch enable allocation [cluster] - renables shard allocation 33 | * hubot: elasticsearch show aliases - shows the aliases for the list of ElasticSearch instances 34 | * hubot: elasticsearch add alias [alias name] [url] - sets the alias for a given url 35 | * hubot: elasticsearch clear alias [alias name] - please note that this needs to include any port numbers as appropriate 36 | -------------------------------------------------------------------------------- /index.coffee: -------------------------------------------------------------------------------- 1 | fs = require 'fs' 2 | path = require 'path' 3 | 4 | module.exports = (robot, scripts) -> 5 | scriptsPath = path.resolve(__dirname, 'src') 6 | fs.exists scriptsPath, (exists) -> 7 | if exists 8 | for script in fs.readdirSync(scriptsPath) 9 | if scripts? and '*' not in scripts 10 | robot.loadFile(scriptsPath, script) if script in scripts 11 | else 12 | robot.loadFile(scriptsPath, script) 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hubot-elasticsearch", 3 | "description": "A Hubot script for interacting with an ElasticSearch cluster", 4 | "version": "0.1.1", 5 | "author": "Paul Stack ", 6 | "license": "MIT", 7 | "keywords": "hubot, hubot-scripts, elasticsearch", 8 | "repository": { 9 | "type": "git", 10 | "url": "git://github.com/stack72/hubot-elasticsearch.git" 11 | }, 12 | "bugs": { 13 | "url": "https://github.com/stack72/hubot-elasticsearch/issues" 14 | }, 15 | "dependencies": { 16 | "querystring": "0.2.x" 17 | }, 18 | "peerDependencies": { 19 | "hubot": "2.x" 20 | }, 21 | "devDependencies": { 22 | "hubot": "2.x" 23 | }, 24 | "main": "index.coffee", 25 | "scripts": { 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/elasticsearch.coffee: -------------------------------------------------------------------------------- 1 | # Description: 2 | # Get ElasticSearch Cluster Information 3 | # 4 | # Commands: 5 | # hubot: elasticsearch cluster health [cluster] - Gets the cluster health for the given server or alias 6 | # hubot: elasticsearch cat nodes [cluster] - Gets the information from the cat nodes endpoint for the given server or alias 7 | # hubot: elasticsearch cat indexes [cluster] - Gets the information from the cat indexes endpoint for the given server or alias 8 | # hubot: elasticsearch cat allocation [cluster] - Gets the information from the cat allocation endpoint for the given server or alias 9 | # hubot: elasticsearch clear cache [cluster] - Clears the cache for the specified cluster 10 | # hubot: elasticsearch cluster settings [cluster] - Gets a list of all of the settings stored for the cluster 11 | # hubot: elasticsearch index settings [cluster] [index] - Gets a list of all of the settings stored for a particular index 12 | # hubot: elasticsearch disable allocation [cluster] - disables shard allocation to allow nodes to be taken offline 13 | # hubot: elasticsearch enable allocation [cluster] - renables shard allocation 14 | # hubot: elasticsearch show aliases - shows the aliases for the list of ElasticSearch instances 15 | # hubot: elasticsearch add alias [alias name] [url] - sets the alias for a given url 16 | # hubot: elasticsearch clear alias [alias name] - please note that this needs to include any port numbers as appropriate 17 | # 18 | # Notes: 19 | # The server must be a fqdn (with the port!) to get to the elasticsearch cluster 20 | # 21 | # Author: 22 | # Paul Stack 23 | 24 | _esAliases = {} 25 | 26 | QS = require 'querystring' 27 | 28 | module.exports = (robot) -> 29 | 30 | robot.brain.on 'loaded', -> 31 | if robot.brain.data.elasticsearch_aliases? 32 | _esAliases = robot.brain.data.elasticsearch_aliases 33 | 34 | clusterHealth = (msg, alias) -> 35 | cluster_url = _esAliases[alias] 36 | 37 | if cluster_url == "" || cluster_url == undefined 38 | msg.send("Do not recognise the cluster alias: #{alias}") 39 | else 40 | msg.http("#{cluster_url}/_cat/health?pretty=true") 41 | .get() (err, res, body) -> 42 | msg.send("/code #{body}") 43 | 44 | catNodes = (msg, alias) -> 45 | cluster_url = _esAliases[alias] 46 | 47 | if cluster_url == "" || cluster_url == undefined 48 | msg.send("Do not recognise the cluster alias: #{alias}") 49 | else 50 | msg.send("Getting the cat stats for the cluster: #{cluster_url}") 51 | msg.http("#{cluster_url}/_cat/nodes?h=host,heapPercent,load,segmentsMemory,fielddataMemory,filterCacheMemory,idCacheMemory,percolateMemory,u,heapMax,nodeRole,master") 52 | .get() (err, res, body) -> 53 | lines = body.split("\n") 54 | header = lines.shift() 55 | list = [header].concat(lines.sort().reverse()).join("\n") 56 | msg.send("/code #{list}") 57 | 58 | catIndexes = (msg, alias) -> 59 | cluster_url = _esAliases[alias] 60 | 61 | if cluster_url == "" || cluster_url == undefined 62 | msg.send("Do not recognise the cluster alias: #{alias}") 63 | else 64 | msg.send("Getting the cat indices for the cluster: #{cluster_url}") 65 | msg.http("#{cluster_url}/_cat/indices/logstash-*?h=idx,sm,fm,fcm,im,pm,ss,sc,dc&v") 66 | .get() (err, res, body) -> 67 | lines = body.split("\n") 68 | header = lines.shift() 69 | list = [header].concat(lines.sort().reverse()).join("\n") 70 | msg.send("/code #{list}") 71 | 72 | catAllocation = (msg, alias) -> 73 | cluster_url = _esAliases[alias] 74 | 75 | if cluster_url == "" || cluster_url == undefined 76 | msg.send("Do not recognise the cluster alias: #{alias}") 77 | else 78 | msg.send("Getting the cat allocation for the cluster: #{cluster_url}") 79 | msg.http("#{cluster_url}/_cat/allocation/?h=disk.percent,node,shards,disk.used,disk.avail") 80 | .get() (err, res, body) -> 81 | lines = body.split("\n") 82 | header = lines.shift() 83 | list = [header].concat(lines.sort().reverse()).join("\n") 84 | msg.send("/code #{list}") 85 | 86 | clearCache = (msg, alias) -> 87 | cluster_url = _esAliases[alias] 88 | 89 | if cluster_url == "" || cluster_url == undefined 90 | msg.send("Do not recognise the cluster alias: #{alias}") 91 | else 92 | msg.send("Clearing the cache for the cluster: #{cluster_url}") 93 | msg.http("#{cluster_url}/_cache/clear") 94 | .post() (err, res, body) -> 95 | json = JSON.parse(body) 96 | shards = json['_shards']['total'] 97 | successful = json['_shards']['successful'] 98 | failure = json['_shards']['failed'] 99 | msg.send "Results: \n Total Shards: #{shards} \n Successful: #{successful} \n Failure: #{failure}" 100 | 101 | disableAllocation = (msg, alias) -> 102 | cluster_url = _esAliases[alias] 103 | 104 | if cluster_url == "" || cluster_url == undefined 105 | msg.send("Do not recognise the cluster alias: #{alias}") 106 | else 107 | msg.send("Disabling Allocation for the cluster #{cluster_url}") 108 | 109 | data = { 110 | 'transient': { 111 | 'cluster.routing.allocation.enable': 'none' 112 | } 113 | } 114 | 115 | json = JSON.stringify(data) 116 | msg.http("#{cluster_url}/_cluster/settings") 117 | .put(json) (err, res, body) -> 118 | msg.send("/code #{body}") 119 | 120 | enableAllocation = (msg, alias) -> 121 | cluster_url = _esAliases[alias] 122 | 123 | if cluster_url == "" || cluster_url == undefined 124 | msg.send("Do not recognise the cluster alias: #{alias}") 125 | else 126 | msg.send("Enabling Allocation for the cluster #{cluster_url}") 127 | 128 | data = { 129 | 'transient': { 130 | 'cluster.routing.allocation.enable': 'all' 131 | } 132 | } 133 | 134 | json = JSON.stringify(data) 135 | msg.http("#{cluster_url}/_cluster/settings") 136 | .put(json) (err, res, body) -> 137 | msg.send("/code #{body}") 138 | 139 | showClusterSettings = (msg, alias) -> 140 | cluster_url = _esAliases[alias] 141 | 142 | if cluster_url == "" || cluster_url == undefined 143 | msg.send("Do not recognise the cluster alias: #{alias}") 144 | else 145 | msg.send("Getting the Cluster settings for #{cluster_url}") 146 | msg.http("#{cluster_url}/_cluster/settings?pretty=true") 147 | .get() (err, res, body) -> 148 | msg.send("/code #{body}") 149 | 150 | showIndexSettings = (msg, alias, index) -> 151 | cluster_url = _esAliases[alias] 152 | 153 | if cluster_url == "" || cluster_url == undefined 154 | msg.send("Do not recognise the cluster alias: #{alias}") 155 | else 156 | msg.send("Getting the Index settings for #{index} on #{cluster_url}") 157 | msg.http("#{cluster_url}/#{index}/_settings?pretty=true") 158 | .get() (err, res, body) -> 159 | msg.send("/code #{body}") 160 | 161 | showAliases = (msg) -> 162 | 163 | if _esAliases == null 164 | msg.send("I cannot find any ElasticSearch Cluster aliases") 165 | else 166 | for alias of _esAliases 167 | msg.send("I found '#{alias}' as an alias for the cluster: #{_esAliases[alias]}") 168 | 169 | clearAlias = (msg, alias) -> 170 | delete _esAliases[alias] 171 | robot.brain.data.elasticsearch_aliases = _esAliases 172 | msg.send("The cluster alias #{alias} has been removed") 173 | 174 | setAlias = (msg, alias, url) -> 175 | _esAliases[alias] = url 176 | robot.brain.data.elasticsearch_aliases = _esAliases 177 | msg.send("The cluster alias #{alias} for #{url} has been added to the brain") 178 | 179 | robot.hear /elasticsearch cat nodes (.*)/i, (msg) -> 180 | if msg.message.user.id is robot.name 181 | return 182 | 183 | catNodes msg, msg.match[1], (text) -> 184 | msg.send text 185 | 186 | robot.hear /elasticsearch cat indexes (.*)/i, (msg) -> 187 | if msg.message.user.id is robot.name 188 | return 189 | 190 | catIndexes msg, msg.match[1], (text) -> 191 | msg.send text 192 | 193 | robot.hear /elasticsearch cat allocation (.*)/i, (msg) -> 194 | if msg.message.user.id is robot.name 195 | return 196 | 197 | catAllocation msg, msg.match[1], (text) -> 198 | msg.send text 199 | 200 | robot.hear /elasticsearch cluster settings (.*)/i, (msg) -> 201 | if msg.message.user.id is robot.name 202 | return 203 | 204 | showClusterSettings msg, msg.match[1], (text) -> 205 | msg.send(text) 206 | 207 | robot.hear /elasticsearch cluster health (.*)/i, (msg) -> 208 | if msg.message.user.id is robot.name 209 | return 210 | 211 | clusterHealth msg, msg.match[1], (text) -> 212 | msg.send text 213 | 214 | robot.hear /elasticsearch index settings (.*) (.*)/i, (msg) -> 215 | if msg.message.user.id is robot.name 216 | return 217 | 218 | showIndexSettings msg, msg.match[1], msg.match[2], (text) -> 219 | msg.send text 220 | 221 | robot.hear /elasticsearch show aliases/i, (msg) -> 222 | if msg.message.user.id is robot.name 223 | return 224 | 225 | showAliases msg, (text) -> 226 | msg.send(text) 227 | 228 | robot.hear /elasticsearch add alias (.*) (.*)/i, (msg) -> 229 | if msg.message.user.id is robot.name 230 | return 231 | 232 | setAlias msg, msg.match[1], msg.match[2], (text) -> 233 | msg.send(text) 234 | 235 | robot.hear /elasticsearch clear alias (.*)/i, (msg) -> 236 | if msg.message.user.id is robot.name 237 | return 238 | 239 | clearAlias msg, msg.match[1], (text) -> 240 | msg.send(text) 241 | 242 | robot.respond /elasticsearch clear cache (.*)/i, (msg) -> 243 | if msg.message.user.id is robot.name 244 | return 245 | 246 | clearCache msg, msg.match[1], (text) -> 247 | msg.send(text) 248 | 249 | robot.respond /elasticsearch disable allocation (.*)/i, (msg) -> 250 | if msg.message.user.id is robot.name 251 | return 252 | 253 | disableAllocation msg, msg.match[1], (text) -> 254 | msg.send(text) 255 | 256 | robot.respond /elasticsearch enable allocation (.*)/i, (msg) -> 257 | if msg.message.user.id is robot.name 258 | return 259 | 260 | enableAllocation msg, msg.match[1], (text) -> 261 | msg.send(text) 262 | --------------------------------------------------------------------------------