xlogin-apiclient 0.2.0 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 18a35f6ba98b58373950e71f3c3a87683087981acc457099952fe85beb474957
4
- data.tar.gz: 6501f3d09a773b2925e779d5c72a7905e9871a0e002bb99560bea537b8747cdd
3
+ metadata.gz: ba7acd60107439028cb9f8c6a77afd5dfaf6c1cf74c2232b529678b8888b6053
4
+ data.tar.gz: 32b07f46ca25f31ee09cadf2de19c5a0284bd1bb5c0a92b1d9a62b6af8a0b261
5
5
  SHA512:
6
- metadata.gz: 84722296fb0c543e96fe23629845694c76a96dbac5f6d7812b3daf3022374163f4e389110b772931517e43fa895fe3baac23e03dbd8908fadaf020986d72d41e
7
- data.tar.gz: 0ac161f727446451c8981e66e80c4c69be3821eab9cf7ad6998b95738cfba11cde028f9fa75e8d51e08f2fff16b73e5ae9c2327c762918ec7e4f66427530a800
6
+ metadata.gz: 6f985e16fe2d94d2daee92e2d060aab4007deb0cda7d7aa56338f6e0f57c86907e8ec2299860d3cf2495f1f1c92b2ab35f84b6e24ecf08a7a711ac6c6238f8b3
7
+ data.tar.gz: d8bf59fae7037c02f2488c7b2115a84a40349a5909a31b3e6ea6995fc981ec60ffba990e1575c8c206a6c938799fd6555b674eab3513d7a52a336366f134cdaa
data/bin/xloginapi ADDED
@@ -0,0 +1,6 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ require 'xlogin/apiclient'
4
+ require 'xlogin/apiclient/cli'
5
+
6
+ Xlogin::APIClient::CLI.run
@@ -1,16 +1,24 @@
1
1
  require 'json'
2
2
  require 'net/http'
3
+ require 'stringio'
3
4
  require 'addressable/uri'
5
+ require 'em-eventsource'
4
6
  require "xlogin/apiclient/version"
5
7
 
8
+
6
9
  module Xlogin
7
10
  class APIClient
11
+ DEFAULT_TIMEOUT = 60
12
+
8
13
  class Error < StandardError; end
9
14
 
10
15
  class << self
11
16
  attr_accessor :base_url
17
+ attr_accessor :timeout
12
18
  end
13
19
 
20
+ attr_reader :type, :args
21
+
14
22
  def initialize(base_url: self.class.base_url, **args)
15
23
  raise Error.new('base_url not defined') unless base_url
16
24
 
@@ -19,26 +27,50 @@ module Xlogin
19
27
  @args = args
20
28
  end
21
29
 
22
- def cmd(args)
30
+ def cmd(args, &block)
23
31
  params = {driver: @type, target: @args, command: args}
24
- resp = request(**params.transform_keys(&:to_sym))
25
- resp['payload'].join
32
+ request(:cmd, **params.transform_keys(&:to_sym), &block)
26
33
  end
27
34
 
28
35
  private
29
- def request(**params)
36
+ def request(endpoint, **params, &block)
30
37
  uri = @uri.dup
38
+ uri.path = File.join(uri.path, endpoint.to_s)
31
39
  uri.query = "q=#{URI.encode_www_form_component(JSON.generate(params))}"
32
40
 
33
- req = Net::HTTP::Get.new(uri.request_uri)
34
- req["Accept"] = "application/json"
41
+ if block
42
+ resp = StringIO.new
43
+ EM.run do
44
+ source = EventMachine::EventSource.new(uri.to_s)
45
+ source.message do |message|
46
+ data = JSON.parse(message) || {}
47
+ if chunk = data['chunk']
48
+ resp.print data['chunk']
49
+ block.call(data['chunk'])
50
+ end
51
+ end
52
+ source.error do |e|
53
+ EM.stop
54
+ end
55
+ source.start
56
+ end
57
+ return resp.string
58
+ else
59
+ req = Net::HTTP::Get.new(uri.request_uri)
60
+ req["Accept"] = "application/json"
61
+
62
+ http = Net::HTTP.new(uri.host, uri.port)
63
+ http.open_timeout = self.class.timeout || DEFAULT_TIMEOUT
64
+ http.read_timeout = self.class.timeout || DEFAULT_TIMEOUT
65
+
66
+ resp = http.request(req)
67
+ raise Error.new(resp.message) unless resp.code =~ /^2[0-9]{2}$/
35
68
 
36
- http = Net::HTTP.new(uri.host, uri.port)
37
- body = http.request(req).body
38
- resp = body ? JSON.parse(body) : {}
39
- return resp if resp['success']
69
+ data = resp.body ? JSON.parse(resp.body) : {}
70
+ raise Error.new(data['error']) unless data['success']
40
71
 
41
- raise Error.new(resp['error'])
72
+ return data['payload'].join
73
+ end
42
74
  end
43
75
  end
44
76
  end
@@ -0,0 +1,75 @@
1
+ require 'optparse'
2
+ require 'singleton'
3
+ require 'xlogin/apiclient'
4
+
5
+
6
+ XLOGIN_API_URL = ENV.fetch('XLOGIN_API_URL', 'http://127.0.0.1:8080')
7
+
8
+ module Xlogin
9
+ class APIClient
10
+
11
+ class Factory
12
+ include Singleton
13
+
14
+ def initialize
15
+ @inventory = Hash.new
16
+ end
17
+
18
+ def set_hostinfo(name, **opts)
19
+ @inventory[name] = (get_hostinfo(name) || {name: name}).merge(opts)
20
+ end
21
+
22
+ def get_hostinfo(name)
23
+ @inventory[name]
24
+ end
25
+
26
+ def method_missing(method_name, *args, **opts, &block)
27
+ super unless args.size == 2 && Addressable::URI::URIREGEX =~ args[1]
28
+
29
+ name = args[0]
30
+ uri = args[1]
31
+ type = method_name.to_s.downcase
32
+ set_hostinfo(name.to_s, type: type, uri: uri, **opts)
33
+ end
34
+ end
35
+
36
+ class CLI
37
+
38
+ def self.run(args = ARGV)
39
+ Xlogin::APIClient::CLI.new.run(args)
40
+ end
41
+
42
+ def run(args)
43
+ config = {api: XLOGIN_API_URL}
44
+ parser = OptionParser.new
45
+ parser.banner = "#{File.basename($0)} HOST [Options]"
46
+ parser.version = Xlogin::APIClient::VERSION
47
+
48
+ parser.on('-a API', '--api', String, 'The Xlogin API URL.') { |v| config[:api] = v }
49
+ parser.on('-t TYPE', '--type', String, 'The TYPE of the device.') { |v| config[:type] = v }
50
+ parser.on('-i PATH', '--inventory', String, 'The PATH to the inventory file..') { |v| config[:inventory] = v }
51
+ parser.on('-e COMMAND', '--exec', String, 'Execute commands and quit.') { |v| config[:exec] = v }
52
+
53
+ args = parser.parse!(args)
54
+ host = args.shift
55
+ hostinfo = if config[:inventory]
56
+ factory = Factory.instance
57
+ factory.instance_eval(IO.read(config[:inventory]))
58
+ factory.get_hostinfo(host) || {}
59
+ else
60
+ {type: config[:type], uri: host}
61
+ end
62
+
63
+ raise "Argument error - type='#{hostinfo[:type]}' uri='#{hostinfo[:uri]}'" unless hostinfo[:type] && hostinfo[:uri]
64
+
65
+ APIClient.base_url = config[:api]
66
+ client = APIClient.new(**hostinfo)
67
+ client.cmd(config[:exec]) { |c| $stdout.print c }
68
+ rescue => e
69
+ $stderr.puts e, '', parser
70
+ end
71
+
72
+ end
73
+ end
74
+ end
75
+
@@ -1,5 +1,5 @@
1
1
  module Xlogin
2
- module Apiclient
3
- VERSION = "0.2.0"
2
+ class APIClient
3
+ VERSION = "0.2.6"
4
4
  end
5
5
  end
@@ -5,7 +5,7 @@ require "xlogin/apiclient/version"
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "xlogin-apiclient"
8
- spec.version = Xlogin::Apiclient::VERSION
8
+ spec.version = Xlogin::APIClient::VERSION
9
9
  spec.authors = ["haccht"]
10
10
  spec.email = ["haccht@users.noreply.github.com"]
11
11
 
@@ -27,4 +27,5 @@ Gem::Specification.new do |spec|
27
27
  spec.add_development_dependency "rake", "~> 10.0"
28
28
 
29
29
  spec.add_dependency 'addressable'
30
+ spec.add_dependency 'em-eventsource'
30
31
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xlogin-apiclient
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - haccht
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-01-26 00:00:00.000000000 Z
11
+ date: 2021-02-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: em-eventsource
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  description: API client for xlogin-api.
56
70
  email:
57
71
  - haccht@users.noreply.github.com
@@ -67,7 +81,9 @@ files:
67
81
  - Rakefile
68
82
  - bin/console
69
83
  - bin/setup
84
+ - bin/xloginapi
70
85
  - lib/xlogin/apiclient.rb
86
+ - lib/xlogin/apiclient/cli.rb
71
87
  - lib/xlogin/apiclient/version.rb
72
88
  - xlogin-apiclient.gemspec
73
89
  homepage: https://github.com/haccht/xlogin-apiclient.