agent_client 0.1.1 → 1.5.0.pre.1113
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/agent_client +32 -0
- data/lib/agent_client.rb +13 -8
- data/lib/agent_client/base.rb +7 -4
- data/lib/agent_client/errors.rb +2 -0
- data/lib/agent_client/http_client.rb +17 -18
- data/lib/agent_client/version.rb +3 -1
- metadata +51 -32
- data/README +0 -1
- data/Rakefile +0 -52
- data/spec/spec_helper.rb +0 -10
- data/spec/unit/http_agent_client_spec.rb +0 -135
data/bin/agent_client
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#!/usr/bin/env ruby
|
3
|
+
|
4
|
+
$:.unshift(File.expand_path('../../lib', __FILE__))
|
5
|
+
require 'agent_client'
|
6
|
+
require 'optparse'
|
7
|
+
|
8
|
+
# Defaults
|
9
|
+
options = {
|
10
|
+
'mbus' => 'https://vcap:vcap@localhost:6969',
|
11
|
+
}
|
12
|
+
|
13
|
+
opts = OptionParser.new do |opts|
|
14
|
+
opts.banner = 'Usage: agent_client [<options>] [ping|state]'
|
15
|
+
opts.on('-m', '--mbus String', 'mbus (https://user:pass@host:port)') do |opt|
|
16
|
+
options['mbus'] = opt
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
command = ARGV.pop
|
21
|
+
unless %w[ping state].include?(command)
|
22
|
+
$stderr.puts opts
|
23
|
+
exit 1
|
24
|
+
end
|
25
|
+
|
26
|
+
opts.parse!(ARGV.dup)
|
27
|
+
mbus = URI.parse(options['mbus'])
|
28
|
+
user, password = mbus.user, mbus.password
|
29
|
+
mbus.user = mbus.password = nil
|
30
|
+
api = Bosh::Agent::Client.create(mbus.to_s, 'user' => user, 'password' => password)
|
31
|
+
|
32
|
+
puts api.send(command.to_sym)
|
data/lib/agent_client.rb
CHANGED
@@ -1,12 +1,17 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
1
3
|
module Bosh; module Agent; end; end
|
2
4
|
|
3
|
-
require
|
4
|
-
|
5
|
-
require
|
6
|
-
require
|
5
|
+
require 'httpclient'
|
6
|
+
|
7
|
+
require 'agent_client/version'
|
8
|
+
require 'agent_client/errors'
|
9
|
+
require 'agent_client/base'
|
10
|
+
require 'agent_client/http_client'
|
7
11
|
|
8
|
-
require
|
9
|
-
require
|
12
|
+
require 'uri'
|
13
|
+
require 'yajl'
|
14
|
+
require 'openssl'
|
10
15
|
|
11
16
|
module Bosh
|
12
17
|
module Agent
|
@@ -14,10 +19,10 @@ module Bosh
|
|
14
19
|
def self.create(uri, options = { })
|
15
20
|
scheme = URI.parse(uri).scheme
|
16
21
|
case scheme
|
17
|
-
when
|
22
|
+
when 'https'
|
18
23
|
HTTPClient.new(uri, options)
|
19
24
|
else
|
20
|
-
raise "Invalid client scheme, available providers are: '
|
25
|
+
raise "Invalid client scheme, available providers are: 'https' agent uri was: #{uri}"
|
21
26
|
end
|
22
27
|
end
|
23
28
|
end
|
data/lib/agent_client/base.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
1
3
|
module Bosh
|
2
4
|
module Agent
|
3
5
|
class BaseClient
|
@@ -5,9 +7,9 @@ module Bosh
|
|
5
7
|
def run_task(method, *args)
|
6
8
|
task = send(method.to_sym, *args)
|
7
9
|
|
8
|
-
while task[
|
10
|
+
while task['state'] == 'running'
|
9
11
|
sleep(1.0)
|
10
|
-
task = get_task(task[
|
12
|
+
task = get_task(task['agent_task_id'])
|
11
13
|
end
|
12
14
|
|
13
15
|
task
|
@@ -16,11 +18,12 @@ module Bosh
|
|
16
18
|
def method_missing(method_name, *args)
|
17
19
|
result = handle_method(method_name, args)
|
18
20
|
|
19
|
-
raise HandlerError, result[
|
20
|
-
result[
|
21
|
+
raise HandlerError, result['exception'] if result.has_key?('exception')
|
22
|
+
result['value']
|
21
23
|
end
|
22
24
|
|
23
25
|
protected
|
26
|
+
|
24
27
|
def handle_method(method_name, args)
|
25
28
|
end
|
26
29
|
end
|
data/lib/agent_client/errors.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
|
1
|
+
# encoding: UTF-8
|
2
2
|
|
3
|
-
|
3
|
+
module Bosh; module Agent; end; end
|
4
4
|
|
5
5
|
module Bosh::Agent
|
6
6
|
class HTTPClient < BaseClient
|
@@ -17,48 +17,47 @@ module Bosh::Agent
|
|
17
17
|
|
18
18
|
def handle_method(method, args)
|
19
19
|
payload = {
|
20
|
-
|
21
|
-
|
20
|
+
'method' => method, 'arguments' => args,
|
21
|
+
'reply_to' => @options['reply_to'] || self.class.name
|
22
22
|
}
|
23
|
-
|
23
|
+
post_json('/agent', Yajl::Encoder.encode(payload))
|
24
24
|
end
|
25
25
|
|
26
26
|
private
|
27
27
|
|
28
28
|
def request(method, uri, content_type = nil, payload = nil, headers = {})
|
29
29
|
headers = headers.dup
|
30
|
-
headers[
|
30
|
+
headers['Content-Type'] = content_type if content_type
|
31
31
|
|
32
32
|
http_client = ::HTTPClient.new
|
33
33
|
|
34
34
|
http_client.send_timeout = IO_TIMEOUT
|
35
35
|
http_client.receive_timeout = IO_TIMEOUT
|
36
36
|
http_client.connect_timeout = CONNECT_TIMEOUT
|
37
|
+
http_client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
38
|
+
http_client.ssl_config.verify_callback = proc {}
|
37
39
|
|
38
40
|
if @options['user'] && @options['password']
|
39
41
|
http_client.set_auth(@base_uri, @options['user'], @options['password'])
|
40
42
|
end
|
41
43
|
|
42
|
-
http_client.request(method, @base_uri + uri,
|
43
|
-
:body => payload, :header => headers)
|
44
|
+
http_client.request(method, @base_uri + uri, body: payload, header: headers)
|
44
45
|
|
45
|
-
rescue URI::Error, SocketError, Errno::ECONNREFUSED => e
|
46
|
-
raise Error, "cannot access agent (%s)" % [ e.message ]
|
47
|
-
rescue SystemCallError => e
|
48
|
-
raise Error, "System call error while talking to agent: #{e}"
|
49
|
-
rescue ::HTTPClient::BadResponseError => e
|
50
|
-
raise Error, "Received bad HTTP response from agent: #{e}"
|
51
46
|
rescue => e
|
52
|
-
raise Error, "
|
47
|
+
raise Error, "Request details:\n" +
|
48
|
+
"uri: #{@base_uri + uri}\n" +
|
49
|
+
"payload: #{payload}\n" +
|
50
|
+
(@options['user'] ? "user: #{@options['user']}\n" : '') +
|
51
|
+
(@options['password'] ? "password: #{@options['password']}\n" : '') +
|
52
|
+
"#{e.class}: #{e.message}"
|
53
53
|
end
|
54
54
|
|
55
55
|
def post_json(url, payload)
|
56
|
-
response = request(:post, url,
|
56
|
+
response = request(:post, url, 'application/json', payload)
|
57
57
|
status = response.code
|
58
|
-
raise AuthError,
|
58
|
+
raise AuthError, 'Authentication failed' if status == 401
|
59
59
|
raise Error, "Agent HTTP #{status}" if status != 200
|
60
60
|
Yajl::Parser.parse(response.body)
|
61
61
|
end
|
62
|
-
|
63
62
|
end
|
64
63
|
end
|
data/lib/agent_client/version.rb
CHANGED
metadata
CHANGED
@@ -1,41 +1,70 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: agent_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 1.5.0.pre.1113
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- VMware
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-10-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: httpclient
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - '='
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
21
|
+
version: 2.2.4
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - '='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 2.2.4
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: yajl-ruby
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 1.1.0
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.1.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
28
49
|
none: false
|
29
50
|
requirements:
|
30
51
|
- - ! '>='
|
31
52
|
- !ruby/object:Gem::Version
|
32
53
|
version: '0'
|
33
|
-
type: :
|
54
|
+
type: :development
|
34
55
|
prerelease: false
|
35
|
-
version_requirements:
|
36
|
-
|
37
|
-
|
38
|
-
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: ! 'BOSH agent client
|
63
|
+
|
64
|
+
cfd471'
|
65
|
+
email: support@cloudfoundry.com
|
66
|
+
executables:
|
67
|
+
- agent_client
|
39
68
|
extensions: []
|
40
69
|
extra_rdoc_files: []
|
41
70
|
files:
|
@@ -44,12 +73,10 @@ files:
|
|
44
73
|
- lib/agent_client/errors.rb
|
45
74
|
- lib/agent_client/http_client.rb
|
46
75
|
- lib/agent_client/version.rb
|
47
|
-
-
|
48
|
-
|
49
|
-
|
50
|
-
-
|
51
|
-
homepage: http://www.vmware.com
|
52
|
-
licenses: []
|
76
|
+
- bin/agent_client
|
77
|
+
homepage: https://github.com/cloudfoundry/bosh
|
78
|
+
licenses:
|
79
|
+
- Apache 2.0
|
53
80
|
post_install_message:
|
54
81
|
rdoc_options: []
|
55
82
|
require_paths:
|
@@ -59,25 +86,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
59
86
|
requirements:
|
60
87
|
- - ! '>='
|
61
88
|
- !ruby/object:Gem::Version
|
62
|
-
version:
|
63
|
-
segments:
|
64
|
-
- 0
|
65
|
-
hash: 12617920935854716
|
89
|
+
version: 1.9.3
|
66
90
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
91
|
none: false
|
68
92
|
requirements:
|
69
|
-
- - ! '
|
93
|
+
- - ! '>'
|
70
94
|
- !ruby/object:Gem::Version
|
71
|
-
version:
|
72
|
-
segments:
|
73
|
-
- 0
|
74
|
-
hash: 12617920935854716
|
95
|
+
version: 1.3.1
|
75
96
|
requirements: []
|
76
97
|
rubyforge_project:
|
77
|
-
rubygems_version: 1.8.
|
98
|
+
rubygems_version: 1.8.23
|
78
99
|
signing_key:
|
79
100
|
specification_version: 3
|
80
101
|
summary: BOSH agent client
|
81
|
-
test_files:
|
82
|
-
- spec/spec_helper.rb
|
83
|
-
- spec/unit/http_agent_client_spec.rb
|
102
|
+
test_files: []
|
data/README
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
Agent client for VMware BOSH.
|
data/Rakefile
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
# Copyright (c) 2009-2012 VMware, Inc.
|
2
|
-
|
3
|
-
$:.unshift(File.expand_path("../../rake", __FILE__))
|
4
|
-
|
5
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __FILE__)
|
6
|
-
|
7
|
-
require "rubygems"
|
8
|
-
require "bundler"
|
9
|
-
Bundler.setup(:default, :test)
|
10
|
-
|
11
|
-
require "rake"
|
12
|
-
require "rake"
|
13
|
-
begin
|
14
|
-
require "rspec/core/rake_task"
|
15
|
-
rescue LoadError
|
16
|
-
end
|
17
|
-
|
18
|
-
require "bundler_task"
|
19
|
-
require "ci_task"
|
20
|
-
|
21
|
-
gem_helper = Bundler::GemHelper.new(Dir.pwd)
|
22
|
-
|
23
|
-
desc "Build BOSH Agent Client gem into the pkg directory"
|
24
|
-
task "build" do
|
25
|
-
gem_helper.build_gem
|
26
|
-
end
|
27
|
-
|
28
|
-
desc "Build and install BOSH Agent Client into system gems"
|
29
|
-
task "install" do
|
30
|
-
Rake::Task["bundler:install"].invoke
|
31
|
-
gem_helper.install_gem
|
32
|
-
end
|
33
|
-
|
34
|
-
BundlerTask.new
|
35
|
-
|
36
|
-
if defined?(RSpec)
|
37
|
-
namespace :spec do
|
38
|
-
desc "Run Unit Tests"
|
39
|
-
rspec_task = RSpec::Core::RakeTask.new(:unit) do |t|
|
40
|
-
t.gemfile = "Gemfile"
|
41
|
-
t.pattern = "spec/unit/**/*_spec.rb"
|
42
|
-
t.rspec_opts = %w(--format progress --colour)
|
43
|
-
end
|
44
|
-
|
45
|
-
CiTask.new do |task|
|
46
|
-
task.rspec_task = rspec_task
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
desc "Install dependencies and run tests"
|
51
|
-
task :spec => %w(bundler:install:test spec:unit)
|
52
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,135 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
-
|
3
|
-
describe Bosh::Agent::HTTPClient do
|
4
|
-
|
5
|
-
before(:each) do
|
6
|
-
@httpclient = mock("httpclient")
|
7
|
-
HTTPClient.stub!(:new).and_return(@httpclient)
|
8
|
-
end
|
9
|
-
|
10
|
-
describe "options" do
|
11
|
-
|
12
|
-
it "should set up authentication when present" do
|
13
|
-
response = mock("response")
|
14
|
-
response.stub!(:code).and_return(200)
|
15
|
-
response.stub!(:body).and_return('{"value": "pong"}')
|
16
|
-
|
17
|
-
[:send_timeout=, :receive_timeout=, :connect_timeout=].each do |method|
|
18
|
-
@httpclient.should_receive(method)
|
19
|
-
end
|
20
|
-
|
21
|
-
@httpclient.should_receive(:set_auth).with("http://localhost", "john", "smith")
|
22
|
-
@httpclient.should_receive(:request).and_return(response)
|
23
|
-
|
24
|
-
@client = Bosh::Agent::HTTPClient.new("http://localhost",
|
25
|
-
{ "user" => "john",
|
26
|
-
"password" => "smith" })
|
27
|
-
@client.ping
|
28
|
-
end
|
29
|
-
|
30
|
-
it "should encode arguments" do
|
31
|
-
response = mock("response")
|
32
|
-
response.stub!(:code).and_return(200)
|
33
|
-
response.stub!(:body).and_return('{"value": "iam"}')
|
34
|
-
|
35
|
-
[:send_timeout=, :receive_timeout=, :connect_timeout=].each do |method|
|
36
|
-
@httpclient.should_receive(method)
|
37
|
-
end
|
38
|
-
|
39
|
-
headers = { "Content-Type" => "application/json" }
|
40
|
-
payload = '{"method":"shh","arguments":["hunting","wabbits"],"reply_to":"elmer"}'
|
41
|
-
|
42
|
-
@httpclient.should_receive(:request).with(:post, "http://localhost/agent",
|
43
|
-
:body => payload, :header => headers).and_return(response)
|
44
|
-
|
45
|
-
@client = Bosh::Agent::HTTPClient.new("http://localhost", {"reply_to" => "elmer"})
|
46
|
-
|
47
|
-
@client.shh("hunting", "wabbits").should == "iam"
|
48
|
-
end
|
49
|
-
|
50
|
-
it "should receive a message value" do
|
51
|
-
response = mock("response")
|
52
|
-
response.stub!(:code).and_return(200)
|
53
|
-
response.stub!(:body).and_return('{"value": "pong"}')
|
54
|
-
|
55
|
-
[:send_timeout=, :receive_timeout=, :connect_timeout=].each do |method|
|
56
|
-
@httpclient.should_receive(method)
|
57
|
-
end
|
58
|
-
|
59
|
-
headers = { "Content-Type" => "application/json" }
|
60
|
-
payload = '{"method":"ping","arguments":[],"reply_to":"fudd"}'
|
61
|
-
|
62
|
-
@httpclient.should_receive(:request).with(:post, "http://localhost/agent",
|
63
|
-
:body => payload, :header => headers).and_return(response)
|
64
|
-
|
65
|
-
@client = Bosh::Agent::HTTPClient.new("http://localhost", {"reply_to" => "fudd"})
|
66
|
-
|
67
|
-
@client.ping.should == "pong"
|
68
|
-
end
|
69
|
-
|
70
|
-
it "should run_task" do
|
71
|
-
response = mock("response")
|
72
|
-
response.stub!(:code).and_return(200)
|
73
|
-
response.stub!(:body).and_return('{"value": {"state": "running", "agent_task_id": "task_id_foo"}}')
|
74
|
-
|
75
|
-
[:send_timeout=, :receive_timeout=, :connect_timeout=].each do |method|
|
76
|
-
@httpclient.should_receive(method)
|
77
|
-
end
|
78
|
-
|
79
|
-
headers = { "Content-Type" => "application/json" }
|
80
|
-
payload = '{"method":"compile_package","arguments":["id","sha1"],"reply_to":"bugs"}'
|
81
|
-
|
82
|
-
@httpclient.should_receive(:request).with(:post, "http://localhost/agent",
|
83
|
-
:body => payload, :header => headers).and_return(response)
|
84
|
-
|
85
|
-
response2 = mock("response2")
|
86
|
-
response2.stub!(:code).and_return(200)
|
87
|
-
response2.stub!(:body).and_return('{"value": {"state": "done"}')
|
88
|
-
|
89
|
-
payload = '{"method":"get_task","arguments":["task_id_foo"],"reply_to":"bugs"}'
|
90
|
-
|
91
|
-
[:send_timeout=, :receive_timeout=, :connect_timeout=].each do |method|
|
92
|
-
@httpclient.should_receive(method)
|
93
|
-
end
|
94
|
-
|
95
|
-
@httpclient.should_receive(:request).with(:post, "http://localhost/agent",
|
96
|
-
:body => payload, :header => headers).and_return(response2)
|
97
|
-
|
98
|
-
@client = Bosh::Agent::HTTPClient.new("http://localhost", {"reply_to" => "bugs"})
|
99
|
-
|
100
|
-
@client.run_task(:compile_package, "id", "sha1").should == { "state" => "done" }
|
101
|
-
end
|
102
|
-
|
103
|
-
it "should raise handler exception when method is invalid" do
|
104
|
-
response = mock("response")
|
105
|
-
response.stub!(:code).and_return(200)
|
106
|
-
response.stub!(:body).and_return('{"exception": "no such method"}')
|
107
|
-
|
108
|
-
[:send_timeout=, :receive_timeout=, :connect_timeout=].each do |method|
|
109
|
-
@httpclient.should_receive(method)
|
110
|
-
end
|
111
|
-
|
112
|
-
@httpclient.should_receive(:request).and_return(response)
|
113
|
-
|
114
|
-
@client = Bosh::Agent::HTTPClient.new("http://localhost")
|
115
|
-
|
116
|
-
lambda { @client.no_such_method }.should raise_error(Bosh::Agent::HandlerError)
|
117
|
-
|
118
|
-
end
|
119
|
-
|
120
|
-
it "should raise authentication exception when 401 is returned" do
|
121
|
-
response = mock("response")
|
122
|
-
response.stub!(:code).and_return(401)
|
123
|
-
|
124
|
-
[:send_timeout=, :receive_timeout=, :connect_timeout=].each do |method|
|
125
|
-
@httpclient.should_receive(method)
|
126
|
-
end
|
127
|
-
|
128
|
-
@httpclient.should_receive(:request).and_return(response)
|
129
|
-
|
130
|
-
@client = Bosh::Agent::HTTPClient.new("http://localhost")
|
131
|
-
|
132
|
-
lambda { @client.ping }.should raise_error(Bosh::Agent::AuthError)
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|