doggy 0.2.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cf029d6c55560584ae887c90bb30d74c330e028b
4
- data.tar.gz: c3e318a4c4ef35243fbc5e95f163e896b81b7cc3
3
+ metadata.gz: da4b32c34a67bbe226feff1f3a478d9d06c583c5
4
+ data.tar.gz: 5fa09a99ea2dc0380b464cb77e0d4f53ca89419b
5
5
  SHA512:
6
- metadata.gz: d8413005760d002bbb137e09ba19b1907ac0ed778873c680d6ca2f1e659bd621a36fada78843a837da862e207ba369d5a48779f4ee117b7dc30db40f2ee91825
7
- data.tar.gz: 7df10df686ff27ec591e6dd5acfe405d701c4f36fbcf3b3ef1c3c5f3e70021feb4fc015713bf2ae6321de668f8e23f426b817912558bf42bcb4aae2408ab6d4d
6
+ metadata.gz: 38682b7ea6457edbc412f8b2255a88f51bbe960d9665b31527c7fa881db1c9c0d3dcc93f7b70d7bfe3363af4153d48f0a79fb4823ef80647ed115a330a2d3cb6
7
+ data.tar.gz: effd9803a381361a31e3a161876cfa22b0807493f5090bb87903af5d545b2b9a018b6066bff41f28d60dba6daf9330061093c83705150900a2f01eedabfe1969
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.2
4
+ before_install: gem install bundler -v 1.10.6
@@ -0,0 +1,13 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
+
5
+ We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
6
+
7
+ Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
+
9
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
+
11
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
+
13
+ This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
data/Gemfile CHANGED
@@ -1,4 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in doggy.gemspec
4
3
  gemspec
@@ -1,29 +1,44 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- doggy (0.2.0)
5
- dogapi (~> 1.17)
6
- ejson (~> 1.0)
7
- thor (~> 0.19)
8
- thread (~> 0.2)
4
+ doggy (2.0.0)
5
+ json (~> 1.8.3)
6
+ parallel (~> 1.6.1)
7
+ thor (~> 0.19.1)
8
+ virtus (~> 1.0.5)
9
9
 
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
- dogapi (1.20.0)
14
- multi_json
15
- ejson (1.0.0)
16
- multi_json (1.11.2)
13
+ axiom-types (0.1.1)
14
+ descendants_tracker (~> 0.0.4)
15
+ ice_nine (~> 0.11.0)
16
+ thread_safe (~> 0.3, >= 0.3.1)
17
+ coercible (1.0.0)
18
+ descendants_tracker (~> 0.0.1)
19
+ descendants_tracker (0.0.4)
20
+ thread_safe (~> 0.3, >= 0.3.1)
21
+ equalizer (0.0.11)
22
+ ice_nine (0.11.1)
23
+ json (1.8.3)
24
+ minitest (5.8.0)
25
+ parallel (1.6.1)
17
26
  rake (10.4.2)
18
27
  thor (0.19.1)
19
- thread (0.2.2)
28
+ thread_safe (0.3.5)
29
+ virtus (1.0.5)
30
+ axiom-types (~> 0.1)
31
+ coercible (~> 1.0)
32
+ descendants_tracker (~> 0.0, >= 0.0.3)
33
+ equalizer (~> 0.0, >= 0.0.9)
20
34
 
21
35
  PLATFORMS
22
36
  ruby
23
37
 
24
38
  DEPENDENCIES
25
- bundler (~> 1.9)
39
+ bundler (~> 1.10)
26
40
  doggy!
41
+ minitest
27
42
  rake (~> 10.0)
28
43
 
29
44
  BUNDLED WITH
data/README.md CHANGED
@@ -69,29 +69,6 @@ $ doggy mute ID ID ID
69
69
  $ doggy unmute ID ID ID
70
70
  ```
71
71
 
72
- ## Example object definition
73
-
74
- #### Ruby DSL
75
-
76
- A DataDog object will be populated from `obj()` hash as shown below.
77
-
78
- ```ruby
79
- created_at = Time.parse('2015-01-01 14:00:01').to_i * 1000
80
-
81
- query = "sum(last_1m):sum:Engine.current_thrust.status{status:error}.as_count() < 50"
82
-
83
- obj({
84
- created_at: created_at,
85
- id: 100500,
86
- message: "Houston, we have a problem @pagerduty-Houston",
87
- name: "Engine thrust",
88
- query: query,
89
- type: "query alert"
90
- })
91
- ```
92
-
93
- For more examples, check the `examples` directory.
94
-
95
72
  ## Development
96
73
 
97
74
  After checking out the repo, run `bundle install` to install dependencies.
data/Rakefile CHANGED
@@ -1,9 +1,10 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rake/testtask"
3
3
 
4
- Rake::TestTask.new do |t|
5
- t.libs << 'test'
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
6
8
  end
7
9
 
8
- desc "Run tests"
9
10
  task :default => :test
@@ -2,5 +2,13 @@
2
2
 
3
3
  require "bundler/setup"
4
4
  require "doggy"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
5
13
  require "irb"
6
14
  IRB.start
data/bin/setup CHANGED
@@ -3,3 +3,5 @@ set -euo pipefail
3
3
  IFS=$'\n\t'
4
4
 
5
5
  bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -6,8 +6,8 @@ require 'doggy/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "doggy"
8
8
  spec.version = Doggy::VERSION
9
- spec.authors = ["Vlad Gorodetsky"]
10
- spec.email = ["v@gor.io"]
9
+ spec.authors = ["Vlad Gorodetsky", "Andre Medeiros"]
10
+ spec.email = ["v@gor.io", "me@andremedeiros.info"]
11
11
 
12
12
  spec.summary = %q{Syncs DataDog dashboards, alerts, screenboards, and monitors.}
13
13
  spec.description = %q{Syncs DataDog dashboards, alerts, screenboards, and monitors.}
@@ -19,10 +19,12 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ["lib"]
21
21
 
22
- spec.add_development_dependency "bundler", "~> 1.9"
22
+ spec.add_dependency "json", "~> 1.8.3"
23
+ spec.add_dependency "parallel", "~> 1.6.1"
24
+ spec.add_dependency "thor", "~> 0.19.1"
25
+ spec.add_dependency "virtus", "~> 1.0.5"
26
+
27
+ spec.add_development_dependency "bundler", "~> 1.10"
23
28
  spec.add_development_dependency "rake", "~> 10.0"
24
- spec.add_dependency "thor", "~> 0.19"
25
- spec.add_dependency "dogapi", "~> 1.17"
26
- spec.add_dependency "thread", "~> 0.2"
27
- spec.add_dependency "ejson", "~> 1.0"
29
+ spec.add_development_dependency "minitest"
28
30
  end
data/exe/doggy CHANGED
@@ -1,12 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- # Exit cleanly from an early interrupt
4
- Signal.trap('INT') { exit 1 }
5
-
6
- require 'bundler/setup'
7
- require 'doggy/friendly_errors'
8
-
9
- Doggy.with_friendly_errors do
10
- require 'doggy/cli'
11
- Doggy::CLI.start(ARGV, :debug => true)
12
- end
3
+ require "doggy"
4
+ Doggy::CLI.start(ARGV)
@@ -1,103 +1,63 @@
1
- require 'fileutils'
2
- require 'pathname'
3
- require 'json'
4
- require 'yaml'
5
- require 'dogapi'
6
-
7
- require 'doggy/friendly_errors'
8
-
9
- require 'doggy/version'
10
- require 'doggy/errors'
11
- require 'doggy/shared_helpers'
12
- require 'doggy/client'
13
- require 'doggy/worker'
14
- require 'doggy/definition'
15
- require 'doggy/dsl'
16
- require 'doggy/serializer/json'
17
- require 'doggy/serializer/yaml'
18
- require 'doggy/model/dash'
19
- require 'doggy/model/monitor'
20
- require 'doggy/model/screen'
1
+ require "pathname"
2
+ require "net/http"
3
+
4
+ require "doggy/cli"
5
+ require "doggy/cli/edit"
6
+ require "doggy/cli/mute"
7
+ require "doggy/cli/pull"
8
+ require "doggy/cli/push"
9
+ require "doggy/cli/unmute"
10
+ require "doggy/model"
11
+ require "doggy/models/dashboard"
12
+ require "doggy/models/monitor"
13
+ require "doggy/models/screen"
14
+ require "doggy/version"
21
15
 
22
16
  module Doggy
23
- DOG_SKIP_REGEX = /😱|:scream:/i.freeze
24
- MANAGED_BY_DOGGY_REGEX = /🐶|\:dog\:/i.freeze
25
- DEFAULT_SERIALIZER_CLASS = Doggy::Serializer::Json
17
+ DOG_SKIP_REGEX = /\xF0\x9F\x98\xB1|:scream:/i.freeze
18
+ MANAGED_BY_DOGGY_REGEX = /\xF0\x9F\x90\xB6|:dog:/i.freeze
26
19
 
27
- class << self
28
- # @option arguments [Constant] :serializer A specific serializer class to use, will be initialized by doggy and passed the object instance
29
- def serializer(options = {})
30
- @serializer ||= options[:serializer] ? options[:serializer] : DEFAULT_SERIALIZER_CLASS
31
- end
20
+ extend self
32
21
 
33
- def client
34
- Doggy::Client.new
35
- end
22
+ def ui
23
+ (defined?(@ui) && @ui) || (self.ui = Thor::Shell::Color.new)
24
+ end
36
25
 
37
- def objects_path
38
- @objects_path ||= Pathname.new('objects').expand_path(SharedHelpers.find_root).expand_path.tap { |path| FileUtils.mkdir_p(path) }
39
- end
26
+ def ui=(ui)
27
+ @ui = ui
28
+ end
40
29
 
41
- def load_item(f)
42
- item = case File.extname(f)
43
- when '.yaml', '.yml' then Doggy::Serializer::Yaml.load(File.read(f))
44
- when '.json' then Doggy::Serializer::Json.load(File.read(f))
45
- when '.rb' then Doggy::Dsl.evaluate(f).obj
46
- else raise InvalidItemType
47
- end
30
+ def object_root
31
+ @object_root ||= Pathname.new('objects').expand_path(repo_root)
32
+ end
48
33
 
49
- # Hackery to support legacy dash format
50
- {
51
- [
52
- determine_type(item), item['id'] || item['dash']['id']
53
- ] => item['dash'] ? item['dash'] : item
54
- }
55
- end
34
+ def repo_root
35
+ # TODO: Raise error when root can't be found
36
+ current_dir = Dir.pwd
56
37
 
57
- def edit(id_or_filename)
58
- if id_or_filename =~ /json|yml|yaml/
59
- item_from_filename = Doggy.load_item(Doggy.objects_path.join(id_or_filename))
60
- id = item_from_filename.keys[0][1]
38
+ while current_dir != '/' do
39
+ if File.exists?(File.join(current_dir, 'Gemfile')) then
40
+ return Pathname.new(current_dir)
61
41
  else
62
- id = id_or_filename
42
+ current_dir = File.expand_path('../', current_dir)
63
43
  end
64
-
65
- object = (item_from_filename || all_local_items).detect { |(type, object_id), object| object_id.to_s == id.to_s }
66
- if object && object[0] && object[0][0] && type = object[0][0].sub(/^[a-z\d]*/) { $&.capitalize }
67
- Object.const_get("Doggy::#{type}").edit(id)
68
- end
69
- end
70
-
71
- def determine_type(item)
72
- return 'dash' if item['graphs'] || item['dash']
73
- return 'monitor' if item['message']
74
- return 'screen' if item['board_title']
75
- raise InvalidItemType
76
44
  end
45
+ end
77
46
 
78
- def emit_shipit_deployment
79
- Doggy.client.dog.emit_event(
80
- Dogapi::Event.new(ENV['REVISION'], msg_title: "ShipIt Deployment by #{ENV['USER']}", tags: %w(audit shipit), source_type_name: 'shipit')
81
- )
82
- rescue => e
83
- puts "Exception: #{e.message}"
84
- end
47
+ def api_key
48
+ ENV['DATADOG_API_KEY'] || secrets['datadog_api_key']
49
+ end
85
50
 
86
- def current_sha
87
- now = Time.now.to_i
88
- month_ago = now - 3600 * 24 * 30
89
- events = Doggy.client.dog.stream(month_ago, now, tags: %w(audit shipit))[1]['events']
51
+ def application_key
52
+ ENV['DATADOG_APP_KEY'] || secrets['datadog_app_key']
53
+ end
90
54
 
91
- events[0]['text'] # most recetly deployed SHA
92
- rescue => e
93
- puts "Exception: #{e.message}"
94
- end
55
+ protected
95
56
 
96
- def all_local_items
97
- @all_local_items ||= Dir[Doggy.objects_path.join('**/*')].inject({}) do |memo, file|
98
- next if File.directory?(file)
99
- memo.merge!(load_item(file))
100
- end
101
- end
57
+ def secrets
58
+ @secrets ||= begin
59
+ raw = File.read(repo_root.join('secrets.json'))
60
+ JSON.parse(raw)
61
+ end
102
62
  end
103
- end
63
+ end # Doggy
@@ -1,106 +1,64 @@
1
- require 'thor'
2
- require 'doggy'
1
+ require "thor"
3
2
 
4
3
  module Doggy
5
4
  class CLI < Thor
6
5
  include Thor::Actions
7
6
 
8
- def self.start(*)
9
- super
10
- rescue Exception => e
11
- raise e
12
- ensure
13
- end
14
-
15
- def initialize(*args)
16
- super
17
- rescue UnknownArgumentError => e
18
- raise Doggy::InvalidOption, e.message
19
- ensure
20
- self.options ||= {}
21
- end
22
-
23
- check_unknown_options!(:except => [:config, :exec])
24
- stop_on_unknown_option! :exec
25
-
26
- desc "pull OBJECT_ID OBJECT_ID OBJECT_ID", "Pulls objects from DataDog"
7
+ desc "pull", "Pulls objects from Datadog"
27
8
  long_desc <<-D
28
- Pull objects from DataDog. If pull is successful, Doggy exits with a status of 0.
29
- If not, the error is displayed and Doggy exits status 1.
9
+ Pull objects from Datadog. All objects are pulled unless the type switches
10
+ are used.
30
11
  D
31
- def pull(*ids)
32
- require 'doggy/cli/pull'
33
- Pull.new(options.dup, ids).run
34
- end
35
12
 
36
- desc "push [OBJECT_ID OBJECT_ID OBJECT_ID]", "Pushes objects to DataDog"
37
- long_desc <<-D
38
- Pushes objects to DataDog. If push is successful, Doggy exits with a status of 0.
39
- If not, the error is displayed and Doggy exits status 1.
40
- D
41
- def push(*ids)
42
- require 'doggy/cli/push'
43
- Push.new(options.dup, ids).run
44
- end
13
+ method_option "dashboards", type: :boolean, desc: 'Pull dashboards'
14
+ method_option "monitors", type: :boolean, desc: 'Pull monitors'
15
+ method_option "screens", type: :boolean, desc: 'Pull screens'
45
16
 
46
- desc "edit OBJECT_ID", "Edit an existing object on DataDog"
47
- long_desc <<-D
48
- Opens default browser pointing to an object to edit it visually. After you finish, it will
49
- display edit result.
50
- D
51
- def edit(id)
52
- require 'doggy/cli/edit'
53
- Edit.new(options.dup, id).run
17
+ def pull
18
+ CLI::Pull.new(options.dup).run
54
19
  end
55
20
 
56
- desc "delete OBJECT_ID OBJECT_ID OBJECT_ID", "Deletes objects from DataDog"
21
+ desc "push", "Pushes objects to Datadog"
57
22
  long_desc <<-D
58
- Deletes objects from DataDog. If delete is successful, Doggy exits with a status of 0.
59
- If not, the error is displayed and Doggy exits status 1.
23
+ Pushes objects to Datadog. Any objects that aren't skipped and don't have
24
+ the marker in their title will get it as a result of a push.
60
25
  D
61
- def delete(*ids)
62
- require 'doggy/cli/delete'
63
- Delete.new(options.dup, ids).run
26
+
27
+ method_option "dashboards", type: :boolean, desc: 'Pull dashboards'
28
+ method_option "monitors", type: :boolean, desc: 'Pull monitors'
29
+ method_option "screens", type: :boolean, desc: 'Pull screens'
30
+
31
+ def push
32
+ CLI::Push.new(options.dup).run
64
33
  end
65
34
 
35
+
66
36
  desc "mute OBJECT_ID OBJECT_ID OBJECT_ID", "Mutes monitor on DataDog"
67
37
  long_desc <<-D
68
- Mutes monitor on DataDog. If mute is successful, Doggy exits with a status of 0.
69
- If not, the error is displayed and Doggy exits status 1.
38
+ Mutes monitors on Datadog.
70
39
  D
40
+
71
41
  def mute(*ids)
72
- require 'doggy/cli/mute'
73
- Mute.new(options.dup, ids).run
42
+ CLI::Mute.new(options.dup, ids).run
74
43
  end
75
44
 
76
45
  desc "unmute OBJECT_ID OBJECT_ID OBJECT_ID", "Unmutes monitor on DataDog"
77
46
  long_desc <<-D
78
- Deletes objects from DataDog. If delete is successful, Doggy exits with a status of 0.
79
- If not, the error is displayed and Doggy exits status 1.
47
+ Unmutes monitors on datadog
80
48
  D
49
+
81
50
  def unmute(*ids)
82
- require 'doggy/cli/unmute'
83
- Unmute.new(options.dup, ids).run
51
+ CLI::Unmute.new(options.dup, ids).run
84
52
  end
85
53
 
86
- desc "sha", "Detects the most recent SHA deployed by ShipIt"
54
+ desc "edit OBJECT_ID", "Edits an object"
87
55
  long_desc <<-D
88
- Scans DataDog event stream for shipit events what contain most recently deployed version
89
- of DataDog properties.
90
- If not, the error is displayed and Doggy exits status 1.
56
+ Edits an object
91
57
  D
92
- def sha
93
- require 'doggy/cli/sha'
94
- Sha.new.run
95
- end
96
58
 
97
- desc "version", "Prints Doggy version"
98
- long_desc <<-D
99
- Prints Doggy version
100
- D
101
- def version
102
- require 'doggy/cli/version'
103
- Version.new.run
59
+ def edit(id)
60
+ CLI::Edit.new(options.dup, id).run
104
61
  end
105
62
  end
106
63
  end
64
+