dropsonde 0.0.5 → 0.0.6

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
  SHA256:
3
- metadata.gz: 643def01638761803e04cf758bbf627ac821bb091fc7dad50c5b161251534728
4
- data.tar.gz: f0c8a36548214da7beeecee9dc583dcd8d81eceb640b967078fadf5b2978f987
3
+ metadata.gz: f4a87b2c8abe75d07a73a52a48041c2734bb7914a54df3471d696458f3f0cb05
4
+ data.tar.gz: cd2b7d3a36aa9aa386997ab21f7ffee57387819b08a79407b98c5bfdbbcd619d
5
5
  SHA512:
6
- metadata.gz: 7c260e1617666fb83d7b0be1a3d73ad13aaee5c33844d5eb4117b186c6eec23a9aad6dc03ff3df393168b6a3715bf492ce677624fdbe536e4961d956d1e9cdcb
7
- data.tar.gz: cffbe7901afe08afa593ee73fa749358257efcd03d612564b3aac507684897d2d0db3e504a599d1eab7251508c3f455e236985501ea9f6722f108bb02cf80e2e
6
+ metadata.gz: 4a033ee5a796d3dab8c46d7562848255ca66552671f31f58ffde8a5a00f98dbcf1e9485a8279529b7c78094f96add8e932fa401e634ccfc067f5c9b72eed93c3
7
+ data.tar.gz: b86bc1f854fe414a388534ced35132d0744ac21001298d3eefce326afa97a63bd56ce9b250458889690831e7b0343963666377eaf10c25c38861b50e1160225d
data/bin/dropsonde CHANGED
@@ -5,6 +5,9 @@ require 'dropsonde'
5
5
  class Dropsonde
6
6
  extend GLI::App
7
7
 
8
+ @cache = nil
9
+ @puppetdb_session = Dropsonde.new
10
+
8
11
  program_desc 'A simple telemetry tool for Puppet infrastructures'
9
12
  config_file "#{File.dirname(Puppet.settings[:confdir])}/telemetry.yaml"
10
13
  version Dropsonde::VERSION
@@ -30,15 +33,18 @@ class Dropsonde
30
33
  desc 'Any number or string used to generate the randomized site ID.'
31
34
  flag [:seed]
32
35
 
36
+ desc 'Static site ID'
37
+ flag [:siteid]
38
+
33
39
  pre do |global, command, options, args|
34
40
  Dropsonde.settings = global
35
- Dropsonde::Cache.init(global[:cachepath], global[:ttl], global[:update])
41
+ @cache = Dropsonde::Cache.new(global[:cachepath], global[:ttl], global[:update])
36
42
  end
37
43
 
38
44
  desc 'Manually update the Forge module name cache'
39
45
  command :update do |c|
40
46
  c.action do |global, options, args|
41
- Dropsonde::Cache.update
47
+ @cache.update
42
48
  end
43
49
  end
44
50
 
@@ -55,8 +61,8 @@ class Dropsonde
55
61
  c.flag [:format], :default_value => 'human'
56
62
 
57
63
  c.action do |global, options, args|
58
- Dropsonde::Cache.autoupdate
59
- Dropsonde.generate_report(options[:format])
64
+ @cache.autoupdate
65
+ Dropsonde.generate_report(options[:format], @puppetdb_session)
60
66
  end
61
67
  end
62
68
 
@@ -69,7 +75,7 @@ class Dropsonde
69
75
  c.flag [:port], :default_value => 443, :type => Integer
70
76
 
71
77
  c.action do |global, options, args|
72
- Dropsonde::Cache.autoupdate
78
+ @cache.autoupdate
73
79
  Dropsonde.submit_report(options[:endpoint], options[:port])
74
80
  end
75
81
  end
@@ -111,7 +117,7 @@ class Dropsonde
111
117
  c.flag [:filename], :default_value => 'example.jsonl'
112
118
 
113
119
  c.action do |global, options, args|
114
- Dropsonde::Cache.autoupdate
120
+ @cache.autoupdate
115
121
  Dropsonde.generate_example(options[:size], options[:filename])
116
122
  end
117
123
  end
@@ -1,34 +1,41 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'date'
2
4
  require 'json'
3
5
  require 'fileutils'
4
6
  require 'puppet_forge'
5
7
 
8
+ # cache class
6
9
  class Dropsonde::Cache
7
- @@autoupdate = false
10
+ @autoupdate = false
8
11
 
9
- def self.init(path, ttl, autoupdate)
12
+ def initialize(path, ttl, autoupdate)
10
13
  FileUtils.mkdir_p(path)
11
- @@path = "#{File.expand_path(path)}/forge.json"
12
- @@ttl = ttl
13
- @@autoupdate = autoupdate
14
-
15
- if File.file? @@path
16
- @@cache = JSON.parse(File.read(@@path))
17
- else
18
- @@cache = {
19
- 'timestamp' => '2000-1-1', # long before any puppet modules were released!
20
- 'modules' => [],
21
- }
22
- end
23
-
24
- PuppetForge.user_agent = "Dropsonde Telemetry Client/0.0.1"
14
+ @path = "#{File.expand_path(path)}/forge.json"
15
+ @ttl = ttl
16
+ @autoupdate = autoupdate
17
+
18
+ @@cache = if File.file? @path # rubocop:disable Style/ClassVars
19
+ JSON.parse(File.read(@path))
20
+ else
21
+ {
22
+ 'timestamp' => '2000-1-1', # long before any puppet modules were released!
23
+ 'modules' => [],
24
+ }
25
+ end
26
+
27
+ PuppetForge.user_agent = 'Dropsonde Telemetry Client/0.0.1'
25
28
  end
26
29
 
27
- def self.modules
30
+ def modules
28
31
  @@cache['modules']
29
32
  end
30
33
 
31
- def self.forgeModule?(mod)
34
+ def cache
35
+ @@cache
36
+ end
37
+
38
+ def self.forge_module?(mod)
32
39
  case mod
33
40
  when Puppet::Module
34
41
  modname = mod.forge_slug
@@ -39,12 +46,12 @@ class Dropsonde::Cache
39
46
  end
40
47
  return unless modname
41
48
 
42
- modules.include? modname.tr('/','-')
49
+ @@cache['modules'].include? modname.tr('/', '-')
43
50
  end
44
51
 
45
- def self.update
46
- puts "Updating module cache..."
47
- iter = PuppetForge::Module.all(:sort_by => 'latest_release')
52
+ def update
53
+ puts 'Updating module cache...'
54
+ iter = PuppetForge::Module.all(sort_by: 'latest_release')
48
55
  newest = DateTime.parse(@@cache['timestamp'])
49
56
 
50
57
  @@cache['timestamp'] = iter.first.updated_at
@@ -53,7 +60,7 @@ class Dropsonde::Cache
53
60
  # stop once we reach modules we've already cached
54
61
  break if DateTime.parse(iter.first.updated_at) <= newest
55
62
 
56
- @@cache['modules'].concat iter.map {|mod| mod.slug }
63
+ @@cache['modules'].concat(iter.map { |mod| mod.slug })
57
64
 
58
65
  iter = iter.next
59
66
  print '.'
@@ -62,22 +69,19 @@ class Dropsonde::Cache
62
69
  @@cache['modules'].sort!
63
70
  @@cache['modules'].uniq!
64
71
 
65
- File.write(@@path, JSON.pretty_generate(@@cache))
72
+ File.write(@path, JSON.pretty_generate(@@cache))
66
73
  end
67
74
 
68
- def self.autoupdate
69
- return unless @@autoupdate
75
+ def autoupdate
76
+ return unless @autoupdate
70
77
 
71
- unless File.file? @@path
72
- puts "Dropsonde caches a list of all Forge modules to ensure that it only reports"
73
- puts "usage data on public modules. Generating this cache may take some time on"
78
+ unless File.file? @path
79
+ puts 'Dropsonde caches a list of all Forge modules to ensure that it only reports'
80
+ puts 'usage data on public modules. Generating this cache may take some time on'
74
81
  puts "the first run and you'll see your screen fill up with dots."
75
82
  update
76
83
  end
77
84
 
78
- if (Date.today - File.mtime(@@path).to_date).to_i > @@ttl
79
- update
80
- end
85
+ return update if (Date.today - File.mtime(@path).to_date).to_i > @ttl
81
86
  end
82
-
83
87
  end
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # dependencies plugin
1
4
  class Dropsonde::Metrics::Dependencies
2
5
  def self.initialize_dependencies
3
6
  # require any libraries needed here -- no need to load puppet; it's already initialized
@@ -5,10 +8,10 @@ class Dropsonde::Metrics::Dependencies
5
8
  end
6
9
 
7
10
  def self.description
8
- <<~EOF
11
+ <<~DESCRIPTION
9
12
  This group of metrics discovers dependencies between modules in all
10
13
  environments. It will omit dependencies on private modules.
11
- EOF
14
+ DESCRIPTION
12
15
  end
13
16
 
14
17
  def self.schema
@@ -18,23 +21,23 @@ class Dropsonde::Metrics::Dependencies
18
21
  {
19
22
  "fields": [
20
23
  {
21
- "description": "The depended on module name",
22
- "mode": "NULLABLE",
23
- "name": "name",
24
- "type": "STRING"
24
+ "description": 'The depended on module name',
25
+ "mode": 'NULLABLE',
26
+ "name": 'name',
27
+ "type": 'STRING',
25
28
  },
26
29
  {
27
- "description": "The depended on module version requirement",
28
- "mode": "NULLABLE",
29
- "name": "version_requirement",
30
- "type": "STRING"
31
- }
30
+ "description": 'The depended on module version requirement',
31
+ "mode": 'NULLABLE',
32
+ "name": 'version_requirement',
33
+ "type": 'STRING',
34
+ },
32
35
  ],
33
- "description": "List of modules that private modules in all environments depend on.",
34
- "mode": "REPEATED",
35
- "name": "dependencies",
36
- "type": "RECORD"
37
- }
36
+ "description": 'List of modules that private modules in all environments depend on.',
37
+ "mode": 'REPEATED',
38
+ "name": 'dependencies',
39
+ "type": 'RECORD',
40
+ },
38
41
  ]
39
42
  end
40
43
 
@@ -42,26 +45,25 @@ class Dropsonde::Metrics::Dependencies
42
45
  # run just before generating this metric
43
46
  end
44
47
 
45
- def self.run
48
+ def self.run(_puppetdb_session = nil)
46
49
  # return an array of hashes representing the data to be merged into the combined checkin
47
- environments = Puppet.lookup(:environments).list.map{|e|e.name}
48
- modules = environments.map do |env|
50
+ environments = Puppet.lookup(:environments).list.map { |e| e.name }
51
+ modules = environments.map { |env|
49
52
  Puppet.lookup(:environments).get(env).modules
50
- end.flatten
53
+ }.flatten
51
54
 
52
55
  # we want only PUBLIC modules that PRIVATE modules depend on
53
- dependencies = modules.map do|mod|
56
+ dependencies = modules.map { |mod|
54
57
  next unless mod.dependencies
55
- next if Dropsonde::Cache.forgeModule? mod # skip unless this is a private module
58
+ next if Dropsonde::Cache.forge_module? mod # skip unless this is a private module
56
59
 
57
60
  # and return a list of all public modules it depends on
58
- mod.dependencies.select {|mod| Dropsonde::Cache.forgeModule? mod }
59
- end.flatten.compact
61
+ mod.dependencies.select { |dep| Dropsonde::Cache.forge_module? dep }
62
+ }.flatten.compact
60
63
 
61
64
  [
62
- { :dependencies => dependencies },
65
+ { dependencies: dependencies },
63
66
  ]
64
-
65
67
  end
66
68
 
67
69
  def self.example
@@ -69,14 +71,17 @@ class Dropsonde::Metrics::Dependencies
69
71
  # make it easier to write data aggregation queries without access to the
70
72
  # actual private data that users have submitted.
71
73
 
74
+ dropsonde_cache = Dropsonde::Cache.new('foo', 7, true)
72
75
  versions = ['>= 1.5.2', '>= 4.3.2', '>= 3.0.0 < 4.0.0', '>= 2.2.1 < 5.0.0', '>= 5.0.0 < 7.0.0', '>= 4.11.0']
73
76
  [
74
- :dependencies => Dropsonde::Cache.modules
75
- .sample(rand(250))
76
- .map {|item| {
77
- :name => item,
78
- :version_requirement => versions.sample,
79
- }},
77
+ dependencies: dropsonde_cache.modules
78
+ .sample(rand(250))
79
+ .map do |item|
80
+ {
81
+ name: item,
82
+ version_requirement: versions.sample,
83
+ }
84
+ end,
80
85
  ]
81
86
  end
82
87
 
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # environments plugin
1
4
  class Dropsonde::Metrics::Environments
2
5
  def self.initialize_environments
3
6
  # Require any libraries needed here -- no need to load puppet or puppetdb;
@@ -7,20 +10,20 @@ class Dropsonde::Metrics::Environments
7
10
 
8
11
  def self.description
9
12
  # This is a Ruby squiggle heredoc; just a multi-line string with indentation removed
10
- <<~EOF
13
+ <<~DESCRIPTION
11
14
  This group of metrics gathers information about environments.
12
- EOF
15
+ DESCRIPTION
13
16
  end
14
17
 
15
18
  def self.schema
16
19
  # return an array of hashes of a partial schema to be merged into the complete schema
17
20
  [
18
21
  {
19
- "description": "The number of environments",
20
- "mode": "NULLABLE",
21
- "name": "environment_count",
22
- "type": "INTEGER"
23
- }
22
+ "description": 'The number of environments',
23
+ "mode": 'NULLABLE',
24
+ "name": 'environment_count',
25
+ "type": 'INTEGER',
26
+ },
24
27
  ]
25
28
  end
26
29
 
@@ -28,10 +31,10 @@ class Dropsonde::Metrics::Environments
28
31
  # run just before generating this metric
29
32
  end
30
33
 
31
- def self.run
34
+ def self.run(_puppetdb_session = nil)
32
35
  # return an array of hashes representing the data to be merged into the combined checkin
33
36
  [
34
- :environment_count => Puppet.lookup(:environments).list.count,
37
+ environment_count: Puppet.lookup(:environments).list.count,
35
38
  ]
36
39
  end
37
40
 
@@ -40,7 +43,7 @@ class Dropsonde::Metrics::Environments
40
43
  # make it easier to write data aggregation queries without access to the
41
44
  # actual private data that users have submitted.
42
45
  [
43
- :environment_count => rand(1..100),
46
+ environment_count: rand(1..100),
44
47
  ]
45
48
  end
46
49
 
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # modules plugin
1
4
  class Dropsonde::Metrics::Modules
2
5
  def self.initialize_modules
3
6
  # require any libraries needed here -- no need to load puppet; it's already initialized
@@ -5,10 +8,10 @@ class Dropsonde::Metrics::Modules
5
8
  end
6
9
 
7
10
  def self.description
8
- <<~EOF
11
+ <<~DESCRIPTION
9
12
  This group of metrics exports name & version information about the public
10
13
  modules installed in all environments, ignoring private modules.
11
- EOF
14
+ DESCRIPTION
12
15
  end
13
16
 
14
17
  def self.schema
@@ -18,49 +21,49 @@ class Dropsonde::Metrics::Modules
18
21
  {
19
22
  "fields": [
20
23
  {
21
- "description": "The module name",
22
- "mode": "NULLABLE",
23
- "name": "name",
24
- "type": "STRING"
24
+ "description": 'The module name',
25
+ "mode": 'NULLABLE',
26
+ "name": 'name',
27
+ "type": 'STRING',
25
28
  },
26
29
  {
27
- "description": "The module slug (author-name)",
28
- "mode": "NULLABLE",
29
- "name": "slug",
30
- "type": "STRING"
30
+ "description": 'The module slug (author-name)',
31
+ "mode": 'NULLABLE',
32
+ "name": 'slug',
33
+ "type": 'STRING',
31
34
  },
32
35
  {
33
- "description": "The module version",
34
- "mode": "NULLABLE",
35
- "name": "version",
36
- "type": "STRING"
37
- }
36
+ "description": 'The module version',
37
+ "mode": 'NULLABLE',
38
+ "name": 'version',
39
+ "type": 'STRING',
40
+ },
38
41
  ],
39
- "description": "List of modules in all environments.",
40
- "mode": "REPEATED",
41
- "name": "modules",
42
- "type": "RECORD"
42
+ "description": 'List of modules in all environments.',
43
+ "mode": 'REPEATED',
44
+ "name": 'modules',
45
+ "type": 'RECORD',
43
46
  },
44
47
  {
45
48
  "fields": [
46
49
  {
47
- "description": "The class name",
48
- "mode": "NULLABLE",
49
- "name": "name",
50
- "type": "STRING"
50
+ "description": 'The class name',
51
+ "mode": 'NULLABLE',
52
+ "name": 'name',
53
+ "type": 'STRING',
51
54
  },
52
55
  {
53
- "description": "How many nodes it is declared on",
54
- "mode": "NULLABLE",
55
- "name": "count",
56
- "type": "INTEGER"
57
- }
56
+ "description": 'How many nodes it is declared on',
57
+ "mode": 'NULLABLE',
58
+ "name": 'count',
59
+ "type": 'INTEGER',
60
+ },
58
61
  ],
59
- "description": "List of classes and counts in all environments.",
60
- "mode": "REPEATED",
61
- "name": "classes",
62
- "type": "RECORD"
63
- }
62
+ "description": 'List of classes and counts in all environments.',
63
+ "mode": 'REPEATED',
64
+ "name": 'classes',
65
+ "type": 'RECORD',
66
+ },
64
67
  ]
65
68
  end
66
69
 
@@ -68,46 +71,44 @@ class Dropsonde::Metrics::Modules
68
71
  # run just before generating this metric
69
72
  end
70
73
 
71
- def self.run
74
+ def self.run(puppetdb_session = nil)
72
75
  # return an array of hashes representing the data to be merged into the combined checkin
73
- environments = Puppet.lookup(:environments).list.map{|e|e.name}
74
- modules = environments.map do |env|
75
- Puppet.lookup(:environments).get(env).modules.map do|mod|
76
+ environments = Puppet.lookup(:environments).list.map { |e| e.name }
77
+ modules = environments.map { |env|
78
+ Puppet.lookup(:environments).get(env).modules.map do |mod|
76
79
  next unless mod.forge_module?
77
80
 
78
81
  {
79
- :name => mod.name,
80
- :slug => mod.forge_slug,
81
- :version => mod.version,
82
+ name: mod.name,
83
+ slug: mod.forge_slug,
84
+ version: mod.version,
82
85
  }
83
86
  end
84
- end.flatten.compact.uniq
87
+ }.flatten.compact.uniq
85
88
 
86
- if Dropsonde.puppetDB
89
+ if puppetdb_session
87
90
  # classes and how many nodes they're enforced on
88
- results = Dropsonde.puppetDB.request( '',
89
- 'resources[type, title] { type = "Class" }'
90
- ).data
91
+ results = puppetdb_session.puppet_db.request('', 'resources[type, title] { type = "Class" }').data
91
92
 
92
93
  # select only classes from public modules.
93
94
  # Use uniq to reduce the iteration over very large datasets
94
- classes = results.uniq.map do |klass|
95
+ classes = results.uniq.map { |klass|
95
96
  title = klass['title']
96
97
  modname = title.split('::').first.downcase
97
- next unless modules.find {|mod| mod[:name] == modname }
98
+ next unless modules.find { |mod| mod[:name] == modname }
98
99
 
99
100
  {
100
- :name => title,
101
- :count => results.count {|row| row['title'] == title},
101
+ name: title,
102
+ count: results.count { |row| row['title'] == title },
102
103
  }
103
- end.compact
104
+ }.compact
104
105
  else
105
106
  classes = []
106
107
  end
107
108
 
108
109
  [
109
- { :modules => modules },
110
- { :classes => classes },
110
+ { modules: modules },
111
+ { classes: classes },
111
112
  ]
112
113
  end
113
114
 
@@ -118,20 +119,25 @@ class Dropsonde::Metrics::Modules
118
119
 
119
120
  versions = ['1.3.2', '0.0.1', '0.1.2', '1.0.0', '3.0.2', '7.10', '6.1.0', '2.1.0', '1.4.0']
120
121
  classes = ['', '::Config', '::Service', '::Server', '::Client', '::Packages']
122
+ dropsonde_cache = Dropsonde::Cache.new('foo', 7, true)
121
123
  [
122
- :modules => Dropsonde::Cache.modules
123
- .sample(rand(100))
124
- .map {|item| {
125
- :name => item.split('-').last,
126
- :slug => item,
127
- :version => versions.sample,
128
- }},
129
- :classes => Dropsonde::Cache.modules
130
- .sample(rand(500))
131
- .map {|item| {
132
- :name => item.split('-').last.capitalize + classes.sample,
133
- :count => rand(750),
134
- }},
124
+ modules: dropsonde_cache.modules
125
+ .sample(rand(100))
126
+ .map do |item|
127
+ {
128
+ name: item.split('-').last,
129
+ slug: item,
130
+ version: versions.sample,
131
+ }
132
+ end,
133
+ classes: dropsonde_cache.modules
134
+ .sample(rand(500))
135
+ .map do |item|
136
+ {
137
+ name: item.split('-').last.capitalize + classes.sample,
138
+ count: rand(750),
139
+ }
140
+ end,
135
141
  ]
136
142
  end
137
143