moose-inventory 0.1.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.
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,41 @@
1
+ require 'thor'
2
+ require_relative './formatter.rb'
3
+
4
+ module Moose
5
+ module Inventory
6
+ module Cli
7
+ ##
8
+ # Implementation of the "group list" method of the CLI
9
+ class Group
10
+ #==========================
11
+ desc 'list',
12
+ 'List the groups, together with any associated hosts and groupvars'
13
+ option :ansiblestyle, type: :boolean
14
+ def list # rubocop:disable Metrics/AbcSize
15
+ # Convenience
16
+ db = Moose::Inventory::DB
17
+
18
+ # Process
19
+ results = {}
20
+ db.models[:group].all.each do |group|
21
+ hosts = group.hosts_dataset.map(:name)
22
+
23
+ groupvars = {}
24
+ group.groupvars_dataset.each do |gv|
25
+ groupvars[gv[:name].to_sym] = gv[:value]
26
+ end
27
+
28
+ results[group[:name].to_sym] = {}
29
+ unless hosts.length == 0
30
+ results[group[:name].to_sym][:hosts] = hosts
31
+ end
32
+ unless groupvars.length == 0
33
+ results[group[:name].to_sym][:groupvars] = groupvars
34
+ end
35
+ end
36
+ Formatter.out(results)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,77 @@
1
+ require 'thor'
2
+ require_relative './formatter.rb'
3
+
4
+ module Moose
5
+ module Inventory
6
+ module Cli
7
+ ##
8
+ # Implementation of "group rm" methods of the CLI
9
+ class Group
10
+
11
+ #==========================
12
+ desc 'rm NAME',
13
+ 'Remove a group NAME from the inventory'
14
+ def rm(*argv) # rubocop:disable Metrics/AbcSize
15
+ #
16
+ # Sanity
17
+ if argv.length < 1
18
+ abort('ERROR: Wrong number of arguments, '\
19
+ "#{argv.length} for 1 or more.")
20
+ end
21
+
22
+ # Convenience
23
+ db = Moose::Inventory::DB
24
+ fmt = Moose::Inventory::Cli::Formatter
25
+
26
+ # Arguments
27
+ names = argv.uniq.map(&:downcase)
28
+
29
+ # sanity
30
+ if names.include?('ungrouped')
31
+ abort("Cannot manually manipulate the automatic group 'ungrouped'\n")
32
+ end
33
+
34
+ # Transaction
35
+ warn_count = 0
36
+ db.transaction do # Transaction start
37
+ names.each do |name|
38
+ puts "Remove group '#{name}':"
39
+ fmt.puts 2, "- Retrieve group '#{name}'..."
40
+ group = db.models[:group].find(name: name)
41
+ if group.nil?
42
+ warn_count += 1
43
+ fmt.warn "Group '#{ name }' does not exist, skipping.\n"
44
+ fmt.puts 4, "- No such group, skipping."
45
+ end
46
+ fmt.puts 4, "- OK"
47
+ unless group.nil?
48
+ # Handle automatic group for any associated hosts
49
+ hosts_ds = group.hosts_dataset
50
+ hosts_ds.each do |host|
51
+ host_groups_ds = host.groups_dataset
52
+ if host_groups_ds.count == 1 # We're the only group
53
+ fmt.puts 2, "- Adding automatic association {group:ungrouped <-> host:#{host[:name]}}..."
54
+ ungrouped = db.models[:group].find_or_create(name: 'ungrouped')
55
+ host.add_group(ungrouped)
56
+ fmt.puts 4, "- OK"
57
+ end
58
+ end
59
+ # Remove the group
60
+ fmt.puts 2, "- Destroy group '#{name}'..."
61
+ group.remove_all_hosts
62
+ group.destroy
63
+ fmt.puts 4, "- OK"
64
+ end
65
+ fmt.puts 2, "- All OK"
66
+ end
67
+ end # Transaction end
68
+ if warn_count == 0
69
+ puts "Succeeded."
70
+ else
71
+ puts "Succeeded, with warnings."
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,20 @@
1
+ require 'thor'
2
+ require_relative './formatter.rb'
3
+
4
+ module Moose
5
+ module Inventory
6
+ module Cli
7
+ ##
8
+ # Implemention of the "group rmchild" methods of the CLI
9
+ class Group < Thor # rubocop:disable ClassLength
10
+ #==========================
11
+ desc 'rmchild NAME CHILDNAME',
12
+ 'Dissociate a child-group CHILDNAME from the group NAME'
13
+ def rmchild
14
+ abort("The 'groups rmchild GROUP' method is not yet implemented")
15
+ puts 'group rmchild'
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,89 @@
1
+ require 'thor'
2
+ require_relative './formatter.rb'
3
+
4
+ module Moose
5
+ module Inventory
6
+ module Cli
7
+ ##
8
+ # Implementation of the "group rmhost" method of the CLI
9
+ class Group
10
+
11
+ #==========================
12
+ desc 'rmhost GROUPNAME HOSTNAME_1 [HOSTNAME_2 ...]',
13
+ 'Dissociate the hosts HOSTNAME_n from the group NAME'
14
+ # rubocop:disable Metrics/LineLength
15
+ def rmhost(*args) # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/CyclomaticComplexity
16
+ # rubocop:enable Metrics/LineLength
17
+ # Sanity
18
+ if args.length < 2
19
+ abort("ERROR: Wrong number of arguments, #{args.length} for 2 or more.")
20
+ end
21
+
22
+ # Arguments
23
+ name = args[0].downcase
24
+ hosts = args.slice(1, args.length - 1).uniq.map(&:downcase)
25
+
26
+ # Sanity
27
+ if name == 'ungrouped'
28
+ abort("ERROR: Cannot manually manipulate the automatic group 'ungrouped'.")
29
+ end
30
+
31
+ # Convenience
32
+ db = Moose::Inventory::DB
33
+ fmt = Moose::Inventory::Cli::Formatter
34
+
35
+ # Transaction
36
+ warn_count = 0
37
+ begin
38
+ db.transaction do # Transaction start
39
+ # Get the target group
40
+ puts "Dissociate group '#{name}' from host(s) '#{hosts.join(',')}':"
41
+ fmt.puts 2, "- retrieve group '#{name}'..."
42
+ group = db.models[:group].find(name: name)
43
+ if group.nil?
44
+ abort("ERROR: The group '#{name}' does not exist.")
45
+ end
46
+ fmt.puts 4, '- OK'
47
+
48
+ # dissociate group from the hosts
49
+ ungrouped = db.models[:group].find_or_create(name: 'ungrouped')
50
+ hosts_ds = group.hosts_dataset
51
+ hosts.each do |h| # rubocop:disable Style/Next
52
+ fmt.puts 2, "- remove association {group:#{name} <-> host:#{ h }}..."
53
+
54
+ # Check against existing associations
55
+ if hosts_ds[name: h].nil?
56
+ warn_count += 1
57
+ fmt.warn "Association {group:#{name} <-> host:#{ h }} doesn't"\
58
+ " exist, skipping.\n"
59
+ fmt.puts 4, '- doesn\'t exist, skipping.'
60
+ fmt.puts 4, '- OK'
61
+ next
62
+ end
63
+
64
+ host = db.models[:host].find(name: h)
65
+ group.remove_host(host) unless host.nil?
66
+ fmt.puts 4,'- OK'
67
+
68
+ # Add the host to the ungrouped group if not in any other group
69
+ if host.groups_dataset.count == 0
70
+ fmt.puts 2, "- add automatic association {group:ungrouped <-> host:#{h}}..."
71
+ host.add_group(ungrouped)
72
+ fmt.puts 4, '- OK'
73
+ end
74
+ end
75
+ fmt.puts 2, '- all OK'
76
+ end # Transaction end
77
+ rescue db.exceptions[:moose] => e
78
+ abort("ERROR: #{e.message}")
79
+ end
80
+ if warn_count == 0
81
+ puts 'Succeeded.'
82
+ else
83
+ puts 'Succeeded, with warnings.'
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,65 @@
1
+ require 'thor'
2
+ require_relative './formatter.rb'
3
+
4
+ module Moose
5
+ module Inventory
6
+ module Cli
7
+ ##
8
+ # Implementation of the "group rmvar" method of the CLI
9
+ class Group
10
+ #==========================
11
+ desc 'rmvar NAME VARNAME',
12
+ 'Remove a variable VARNAME from the group NAME'
13
+ def rmvar(*args)
14
+ if args.length < 2
15
+ abort('ERROR: Wrong number of arguments, ' \
16
+ "#{args.length} for 2 or more.")
17
+ end
18
+
19
+ # Convenience
20
+ db = Moose::Inventory::DB
21
+ fmt = Moose::Inventory::Cli::Formatter
22
+
23
+ # Arguments
24
+ name = args[0].downcase
25
+ vars = args.slice(1, args.length - 1).uniq
26
+
27
+ # Transaction
28
+ db.transaction do # Transaction start
29
+ puts "Remove variable(s) '#{vars.join(",")}' from group '#{name}':"
30
+
31
+ fmt.puts 2, "- retrieve group '#{name}'..."
32
+ group = db.models[:group].find(name: name)
33
+ if group.nil?
34
+ fail db.exceptions[:moose],
35
+ "The group '#{name}' does not exist."
36
+ end
37
+ fmt.puts 4, '- OK'
38
+
39
+ groupvars_ds = group.groupvars_dataset
40
+ vars.each do |v|
41
+ fmt.puts 2, "- remove variable '#{v}'..."
42
+ vararray = v.split('=')
43
+ if v.start_with?('=') || v.scan('=').count > 1
44
+ fail db.exceptions[:moose],
45
+ "Incorrect format in {#{v}}. " \
46
+ 'Expected \'key\' or \'key=value\'.'
47
+ end
48
+
49
+ # Check against existing associations
50
+ groupvar = groupvars_ds[name: vararray[0]]
51
+ unless groupvar.nil?
52
+ # remove the association
53
+ group.remove_groupvar(groupvar)
54
+ groupvar.destroy
55
+ end
56
+ fmt.puts 4, '- OK'
57
+ end
58
+ fmt.puts 2, '- all OK'
59
+ end # Transaction end
60
+ puts 'Succeeded.'
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,24 @@
1
+ require 'thor'
2
+ require 'json'
3
+
4
+ require_relative './formatter.rb'
5
+ require_relative '../db/exceptions.rb'
6
+
7
+ module Moose
8
+ module Inventory
9
+ module Cli
10
+ ##
11
+ # Class implementing the "host" methods of the CLI
12
+ class Host < Thor # rubocop:disable Metrics/ClassLength
13
+ require_relative 'host_add'
14
+ require_relative 'host_get'
15
+ require_relative 'host_list'
16
+ require_relative 'host_rm'
17
+ require_relative 'host_addgroup'
18
+ require_relative 'host_rmgroup'
19
+ require_relative 'host_addvar'
20
+ require_relative 'host_rmvar'
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,93 @@
1
+ require 'thor'
2
+ require 'json'
3
+ require 'indentation'
4
+
5
+ require_relative './formatter.rb'
6
+ require_relative '../db/exceptions.rb'
7
+
8
+ module Moose
9
+ module Inventory
10
+ module Cli
11
+ ##
12
+ # Class implementing the "host" methods of the CLI
13
+ class Host
14
+ #==========================
15
+ desc 'add HOSTNAME_1 [HOSTNAME_2 ...]',
16
+ 'Add a hosts HOSTNAME_n to the inventory'
17
+ option :groups
18
+ # rubocop:disable Metrics/LineLength
19
+ def add(*argv) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
20
+ # rubocop:enable Metrics/LineLength
21
+ if argv.length < 1
22
+ abort('ERROR: Wrong number of arguments, '\
23
+ "#{argv.length} for 1 or more.")
24
+ end
25
+
26
+ # Convenience
27
+ db = Moose::Inventory::DB
28
+ fmt = Moose::Inventory::Cli::Formatter
29
+
30
+ # Arguments
31
+ names = argv.uniq.map(&:downcase)
32
+
33
+ # split(/\W+/) splits on hyphens too, which is not what we want
34
+ #groups = options[:groups].downcase.split(/\W+/).uniq
35
+ options[:groups].nil? && options[:groups] = ''
36
+ groups = options[:groups].downcase.split(',').uniq
37
+
38
+ # Sanity
39
+ if groups.include?('ungrouped')
40
+ abort("ERROR: Cannot manually manipulate "\
41
+ "the automatic group 'ungrouped'.")
42
+ end
43
+
44
+ # Process
45
+ db.transaction do # Transaction start
46
+ fmt.reset_indent
47
+
48
+ names.each do |name|
49
+ puts "Add host '#{name}':"
50
+ fmt.puts 2, "- Creating host '#{name}'..."
51
+ host = db.models[:host].find(name: name)
52
+ groups_ds = nil
53
+ if host.nil?
54
+ host = db.models[:host].create(name: name)
55
+ else
56
+ fmt.warn "The host '#{name}' already exists, skipping creation.\n"
57
+ groups_ds = host.groups_dataset
58
+ end
59
+ fmt.puts 4, "- OK"
60
+
61
+ groups.each do |g|
62
+ next if g.nil? || g.empty?
63
+ fmt.puts 2, "- Adding association {host:#{name} <-> group:#{g}}..."
64
+ group = db.models[:group].find(name: g)
65
+ if group.nil?
66
+ fmt.warn "The group '#{g}' doesn't exist, but will be created.\n"
67
+ group = db.models[:group].create(name: g)
68
+ end
69
+ if !groups_ds.nil? && groups_ds[name: g].nil?
70
+ fmt.warn "Association {host:#{name} <-> group:#{ g }} already exists, skipping creation.\n"
71
+ else
72
+ host.add_group(group)
73
+ end
74
+ fmt.puts 4, '- OK'
75
+ end
76
+
77
+ # Handle the automatic 'ungrouped' group
78
+ groups_ds = host.groups_dataset
79
+ if !groups_ds.nil? && groups_ds.count == 0
80
+ fmt.puts 2, "- Adding automatic association {host:#{name} <-> group:ungrouped}..."
81
+ ungrouped = db.models[:group].find_or_create(name: 'ungrouped')
82
+ host.add_group(ungrouped)
83
+ fmt.puts 4, "- OK"
84
+ end
85
+ fmt.puts 2, "- All OK"
86
+ end
87
+ end # Transaction end
88
+ puts 'Succeeded'
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,88 @@
1
+ require 'thor'
2
+ require 'json'
3
+
4
+ require_relative './formatter.rb'
5
+ require_relative '../db/exceptions.rb'
6
+
7
+ module Moose
8
+ module Inventory
9
+ module Cli
10
+ ##
11
+ # implementation of the "addgroup" method of the CLI
12
+ class Host
13
+ desc 'addgroup HOSTNAME GROUPNAME [GROUPNAME ...]',
14
+ 'Associate the host with a group'
15
+ # rubocop:disable Metrics/LineLength
16
+ def addgroup(*args) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
17
+ # rubocop:enable Metrics/LineLength
18
+ # Sanity
19
+ if args.length < 2
20
+ abort('ERROR: Wrong number of arguments, '\
21
+ "#{args.length} for 2 or more.")
22
+ end
23
+
24
+ # Convenience
25
+ db = Moose::Inventory::DB
26
+ fmt = Moose::Inventory::Cli::Formatter
27
+
28
+ # Arguments
29
+ name = args[0].downcase
30
+ groups = args.slice(1, args.length - 1).uniq.map(&:downcase)
31
+
32
+ # Sanity
33
+ if groups.include?('ungrouped')
34
+ abort 'ERROR: Cannot manually manipulate the automatic '\
35
+ 'group \'ungrouped\'.'
36
+ end
37
+
38
+ # Transaction
39
+ db.transaction do # Transaction start
40
+ puts "Associate host '#{name}' with groups '#{groups.join(',')}':"
41
+ # Get the target host
42
+ fmt.puts 2, "- Retrieve host '#{name}'..."
43
+ host = db.models[:host].find(name: name)
44
+ if host.nil?
45
+ fail db.exceptions[:moose], "The host '#{name}' "\
46
+ 'was not found in the database.'
47
+ end
48
+ fmt.puts 4, '- OK'
49
+
50
+ # Associate host with the groups
51
+ groups_ds = host.groups_dataset
52
+ groups.each do |g|
53
+ fmt.puts 2, "- Add association {host:#{name} <-> group:#{ g }}..."
54
+
55
+ # Check against existing associations
56
+ if !groups_ds[name: g].nil?
57
+ fmt.warn "Association {host:#{name} <-> group:#{g}} already exists, skipping."
58
+ fmt.puts 4, "- Already exists, skipping."
59
+ else
60
+ # Add new association
61
+ group = db.models[:group].find(name: g)
62
+ if group.nil?
63
+ fmt.warn "Group '#{g}' does not exist and will be created."
64
+ fmt.puts 4, "- Group does not exist, creating now..."
65
+ group = db.models[:group].create(name: g)
66
+ fmt.puts 6, "- OK"
67
+ end
68
+ host.add_group(group)
69
+ end
70
+ fmt.puts 4, '- OK'
71
+ end
72
+
73
+ # Handle 'ungrouped' group automation
74
+ unless groups_ds[name: 'ungrouped'].nil?
75
+ fmt.puts 2, '- Remove automatic association '\
76
+ "{host:#{name} <-> group:ungrouped}..."
77
+ ungrouped = db.models[:group].find(name: 'ungrouped')
78
+ host.remove_group(ungrouped) unless ungrouped.nil?
79
+ fmt.puts 4, '- OK'
80
+ end
81
+ fmt.puts 2, '- All OK'
82
+ end # Transaction end
83
+ puts 'Succeeded'
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end