flapjack-diner 1.0.0 → 1.2.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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.rubocop.yml +21 -0
  4. data/.rubocop_todo.yml +135 -0
  5. data/Gemfile +7 -0
  6. data/README.md +86 -20
  7. data/flapjack-diner.gemspec +11 -15
  8. data/lib/flapjack-diner.rb +23 -548
  9. data/lib/flapjack-diner/argument_validator.rb +31 -22
  10. data/lib/flapjack-diner/resources/checks.rb +58 -0
  11. data/lib/flapjack-diner/resources/contacts.rb +70 -0
  12. data/lib/flapjack-diner/resources/entities.rb +68 -0
  13. data/lib/flapjack-diner/resources/maintenance_periods.rb +82 -0
  14. data/lib/flapjack-diner/resources/media.rb +61 -0
  15. data/lib/flapjack-diner/resources/notification_rules.rb +66 -0
  16. data/lib/flapjack-diner/resources/notifications.rb +27 -0
  17. data/lib/flapjack-diner/resources/pagerduty_credentials.rb +60 -0
  18. data/lib/flapjack-diner/resources/reports.rb +33 -0
  19. data/lib/flapjack-diner/tools.rb +277 -0
  20. data/lib/flapjack-diner/version.rb +1 -1
  21. data/spec/argument_validator_spec.rb +15 -15
  22. data/spec/flapjack-diner_spec.rb +58 -1275
  23. data/spec/pacts/flapjack-diner-flapjack.json +4522 -0
  24. data/spec/resources/checks_spec.rb +171 -0
  25. data/spec/resources/contacts_spec.rb +297 -0
  26. data/spec/resources/entities_spec.rb +181 -0
  27. data/spec/resources/maintenance_periods_spec.rb +603 -0
  28. data/spec/resources/media_spec.rb +277 -0
  29. data/spec/resources/notification_rules_spec.rb +341 -0
  30. data/spec/resources/notifications_spec.rb +210 -0
  31. data/spec/resources/pagerduty_credentials_spec.rb +243 -0
  32. data/spec/resources/reports_spec.rb +255 -0
  33. data/spec/spec_helper.rb +14 -2
  34. metadata +35 -72
@@ -1,6 +1,5 @@
1
1
  module Flapjack
2
2
  class ArgumentValidator
3
-
4
3
  attr_reader :query
5
4
 
6
5
  def initialize(query = {})
@@ -13,49 +12,56 @@ module Flapjack
13
12
  validations = args.delete(:as)
14
13
  validations = [validations] unless validations.is_a?(Array)
15
14
 
16
- if elements = args[:query]
15
+ elements = args[:query]
16
+
17
+ unless elements.nil?
17
18
  elements = [elements] unless elements.is_a?(Array)
18
- validations.each do |validation|
19
- __send__(validation.to_s.downcase, *elements)
20
- end
19
+ validations.each {|v| __send__(v.to_s.downcase, *elements) }
21
20
  end
22
21
 
23
- raise ArgumentError.new(@errors.join('; ')) unless @errors.empty?
22
+ raise(ArgumentError, @errors.join('; ')) unless @errors.empty?
24
23
  end
25
24
 
26
25
  private
27
26
 
27
+ def valid_time_str?(str)
28
+ Time.iso8601(str)
29
+ true
30
+ rescue ArgumentError
31
+ false
32
+ end
33
+
28
34
  def time(*elements)
29
35
  elements.each do |element|
30
- if target = @query[element]
31
- next if target.respond_to?(:iso8601) || (target.is_a?(String) &&
32
- (begin; Time.iso8601(target); true; rescue ArgumentError; false; end))
33
- @errors << "'#{target}' should be a time object or ISO 8601-formatted string."
34
- end
36
+ target = @query[element]
37
+ next if target.nil? || target.respond_to?(:iso8601) ||
38
+ (target.is_a?(String) && valid_time_str?(target))
39
+ @errors << "'#{target}' should be a time object or ISO " \
40
+ '8601-formatted string.'
35
41
  end
36
42
  end
37
43
 
38
44
  def boolean(*elements)
39
45
  elements.each do |element|
40
- if target = @query[element]
41
- next if [TrueClass, FalseClass].include?(target.class)
42
- @errors << "'#{target}' should be 'true' or 'false'."
43
- end
46
+ target = @query[element]
47
+ next if target.nil? || [TrueClass, FalseClass].include?(target.class)
48
+ @errors << "'#{target}' should be 'true' or 'false'."
44
49
  end
45
50
  end
46
51
 
47
52
  def array_of_strings(*elements)
48
53
  elements.each do |element|
49
- if target = @query[element]
50
- next if target.is_a?(Array) && target.all? {|t| t.is_a?(String)}
51
- @errors << "'#{target}' should be an Array of Strings."
52
- end
54
+ target = @query[element]
55
+ next if target.nil? || (target.is_a?(Array) &&
56
+ target.all? {|t| t.is_a?(String) })
57
+ @errors << "'#{target}' should be an Array of Strings."
53
58
  end
54
59
  end
55
60
 
56
61
  def required(*elements)
57
62
  elements.each do |element|
58
- @errors << "'#{element}' is required." if @query[element].nil?
63
+ next unless @query[element].nil?
64
+ @errors << "'#{element}' is required."
59
65
  end
60
66
  end
61
67
 
@@ -64,10 +70,12 @@ module Flapjack
64
70
  end
65
71
 
66
72
  def method_missing(name, *args)
67
- return super unless klass = classify_name(name)
73
+ klass = classify_name(name)
74
+ return super if klass.nil?
68
75
  elements = args
69
76
  elements.each do |element|
70
- @errors << "'#{element}' is expected to be a #{klass}" unless @query[element].nil? || @query[element].is_a?(klass)
77
+ next if @query[element].nil? || @query[element].is_a?(klass)
78
+ @errors << "'#{element}' is expected to be a #{klass}"
71
79
  end
72
80
  end
73
81
 
@@ -75,6 +83,7 @@ module Flapjack
75
83
  class_name = name.to_s.split('_').map(&:capitalize).join
76
84
  Module.const_get(class_name)
77
85
  rescue NameError
86
+ nil
78
87
  end
79
88
  end
80
89
  end
@@ -0,0 +1,58 @@
1
+ require 'httparty'
2
+ require 'json'
3
+ require 'uri'
4
+
5
+ require 'flapjack-diner/version'
6
+ require 'flapjack-diner/argument_validator'
7
+
8
+ module Flapjack
9
+ module Diner
10
+ module Resources
11
+ module Checks
12
+ def create_checks(*args)
13
+ data = unwrap_create_data(*args)
14
+ validate_params(data) do
15
+ validate :query => :entity_id, :as => [:required, :string]
16
+ validate :query => :name, :as => [:required, :string]
17
+ validate :query => :tags, :as => :array_of_strings
18
+ end
19
+ perform_post('/checks', nil, :checks => data)
20
+ end
21
+
22
+ def checks(*ids)
23
+ perform_get('checks', '/checks', ids)
24
+ end
25
+
26
+ def update_checks(*args)
27
+ ids, params = unwrap_ids(*args), unwrap_params(*args)
28
+ raise "'update_checks' requires at least one check id " \
29
+ 'parameter' if ids.nil? || ids.empty?
30
+ validate_params(params) do
31
+ validate :query => :enabled, :as => :boolean
32
+ validate :query => :tags, :as => :array_of_strings
33
+ end
34
+ perform_patch("/checks/#{escaped_ids(ids)}", nil,
35
+ update_checks_ops(params))
36
+ end
37
+
38
+ private
39
+
40
+ def update_checks_ops(params)
41
+ ops = params.each_with_object([]) do |(k, v), memo|
42
+ case k
43
+ when :enabled
44
+ memo << patch_replace('checks', k, v)
45
+ when :add_tag
46
+ memo << patch_add('checks', 'tags', v)
47
+ when :remove_tag
48
+ memo << patch_remove('checks', 'tags', v)
49
+ end
50
+ end
51
+ raise "'update_checks' did not find any valid update " \
52
+ 'fields' if ops.empty?
53
+ ops
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,70 @@
1
+ require 'httparty'
2
+ require 'json'
3
+ require 'uri'
4
+
5
+ require 'flapjack-diner/version'
6
+ require 'flapjack-diner/argument_validator'
7
+
8
+ module Flapjack
9
+ module Diner
10
+ module Resources
11
+ module Contacts
12
+ def create_contacts(*args)
13
+ data = unwrap_create_data(*args)
14
+ validate_params(data) do
15
+ validate :query => [:first_name, :last_name, :email],
16
+ :as => [:required, :string]
17
+ validate :query => :timezone, :as => :string
18
+ validate :query => :tags, :as => :array_of_strings
19
+ end
20
+ perform_post('/contacts', nil, :contacts => data)
21
+ end
22
+
23
+ def contacts(*ids)
24
+ perform_get('contacts', '/contacts', ids)
25
+ end
26
+
27
+ def update_contacts(*args)
28
+ ids, params = unwrap_ids(*args), unwrap_params(*args)
29
+ raise "'update_contacts' requires at least one contact id " \
30
+ 'parameter' if ids.nil? || ids.empty?
31
+ validate_params(params) do
32
+ validate :query => [:first_name, :last_name,
33
+ :email, :timezone], :as => :string
34
+ validate :query => :tags, :as => :array_of_strings
35
+ end
36
+ perform_patch("/contacts/#{escaped_ids(ids)}", nil,
37
+ update_contacts_ops(params))
38
+ end
39
+
40
+ def delete_contacts(*ids)
41
+ raise "'delete_contacts' requires at least one contact id " \
42
+ 'parameter' if ids.nil? || ids.empty?
43
+ perform_delete('/contacts', ids)
44
+ end
45
+
46
+ private
47
+
48
+ def update_contacts_ops(params)
49
+ ops = params.each_with_object([]) do |(k, v), memo|
50
+ case k
51
+ when :add_entity
52
+ memo << patch_add('contacts', 'entities', v)
53
+ when :remove_entity
54
+ memo << patch_remove('contacts', 'entities', v)
55
+ when :add_notification_rule
56
+ memo << patch_add('contacts', 'notification_rules', v)
57
+ when :remove_notification_rule
58
+ memo << patch_remove('contacts', 'notification_rules', v)
59
+ when :first_name, :last_name, :email, :timezone
60
+ memo << patch_replace('contacts', k, v)
61
+ end
62
+ end
63
+ raise "'update_contacts' did not find any valid update " \
64
+ 'fields' if ops.empty?
65
+ ops
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,68 @@
1
+ require 'httparty'
2
+ require 'json'
3
+ require 'uri'
4
+
5
+ require 'flapjack-diner/version'
6
+ require 'flapjack-diner/argument_validator'
7
+
8
+ module Flapjack
9
+ module Diner
10
+ module Resources
11
+ module Entities
12
+ def create_entities(*args)
13
+ data = unwrap_create_data(*args)
14
+ validate_params(data) do
15
+ validate :query => :id, :as => [:required, :string]
16
+ validate :query => :name, :as => :string
17
+ validate :query => :tags, :as => :array_of_strings
18
+ end
19
+ perform_post('/entities', nil, :entities => data)
20
+ end
21
+
22
+ def entities(*ids)
23
+ perform_get('entities', '/entities', ids)
24
+ end
25
+
26
+ def entities_matching(name_re)
27
+ raise "Must be a regexp: #{name_re.inspect}" unless
28
+ name_re.is_a?(Regexp)
29
+ entities.reject {|e| name_re.match(e[:name]).nil? }
30
+ end
31
+
32
+ def update_entities(*args)
33
+ ids, params = unwrap_ids(*args), unwrap_params(*args)
34
+ raise "'update_entities' requires at least one entity id " \
35
+ ' parameter' if ids.nil? || ids.empty?
36
+ validate_params(params) do
37
+ validate :query => :name, :as => :string
38
+ validate :query => :tags, :as => :array_of_strings
39
+ end
40
+ perform_patch("/entities/#{escaped_ids(ids)}", nil,
41
+ update_entities_ops(params))
42
+ end
43
+
44
+ private
45
+
46
+ def update_entities_ops(params)
47
+ ops = params.each_with_object([]) do |(k, v), memo|
48
+ case k
49
+ when :name
50
+ memo << patch_replace('entities', k, v)
51
+ when :add_contact
52
+ memo << patch_add('entities', 'contacts', v)
53
+ when :remove_contact
54
+ memo << patch_remove('entities', 'contacts', v)
55
+ when :add_tag
56
+ memo << patch_add('entities', 'tags', v)
57
+ when :remove_tag
58
+ memo << patch_remove('entities', 'tags', v)
59
+ end
60
+ end
61
+ raise "'update_entities' did not find any valid update " \
62
+ 'fields' if ops.empty?
63
+ ops
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,82 @@
1
+ require 'httparty'
2
+ require 'json'
3
+ require 'uri'
4
+
5
+ require 'flapjack-diner/version'
6
+ require 'flapjack-diner/argument_validator'
7
+
8
+ module Flapjack
9
+ module Diner
10
+ module Resources
11
+ module MaintenancePeriods
12
+ %w(entities checks).each do |data_type|
13
+ define_method("create_scheduled_maintenances_#{data_type}") do |*args|
14
+ ids, data = unwrap_ids(*args), unwrap_create_data(*args)
15
+ if ids.nil? || ids.empty?
16
+ raise "'create_scheduled_maintenances_#{data_type}' requires " \
17
+ "at least one #{data_type} id parameter"
18
+ end
19
+ validate_params(data) do
20
+ validate :query => :start_time, :as => [:required, :time]
21
+ validate :query => :duration, :as => [:required, :integer]
22
+ validate :query => :summary, :as => :string
23
+ end
24
+ perform_post("/scheduled_maintenances/#{data_type}", ids,
25
+ :scheduled_maintenances => data)
26
+ end
27
+
28
+ define_method("create_unscheduled_maintenances_#{data_type}") do |*a|
29
+ ids, data = unwrap_ids(*a), unwrap_create_data(*a)
30
+ if ids.nil? || ids.empty?
31
+ raise "'create_unscheduled_maintenances_#{data_type}' requires " \
32
+ "at least one #{data_type} id parameter"
33
+ end
34
+ validate_params(data) do
35
+ validate :query => :duration, :as => [:required, :integer]
36
+ validate :query => :summary, :as => :string
37
+ end
38
+ perform_post("/unscheduled_maintenances/#{data_type}", ids,
39
+ :unscheduled_maintenances => data)
40
+ end
41
+
42
+ define_method("update_unscheduled_maintenances_#{data_type}") do |*a|
43
+ ids, params = unwrap_ids(*a), unwrap_params(*a)
44
+ if ids.nil? || ids.empty?
45
+ raise "'update_unscheduled_maintenances_#{data_type}' requires " \
46
+ "at least one #{data_type} id parameter"
47
+ end
48
+ validate_params(params) do
49
+ validate :query => :end_time, :as => :time
50
+ end
51
+ ops = update_unscheduled_maintenances_ops(data_type, params)
52
+ perform_patch("/unscheduled_maintenances/#{data_type}", ids, ops)
53
+ end
54
+
55
+ define_method("delete_scheduled_maintenances_#{data_type}") do |*args|
56
+ ids, params = unwrap_ids(*args), unwrap_params(*args)
57
+ if ids.nil? || ids.empty?
58
+ raise "'delete_scheduled_maintenances_#{data_type}' requires " \
59
+ "at least one #{data_type} id parameter"
60
+ end
61
+ validate_params(params) do
62
+ validate :query => :start_time, :as => [:required, :time]
63
+ end
64
+ perform_delete("/scheduled_maintenances/#{data_type}", ids, params)
65
+ end
66
+ end
67
+
68
+ private
69
+
70
+ def update_unscheduled_maintenances_ops(data_type, params)
71
+ ops = params.each_with_object([]) do |(k, v), memo|
72
+ next unless :end_time.eql?(k)
73
+ memo << patch_replace('unscheduled_maintenances', k, v)
74
+ end
75
+ raise "'update_unscheduled_maintenances_#{data_type}' did not " \
76
+ 'find any valid update fields' if ops.empty?
77
+ ops
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,61 @@
1
+ require 'httparty'
2
+ require 'json'
3
+ require 'uri'
4
+
5
+ require 'flapjack-diner/version'
6
+ require 'flapjack-diner/argument_validator'
7
+
8
+ module Flapjack
9
+ module Diner
10
+ module Resources
11
+ module Media
12
+ def create_contact_media(*args)
13
+ ids, data = unwrap_ids(*args), unwrap_create_data(*args)
14
+ raise "'create_contact_media' requires at least one contact id " \
15
+ 'parameter' if ids.nil? || ids.empty?
16
+ validate_params(data) do
17
+ validate :query => [:type, :address], :as => [:required, :string]
18
+ validate :query => [:interval, :rollup_threshold],
19
+ :as => [:required, :integer]
20
+ end
21
+ perform_post("/contacts/#{escaped_ids(ids)}/media", nil,
22
+ :media => data)
23
+ end
24
+
25
+ def media(*ids)
26
+ perform_get('media', '/media', ids)
27
+ end
28
+
29
+ def update_media(*args)
30
+ ids, params = unwrap_ids(*args), unwrap_params(*args)
31
+ raise "'update_media' requires at least one media id " \
32
+ 'parameter' if ids.nil? || ids.empty?
33
+ validate_params(params) do
34
+ validate :query => :address, :as => :string
35
+ validate :query => [:interval, :rollup_threshold], :as => :integer
36
+ end
37
+ perform_patch("/media/#{escaped_ids(ids)}", nil,
38
+ update_media_ops(params))
39
+ end
40
+
41
+ def delete_media(*ids)
42
+ raise "'delete_media' requires at least one media id " \
43
+ 'parameter' if ids.nil? || ids.empty?
44
+ perform_delete('/media', ids)
45
+ end
46
+
47
+ private
48
+
49
+ def update_media_ops(params)
50
+ ops = params.each_with_object([]) do |(k, v), memo|
51
+ next unless [:address, :interval, :rollup_threshold].include?(k)
52
+ memo << patch_replace('media', k, v)
53
+ end
54
+ raise "'update_media' did not find any valid update " \
55
+ 'fields' if ops.empty?
56
+ ops
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end