forked from SatelliteQE/robottelo
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_rhcloud_inventory.py
More file actions
665 lines (519 loc) · 22.3 KB
/
Copy pathtest_rhcloud_inventory.py
File metadata and controls
665 lines (519 loc) · 22.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
"""CLI tests for RH Cloud - Inventory, aka Insights Inventory Upload
:Requirement: RHCloud
:CaseAutomation: Automated
:CaseComponent: RHCloud
:Team: Proton
:CaseImportance: High
"""
from datetime import UTC, datetime
import json
import time
import pytest
from wait_for import wait_for
from robottelo import constants
from robottelo.config import robottelo_tmp_dir
from robottelo.constants import DEFAULT_CV, ENVIRONMENT
from robottelo.utils.io import get_local_file_data, get_remote_report_checksum
inventory_sync_task = 'InventorySync::Async::InventoryFullSync'
generate_report_jobs = 'ForemanInventoryUpload::Async::GenerateAllReportsJob'
@pytest.mark.e2e
def test_positive_inventory_generate_upload_cli(
rhcloud_manifest_org, rhcloud_registered_hosts, module_target_sat
):
"""Tests Insights inventory generation and upload via foreman-rake commands:
https://github.com/theforeman/foreman_rh_cloud/blob/master/README.md
:id: f2da9506-97d4-4d1c-b373-9f71a52b8ab8
:customerscenario: true
:steps:
0. Create a VM and register to insights within org having manifest.
1. Generate and upload report for all organizations
# /usr/sbin/foreman-rake rh_cloud_inventory:report:generate_upload
2. Generate and upload report for specific organization
# export organization_id=1
# /usr/sbin/foreman-rake rh_cloud_inventory:report:generate_upload
3. Generate report for specific organization (don't upload)
# export organization_id=1
# export target=/var/lib/foreman/red_hat_inventory/generated_reports/
# /usr/sbin/foreman-rake rh_cloud_inventory:report:generate
4. Upload previously generated report
(needs to be named 'report_for_#{organization_id}.tar.gz')
# export organization_id=1
# export target=/var/lib/foreman/red_hat_inventory/generated_reports/
# /usr/sbin/foreman-rake rh_cloud_inventory:report:upload
:expectedresults: Inventory is generated and uploaded to cloud.redhat.com.
:BZ: 1957129, 1895953, 1956190
:CaseAutomation: Automated
"""
org = rhcloud_manifest_org
cmd = f'organization_id={org.id} foreman-rake rh_cloud_inventory:report:generate_upload'
upload_success_msg = f"Generated and uploaded inventory report for organization '{org.name}'"
result = module_target_sat.execute(cmd)
assert result.status == 0
assert upload_success_msg in result.stdout
local_report_path = robottelo_tmp_dir.joinpath(f'report_for_{org.id}.tar.xz')
remote_report_path = (
f'/var/lib/foreman/red_hat_inventory/uploads/done/report_for_{org.id}.tar.xz'
)
wait_for(
lambda: module_target_sat.get(
remote_path=str(remote_report_path), local_path=str(local_report_path)
),
timeout=60,
delay=15,
silent_failure=True,
handle_exception=True,
)
local_file_data = get_local_file_data(local_report_path)
assert local_file_data['checksum'] == get_remote_report_checksum(module_target_sat, org.id)
assert local_file_data['size'] > 0
assert local_file_data['extractable']
assert local_file_data['json_files_parsable']
slices_in_metadata = set(local_file_data['metadata_counts'].keys())
slices_in_tar = set(local_file_data['slices_counts'].keys())
assert slices_in_metadata == slices_in_tar
for slice_name, hosts_count in local_file_data['metadata_counts'].items():
assert hosts_count == local_file_data['slices_counts'][slice_name]
@pytest.mark.e2e
@pytest.mark.pit_server
@pytest.mark.pit_client
def test_positive_inventory_recommendation_sync(
rhcloud_manifest_org,
rhcloud_registered_hosts,
module_target_sat,
):
"""Tests Insights recommendation sync via foreman-rake commands:
https://github.com/theforeman/foreman_rh_cloud/blob/master/README.md
:id: 361af91d-1246-4308-9cc8-66beada7d651
:steps:
0. Create a VM and register to insights within org having manifest.
1. Sync insights recommendation using following foreman-rake command.
# /usr/sbin/foreman-rake rh_cloud_insights:sync
:expectedresults: Insights recommendations are successfully synced for the host.
:BZ: 1957186
:CaseAutomation: Automated
"""
org = rhcloud_manifest_org
cmd = f'organization_id={org.id} foreman-rake rh_cloud_insights:sync'
timestamp = datetime.now(UTC).strftime('%Y-%m-%d %H:%M')
result = module_target_sat.execute(cmd)
wait_for(
lambda: (
module_target_sat.api.ForemanTask()
.search(query={'search': f'Insights full sync and started_at >= "{timestamp}"'})[0]
.result
== 'success'
),
timeout=400,
delay=15,
silent_failure=True,
handle_exception=True,
)
assert result.status == 0
assert 'Synchronized Insights hosts hits data' in result.stdout
def test_positive_sync_inventory_status_missing_host_ip(
rhcloud_manifest_org,
rhcloud_registered_hosts,
module_target_sat,
):
"""Sync inventory status via foreman-rake commands with missing IP.
:id: 372c03df-038b-49fb-a509-bb28edf178f3
:steps:
1. Create a vm and register to insights within org having manifest.
2. Remove IP from host.
3. Sync inventory status for specific organization.
# export organization_id=1
# /usr/sbin/foreman-rake rh_cloud_inventory:sync
:expectedresults: Inventory status is successfully synced for satellite host with missing IP.
:Verifies: SAT-24805
:customerscenario: true
"""
org = rhcloud_manifest_org
cmd = f'organization_id={org.id} foreman-rake rh_cloud_inventory:sync'
success_msg = f"Synchronized inventory for organization '{org.name}'"
timestamp = datetime.now(UTC).strftime('%Y-%m-%d %H:%M')
rhcloud_host = module_target_sat.cli.Host.info({'name': rhcloud_registered_hosts[0].hostname})[
'id'
]
update_ip = module_target_sat.execute(
f'echo "Host.find({rhcloud_host}).update(ip: nil)" | foreman-rake console'
)
assert 'true' in update_ip.stdout
result = module_target_sat.execute(cmd)
assert result.status == 0
assert success_msg in result.stdout
# Check task details
wait_for(
lambda: (
module_target_sat.api.ForemanTask()
.search(
query={
'search': f'{inventory_sync_task} and started_at >= "{timestamp}"',
'per_page': 'all',
}
)[0]
.result
== 'success'
),
timeout=400,
delay=15,
silent_failure=True,
handle_exception=True,
)
task_output = module_target_sat.api.ForemanTask().search(
query={'search': f'{inventory_sync_task} and started_at >= "{timestamp}"'}
)
host_status = None
for task in task_output:
if task.input.get("organization_ids") is None:
continue
if str(task.input.get("organization_ids")[0]) == str(org.id):
host_status = task.output
break
assert host_status['host_statuses']['sync'] == 2
assert host_status['host_statuses']['disconnect'] == 0
def test_positive_sync_inventory_status_cli(
rhcloud_manifest_org,
module_target_sat,
rhcloud_registered_hosts,
):
"""Sync inventory status via hammer:
:id: cb1e883f-04d2-4564-bbcb-6a0087cabef4
:steps:
0. Create a VM and register to insights within org having manifest.
1. Sync inventory status for specific organization.
# hammer insights inventory sync --organization_id=1
:expectedresults: Inventory status is successfully synced for satellite hosts.
"""
org = rhcloud_manifest_org
result = module_target_sat.cli.Insights.inventory_sync({'organization-id': org.id})
success_msg = "Inventory sync task started successfully"
timestamp = datetime.now(UTC).strftime('%Y-%m-%d %H:%M')
assert success_msg in result
# Check task details
wait_for(
lambda: (
module_target_sat.api.ForemanTask()
.search(query={'search': f'{inventory_sync_task} and started_at >= "{timestamp}"'})[0]
.result
== 'success'
),
timeout=400,
delay=15,
silent_failure=True,
handle_exception=True,
)
task_output = module_target_sat.api.ForemanTask().search(
query={'search': f'{inventory_sync_task} and started_at >= "{timestamp}"'}
)
assert task_output[0].output['host_statuses']['sync'] == 2
assert task_output[0].output['host_statuses']['disconnect'] == 0
def test_positive_cloud_connector_enable_cli(module_target_sat):
"""Cloud-connector enable via hammer:
:id: 7f9e9918-f5b4-48bd-b316-328c3951fa42
:steps:
0. Create a VM and register to insights within org having manifest.
1. Enable cloud connector.
# hammer insights cloud-connector enable
:expectedresults: Cloud connector enablement starts successfully.
"""
result = module_target_sat.cli.Insights.cloud_connector_enable({})
success_msg = "Cloud connector enable task started"
assert success_msg in result
@pytest.mark.stubbed
def test_max_org_size_variable():
"""Verify that if organization had more hosts than specified by max_org_size variable
then report won't be uploaded.
:id: 7dd964c3-fde8-4335-ab13-02329119d7f6
:steps:
1. Register few content hosts with satellite.
2. Change value of max_org_size for testing purpose(See BZ#1962694#c2).
3. Start report generation and upload using
ForemanTasks.sync_task(ForemanInventoryUpload::Async::GenerateAllReportsJob)
:expectedresults: If organization had more hosts than specified by max_org_size variable
then report won't be uploaded.
:CaseImportance: Low
:BZ: 1962694
:CaseAutomation: ManualOnly
"""
@pytest.mark.stubbed
def test_satellite_inventory_slice_variable():
"""Test SATELLITE_INVENTORY_SLICE_SIZE dynflow environment variable.
:id: ffbef1c7-08f3-444b-9255-2251d5594fcb
:steps:
1. Register few content hosts with satellite.
2. Set SATELLITE_INVENTORY_SLICE_SIZE=1 dynflow environment variable.
See BZ#1945661#c1
3. Run "satellite-maintain service restart --only dynflow-sidekiq@worker-1"
4. Generate inventory report.
:expectedresults: Generated report had slice containing only one host.
:CaseImportance: Low
:BZ: 1945661
:CaseAutomation: ManualOnly
"""
@pytest.mark.stubbed
def test_rhcloud_external_links():
"""Verify that all external links on Insights and Inventory page are working.
:id: bc7f6354-ed3e-4ac5-939d-90bfe4177043
:steps:
1. Go to Configure > Inventory upload
2. Go to Configure > Insights
:expectedresults: all external links on Insights and Inventory page are working.
:CaseImportance: Low
:BZ: 1975093
:CaseAutomation: ManualOnly
"""
def test_positive_generate_all_reports_job(target_sat):
"""Generate all reports job via foreman-rake console:
:id: a9e4bfdb-6d7c-4f8c-ae57-a81442926dd8
:steps:
1. Disable the Automatic Inventory upload setting.
2. Execute Foreman GenerateAllReportsJob via foreman-rake.
:expectedresults: Reports generation works as expected.
:BZ: 2110163
:customerscenario: true
:CaseAutomation: Automated
"""
try:
target_sat.update_setting('allow_auto_inventory_upload', False)
with target_sat.session.shell() as sh:
sh.send('foreman-rake console')
time.sleep(30) # sleep to allow time for console to open
sh.send(f'ForemanTasks.async_task({generate_report_jobs})')
time.sleep(3) # sleep for the cmd execution
timestamp = datetime.now(UTC).strftime('%Y-%m-%d %H:%M')
wait_for(
lambda: (
target_sat.api.ForemanTask()
.search(
query={'search': f'{generate_report_jobs} and started_at >= "{timestamp}"'}
)[0]
.result
== 'success'
),
timeout=400,
delay=15,
silent_failure=True,
handle_exception=True,
)
task_output = target_sat.api.ForemanTask().search(
query={'search': f'{generate_report_jobs} and started_at >= {timestamp}'}
)
assert task_output[0].result == "success"
finally:
target_sat.update_setting('allow_auto_inventory_upload', True)
def test_positive_generate_reports_job_cli(
rhcloud_manifest_org, module_target_sat, rhcloud_registered_hosts
):
"""Generate reports job via cli:
:id: 2f3e2e38-fd76-45b0-bf75-07fc12e5a118
:steps:
1. Execute hammer insights inventory generate-report.
:expectedresults: Reports generation works as expected.
:BlockedBy: SAT-38836
"""
org = rhcloud_manifest_org
generate_report(org, module_target_sat, disconnected=False)
result = module_target_sat.api.Organization(id=org.id).rh_cloud_fetch_last_upload_log()
expected = 'Connected to cert.cloud.redhat.com'
assert expected in result['output']
def test_positive_generate_reports_job_cli_disconnected(
rhcloud_manifest_org,
module_target_sat,
rhcloud_registered_hosts,
):
"""Generate reports job via cli:
:id: 7540edce-1d4e-4a67-adb6-116729e9bfeb
:steps:
1. Execute hammer insights inventory generate-report.
:expectedresults: Reports generation works as expected.
:BlockedBy: SAT-38836
"""
org = rhcloud_manifest_org
generate_report(org, module_target_sat, disconnected=True)
result = module_target_sat.api.Organization(id=org.id).rh_cloud_fetch_last_upload_log()
expected = 'Upload canceled because connection to Insights is not enabled or the --no-upload option was passed.'
assert expected == result['output']
@pytest.mark.rhel_ver_match('N-2')
def test_positive_download_reports_job_cli_disconnected(
rhcloud_manifest_org, module_target_sat, rhcloud_registered_hosts
):
"""Download generated report job via cli:
:id: a9e4bfdb-6d7c-4f8c-ae57-a81442926ddc
:steps:
1. Generate a report
2. Execute hammer insights inventory download-report.
:expectedresults: Reports download works as expected.
:Verifies: SAT-41462
"""
org = rhcloud_manifest_org
generate_report(org, module_target_sat, disconnected=True)
report_path = f'/tmp/report_for_{org.id}.tar.xz'
result = module_target_sat.cli.Insights.inventory_download_report(
{
'organization-id': org.id,
'path': "/tmp",
}
)
time.sleep(5)
success_msg = f"The response has been saved to {report_path}"
assert success_msg in result
command = f'''rm -rf /tmp/report && \
mkdir -p /tmp/report && \
tar xf /tmp/report_for_{org.id}.tar.xz --directory /tmp/report && \
cat $(ls /tmp/report/*.json | grep -v meta)'''
result = module_target_sat.execute(command)
assert result.status == 0
report_data = json.loads(result.stdout)
assert len(report_data['hosts']) >= len(rhcloud_registered_hosts)
@pytest.mark.rhel_ver_match('N-2')
def test_positive_register_insights_client_host(module_target_sat, rhel_insights_vm):
"""Check the below command executed successfully
command - insights-client --ansible-host=foo.example.com
:id: b578371e-ec36-42de-83fa-bcea6e027fe2
:setup:
1. Enable, sync RHEL BaseOS and AppStream repositories
2. Create CV, Publish/promote and create AK for host registration
3. Register host to satellite, Setup Insights is Yes (Override), Install insights-client
:steps:
2. Test connection of insights client
3. execute insight client command given in the description
:expectedresults: Command executed successfully
:Verifies: SAT-28695
:customerscenario: true
:CaseAutomation: Automated
"""
# Test connection of insights client
assert rhel_insights_vm.execute('insights-client --test-connection').status == 0
# Execute insight client command
output = rhel_insights_vm.execute(f'insights-client --ansible-host={rhel_insights_vm.hostname}')
assert output.status == 0
assert 'Ansible hostname updated' in output.stdout
def test_positive_check_report_autosync_setting(target_sat):
"""Verify that the Insights report autosync setting is enabled by default.
:id: 137dffe6-50a4-4327-8e93-79e128bee63b
:steps:
1. Check the Insights report autosync setting.
:expectedresults:
1. The Insights setting "Synchronize recommendations Automatically" should have value "true"
:Verifies: SAT-30227
"""
assert (
target_sat.cli.Settings.list({'search': 'Synchronize recommendations Automatically'})[0][
'value'
]
== 'true'
), 'Setting is not enabled by default!'
def generate_report(rhcloud_manifest_org, module_target_sat, disconnected=False):
"""Download generated report job via cli"""
org = rhcloud_manifest_org
params = {'organization-id': org.id}
if disconnected:
params['no-upload'] = True
result = module_target_sat.cli.Insights.inventory_generate_report(params)
success_msg = "Report generation started successfully"
timestamp = datetime.now(UTC).strftime('%Y-%m-%d %H:%M')
assert success_msg in result
# Check task details
generate_job_name = 'ForemanInventoryUpload::Async::HostInventoryReportJob'
wait_for(
lambda: (
module_target_sat.api.ForemanTask()
.search(query={'search': f'{generate_job_name} and started_at >= "{timestamp}"'})[0]
.result
== 'success'
),
timeout=400,
delay=15,
silent_failure=True,
handle_exception=True,
)
task_output = module_target_sat.api.ForemanTask().search(
query={'search': f'{generate_job_name} and started_at >= "{timestamp}"'}
)
assert task_output[0].result == "success"
def test_positive_config_on_sat_without_network_protocol(
request, target_sat, function_sca_manifest, function_org
):
"""Test cloud connector configuration on Satellite without explicit network protocol.
:id: e6bf1c56-3091-4db2-b162-4cf3c6e23394
:steps:
1. Create organization and get its Library lifecycle environment and default content view.
2. Upload manifest to enable Red Hat content.
3. Enable and sync RHEL BaseOS and AppStream repositories.
4. Create activation key and register Satellite to itself.
5. Enable cloud connector via CLI.
6. Verify that the 'Configure Cloud Connector' job template executes successfully.
7. Check that rhcd service proxy configuration is properly set.
:expectedresults:
1. Satellite is successfully registered.
2. Cloud connector is enabled successfully.
3. The job invocation for configuring cloud connector succeeds.
4. The rhcd.service.d/proxy.conf file contains the correct NO_PROXY environment variable
with the FQDN without https:// prefix.
:Verifies: SAT-34224
:customerscenario: true
"""
# Ensure Satellite is not registered from previous test runs
target_sat.unregister()
# Delete the host from Satellite's database if it exists from a previous test run
existing_host = target_sat.api.Host().search(query={'search': f'name="{target_sat.hostname}"'})
if existing_host:
existing_host[0].delete()
# Get the Library lifecycle environment and default content view for the organization
cv = target_sat.api.ContentView().search(
query={'search': f'name="{DEFAULT_CV}" AND organization_id={function_org.id}'}
)[0]
lce = target_sat.api.LifecycleEnvironment().search(
query={'search': f'name="{ENVIRONMENT}" AND organization_id={function_org.id}'}
)[0]
# Upload manifest to enable Red Hat content
target_sat.upload_manifest(function_org.id, function_sca_manifest.content)
# Enable and sync RHEL BaseOS and AppStream repositories based on Satellite's OS version
rhel_ver = target_sat.os_version.major
for name in [f'rhel{rhel_ver}_bos', f'rhel{rhel_ver}_aps']:
# Enable the Red Hat repository and get its ID
rh_repo_id = target_sat.api_factory.enable_rhrepo_and_fetchid(
basearch=constants.DEFAULT_ARCHITECTURE,
org_id=function_org.id,
product=constants.REPOS[name]['product'],
repo=constants.REPOS[name]['name'],
reposet=constants.REPOS[name]['reposet'],
releasever=constants.REPOS[name]['version'],
)
# Sync the repository
rh_repo = target_sat.api.Repository(id=rh_repo_id).read()
rh_repo.sync(timeout=2000)
# Create an activation key for Satellite self-registration
ac_key = target_sat.api.ActivationKey(
content_view=cv,
environment=lce,
organization=function_org,
).create()
# Register the Satellite to itself using the activation key
result = target_sat.register(function_org, None, ac_key.name, target_sat, force=True)
assert result.status == 0, f'Failed to register host: {result.stderr}'
# Add finalizer to ensure the Satellite is always unregistered
@request.addfinalizer
def cleanup():
target_sat.unregister()
# Enable cloud connector
result = target_sat.cli.Insights.cloud_connector_enable({})
assert "Cloud connector enable task started" in result
# Find the job invocation for the 'Configure Cloud Connector' template
template_name = 'Configure Cloud Connector'
result = target_sat.api.JobInvocation().search(
query={'search': f'description="{template_name}"'}
)[0]
# Wait for the job to complete
target_sat.wait_for_tasks(
f'resource_type = JobInvocation and resource_id = {result.id}', poll_timeout=600
)
# Verify the job completed successfully
result = target_sat.api.JobInvocation(id=result.id).read()
assert result.status_label == 'succeeded'
# Read the rhcd service proxy configuration file to verify correct setup
status = target_sat.execute('cat /etc/systemd/system/rhcd.service.d/proxy.conf')
# Check the correct format is present
assert f'Environment=NO_PROXY={target_sat.hostname}' in status.stdout
# Ensure NO_PROXY doesn't contain https:// prefix
assert 'Environment=NO_PROXY=https://' not in status.stdout