bin/onering in onering-client-0.0.46 vs bin/onering in onering-client-0.0.50
- old
+ new
@@ -1,328 +1,45 @@
#!/usr/bin/env ruby
-
-#onering
-# list [options] field [key:value ..]
-# search [options] [key:value .. ]
-# provision [options] [key:value .. ] [pxe profile | ]
-
-
-require 'multi_json'
-require 'rubygems'
-require 'subcommander'
+require 'trollop'
require 'onering'
-require 'pp'
+require 'hashlib'
require 'rainbow'
+require 'pp'
-include Subcommander
+plugins = Onering::CLI.submodules.collect{|i| i.name.split('::').last.downcase }
+global = Trollop::options do
+ banner <<-EOS
+onering command line client utility
+Usage:
+ onering [global] [plugin] [subcommand] [options]
-def print_format(data, format=nil)
- format = :text unless format
+where [global] options are:
+EOS
- case format.to_sym
- when :text
- if data.is_a?(Hash)
- pp data
- else
- unless data.empty?
- if data.is_a?(Array)
- puts data.join("\n")
- else
- puts data.to_s
- end
- end
- end
+ opt :url, "The URL of the Onering server to connect to", :short => "-s", :type => :string
+ opt :path, "The base path to prepend to all requests (default: /api)", :type => :string
+ opt :format, "The output format for return values (i.e.: json, yaml, text)", :default => 'text', :short => "-t", :type => :string
+ opt :sslkey, "Location of the SSL client key to use for authentication", :short => "-c", :type => :string
+ opt :apikey, "The API token to use for authentication", :short => "-k", :type => :string
+ opt :quiet, "Suppress standard output", :short => '-q'
- when :yaml
- require 'yaml'
- puts YAML.dump(data)
-
- when :json
- require 'json'
- puts MultiJson.dump(data)
-
- else
- raise "Unknown output format #{format}"
- end
+ stop_on plugins
end
-begin
- subcommander.version = ::Gem.loaded_specs['onering-client'].version.to_s
- subcommander.desc = ::Gem.loaded_specs['onering-client'].description
+plugin = ARGV.shift
+Trollop::die("plugin argument is requried") if plugin.nil?
- subcommand :devices, "Operations related to Onering's assets database" do |devices|
- api = Onering::API::Devices
- api.connect({
- :host => ENV['ONERING_URL'],
- :pemfile => ENV['ONERING_PEM']
- })
-
- def _field(action, field, value, opts={})
- rv = []
- ids = []
-
- # append IDs from filter
- ids += Onering::API::Devices.list('id', {
- :filter => opts[:filter]
- }) if opts[:filter]
-
- # add specific ID
- ids << opts[:id] if opts[:id]
-
- ids.each do |id|
- case action
- when :get
- rv << Onering::API::Devices.get_field(id, field)
- when :set
- rv << Onering::API::Devices.set_field(id, field, value)
- end
- end
-
- rv
- end
-
- # SHOW
- devices.subcommand :show, "Print out a single node by ID" do |sc|
- sc.usage = "onering devices show ID"
- sc.opt :format, '-t', '--format FORMAT', "Return the results as FORMAT"
-
- sc.exec do
- id = sc[:args].first
- print_format(api.get(id), sc[:format])
- end
- end
-
- # GET [FIELD]
- devices.subcommand :get, "Get a named field from one or more devices" do |sc|
- sc.usage = "onering devices get FIELD"
- sc.opt :filter, '-f', '--filter FILTER', "A urlquery filter string"
- sc.opt :format, '-t', '--format FORMAT', "Return the results as FORMAT"
- sc.opt :id, '-i', '--id ID', "A specific node ID"
-
-
- sc.exec do
- rv = _field(:get, sc[:args].first, nil, sc)
- print_format(rv, sc[:format])
- end
- end
-
- # SET [FIELD]
- devices.subcommand :set, "Set a named field for one or more devices" do |sc|
- sc.usage = "onering devices set FIELD VALUE"
- sc.opt :filter, '-f', '--filter FILTER', "A urlquery filter string"
- sc.opt :format, '-t', '--format FORMAT', "Return the results as FORMAT"
- sc.opt :id, '-i', '--id ID', "A specific node ID"
-
- sc.exec do
- rv = _field(:set, sc[:args].first, sc[:args][1], sc)
- print_format(rv, sc[:format])
- end
- end
-
- # LIST
- devices.subcommand :list, "List field values" do |sc|
- sc.usage = "onering devices list [-f FILTER] FIELD"
- sc.opt :filter, '-f', '--filter FILTER', "A urlquery filter string"
- sc.opt :format, '-t', '--format FORMAT', "Return the results as FORMAT"
-
- sc.exec do
- field = sc[:args].first
- filter = sc[:filter]
-
- print_format(api.list(field, {
- :filter => filter
- }), sc[:format])
- end
- end
-
- # FIND
- devices.subcommand :find, "Finds all nodes that match a urlquery filter string" do |sc|
- sc.arity = 1
- sc.usage = "onering devices find FILTER"
- sc.opt :format, '-t', '--format FORMAT', "Return the results as FORMAT"
-
- sc.exec do
- print_format(api.find(sc[:args].first), sc[:format])
- end
- end
-
- # SAVE
- devices.subcommand :save, "Creates or updates a new device in Onering, reading a JSON document from standard input" do |sc|
- sc.usage = "onering report | onering devices save [ID]"
-
- sc.exec do
- unless STDIN.tty?
- begin
- json = ::MultiJson.load(STDIN.read)
- raise "Input document must specify an ID" if sc[:args].empty? and not json['id']
-
- rv = api.save((sc[:args].first || json['id']), json)
- print_format(rv, :json) if rv
- rescue Exception => e
- STDERR.puts "#{e.class.name}: #{e.message}"
- exit 1
- end
- end
- end
- end
+if plugins.include?(plugin)
+ begin
+ plugin = Onering::CLI.const_get(plugin.capitalize)
+ plugin.configure(global)
+ rv = plugin.run(ARGV)
+ Onering::CLI.output(rv, global[:format])
+ rescue Onering::API::Errors::Exception => e
+ STDERR.puts("[#{e.class.name.split('::').last}]".foreground(:red) + " #{e.message}")
+ exit 1
end
-
-
- subcommand :users, "Manage Onering users" do |users|
- api = Onering::API::Auth
- api.connect({
- :host => ENV['ONERING_URL'],
- :pemfile => ENV['ONERING_PEM']
- })
-
- # SHOW
- users.subcommand :show, "Print out a single user by ID" do |sc|
- sc.usage = "onering users show ID"
-
- sc.exec do
- id = sc[:args].first
- print_format(api.get(:users, id))
- end
- end
-
- # LIST
- users.subcommand :list, "List users" do |sc|
- sc.usage = "onering users list FIELD"
- sc.opt :format, '-t', '--format FORMAT', "Return the results as FORMAT"
-
- sc.exec do
- field = sc[:args].first
- filter = sc[:filter]
-
- print_format(api.list(:users, field, {
- :filter => filter
- }), sc[:format])
- end
- end
-
- # SAVE
- users.subcommand :save, "Creates or updates a new device in Onering, reading a JSON document from standard input" do |sc|
- sc.usage = "cat user.json | onering users save [ID]"
-
- sc.exec do
- unless STDIN.tty?
- begin
- json = ::MultiJson.load(STDIN.read)
- raise "Input document must specify an ID" if sc[:args].empty? and not json['id']
-
- print_format(api.save((sc[:args].first || json['id']), json))
- rescue Exception => e
- STDERR.puts "#{e.class.name}: #{e.message}"
- exit 1
- end
- end
- end
- end
- end
-
- subcommand :call, "Call generic Onering API endpoints" do |call|
- api = Onering::API::Base
- api.connect({
- :host => ENV['ONERING_URL'],
- :pemfile => ENV['ONERING_PEM']
- })
-
- call.usage = "onering call path/to/endpoint"
- call.opt :format, '-t', '--format FORMAT', "Return the results as FORMAT"
- call.opt :method, '-m', '--method VERB', "The HTTP method to use for the call (default: GET)"
- call.opt :opts, '-o', '--option KEY:VALUE', Array, "A comma-separated list of key:value querystrings to pass with the request"
-
- call.exec do
- rv = api.request(call[:args].first.to_sym, {
- :method => (call[:method] || :get),
- :data => (STDIN.tty? ? {} : ::MultiJson.load(STDIN.read) rescue {}),
- :fields => (Hash[call[:opts].collect{|i| i.split(':',2) }] rescue {})
- })
-
- print_format(rv, call[:format] || :json) unless rv.nil? or rv.to_s.strip.chomp.empty?
- end
- end
-
- subcommand :fact, "Retrieve a system fact" do |fact|
- fact.usage = "onering fact NAME [DEFAULT] [NAME2 [DEFAULT2] ..]"
- fact.opt :format, '-t', '--format FORMAT', "Return the results as FORMAT"
-
- fact.exec do
- Onering::Reporter.setup()
- rv = []
-
- fact[:args].each_index do |i|
- if i.even?
- name = fact[:args][i]
- else
- default = fact[:args][i]
- end
-
- rv << Onering::Reporter.fact(name, default)
- end
-
- rv.compact!
- rv = rv.first if rv.length == 1
-
- print_format(rv, fact[:format]) unless rv.nil? or rv.to_s.empty?
- end
- end
-
-
- subcommand :report, "Collect and output system information" do |report|
- report.usage = "onering report"
- report.opt :plugin_path, '-p', '--plugin PATH', 'Add the named path to the plugin search path'
- report.opt :status, '-S', '--status STATUS', 'Set the status to report'
- report.opt :tags, '-T', '--tag TAG[,...]', 'Add a tag to the report output'
- report.opt :aliases, '-A', '--alias ALIAS[,...]', 'Add a alias to the report output'
- report.opt :id, '-I', '--id ID', 'Override the auto-detected hardware ID'
- report.opt :format, '-t', '--format FORMAT', 'Format the output'
-
- report.exec do
- config = {}
- %w{
- plugin_path
- status
- tags
- aliases
- id
- }.each do |a|
- a = a.to_sym
- next if report[a].nil?
-
- if [:tags, :aliases].include?(a)
- config[a] = report[a].split(',')
- else
- config[a] = report[a]
- end
- end
-
- Onering::Reporter.setup(config)
-
- rv = Onering::Reporter.report()
- print_format(rv, report[:format] || :json) unless rv.nil?
- end
- end
-
-
- subcommander.go!
-
-rescue SystemExit
- exit 0
-
-rescue Interrupt
- exit 127
-
-rescue Onering::API::Errors::ClientError => e
- STDERR.puts("#{e.message}".foreground(:red))
- exit 1
-
-rescue Exception => e
- STDERR.puts("#{e.class.name}: #{e.message}".foreground(:red))
- e.backtrace.each do |b|
- STDERR.puts(" #{b}")
- end
-
- exit 1
+else
+ Trollop::die("unknown plugin #{plugin}")
end
\ No newline at end of file