bosh-monitor 1.2989.0 → 1.2992.0

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
2
  SHA1:
3
- metadata.gz: 662d0c42ef02320624ca88219a0824de74e466c9
4
- data.tar.gz: 34e785eaacdb4a4c25de72d69a6e2345d94c71e6
3
+ metadata.gz: 5f229ffb0bccb50c4d7ae7a472c345ae04719415
4
+ data.tar.gz: a8bb9421c24077f30ab27fc67b6887b1e51313d6
5
5
  SHA512:
6
- metadata.gz: 12e9c7e6642d15c99744652fe45d97354309e163104c1851cc164dbc0bc8c95c37a3370352054be4c87da6bc10509b20b712d9672b4d5fcf9d0dc1fbf86fdd64
7
- data.tar.gz: dcbdac0db73a12eeef94ec2391ded58d70222d3ab23655aa3f0225c6fb60cf440e368abb40431efc21a55f50df42767a5334d454861b9bcfe62810a280b0f699
6
+ metadata.gz: d0b59682c39188b6c79b039115d688ed5a5db8bc7b555d5a1dea2c0b3e683c7c2014fee5ba0679c469aa5742630f5f51cb56d49be092d2c0939cba541a204b97
7
+ data.tar.gz: a4360a766685fbef249ef7240ad7680e66e00a78f5dc36237fe1a4259fb416a67f85b832f2ce8fe947003578103a89e95df3f4f45d3fed78c9a609f285048473
data/lib/bosh/monitor.rb CHANGED
@@ -31,6 +31,7 @@ require 'bosh/monitor/yaml_helper'
31
31
 
32
32
  # Basic blocks
33
33
  require 'bosh/monitor/agent'
34
+ require 'bosh/monitor/auth_provider'
34
35
  require 'bosh/monitor/config'
35
36
  require 'bosh/monitor/core_ext'
36
37
  require 'bosh/monitor/director'
@@ -0,0 +1,81 @@
1
+ require 'uaa'
2
+
3
+ module Bosh::Monitor
4
+ class AuthProvider
5
+ def initialize(auth_info, config, logger)
6
+ @auth_info = auth_info.fetch('user_authentication', {})
7
+
8
+ @user = config['user'].to_s
9
+ @password = config['password'].to_s
10
+ @client_id = config['client_id'].to_s
11
+ @client_secret = config['client_secret'].to_s
12
+ @ca_cert = config['ca_cert'].to_s
13
+
14
+ @logger = logger
15
+ end
16
+
17
+ def auth_header
18
+ if @auth_info.fetch('type', 'local') == 'uaa'
19
+ uaa_url = @auth_info.fetch('options', {}).fetch('url')
20
+ return uaa_token_header(uaa_url)
21
+ end
22
+
23
+ [@user, @password]
24
+ end
25
+
26
+ private
27
+
28
+ def uaa_token_header(uaa_url)
29
+ @uaa_token ||= UAAToken.new(@client_id, @client_secret, uaa_url, @ca_cert, @logger)
30
+ @uaa_token.auth_header
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ class UAAToken
37
+ EXPIRATION_DEADLINE_IN_SECONDS = 60
38
+
39
+ def initialize(client_id, client_secret, uaa_url, ca_cert, logger)
40
+ @uaa_token_issuer = CF::UAA::TokenIssuer.new(
41
+ uaa_url,
42
+ client_id,
43
+ client_secret,
44
+ {ssl_ca_file: ca_cert}
45
+ )
46
+ @logger = logger
47
+ end
48
+
49
+ def auth_header
50
+ if @uaa_token && !expires_soon?
51
+ return @uaa_token.auth_header
52
+ end
53
+
54
+ fetch
55
+
56
+ @uaa_token ? @uaa_token.auth_header : nil
57
+ end
58
+
59
+ private
60
+
61
+ def expires_soon?
62
+ expiration = @token_data[:exp] || @token_data['exp']
63
+ (Time.at(expiration).to_i - Time.now.to_i) < EXPIRATION_DEADLINE_IN_SECONDS
64
+ end
65
+
66
+ def fetch
67
+ @uaa_token = @uaa_token_issuer.client_credentials_grant
68
+ @token_data = decode
69
+ rescue => e
70
+ @logger.error("Failed to obtain token from UAA: #{e.inspect}")
71
+ end
72
+
73
+ def decode
74
+ access_token = @uaa_token.info['access_token'] || @uaa_token.info[:access_token]
75
+ CF::UAA::TokenCoder.decode(
76
+ access_token,
77
+ {verify: false},
78
+ nil, nil)
79
+ end
80
+ end
81
+ end
@@ -21,7 +21,7 @@ module Bosh::Monitor
21
21
 
22
22
  @logger = Logging.logger(config["logfile"] || STDOUT)
23
23
  @intervals = OpenStruct.new(config["intervals"])
24
- @director = Director.new(config["director"])
24
+ @director = Director.new(config["director"], @logger)
25
25
  @mbus = OpenStruct.new(config["mbus"])
26
26
 
27
27
  @event_processor = EventProcessor.new
@@ -1,19 +1,18 @@
1
1
  module Bosh::Monitor
2
2
  class Director
3
3
 
4
- def initialize(options)
5
- @endpoint = options["endpoint"].to_s
6
- @user = options["user"].to_s
7
- @password = options["password"].to_s
4
+ def initialize(options, logger)
5
+ @options = options
6
+ @logger = logger
8
7
  end
9
8
 
10
9
  def get_deployments
11
- http = perform_request(:get, "/deployments")
10
+ http = perform_request(:get, '/deployments')
12
11
 
13
12
  body = http.response
14
13
  status = http.response_header.http_status
15
14
 
16
- if status != "200"
15
+ if status != '200'
17
16
  raise DirectorError, "Cannot get deployments from director at #{http.uri}: #{status} #{body}"
18
17
  end
19
18
 
@@ -26,7 +25,7 @@ module Bosh::Monitor
26
25
  body = http.response
27
26
  status = http.response_header.http_status
28
27
 
29
- if status != "200"
28
+ if status != '200'
30
29
  raise DirectorError, "Cannot get deployment `#{name}' from director at #{http.uri}: #{status} #{body}"
31
30
  end
32
31
 
@@ -35,6 +34,10 @@ module Bosh::Monitor
35
34
 
36
35
  private
37
36
 
37
+ def endpoint
38
+ @options['endpoint'].to_s
39
+ end
40
+
38
41
  def parse_json(json, expected_type = nil)
39
42
  result = Yajl::Parser.parse(json)
40
43
 
@@ -52,14 +55,15 @@ module Bosh::Monitor
52
55
  # This is a very bad thing to do on eventmachine because it will block the single
53
56
  # event loop. This code should be removed and all requests converted
54
57
  # to "the eventmachine way".
55
- def perform_request(method, uri)
58
+ def perform_request(method, uri, options={})
56
59
  f = Fiber.current
57
60
 
58
- target_uri = @endpoint + uri
61
+ target_uri = endpoint + uri
59
62
 
60
- headers = {
61
- "authorization" => [@user, @password]
62
- }
63
+ headers = {}
64
+ unless options.fetch(:no_login, false)
65
+ headers['authorization'] = auth_provider.auth_header
66
+ end
63
67
 
64
68
  http = EM::HttpRequest.new(target_uri).send(method.to_sym, :head => headers)
65
69
 
@@ -68,9 +72,25 @@ module Bosh::Monitor
68
72
 
69
73
  Fiber.yield
70
74
 
71
- rescue URI::Error => e
75
+ rescue URI::Error
72
76
  raise DirectorError, "Invalid URI: #{target_uri}"
73
77
  end
74
78
 
79
+ def get_info
80
+ http = perform_request(:get, '/info', no_login: true)
81
+
82
+ body = http.response
83
+ status = http.response_header.http_status
84
+
85
+ if status != '200'
86
+ raise DirectorError, "Cannot get status from director at #{http.uri}: #{status} #{body}"
87
+ end
88
+
89
+ parse_json(body, Hash)
90
+ end
91
+
92
+ def auth_provider
93
+ @auth_provider ||= AuthProvider.new(get_info, @options, @logger)
94
+ end
75
95
  end
76
96
  end
@@ -1,3 +1,5 @@
1
+ require 'httpclient'
2
+
1
3
  module Bosh::Monitor::Plugins
2
4
  module HttpRequestHelper
3
5
  def send_http_post_request(uri, request)
@@ -8,6 +10,12 @@ module Bosh::Monitor::Plugins
8
10
  send_http_request(:put, uri, request)
9
11
  end
10
12
 
13
+ def send_http_get_request(uri)
14
+ # we are interested in response, so send sync request
15
+ logger.debug("Sending GET request to #{uri}")
16
+ sync_client.get(uri)
17
+ end
18
+
11
19
  def send_http_request(method, uri, request)
12
20
  name = self.class.name
13
21
  logger.debug("sending HTTP #{method.to_s.upcase} to: #{uri}")
@@ -21,5 +29,13 @@ module Bosh::Monitor::Plugins
21
29
  logger.error("Failed to send #{name} event: #{e.error}")
22
30
  end
23
31
  end
32
+
33
+ private
34
+
35
+ def sync_client
36
+ client = HTTPClient.new
37
+ client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
38
+ client
39
+ end
24
40
  end
25
41
  end
@@ -13,11 +13,10 @@ module Bosh::Monitor
13
13
  director = @options['director']
14
14
  raise ArgumentError 'director options not set' unless director
15
15
 
16
- @url = URI(director['endpoint'])
17
- @user = director['user']
18
- @password = director['password']
19
- @processor = Bhm.event_processor
20
- @alert_tracker = ResurrectorHelper::AlertTracker.new(@options)
16
+ @url = URI(director['endpoint'])
17
+ @director_options = director
18
+ @processor = Bhm.event_processor
19
+ @alert_tracker = ResurrectorHelper::AlertTracker.new(@options)
21
20
  end
22
21
 
23
22
  def run
@@ -41,10 +40,16 @@ module Bosh::Monitor
41
40
  @alert_tracker.record(agent_key, alert.created_at)
42
41
 
43
42
  payload = {'jobs' => {job => [index]}}
43
+
44
+ unless director_info
45
+ logger.error("(Resurrector) director is not responding with the status")
46
+ return
47
+ end
48
+
44
49
  request = {
45
50
  head: {
46
51
  'Content-Type' => 'application/json',
47
- 'authorization' => [@user, @password]
52
+ 'authorization' => auth_provider(director_info).auth_header
48
53
  },
49
54
  body: Yajl::Encoder.encode(payload)
50
55
  }
@@ -70,12 +75,27 @@ module Bosh::Monitor
70
75
  send_http_put_request(url.to_s, request)
71
76
  end
72
77
 
73
-
74
78
  else
75
79
  logger.warn("(Resurrector) event did not have deployment, job and index: #{alert}")
76
80
  end
77
81
  end
78
82
 
83
+ private
84
+
85
+ def auth_provider(director_info)
86
+ @auth_provider ||= AuthProvider.new(director_info, @director_options, logger)
87
+ end
88
+
89
+ def director_info
90
+ return @director_info if @director_info
91
+
92
+ director_info_url = @url.dup
93
+ director_info_url.path = '/info'
94
+ response = send_http_get_request(director_info_url.to_s)
95
+ return nil if response.status_code != 200
96
+
97
+ @director_info = Yajl::Parser.parse(response.body)
98
+ end
79
99
  end
80
100
  end
81
101
  end
@@ -1,5 +1,5 @@
1
1
  module Bosh
2
2
  module Monitor
3
- VERSION = '1.2989.0'
3
+ VERSION = '1.2992.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bosh-monitor
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2989.0
4
+ version: 1.2992.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - VMware
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-16 00:00:00.000000000 Z
11
+ date: 2015-06-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: eventmachine
@@ -136,6 +136,34 @@ dependencies:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
138
  version: 1.6.0
139
+ - !ruby/object:Gem::Dependency
140
+ name: cf-uaa-lib
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: 3.2.1
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: 3.2.1
153
+ - !ruby/object:Gem::Dependency
154
+ name: httpclient
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - '='
158
+ - !ruby/object:Gem::Version
159
+ version: 2.4.0
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - '='
165
+ - !ruby/object:Gem::Version
166
+ version: 2.4.0
139
167
  - !ruby/object:Gem::Dependency
140
168
  name: rake
141
169
  requirement: !ruby/object:Gem::Requirement
@@ -180,7 +208,7 @@ dependencies:
180
208
  version: '0'
181
209
  description: |-
182
210
  BOSH Health Monitor
183
- 0c4ecd
211
+ 2996bb
184
212
  email: support@cloudfoundry.com
185
213
  executables:
186
214
  - bosh-monitor-console
@@ -197,6 +225,7 @@ files:
197
225
  - lib/bosh/monitor/agent.rb
198
226
  - lib/bosh/monitor/agent_manager.rb
199
227
  - lib/bosh/monitor/api_controller.rb
228
+ - lib/bosh/monitor/auth_provider.rb
200
229
  - lib/bosh/monitor/config.rb
201
230
  - lib/bosh/monitor/core_ext.rb
202
231
  - lib/bosh/monitor/director.rb