logstream 0.0.8 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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-----
|