flapjack-diner 1.0.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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