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 +4 -4
- data/bin/xloginapi +6 -0
- data/lib/xlogin/apiclient.rb +43 -11
- data/lib/xlogin/apiclient/cli.rb +75 -0
- data/lib/xlogin/apiclient/version.rb +2 -2
- data/xlogin-apiclient.gemspec +2 -1
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ba7acd60107439028cb9f8c6a77afd5dfaf6c1cf74c2232b529678b8888b6053
|
4
|
+
data.tar.gz: 32b07f46ca25f31ee09cadf2de19c5a0284bd1bb5c0a92b1d9a62b6af8a0b261
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f985e16fe2d94d2daee92e2d060aab4007deb0cda7d7aa56338f6e0f57c86907e8ec2299860d3cf2495f1f1c92b2ab35f84b6e24ecf08a7a711ac6c6238f8b3
|
7
|
+
data.tar.gz: d8bf59fae7037c02f2488c7b2115a84a40349a5909a31b3e6ea6995fc981ec60ffba990e1575c8c206a6c938799fd6555b674eab3513d7a52a336366f134cdaa
|
data/bin/xloginapi
ADDED
data/lib/xlogin/apiclient.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
34
|
-
|
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
|
-
|
37
|
-
|
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
|
-
|
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
|
+
|
data/xlogin-apiclient.gemspec
CHANGED
@@ -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::
|
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.
|
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-
|
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.
|