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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 4bbadd16844a443623b6d9d1389b580960b17592
4
- data.tar.gz: cfe1c97388dbab0db4496b316f57961cc6e30d9d
2
+ SHA256:
3
+ metadata.gz: c8712776d17a4fffc25f012a1471bb56de3af9db2edbfe9c770cae53fc6de82c
4
+ data.tar.gz: 7e53fc42f88e35bf7d2d2051188d9672d39ac82ed568d3fab0ddacc666666a00
5
5
  SHA512:
6
- metadata.gz: d006505e2bfdee5de658da1a1dff1215d3a483ce4e7326815f8229b39f9acf61597686ad7c4a83e1e0d46e712aa8420742387743792df3212ef760bbeb25947d
7
- data.tar.gz: ef1ab13ddaeffda48954bc65c8d7b1d28c62037667dad6d40708eb79c37c69544767cd41198778cf690bd35b547d759665020897f82774aa7c85c31af5a30f04
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
@@ -0,0 +1,4 @@
1
+ class PCPClient
2
+ VERSION = '0.5.3'.freeze
3
+ end
4
+
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, @server] }
54
- @connection = Faye::WebSocket::Client.new(@server, nil, {:tls => {:private_key_file => @ssl_key,
55
- :cert_chain_file => @ssl_cert,
56
- :ssl_version => ["TLSv1", "TLSv1_1", "TLSv1_2"]}})
57
-
58
- @connection.on :open do |event|
59
- begin
60
- @logger.info { [:open] }
61
- send(associate_request)
62
- rescue Exception => e
63
- @logger.error { [:open_exception, e] }
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
- @connection.on :message do |event|
68
- begin
69
- message = ::PCP::Message.new(event.data)
70
- @logger.debug { [:message, :decoded, message] }
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
- if message[:message_type] == 'http://puppetlabs.com/associate_response'
100
+ @connection.on :close do |event|
101
+ begin
102
+ @logger.info { [:close, event.code, event.reason] }
73
103
  mutex.synchronize do
74
- @associated = JSON.load(message.data)["success"]
104
+ @associated = false
75
105
  associated_cv.signal
76
106
  end
77
- elsif @on_message
78
- @on_message.call(message)
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
- @connection.on :close do |event|
86
- begin
87
- @logger.info { [:close, event.code, event.reason] }
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
- @logger.debug { [:send, message] }
145
- message[:sender] = identity
146
- @connection.send(message.encode)
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
- @logger.debug { [:close] }
154
- @connection.close
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
- RSchema.validate!(PCP::Protocol::Envelope, envelope)
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
- RSchema.validate!(PCP::Protocol::Envelope, @envelope)
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.0
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: 2016-04-05 00:00:00.000000000 Z
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: '0.10'
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: '0.10'
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
- rubyforge_project:
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: