moose-inventory 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +0 -0
  3. data/.gitignore +17 -0
  4. data/.rubocop.yml +793 -0
  5. data/Gemfile +3 -0
  6. data/Guardfile +38 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +31 -0
  9. data/README.md.orig +35 -0
  10. data/Rakefile +1 -0
  11. data/bin/moose_inventory +10 -0
  12. data/config/dotfiles/coveralls.yml +0 -0
  13. data/config/dotfiles/gitignore +17 -0
  14. data/config/dotfiles/rubocop.yml +793 -0
  15. data/lib/moose/inventory/cli/application.rb +30 -0
  16. data/lib/moose/inventory/cli/formatter.rb +92 -0
  17. data/lib/moose/inventory/cli/group.rb +23 -0
  18. data/lib/moose/inventory/cli/group_add.rb +98 -0
  19. data/lib/moose/inventory/cli/group_addchild.rb +21 -0
  20. data/lib/moose/inventory/cli/group_addhost.rb +97 -0
  21. data/lib/moose/inventory/cli/group_addvar.rb +72 -0
  22. data/lib/moose/inventory/cli/group_get.rb +52 -0
  23. data/lib/moose/inventory/cli/group_list.rb +41 -0
  24. data/lib/moose/inventory/cli/group_rm.rb +77 -0
  25. data/lib/moose/inventory/cli/group_rmchild.rb +20 -0
  26. data/lib/moose/inventory/cli/group_rmhost.rb +89 -0
  27. data/lib/moose/inventory/cli/group_rmvar.rb +65 -0
  28. data/lib/moose/inventory/cli/host.rb +24 -0
  29. data/lib/moose/inventory/cli/host_add.rb +93 -0
  30. data/lib/moose/inventory/cli/host_addgroup.rb +88 -0
  31. data/lib/moose/inventory/cli/host_addvar.rb +76 -0
  32. data/lib/moose/inventory/cli/host_get.rb +59 -0
  33. data/lib/moose/inventory/cli/host_list.rb +40 -0
  34. data/lib/moose/inventory/cli/host_rm.rb +62 -0
  35. data/lib/moose/inventory/cli/host_rmgroup.rb +80 -0
  36. data/lib/moose/inventory/cli/host_rmvar.rb +69 -0
  37. data/lib/moose/inventory/config/config.rb +169 -0
  38. data/lib/moose/inventory/db/db.rb +249 -0
  39. data/lib/moose/inventory/db/exceptions.rb +14 -0
  40. data/lib/moose/inventory/db/models.rb +32 -0
  41. data/lib/moose/inventory/moose_inventory_cli.rb +25 -0
  42. data/lib/moose/inventory/version.rb +7 -0
  43. data/moose-inventory.gemspec +45 -0
  44. data/scripts/guard_quality.sh +3 -0
  45. data/scripts/guard_test.sh +2 -0
  46. data/scripts/reports.sh +4 -0
  47. data/spec/config/config.yml +12 -0
  48. data/spec/lib/moose/inventory/cli/application_spec.rb +15 -0
  49. data/spec/lib/moose/inventory/cli/cli_spec.rb +26 -0
  50. data/spec/lib/moose/inventory/cli/formatter_spec.rb +63 -0
  51. data/spec/lib/moose/inventory/cli/group_add_spec.rb +398 -0
  52. data/spec/lib/moose/inventory/cli/group_addhost_spec.rb +251 -0
  53. data/spec/lib/moose/inventory/cli/group_addvar_spec.rb +235 -0
  54. data/spec/lib/moose/inventory/cli/group_get_spec.rb +107 -0
  55. data/spec/lib/moose/inventory/cli/group_list_spec.rb +79 -0
  56. data/spec/lib/moose/inventory/cli/group_rm_spec.rb +191 -0
  57. data/spec/lib/moose/inventory/cli/group_rmhost_spec.rb +215 -0
  58. data/spec/lib/moose/inventory/cli/group_rmvar_spec.rb +202 -0
  59. data/spec/lib/moose/inventory/cli/group_spec.rb +15 -0
  60. data/spec/lib/moose/inventory/cli/host_add_spec.rb +330 -0
  61. data/spec/lib/moose/inventory/cli/host_addgroup_spec.rb +248 -0
  62. data/spec/lib/moose/inventory/cli/host_addvar_spec.rb +233 -0
  63. data/spec/lib/moose/inventory/cli/host_get_spec.rb +106 -0
  64. data/spec/lib/moose/inventory/cli/host_list_spec.rb +83 -0
  65. data/spec/lib/moose/inventory/cli/host_rm_spec.rb +132 -0
  66. data/spec/lib/moose/inventory/cli/host_rmgroup_spec.rb +245 -0
  67. data/spec/lib/moose/inventory/cli/host_rmvar_spec.rb +206 -0
  68. data/spec/lib/moose/inventory/cli/host_spec.rb +12 -0
  69. data/spec/lib/moose/inventory/config/config_spec.rb +80 -0
  70. data/spec/lib/moose/inventory/db/db_spec.rb +184 -0
  71. data/spec/lib/moose/inventory/db/models_spec.rb +150 -0
  72. data/spec/shared/shared_config_setup.rb +21 -0
  73. data/spec/spec_helper.rb +110 -0
  74. metadata +386 -0
@@ -0,0 +1,30 @@
1
+ require 'thor'
2
+ require_relative '../version.rb'
3
+ require_relative '../config/config.rb'
4
+ require_relative './group.rb'
5
+ require_relative './host.rb'
6
+
7
+ module Moose
8
+ module Inventory
9
+ module Cli
10
+ ##
11
+ # TODO: Documentation
12
+ class Application < Thor
13
+ desc 'version', 'Get the code version'
14
+ def version
15
+ puts "Version #{Moose::Inventory::VERSION}"
16
+ end
17
+
18
+ desc 'group ACTION',
19
+ 'Manipulate groups in the inventory. ' \
20
+ 'ACTION can be add, rm, addhost, rmhost, addvar, rmvar'
21
+ subcommand 'group', Moose::Inventory::Cli::Group
22
+
23
+ desc 'host ACTION',
24
+ 'Manipulate hosts in the inventory. ' \
25
+ 'ACTION can be add, rm, addgroup, rmgroup, addvar, rmvar'
26
+ subcommand 'host', Moose::Inventory::Cli::Host
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,92 @@
1
+ require 'json'
2
+ require 'yaml'
3
+ require 'indentation'
4
+
5
+ module Moose
6
+ module Inventory
7
+ module Cli
8
+ ##
9
+ # TODO: Documentation
10
+ module Formatter
11
+ # rubocop:disable Style/ModuleFunction
12
+ extend self
13
+ # rubocop:enable Style/ModuleFunction
14
+
15
+ def self.dump(arg, format = nil)
16
+ out(arg, format)
17
+ end
18
+
19
+ def self.out(arg, format = nil)
20
+ return if arg.nil?
21
+
22
+ if format.nil?
23
+ format = Moose::Inventory::Config._confopts[:format].downcase
24
+ end
25
+
26
+ case format
27
+ when 'yaml','y'
28
+ $stdout.puts arg.to_yaml
29
+
30
+ when 'prettyjson','pjson','p'
31
+ $stdout.puts JSON.pretty_generate(arg)
32
+
33
+ when 'json','j'
34
+ $stdout.puts arg.to_json
35
+
36
+ else
37
+ abort("Output format '#{format}' is not yet supported.")
38
+ end
39
+ end
40
+
41
+ #---------------
42
+ attr_accessor :indent
43
+
44
+ def reset_indent
45
+ @indent = 2
46
+ end
47
+
48
+ def puts(indent, msg, stream='STDOUT')
49
+ case stream
50
+ when 'STDOUT'
51
+ $stdout.puts msg.indent(indent)
52
+ when 'STDERR'
53
+ $stderr.puts msg.indent(indent)
54
+ else
55
+ abort("Output stream '#{stream}' is not known.")
56
+ end
57
+ end
58
+
59
+ def print(indent, msg, stream='STDOUT')
60
+ case stream
61
+ when 'STDOUT'
62
+ $stdout.print msg.indent(indent)
63
+ when 'STDERR'
64
+ $stderr.print msg.indent(indent)
65
+ else
66
+ abort("Output stream '#{stream}' is not known.")
67
+ end
68
+ end
69
+
70
+ def info(indent, msg, stream='STDOUT')
71
+ case stream
72
+ when 'STDOUT'
73
+ $stdout.print "INFO: {msg}"
74
+ when 'STDERR'
75
+ $stderr.print "INFO: {msg}"
76
+ else
77
+ abort("Output stream '#{stream}' is not known.")
78
+ end
79
+ end
80
+
81
+ def warn(msg)
82
+ $stderr.print "WARNING: #{msg}"
83
+ end
84
+
85
+ def error(msg)
86
+ $stderr.print "ERROR: #{msg}"
87
+ end
88
+
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,23 @@
1
+ require 'thor'
2
+ require_relative './formatter.rb'
3
+
4
+ module Moose
5
+ module Inventory
6
+ module Cli
7
+ ##
8
+ # Class implementing the "group" methods of the CLI
9
+ class Group < Thor
10
+ require_relative 'group_add'
11
+ require_relative 'group_get'
12
+ require_relative 'group_list'
13
+ require_relative 'group_rm'
14
+ require_relative 'group_addchild'
15
+ require_relative 'group_rmchild'
16
+ require_relative 'group_addhost'
17
+ require_relative 'group_rmhost'
18
+ require_relative 'group_addvar'
19
+ require_relative 'group_rmvar'
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,98 @@
1
+ require 'thor'
2
+ require_relative './formatter.rb'
3
+
4
+ module Moose
5
+ module Inventory
6
+ module Cli
7
+ ##
8
+ # Implementation of the "group add" method of the CLI
9
+ class Group
10
+ #==========================
11
+ desc 'add NAME', 'Add a group NAME to the inventory'
12
+ option :hosts
13
+ # rubocop:disable Metrics/LineLength
14
+ def add(*argv) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
15
+ # rubocop:enable Metrics/LineLength
16
+ if argv.length < 1
17
+ abort("ERROR: Wrong number of arguments, #{argv.length} for 1 or more.")
18
+ end
19
+
20
+ # Arguments
21
+ names = argv.uniq.map(&:downcase)
22
+ options[:hosts] = '' if options[:hosts].nil?
23
+ hosts = options[:hosts].downcase.split(',').uniq
24
+
25
+ # sanity
26
+ if names.include?('ungrouped')
27
+ abort("ERROR: Cannot manually manipulate the automatic group 'ungrouped'\n")
28
+ end
29
+
30
+ # Convenience
31
+ db = Moose::Inventory::DB
32
+ fmt = Moose::Inventory::Cli::Formatter
33
+
34
+ # Transaction
35
+ warn_count = 0
36
+ db.transaction do # Transaction start
37
+ names.each do |name|
38
+ # Add the group
39
+ puts "Add group '#{name}':"
40
+ group = db.models[:group].find(name: name)
41
+ hosts_ds = nil
42
+ fmt.puts 2, "- create group..."
43
+ if group.nil?
44
+ group = db.models[:group].create(name: name)
45
+ fmt.puts 4, '- OK'
46
+ else
47
+ warn_count += 1
48
+ fmt.warn "Group '#{name}' already exists, skipping creation.\n"
49
+ fmt.puts 4, "- already exists, skipping."
50
+ hosts_ds = group.hosts_dataset
51
+ fmt.puts 4, '- OK'
52
+ end
53
+
54
+ # Associate with hosts
55
+ hosts.each do |h|
56
+ next if h.nil? || h.empty?
57
+ fmt.puts 2, "- add association {group:#{name} <-> host:#{ h }}..."
58
+ host = db.models[:host].find(name: h)
59
+ if host.nil?
60
+ warn_count += 1
61
+ fmt.warn "Host '#{h}' doesn't exist, but will be created.\n"
62
+ fmt.puts 4, "- host doesn't exist, creating now..."
63
+ host = db.models[:host].create(name: h)
64
+ fmt.puts 6, "- OK"
65
+ end
66
+ if !hosts_ds.nil? && !hosts_ds[name: h].nil?
67
+ warn_count += 1
68
+ fmt.warn "Association {group:#{name} <-> host:#{ h }}"\
69
+ " already exists, skipping creation.\n"
70
+ fmt.puts 4, "- already exists, skipping."
71
+ else
72
+ group.add_host(host)
73
+ end
74
+ fmt.puts 4, '- OK'
75
+
76
+ # Handle the host's automatic 'ungrouped' group
77
+ ungrouped = host.groups_dataset[name: 'ungrouped']
78
+ unless ungrouped.nil?
79
+ fmt.puts 2, "- remove automatic association {group:ungrouped"\
80
+ " <-> host:#{ h }}..."
81
+ host.remove_group( ungrouped ) unless ungrouped.nil?
82
+ fmt.puts 4, '- OK'
83
+ end
84
+ end
85
+ fmt.puts 2, '- all OK'
86
+ end
87
+ end # Transaction end
88
+ if warn_count == 0
89
+ puts 'Succeeded'
90
+ else
91
+ puts 'Succeeded, with warnings.'
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+
@@ -0,0 +1,21 @@
1
+ require 'thor'
2
+ require_relative './formatter.rb'
3
+
4
+ module Moose
5
+ module Inventory
6
+ module Cli
7
+ ##
8
+ # Implemention of the "group addchild" methods of the CLI
9
+ class Group < Thor # rubocop:disable ClassLength
10
+ #==========================
11
+ desc 'addchild [options] NAME CHILDNAME',
12
+ 'Associate a child-group CHILDNAME with the group NAME'
13
+ option :allowcreate, type: :boolean
14
+ def addchild
15
+ abort("The 'groups addchild GROUP' method is not yet implemented")
16
+ puts 'group addchild'
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,97 @@
1
+ require 'thor'
2
+ require_relative './formatter.rb'
3
+
4
+ module Moose
5
+ module Inventory
6
+ module Cli
7
+ ##
8
+ # Implementation of the "group addhost" method of the CLI
9
+ class Group
10
+ #==========================
11
+ desc 'addhost NAME HOSTNAME',
12
+ 'Associate a host HOSTNAME with the group NAME'
13
+ def addhost(*args) # rubocop:disable Metrics/AbcSize
14
+ # Sanity
15
+ if args.length < 2
16
+ abort("ERROR: Wrong number of arguments, #{args.length} for 2 or more.")
17
+ end
18
+
19
+ # Arguments
20
+ name = args[0].downcase
21
+ hosts = args.slice(1, args.length - 1).uniq.map(&:downcase)
22
+
23
+ # Sanity
24
+ if name == 'ungrouped'
25
+ abort("ERROR: Cannot manually manipulate the automatic group 'ungrouped'.")
26
+ end
27
+
28
+ # Convenience
29
+ db = Moose::Inventory::DB
30
+ fmt = Moose::Inventory::Cli::Formatter
31
+
32
+ # Transaction
33
+ warn_count = 0
34
+ begin
35
+ db.transaction do # Transaction start
36
+ puts "Associate group '#{name}' with host(s) '#{hosts.join(',')}':"
37
+ # Get the target group
38
+ fmt.puts 2, "- retrieve group '#{name}'..."
39
+ group = db.models[:group].find(name: name)
40
+ if group.nil?
41
+ abort("ERROR: The group '#{name}' does not exist.")
42
+ end
43
+ fmt.puts 4, '- OK'
44
+
45
+ # Associate group with the hosts
46
+ ungrouped = db.models[:group].find_or_create(name: 'ungrouped')
47
+ hosts_ds = group.hosts_dataset
48
+ hosts.each do |h| # rubocop:disable Style/Next
49
+ fmt.puts 2, "- add association {group:#{name} <-> host:#{ h }}..."
50
+
51
+ # Check against existing associations
52
+ unless hosts_ds[name: h].nil?
53
+ warn_count += 1
54
+ fmt.warn "Association {group:#{name} <-> host:#{ h }} already"\
55
+ " exists, skipping.\n"
56
+ fmt.puts 4, '- already exists, skipping.'
57
+ fmt.puts 4, '- OK'
58
+ next
59
+ end
60
+
61
+ # Add new association
62
+ host = db.models[:host].find(name: h)
63
+ if host.nil?
64
+ warn_count += 1
65
+ fmt.warn "Host '#{h}' does not exist and will be created.\n"
66
+ fmt.puts 4, '- host does not exist, creating now...'
67
+ host = db.models[:host].create(name: h)
68
+ fmt.puts 6, '- OK'
69
+ end
70
+
71
+ group.add_host(host)
72
+ fmt.puts 4, '- OK'
73
+
74
+ # Remove the host from the ungrouped group, if necessary
75
+ unless host.groups_dataset[name: 'ungrouped'].nil?
76
+ fmt.puts 2,'- remove automatic association '\
77
+ "{group:ungrouped <-> host:#{h}}..."
78
+ host.remove_group(ungrouped)
79
+ fmt.puts 4, '- OK'
80
+ end
81
+ end
82
+ fmt.puts 2, '- all OK'
83
+ end # Transaction end
84
+ rescue db.exceptions[:moose] => e
85
+ abort("ERROR: #{e.message}")
86
+ end
87
+ if warn_count == 0
88
+ puts 'Succeeded.'
89
+ else
90
+ puts 'Succeeded, with warnings.'
91
+ end
92
+ end
93
+
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,72 @@
1
+ require 'thor'
2
+ require_relative './formatter.rb'
3
+
4
+ module Moose
5
+ module Inventory
6
+ module Cli
7
+ ##
8
+ # Implementation of the "group addvar" method of the CLI
9
+ class Group
10
+ #==========================
11
+ desc 'addvar NAME VARNAME=VALUE',
12
+ 'Add a variable VARNAME with value VALUE to the group NAME'
13
+ def addvar(*args)
14
+ if args.length < 2
15
+ abort('ERROR: Wrong number of arguments, '\
16
+ "#{args.length} for 2 or more.")
17
+ end
18
+ # Convenience
19
+ db = Moose::Inventory::DB
20
+ fmt = Moose::Inventory::Cli::Formatter
21
+
22
+ # Arguments
23
+ name = args[0].downcase
24
+ vars = args.slice(1, args.length - 1).uniq
25
+
26
+ # Transaction
27
+ db.transaction do # Transaction start
28
+ puts "Add variables '#{vars.join(",")}' to group '#{name}':"
29
+ fmt.puts 2,"- retrieve group '#{name}'..."
30
+ group = db.models[:group].find(name: name)
31
+ if group.nil?
32
+ fail db.exceptions[:moose],
33
+ "The group '#{name}' does not exist."
34
+ end
35
+ fmt.puts 4, '- OK'
36
+
37
+ groupvars_ds = group.groupvars_dataset
38
+ vars.each do |v|
39
+ fmt.puts 2, "- add variable '#{v}'..."
40
+ vararray = v.split('=')
41
+
42
+ if v.start_with?('=') || v.end_with?('=') || vararray.length != 2
43
+ fail db.exceptions[:moose],
44
+ "Incorrect format in '{#{v}}'. Expected 'key=value'."
45
+ end
46
+
47
+ # Check against existing associations
48
+ groupvar = groupvars_ds[name: vararray[0]]
49
+ if !groupvar.nil?
50
+ unless groupvar[:value] == vararray[1]
51
+ fmt.puts 4, '- already exists, applying as an update...'
52
+ update = db.models[:groupvar].find(id: groupvar[:id])
53
+ update[:value] = vararray[1]
54
+ update.save
55
+ end
56
+ else
57
+ # groupvar doesn't exist, so create and associate
58
+ groupvar = db.models[:groupvar].create(name: vararray[0],
59
+ value: vararray[1])
60
+ group.add_groupvar(groupvar)
61
+ end
62
+ fmt.puts 4, '- OK'
63
+ end
64
+ fmt.puts 2, '- all OK'
65
+ end # Transaction end
66
+
67
+ puts 'Succeeded.'
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,52 @@
1
+ require 'thor'
2
+ require_relative './formatter.rb'
3
+
4
+ module Moose
5
+ module Inventory
6
+ module Cli
7
+ ##
8
+ # Implementation of the "group get" method of the CLI
9
+ class Group
10
+ desc 'get GROUP_1 [GROUP_2 ...]', 'Get groups GROUP_n from the inventory'
11
+ def get(*argv) # rubocop:disable Metrics/AbcSize
12
+ if argv.length < 1
13
+ abort('ERROR: Wrong number of arguments, '\
14
+ "#{argv.length} for 1 or more")
15
+ end
16
+
17
+ # Convenience
18
+ db = Moose::Inventory::DB
19
+ fmt = Moose::Inventory::Cli::Formatter
20
+
21
+ # Arguments
22
+ names = argv.uniq.map(&:downcase)
23
+
24
+ # Process
25
+ results = {}
26
+ names.each do |name|
27
+ group = db.models[:group].find(name: name)
28
+
29
+ unless group.nil?
30
+ hosts = group.hosts_dataset.map(:name)
31
+
32
+ groupvars = {}
33
+ group.groupvars_dataset.each do |gv|
34
+ groupvars[gv[:name].to_sym] = gv[:value]
35
+ end
36
+
37
+ results[group[:name].to_sym] = {}
38
+ unless hosts.length == 0
39
+ results[group[:name].to_sym][:hosts] = hosts
40
+ end
41
+ unless groupvars.length == 0
42
+ results[group[:name].to_sym][:groupvars] = groupvars
43
+ end
44
+ end
45
+ end
46
+
47
+ fmt.dump(results)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end