logstream 0.0.8 → 2.0.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 +4 -4
- data/Dockerfile +19 -0
- data/LICENSE +1 -1
- data/README.md +13 -15
- data/bin/logstream +24 -41
- data/lib/logstream.rb +1 -0
- data/lib/logstream/client.rb +13 -3
- data/lib/logstream/cloudapi_v2.rb +60 -0
- data/logstream.gemspec +26 -0
- metadata +7 -20
- data/etc/ca.pem +0 -98
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5c342a7bd87ef68659a38e1a178aa215300f799b40d3da2f20e39450d223c7b0
|
|
4
|
+
data.tar.gz: e7c15933144d09121045040fd829185c6a1d91d95af642bd7c3e0e820fbaa23c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d4464befbf1bb3872679b1bd5e3b9688807068659ad02f6c34720009315b3986d60d7bae15bba562acc12147089eac0defdd83242eb4a2024def00593bef7f38
|
|
7
|
+
data.tar.gz: c2d90fbb124b7e7a12a7ea7bbb4a96d6ee758a7baf28138ba5017582e68fb846d4319185a15374a587172c3f649c4a03ca355da7ed5fb8c69f35d689bdc0fab0
|
data/Dockerfile
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
FROM ubuntu:latest
|
|
2
|
+
|
|
3
|
+
RUN apt-get update \
|
|
4
|
+
&& apt-get install -y \
|
|
5
|
+
curl \
|
|
6
|
+
make \
|
|
7
|
+
build-essential \
|
|
8
|
+
g++ \
|
|
9
|
+
libssl-dev \
|
|
10
|
+
ruby-dev
|
|
11
|
+
RUN mkdir /src
|
|
12
|
+
|
|
13
|
+
COPY . /src
|
|
14
|
+
|
|
15
|
+
RUN cd /src \
|
|
16
|
+
&& gem build logstream \
|
|
17
|
+
&& gem install logstream-*.gem
|
|
18
|
+
|
|
19
|
+
ENTRYPOINT ["/bin/bash"]
|
data/LICENSE
CHANGED
data/README.md
CHANGED
|
@@ -15,25 +15,24 @@ UI</a> as well.
|
|
|
15
15
|
|
|
16
16
|
## Quick start
|
|
17
17
|
|
|
18
|
-
* Logstream works in conjunction with Acquia's
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
* Logstream works in conjunction with Acquia's [Cloud API](https://cloudapi-docs.acquia.com/). In order to use Cloud API you will need to generate credentials for your account. [Cloud API v2 authentication](https://docs.acquia.com/acquia-cloud/develop/api/auth/#generating-an-api-token) explains how to generate the credentials. Place the credentials in `$HOME/.acquia/cloudapiv2.conf` . This file is in JSON format with api_key and api_secret defined.
|
|
19
|
+
```
|
|
20
|
+
{
|
|
21
|
+
"api_key" : "key",
|
|
22
|
+
"api_secret" : "secret"
|
|
23
|
+
}
|
|
24
|
+
```
|
|
22
25
|
|
|
23
26
|
* Install the Logstream CLI:
|
|
24
27
|
```
|
|
25
28
|
$ gem install logstream
|
|
26
29
|
```
|
|
27
30
|
|
|
28
|
-
*
|
|
29
|
-
```
|
|
30
|
-
$ drush ac-site-list
|
|
31
|
-
devcloud:mysite
|
|
32
|
-
```
|
|
31
|
+
* Find the UUID of the application you would like to stream logs for. Documentation on how to find applicaiton UUID can be found [here](https://docs.acquia.com/acquia-cloud/manage/applications/#obtaining-your-subscription-s-application-id)
|
|
33
32
|
|
|
34
33
|
* Stream logs from the production environment:
|
|
35
34
|
```
|
|
36
|
-
$ logstream tail
|
|
35
|
+
$ logstream tail 55ea1945-4aa6-4c56-bb7b-2108565e22d6 prod
|
|
37
36
|
127.0.0.1 - - [11/Jun/2014:17:28:47 +0000] "GET / HTTP/1.1" 200 7708 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36" http_host=mysite.com affinity="-" upstream_addr="10.218.29.150:80" hosting_site=mysite request_time=0.030 forwarded_for="64.80.128.4" upstream_status="200"
|
|
38
37
|
... etc ...
|
|
39
38
|
```
|
|
@@ -44,11 +43,10 @@ A variety of filtering and display options are available:
|
|
|
44
43
|
$ logstream help tail
|
|
45
44
|
```
|
|
46
45
|
|
|
47
|
-
## API
|
|
46
|
+
## API v2
|
|
48
47
|
|
|
49
|
-
Logstream communicates over TCP using the WebSocket protocol. Use the
|
|
50
|
-
|
|
51
|
-
Cloud API call</a> to retrieve the URL to connect to and an authenticated
|
|
48
|
+
Logstream communicates over TCP using the WebSocket protocol. Use the [logstream
|
|
49
|
+
Cloud API call](https://cloudapi-docs.acquia.com/#/Environments/getEnvironmentsLogstream) to retrieve the URL to connect to and an authenticated
|
|
52
50
|
message to initial streaming for a particular Cloud environment.
|
|
53
51
|
|
|
54
52
|
Messages use text data frames, and contain JSON-encoded hashes. Each message
|
|
@@ -73,7 +71,7 @@ default, the CLI enables the log types apache-request, php-error,
|
|
|
73
71
|
drupal-watchdog, and varnish-request.
|
|
74
72
|
|
|
75
73
|
```
|
|
76
|
-
$ logstream tail
|
|
74
|
+
$ logstream tail 55ea1945-4aa6-4c56-bb7b-2108565e22d6 dev --debug
|
|
77
75
|
-> connect to wss://logstream.acquia.com/ah_websocket/logstream/v1
|
|
78
76
|
-> {"site":"devcloud:mysite","d":"deaefc1f42a4d18cb932c2eb9fa75115fba5ab83f1a3c564767ef1ce8dabf2cc","t":1404764927,"env":"dev","cmd":"stream-environment"}
|
|
79
77
|
<- {"cmd":"connected","server":"logstream-api-61"}
|
data/bin/logstream
CHANGED
|
@@ -1,45 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
|
|
3
3
|
require 'rubygems'
|
|
4
|
-
require 'net/https'
|
|
5
|
-
require 'json'
|
|
6
4
|
require 'thor'
|
|
5
|
+
require 'json'
|
|
7
6
|
require 'logstream/client'
|
|
8
|
-
|
|
9
|
-
# @todo: Yeah, this is terrible. Replace it with a real Cloud API gem.
|
|
10
|
-
class QuickCloudAPI
|
|
11
|
-
class Error < StandardError; end
|
|
12
|
-
|
|
13
|
-
def self.get(path, opts = {})
|
|
14
|
-
confpath = "#{ENV['HOME']}/.acquia/cloudapi.conf"
|
|
15
|
-
begin
|
|
16
|
-
json = File.read(confpath)
|
|
17
|
-
config = JSON.load(json)
|
|
18
|
-
rescue Errno::ENOENT, JSON::ParserError => e
|
|
19
|
-
raise Error, "#{confpath} is missing or invalid. Download your Drush aliases from https://accounts.acquia.com/account/security to initialize it."
|
|
20
|
-
end
|
|
21
|
-
opts[:endpoint] ||= "https://cloudapi.acquia.com/v1"
|
|
22
|
-
uri = URI.parse("#{opts[:endpoint]}#{path}.json")
|
|
23
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
|
24
|
-
http.use_ssl = true
|
|
25
|
-
http.ca_file = File.dirname(__FILE__) + "/../etc/ca.pem"
|
|
26
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
|
27
|
-
request = Net::HTTP::Get.new(uri.request_uri)
|
|
28
|
-
request.basic_auth(config['email'], config['key'])
|
|
29
|
-
response = http.request(request)
|
|
30
|
-
parsed = JSON.parse(response.body) rescue nil
|
|
31
|
-
case response.code.to_i
|
|
32
|
-
when 200
|
|
33
|
-
raise Error, "Unexpected reply #{response.body}" unless parsed
|
|
34
|
-
parsed
|
|
35
|
-
else
|
|
36
|
-
raise Error, "HTTP #{response.code}: #{response.body}"
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
7
|
+
require 'logstream/cloudapi_v2'
|
|
40
8
|
|
|
41
9
|
class LogTailorCLI < Thor
|
|
42
|
-
desc "tail
|
|
10
|
+
desc "tail APPLICATION_UUID ENV", "Stream log information for the specified application environment."
|
|
43
11
|
method_option(:types, :type => :array, :aliases => '-t',
|
|
44
12
|
:desc => "Only display listed log types",
|
|
45
13
|
:default => %w(apache-request php-error drupal-watchdog varnish-request),
|
|
@@ -59,15 +27,30 @@ class LogTailorCLI < Thor
|
|
|
59
27
|
:banner => "disp_time http_status log_type request_id server text"
|
|
60
28
|
)
|
|
61
29
|
method_option(:color, :type => :boolean, :default => true, :desc => 'Turn on or off colorized lines.')
|
|
62
|
-
method_option(:endpoint, :type => :string, :desc => 'The Cloud API URL to connect to.')
|
|
63
30
|
method_option(:debug, :type => :boolean, :default => false, :desc => 'Turn on debugging.')
|
|
64
|
-
def tail(
|
|
31
|
+
def tail(application_uuid, env)
|
|
65
32
|
begin
|
|
66
33
|
shows = Hash[options[:show].map { |s| s.split('=') }.map { |k,v| [k, Regexp.new(v)] }] rescue {}
|
|
67
34
|
hides = Hash[options[:hide].map { |h| h.split('=') }.map { |k,v| [k, Regexp.new(v)] }] rescue {}
|
|
68
35
|
|
|
69
36
|
begin
|
|
70
|
-
|
|
37
|
+
confpath = "#{ENV['HOME']}/.acquia/cloudapiv2.conf"
|
|
38
|
+
begin
|
|
39
|
+
json = File.read(confpath)
|
|
40
|
+
config = JSON.load(json)
|
|
41
|
+
rescue Errno::ENOENT, JSON::ParserError => e
|
|
42
|
+
raise Error, "#{confpath} is missing or invalid. Please configure your Cloud API v2 credentials"
|
|
43
|
+
end
|
|
44
|
+
cloudapi_client = Logstream::CloudAPIV2.new(config['api_key'], config['api_secret'])
|
|
45
|
+
environments = cloudapi_client.get_application_environments(application_uuid)
|
|
46
|
+
environment_uuid = nil
|
|
47
|
+
environments.each do |environment|
|
|
48
|
+
if environment['name'] == env
|
|
49
|
+
environment_uuid = environment['id']
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
raise Error, "No environment found with #{env} name." unless environment_uuid
|
|
53
|
+
stream_info = cloudapi_client.get_envirornment_logstream(environment_uuid)
|
|
71
54
|
logstream = Logstream::Client.new({
|
|
72
55
|
:columns => options[:columns],
|
|
73
56
|
:types => options[:types],
|
|
@@ -76,8 +59,8 @@ class LogTailorCLI < Thor
|
|
|
76
59
|
:no_color => !options[:color],
|
|
77
60
|
:debug => options[:debug],
|
|
78
61
|
})
|
|
79
|
-
logstream.run(
|
|
80
|
-
rescue
|
|
62
|
+
logstream.run(stream_info['url'], stream_info['params'])
|
|
63
|
+
rescue Logstream::CloudAPIV2::Error => e
|
|
81
64
|
puts "Cloud API error: #{e.message}"
|
|
82
65
|
exit(1)
|
|
83
66
|
end
|
|
@@ -85,5 +68,5 @@ class LogTailorCLI < Thor
|
|
|
85
68
|
end
|
|
86
69
|
end
|
|
87
70
|
|
|
88
|
-
LogTailorCLI.start
|
|
71
|
+
LogTailorCLI.start(ARGV)
|
|
89
72
|
|
data/lib/logstream.rb
CHANGED
data/lib/logstream/client.rb
CHANGED
|
@@ -39,18 +39,28 @@ module Logstream
|
|
|
39
39
|
debug("<- #{msg}")
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
def run(url,
|
|
42
|
+
def run(url, info)
|
|
43
43
|
EM.run do
|
|
44
44
|
debug_send("connect to #{url}")
|
|
45
|
+
connect_message = {
|
|
46
|
+
'cmd' => 'stream-environment',
|
|
47
|
+
'site' => info['site'],
|
|
48
|
+
'env' => info['environment'],
|
|
49
|
+
't' => info['t'],
|
|
50
|
+
'd' => info['hmac'],
|
|
51
|
+
}
|
|
45
52
|
ws = Faye::WebSocket::Client.new(url)
|
|
46
53
|
ws.on :open do
|
|
47
|
-
|
|
48
|
-
ws.send(connect_message)
|
|
54
|
+
@running = false
|
|
49
55
|
end
|
|
50
56
|
ws.on :message do |body,type|
|
|
51
57
|
debug_recv(body.data)
|
|
52
58
|
msg = JSON.parse(body.data)
|
|
53
59
|
case msg['cmd']
|
|
60
|
+
when 'connected'
|
|
61
|
+
debug_send(connect_message.to_json)
|
|
62
|
+
ws.send(connect_message.to_json) unless @running
|
|
63
|
+
@running = true
|
|
54
64
|
when 'success'
|
|
55
65
|
color('logtailor-error', msg['code']) do
|
|
56
66
|
# puts "#{msg.inspect}"
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
require 'net/https'
|
|
2
|
+
require 'json'
|
|
3
|
+
|
|
4
|
+
module Logstream
|
|
5
|
+
class CloudAPIV2
|
|
6
|
+
class Error < StandardError; end
|
|
7
|
+
|
|
8
|
+
attr_accessor :client_id, :client_secret, :endpoint
|
|
9
|
+
CLOUDAPI_ENDPOINT = 'https://cloud.acquia.com/api'
|
|
10
|
+
|
|
11
|
+
def initialize(client_id, client_secret)
|
|
12
|
+
@client_id = client_id
|
|
13
|
+
@client_secret = client_secret
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def get(path)
|
|
17
|
+
bearer_token = get_token
|
|
18
|
+
uri = URI.parse("#{CLOUDAPI_ENDPOINT}#{path}")
|
|
19
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
20
|
+
http.use_ssl = true
|
|
21
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
|
22
|
+
request['Authorization'] = "Bearer #{bearer_token}"
|
|
23
|
+
response = http.request(request)
|
|
24
|
+
parsed = JSON.parse(response.body) rescue nil
|
|
25
|
+
case response.code.to_i
|
|
26
|
+
when 200
|
|
27
|
+
raise Error, "Unexpected reply #{response.body}" unless parsed
|
|
28
|
+
parsed
|
|
29
|
+
else
|
|
30
|
+
raise Error, "HTTP #{response.code}: #{response.body}"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def get_application_environments(application_uuid)
|
|
35
|
+
response = get("/applications/#{application_uuid}/environments") #, { :query => { "filter" => "name%3D#{env}"}})
|
|
36
|
+
raise Error, "No Environments found." if response['total'] == 0
|
|
37
|
+
raise Error, "Unexpected reply #{response}" unless response['_embedded']['items']
|
|
38
|
+
response['_embedded']['items']
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def get_envirornment_logstream(environment_uuid)
|
|
42
|
+
response = get("/environments/#{environment_uuid}/logstream")
|
|
43
|
+
raise Error, "Unexpected reply #{response}" unless response['logstream']
|
|
44
|
+
response['logstream']
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def get_token
|
|
48
|
+
uri = URI.parse("https://accounts.acquia.com/api/auth/oauth/token")
|
|
49
|
+
response = Net::HTTP.post_form(uri, 'client_id' => @client_id, 'client_secret' => @client_secret, 'grant_type' => 'client_credentials')
|
|
50
|
+
parsed = JSON.parse(response.body) rescue nil
|
|
51
|
+
case response.code.to_i
|
|
52
|
+
when 200
|
|
53
|
+
raise Error, "Unexpected reply #{response.body}" unless parsed["access_token"]
|
|
54
|
+
parsed["access_token"]
|
|
55
|
+
else
|
|
56
|
+
raise Error, "HTTP #{response.code}: #{response.body}"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
data/logstream.gemspec
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
libpath = File.join(File.dirname(__FILE__), 'lib')
|
|
2
|
+
$LOAD_PATH.unshift(libpath) unless $LOAD_PATH.include?(libpath)
|
|
3
|
+
|
|
4
|
+
Gem::Specification.new do |s|
|
|
5
|
+
s.name = "logstream"
|
|
6
|
+
s.version = "2.0.0"
|
|
7
|
+
s.date = Time.now.strftime("%Y-%m-%d")
|
|
8
|
+
|
|
9
|
+
s.author = "Acquia Engineering"
|
|
10
|
+
s.homepage = "https://github.com/acquia/logstream"
|
|
11
|
+
|
|
12
|
+
s.licenses = ['MIT']
|
|
13
|
+
|
|
14
|
+
s.summary = "Acquia Logstream tools and library"
|
|
15
|
+
s.description = "Logstream is an Acquia service for streaming logs from Acquia Cloud."
|
|
16
|
+
|
|
17
|
+
s.files = Dir["[A-Z]*", "{bin,etc,lib,test}/**/*"]
|
|
18
|
+
s.bindir = "bin"
|
|
19
|
+
s.executables = Dir["bin/*"].map { |f| File.basename(f) }.select { |f| f =~ /^[\w\-]+$/ }
|
|
20
|
+
s.test_files = Dir["test/**/*"]
|
|
21
|
+
|
|
22
|
+
s.add_runtime_dependency('faye-websocket', ['~> 0.10.0'])
|
|
23
|
+
s.add_runtime_dependency('thor', ['~> 0.20.0'])
|
|
24
|
+
|
|
25
|
+
s.required_ruby_version = '>= 2.4'
|
|
26
|
+
end
|
metadata
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: logstream
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
-
|
|
7
|
+
- Acquia Engineering
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
@@ -24,20 +24,6 @@ dependencies:
|
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: 0.10.0
|
|
27
|
-
- !ruby/object:Gem::Dependency
|
|
28
|
-
name: json
|
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
|
30
|
-
requirements:
|
|
31
|
-
- - ">="
|
|
32
|
-
- !ruby/object:Gem::Version
|
|
33
|
-
version: 1.7.7
|
|
34
|
-
type: :runtime
|
|
35
|
-
prerelease: false
|
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
-
requirements:
|
|
38
|
-
- - ">="
|
|
39
|
-
- !ruby/object:Gem::Version
|
|
40
|
-
version: 1.7.7
|
|
41
27
|
- !ruby/object:Gem::Dependency
|
|
42
28
|
name: thor
|
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -53,20 +39,22 @@ dependencies:
|
|
|
53
39
|
- !ruby/object:Gem::Version
|
|
54
40
|
version: 0.20.0
|
|
55
41
|
description: Logstream is an Acquia service for streaming logs from Acquia Cloud.
|
|
56
|
-
email:
|
|
42
|
+
email:
|
|
57
43
|
executables:
|
|
58
44
|
- logstream
|
|
59
45
|
extensions: []
|
|
60
46
|
extra_rdoc_files: []
|
|
61
47
|
files:
|
|
48
|
+
- Dockerfile
|
|
62
49
|
- Gemfile
|
|
63
50
|
- Gemfile.lock
|
|
64
51
|
- LICENSE
|
|
65
52
|
- README.md
|
|
66
53
|
- bin/logstream
|
|
67
|
-
- etc/ca.pem
|
|
68
54
|
- lib/logstream.rb
|
|
69
55
|
- lib/logstream/client.rb
|
|
56
|
+
- lib/logstream/cloudapi_v2.rb
|
|
57
|
+
- logstream.gemspec
|
|
70
58
|
homepage: https://github.com/acquia/logstream
|
|
71
59
|
licenses:
|
|
72
60
|
- MIT
|
|
@@ -86,8 +74,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
86
74
|
- !ruby/object:Gem::Version
|
|
87
75
|
version: '0'
|
|
88
76
|
requirements: []
|
|
89
|
-
|
|
90
|
-
rubygems_version: 2.7.10
|
|
77
|
+
rubygems_version: 3.0.3
|
|
91
78
|
signing_key:
|
|
92
79
|
specification_version: 4
|
|
93
80
|
summary: Acquia Logstream tools and library
|
data/etc/ca.pem
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
-----BEGIN CERTIFICATE-----
|
|
2
|
-
MIIGvzCCBaegAwIBAgIQD1pdYvA5l5l2ezeWEsVwNTANBgkqhkiG9w0BAQUFADBm
|
|
3
|
-
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
|
4
|
-
d3cuZGlnaWNlcnQuY29tMSUwIwYDVQQDExxEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
|
|
5
|
-
ZSBDQS0zMB4XDTEyMDgyNzAwMDAwMFoXDTE1MDkwOTEyMDAwMFowfzELMAkGA1UE
|
|
6
|
-
BhMCVVMxFjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxEzARBgNVBAcTCkJ1cmxpbmd0
|
|
7
|
-
b24xEzARBgNVBAoTCkFjcXVpYSBJbmMxFzAVBgNVBAsTDkFjcXVpYSBIb3N0aW5n
|
|
8
|
-
MRUwEwYDVQQDDAwqLmFjcXVpYS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
|
|
9
|
-
ggEKAoIBAQCVmcKz54qAbNO9NyP3hA96gzGRORSB9Bz4EOuFM1kfD/gvZoXoqk87
|
|
10
|
-
NC/jPrvPAxNZDJ33IrO08WDWxBVi6UQ7Q9YYFgU1mm0se4qjwld7dtziDnaq2zXc
|
|
11
|
-
x4Q+AVfBj92w+RsVDWA2mNtMSaDePqXGzLOz4muUCA5oCtMg2QD+XIEp1yt13nQb
|
|
12
|
-
5nW6PbY6kHHviepNX3wj7TdqTLNPdCVcK9BJz2YTjfHtBBxnGxR/m804RL9fYWKz
|
|
13
|
-
r6XUbbf+gcKFwMqRI54Qs5cD20jmYnYgXFYwAx6HvOH9Lr969xMq5ePIQkKc66kG
|
|
14
|
-
Opie8unjAQRgd6T7lL+zvpaen1UhJruhAgMBAAGjggNOMIIDSjAfBgNVHSMEGDAW
|
|
15
|
-
gBRQ6nOJ2yn7EI+e5QEg1N55mUiD9zAdBgNVHQ4EFgQUJuo64qCLWo0Fvi6AsOYG
|
|
16
|
-
IiNj+s8wIwYDVR0RBBwwGoIMKi5hY3F1aWEuY29tggphY3F1aWEuY29tMA4GA1Ud
|
|
17
|
-
DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwYQYDVR0f
|
|
18
|
-
BFowWDAqoCigJoYkaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL2NhMy1nMjcuY3Js
|
|
19
|
-
MCqgKKAmhiRodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vY2EzLWcyNy5jcmwwggHE
|
|
20
|
-
BgNVHSAEggG7MIIBtzCCAbMGCWCGSAGG/WwBATCCAaQwOgYIKwYBBQUHAgEWLmh0
|
|
21
|
-
dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0wggFk
|
|
22
|
-
BggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgAaQBz
|
|
23
|
-
ACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQAZQBz
|
|
24
|
-
ACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcAaQBD
|
|
25
|
-
AGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwAeQBp
|
|
26
|
-
AG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkAYwBo
|
|
27
|
-
ACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEAcgBl
|
|
28
|
-
ACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIAeQAg
|
|
29
|
-
AHIAZQBmAGUAcgBlAG4AYwBlAC4wewYIKwYBBQUHAQEEbzBtMCQGCCsGAQUFBzAB
|
|
30
|
-
hhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wRQYIKwYBBQUHMAKGOWh0dHA6Ly9j
|
|
31
|
-
YWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEhpZ2hBc3N1cmFuY2VDQS0zLmNy
|
|
32
|
-
dDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBBQUAA4IBAQCwbrUX+rSNdiS1ivce
|
|
33
|
-
pI3gzzlOG9FjcPPTfoLD/+eiysiTKe7d3Hb9urHZWGuEWWxXRl+6tND3TAt8ONpM
|
|
34
|
-
ZCs+nls+qvspG8ApQMZLgak4kb4+CaLMi6ZpQ2JTI89iChonOjI0OP6dVDbGbTvV
|
|
35
|
-
a7LKkiZw1xJNYUnhIiqOE1B9Ww3SUUpe1TLmiAYiiYiiuiyBxMz48sARHXnlEbWw
|
|
36
|
-
0dHOnU51tvG1zkv9sATYwv3LtIjf9pmXZnS1W0j5Ap0JeFbgFywVi0zSpbix0fzr
|
|
37
|
-
pyArWETFKxirR2bCVFH0sVZ2q3/sznguUx1QgH+tese0hqHm2epRORcOi69mcDYi
|
|
38
|
-
Cf5v
|
|
39
|
-
-----END CERTIFICATE-----
|
|
40
|
-
-----BEGIN CERTIFICATE-----
|
|
41
|
-
MIIGWDCCBUCgAwIBAgIQCl8RTQNbF5EX0u/UA4w/OzANBgkqhkiG9w0BAQUFADBs
|
|
42
|
-
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
|
43
|
-
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
|
|
44
|
-
ZSBFViBSb290IENBMB4XDTA4MDQwMjEyMDAwMFoXDTIyMDQwMzAwMDAwMFowZjEL
|
|
45
|
-
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
|
|
46
|
-
LmRpZ2ljZXJ0LmNvbTElMCMGA1UEAxMcRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
|
|
47
|
-
Q0EtMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9hCikQH17+NDdR
|
|
48
|
-
CPge+yLtYb4LDXBMUGMmdRW5QYiXtvCgFbsIYOBC6AUpEIc2iihlqO8xB3RtNpcv
|
|
49
|
-
KEZmBMcqeSZ6mdWOw21PoF6tvD2Rwll7XjZswFPPAAgyPhBkWBATaccM7pxCUQD5
|
|
50
|
-
BUTuJM56H+2MEb0SqPMV9Bx6MWkBG6fmXcCabH4JnudSREoQOiPkm7YDr6ictFuf
|
|
51
|
-
1EutkozOtREqqjcYjbTCuNhcBoz4/yO9NV7UfD5+gw6RlgWYw7If48hl66l7XaAs
|
|
52
|
-
zPw82W3tzPpLQ4zJ1LilYRyyQLYoEt+5+F/+07LJ7z20Hkt8HEyZNp496+ynaF4d
|
|
53
|
-
32duXvsCAwEAAaOCAvowggL2MA4GA1UdDwEB/wQEAwIBhjCCAcYGA1UdIASCAb0w
|
|
54
|
-
ggG5MIIBtQYLYIZIAYb9bAEDAAIwggGkMDoGCCsGAQUFBwIBFi5odHRwOi8vd3d3
|
|
55
|
-
LmRpZ2ljZXJ0LmNvbS9zc2wtY3BzLXJlcG9zaXRvcnkuaHRtMIIBZAYIKwYBBQUH
|
|
56
|
-
AgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAAbwBmACAAdABoAGkAcwAgAEMAZQBy
|
|
57
|
-
AHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMAdABpAHQAdQB0AGUAcwAgAGEAYwBj
|
|
58
|
-
AGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAg
|
|
59
|
-
AEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQ
|
|
60
|
-
AGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4AdAAgAHcAaABpAGMAaAAgAGwAaQBt
|
|
61
|
-
AGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBj
|
|
62
|
-
AG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIAZQBpAG4AIABiAHkAIAByAGUAZgBl
|
|
63
|
-
AHIAZQBuAGMAZQAuMBIGA1UdEwEB/wQIMAYBAf8CAQAwNAYIKwYBBQUHAQEEKDAm
|
|
64
|
-
MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wgY8GA1UdHwSB
|
|
65
|
-
hzCBhDBAoD6gPIY6aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0SGln
|
|
66
|
-
aEFzc3VyYW5jZUVWUm9vdENBLmNybDBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNl
|
|
67
|
-
cnQuY29tL0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNybDAfBgNVHSME
|
|
68
|
-
GDAWgBSxPsNpA/i/RwHUmCYaCALvY2QrwzAdBgNVHQ4EFgQUUOpzidsp+xCPnuUB
|
|
69
|
-
INTeeZlIg/cwDQYJKoZIhvcNAQEFBQADggEBAB7ipUiebNtTOA/vphoqrOIDQ+2a
|
|
70
|
-
vD6OdRvw/S4iWawTwGHi5/rpmc2HCXVUKL9GYNy+USyS8xuRfDEIcOI3ucFbqL2j
|
|
71
|
-
CwD7GhX9A61YasXHJJlIR0YxHpLvtF9ONMeQvzHB+LGEhtCcAarfilYGzjrpDq6X
|
|
72
|
-
dF3XcZpCdF/ejUN83ulV7WkAywXgemFhM9EZTfkI7qA5xSU1tyvED7Ld8aW3DiTE
|
|
73
|
-
JiiNeXf1L/BXunwH1OH8zVowV36GEEfdMR/X/KLCvzB8XSSq6PmuX2p0ws5rs0bY
|
|
74
|
-
Ib4p1I5eFdZCSucyb6Sxa1GDWL4/bcf72gMhy2oWGU4K8K2Eyl2Us1p292E=
|
|
75
|
-
-----END CERTIFICATE-----
|
|
76
|
-
-----BEGIN CERTIFICATE-----
|
|
77
|
-
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
|
|
78
|
-
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
|
79
|
-
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
|
|
80
|
-
ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
|
|
81
|
-
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
|
|
82
|
-
LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
|
|
83
|
-
RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
|
|
84
|
-
+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
|
|
85
|
-
PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
|
|
86
|
-
xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
|
|
87
|
-
Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
|
|
88
|
-
hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
|
|
89
|
-
EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
|
|
90
|
-
MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
|
|
91
|
-
FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
|
|
92
|
-
nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
|
|
93
|
-
eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
|
|
94
|
-
hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
|
|
95
|
-
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
|
|
96
|
-
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
|
|
97
|
-
+OkuE6N36B9K
|
|
98
|
-
-----END CERTIFICATE-----
|