dropsonde 0.0.5 → 0.0.6
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 +4 -4
- data/bin/dropsonde +12 -6
- data/lib/dropsonde/cache.rb +37 -33
- data/lib/dropsonde/metrics/dependencies.rb +37 -32
- data/lib/dropsonde/metrics/environments.rb +13 -10
- data/lib/dropsonde/metrics/modules.rb +71 -65
- data/lib/dropsonde/metrics/platforms.rb +64 -61
- data/lib/dropsonde/metrics/puppetfiles.rb +35 -32
- data/lib/dropsonde/metrics.rb +80 -77
- data/lib/dropsonde/monkeypatches.rb +12 -11
- data/lib/dropsonde/version.rb +3 -1
- data/lib/dropsonde.rb +64 -26
- metadata +4 -4
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: f4a87b2c8abe75d07a73a52a48041c2734bb7914a54df3471d696458f3f0cb05
         | 
| 4 | 
            +
              data.tar.gz: cd2b7d3a36aa9aa386997ab21f7ffee57387819b08a79407b98c5bfdbbcd619d
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 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. | 
| 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 | 
            -
                   | 
| 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 | 
            -
                   | 
| 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 | 
            -
                   | 
| 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 | 
            -
                     | 
| 120 | 
            +
                    @cache.autoupdate
         | 
| 115 121 | 
             
                    Dropsonde.generate_example(options[:size], options[:filename])
         | 
| 116 122 | 
             
                  end
         | 
| 117 123 | 
             
                end
         | 
    
        data/lib/dropsonde/cache.rb
    CHANGED
    
    | @@ -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 | 
            -
               | 
| 10 | 
            +
              @autoupdate = false
         | 
| 8 11 |  | 
| 9 | 
            -
              def  | 
| 12 | 
            +
              def initialize(path, ttl, autoupdate)
         | 
| 10 13 | 
             
                FileUtils.mkdir_p(path)
         | 
| 11 | 
            -
                 | 
| 12 | 
            -
                 | 
| 13 | 
            -
                 | 
| 14 | 
            -
             | 
| 15 | 
            -
                if File.file?  | 
| 16 | 
            -
             | 
| 17 | 
            -
             | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
                PuppetForge.user_agent =  | 
| 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  | 
| 30 | 
            +
              def modules
         | 
| 28 31 | 
             
                @@cache['modules']
         | 
| 29 32 | 
             
              end
         | 
| 30 33 |  | 
| 31 | 
            -
              def  | 
| 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  | 
| 46 | 
            -
                puts  | 
| 47 | 
            -
                iter   = PuppetForge::Module.all(: | 
| 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 | 
| 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( | 
| 72 | 
            +
                File.write(@path, JSON.pretty_generate(@@cache))
         | 
| 66 73 | 
             
              end
         | 
| 67 74 |  | 
| 68 | 
            -
              def  | 
| 69 | 
            -
                return unless  | 
| 75 | 
            +
              def autoupdate
         | 
| 76 | 
            +
                return unless @autoupdate
         | 
| 70 77 |  | 
| 71 | 
            -
                unless File.file?  | 
| 72 | 
            -
                  puts  | 
| 73 | 
            -
                  puts  | 
| 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( | 
| 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 | 
            -
                <<~ | 
| 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 | 
            -
                 | 
| 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":  | 
| 22 | 
            -
                        "mode":  | 
| 23 | 
            -
                        "name":  | 
| 24 | 
            -
                        "type":  | 
| 24 | 
            +
                        "description": 'The depended on module name',
         | 
| 25 | 
            +
                        "mode": 'NULLABLE',
         | 
| 26 | 
            +
                        "name": 'name',
         | 
| 27 | 
            +
                        "type": 'STRING',
         | 
| 25 28 | 
             
                      },
         | 
| 26 29 | 
             
                      {
         | 
| 27 | 
            -
                        "description":  | 
| 28 | 
            -
                        "mode":  | 
| 29 | 
            -
                        "name":  | 
| 30 | 
            -
                        "type":  | 
| 31 | 
            -
                      }
         | 
| 30 | 
            +
                        "description": 'The depended on module version requirement',
         | 
| 31 | 
            +
                        "mode": 'NULLABLE',
         | 
| 32 | 
            +
                        "name": 'version_requirement',
         | 
| 33 | 
            +
                        "type": 'STRING',
         | 
| 34 | 
            +
                      },
         | 
| 32 35 | 
             
                    ],
         | 
| 33 | 
            -
                    "description":  | 
| 34 | 
            -
                    "mode":  | 
| 35 | 
            -
                    "name":  | 
| 36 | 
            -
                    "type":  | 
| 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  | 
| 50 | 
            +
                environments = Puppet.lookup(:environments).list.map { |e| e.name }
         | 
| 51 | 
            +
                modules = environments.map { |env|
         | 
| 49 52 | 
             
                  Puppet.lookup(:environments).get(env).modules
         | 
| 50 | 
            -
                 | 
| 53 | 
            +
                }.flatten
         | 
| 51 54 |  | 
| 52 55 | 
             
                # we want only PUBLIC modules that PRIVATE modules depend on
         | 
| 53 | 
            -
                dependencies = modules.map  | 
| 56 | 
            +
                dependencies = modules.map { |mod|
         | 
| 54 57 | 
             
                  next unless mod.dependencies
         | 
| 55 | 
            -
                  next if Dropsonde::Cache. | 
| 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 {| | 
| 59 | 
            -
                 | 
| 61 | 
            +
                  mod.dependencies.select { |dep| Dropsonde::Cache.forge_module? dep }
         | 
| 62 | 
            +
                }.flatten.compact
         | 
| 60 63 |  | 
| 61 64 | 
             
                [
         | 
| 62 | 
            -
                  { : | 
| 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 | 
            -
                  : | 
| 75 | 
            -
             | 
| 76 | 
            -
             | 
| 77 | 
            -
             | 
| 78 | 
            -
             | 
| 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 | 
            -
                <<~ | 
| 13 | 
            +
                <<~DESCRIPTION
         | 
| 11 14 | 
             
                  This group of metrics gathers information about environments.
         | 
| 12 | 
            -
                 | 
| 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":  | 
| 20 | 
            -
                    "mode":  | 
| 21 | 
            -
                    "name":  | 
| 22 | 
            -
                    "type":  | 
| 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 | 
            -
                  : | 
| 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 | 
            -
                  : | 
| 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 | 
            -
                <<~ | 
| 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 | 
            -
                 | 
| 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":  | 
| 22 | 
            -
                        "mode":  | 
| 23 | 
            -
                        "name":  | 
| 24 | 
            -
                        "type":  | 
| 24 | 
            +
                        "description": 'The module name',
         | 
| 25 | 
            +
                        "mode": 'NULLABLE',
         | 
| 26 | 
            +
                        "name": 'name',
         | 
| 27 | 
            +
                        "type": 'STRING',
         | 
| 25 28 | 
             
                      },
         | 
| 26 29 | 
             
                      {
         | 
| 27 | 
            -
                        "description":  | 
| 28 | 
            -
                        "mode":  | 
| 29 | 
            -
                        "name":  | 
| 30 | 
            -
                        "type":  | 
| 30 | 
            +
                        "description": 'The module slug (author-name)',
         | 
| 31 | 
            +
                        "mode": 'NULLABLE',
         | 
| 32 | 
            +
                        "name": 'slug',
         | 
| 33 | 
            +
                        "type": 'STRING',
         | 
| 31 34 | 
             
                      },
         | 
| 32 35 | 
             
                      {
         | 
| 33 | 
            -
                        "description":  | 
| 34 | 
            -
                        "mode":  | 
| 35 | 
            -
                        "name":  | 
| 36 | 
            -
                        "type":  | 
| 37 | 
            -
                      }
         | 
| 36 | 
            +
                        "description": 'The module version',
         | 
| 37 | 
            +
                        "mode": 'NULLABLE',
         | 
| 38 | 
            +
                        "name": 'version',
         | 
| 39 | 
            +
                        "type": 'STRING',
         | 
| 40 | 
            +
                      },
         | 
| 38 41 | 
             
                    ],
         | 
| 39 | 
            -
                    "description":  | 
| 40 | 
            -
                    "mode":  | 
| 41 | 
            -
                    "name":  | 
| 42 | 
            -
                    "type":  | 
| 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":  | 
| 48 | 
            -
                        "mode":  | 
| 49 | 
            -
                        "name":  | 
| 50 | 
            -
                        "type":  | 
| 50 | 
            +
                        "description": 'The class name',
         | 
| 51 | 
            +
                        "mode": 'NULLABLE',
         | 
| 52 | 
            +
                        "name": 'name',
         | 
| 53 | 
            +
                        "type": 'STRING',
         | 
| 51 54 | 
             
                      },
         | 
| 52 55 | 
             
                      {
         | 
| 53 | 
            -
                        "description":  | 
| 54 | 
            -
                        "mode":  | 
| 55 | 
            -
                        "name":  | 
| 56 | 
            -
                        "type":  | 
| 57 | 
            -
                      }
         | 
| 56 | 
            +
                        "description": 'How many nodes it is declared on',
         | 
| 57 | 
            +
                        "mode": 'NULLABLE',
         | 
| 58 | 
            +
                        "name": 'count',
         | 
| 59 | 
            +
                        "type": 'INTEGER',
         | 
| 60 | 
            +
                      },
         | 
| 58 61 | 
             
                    ],
         | 
| 59 | 
            -
                    "description":  | 
| 60 | 
            -
                    "mode":  | 
| 61 | 
            -
                    "name":  | 
| 62 | 
            -
                    "type":  | 
| 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  | 
| 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 | 
            -
                      : | 
| 80 | 
            -
                      : | 
| 81 | 
            -
                      : | 
| 82 | 
            +
                      name: mod.name,
         | 
| 83 | 
            +
                      slug: mod.forge_slug,
         | 
| 84 | 
            +
                      version: mod.version,
         | 
| 82 85 | 
             
                    }
         | 
| 83 86 | 
             
                  end
         | 
| 84 | 
            -
                 | 
| 87 | 
            +
                }.flatten.compact.uniq
         | 
| 85 88 |  | 
| 86 | 
            -
                if  | 
| 89 | 
            +
                if puppetdb_session
         | 
| 87 90 | 
             
                  # classes and how many nodes they're enforced on
         | 
| 88 | 
            -
                  results =  | 
| 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  | 
| 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 | 
            -
                      : | 
| 101 | 
            -
                      : | 
| 101 | 
            +
                      name: title,
         | 
| 102 | 
            +
                      count: results.count { |row| row['title'] == title },
         | 
| 102 103 | 
             
                    }
         | 
| 103 | 
            -
                   | 
| 104 | 
            +
                  }.compact
         | 
| 104 105 | 
             
                else
         | 
| 105 106 | 
             
                  classes = []
         | 
| 106 107 | 
             
                end
         | 
| 107 108 |  | 
| 108 109 | 
             
                [
         | 
| 109 | 
            -
                  { : | 
| 110 | 
            -
                  { : | 
| 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 | 
            -
                  : | 
| 123 | 
            -
             | 
| 124 | 
            -
             | 
| 125 | 
            -
             | 
| 126 | 
            -
             | 
| 127 | 
            -
             | 
| 128 | 
            -
             | 
| 129 | 
            -
             | 
| 130 | 
            -
             | 
| 131 | 
            -
             | 
| 132 | 
            -
             | 
| 133 | 
            -
             | 
| 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 |  |