pcp-client 0.3.0 → 0.5.3
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.
- checksums.yaml +5 -5
- data/bin/pcp-ping +112 -0
- data/lib/pcp-client/version.rb +4 -0
- data/lib/pcp/client.rb +65 -42
- data/lib/pcp/message.rb +10 -2
- metadata +9 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: c8712776d17a4fffc25f012a1471bb56de3af9db2edbfe9c770cae53fc6de82c
|
|
4
|
+
data.tar.gz: 7e53fc42f88e35bf7d2d2051188d9672d39ac82ed568d3fab0ddacc666666a00
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ccc042e29255ca1d5c3d4951d35126bbb7383c87c966c62c23beaee21e15fcc507784a900c09b7cf6b77e4833f2116f636eca468e263379dd5c73dca5c71a92c
|
|
7
|
+
data.tar.gz: cfa9f803edb4339b4ab5d9fbc77c64c2c13fe669920391f5f63b0876dcf073d0f8105a7be4079a72a683e7f79c96e63da8ab9f7e0a8ab9188bd4a22e72da3892
|
data/bin/pcp-ping
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'pcp/client'
|
|
3
|
+
require 'optparse'
|
|
4
|
+
|
|
5
|
+
ssl_key = '../pcp-broker/test-resources/ssl/private_keys/client01.example.com.pem'
|
|
6
|
+
ssl_cert = '../pcp-broker/test-resources/ssl/certs/client01.example.com.pem'
|
|
7
|
+
ssl_ca_cert = '../pcp-broker/test-resources/ssl/ca/ca_crt.pem'
|
|
8
|
+
debug = false
|
|
9
|
+
server = 'wss://localhost:8142/pcp'
|
|
10
|
+
|
|
11
|
+
OptionParser.new do |opts|
|
|
12
|
+
opts.on("-d", "--debug", "Run noisily") { |v| debug = v }
|
|
13
|
+
opts.on("--ssl_key FILE", "Use this ssl key") { |v| ssl_key = v }
|
|
14
|
+
opts.on("--ssl_cert FILE", "Use this ssl cert") { |v| ssl_cert = v }
|
|
15
|
+
opts.on("--ssl_ca_cert FILE", "Use this ssl ca cert") { |v| ssl_ca_cert = v }
|
|
16
|
+
opts.on("--server URL", "Server to connect to") { |v| server = v }
|
|
17
|
+
end.parse!
|
|
18
|
+
|
|
19
|
+
start_time = Time.now.to_f
|
|
20
|
+
|
|
21
|
+
Thread.new { EM.run }
|
|
22
|
+
Thread.pass until EM.reactor_running?
|
|
23
|
+
|
|
24
|
+
client = PCP::Client.new({:ssl_key => ssl_key,
|
|
25
|
+
:ssl_cert => ssl_cert,
|
|
26
|
+
:ssl_ca_cert => ssl_ca_cert,
|
|
27
|
+
:loglevel => debug ? Logger::DEBUG : Logger::WARN,
|
|
28
|
+
:server => server,
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
# Record the expected set of destinations from the destination_report,
|
|
32
|
+
# then all the responses from the rpc_blocking_response
|
|
33
|
+
mutex = Mutex.new
|
|
34
|
+
have_responses = ConditionVariable.new
|
|
35
|
+
responses = {}
|
|
36
|
+
expected = nil
|
|
37
|
+
ping_time = nil
|
|
38
|
+
|
|
39
|
+
client.on_message = proc do |message|
|
|
40
|
+
mutex.synchronize do
|
|
41
|
+
case message[:message_type]
|
|
42
|
+
when 'http://puppetlabs.com/destination_report'
|
|
43
|
+
expected = JSON.load(message.data)['targets']
|
|
44
|
+
when 'http://puppetlabs.com/rpc_blocking_response'
|
|
45
|
+
sender = message[:sender]
|
|
46
|
+
time = Time.now.to_f - ping_time
|
|
47
|
+
responses[sender] = time
|
|
48
|
+
puts '%-55s %0.2f seconds' % [sender, time]
|
|
49
|
+
else
|
|
50
|
+
p [:unexpected_message, message]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
have_responses.signal
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
client.connect
|
|
58
|
+
|
|
59
|
+
if !client.associated?
|
|
60
|
+
puts "Didn't connect to broker."
|
|
61
|
+
exit 1
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
connect_time = Time.now.to_f - start_time
|
|
65
|
+
puts "Connected to broker in %0.2f seconds." % [connect_time]
|
|
66
|
+
puts
|
|
67
|
+
|
|
68
|
+
ping = ::PCP::Message.new(:message_type => 'http://puppetlabs.com/rpc_blocking_request',
|
|
69
|
+
:targets => ['pcp://*/agent'],
|
|
70
|
+
:destination_report => true)
|
|
71
|
+
|
|
72
|
+
ping.data = {:transaction_id => ping[:id],
|
|
73
|
+
:module => 'echo',
|
|
74
|
+
:action => 'echo',
|
|
75
|
+
:params => {:argument => 'echo'}}.to_json
|
|
76
|
+
|
|
77
|
+
ping.expires(3)
|
|
78
|
+
|
|
79
|
+
ping_time = Time.now.to_f
|
|
80
|
+
client.send(ping)
|
|
81
|
+
|
|
82
|
+
begin
|
|
83
|
+
Timeout::timeout(3) do
|
|
84
|
+
done = false
|
|
85
|
+
loop do
|
|
86
|
+
mutex.synchronize do
|
|
87
|
+
have_responses.wait(mutex)
|
|
88
|
+
if expected && expected.all? { |from| responses.include?(from) }
|
|
89
|
+
# Have all responses we expect, bail
|
|
90
|
+
run_time = Time.now.to_f - start_time
|
|
91
|
+
puts
|
|
92
|
+
puts "Received all responses in %0.2f seconds." % [run_time]
|
|
93
|
+
done = true
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
break if done
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
rescue Timeout::Error
|
|
100
|
+
puts
|
|
101
|
+
if expected
|
|
102
|
+
puts "Received %d/%d responses. Following nodes were missing" % [responses.keys.size, expected.size]
|
|
103
|
+
puts
|
|
104
|
+
expected.select { |from| !responses.include?(from) }.each do |missing|
|
|
105
|
+
puts " #{missing}"
|
|
106
|
+
end
|
|
107
|
+
else
|
|
108
|
+
puts "Didn't get destination report, not sure how many responses to expect. We got %d." % [responses.keys.size]
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
EM.stop
|
data/lib/pcp/client.rb
CHANGED
|
@@ -2,6 +2,7 @@ require 'eventmachine'
|
|
|
2
2
|
require 'faye/websocket'
|
|
3
3
|
require 'pcp/message'
|
|
4
4
|
require 'logger'
|
|
5
|
+
require 'openssl'
|
|
5
6
|
|
|
6
7
|
module PCP
|
|
7
8
|
# Manages a client connection to a pcp broker
|
|
@@ -27,12 +28,14 @@ module PCP
|
|
|
27
28
|
@server = params[:server] || 'wss://localhost:8142/pcp'
|
|
28
29
|
@ssl_key = params[:ssl_key]
|
|
29
30
|
@ssl_cert = params[:ssl_cert]
|
|
31
|
+
@ssl_ca_cert = params[:ssl_ca_cert]
|
|
30
32
|
@logger = params[:logger] || Logger.new(STDOUT)
|
|
31
33
|
@logger.level = params[:loglevel] || Logger::WARN
|
|
32
34
|
@connection = nil
|
|
33
35
|
type = params[:type] || "ruby-pcp-client-#{$$}"
|
|
34
36
|
@identity = make_identity(@ssl_cert, type)
|
|
35
37
|
@on_message = params[:on_message]
|
|
38
|
+
@max_message_size = params[:max_message_size] || 64*1024*1024
|
|
36
39
|
@associated = false
|
|
37
40
|
end
|
|
38
41
|
|
|
@@ -50,55 +53,68 @@ module PCP
|
|
|
50
53
|
mutex = Mutex.new
|
|
51
54
|
associated_cv = ConditionVariable.new
|
|
52
55
|
|
|
53
|
-
@logger.debug { [:connect,
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
56
|
+
@logger.debug { [:connect, :scheduling] }
|
|
57
|
+
EM.next_tick do
|
|
58
|
+
@logger.debug { [:connect, @server] }
|
|
59
|
+
|
|
60
|
+
start_tls_options = {
|
|
61
|
+
:ssl_version => ["TLSv1", "TLSv1_1", "TLSv1_2"],
|
|
62
|
+
:private_key_file => @ssl_key,
|
|
63
|
+
:cert_chain_file => @ssl_cert,
|
|
64
|
+
:root_cert_file => @ssl_ca_cert,
|
|
65
|
+
:verify_peer => true,
|
|
66
|
+
:fail_if_no_peer_cert => true,
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@connection = Faye::WebSocket::Client.new(@server, nil, {:tls => start_tls_options,
|
|
70
|
+
:ping => 30,
|
|
71
|
+
:max_length => @max_message_size})
|
|
72
|
+
|
|
73
|
+
@connection.on :open do |event|
|
|
74
|
+
begin
|
|
75
|
+
@logger.info { [:open] }
|
|
76
|
+
send(associate_request)
|
|
77
|
+
rescue Exception => e
|
|
78
|
+
@logger.error { [:open_exception, e] }
|
|
79
|
+
end
|
|
64
80
|
end
|
|
65
|
-
end
|
|
66
81
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
82
|
+
@connection.on :message do |event|
|
|
83
|
+
begin
|
|
84
|
+
message = ::PCP::Message.new(event.data)
|
|
85
|
+
@logger.debug { [:message, :decoded, message] }
|
|
86
|
+
|
|
87
|
+
if message[:message_type] == 'http://puppetlabs.com/associate_response'
|
|
88
|
+
mutex.synchronize do
|
|
89
|
+
@associated = JSON.load(message.data)["success"]
|
|
90
|
+
associated_cv.signal
|
|
91
|
+
end
|
|
92
|
+
elsif @on_message
|
|
93
|
+
@on_message.call(message)
|
|
94
|
+
end
|
|
95
|
+
rescue Exception => e
|
|
96
|
+
@logger.error { [:message_exception, e] }
|
|
97
|
+
end
|
|
98
|
+
end
|
|
71
99
|
|
|
72
|
-
|
|
100
|
+
@connection.on :close do |event|
|
|
101
|
+
begin
|
|
102
|
+
@logger.info { [:close, event.code, event.reason] }
|
|
73
103
|
mutex.synchronize do
|
|
74
|
-
@associated =
|
|
104
|
+
@associated = false
|
|
75
105
|
associated_cv.signal
|
|
76
106
|
end
|
|
77
|
-
|
|
78
|
-
@
|
|
107
|
+
rescue Exception => e
|
|
108
|
+
@logger.error { [:close_exception, e] }
|
|
79
109
|
end
|
|
80
|
-
rescue Exception => e
|
|
81
|
-
@logger.error { [:message_exception, e] }
|
|
82
110
|
end
|
|
83
|
-
end
|
|
84
111
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
@
|
|
88
|
-
mutex.synchronize do
|
|
89
|
-
@associated = false
|
|
90
|
-
associated_cv.signal
|
|
91
|
-
end
|
|
92
|
-
rescue Exception => e
|
|
93
|
-
@logger.error { [:close_exception, e] }
|
|
112
|
+
@connection.on :error do |event|
|
|
113
|
+
@logger.error { [:error, event] }
|
|
114
|
+
@associated = false
|
|
94
115
|
end
|
|
95
116
|
end
|
|
96
117
|
|
|
97
|
-
@connection.on :error do |event|
|
|
98
|
-
@logger.error { [:error, event] }
|
|
99
|
-
@associated = false
|
|
100
|
-
end
|
|
101
|
-
|
|
102
118
|
if !EM.reactor_running?
|
|
103
119
|
@logger.debug { [:no_eventmachine_reactor,
|
|
104
120
|
"Eventmachine reactor is not running" ] }
|
|
@@ -141,17 +157,24 @@ module PCP
|
|
|
141
157
|
# @param message [PCP::Message]
|
|
142
158
|
# @return unused
|
|
143
159
|
def send(message)
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
160
|
+
EM.next_tick do
|
|
161
|
+
@logger.debug { [:send, message] }
|
|
162
|
+
if message[:expires].nil?
|
|
163
|
+
message.expires(3)
|
|
164
|
+
end
|
|
165
|
+
message[:sender] = identity
|
|
166
|
+
@connection.send(message.encode)
|
|
167
|
+
end
|
|
147
168
|
end
|
|
148
169
|
|
|
149
170
|
# Disconnect the client
|
|
150
171
|
# @api public
|
|
151
172
|
# @return unused
|
|
152
173
|
def close
|
|
153
|
-
|
|
154
|
-
|
|
174
|
+
EM.next_tick do
|
|
175
|
+
@logger.debug { [:close] }
|
|
176
|
+
@connection.close
|
|
177
|
+
end
|
|
155
178
|
end
|
|
156
179
|
|
|
157
180
|
private
|
data/lib/pcp/message.rb
CHANGED
|
@@ -111,11 +111,19 @@ module PCP
|
|
|
111
111
|
chunks << frame_chunk(i + 2, @chunks[i])
|
|
112
112
|
end
|
|
113
113
|
|
|
114
|
-
|
|
114
|
+
validate
|
|
115
115
|
|
|
116
116
|
[1, frame_chunk(1, envelope.to_json), chunks].flatten
|
|
117
117
|
end
|
|
118
118
|
|
|
119
|
+
# Validate the data in message against schema
|
|
120
|
+
#
|
|
121
|
+
# @api public
|
|
122
|
+
# @return ignore
|
|
123
|
+
def validate
|
|
124
|
+
RSchema.validate!(PCP::Protocol::Envelope, envelope)
|
|
125
|
+
end
|
|
126
|
+
|
|
119
127
|
private
|
|
120
128
|
|
|
121
129
|
# Decodes an array of bytes into the message
|
|
@@ -144,7 +152,7 @@ module PCP
|
|
|
144
152
|
parsed.each do |k,v|
|
|
145
153
|
@envelope[k.to_sym] = v
|
|
146
154
|
end
|
|
147
|
-
|
|
155
|
+
validate
|
|
148
156
|
else
|
|
149
157
|
@chunks[type - 2] = body
|
|
150
158
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pcp-client
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3
|
|
4
|
+
version: 0.5.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Puppet Labs
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-06-17 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: eventmachine
|
|
@@ -30,14 +30,14 @@ dependencies:
|
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
33
|
+
version: 0.11.0
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version:
|
|
40
|
+
version: 0.11.0
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: rschema
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -54,10 +54,13 @@ dependencies:
|
|
|
54
54
|
version: '1.3'
|
|
55
55
|
description: See https://github.com/puppetlabs/pcp-specifications
|
|
56
56
|
email: puppet@puppetlabs.com
|
|
57
|
-
executables:
|
|
57
|
+
executables:
|
|
58
|
+
- pcp-ping
|
|
58
59
|
extensions: []
|
|
59
60
|
extra_rdoc_files: []
|
|
60
61
|
files:
|
|
62
|
+
- bin/pcp-ping
|
|
63
|
+
- lib/pcp-client/version.rb
|
|
61
64
|
- lib/pcp.rb
|
|
62
65
|
- lib/pcp/client.rb
|
|
63
66
|
- lib/pcp/message.rb
|
|
@@ -82,10 +85,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
82
85
|
- !ruby/object:Gem::Version
|
|
83
86
|
version: '0'
|
|
84
87
|
requirements: []
|
|
85
|
-
|
|
86
|
-
rubygems_version: 2.2.5
|
|
88
|
+
rubygems_version: 3.0.8
|
|
87
89
|
signing_key:
|
|
88
90
|
specification_version: 4
|
|
89
91
|
summary: Client library for PCP
|
|
90
92
|
test_files: []
|
|
91
|
-
has_rdoc:
|