motoko 1.0.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.
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Motoko
4
+ class OptionParser
5
+ attr_accessor :formatter
6
+
7
+ def initialize
8
+ @parser = ::OptionParser.new
9
+ @formatter = Formatter.new
10
+ end
11
+
12
+ def parse
13
+ self.class.add_inventory_options(@parser, @formatter)
14
+
15
+ yield(@parser, @formatter) if block_given?
16
+
17
+ @parser.parse!
18
+
19
+ @formatter
20
+ end
21
+
22
+ # rubocop:disable Metrics/AbcSize
23
+ def self.add_inventory_options(parser, formatter)
24
+ parser.separator ''
25
+ parser.separator 'Inventory Options'
26
+
27
+ parser.on('-a', '--add-columns=COLUMNS', 'Add COLUMNS to the displayed column list', Array) do |columns|
28
+ formatter.columns += columns
29
+ end
30
+
31
+ parser.on('--columns=COLUMNS', 'Set the displayed column list to COLUMNS', Array) do |columns|
32
+ formatter.columns = columns
33
+ end
34
+
35
+ parser.on('--hw', 'Display hardware information') do
36
+ formatter.columns += %i[is_virtual cpu memory]
37
+ end
38
+
39
+ parser.on('--puppet', 'Display Puppet information') do
40
+ formatter.columns += %i[puppet]
41
+ end
42
+
43
+ parser.on('--sw', 'Display sodtware information') do
44
+ formatter.columns += %i[os kernel]
45
+ end
46
+
47
+ parser.on('--mono', 'Do not display a colored output') do
48
+ formatter.mono = true
49
+ end
50
+
51
+ parser.on('-w', '--wide', 'Do not ellipsis long strings') do
52
+ formatter.wide = true
53
+ end
54
+
55
+ parser.on('--[no-]count', 'Count values') do |count|
56
+ formatter.count = count
57
+ end
58
+
59
+ parser.on('--sort-by=COLUMNS', 'Sort lines by COLUMS', Array) do |columns|
60
+ formatter.sort_by = columns
61
+ end
62
+ end
63
+
64
+ def self.add_shortcut_options(parser, formatter, local_options)
65
+ parser.separator ''
66
+ parser.separator 'Shortcuts'
67
+
68
+ formatter.shortcuts.each do |key, value|
69
+ parser.on("--#{key}", value.delete('description')) do
70
+ formatter.columns.push(*value.delete('add_columns'))
71
+ local_options[:with_class] ||= []
72
+ local_options[:with_class].push(*value.delete('with_class'))
73
+ local_options[:with_fact] ||= []
74
+ local_options[:with_fact].push(*value.delete('with_fact'))
75
+ end
76
+ end
77
+ end
78
+ # rubocop:enable Metrics/AbcSize
79
+ end
80
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'motoko/utils/snake_to_camel'
4
+
5
+ module Motoko
6
+ module Resolvers
7
+ class BaseResolver
8
+ attr_accessor :name
9
+ attr_writer :human_name
10
+ attr_reader :formatter
11
+
12
+ include Motoko::Utils::SnakeToCamel
13
+
14
+ def initialize(name, options)
15
+ options ||= {}
16
+
17
+ @name = name
18
+ @human_name = options.delete('human_name') if options.key?('human_name')
19
+ formatter = options.delete('formatter') || 'base_formatter'
20
+ @align = options.delete('align')
21
+
22
+ @formatter = Object.const_get("Motoko::Formatters::#{snake_to_camel_case(formatter)}").new(options)
23
+
24
+ puts "unused keys for column #{name}: #{options.keys.join(', ')}" if options.keys.any?
25
+ end
26
+
27
+ def align
28
+ @align&.to_sym
29
+ end
30
+
31
+ def human_name
32
+ @human_name ||= name.tr('_', ' ').gsub('.', ' > ').split.map(&:capitalize).join(' ')
33
+ end
34
+
35
+ def resolve_for(_node)
36
+ raise 'Not implemented'
37
+ end
38
+
39
+ def value(node)
40
+ formatter.format(resolve_for(node))
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Motoko
4
+ module Resolvers
5
+ class Cpu < BaseResolver
6
+ def resolve_for(node)
7
+ format('%<ncpu>2d × %<model>s', ncpu: node.fact('processors.count'), model: node.fact('processors.models').first.gsub(/\((R|TM)\)|Processor/, '').gsub(/ {2,}/, ' '))
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Motoko
4
+ module Resolvers
5
+ class Fact < BaseResolver
6
+ attr_accessor :fact
7
+
8
+ def initialize(name, options)
9
+ @fact = options.delete('fact') || name
10
+
11
+ super
12
+ end
13
+
14
+ def resolve_for(node)
15
+ node.fact(fact)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Motoko
4
+ module Resolvers
5
+ class Identity < BaseResolver
6
+ def resolve_for(node)
7
+ node.identity
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Motoko
4
+ module Resolvers
5
+ class Os < BaseResolver
6
+ def resolve_for(node)
7
+ node.fact('os.distro.description') || format('%<name>s %<release>s', name: node.fact('os.name'), release: node.fact('os.release.full'))
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Motoko
4
+ module Resolvers
5
+ class RebootRequired < BaseResolver
6
+ def resolve_for(node)
7
+ %w[
8
+ apt_reboot_required
9
+ pkg_reboot_required
10
+ yum_reboot_required
11
+ ].each do |fact|
12
+ value = node.fact(fact)
13
+ return value unless value.nil?
14
+ end
15
+
16
+ nil
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Motoko
4
+ module Utils
5
+ module PuppetDB
6
+ def self.class_filter(klass)
7
+ operator = '='
8
+
9
+ if klass =~ %r{\A/.*/\z}
10
+ klass = klass[1..-2]
11
+ operator = '~'
12
+ end
13
+
14
+ "certname in resources[certname] { type = 'Class' and title #{operator} '#{klass.split('::').map(&:capitalize).join('::')}' }"
15
+ end
16
+
17
+ def self.fact_filter(fact)
18
+ name, operator, value = fact.split(/([!<>]?=|[<>])/, 2)
19
+
20
+ if operator == '=' && value =~ %r{\A/.*/\z}
21
+ value = value[1..-2]
22
+ operator = '~'
23
+ end
24
+
25
+ begin
26
+ value = case value
27
+ when 'true' then true
28
+ when 'false' then false
29
+ else Integer(value)
30
+ end
31
+ rescue ArgumentError
32
+ value = "'#{value}'"
33
+ end
34
+
35
+ "certname in inventory[certname] { facts.#{name} #{operator} #{value} }"
36
+ end
37
+
38
+ def self.identity_filter(identity)
39
+ operator = '='
40
+
41
+ if identity =~ %r{\A/.*/\z}
42
+ identity = identity[1..-2]
43
+ operator = '~'
44
+ end
45
+
46
+ "certname #{operator} '#{identity}'"
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Motoko
4
+ module Utils
5
+ module SnakeToCamel
6
+ def snake_to_camel_case(subject)
7
+ subject.split('_').map(&:capitalize).join
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Motoko
4
+ module Utils
5
+ module TimeAgo
6
+ def seconds_to_human(value)
7
+ return nil unless value
8
+
9
+ value = value.round
10
+ res = []
11
+
12
+ {
13
+ 's' => 60,
14
+ 'm' => 60,
15
+ 'h' => 24,
16
+ }.each do |unit, count|
17
+ res << Kernel.format('%<n>2d%<unit>s', n: value % count, unit: unit)
18
+ value /= count
19
+
20
+ break if value.zero?
21
+ end
22
+
23
+ res << "#{value}d" if value.positive?
24
+
25
+ res.reverse.join(' ')
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Motoko
4
+ VERSION = '1.0.0'
5
+ end
data/motoko.gemspec ADDED
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/motoko/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'motoko'
7
+ spec.version = Motoko::VERSION
8
+ spec.authors = ['Romain Tartière']
9
+ spec.email = ['romain@blogreen.org']
10
+
11
+ spec.summary = 'Inventory tools for Puppet / Choria infrastructures'
12
+ spec.homepage = 'https://github.com/smortex/motoko'
13
+ spec.license = 'MIT'
14
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0')
15
+
16
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org/'
17
+
18
+ spec.metadata['homepage_uri'] = spec.homepage
19
+ spec.metadata['source_code_uri'] = spec.homepage
20
+ spec.metadata['changelog_uri'] = spec.homepage
21
+
22
+ # Specify which files should be added to the gem when it is released.
23
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
24
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
25
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ end
27
+ spec.bindir = 'exe'
28
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
29
+ spec.require_paths = ['lib']
30
+
31
+ spec.add_dependency 'choria-mcorpc-support'
32
+ spec.add_dependency 'skittlize', '~> 1.2'
33
+ spec.add_dependency 'terminal-table'
34
+ end
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: motoko
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Romain Tartière
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-07-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: choria-mcorpc-support
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: skittlize
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: terminal-table
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description:
56
+ email:
57
+ - romain@blogreen.org
58
+ executables:
59
+ - inventory
60
+ - pdb-inventory
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - ".github/workflows/ci.yaml"
65
+ - ".gitignore"
66
+ - ".rspec"
67
+ - ".rubocop.yml"
68
+ - ".simplecov"
69
+ - ".travis.yml"
70
+ - CODE_OF_CONDUCT.md
71
+ - Gemfile
72
+ - LICENSE.txt
73
+ - README.md
74
+ - Rakefile
75
+ - bin/console
76
+ - bin/setup
77
+ - exe/inventory
78
+ - exe/pdb-inventory
79
+ - lib/motoko.rb
80
+ - lib/motoko/config.rb
81
+ - lib/motoko/formatter.rb
82
+ - lib/motoko/formatters/base_formatter.rb
83
+ - lib/motoko/formatters/boolean.rb
84
+ - lib/motoko/formatters/datetime.rb
85
+ - lib/motoko/formatters/datetime_ago.rb
86
+ - lib/motoko/formatters/ellipsis.rb
87
+ - lib/motoko/formatters/timestamp.rb
88
+ - lib/motoko/formatters/timestamp_ago.rb
89
+ - lib/motoko/node.rb
90
+ - lib/motoko/option_parser.rb
91
+ - lib/motoko/resolvers/base_resolver.rb
92
+ - lib/motoko/resolvers/cpu.rb
93
+ - lib/motoko/resolvers/fact.rb
94
+ - lib/motoko/resolvers/identity.rb
95
+ - lib/motoko/resolvers/os.rb
96
+ - lib/motoko/resolvers/reboot_required.rb
97
+ - lib/motoko/utils/puppet_db.rb
98
+ - lib/motoko/utils/snake_to_camel.rb
99
+ - lib/motoko/utils/time_ago.rb
100
+ - lib/motoko/version.rb
101
+ - motoko.gemspec
102
+ homepage: https://github.com/smortex/motoko
103
+ licenses:
104
+ - MIT
105
+ metadata:
106
+ allowed_push_host: https://rubygems.org/
107
+ homepage_uri: https://github.com/smortex/motoko
108
+ source_code_uri: https://github.com/smortex/motoko
109
+ changelog_uri: https://github.com/smortex/motoko
110
+ post_install_message:
111
+ rdoc_options: []
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: 2.5.0
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ requirements: []
125
+ rubygems_version: 3.0.8
126
+ signing_key:
127
+ specification_version: 4
128
+ summary: Inventory tools for Puppet / Choria infrastructures
129
+ test_files: []