puppetdb_foreman 4.0.0 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -23
  3. data/Rakefile +9 -6
  4. data/app/controllers/api/v2/puppetdb_nodes_controller.rb +8 -6
  5. data/app/controllers/puppetdb_foreman/nodes_controller.rb +32 -7
  6. data/app/helpers/concerns/puppetdb_foreman/hosts_helper_extensions.rb +28 -0
  7. data/app/models/concerns/orchestration/puppetdb.rb +13 -6
  8. data/app/models/puppetdb_foreman/host_extensions.rb +5 -4
  9. data/app/services/puppetdb.rb +8 -12
  10. data/app/services/puppetdb_client/base.rb +12 -6
  11. data/app/services/puppetdb_client/v4.rb +48 -1
  12. data/app/services/puppetdb_host.rb +5 -3
  13. data/app/views/api/v2/puppetdb_nodes/import.json.rabl +2 -0
  14. data/app/views/api/v2/puppetdb_nodes/index.json.rabl +2 -0
  15. data/app/views/api/v2/puppetdb_nodes/unknown.json.rabl +2 -0
  16. data/app/views/puppetdb_foreman/nodes/index.html.erb +1 -0
  17. data/app/views/puppetdb_foreman/nodes/show.html.erb +69 -0
  18. data/config/routes.rb +11 -11
  19. data/db/migrate/20170717140010_migrate_puppetdb_api_version_setting.rb +4 -2
  20. data/db/migrate/20181001113836_remove_puppetdb_dashboard_address_setting.puppetdb_foreman.rb +7 -0
  21. data/lib/puppetdb_foreman/engine.rb +58 -33
  22. data/lib/puppetdb_foreman/version.rb +3 -1
  23. data/lib/puppetdb_foreman.rb +2 -0
  24. data/lib/tasks/puppetdb_foreman_tasks.rake +4 -4
  25. data/test/controllers/api/v2/puppetdb_nodes_controller_test.rb +60 -55
  26. data/test/controllers/nodes_controller_test.rb +34 -9
  27. data/test/models/host_test.rb +5 -4
  28. data/test/static_fixtures/resources.json +41 -0
  29. data/test/test_plugin_helper.rb +2 -4
  30. data/test/unit/puppetdb_host_test.rb +5 -4
  31. data/test/unit/puppetdb_test.rb +34 -85
  32. metadata +20 -23
  33. data/app/controllers/puppetdb_foreman/puppetdb_controller.rb +0 -30
  34. data/app/models/setting/puppetdb.rb +0 -52
  35. data/app/services/puppetdb_client/v1.rb +0 -29
  36. data/app/services/puppetdb_client/v3.rb +0 -45
  37. data/app/views/puppetdb_foreman/puppetdb/error.html.erb +0 -6
  38. data/test/static_fixtures/query_nodes.json +0 -61
@@ -1,56 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_plugin_helper'
2
4
 
3
5
  class PuppetdbTest < ActiveSupport::TestCase
4
6
  setup do
5
7
  User.current = FactoryBot.build(:user, :admin)
6
- setup_settings
7
8
  disable_orchestration
8
9
  end
9
10
 
10
11
  let(:client) { Puppetdb.client }
11
12
  let(:uuid) { SecureRandom.uuid }
12
13
 
13
- context 'with V1 API' do
14
- setup do
15
- Setting[:puppetdb_api_version] = 1
16
- Setting[:puppetdb_address] = 'https://localhost:8080/v3/commands'
17
- end
18
-
19
- test 'deactivate_node' do
20
- stub_request(:post, 'https://localhost:8080/v3/commands')
21
- .with(:body => 'payload={"command":"deactivate node","version":1,"payload":"\\"www.example.com\\""}',
22
- :headers => { 'Accept' => 'application/json' })
23
- .to_return(:status => 200, :body => "{\"uuid\" : \"#{uuid}\"}", :headers => { 'Content-Type' => 'application/json; charset=utf-8' })
24
-
25
- assert_equal uuid, client.deactivate_node('www.example.com')
26
- end
27
-
28
- test 'query_nodes' do
29
- stub_request(:get, 'https://localhost:8080/v3/nodes')
30
- .with(:headers => { 'Accept' => 'application/json' })
31
- .to_return(:status => 200, :body => fixture('query_nodes.json'), :headers => { 'Content-Type' => 'application/json; charset=utf-8' })
32
- expected = (1..10).map { |i| "server#{i}.example.com" }
33
- assert_equal expected, client.query_nodes
34
- end
35
-
36
- test 'facts' do
37
- stub_request(:get, 'https://localhost:8080/v3/facts?query=%5B%22=%22,%20%22certname%22,%20%22host.example.com%22%5D')
38
- .with(:headers => { 'Accept' => 'application/json' })
39
- .to_return(:status => 200, :body => fixture('facts.json'), :headers => { 'Content-Type' => 'application/json; charset=utf-8' })
40
- facts = client.facts('host.example.com')
41
- assert_kind_of Array, facts
42
- sample = {
43
- 'value' => 'CEST',
44
- 'name' => 'timezone',
45
- 'certname' => 'host.example.com'
46
- }
47
- assert_includes facts, sample
48
- end
49
- end
50
-
51
- context 'with V3 API' do
14
+ context 'with V4 API' do
52
15
  setup do
53
- Setting[:puppetdb_api_version] = 3
16
+ Setting[:puppetdb_api_version] = 4
54
17
  end
55
18
 
56
19
  let(:producer_timestamp) { Time.now.iso8601.to_s }
@@ -59,72 +22,58 @@ class PuppetdbTest < ActiveSupport::TestCase
59
22
  client.stubs(:producer_timestamp).returns(producer_timestamp)
60
23
 
61
24
  stub_request(:post, 'https://puppetdb:8081/pdb/cmd/v1')
62
- .with(:body => "{\"command\":\"deactivate node\",\"version\":3,\"payload\":{\"certname\":\"www.example.com\",\"producer_timestamp\":\"#{producer_timestamp}\"}}",
63
- :headers => { 'Accept' => 'application/json', 'Content-Type' => 'application/json' })
64
- .to_return(:status => 200, :body => "{\"uuid\" : \"#{uuid}\"}", :headers => { 'Content-Type' => 'application/json; charset=utf-8' })
25
+ .with(
26
+ body: "{\"command\":\"deactivate node\",\"version\":3,\"payload\":{\"certname\":\"www.example.com\",\"producer_timestamp\":\"#{producer_timestamp}\"}}",
27
+ headers: {
28
+ 'Accept' => 'application/json',
29
+ 'Content-Type' => 'application/json',
30
+ }
31
+ )
32
+ .to_return(status: 200, body: "{\"uuid\" : \"#{uuid}\"}", headers: { 'Content-Type' => 'application/json; charset=utf-8' })
65
33
 
66
34
  assert_equal uuid, client.deactivate_node('www.example.com')
67
35
  end
68
36
 
69
37
  test 'query_nodes' do
70
38
  stub_request(:get, 'https://puppetdb:8081/pdb/query/v4/nodes')
71
- .with(:headers => { 'Accept' => 'application/json' })
72
- .to_return(:status => 200, :body => fixture('query_nodes_v3_4.json'), :headers => { 'Content-Type' => 'application/json; charset=utf-8' })
39
+ .with(headers: { 'Accept' => 'application/json' })
40
+ .to_return(status: 200, body: fixture('query_nodes_v3_4.json'), headers: { 'Content-Type' => 'application/json; charset=utf-8' })
73
41
  expected = (1..10).map { |i| "server#{i}.example.com" }
74
42
  assert_equal expected, client.query_nodes
75
43
  end
76
44
 
77
- test 'facts' do
78
- stub_request(:get, 'https://puppetdb:8081/pdb/query/v4/facts?query=%5B%22=%22,%20%22certname%22,%20%22host.example.com%22%5D')
79
- .with(:headers => { 'Accept' => 'application/json' })
80
- .to_return(:status => 200, :body => fixture('facts.json'), :headers => { 'Content-Type' => 'application/json; charset=utf-8' })
81
- facts = client.facts('host.example.com')
82
- assert_kind_of Array, facts
45
+ test 'resources' do
46
+ stub_request(:get, 'https://puppetdb:8081/pdb/query/v4/resources?query=%5B%22=%22,%20%22certname%22,%20%22host.example.com%22%5D')
47
+ .with(headers: { 'Accept' => 'application/json' })
48
+ .to_return(status: 200, body: fixture('resources.json'), headers: { 'Content-Type' => 'application/json; charset=utf-8' })
49
+
50
+ resources = client.resources('host.example.com')
83
51
  sample = {
84
- 'value' => 'CEST',
85
- 'name' => 'timezone',
86
- 'certname' => 'host.example.com'
52
+ 'tags' => %w[params class],
53
+ 'file' => nil,
54
+ 'type' => 'Class',
55
+ 'title' => 'Cron',
56
+ 'line' => nil,
57
+ 'resource' => 'f13ec266-2914-420c-8d71-13e3466c5856',
58
+ 'certname' => 'host.example.com',
59
+ 'parameters' => {},
60
+ 'exported' => false,
87
61
  }
88
- assert_includes facts, sample
89
- end
90
- end
91
-
92
- context 'with V4 API' do
93
- setup do
94
- Setting[:puppetdb_api_version] = 4
95
- end
96
62
 
97
- let(:producer_timestamp) { Time.now.iso8601.to_s }
98
-
99
- test 'deactivate_node' do
100
- client.stubs(:producer_timestamp).returns(producer_timestamp)
101
-
102
- stub_request(:post, 'https://puppetdb:8081/pdb/cmd/v1')
103
- .with(:body => "{\"command\":\"deactivate node\",\"version\":3,\"payload\":{\"certname\":\"www.example.com\",\"producer_timestamp\":\"#{producer_timestamp}\"}}",
104
- :headers => { 'Accept' => 'application/json', 'Content-Type' => 'application/json' })
105
- .to_return(:status => 200, :body => "{\"uuid\" : \"#{uuid}\"}", :headers => { 'Content-Type' => 'application/json; charset=utf-8' })
106
-
107
- assert_equal uuid, client.deactivate_node('www.example.com')
108
- end
109
-
110
- test 'query_nodes' do
111
- stub_request(:get, 'https://puppetdb:8081/pdb/query/v4/nodes')
112
- .with(:headers => { 'Accept' => 'application/json' })
113
- .to_return(:status => 200, :body => fixture('query_nodes_v3_4.json'), :headers => { 'Content-Type' => 'application/json; charset=utf-8' })
114
- expected = (1..10).map { |i| "server#{i}.example.com" }
115
- assert_equal expected, client.query_nodes
63
+ assert_kind_of Array, resources
64
+ assert_includes resources, sample
116
65
  end
117
66
 
118
67
  test 'facts' do
119
68
  stub_request(:get, 'https://puppetdb:8081/pdb/query/v4/facts?query=%5B%22=%22,%20%22certname%22,%20%22host.example.com%22%5D')
120
- .with(:headers => { 'Accept' => 'application/json' })
121
- .to_return(:status => 200, :body => fixture('facts.json'), :headers => { 'Content-Type' => 'application/json; charset=utf-8' })
69
+ .with(headers: { 'Accept' => 'application/json' })
70
+ .to_return(status: 200, body: fixture('facts.json'), headers: { 'Content-Type' => 'application/json; charset=utf-8' })
122
71
  facts = client.facts('host.example.com')
123
72
  assert_kind_of Array, facts
124
73
  sample = {
125
74
  'value' => 'CEST',
126
75
  'name' => 'timezone',
127
- 'certname' => 'host.example.com'
76
+ 'certname' => 'host.example.com',
128
77
  }
129
78
  assert_includes facts, sample
130
79
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puppetdb_foreman
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0
4
+ version: 6.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Lobato Garcia
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-15 00:00:00.000000000 Z
11
+ date: 2022-10-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -39,19 +39,19 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rubocop
42
+ name: theforeman-rubocop
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '='
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 0.52.0
47
+ version: 0.1.2
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '='
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 0.52.0
54
+ version: 0.1.2
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: webmock
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -66,10 +66,10 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
- description: 'Disable hosts on PuppetDB after they are deleted or built in Foreman,
70
- and proxy the PuppetDB dashboard to Foreman. Follow https://github.com/theforeman/puppetdb_foreman
71
- and raise an issue/submit a pull request if you need extra functionality. You can
72
- also find some help in #theforeman IRC channel on Freenode.'
69
+ description: 'Disable hosts on PuppetDB after they are deleted or built in Foreman.
70
+ Follow https://github.com/theforeman/puppetdb_foreman and raise an issue/submit
71
+ a pull request if you need extra functionality. You can also find some help in #theforeman
72
+ IRC channel on Freenode.'
73
73
  email: elobatocs@gmail.com
74
74
  executables: []
75
75
  extensions: []
@@ -80,23 +80,21 @@ files:
80
80
  - Rakefile
81
81
  - app/controllers/api/v2/puppetdb_nodes_controller.rb
82
82
  - app/controllers/puppetdb_foreman/nodes_controller.rb
83
- - app/controllers/puppetdb_foreman/puppetdb_controller.rb
83
+ - app/helpers/concerns/puppetdb_foreman/hosts_helper_extensions.rb
84
84
  - app/models/concerns/orchestration/puppetdb.rb
85
85
  - app/models/puppetdb_foreman/host_extensions.rb
86
- - app/models/setting/puppetdb.rb
87
86
  - app/services/puppetdb.rb
88
87
  - app/services/puppetdb_client/base.rb
89
- - app/services/puppetdb_client/v1.rb
90
- - app/services/puppetdb_client/v3.rb
91
88
  - app/services/puppetdb_client/v4.rb
92
89
  - app/services/puppetdb_host.rb
93
90
  - app/views/api/v2/puppetdb_nodes/import.json.rabl
94
91
  - app/views/api/v2/puppetdb_nodes/index.json.rabl
95
92
  - app/views/api/v2/puppetdb_nodes/unknown.json.rabl
96
93
  - app/views/puppetdb_foreman/nodes/index.html.erb
97
- - app/views/puppetdb_foreman/puppetdb/error.html.erb
94
+ - app/views/puppetdb_foreman/nodes/show.html.erb
98
95
  - config/routes.rb
99
96
  - db/migrate/20170717140010_migrate_puppetdb_api_version_setting.rb
97
+ - db/migrate/20181001113836_remove_puppetdb_dashboard_address_setting.puppetdb_foreman.rb
100
98
  - lib/puppetdb_foreman.rb
101
99
  - lib/puppetdb_foreman/engine.rb
102
100
  - lib/puppetdb_foreman/version.rb
@@ -105,8 +103,8 @@ files:
105
103
  - test/controllers/nodes_controller_test.rb
106
104
  - test/models/host_test.rb
107
105
  - test/static_fixtures/facts.json
108
- - test/static_fixtures/query_nodes.json
109
106
  - test/static_fixtures/query_nodes_v3_4.json
107
+ - test/static_fixtures/resources.json
110
108
  - test/test_plugin_helper.rb
111
109
  - test/unit/puppetdb_host_test.rb
112
110
  - test/unit/puppetdb_test.rb
@@ -114,7 +112,7 @@ homepage: http://www.github.com/theforeman/puppetdb_foreman
114
112
  licenses:
115
113
  - GPL-3.0
116
114
  metadata: {}
117
- post_install_message:
115
+ post_install_message:
118
116
  rdoc_options: []
119
117
  require_paths:
120
118
  - lib
@@ -129,9 +127,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
129
127
  - !ruby/object:Gem::Version
130
128
  version: '0'
131
129
  requirements: []
132
- rubyforge_project:
133
- rubygems_version: 2.7.3
134
- signing_key:
130
+ rubygems_version: 3.3.7
131
+ signing_key:
135
132
  specification_version: 4
136
133
  summary: This is a Foreman plugin to interact with PuppetDB.
137
134
  test_files:
@@ -139,8 +136,8 @@ test_files:
139
136
  - test/controllers/nodes_controller_test.rb
140
137
  - test/models/host_test.rb
141
138
  - test/static_fixtures/facts.json
142
- - test/static_fixtures/query_nodes.json
143
139
  - test/static_fixtures/query_nodes_v3_4.json
140
+ - test/static_fixtures/resources.json
144
141
  - test/test_plugin_helper.rb
145
142
  - test/unit/puppetdb_host_test.rb
146
143
  - test/unit/puppetdb_test.rb
@@ -1,30 +0,0 @@
1
- module PuppetdbForeman
2
- class PuppetdbController < ApplicationController
3
- protect_from_forgery :except => :index
4
-
5
- def index
6
- uri = URI.parse(Setting[:puppetdb_dashboard_address])
7
- puppetdb_url, layout = case params[:puppetdb]
8
- when 'd3.v2', 'charts' then ["#{uri.path}#{request.original_fullpath}", false]
9
- when 'v3', 'metrics', 'pdb/meta/v1/version', 'pdb/meta/v1/version/latest', 'pdb/dashboard/data' then [request.original_fullpath, false]
10
- else ["#{uri.path}/index.html", true]
11
- end
12
- result = Net::HTTP.get_response(uri.host, puppetdb_url, uri.port)
13
- render :text => result.body, :layout => layout
14
- rescue SocketError
15
- @proxy_error = "Problem connecting to host #{uri.host} on port #{uri.port}"
16
- render :action => :error, :layout => true
17
- rescue Errno::ECONNREFUSED
18
- @proxy_error = "#{uri.host} refused our connection"
19
- render :action => :error, :layout => true
20
- rescue EOFError
21
- @proxy_error = "Don't use ssl (https)"
22
- render :action => :error, :layout => true
23
- end
24
-
25
- # Override from application controller to fix issue
26
- def api_request?
27
- request.format && (request.format.json? || request.format.yaml?)
28
- end
29
- end
30
- end
@@ -1,52 +0,0 @@
1
- class Setting::Puppetdb < ::Setting
2
- BLANK_ATTRS << 'puppetdb_address'
3
- BLANK_ATTRS << 'puppetdb_ssl_ca_file'
4
- BLANK_ATTRS << 'puppetdb_ssl_certificate'
5
- BLANK_ATTRS << 'puppetdb_ssl_private_key'
6
- BLANK_ATTRS << 'puppetdb_api_version'
7
-
8
- def self.default_settings
9
- if SETTINGS[:puppetdb].present?
10
- default_enabled = SETTINGS[:puppetdb][:enabled]
11
- default_address = SETTINGS[:puppetdb][:address]
12
- default_dashboard_address = SETTINGS[:puppetdb][:dashboard_address]
13
- default_ssl_ca_file = SETTINGS[:puppetdb][:ssl_ca_file]
14
- default_ssl_certificate = SETTINGS[:puppetdb][:ssl_certificate]
15
- default_ssl_private_key = SETTINGS[:puppetdb][:ssl_private_key]
16
- default_api_version = SETTINGS[:puppetdb][:api_version]
17
- end
18
-
19
- default_enabled = false if default_enabled.nil?
20
- default_address ||= 'https://puppetdb:8081/pdb/cmd/v1'
21
- default_dashboard_address ||= 'http://puppetdb:8080/pdb/dashboard'
22
- default_ssl_ca_file ||= (SETTINGS[:ssl_ca_file]).to_s
23
- default_ssl_certificate ||= (SETTINGS[:ssl_certificate]).to_s
24
- default_ssl_private_key ||= (SETTINGS[:ssl_priv_key]).to_s
25
- default_api_version ||= 4
26
-
27
- [
28
- set('puppetdb_enabled', _("Integration with PuppetDB, enabled will deactivate a host in PuppetDB when it's deleted in Foreman"), default_enabled),
29
- set('puppetdb_address', _('Foreman will send PuppetDB requests to this address'), default_address),
30
- set('puppetdb_dashboard_address', _('Foreman will proxy PuppetDB Performance Dashboard requests to this address'), default_dashboard_address),
31
- set('puppetdb_ssl_ca_file', _('Foreman will send PuppetDB requests with this CA file'), default_ssl_ca_file),
32
- set('puppetdb_ssl_certificate', _('Foreman will send PuppetDB requests with this certificate file'), default_ssl_certificate),
33
- set('puppetdb_ssl_private_key', _('Foreman will send PuppetDB requests with this key file'), default_ssl_private_key),
34
- set('puppetdb_api_version', _('Foreman will use this PuppetDB API version'), default_api_version, N_('PuppetDB API Version'), nil, collection: proc { ::Puppetdb::API_VERSIONS })
35
- ]
36
- end
37
-
38
- def self.load_defaults
39
- # Check the table exists
40
- return unless super
41
-
42
- transaction do
43
- default_settings.each { |s| create! s.update(:category => 'Setting::Puppetdb') }
44
- end
45
-
46
- true
47
- end
48
-
49
- def self.humanized_category
50
- N_('PuppetDB')
51
- end
52
- end
@@ -1,29 +0,0 @@
1
- module PuppetdbClient
2
- class V1 < Base
3
- # The payload is expected to be the certname of a node as a serialized JSON string.
4
- def deactivate_node_payload(nodename)
5
- payload = {
6
- 'command' => 'deactivate node',
7
- 'version' => 1,
8
- 'payload' => nodename.to_json
9
- }.to_json
10
- 'payload=' + payload
11
- end
12
-
13
- def command_url
14
- '/v3/commands'
15
- end
16
-
17
- def nodes_url
18
- '/v3/nodes'
19
- end
20
-
21
- def facts_url
22
- '/v3/facts'
23
- end
24
-
25
- def query_nodes
26
- super.map { |node| node['name'] }
27
- end
28
- end
29
- end
@@ -1,45 +0,0 @@
1
- module PuppetdbClient
2
- class V3 < Base
3
- # The payload is formatted as a JSON map.
4
- # certname: The name of the node for which the catalog was compiled.
5
- # producer_timestamp: The time of command submission.
6
- def deactivate_node_payload(nodename)
7
- {
8
- 'command' => 'deactivate node',
9
- 'version' => 3,
10
- 'payload' => {
11
- 'certname' => nodename,
12
- 'producer_timestamp' => producer_timestamp
13
- }
14
- }.to_json
15
- end
16
-
17
- def command_url
18
- '/pdb/cmd/v1'
19
- end
20
-
21
- def nodes_url
22
- '/pdb/query/v4/nodes'
23
- end
24
-
25
- def facts_url
26
- '/pdb/query/v4/facts'
27
- end
28
-
29
- def query_nodes
30
- super.map { |node| node['certname'] }
31
- end
32
-
33
- private
34
-
35
- def post_options
36
- {
37
- content_type: :json
38
- }
39
- end
40
-
41
- def producer_timestamp
42
- Time.now.iso8601.to_s
43
- end
44
- end
45
- end
@@ -1,6 +0,0 @@
1
- <%= alert(:class => 'alert-warning',
2
- :text => _("Error proxying PuppetDB Dashboard: #{@proxy_error}.") +
3
- ' ' + _('Maybe you need to set ') +
4
- link_to(_('puppetdb_dashboard_address'),
5
- settings_path(:search => 'puppetdb_dashboard_address')) +
6
- _(' in Settings')) %>
@@ -1,61 +0,0 @@
1
- [ {
2
- "name" : "server1.example.com",
3
- "deactivated" : null,
4
- "catalog_timestamp" : "2017-04-20T15:07:27.114Z",
5
- "facts_timestamp" : "2017-04-20T15:06:52.738Z",
6
- "report_timestamp" : null
7
- }, {
8
- "name" : "server2.example.com",
9
- "deactivated" : null,
10
- "catalog_timestamp" : "2017-04-20T15:06:28.282Z",
11
- "facts_timestamp" : "2017-04-20T15:06:12.253Z",
12
- "report_timestamp" : null
13
- }, {
14
- "name" : "server3.example.com",
15
- "deactivated" : null,
16
- "catalog_timestamp" : "2017-04-20T15:12:56.090Z",
17
- "facts_timestamp" : "2017-04-20T15:12:32.117Z",
18
- "report_timestamp" : null
19
- }, {
20
- "name" : "server4.example.com",
21
- "deactivated" : null,
22
- "catalog_timestamp" : "2017-04-20T15:04:01.154Z",
23
- "facts_timestamp" : "2017-04-20T15:03:38.150Z",
24
- "report_timestamp" : null
25
- }, {
26
- "name" : "server5.example.com",
27
- "deactivated" : null,
28
- "catalog_timestamp" : "2017-04-20T15:20:06.853Z",
29
- "facts_timestamp" : "2017-04-20T15:19:49.088Z",
30
- "report_timestamp" : null
31
- }, {
32
- "name" : "server6.example.com",
33
- "deactivated" : null,
34
- "catalog_timestamp" : "2017-04-20T15:21:11.520Z",
35
- "facts_timestamp" : "2017-04-20T15:20:57.685Z",
36
- "report_timestamp" : null
37
- }, {
38
- "name" : "server7.example.com",
39
- "deactivated" : null,
40
- "catalog_timestamp" : "2017-04-20T15:15:37.033Z",
41
- "facts_timestamp" : "2017-04-20T15:15:13.918Z",
42
- "report_timestamp" : null
43
- }, {
44
- "name" : "server8.example.com",
45
- "deactivated" : null,
46
- "catalog_timestamp" : "2017-04-20T15:19:18.236Z",
47
- "facts_timestamp" : "2017-04-20T15:19:02.659Z",
48
- "report_timestamp" : null
49
- }, {
50
- "name" : "server9.example.com",
51
- "deactivated" : null,
52
- "catalog_timestamp" : "2017-04-20T14:39:35.070Z",
53
- "facts_timestamp" : "2017-04-20T14:39:19.003Z",
54
- "report_timestamp" : null
55
- }, {
56
- "name" : "server10.example.com",
57
- "deactivated" : null,
58
- "catalog_timestamp" : "2017-04-20T15:17:06.209Z",
59
- "facts_timestamp" : "2017-04-20T15:16:50.007Z",
60
- "report_timestamp" : null
61
- } ]