flapjack_configurator 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +47 -0
- data/Dockerfile +11 -0
- data/Gemfile +3 -0
- data/README.md +139 -0
- data/Rakefile +19 -0
- data/bin/flapjack_configurator +82 -0
- data/example.yml +121 -0
- data/flapjack_configurator.gemspec +29 -0
- data/lib/flapjack_configurator.rb +32 -0
- data/lib/flapjack_configurator/entity_mapper.rb +70 -0
- data/lib/flapjack_configurator/flapjack_config.rb +72 -0
- data/lib/flapjack_configurator/flapjack_contact.rb +156 -0
- data/lib/flapjack_configurator/flapjack_media.rb +23 -0
- data/lib/flapjack_configurator/flapjack_notification_rule.rb +39 -0
- data/lib/flapjack_configurator/flapjack_object_base.rb +86 -0
- data/lib/flapjack_configurator/flapjack_pagerduty.rb +28 -0
- data/lib/flapjack_configurator/flapjack_sub_object_base.rb +33 -0
- data/lib/flapjack_configurator/user_configuration.rb +107 -0
- data/lib/flapjack_configurator/version.rb +6 -0
- data/spec/docker_test_wrapper.rb +52 -0
- data/spec/functional/all_entity_spec.rb +19 -0
- data/spec/functional/config_test_common.rb +58 -0
- data/spec/functional/configuration_contact_attributes_spec.rb +18 -0
- data/spec/functional/configuration_contact_entities_spec.rb +116 -0
- data/spec/functional/configuration_contact_notification_media_spec.rb +73 -0
- data/spec/functional/configuration_contact_notification_rules_spec.rb +58 -0
- data/spec/functional/configuration_contact_removal_spec.rb +83 -0
- data/spec/functional/test_configs/changes/attributes.yaml +24 -0
- data/spec/functional/test_configs/changes/notification_media.yaml +155 -0
- data/spec/functional/test_configs/changes/notification_rules.yaml +143 -0
- data/spec/functional/test_configs/entities.yaml +71 -0
- data/spec/functional/test_configs/initial/attributes.yaml +24 -0
- data/spec/functional/test_configs/initial/notification_media.yaml +155 -0
- data/spec/functional/test_configs/initial/notification_rules.yaml +143 -0
- data/spec/functional/test_configs/obj_removal_setup.yaml +106 -0
- data/spec/spec_helper.rb +9 -0
- metadata +211 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: cd6924183c859202d58b0a39d5bd4ef0a90cfbb5
|
4
|
+
data.tar.gz: f65b30f3d4ecf257a2e964dfa3c27f51d5fde57e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 05f44c8e5a7c11334478166df466478e905d1a9cacf1346026232834bf2c0251b04b03c3ba4cb965d3e87d3816b104c3df09579d79ee879f8206615c04031f07
|
7
|
+
data.tar.gz: 02d11b88c7a9d5b03dd73ed44940e48b80cf2ceb30e30b24b4cd5d57944b03280a79efaeec0716cb38c8000ca3dc97e228e9f95bc0e044e9f42da449c8f823bd
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# Disable requirement of "encoding" headers on files
|
2
|
+
Encoding:
|
3
|
+
Enabled: false
|
4
|
+
|
5
|
+
# Increase line length, we're not on VT220s anymore
|
6
|
+
LineLength:
|
7
|
+
Max: 180
|
8
|
+
|
9
|
+
# Increase allowed lines in a method. Short methods are good, but 10 lines
|
10
|
+
# is a bit too low.
|
11
|
+
MethodLength:
|
12
|
+
Max: 40
|
13
|
+
|
14
|
+
# Favor explicit over implicit code: don't complain of "redundant returns"
|
15
|
+
RedundantReturn:
|
16
|
+
Enabled: false
|
17
|
+
|
18
|
+
# Don't complain about if/unless modifiers. The merit of this is debatable
|
19
|
+
# and it will likely require building of over-length lines.
|
20
|
+
IfUnlessModifier:
|
21
|
+
Enabled: false
|
22
|
+
|
23
|
+
# Raise allowed CyclomaticComplexity to 10.
|
24
|
+
CyclomaticComplexity:
|
25
|
+
Max: 10
|
26
|
+
|
27
|
+
# Raise allowed parameter count to 8, 5 is a bit low.
|
28
|
+
ParameterLists:
|
29
|
+
Max: 8
|
30
|
+
|
31
|
+
# 123_456 doesn't add value IMO.
|
32
|
+
NumericLiterals:
|
33
|
+
Enabled: false
|
34
|
+
|
35
|
+
# Turn up Assignment Branch Condition size
|
36
|
+
# This baby's gonna be complicated \m/
|
37
|
+
AbcSize:
|
38
|
+
Max: 40
|
39
|
+
|
40
|
+
# Disable the english library substitution cop: What is the value here?
|
41
|
+
SpecialGlobalVars:
|
42
|
+
Enabled: false
|
43
|
+
|
44
|
+
# Turn up the class length
|
45
|
+
# The contact class is big, and isn't easily pared down.
|
46
|
+
ClassLength:
|
47
|
+
Max: 250
|
data/Dockerfile
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
FROM debian:jessie
|
2
|
+
MAINTAINER Tom Noonan II <thomas.noonan@corvisa.com>
|
3
|
+
|
4
|
+
RUN apt-get update && apt-get install -y ruby bundler git
|
5
|
+
|
6
|
+
COPY ./ /gem_build
|
7
|
+
RUN cd /gem_build; rm -r pkg; bundle install && rake install
|
8
|
+
|
9
|
+
RUN useradd -m flapjackconf
|
10
|
+
USER flapjackconf
|
11
|
+
ENTRYPOINT ["/usr/local/bin/flapjack_configurator"]
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
Flapjack Configurator
|
2
|
+
=====================
|
3
|
+
|
4
|
+
This gem provides a idempotent, file based fonfigurator for [Flapjack](http://flapjack.io)
|
5
|
+
|
6
|
+
Configuration
|
7
|
+
-------------
|
8
|
+
|
9
|
+
The general config form is:
|
10
|
+
|
11
|
+
```yaml
|
12
|
+
# Example/Demo Flapjack setup file
|
13
|
+
|
14
|
+
baseline_options:
|
15
|
+
notification_media:
|
16
|
+
# Baseline Pagerduty creds
|
17
|
+
# Pagerduty setup takes the domain, a API token to poll for acks, and a service key unique to the Pagerduty service
|
18
|
+
# Define the (common) domain id and API token here
|
19
|
+
# Currently only one PD instance is supported to keep the config handling easy. (/lazy)
|
20
|
+
pagerduty:
|
21
|
+
subdomain: foocorp
|
22
|
+
token: PagerDutyAPIToken
|
23
|
+
|
24
|
+
# Contacts!
|
25
|
+
contacts:
|
26
|
+
TestUser:
|
27
|
+
# Details is a direct map to the Flapjack API arguments (except notification related fields)
|
28
|
+
# http://flapjack.io/docs/1.0/jsonapi/#create-contacts
|
29
|
+
details:
|
30
|
+
first_name: Test
|
31
|
+
last_name: User
|
32
|
+
# Email is required but is only used here for documentation
|
33
|
+
email: test.user@example.com
|
34
|
+
timezone: MST7MDT
|
35
|
+
|
36
|
+
notification_media:
|
37
|
+
defaults:
|
38
|
+
# Re-notify every 30 minutes
|
39
|
+
interval: 1800
|
40
|
+
rollup_threshold: 3
|
41
|
+
|
42
|
+
# Only one of each is allowed in Flapjack 1.x :(
|
43
|
+
pagerduty:
|
44
|
+
service_key: PagerDutyServiceKey
|
45
|
+
|
46
|
+
email:
|
47
|
+
address: test.user@example.com
|
48
|
+
|
49
|
+
jabber:
|
50
|
+
address: room@conf.hipchat.com
|
51
|
+
|
52
|
+
notification_rules:
|
53
|
+
default:
|
54
|
+
warning_media:
|
55
|
+
- jabber
|
56
|
+
- email
|
57
|
+
critical_media:
|
58
|
+
- pagerduty
|
59
|
+
- jabber
|
60
|
+
- email
|
61
|
+
|
62
|
+
# Entities: A list of entities to associate with the contact
|
63
|
+
# Priority ordering is:
|
64
|
+
# 1: Exact entities
|
65
|
+
# 2: Blacklist entities
|
66
|
+
# 3: Blacklist regex
|
67
|
+
# 4: Entities regex
|
68
|
+
#
|
69
|
+
# If entities/default is true the contact will be associated with all entities which would otherwise not be associated with any contact.
|
70
|
+
entities:
|
71
|
+
default: false
|
72
|
+
exact:
|
73
|
+
- foo-app-1
|
74
|
+
regex:
|
75
|
+
- "datagen-[0-9]+"
|
76
|
+
entities_blacklist:
|
77
|
+
exact:
|
78
|
+
- datagen-2
|
79
|
+
regex:
|
80
|
+
- "datagen-[78]"
|
81
|
+
```
|
82
|
+
|
83
|
+
Most (but not all) of the options are passed through directly to the API (This is logged at debug level).
|
84
|
+
notification_media and notification_rules are merged down with the per contact rule with the highest precidence, contact defaults, and then baseline_options.
|
85
|
+
The key must be present in the contact to merge to prevent partial settings from being built off defaults.
|
86
|
+
Complete configs at the baseline_option level with automatic inheritance is not currently supported.
|
87
|
+
|
88
|
+
Use
|
89
|
+
===
|
90
|
+
|
91
|
+
WARNING: Passwords/API tokens will be logged at debug log level!
|
92
|
+
|
93
|
+
Command Line
|
94
|
+
------------
|
95
|
+
|
96
|
+
```
|
97
|
+
$ flapjack_configurator -h
|
98
|
+
Usage: flapjack_configurator [options]
|
99
|
+
|
100
|
+
Specific options:
|
101
|
+
-u, --apiurl URL Flapjack API URL
|
102
|
+
-v, --verbosity [level] Set Verbosity, level corresponds to Ruby logger levels (0: debug, 3: error)
|
103
|
+
-f, --files file1,file2,file3 List of YAML config files to load, increasing precidence
|
104
|
+
-h, --help Show this message
|
105
|
+
--version Show version
|
106
|
+
```
|
107
|
+
|
108
|
+
Files is a comma-separated list of yaml files which are merged together to form the configuration.
|
109
|
+
API URL should be of the form "http://${hostname}:${port}"
|
110
|
+
|
111
|
+
Gem
|
112
|
+
---
|
113
|
+
|
114
|
+
```
|
115
|
+
require 'flapjack_configurator'
|
116
|
+
|
117
|
+
FlapjackConfigurator.configure_flapjack(config, api_base_url, logger)
|
118
|
+
```
|
119
|
+
|
120
|
+
### configure_flapjack method:
|
121
|
+
|
122
|
+
- Arguments:
|
123
|
+
- config (Hash): Configuration hash to apply
|
124
|
+
- api_base_url (String)(Default: http://127.0.0.1:3081): Flapjack API URL string to connect to
|
125
|
+
- logger (Logger)(Default: Logger.new(STDOUT)): Logger class to log to
|
126
|
+
- enable_all_entity (Boolean)(Default: true): Add the ALL magic entity if it doesn't exist
|
127
|
+
- Return value: Boolean: true if changes were applied, false otherwise
|
128
|
+
|
129
|
+
Testing
|
130
|
+
=======
|
131
|
+
|
132
|
+
The Rubocop and Rspec coverage are part of the default rake task.
|
133
|
+
Tests spin up a Flapjack container in Docker and interact with its API, no mocks are used.
|
134
|
+
As such a running Docker daemon is required for tests.
|
135
|
+
|
136
|
+
Authors
|
137
|
+
=======
|
138
|
+
|
139
|
+
- Tom Noonan <thomas.noonan@corvisa.com>
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
|
3
|
+
# https://github.com/bbatsov/rubocop#rake-integration
|
4
|
+
begin
|
5
|
+
require 'rubocop/rake_task'
|
6
|
+
RuboCop::RakeTask.new
|
7
|
+
task default: :rubocop
|
8
|
+
rescue LoadError
|
9
|
+
puts 'WARNING: Rubocop unavailable'
|
10
|
+
end
|
11
|
+
|
12
|
+
# https://www.relishapp.com/rspec/rspec-core/docs/command-line/rake-task
|
13
|
+
begin
|
14
|
+
require 'rspec/core/rake_task'
|
15
|
+
RSpec::Core::RakeTask.new(:spec)
|
16
|
+
task default: :spec
|
17
|
+
rescue LoadError
|
18
|
+
puts 'WARNING: Rspec unavailable'
|
19
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'flapjack_configurator'
|
4
|
+
require 'optparse'
|
5
|
+
require 'ostruct'
|
6
|
+
require 'logger'
|
7
|
+
require 'yaml'
|
8
|
+
require 'deep_merge'
|
9
|
+
|
10
|
+
# Parse the command line arguments
|
11
|
+
def parse_arguments(args, logger)
|
12
|
+
options = OpenStruct.new
|
13
|
+
options.api_url = 'http://127.0.0.1:3081'
|
14
|
+
logger.level = Logger::INFO
|
15
|
+
options.files = []
|
16
|
+
|
17
|
+
parser = OptionParser.new do |opts|
|
18
|
+
opts.banner = 'Usage: flapjack_configurator [options]'
|
19
|
+
|
20
|
+
opts.separator ''
|
21
|
+
opts.separator 'Specific options:'
|
22
|
+
|
23
|
+
opts.on('-u', '--apiurl URL', String, 'Flapjack API URL') do |url|
|
24
|
+
options.api_url = url
|
25
|
+
logger.debug("API URL set to #{url}")
|
26
|
+
end
|
27
|
+
|
28
|
+
opts.on('-v', '--verbosity [level]', Integer, 'Set Verbosity, level corresponds to Ruby logger levels (0: debug, 3: error)') do |level|
|
29
|
+
if level
|
30
|
+
logger.level = level
|
31
|
+
else
|
32
|
+
logger.level -= 1 if logger.level > 0
|
33
|
+
end
|
34
|
+
logger.debug('Log level set to #{logger.level}')
|
35
|
+
end
|
36
|
+
|
37
|
+
opts.on('-f', '--files file1,file2,file3', Array, 'List of YAML config files to load, increasing precidence') do |files|
|
38
|
+
options.files += files
|
39
|
+
end
|
40
|
+
|
41
|
+
opts.on_tail('-h', '--help', 'Show this message') do
|
42
|
+
puts opts
|
43
|
+
exit
|
44
|
+
end
|
45
|
+
|
46
|
+
opts.on_tail('--version', 'Show version') do
|
47
|
+
puts "Flapjack Configurator #{Gem.loaded_specs['flapjack_configurator'].version}"
|
48
|
+
exit
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
parser.parse!(args)
|
53
|
+
|
54
|
+
if options.files.length < 1
|
55
|
+
logger.fatal('Option --files is required')
|
56
|
+
exit
|
57
|
+
end
|
58
|
+
|
59
|
+
return options
|
60
|
+
end
|
61
|
+
|
62
|
+
# Load and merge the configs
|
63
|
+
def load_config(file_list, logger)
|
64
|
+
config = {}
|
65
|
+
file_list.each do |file_name|
|
66
|
+
logger.debug("Loading config file #{file_name}")
|
67
|
+
config.deep_merge!(YAML.load_file(file_name))
|
68
|
+
end
|
69
|
+
|
70
|
+
return config
|
71
|
+
end
|
72
|
+
|
73
|
+
def main
|
74
|
+
logger = Logger.new(STDOUT)
|
75
|
+
options = parse_arguments(ARGV, logger)
|
76
|
+
config = load_config(options.files, logger)
|
77
|
+
|
78
|
+
logger.info('Nothing to do') unless FlapjackConfigurator.configure_flapjack(config, options.api_url, logger)
|
79
|
+
end
|
80
|
+
|
81
|
+
# The __FILE__ $0 trick doesn't work when loaded through the gem wrapper
|
82
|
+
main
|
data/example.yml
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
# Example/Demo Flapjack setup file
|
2
|
+
|
3
|
+
baseline_options:
|
4
|
+
notification_media:
|
5
|
+
# Baseline Pagerduty creds
|
6
|
+
# Pagerduty setup takes the domain, a API token to poll for acks, and a service key unique to the Pagerduty service
|
7
|
+
# Define the (common) domain id and API token here
|
8
|
+
# Currently only one PD instance is supported to keep the config handling easy. (/lazy)
|
9
|
+
pagerduty:
|
10
|
+
subdomain: foocorp
|
11
|
+
token: PagerDutyAPIToken
|
12
|
+
|
13
|
+
# Contacts!
|
14
|
+
contacts:
|
15
|
+
TestUser:
|
16
|
+
# Details is a direct map to the Flapjack API arguments (except notification related fields)
|
17
|
+
# http://flapjack.io/docs/1.0/jsonapi/#create-contacts
|
18
|
+
details:
|
19
|
+
first_name: Test
|
20
|
+
last_name: User
|
21
|
+
# Email is required but is only used here for documentation
|
22
|
+
email: test.user@example.com
|
23
|
+
timezone: MST7MDT
|
24
|
+
|
25
|
+
notification_media:
|
26
|
+
defaults:
|
27
|
+
# Re-notify every 30 minutes
|
28
|
+
interval: 1800
|
29
|
+
rollup_threshold: 3
|
30
|
+
|
31
|
+
# Only one of each is allowed in Flapjack 1.x :(
|
32
|
+
pagerduty:
|
33
|
+
service_key: PagerDutyServiceKey
|
34
|
+
|
35
|
+
email:
|
36
|
+
address: test.user@example.com
|
37
|
+
|
38
|
+
jabber:
|
39
|
+
address: room@conf.hipchat.com
|
40
|
+
|
41
|
+
notification_rules:
|
42
|
+
default:
|
43
|
+
warning_media:
|
44
|
+
- jabber
|
45
|
+
- email
|
46
|
+
critical_media:
|
47
|
+
- pagerduty
|
48
|
+
- jabber
|
49
|
+
- email
|
50
|
+
|
51
|
+
# Entities: An exact list of entities
|
52
|
+
# Priority ordering is:
|
53
|
+
# 1: Exact entities
|
54
|
+
# 2: Blacklist entities
|
55
|
+
# 3: Blacklist regex
|
56
|
+
# 4: Entities regex
|
57
|
+
entities:
|
58
|
+
exact:
|
59
|
+
- foo-app-1
|
60
|
+
regex:
|
61
|
+
- "datagen-[0-9]+"
|
62
|
+
entities_blacklist:
|
63
|
+
exact:
|
64
|
+
- datagen-2
|
65
|
+
regex:
|
66
|
+
- "datagen-[78]"
|
67
|
+
|
68
|
+
DefaultUser:
|
69
|
+
details:
|
70
|
+
first_name: Default
|
71
|
+
last_name: User
|
72
|
+
email: default.user@example.com
|
73
|
+
timezone: MST7MDT
|
74
|
+
|
75
|
+
notification_media:
|
76
|
+
defaults:
|
77
|
+
# Re-notify every 30 minutes
|
78
|
+
interval: 1800
|
79
|
+
rollup_threshold: 3
|
80
|
+
|
81
|
+
# Only one of each is allowed in Flapjack 1.x :(
|
82
|
+
email:
|
83
|
+
address: test.user@example.com
|
84
|
+
|
85
|
+
notification_rules:
|
86
|
+
default:
|
87
|
+
warning_media:
|
88
|
+
- email
|
89
|
+
critical_media:
|
90
|
+
- email
|
91
|
+
|
92
|
+
entities:
|
93
|
+
default: true
|
94
|
+
|
95
|
+
Beard:
|
96
|
+
details:
|
97
|
+
first_name: Beard
|
98
|
+
last_name: User
|
99
|
+
email: beard.user@example.com
|
100
|
+
timezone: CST6CDT
|
101
|
+
|
102
|
+
notification_media:
|
103
|
+
defaults:
|
104
|
+
# Re-notify every 30 minutes
|
105
|
+
interval: 1800
|
106
|
+
rollup_threshold: 3
|
107
|
+
|
108
|
+
# Only one of each is allowed in Flapjack 1.x :(
|
109
|
+
email:
|
110
|
+
address: beard.user@example.com
|
111
|
+
|
112
|
+
notification_rules:
|
113
|
+
default:
|
114
|
+
warning_media:
|
115
|
+
- email
|
116
|
+
critical_media:
|
117
|
+
- email
|
118
|
+
|
119
|
+
entities:
|
120
|
+
exact:
|
121
|
+
- ALL
|
@@ -0,0 +1,29 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'flapjack_configurator/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.authors = ['Tom Noonan II']
|
7
|
+
gem.email = 'thomas.noonan@corvisa.com'
|
8
|
+
gem.description = 'FlapjackConfigurator loads a user specified config from YAML files and loads them idempotently into Flapjack via the Flapjack API'
|
9
|
+
gem.summary = 'Flapjack configuration tool'
|
10
|
+
gem.homepage = 'https://github.com/CVTJNII/FlapjackConfigurator'
|
11
|
+
gem.license = 'Apache License, Version 2'
|
12
|
+
|
13
|
+
gem.files = `git ls-files`.split($\) - ['Gemfile.lock']
|
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.name = 'flapjack_configurator'
|
17
|
+
gem.require_paths = ['lib']
|
18
|
+
gem.version = FlapjackConfigurator::VERSION
|
19
|
+
|
20
|
+
gem.add_dependency 'flapjack-diner', '~>1.4'
|
21
|
+
gem.add_dependency 'ruby_deep_clone', '~>0.6'
|
22
|
+
gem.add_dependency 'deep_merge', '~>1.0'
|
23
|
+
|
24
|
+
gem.add_development_dependency 'bundler', '~> 1.7'
|
25
|
+
gem.add_development_dependency 'rake', '~> 10.0'
|
26
|
+
gem.add_development_dependency 'rspec'
|
27
|
+
gem.add_development_dependency 'docker-api'
|
28
|
+
gem.add_development_dependency 'simplecov'
|
29
|
+
end
|