pcp-client 0.3.0 → 0.5.3

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
- 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: