autocronitor 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/LICENSE +22 -0
- data/README.md +62 -0
- data/autocronitor.gemspec +20 -0
- data/bin/autocronitor +124 -0
- data/lib/autocronitor/helper.rb +61 -0
- metadata +97 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0d7879ba85bc3cbb42dfb0535bac49e5335fec6a
|
4
|
+
data.tar.gz: 9e72991e8ee4a2de7a364a5ac170fab01e50d4ab
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b144187d9fd5324925930fdb0f5c81735e6cfd9ebcdca7f0249737253feea7c7cd7d8d0449deb928d41f88eb1ca40045467ade33248ec264ef44452f2aa293e2
|
7
|
+
data.tar.gz: 0b541146a3e5996425ed4599ef21987bcdbfae5d6ec4470d2fe1b9f57ec293f04a377e030734264c8212a2ba0ce1bde8dc39724e404c2eec425f98c209499e13
|
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Jon Cowie
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
|
data/README.md
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# autocronitor
|
2
|
+
|
3
|
+
A CLI tool to parse a standard format crontab file, create monitors in cronitor.io for each job, and automatically add the necessary curl commands to the original crontab.
|
4
|
+
|
5
|
+
It assumes that you are using cronitor's "template" feature to configure notifications for your monitors, and that you have created templates which will then be passed to autocronitor.
|
6
|
+
|
7
|
+
Please note, cronitor.io (and therefore autocronitor) do not support "informal" cron expressions such as ```@hourly``` or ```@daily```.
|
8
|
+
## GEM INSTALL
|
9
|
+
autocronitor is available on rubygems.org - if you have that source in your gemrc, you can simply use:
|
10
|
+
|
11
|
+
````
|
12
|
+
gem install autocronitor
|
13
|
+
````
|
14
|
+
|
15
|
+
Autocronitor Usage
|
16
|
+
-----------
|
17
|
+
You can run autocronitor by running the ```autocronitor``` command.
|
18
|
+
|
19
|
+
#### Usage
|
20
|
+
```bash
|
21
|
+
Usage: autocronitor [-aft]
|
22
|
+
|
23
|
+
Specific options:
|
24
|
+
-a, --api-key APIKEY Your cronitor.io API key
|
25
|
+
-f, --filename FILENAME The cron files to read
|
26
|
+
|
27
|
+
Email Options:
|
28
|
+
-t, --templace *TEMPLATES The Cronitor.io templates to send alerts for this monitor to
|
29
|
+
|
30
|
+
Text to exclude:
|
31
|
+
-c, --common-text *COMMONTEXT A space separated list of common text to exclude from cron names
|
32
|
+
-i, --common-include-text *COMMONINCLUDETEXT
|
33
|
+
A space separated list of common text to exclude from cron names (includes strings which contain each phrase)
|
34
|
+
```
|
35
|
+
|
36
|
+
* Mandatory Parameters (you must specify one or the other)
|
37
|
+
* -a, --api-key APIKEY Your cronitor.io API key
|
38
|
+
* -f, --filename FILENAME The crontab files to read
|
39
|
+
* -t, --templace *TEMPLATES The Cronitor.io template(s) to use for notifications
|
40
|
+
|
41
|
+
* Optional Parameters
|
42
|
+
* -c, --common-text *COMMONTEXT A space separated list of common text to exclude from cron names
|
43
|
+
* -i, --common-include-text *COMMONINCLUDETEXT A space separated list of common text to exclude from cron names (includes strings which contain each phrase)
|
44
|
+
|
45
|
+
|
46
|
+
#### Example)
|
47
|
+
|
48
|
+
```text
|
49
|
+
$> autocronitor -a abcdef123456 -f test.conf -t mydefault-template
|
50
|
+
|
51
|
+
Processing file test.conf
|
52
|
+
|
53
|
+
Cron expression: 10 * * * *
|
54
|
+
Cron name: testcron
|
55
|
+
Suggested rules:
|
56
|
+
[{"rule_type"=>"ran_longer_than", "duration"=>1, "human_readable"=>"Ran for longer than 1 hour", "time_unit"=>"hours", "hours_to_followup_alert"=>24}, {"rule_type"=>"not_completed_in", "duration"=>61, "human_readable"=>"Has not received a complete ping in over 61 minutes", "time_unit"=>"minutes", "hours_to_followup_alert"=>24}]
|
57
|
+
Creating monitor testcron...
|
58
|
+
Monitor 'testcron' created with ID abc123
|
59
|
+
|
60
|
+
Writing new test.conf with added Cronitor URLs...
|
61
|
+
```
|
62
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
$:.push File.expand_path('../lib', __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |gem|
|
4
|
+
gem.name = 'autocronitor'
|
5
|
+
gem.version = '0.0.1'
|
6
|
+
gem.authors = ["Jon Cowie"]
|
7
|
+
gem.email = 'jonlives@gmail.com'
|
8
|
+
gem.homepage = 'https://github.com/jonlives/autocronitor'
|
9
|
+
gem.licenses = ['MIT']
|
10
|
+
gem.summary = "A tool to automatically pass a standard-format crontab file and add jobs to cronitor.io for monitoring"
|
11
|
+
gem.description = "A CLI tool to parse a standard format crontab file, create monitors in cronitor.io for each job, and automatically add the necessary curl commands to the original crontab. It assumes that you are using cronitor's 'template' feature to configure notifications for your monitors, and that you have created templates which will then be passed to autocronitor. Please note, cronitor.io (and therefore autocronitor) do not support 'informal' cron expressions such as @hourly or @daily."
|
12
|
+
|
13
|
+
gem.files = `git ls-files`.split($\)
|
14
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
15
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
16
|
+
gem.require_paths = ["lib"]
|
17
|
+
|
18
|
+
gem.add_runtime_dependency 'unirest', '~> 1.1', '>= 1.1.2'
|
19
|
+
gem.add_runtime_dependency 'choice', '~> 0.2', '>= 0.2.0'
|
20
|
+
end
|
data/bin/autocronitor
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
require 'unirest'
|
3
|
+
require 'choice'
|
4
|
+
require 'autocronitor/helper'
|
5
|
+
|
6
|
+
Unirest.default_header 'Accept', 'application/json'
|
7
|
+
Unirest.default_header 'Content-Type', 'application/json'
|
8
|
+
|
9
|
+
|
10
|
+
Choice.options do
|
11
|
+
header ''
|
12
|
+
header 'Specific options:'
|
13
|
+
|
14
|
+
option :api_key, :required => true do
|
15
|
+
short '-a'
|
16
|
+
long '--api-key APIKEY'
|
17
|
+
desc 'Your cronitor.io API key'
|
18
|
+
end
|
19
|
+
|
20
|
+
option :file_name, :required => true do
|
21
|
+
short '-f'
|
22
|
+
long '--filename FILENAME'
|
23
|
+
desc 'The cron files to read'
|
24
|
+
end
|
25
|
+
|
26
|
+
separator ''
|
27
|
+
separator 'Email Options: '
|
28
|
+
|
29
|
+
option :template_name, :required => true do
|
30
|
+
short '-t'
|
31
|
+
long '--templace *TEMPLATES'
|
32
|
+
desc 'The Cronitor.io templates to send alerts for this monitor to'
|
33
|
+
end
|
34
|
+
|
35
|
+
separator ''
|
36
|
+
separator 'Text to exclude: '
|
37
|
+
|
38
|
+
option :common_text do
|
39
|
+
short '-c'
|
40
|
+
long '--common-text *COMMONTEXT'
|
41
|
+
desc 'A space separated list of common text to exclude from cron names'
|
42
|
+
end
|
43
|
+
|
44
|
+
option :common_include_text do
|
45
|
+
short '-i'
|
46
|
+
long '--common-include-text *COMMONINCLUDETEXT'
|
47
|
+
desc 'A space separated list of common text to exclude from cron names (includes strings which contain each phrase)'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
file_name = Choice[:file_name]
|
53
|
+
api_key = Choice[:api_key]
|
54
|
+
template_names = Choice[:template_name]
|
55
|
+
|
56
|
+
# Filter common text out of cron_line so we don't produce an unreadable name
|
57
|
+
common_text = Choice[:common_text]|| %w(SYMFONY_ENV=prod php 2>&1 && >> touch)
|
58
|
+
common_text_include = Choice[:common_include_text]|| %w(/var/log /tmp)
|
59
|
+
|
60
|
+
helper = Autocronitor::Helper.new(api_key)
|
61
|
+
|
62
|
+
# This array will contain lines to be written back to the file
|
63
|
+
new_file_lines = []
|
64
|
+
|
65
|
+
# Check if the file name exists, and exit if not
|
66
|
+
if !File.exists?(file_name)
|
67
|
+
puts "ERROR: File #{file_name} does not exist. Exiting."
|
68
|
+
exit 1
|
69
|
+
else
|
70
|
+
puts "Processing file #{file_name}"
|
71
|
+
puts ""
|
72
|
+
|
73
|
+
# Read all lines from file
|
74
|
+
File.readlines(file_name).each do |line|
|
75
|
+
|
76
|
+
# Skip the current line if it's a comment
|
77
|
+
if line.include?("#") or line == "\n"
|
78
|
+
new_file_lines << line
|
79
|
+
next
|
80
|
+
end
|
81
|
+
|
82
|
+
# Split line by whitespace
|
83
|
+
split_line = line.split(/\s+/m)
|
84
|
+
|
85
|
+
# If we have an @ cron expression - eg @hourly, cronitor doesn't support those, so skip this line
|
86
|
+
if split_line.first.include?("@")
|
87
|
+
puts "Non standard '@' format cron expression detected, cannot create cronitor job. Skpping..."
|
88
|
+
next
|
89
|
+
# Otherwise, we have a standard cron expression, so extract it and the remainder of the line
|
90
|
+
else
|
91
|
+
cron_expression = split_line[0..4].join(" ")
|
92
|
+
remaining_line = split_line[5..-1]
|
93
|
+
end
|
94
|
+
|
95
|
+
# Filter out line segments which include text from the above arrays, then re-join the string
|
96
|
+
filtered_line = remaining_line.select{|segment| !common_text.include?(segment) and !common_text_include.any?{ |word| segment.include?(word) }}.map{|segment|segment.include?("/") ? segment.split("/").last : segment}.join(" ")
|
97
|
+
|
98
|
+
puts "Cron expression: #{cron_expression}"
|
99
|
+
puts "Cron name: #{filtered_line}"
|
100
|
+
|
101
|
+
# Talk to cronitor's suggest API to get auto-generated rules for our cron expression
|
102
|
+
rules = helper.monitor_suggest(cron_expression)
|
103
|
+
puts "Suggested rules:"
|
104
|
+
puts rules.inspect
|
105
|
+
|
106
|
+
# Create a new monitor via cronitor's API with the name and rules we've created
|
107
|
+
puts "Creating monitor #{filtered_line}..."
|
108
|
+
monitor_id = helper.monitor_create(filtered_line,rules,template_names)
|
109
|
+
monitor_url = "#{@monitor_url}/#{monitor_id}"
|
110
|
+
|
111
|
+
# Construct the replacement line to be written back to the file
|
112
|
+
cronitored_line = "#{cron_expression} curl #{monitor_url + '/run'} -m 10 && #{remaining_line.join(" ")} && curl #{monitor_url + '/complete'} -m 10"
|
113
|
+
new_file_lines << cronitored_line
|
114
|
+
puts ""
|
115
|
+
end
|
116
|
+
|
117
|
+
puts "Writing new #{file_name} with added Cronitor URLs..."
|
118
|
+
open(file_name, 'w') { |f|
|
119
|
+
new_file_lines.each do |line|
|
120
|
+
f.puts line
|
121
|
+
end
|
122
|
+
}
|
123
|
+
|
124
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'unirest'
|
2
|
+
|
3
|
+
require 'ipecache/plugins'
|
4
|
+
|
5
|
+
module Autocronitor
|
6
|
+
class Helper
|
7
|
+
|
8
|
+
def initialize(api_key)
|
9
|
+
@monitor_template = {
|
10
|
+
name: '',
|
11
|
+
notifications: {
|
12
|
+
emails: [],
|
13
|
+
slack: [],
|
14
|
+
pagerduty: [],
|
15
|
+
phones: [],
|
16
|
+
webhooks: [],
|
17
|
+
templates: [],
|
18
|
+
},
|
19
|
+
rules: [
|
20
|
+
],
|
21
|
+
note: 'A human-friendly description of this monitor'
|
22
|
+
}
|
23
|
+
|
24
|
+
@api_url = 'https://cronitor.io/v1'
|
25
|
+
@monitor_url = 'https://cronitor.link'
|
26
|
+
@monitor_details = {}
|
27
|
+
@api_key = api_key
|
28
|
+
end
|
29
|
+
|
30
|
+
def monitor_create(monitor_name,rules,template_names)
|
31
|
+
@monitor_template[:name] = monitor_name
|
32
|
+
@monitor_template[:rules] = rules
|
33
|
+
@monitor_template[:notifications][:templates] = rules.kind_of?(Array) ? template_names : [template_names]
|
34
|
+
|
35
|
+
response = Unirest.post(
|
36
|
+
"#{@api_url}/monitors",
|
37
|
+
auth: { user: @api_key },
|
38
|
+
parameters: @monitor_template.to_json
|
39
|
+
)
|
40
|
+
|
41
|
+
monitor_id = response.body["code"]
|
42
|
+
if response.code == 201
|
43
|
+
puts "Monitor '#{monitor_name}' created with ID #{monitor_id}"
|
44
|
+
else
|
45
|
+
puts "Error code: #{response.code} returned, exiting"
|
46
|
+
exit 1
|
47
|
+
end
|
48
|
+
@monitor_details[monitor_name] = monitor_id
|
49
|
+
return "#{@monitor_url}/#{monitor_id}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def monitor_suggest(cron_expression)
|
53
|
+
response = Unirest.get(
|
54
|
+
"#{@api_url}/rules/suggest",
|
55
|
+
auth: { user: @api_key },
|
56
|
+
parameters:{ 'cron-expression' => cron_expression }
|
57
|
+
)
|
58
|
+
return response.body
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: autocronitor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jon Cowie
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-12-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: unirest
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.1'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.1.2
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.1'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.1.2
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: choice
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0.2'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 0.2.0
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0.2'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 0.2.0
|
53
|
+
description: A CLI tool to parse a standard format crontab file, create monitors in
|
54
|
+
cronitor.io for each job, and automatically add the necessary curl commands to the
|
55
|
+
original crontab. It assumes that you are using cronitor's 'template' feature to
|
56
|
+
configure notifications for your monitors, and that you have created templates which
|
57
|
+
will then be passed to autocronitor. Please note, cronitor.io (and therefore autocronitor)
|
58
|
+
do not support 'informal' cron expressions such as @hourly or @daily.
|
59
|
+
email: jonlives@gmail.com
|
60
|
+
executables:
|
61
|
+
- autocronitor
|
62
|
+
extensions: []
|
63
|
+
extra_rdoc_files: []
|
64
|
+
files:
|
65
|
+
- ".gitignore"
|
66
|
+
- LICENSE
|
67
|
+
- README.md
|
68
|
+
- autocronitor.gemspec
|
69
|
+
- bin/autocronitor
|
70
|
+
- lib/autocronitor/helper.rb
|
71
|
+
homepage: https://github.com/jonlives/autocronitor
|
72
|
+
licenses:
|
73
|
+
- MIT
|
74
|
+
metadata: {}
|
75
|
+
post_install_message:
|
76
|
+
rdoc_options: []
|
77
|
+
require_paths:
|
78
|
+
- lib
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
requirements: []
|
90
|
+
rubyforge_project:
|
91
|
+
rubygems_version: 2.2.2
|
92
|
+
signing_key:
|
93
|
+
specification_version: 4
|
94
|
+
summary: A tool to automatically pass a standard-format crontab file and add jobs
|
95
|
+
to cronitor.io for monitoring
|
96
|
+
test_files: []
|
97
|
+
has_rdoc:
|