bin/mkitc in mkit-0.4.1 vs bin/mkitc in mkit-0.4.2
- old
+ new
@@ -6,144 +6,310 @@
require 'yaml'
require 'net/http'
require 'json'
require 'net_http_unix'
require 'securerandom'
+require 'erb'
-class MKItClient
+class InvalidParametersException < RuntimeError
+ attr_reader :command
+ def initialize(cause, command = nil)
+ super(cause)
+ @command = command
+ end
+end
+class MKItClient
def initialize
- @client = NetX::HTTPUnix.new("localhost",4567)
+ @client = NetX::HTTPUnix.new('localhost', 4567)
end
- def parse_args(args)
- request = nil
- case args[0]
- when /^ps$/
- if args.include?('-v')
- params = {verbose: 'true'}
- args.delete('-v')
- else
- params = {}
+ def dict
+ global_args = [
+ { short: '-v', long: '--verbose', help: 'verbose', mandatory: false, value: nil }
+ ]
+ command_dict = [
+ {
+ cmd: 'ps',
+ args: [
+ { name: 'id', mandatory: false, uri: '/<%=id%>' }
+ ],
+ help: 'show services status (alias for status)',
+ usage: ['[service_id_or_name]'],
+ request: { verb: :get, uri: '/services' }
+ },
+ {
+ cmd: 'status',
+ args: [
+ { name: 'id', mandatory: false, uri: '/<%=id%>' }
+ ],
+ help: 'show services status',
+ usage: ['[service_id_or_name]'],
+ request: { verb: :get, uri: '/services' }
+ },
+ {
+ cmd: 'start',
+ args: [
+ { name: 'id', mandatory: true }
+ ],
+ help: 'start service',
+ usage: ['<service_id_or_name>'],
+ request: { verb: :put, uri: '/services/<%=id%>/start' }
+ },
+ {
+ cmd: 'stop',
+ args: [
+ { name: 'id', mandatory: true }
+ ],
+ help: 'stop service',
+ usage: ['<service_id_or_name>'],
+ request: { verb: :put, uri: '/services/<%=id%>/stop' }
+ },
+ {
+ cmd: 'restart',
+ args: [
+ { name: 'id', mandatory: true }
+ ],
+ help: 'restart service',
+ usage: ['<service_id_or_name>'],
+ request: { verb: :put, uri: '/services/<%=id%>/restart' }
+ },
+ {
+ cmd: 'create',
+ args: [
+ { name: 'file', mandatory: true }
+ ],
+ help: 'create new service',
+ usage: ['<service.yaml>'],
+ request: { verb: :post, uri: '/services' }
+ },
+ {
+ cmd: 'update',
+ args: [
+ { name: 'file', mandatory: true }
+ ],
+ help: 'update service',
+ usage: ['<service.yaml>'],
+ request: { verb: :put, uri: '/services/<%=id%>' }
+ },
+ {
+ cmd: 'rm',
+ args: [
+ { name: 'id', mandatory: true }
+ ],
+ help: 'remove service',
+ usage: ['<service_id_or_name>'],
+ request: { verb: :delete, uri: '/services/<%=id%>' }
+ },
+ {
+ cmd: 'version',
+ help: 'prints mkit server version',
+ request: { verb: :get, uri: '/mkit/version' }
+ },
+ {
+ cmd: 'proxy',
+ options: [
+ {
+ cmd: 'start',
+ request: { verb: :put, uri: '/mkit/proxy/start' },
+ help: 'start proxy service'
+ },
+ {
+ cmd: 'stop',
+ request: { verb: :put, uri: '/mkit/proxy/stop' },
+ help: 'stop proxy service'
+ },
+ {
+ cmd: 'restart',
+ request: { verb: :put, uri: '/mkit/proxy/restart' },
+ help: 'restarts proxy service'
+ },
+ {
+ cmd: 'status',
+ request: { verb: :get, uri: '/mkit/proxy/status' },
+ help: 'proxy service status'
+ }
+ ],
+ help: 'haproxy status and control',
+ usage: ['<start|stop|restart|status>']
+ }
+ ]
+ command_dict
+ end
+
+ def help(cause: nil, cmd: nil)
+ msg = ''
+ if cause.nil?
+ my_cmd = cmd
+ else
+ msg += "MKItc: #{cause.message}\n"
+ my_cmd = cause.command
+ end
+ if my_cmd.nil?
+ msg += "\nUsage: mkitc <command> [options]\n\n"
+ msg += "Micro k8s on Ruby - a simple tool to mimic a (very) minimalistic k8 cluster\n\n"
+ msg += "Commands:\n\n"
+ dict.each do |c|
+ msg += format("%-10s %s\n", c[:cmd], c[:help])
end
- case args.size
- when 1
- #mkitc ps [-v] GET services[?verbose=true]
- request = { verb: :get, uri: '/services', params: params }
- when 2
- #mkitc ps {id} GET services/{id}
- id = args[1]
- request = { verb: :get, uri: "/services/#{id}" }
- else
- raise 'invalid parameters'
+ msg += "\n"
+ msg += "Run 'mkitc help <command>' for specific command information.\n\n"
+ else
+ msg += format("\nUsage: mkitc %s %s\n\n", my_cmd[:cmd], my_cmd[:usage].nil? ? '' : my_cmd[:usage].join(' '))
+ msg += format("%s\n", my_cmd[:help])
+ unless my_cmd[:options].nil?
+ msg += "\nOptions:\n"
+ my_cmd[:options].each do |c|
+ msg += format("%-10s %s\n", c[:cmd], c[:help])
+ end
end
- when /^config:show$/
- #mkitc config:show {id} => GET services/{id}/config
- #TODO
- when /^stop$/
- #mkitc stop {id} => PUT services/{id}/stop
- case args.size
- when 2
- id = args[1]
- request = { verb: :put, uri: "/services/#{id}/stop" }
- else
- raise 'invalid parameters'
+ msg += "\n"
+ end
+ puts msg
+ exit 1
+ end
+
+ def create(request, request_hash = nil)
+ unless File.file?(request_hash[:file])
+ raise InvalidParametersException.new('File not found.', c = dict.select { |k| k[:cmd] == 'create' }.first)
+ end
+
+ yaml = YAML.load_file(request_hash[:file])
+ if yaml['service'].nil?
+ raise InvalidParametersException.new('Invalid configuration file', c = dict.select { |k| k[:cmd] == 'create' }.first)
+ else
+ request(request, request_hash)
+ end
+ end
+
+ def update(request, request_hash = nil)
+ unless File.file?(request_hash[:file])
+ raise InvalidParametersException.new('File not found.', c = dict.select { |k| k[:cmd] == 'update' }.first)
+ end
+
+ yaml = YAML.load_file(request_hash[:file])
+ if yaml['service'].nil?
+ raise InvalidParametersException.new('Invalid configuration file', c = dict.select { |k| k[:cmd] == 'update' }.first)
+ else
+ id = yaml['service']['name']
+ request_hash[:id] = id
+ request(request, request_hash)
+ end
+ end
+
+ def parse_args(args)
+ cmd = args[0]
+ c = nil
+ # short circuit for help
+ if cmd == 'help' || args.empty?
+ if args.size > 1
+ c = dict.select { |k| k[:cmd] == args[1] }.first
+ raise InvalidParametersException, "'#{args[1]}' is not a valid help topic." if c.nil?
end
- when /^start$/
- #mkitc start {id} => PUT services/{id}/start
- case args.size
- when 2
- id = args[1]
- request = { verb: :put, uri: "/services/#{id}/start" }
- else
- raise 'invalid parameters'
+ return help(cmd: c)
+ else
+ c = dict.select { |k| k[:cmd] == cmd }.first
+ end
+ raise InvalidParametersException, 'Command not found' if c.nil?
+
+ myargs = args.dup
+ myargs.delete(cmd)
+
+ max_args_size = c[:args].nil? ? 0 : c[:args].size
+ max_options_size = c[:options].nil? ? 0 : 1
+ max_args_size += max_options_size
+
+ min_args_size = c[:args].nil? ? 0 : c[:args].select { |a| a[:mandatory] == true }.size
+ min_options_size = c[:options].nil? ? 0 : 1
+ min_args_size += min_options_size
+
+ if myargs.size > max_args_size || myargs.size < min_args_size
+ raise InvalidParametersException.new('Invalid parameters found.', c)
+ end
+
+ request_hash = {}
+ request = c[:request]
+ unless myargs.empty?
+ unless c[:args].nil?
+ idx = 0
+ c[:args].each do |a|
+ request_hash[a[:name].to_sym] = myargs[idx]
+ request[:uri] = request[:uri] + a[:uri] unless a[:uri].nil?
+ idx += 1
+ end
end
- when /^rm$/
- #mkitc rm {id} => DELETE services/{id}
- case args.size
- when 2
- id = args[1]
- request = { verb: :delete, uri: "/services/#{id}" }
- else
- raise 'invalid parameters'
- end
- when /^create$/
- #mkitc create service.yaml => POST services service.yaml
- case args.size
- when 2
- file = args[1]
- request = { verb: :post, uri: "/services", file: file }
- else
- raise 'invalid parameters'
- end
- when /^update$/
- #mkitc update service.yaml => PUT services/{id} service.yaml
- case args.size
- when 2
- file = args[1]
- yaml = YAML.load_file(file)
- if yaml["service"].nil?
- raise 'invalid configuration file'
- else
- id = yaml["service"]["name"]
- request = { verb: :put, uri: "/services/#{id}", file: file }
+ # options
+ unless c[:options].nil?
+ option = nil
+ myargs.each do |s|
+ option = c[:options].select { |o| o[:cmd] == s }.first
+ raise InvalidParametersException.new('Invalid parameters found.', c) if option.nil? || option.empty?
end
- else
- raise 'invalid parameters'
+ raise InvalidParametersException.new('Invalid parameters found.', c) if option.nil? || option.empty?
+
+ request = option[:request]
end
+ end
+ raise InvalidParametersException, "Can't find request." if request.nil?
+
+ if respond_to? c[:cmd]
+ send(c[:cmd], request, request_hash)
else
- raise "Usage: invalid parameters"
+ request(request, request_hash)
end
- request
end
def doIt(args)
- operation = parse_args(args)
- puts request(operation).body
+ result = parse_args(args)
+ puts result
+ rescue InvalidParametersException => e
+ help(cause: e)
end
- def request(request)
+ def request(request, request_args = nil)
req = nil
- uri = request[:uri]
+ uri = ERB.new(request[:uri]).result_with_hash(request_args)
+ request[:file] = request_args[:file]
+
unless request[:params].nil? || request[:params].empty?
- uri = uri + '?' + request[:params].map{|k,v| "#{k}=#{v}"}.join('&')
+ uri = uri + '?' + request[:params].map { |k, v| "#{k}=#{v}" }.join('&')
end
case request[:verb]
when :post
req = Net::HTTP::Post.new(uri)
unless request[:file].nil?
(body, boundary) = attach(request[:file])
req.body = body
- req["Content-Type"] = "multipart/form-data, boundary=#{boundary}"
+ req['Content-Type'] = "multipart/form-data, boundary=#{boundary}"
end
when :put
req = Net::HTTP::Put.new(uri)
unless request[:file].nil?
(body, boundary) = attach(request[:file])
req.body = body
- req["Content-Type"] = "multipart/form-data, boundary=#{boundary}"
+ req['Content-Type'] = "multipart/form-data, boundary=#{boundary}"
end
when :patch
req = Net::HTTP::Patch.new(uri)
when :get
req = Net::HTTP::Get.new(uri)
when :delete
req = Net::HTTP::Delete.new(uri)
end
- @client.request(req)
+ @client.request(req).body
end
def attach(file)
- boundary=SecureRandom.alphanumeric
+ boundary = SecureRandom.alphanumeric
body = []
body << "--#{boundary}\r\n"
body << "Content-Disposition: form-data; name=file; filename='#{File.basename(file)}'\r\n"
body << "Content-Type: text/plain\r\n"
body << "\r\n"
body << File.read(file)
body << "\r\n--#{boundary}--\r\n"
- [ body.join, boundary]
+ [body.join, boundary]
end
end
#
# go
@@ -153,6 +319,5 @@
#
# if ARGV.any?
# parse args
# host, socket, config file
# end
-