hammer_cli_foreman_host_reports 0.1.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.
@@ -0,0 +1,26 @@
1
+ # Data for tests
2
+
3
+ ## How to include API tests for new Foreman release
4
+ 1. on the **Foreman instance** run the tests with recording of examples turned on
5
+
6
+ ```bash
7
+ $ APIPIE_RECORD=examples bundle exec rake test:functionals
8
+ ```
9
+ 1. on the **Foreman instance** generate API documentation cache. It will land in `/usr/share/foreman/public/apipie-cache/apidoc/v2.en.json`
10
+
11
+ ```bash
12
+ $ FOREMAN_APIPIE_LANGS=en foreman-rake apipie:cache
13
+ ```
14
+ 1. when running from **git**, run a similar command and it will land in `$FOREMAN_CHECKOUT/public/apipie-cache/apidoc/v2.en.json`
15
+
16
+ ```bash
17
+ $ FOREMAN_APIPIE_LANGS=en bundle exec rake apipie:cache
18
+ ```
19
+ 1. in **hammer-cli-foreman** in `test/data/` Create directory with name matching the Foreman version in `test/data/` (e.g. `test/data/3.2`)
20
+ 1. copy the API cache from the Foreman instance into the newly created directory and name it as `foreman_api.json`
21
+ 1. update the following line in `test/test_helper.rb` to match the new default Foreman version
22
+
23
+ ```ruby
24
+ FOREMAN_VERSION = Gem::Version.new(ENV['TEST_API_VERSION'] || '3.2')
25
+ ```
26
+ 1. make sure the tests are green
@@ -0,0 +1,309 @@
1
+ module ResourceMocks
2
+
3
+ def self.mock_action_call(resource, action, value, params=:default)
4
+ response = ApipieBindings::Example.new('GET', '/', '', 200, JSON.dump(value))
5
+ @mocks ||= {}
6
+ @mocks[[resource, action]] ||= {}
7
+ @mocks[[resource, action]][params] = response
8
+ ApipieBindings::API.any_instance.stubs(:fake_responses).returns(@mocks)
9
+ end
10
+
11
+ def self.clear_mocks
12
+ @mocks = {}
13
+ ApipieBindings::API.any_instance.stubs(:fake_responses).returns(@mocks)
14
+ end
15
+
16
+ def self.mock_action_calls(*calls)
17
+ calls.each do |(resource, action, value, params)|
18
+ mock_action_call(resource, action, value, (params || :default))
19
+ end
20
+ end
21
+
22
+ def self.smart_variables_index
23
+ ResourceMocks.mock_action_call(:smart_variables, :index,
24
+ { "results" => [ { 'variable' => 'var', 'id' => '1'} ] })
25
+ end
26
+
27
+ def self.smart_variables_show
28
+ ResourceMocks.mock_action_call(:smart_variables, :show, { "id" => 1, "override_value_order" => "fqdn" })
29
+ end
30
+
31
+ def self.compute_resources_available_images
32
+ ResourceMocks.mock_action_call(:compute_resources, :available_images, [])
33
+ end
34
+
35
+ def self.compute_resources_available_networks
36
+ ResourceMocks.mock_action_call(:compute_resources, :available_networks, [])
37
+ end
38
+
39
+ def self.compute_resources_available_clusters
40
+ ResourceMocks.mock_action_call(:compute_resources, :available_clusters, [])
41
+ end
42
+
43
+ def self.organizations_index
44
+ ResourceMocks.mock_action_call(:organizations, :index, {
45
+ "results" => [
46
+ {
47
+ "label" => "Default_Organization",
48
+ "id" => 1,
49
+ "name" => "Default_Organization",
50
+ "title" => "Default_Organization"
51
+ }
52
+ ]})
53
+ end
54
+
55
+ def self.users_show
56
+ ResourceMocks.mock_action_call(:users, :show, {
57
+ "firstname" => "Admin",
58
+ "lastname" => "User",
59
+ "mail" => "root@example.com",
60
+ "admin" => true,
61
+ "auth_source_id" => 1,
62
+ "auth_source_name" => "Internal",
63
+ "timezone" => nil,
64
+ "locale" => nil,
65
+ "last_login_on" => "2016-12-20 17:30:13 UTC",
66
+ "created_at" => "2016-10-24 08:11:24 UTC",
67
+ "updated_at" => "2016-10-24 08:11:38 UTC",
68
+ "id" => 3,
69
+ "login" => "admin",
70
+ "description" => nil,
71
+ "default_location" => nil,
72
+ "locations" => [],
73
+ "default_organization" => {
74
+ "id" => 1,
75
+ "name" => "Default Organization",
76
+ "title" => "Default Organization",
77
+ "description" => nil
78
+ },
79
+ "organizations" => [],
80
+ "effective_admin" => true,
81
+ "cached_usergroups" => [],
82
+ "auth_source_internal" => {
83
+ "id" => 1,
84
+ "type" => "AuthSourceInternal",
85
+ "name" => "Internal"
86
+ },
87
+ "mail_notifications" => [],
88
+ "roles" => [{
89
+ "name" => "Default role",
90
+ "id" => 9,
91
+ "description" => nil
92
+ }],
93
+ "usergroups" => []
94
+ })
95
+ end
96
+
97
+ def self.hosts_show
98
+ ResourceMocks.mock_action_call(:hosts, :show, {
99
+ "ip" => "192.168.122.51",
100
+ "ip6" => nil,
101
+ "last_report" => "2016-10-24 12:06:31 UTC",
102
+ "mac" => "52:54:00:ce:b2:b9",
103
+ "realm_id" => nil,
104
+ "realm_name" => nil,
105
+ "sp_mac" => nil,
106
+ "sp_ip" => nil,
107
+ "sp_name" => nil,
108
+ "domain_id" => 1,
109
+ "domain_name" => "tstrachota.usersys.redhat.com",
110
+ "architecture_id" => 1,
111
+ "architecture_name" => "x86_64",
112
+ "operatingsystem_id" => 1,
113
+ "operatingsystem_name" => "CentOS 7.2.1511",
114
+ "build" => false,
115
+ "model_id" => 1,
116
+ "hostgroup_id" => nil,
117
+ "owner_id" => nil,
118
+ "owner_type" => nil,
119
+ "enabled" => true,
120
+ "managed" => false,
121
+ "use_image" => nil,
122
+ "image_file" => "",
123
+ "uuid" => nil,
124
+ "compute_resource_id" => nil,
125
+ "compute_resource_name" => nil,
126
+ "compute_profile_id" => nil,
127
+ "compute_profile_name" => nil,
128
+ "capabilities" => ["build"],
129
+ "provision_method" => "build",
130
+ "certname" => "foreman.example.com",
131
+ "image_id" => nil,
132
+ "image_name" => nil,
133
+ "created_at" => "2016-10-24 08:36:43 UTC",
134
+ "updated_at" => "2016-10-24 12:06:46 UTC",
135
+ "last_compile" => "2016-10-24 12:06:41 UTC",
136
+ "global_status" => 0,
137
+ "global_status_label" => "Warning",
138
+ "organization_id" => nil,
139
+ "organization_name" => nil,
140
+ "location_id" => nil,
141
+ "location_name" => nil,
142
+ "model_name" => "KVM",
143
+ "configuration_status" => 0,
144
+ "configuration_status_label" => "No reports",
145
+ "name" => "foreman.example.com",
146
+ "id" => 1,
147
+ "hostgroup_name" => nil,
148
+ "hostgroup_title" => nil,
149
+ "parameters" => [],
150
+ "all_parameters" => [],
151
+ "interfaces" => [{
152
+ "id" => 1,
153
+ "name" => "foreman.example.com",
154
+ "ip" => "192.168.122.51",
155
+ "mac" => "52:54:00:ce:b2:b9",
156
+ "identifier" => "eth0",
157
+ "primary" => true,
158
+ "provision" => true,
159
+ "type" => "interface"
160
+ },
161
+ {
162
+ "id" => 2,
163
+ "name" => nil,
164
+ "ip" => "10.34.130.105",
165
+ "mac" => "52:54:00:f5:1b:57",
166
+ "identifier" => "eth1",
167
+ "primary" => false,
168
+ "provision" => false,
169
+ "type" => "interface"
170
+ }]
171
+ })
172
+ end
173
+
174
+
175
+ def self.organizations_show
176
+ ResourceMocks.mock_action_calls(
177
+ [:organizations, :index, [{ "id" => 2, "name" => "ACME" }]],
178
+ [:organizations, :show, { "id" => 2, "name" => "ACME" }]
179
+ )
180
+ end
181
+
182
+ def self.locations_index
183
+ ResourceMocks.mock_action_call(:locations, :index, {
184
+ "results" => [
185
+ {
186
+ "ancestry" => nil,
187
+ "created_at" => "2014-07-17T17:21:49+02:00",
188
+ "updated_at" => "2015-06-17T13:18:10+02:00",
189
+ "id" => 2,
190
+ "name" => "Default_Location",
191
+ "title" => "Default_Location"
192
+ }
193
+ ]})
194
+ end
195
+
196
+ def self.locations_show
197
+ ResourceMocks.mock_action_calls(
198
+ [:locations, :index, [{ "id" => 2, "name" => "Rack" }]],
199
+ [:locations, :show, { "id" => 2, "name" => "Rack" }]
200
+ )
201
+ end
202
+
203
+ def self.operatingsystems
204
+ ResourceMocks.mock_action_calls(
205
+ [:parameters, :index, []],
206
+ [:operatingsystems, :index, []],
207
+ [:operatingsystems, :show, {}]
208
+ )
209
+ end
210
+
211
+ def self.bookmarks
212
+ ResourceMocks.mock_action_calls(
213
+ [:bookmarks, :index, []],
214
+ [:bookmarks, :show, {}]
215
+ )
216
+ end
217
+
218
+ def self.mail_notifications
219
+ ResourceMocks.mock_action_calls(
220
+ [:mail_notifications, :index, []],
221
+ [:mail_notifications, :show, {}]
222
+ )
223
+ end
224
+
225
+ def self.compute_profiles
226
+ ResourceMocks.mock_action_calls(
227
+ [:compute_profiles, :index, []],
228
+ [:compute_profiles, :show, {}]
229
+ )
230
+ end
231
+
232
+ def self.parameters_index
233
+ ResourceMocks.mock_action_call(:parameters, :index, [])
234
+ end
235
+
236
+ def self.facts_index
237
+ ResourceMocks.mock_action_call(:fact_values, :index, {
238
+ "total"=>5604,
239
+ "subtotal"=>0,
240
+ "page"=>1,
241
+ "per_page"=>20,
242
+ "search"=>"",
243
+ "sort" => {
244
+ "by" => nil,
245
+ "order" => nil
246
+ },
247
+ "results"=>[{
248
+ "some.host.com" => {
249
+ "network_br180"=>"10.32.83.0",
250
+ "mtu_usb0"=>"1500",
251
+ "physicalprocessorcount"=>"1",
252
+ "rubyversion"=>"1.8.7"
253
+ }
254
+ }]
255
+ })
256
+ end
257
+
258
+ def self.auth_source_ldap_index
259
+ ResourceMocks.mock_action_call(:auth_source_ldaps, :index, {
260
+ 'results' => [{
261
+ 'name' => 'my LDAP',
262
+ 'id' => 1,
263
+ 'tls' => false,
264
+ 'port' => 389,
265
+ 'server_type' => 'POSIX'
266
+ }]
267
+ })
268
+ end
269
+
270
+ def self.auth_source_external_index
271
+ ResourceMocks.mock_action_call(:auth_source_externals, :index, {
272
+ 'results' => [{
273
+ 'id' => 11,
274
+ 'name' => 'External',
275
+ 'locations' => [{
276
+ 'id' => 2,
277
+ 'name' => 'Default Location',
278
+ 'title' => 'Default Location',
279
+ 'description' => nil
280
+ }],
281
+ 'organizations' => [{
282
+ 'id' => 1,
283
+ 'name' => 'Default Organization',
284
+ 'title' => 'Default Organization',
285
+ 'description' => nil
286
+ }]
287
+ }]
288
+ })
289
+ end
290
+
291
+ def self.compute_resource_show
292
+ cr = {
293
+ "name" => "My compute resource",
294
+ "id" => 42,
295
+ "provider" => "Libvirt"
296
+ }
297
+ ResourceMocks.mock_action_calls(
298
+ [:compute_resources, :index, [ "results" => cr ]],
299
+ [:compute_resources, :show, cr]
300
+ )
301
+ end
302
+
303
+ def self.common_parameter_list
304
+ ResourceMocks.mock_action_call(:common_parameters, :index, [{
305
+ "name" => "my param",
306
+ "value" => "random value",
307
+ }])
308
+ end
309
+ end
@@ -0,0 +1,211 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ describe 'host report' do
4
+ describe 'list' do
5
+ let(:cmd) { %w[host-report list] }
6
+ let(:params) { ['--host=host.example.com'] }
7
+ let(:host1_report_ansible) do
8
+ {
9
+ id: 1,
10
+ host_name: 'host.example.com',
11
+ format: 'ansible',
12
+ reported_at: '01/12/2021',
13
+ change: 1,
14
+ nochange: 2,
15
+ failure: 1
16
+ }
17
+ end
18
+ let(:host1_report_puppet) do
19
+ {
20
+ id: 2,
21
+ host_name: 'host.example.com',
22
+ format: 'puppet',
23
+ reported_at: '01/12/2021',
24
+ change: 1,
25
+ nochange: 2,
26
+ failure: 1
27
+ }
28
+ end
29
+ let(:host2_report_puppet) do
30
+ {
31
+ id: 3,
32
+ host_name: 'host2.example.com',
33
+ format: 'puppet',
34
+ reported_at: '01/12/2021',
35
+ change: 5,
36
+ nochange: 2,
37
+ failure: 1
38
+ }
39
+ end
40
+
41
+ it 'lists all host reports' do
42
+ api_expects(:host_reports, :index, 'Host report list').with_params(
43
+ 'page' => 1, 'per_page' => 1000
44
+ ).returns(index_response([host1_report_puppet, host1_report_ansible, host2_report_puppet]))
45
+
46
+ output = IndexMatcher.new(
47
+ [
48
+ ['ID', 'HOST', 'REPORTED AT', 'FORMAT', 'CHANGE', 'NO CHANGE', 'FAILURE'],
49
+ ['1', 'host.example.com', '2021/12/01 00:00:00', 'ansible', '1', '2', '1'],
50
+ ['2', 'host.example.com', '2021/12/01 00:00:00', 'puppet', '1', '2', '1'],
51
+ ['3', 'host2.example.com', '2021/12/01 00:00:00', 'puppet', '5', '2', '1']
52
+ ]
53
+ )
54
+ expected_result = success_result(output)
55
+
56
+ result = run_cmd(cmd)
57
+ assert_cmd(expected_result, result)
58
+ end
59
+
60
+ it 'lists all host reports for a given host' do
61
+ api_expects(:hosts, :index, 'Host list').with_params(
62
+ 'search' => 'name = "host.example.com"'
63
+ ).returns(index_response([{ 'id' => 1 }]))
64
+ api_expects(:host_reports, :index, 'Host report list').with_params(
65
+ 'host_id' => 1, 'page' => 1, 'per_page' => 1000
66
+ ).returns(index_response([host1_report_puppet, host1_report_ansible]))
67
+
68
+ output = IndexMatcher.new(
69
+ [
70
+ ['ID', 'HOST', 'REPORTED AT', 'FORMAT', 'CHANGE', 'NO CHANGE', 'FAILURE'],
71
+ ['1', 'host.example.com', '2021/12/01 00:00:00', 'ansible', '1', '2', '1'],
72
+ ['2', 'host.example.com', '2021/12/01 00:00:00', 'puppet', '1', '2', '1']
73
+ ]
74
+ )
75
+ expected_result = success_result(output)
76
+
77
+ result = run_cmd(cmd + params)
78
+ assert_cmd(expected_result, result)
79
+ end
80
+ end
81
+
82
+ describe 'create' do
83
+ let(:cmd) { %w[host-report create] }
84
+ let(:params) do
85
+ [
86
+ '--host=new.example.com', '--reported-at=01/12/2021', '--body=""',
87
+ '--format=ansible', '--change=5', '--nochange=2', '--failure=1'
88
+ ]
89
+ end
90
+ let(:new_host_report) do
91
+ {
92
+ id: 1,
93
+ host_id: 1,
94
+ format: 'ansible',
95
+ host_name: 'new.example.com',
96
+ reported_at: '01/12/2021',
97
+ body: nil,
98
+ change: 5,
99
+ failure: 1,
100
+ nochange: 2
101
+ }
102
+ end
103
+
104
+ it 'requires minimal parameters' do
105
+ api_expects_no_call
106
+
107
+ expected_result = "Could not create the host report:\n" \
108
+ " Missing arguments for '--host', '--reported-at', '--body'.\n"
109
+
110
+ result = run_cmd(cmd)
111
+ assert_match(expected_result, result.err)
112
+ end
113
+
114
+ it 'creates a new host report' do
115
+ api_expects(:host_reports, :create).with_params(
116
+ 'host_report' => {
117
+ 'reported_at' => '01/12/2021', 'host' => 'new.example.com',
118
+ 'body' => '""', 'change' => 5, 'format' => 'ansible', 'nochange' => 2,
119
+ 'failure' => 1
120
+ }
121
+ ).returns(new_host_report)
122
+
123
+ expected_result = success_result("Host report created.\n")
124
+
125
+ result = run_cmd(cmd + params)
126
+ assert_cmd(expected_result, result)
127
+ end
128
+ end
129
+
130
+ describe 'info' do
131
+ let(:cmd) { %w[host-report info] }
132
+ let(:params) { ['--id=1'] }
133
+ let(:body) do
134
+ {
135
+ 'environment' => 'Development',
136
+ 'format' => 'puppet',
137
+ 'logs' => [
138
+ %w[notice resource message],
139
+ %w[err resource message]
140
+ ]
141
+ }
142
+ end
143
+ let(:full_host_report) do
144
+ {
145
+ id: 1,
146
+ host_id: 1,
147
+ host_name: 'full.example.com',
148
+ proxy_id: 1,
149
+ proxy_name: 'proxy.example.com',
150
+ format: 'puppet',
151
+ reported_at: '01/12/2021',
152
+ body: body.to_json,
153
+ change: 5,
154
+ failure: 1,
155
+ nochange: 2,
156
+ keywords: %w[HasChange PuppetHasChange]
157
+ }
158
+ end
159
+
160
+ it 'shows the host report' do
161
+ api_expects(:host_reports, :show, 'Show host report').with_params(
162
+ 'id' => '1'
163
+ ).returns(full_host_report.transform_keys(&:to_s))
164
+
165
+ output = OutputMatcher.new(
166
+ [
167
+ 'Id: 1',
168
+ 'Host: full.example.com',
169
+ 'Host id: 1',
170
+ 'Proxy: proxy.example.com',
171
+ 'Proxy id: 1',
172
+ 'Keywords: HasChange, PuppetHasChange',
173
+ 'Reported at: 2021/12/01 00:00:00',
174
+ 'Format: Puppet',
175
+ 'Puppet environment: Development',
176
+ 'Summary:',
177
+ ' Change: 5',
178
+ ' No change: 2',
179
+ ' Failure: 1',
180
+ 'Logs:',
181
+ ' 1) Level: notice',
182
+ ' Resource: resource',
183
+ ' Message: message',
184
+ ' 2) Level: err',
185
+ ' Resource: resource',
186
+ ' Message: message'
187
+ ]
188
+ )
189
+
190
+ expected_result = success_result(output)
191
+
192
+ result = run_cmd(cmd + params)
193
+ assert_cmd(expected_result, result)
194
+ end
195
+ end
196
+
197
+ describe 'delete' do
198
+ let(:cmd) { %w[host-report delete] }
199
+ let(:params) { ['--id=1'] }
200
+ it 'deletes the host report' do
201
+ api_expects(:host_reports, :destroy, 'Delete host report').with_params(
202
+ 'id' => '1'
203
+ )
204
+
205
+ expected_result = success_result("Host report deleted.\n")
206
+
207
+ result = run_cmd(cmd + params)
208
+ assert_cmd(expected_result, result)
209
+ end
210
+ end
211
+ end
@@ -0,0 +1,11 @@
1
+ require File.join(File.dirname(__FILE__), '../test_helper')
2
+
3
+ require 'hammer_cli/testing/output_matchers'
4
+ require 'hammer_cli/testing/command_assertions'
5
+ require 'hammer_cli/testing/data_helpers'
6
+ require 'hammer_cli_foreman/testing/api_expectations'
7
+
8
+ include HammerCLI::Testing::OutputMatchers
9
+ include HammerCLI::Testing::CommandAssertions
10
+ include HammerCLI::Testing::DataHelpers
11
+ include HammerCLIForeman::Testing::APIExpectations
@@ -0,0 +1,18 @@
1
+ ENV['TEST_API_VERSION'] = ENV['TEST_API_VERSION'] || '3.2'
2
+ FOREMAN_HOST_REPORTS_VERSION = Gem::Version.new(ENV['TEST_API_VERSION']).to_s
3
+
4
+ require 'minitest/autorun'
5
+ require 'minitest/spec'
6
+ require 'minitest-spec-context'
7
+ require 'mocha/minitest'
8
+ require 'hammer_cli'
9
+
10
+ HammerCLI.context[:api_connection].create('foreman') do
11
+ HammerCLI::Apipie::ApiConnection.new(
12
+ apidoc_cache_dir: 'test/data/' + FOREMAN_HOST_REPORTS_VERSION,
13
+ apidoc_cache_name: 'foreman_api',
14
+ dry_run: true
15
+ )
16
+ end
17
+
18
+ require 'hammer_cli_foreman_host_reports'
@@ -0,0 +1,47 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ describe HammerCLIForemanHostReports::HostReport do
4
+ include ::CommandTestHelper
5
+
6
+ context 'ListCommand' do
7
+ before do
8
+ ResourceMocks.mock_action_call(:host_reports, :index, [])
9
+ end
10
+
11
+ let(:cmd) { HammerCLIForemanHostReports::HostReport::ListCommand.new('', ctx) }
12
+
13
+ context 'parameters' do
14
+ it_should_accept 'no arguments'
15
+ it_should_accept_search_params
16
+ end
17
+
18
+ context 'output' do
19
+ let(:expected_record_count) { count_records(cmd.resource.call(:index)) }
20
+
21
+ it_should_print_n_records
22
+ it_should_print_column 'Id'
23
+ it_should_print_column 'Host'
24
+ it_should_print_column 'Format'
25
+ it_should_print_column 'Reported at'
26
+ it_should_print_column 'Change'
27
+ it_should_print_column 'No change'
28
+ it_should_print_column 'Failure'
29
+ end
30
+ end
31
+
32
+ context 'InfoCommand' do
33
+ let(:cmd) { HammerCLIForemanHostReports::HostReport::InfoCommand.new('', ctx) }
34
+
35
+ context 'parameters' do
36
+ it_should_accept 'id', ['--id=1']
37
+ end
38
+ end
39
+
40
+ context 'DeleteCommand' do
41
+ let(:cmd) { HammerCLIForemanHostReports::HostReport::DeleteCommand.new('', ctx) }
42
+
43
+ context 'parameters' do
44
+ it_should_accept 'id', ['--id=1']
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
4
+ require File.join(Gem.loaded_specs['hammer_cli_foreman'].full_gem_path, 'test/unit/test_helper')