class Moose::Inventory::Cli::Group

Class implementing the “group” methods of the CLI

Implementation of the “group add” method of the CLI

Implemention of the “group addchild” methods of the CLI

Implementation of the “group addhost” method of the CLI

Implementation of the “group addvar” method of the CLI

Implementation of the “group get” method of the CLI

Implementation of the “group list” method of the CLI

implementation of the “group listvars” method of the CLI

Implementation of “group rm” methods of the CLI

Implemention of the “group rmchild” methods of the CLI

Implementation of the “group rmhost” method of the CLI

Implementation of the “group rmvar” method of the CLI

Public Instance Methods

add(*argv) click to toggle source

rubocop:disable Metrics/LineLength

# File lib/moose_inventory/cli/group_add.rb, line 14
def add(*argv) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
  # rubocop:enable Metrics/LineLength
  if argv.length < 1
    abort("ERROR: Wrong number of arguments, #{argv.length} for 1 or more.")
  end

  # Arguments
  names = argv.uniq.map(&:downcase)
  options[:hosts] = '' if options[:hosts].nil?
  hosts = options[:hosts].downcase.split(',').uniq

  # sanity
  if names.include?('ungrouped')
    abort("ERROR: Cannot manually manipulate the automatic group 'ungrouped'\n")
  end

    # Convenience
    db    = Moose::Inventory::DB
    fmt = Moose::Inventory::Cli::Formatter
  
  # Transaction
  warn_count = 0
  db.transaction do # Transaction start
    names.each do |name|
      # Add the group
      puts "Add group '#{name}':"
      group = db.models[:group].find(name: name)
      hosts_ds = nil
      fmt.puts 2, "- create group..."
      if group.nil?
        group = db.models[:group].create(name: name)
        fmt.puts 4, '- OK'
      else
        warn_count += 1
        fmt.warn "Group '#{name}' already exists, skipping creation.\n"
        fmt.puts 4, "- already exists, skipping."
        hosts_ds = group.hosts_dataset
        fmt.puts 4, '- OK'
      end
      
      # Associate with hosts
      hosts.each do |h|
        next if h.nil? || h.empty?
        fmt.puts 2, "- add association {group:#{name} <-> host:#{ h }}..."
        host = db.models[:host].find(name: h)
        if host.nil?
          warn_count += 1
          fmt.warn "Host '#{h}' doesn't exist, but will be created.\n"
          fmt.puts 4, "- host doesn't exist, creating now..."
          host = db.models[:host].create(name: h)
          fmt.puts 6, "- OK"
        end
        if !hosts_ds.nil? && !hosts_ds[name: h].nil?
          warn_count += 1
          fmt.warn "Association {group:#{name} <-> host:#{ h }}"\
            " already exists, skipping creation.\n"
            fmt.puts 4, "- already exists, skipping."
        else  
          group.add_host(host)
        end
        fmt.puts 4, '- OK'
  
        # Handle the host's automatic 'ungrouped' group
        ungrouped = host.groups_dataset[name: 'ungrouped']
        unless ungrouped.nil?
          fmt.puts 2, "- remove automatic association {group:ungrouped"\
            " <-> host:#{ h }}..."
          host.remove_group( ungrouped ) unless ungrouped.nil?
          fmt.puts 4, '- OK'
        end
      end
      fmt.puts 2, '- all OK'
    end
  end # Transaction end
  if warn_count == 0
    puts 'Succeeded'
  else
    puts 'Succeeded, with warnings.'
  end
end
addchild(*argv) click to toggle source
# File lib/moose_inventory/cli/group_addchild.rb, line 13
def addchild(*argv)
  
  # Sanity check
  if args.length < 2
    abort("ERROR: Wrong number of arguments, #{args.length} "\
      "for 2 or more.")
  end
  
  # Arguments
  pname = args[0].downcase
  cnames = args.slice(1, args.length - 1).uniq.map(&:downcase)
   
  # Sanity
  if pname == 'ungrouped' || cnames.include?('ungrouped')
    abort("ERROR: Cannot manually manipulate the automatic group 'ungrouped'.")
  end
  
  # Convenience
  db = Moose::Inventory::DB
  fmt = Moose::Inventory::Cli::Formatter

  # Transaction
  warn_count = 0
  begin 
    db.transaction do # Transaction start
      puts "Associate parent group '#{pname}' with child group(s) '#{cnames.join(',')}':"
      # Get the target group
      fmt.puts 2, "- retrieve group '#{pname}'..."
      pgroup = db.models[:group].find(name: pname)
      if pgroup.nil?
        abort("ERROR: The group '#{pname}' does not exist.")
      end
      fmt.puts 4, "- OK"
      
       # Associate parent group with the child groups

       groups_ds = pgroup.children_dataset
       cnames.each do |cname|
         fmt.puts 2, "- add association {group:#{pname} <-> group:#{cname}}..."
          
         # Check against existing associations
         unless groups_ds[name: cname].nil?
            warn_count += 1
            fmt.warn "Association {group:#{pname} <-> group:#{cname}}}"\
              " already exists, skipping.\n" 
            fmt.puts 4, '- already exists, skipping.'
            fmt.puts 4, '- OK'
            next
          end
          
          # Add new association
          cgroup = db.models[:group].find(name: cname)
          if cgroup.nil?
            warn_count += 1
            fmt.warn "Group '#{cname}' does not exist and will be created.\n"
            fmt.puts 4, '- child group does not exist, creating now...'
            cgroup = db.models[:group].create(name: cname)
            fmt.puts 6, '- OK'
          end
          pgroup.add_child(cgroup)
          fmt.puts 4, '- OK'
        end
        fmt.puts 2, '- all OK'
    end # Transaction end
  rescue db.exceptions[:moose] => e
      abort("ERROR: #{e}")
  end
  if warn_count == 0
    puts 'Succeeded.'
  else
    puts 'Succeeded, with warnings.'
  end
            
end
addhost(*args) click to toggle source
# File lib/moose_inventory/cli/group_addhost.rb, line 13
def addhost(*args) # rubocop:disable Metrics/AbcSize
  # Sanity
  if args.length < 2
    abort("ERROR: Wrong number of arguments, #{args.length} "\
      "for 2 or more.")
  end

  # Arguments
  name  = args[0].downcase
  hosts = args.slice(1, args.length - 1).uniq.map(&:downcase)

  # Sanity
  if name == 'ungrouped'
    abort("ERROR: Cannot manually manipulate the automatic group 'ungrouped'.")
  end

  # Convenience
  db = Moose::Inventory::DB
  fmt = Moose::Inventory::Cli::Formatter

  # Transaction
  warn_count = 0
  begin 
    db.transaction do # Transaction start
      puts "Associate group '#{name}' with host(s) '#{hosts.join(',')}':"
      # Get the target group
      fmt.puts 2, "- retrieve group '#{name}'..."
      group = db.models[:group].find(name: name)
      if group.nil?
        abort("ERROR: The group '#{name}' does not exist.")
      end
      fmt.puts 4,  '- OK'

      # Associate group with the hosts
      ungrouped  = db.models[:group].find_or_create(name: 'ungrouped')
      hosts_ds = group.hosts_dataset
      hosts.each do |h| # rubocop:disable Style/Next
        fmt.puts 2, "- add association {group:#{name} <-> host:#{ h }}..."

        # Check against existing associations
        unless hosts_ds[name: h].nil?
          warn_count += 1
          fmt.warn "Association {group:#{name} <-> host:#{ h }} already"\
            " exists, skipping.\n"
          fmt.puts 4, '- already exists, skipping.'
          fmt.puts 4, '- OK'
          next
        end

        # Add new association
        host = db.models[:host].find(name: h)
        if host.nil?
          warn_count += 1
          fmt.warn "Host '#{h}' does not exist and will be created.\n"
          fmt.puts 4, '- host does not exist, creating now...'
          host = db.models[:host].create(name: h)
          fmt.puts 6, '- OK'
        end
          
        group.add_host(host)
        fmt.puts 4, '- OK'

        # Remove the host from the ungrouped group, if necessary
        unless host.groups_dataset[name: 'ungrouped'].nil?
          fmt.puts 2,'- remove automatic association '\
            "{group:ungrouped <-> host:#{h}}..."
          host.remove_group(ungrouped)
          fmt.puts 4, '- OK'
        end
      end
      fmt.puts 2, '- all OK'
    end # Transaction end
  rescue db.exceptions[:moose] => e
    abort("ERROR: #{e.message}")
  end
  if warn_count == 0
    puts 'Succeeded.'
  else
    puts 'Succeeded, with warnings.'
  end
end
addvar(*args) click to toggle source
# File lib/moose_inventory/cli/group_addvar.rb, line 13
def addvar(*args)
  if args.length < 2
    abort('ERROR: Wrong number of arguments, '\
      "#{args.length} for 2 or more.")
  end
  # Convenience
  db = Moose::Inventory::DB
  fmt = Moose::Inventory::Cli::Formatter

  # Arguments
  name = args[0].downcase
  vars = args.slice(1, args.length - 1).uniq
  
# Transaction
db.transaction do # Transaction start
  puts "Add variables '#{vars.join(",")}' to group '#{name}':"
  fmt.puts 2,"- retrieve group '#{name}'..."
  group = db.models[:group].find(name: name)
  if group.nil?
    fail db.exceptions[:moose],
         "The group '#{name}' does not exist."
  end
  fmt.puts 4, '- OK'

  groupvars_ds = group.groupvars_dataset
  vars.each do |v|
    fmt.puts 2, "- add variable '#{v}'..."
    vararray = v.split('=')

    if v.start_with?('=') ||  v.end_with?('=') || vararray.length != 2
      fail db.exceptions[:moose],
           "Incorrect format in '{#{v}}'. Expected 'key=value'."
    end
 
    # Check against existing associations
    groupvar = groupvars_ds[name: vararray[0]]
    if !groupvar.nil?
      unless groupvar[:value] == vararray[1]
        fmt.puts 4, '- already exists, applying as an update...'
        update = db.models[:groupvar].find(id: groupvar[:id])
        update[:value] = vararray[1]
        update.save
      end
    else
      # groupvar doesn't exist, so create and associate
      groupvar = db.models[:groupvar].create(name: vararray[0],
                                            value: vararray[1])
      group.add_groupvar(groupvar)
    end
    fmt.puts 4, '- OK'
  end
  fmt.puts 2, '- all OK'
end # Transaction end

puts 'Succeeded.'
end
get(*argv) click to toggle source
# File lib/moose_inventory/cli/group_get.rb, line 11
def get(*argv) # rubocop:disable Metrics/AbcSize
  if argv.length < 1
    abort('ERROR: Wrong number of arguments, '\
      "#{argv.length} for 1 or more")
  end

  # Convenience
  db    = Moose::Inventory::DB
  fmt = Moose::Inventory::Cli::Formatter

  # Arguments
  names = argv.uniq.map(&:downcase)

  # Process
  results = {}
  names.each do |name|
    group = db.models[:group].find(name: name)
      
    unless group.nil?
      hosts = group.hosts_dataset.map(:name)
    
      children = group.children_dataset.map(:name)
      
      groupvars = {}
      group.groupvars_dataset.each do |gv|
        groupvars[gv[:name].to_sym] = gv[:value]
      end

      results[group[:name].to_sym] = {}
      unless hosts.length == 0
        results[group[:name].to_sym][:hosts]     = hosts
      end

      unless children.length == 0
        results[group[:name].to_sym][:children] = children
      end
      
      unless groupvars.length == 0
        results[group[:name].to_sym][:groupvars] = groupvars
      end
    end
  end
  
  fmt.dump(results)
end
list() click to toggle source
# File lib/moose_inventory/cli/group_list.rb, line 13
def list # rubocop:disable Metrics/AbcSize
  # Convenience
  db    = Moose::Inventory::DB
  confopts = Moose::Inventory::Config._confopts
  
  # Process
  results = {}
  db.models[:group].all.each do |group|
    
    hosts = group.hosts_dataset.map(:name)

    # Hide the automatic ungrouped group, if it's empty
    next if group[:name] == 'ungrouped' && hosts.length == 0

    children = group.children_dataset.map(:name)
                  
    groupvars = {}
    group.groupvars_dataset.each do |gv|
      groupvars[gv[:name].to_sym] = gv[:value]
    end

      
    results[group[:name].to_sym] = {}
    unless hosts.length == 0  and confopts[:ansible] != true 
      results[group[:name].to_sym][:hosts] = hosts
    end

    unless children.length == 0
      results[group[:name].to_sym][:children] = children
    end
    
    unless groupvars.length == 0
      if confopts[:ansible] == true
        results[group[:name].to_sym][:vars] = groupvars
      else
        results[group[:name].to_sym][:groupvars] = groupvars
      end
    end
  end
  Formatter.out(results)
end
listvars(*argv) click to toggle source
# File lib/moose_inventory/cli/group_listvars.rb, line 15
def listvars(*argv)
  # Convenience
  confopts = Moose::Inventory::Config._confopts

  # Note, the Ansible spects don't call for a "--group GROUPNAME" method.
  # So, strictly, there is no Ansible compatibility for this method.
  # Instead, the Ansible compatibility included herein is for consistency
  # with the "hosts listvars" method, which services the Ansible
  # "--host HOSTNAME" specs.
             
  # sanity
  if confopts[:ansible] == true
    if argv.length != 1
    abort('ERROR: Wrong number of arguments for Ansible mode, '\
          "#{args.length} for 1.")
    end
  else
    if argv.length < 1
      abort('ERROR: Wrong number of arguments, '\
            "#{args.length} for 1 or more.")
    end
  end


  # Convenience
  db = Moose::Inventory::DB
  fmt = Moose::Inventory::Cli::Formatter

  # Arguments
  names = argv.uniq.map(&:downcase)

  #process
  results = {}
    
  if confopts[:ansible] == true 
    # This is the implementation per Ansible specs
    name = names.first
    group = db.models[:group].find(name: name)
    if group.nil?
      fmt.warn "The Group #{name} does not exist."
    else
      group.groupvars_dataset.each do |gv|
        results[gv[:name].to_sym] = gv[:value]
      end
    end
  else
    # This our more flexible implementation
    names.each do |name|
      group = db.models[:group].find(name: name)
      unless group.nil?
        results[name.to_sym] = {}
        group.groupvars_dataset.each do |gv|
          results[name.to_sym][gv[:name].to_sym] = gv[:value]
        end
      end
    end
  end
  fmt.dump(results)
end
rm(*argv) click to toggle source
# File lib/moose_inventory/cli/group_rm.rb, line 14
def rm(*argv) # rubocop:disable Metrics/AbcSize
  #
  # Sanity
  if argv.length < 1
       abort('ERROR: Wrong number of arguments, '\
         "#{argv.length} for 1 or more.")
   end          
  
  # Convenience
  db    = Moose::Inventory::DB
  fmt = Moose::Inventory::Cli::Formatter

  # Arguments
  names = argv.uniq.map(&:downcase)

  # sanity
  if names.include?('ungrouped')
    abort("Cannot manually manipulate the automatic group 'ungrouped'\n")
  end
    
  # Transaction
  warn_count = 0
  db.transaction do # Transaction start
    names.each do |name|
      puts "Remove group '#{name}':"
      fmt.puts 2, "- Retrieve group '#{name}'..."
      group = db.models[:group].find(name: name)
      if group.nil?
        warn_count += 1
        fmt.warn "Group '#{ name }' does not exist, skipping.\n"
        fmt.puts 4, "- No such group, skipping."
      end
      fmt.puts 4, "- OK" 
      unless group.nil?
        # Dissociate from any parent groups
        pgroups_ds = group.parents_dataset
        pgroups_ds.each do |parent|
          fmt.puts 2, "- Remove association {group:#{name} <-> group:#{parent.name}}..."
          parent.remove_child(group)
          fmt.puts 4, '- OK'
        end

        # Dissociate from any child groups
        groups_ds = group.children_dataset
        groups_ds.each do |child|
          fmt.puts 2, "- Remove association {group:#{name} <-> group:#{child.name}}..."
          group.remove_child(child)
          # TODO: Should we propagate the delete to orphaned children?
          fmt.puts 4, '- OK'
        end
                        
        # Handle automatic group for any associated hosts
        hosts_ds = group.hosts_dataset
        hosts_ds.each do |host|
          host_groups_ds = host.groups_dataset
          if host_groups_ds.count == 1 # We're the only group
            fmt.puts 2, "- Adding automatic association {group:ungrouped <-> host:#{host[:name]}}..."
            ungrouped = db.models[:group].find_or_create(name: 'ungrouped')
            host.add_group(ungrouped)
            fmt.puts 4, "- OK"
          end
        end
        # Remove the group
        fmt.puts 2, "- Destroy group '#{name}'..."
        group.remove_all_hosts
        group.destroy
        fmt.puts 4, "- OK"
      end
      fmt.puts 2, "- All OK"
    end
  end # Transaction end
  if warn_count == 0
    puts "Succeeded."
  else
    puts "Succeeded, with warnings."
  end
end
rmchild(*argv) click to toggle source
# File lib/moose_inventory/cli/group_rmchild.rb, line 14
def rmchild(*argv)

  # Sanity check
  if args.length < 2
    abort("ERROR: Wrong number of arguments, #{args.length} "\
      "for 2 or more.")
  end

  # Arguments
  pname = args[0].downcase
  cnames = args.slice(1, args.length - 1).uniq.map(&:downcase)

  # Sanity
  if pname == 'ungrouped' || cnames.include?('ungrouped')
    abort("ERROR: Cannot manually manipulate the automatic group 'ungrouped'.")
  end

  # Convenience
  db = Moose::Inventory::DB
  fmt = Moose::Inventory::Cli::Formatter

  # Transaction
  warn_count = 0
  begin
    db.transaction do # Transaction start
      puts "Dissociate parent group '#{pname}' from child group(s) '#{cnames.join(',')}':"
      # Get the target group
      fmt.puts 2, "- retrieve group '#{pname}'..."
      pgroup = db.models[:group].find(name: pname)
      if pgroup.nil?
        abort("ERROR: The group '#{pname}' does not exist.")
      end
      fmt.puts 4, "- OK"

      # Dissociate parent group from the child groups
      groups_ds = pgroup.children_dataset
      cnames.each do |cname|
        fmt.puts 2, "- remove association {group:#{pname} <-> group:#{cname}}..."

        # Check against existing associations
        if groups_ds[name: cname].nil?
          warn_count += 1
          fmt.warn "Association {group:#{pname} <-> group:#{cname}}"\
              " does not exist, skipping.\n"
          fmt.puts 4, "- doesn't exist, skipping."
          fmt.puts 4, '- OK'
          next
        end

        # remove association
        cgroup = db.models[:group].find(name: cname)
        pgroup.remove_child(cgroup)
        fmt.puts 4, '- OK'
      end
      fmt.puts 2, '- all OK'
    end # Transaction end
  rescue db.exceptions[:moose] => e
    abort("ERROR: #{e}")
  end
  if warn_count == 0
    puts 'Succeeded.'
  else
    puts 'Succeeded, with warnings.'
  end
end
rmhost(*args) click to toggle source

rubocop:disable Metrics/LineLength

# File lib/moose_inventory/cli/group_rmhost.rb, line 15
def rmhost(*args) # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/CyclomaticComplexity
  # rubocop:enable Metrics/LineLength
  # Sanity
  if args.length < 2
    abort("ERROR: Wrong number of arguments, #{args.length} for 2 or more.")
  end

  # Arguments
  name = args[0].downcase
  hosts = args.slice(1, args.length - 1).uniq.map(&:downcase)

  # Sanity
  if name == 'ungrouped'
    abort("ERROR: Cannot manually manipulate the automatic group 'ungrouped'.")
  end

  # Convenience
  db    = Moose::Inventory::DB
  fmt = Moose::Inventory::Cli::Formatter

  # Transaction
  warn_count = 0
  begin
    db.transaction do # Transaction start
      # Get the target group
      puts "Dissociate group '#{name}' from host(s) '#{hosts.join(',')}':"
      fmt.puts 2, "- retrieve group '#{name}'..."
      group = db.models[:group].find(name: name)
      if group.nil?
        abort("ERROR: The group '#{name}' does not exist.")
      end
      fmt.puts 4, '- OK'

      # dissociate group from the hosts
      ungrouped  = db.models[:group].find_or_create(name: 'ungrouped')
      hosts_ds = group.hosts_dataset
      hosts.each do |h| # rubocop:disable Style/Next
        fmt.puts 2, "- remove association {group:#{name} <-> host:#{ h }}..."

        # Check against existing associations
        if hosts_ds[name: h].nil?
          warn_count += 1
          fmt.warn "Association {group:#{name} <-> host:#{ h }} doesn't"\
            " exist, skipping.\n"
          fmt.puts 4, '- doesn\'t exist, skipping.'
          fmt.puts 4, '- OK'
          next
        end

        host = db.models[:host].find(name: h)
        group.remove_host(host) unless host.nil?
        fmt.puts 4,'- OK'

        # Add the host to the ungrouped group if not in any other group
        if host.groups_dataset.count == 0
          fmt.puts 2, "- add automatic association {group:ungrouped <-> host:#{h}}..."
          host.add_group(ungrouped)
          fmt.puts 4, '- OK'
        end
      end
      fmt.puts 2, '- all OK'
    end # Transaction end
  rescue db.exceptions[:moose] => e
    abort("ERROR: #{e.message}")
  end
  if warn_count == 0
    puts 'Succeeded.'
  else
    puts 'Succeeded, with warnings.'
  end
end
rmvar(*args) click to toggle source
# File lib/moose_inventory/cli/group_rmvar.rb, line 13
def rmvar(*args)
  if args.length < 2
    abort('ERROR: Wrong number of arguments, ' \
          "#{args.length} for 2 or more.")
  end
  
  # Convenience
  db  = Moose::Inventory::DB
  fmt = Moose::Inventory::Cli::Formatter

  # Arguments
  name = args[0].downcase
  vars = args.slice(1, args.length - 1).uniq

  # Transaction
  db.transaction do # Transaction start
    puts "Remove variable(s) '#{vars.join(",")}' from group '#{name}':"
    
    fmt.puts 2, "- retrieve group '#{name}'..."
    group = db.models[:group].find(name: name)
    if group.nil?
      fail db.exceptions[:moose],
           "The group '#{name}' does not exist."
    end
    fmt.puts 4, '- OK'
    
    groupvars_ds = group.groupvars_dataset
    vars.each do |v|
      fmt.puts 2, "- remove variable '#{v}'..."
      vararray = v.split('=')
      if v.start_with?('=') || v.scan('=').count > 1
        fail db.exceptions[:moose],
             "Incorrect format in {#{v}}. " \
             'Expected \'key\' or \'key=value\'.'
      end
    
      # Check against existing associations
      groupvar = groupvars_ds[name: vararray[0]]
      unless groupvar.nil?
        # remove the association
        group.remove_groupvar(groupvar)
        groupvar.destroy
      end
      fmt.puts 4, '- OK'
    end
    fmt.puts 2, '- all OK'
  end # Transaction end
  puts 'Succeeded.'
end