foreman_openscap 13.1.2 → 13.2.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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/foreman_openscap/locale/de/foreman_openscap.js +5 -5
  3. data/app/assets/javascripts/foreman_openscap/locale/en/foreman_openscap.js +1 -1
  4. data/app/assets/javascripts/foreman_openscap/locale/en_GB/foreman_openscap.js +1 -1
  5. data/app/assets/javascripts/foreman_openscap/locale/es/foreman_openscap.js +1 -1
  6. data/app/assets/javascripts/foreman_openscap/locale/fr/foreman_openscap.js +26 -24
  7. data/app/assets/javascripts/foreman_openscap/locale/gl/foreman_openscap.js +1 -1
  8. data/app/assets/javascripts/foreman_openscap/locale/it/foreman_openscap.js +1 -1
  9. data/app/assets/javascripts/foreman_openscap/locale/ja/foreman_openscap.js +26 -28
  10. data/app/assets/javascripts/foreman_openscap/locale/ka/foreman_openscap.js +5 -5
  11. data/app/assets/javascripts/foreman_openscap/locale/ko/foreman_openscap.js +26 -28
  12. data/app/assets/javascripts/foreman_openscap/locale/pt_BR/foreman_openscap.js +1 -1
  13. data/app/assets/javascripts/foreman_openscap/locale/ru/foreman_openscap.js +1 -1
  14. data/app/assets/javascripts/foreman_openscap/locale/sv_SE/foreman_openscap.js +1 -1
  15. data/app/assets/javascripts/foreman_openscap/locale/zh_CN/foreman_openscap.js +22 -24
  16. data/app/assets/javascripts/foreman_openscap/locale/zh_TW/foreman_openscap.js +1 -1
  17. data/app/controllers/api/v2/compliance/hosts_bulk_actions_controller.rb +38 -1
  18. data/app/controllers/policies_controller.rb +1 -1
  19. data/app/models/concerns/foreman_openscap/host_extensions.rb +10 -4
  20. data/app/models/concerns/foreman_openscap/hostgroup_extensions.rb +7 -0
  21. data/app/models/foreman_openscap/asset.rb +21 -1
  22. data/app/models/foreman_openscap/compliance_status.rb +19 -7
  23. data/app/models/foreman_openscap/policy.rb +43 -3
  24. data/app/services/foreman_openscap/compliance_status_resetter.rb +26 -0
  25. data/config/routes.rb +2 -0
  26. data/lib/foreman_openscap/engine.rb +3 -1
  27. data/lib/foreman_openscap/version.rb +1 -1
  28. data/locale/de/LC_MESSAGES/foreman_openscap.mo +0 -0
  29. data/locale/de/foreman_openscap.po +5 -5
  30. data/locale/en/LC_MESSAGES/foreman_openscap.mo +0 -0
  31. data/locale/en/foreman_openscap.po +1 -1
  32. data/locale/en_GB/LC_MESSAGES/foreman_openscap.mo +0 -0
  33. data/locale/en_GB/foreman_openscap.po +1 -1
  34. data/locale/es/LC_MESSAGES/foreman_openscap.mo +0 -0
  35. data/locale/es/foreman_openscap.po +1 -1
  36. data/locale/foreman_openscap.pot +2 -2
  37. data/locale/fr/LC_MESSAGES/foreman_openscap.mo +0 -0
  38. data/locale/fr/foreman_openscap.po +26 -24
  39. data/locale/gl/LC_MESSAGES/foreman_openscap.mo +0 -0
  40. data/locale/gl/foreman_openscap.po +1 -1
  41. data/locale/it/LC_MESSAGES/foreman_openscap.mo +0 -0
  42. data/locale/it/foreman_openscap.po +1 -1
  43. data/locale/ja/LC_MESSAGES/foreman_openscap.mo +0 -0
  44. data/locale/ja/foreman_openscap.po +26 -28
  45. data/locale/ka/LC_MESSAGES/foreman_openscap.mo +0 -0
  46. data/locale/ka/foreman_openscap.po +5 -5
  47. data/locale/ko/LC_MESSAGES/foreman_openscap.mo +0 -0
  48. data/locale/ko/foreman_openscap.po +26 -28
  49. data/locale/pt_BR/LC_MESSAGES/foreman_openscap.mo +0 -0
  50. data/locale/pt_BR/foreman_openscap.po +1 -1
  51. data/locale/ru/LC_MESSAGES/foreman_openscap.mo +0 -0
  52. data/locale/ru/foreman_openscap.po +1 -1
  53. data/locale/sv_SE/LC_MESSAGES/foreman_openscap.mo +0 -0
  54. data/locale/sv_SE/foreman_openscap.po +1 -1
  55. data/locale/zh_CN/LC_MESSAGES/foreman_openscap.mo +0 -0
  56. data/locale/zh_CN/foreman_openscap.po +22 -24
  57. data/locale/zh_TW/LC_MESSAGES/foreman_openscap.mo +0 -0
  58. data/locale/zh_TW/foreman_openscap.po +1 -1
  59. data/test/functional/api/v2/compliance/hosts_bulk_actions_controller_test.rb +175 -1
  60. data/test/test_plugin_helper.rb +7 -0
  61. data/test/unit/compliance_status_resetter_test.rb +48 -0
  62. data/test/unit/compliance_status_test.rb +53 -4
  63. data/test/unit/concerns/host_extensions_test.rb +55 -0
  64. data/test/unit/concerns/hostgroup_extensions_test.rb +64 -0
  65. data/test/unit/policy_test.rb +90 -0
  66. data/webpack/components/BulkActions/compliancePolicy/BulkCompliancePolicyMenuItems.js +49 -0
  67. data/webpack/components/BulkActions/compliancePolicy/BulkCompliancePolicyModal.js +304 -0
  68. data/webpack/components/BulkActions/compliancePolicy/BulkCompliancePolicyModalScene.js +65 -0
  69. data/webpack/components/BulkActions/compliancePolicy/__tests__/actions.test.js +121 -0
  70. data/webpack/components/BulkActions/compliancePolicy/actions.js +32 -0
  71. data/webpack/components/BulkActions/compliancePolicy/constants.js +8 -0
  72. data/webpack/global_index.js +27 -1
  73. metadata +10 -1
@@ -45,7 +45,7 @@
45
45
  "기간별 %s 보고서"
46
46
  ],
47
47
  "%s selected hosts.": [
48
- ""
48
+ "%s개 호스트가 선택되었습니다."
49
49
  ],
50
50
  "%s spool errors detected, inspect the appropriate file directly on proxy": [
51
51
  "%s spool 오류가 감지되었습니다. 프록시에서 직접 해당 파일을 검사하세요."
@@ -66,7 +66,7 @@
66
66
  "OpenSCAP 정책에 대한 보고서 요약"
67
67
  ],
68
68
  "ALL selected hosts.": [
69
- ""
69
+ "선택한 모든 호스트"
70
70
  ],
71
71
  "Actions": [
72
72
  "동작 "
@@ -87,19 +87,19 @@
87
87
  "호스트에 정책 적용"
88
88
  ],
89
89
  "Assign": [
90
- ""
90
+ "할당"
91
91
  ],
92
92
  "Assign Compliance Policy": [
93
93
  "컴플라이언스 정책 할당"
94
94
  ],
95
95
  "Assign OpenSCAP Proxy": [
96
- ""
96
+ "OpenSCAP 프록시 할당"
97
97
  ],
98
98
  "Assign OpenSCAP Proxy for ": [
99
- ""
99
+ "OpenSCAP 프록시 할당 대상"
100
100
  ],
101
101
  "Assign OpenSCAP Proxy to multiple hosts": [
102
- ""
102
+ "여러 호스트에 OpenSCAP 프록시 할당"
103
103
  ],
104
104
  "Back": [
105
105
  "뒤로 "
@@ -291,7 +291,7 @@
291
291
  "bzipped ARF 보고서 다운로드"
292
292
  ],
293
293
  "Edit %s": [
294
- "%s 편집 "
294
+ "%s 편집"
295
295
  ],
296
296
  "Effective Profile": [
297
297
  "효과적인 프로필"
@@ -318,8 +318,7 @@
318
318
  "%s 저장에 실패했습니다:"
319
319
  ],
320
320
  "Failed to assign OpenSCAP Proxy to %{failed} of %{total} host.": [
321
- "",
322
- ""
321
+ "%{total}개 호스트 중 %{failed}개 호스트에 OpenSCAP 프록시를 할당하지 못했습니다."
323
322
  ],
324
323
  "Failed to delete %s compliance reports": [
325
324
  "%s 컴플라이언스 보고서를 삭제하지 못했습니다."
@@ -409,10 +408,10 @@
409
408
  "이 규칙을 통과하는 호스트"
410
409
  ],
411
410
  "Hosts to explicitly exclude in the action. All other hosts will be included in the action, unless an included parameter is passed as well.": [
412
- ""
411
+ "작업에서 명시적으로 제외할 호스트. 포함된 매개변수가 전달되지 않는 한 다른 모든 호스트는 작업에 포함됩니다."
413
412
  ],
414
413
  "Hosts to include in the action": [
415
- ""
414
+ "작업에 포함할 호스트"
416
415
  ],
417
416
  "How the policy should be deployed": [
418
417
  "정책이 어떻게 배포되어야 하는가"
@@ -421,7 +420,7 @@
421
420
  "OpenSCAP 프록시 ID"
422
421
  ],
423
422
  "ID of the OpenSCAP Proxy to assign to the hosts": [
424
- ""
423
+ "호스트에 할당할 OpenSCAP 프록시의 ID"
425
424
  ],
426
425
  "In Foreman, a compliance policy checklist is defined via %s.": [
427
426
  "Foreman에서는 컴플라이언스 정책 체크리스트는 %s을/를 통해 정의됩니다."
@@ -457,7 +456,7 @@
457
456
  "정책에 대한 최신 보고서: %s"
458
457
  ],
459
458
  "Line chart": [
460
- ""
459
+ "선 그래프"
461
460
  ],
462
461
  "List ARF reports": [
463
462
  "ARF 보고서 목록"
@@ -475,16 +474,16 @@
475
474
  "맞춤형 파일 목록"
476
475
  ],
477
476
  "List of host ids to exclude and not perform the action on": [
478
- ""
477
+ "제외하고 작업을 수행하지 않을 호스트 ID 목록"
479
478
  ],
480
479
  "List of host ids to perform the action on": [
481
- ""
480
+ "작업을 수행할 호스트 ID 목록"
482
481
  ],
483
482
  "Loading": [
484
- ""
483
+ "로딩 중"
485
484
  ],
486
485
  "Loading...": [
487
- "로딩..."
486
+ "로딩 중..."
488
487
  ],
489
488
  "Locations": [
490
489
  "위치"
@@ -529,7 +528,7 @@
529
528
  "이 정책에 대한 ARF 보고서가 없습니다."
530
529
  ],
531
530
  "No OpenSCAP Proxies available. Please configure a Smart Proxy with the OpenSCAP feature.": [
532
- ""
531
+ "사용 가능한 OpenSCAP 프록시가 없습니다. OpenSCAP 기능을 갖춘 Smart Proxy를 구성하십시오."
533
532
  ],
534
533
  "No OpenSCAP Proxy selected.": [
535
534
  "OpenSCAP 프록시가 선택되지 않았습니다."
@@ -553,7 +552,7 @@
553
552
  "컴플라이언트 보고서를 찾을 수 없습니다."
554
553
  ],
555
554
  "No data available": [
556
- ""
555
+ "사용 가능한 데이터가 없음"
557
556
  ],
558
557
  "No hosts selected": [
559
558
  "선택된 호스트가 없음"
@@ -619,13 +618,13 @@
619
618
  "OpenSCAP Proxy"
620
619
  ],
621
620
  "OpenSCAP Proxy is set to %s": [
622
- ""
621
+ "OpenSCAP 프록시가 %s(으)로 설정되었습니다."
623
622
  ],
624
623
  "OpenSCAP Proxy to use for fetching SCAP content and uploading ARF reports. Leave blank and override appropriate parameters when using proxy load balancer.": [
625
624
  "SCAP 콘텐츠를 가져오고 ARF 보고서를 업로드하는 데 사용할 OpenSCAP 프록시입니다. 프록시 로드 밸런서를 사용할 때는 공백으로 두고 적절한 매개변수를 재정의합니다."
626
625
  ],
627
626
  "OpenSCAP Proxy with id %s not found": [
628
- ""
627
+ "ID가 %s인 OpenSCAP 프록시를 찾을 수 없습니다."
629
628
  ],
630
629
  "Openscap Proxy": [
631
630
  "Openscap 프록시"
@@ -763,7 +762,7 @@
763
762
  "요청 시간이 초과되었습니다. 설정 -> proxy_request_timeout을 늘려보세요."
764
763
  ],
765
764
  "Required %{msg_name} %{class} was not found, please ensure it is imported first.": [
766
- "필수의 %{msg_name} %{class} 을/를 찾을 수 없습니다. 먼저 가져왔는지 확인하세요."
765
+ "필수의 %{msg_name} %{class}을/를 찾을 수 없습니다. 먼저 가져왔는지 확인하세요."
767
766
  ],
768
767
  "Requires %s Puppet class. This will assign the class to the hosts or selected hostgroups.": [
769
768
  "%s Puppet 클래스가 필요합니다. 이는 클래스를 호스트 또는 선택된 호스트그룹에 할당합니다."
@@ -829,7 +828,7 @@
829
828
  "스케줄 "
830
829
  ],
831
830
  "Search string describing which hosts to perform the action on": [
832
- ""
831
+ "작업을 수행할 호스트를 설명하는 검색 문자열"
833
832
  ],
834
833
  "Select Action": [
835
834
  "작업 선택"
@@ -883,7 +882,7 @@
883
882
  "스마트 클래스 매개변수"
884
883
  ],
885
884
  "Snippet": [
886
- "조각 모음 "
885
+ "스니펫"
887
886
  ],
888
887
  "Something went wrong while selecting compliance reports - %s": [
889
888
  "컴플라이언스 보고서를 선택하는 도중 문제가 발생했습니다 - %s"
@@ -913,8 +912,7 @@
913
912
  "ARF 보고서를 성공적으로 삭제했습니다."
914
913
  ],
915
914
  "Successfully updated %{success} host.": [
916
- "",
917
- ""
915
+ "%{success}개 호스트를 성공적으로 업데이트했습니다."
918
916
  ],
919
917
  "Summary from %{time} ago to now": [
920
918
  "%{time} 전에서 현재까지의 요약"
@@ -959,7 +957,7 @@
959
957
  "선택한 호스트에서 작업이 시작되었습니다. 작업 세부 정보 페이지에서 상태를 확인할 수 있습니다."
960
958
  ],
961
959
  "The selected OpenSCAP Proxy does not have the OpenSCAP feature enabled.": [
962
- ""
960
+ "선택한 OpenSCAP 프록시에 OpenSCAP 기능이 활성화되어 있지 않습니다."
963
961
  ],
964
962
  "There are significant differences in deployment options.": [
965
963
  "배포 옵션에는 상당한 차이가 있습니다."
@@ -977,7 +975,7 @@
977
975
  "이 프로필은 scap 콘텐츠의 프로필을 재정의하는 데 사용됩니다."
978
976
  ],
979
977
  "This will change previous proxy assignments on the selected hosts.": [
980
- ""
978
+ "이렇게 하면 선택한 호스트에 대한 기존 프록시 할당이 변경됩니다."
981
979
  ],
982
980
  "Title": [
983
981
  "제목"
@@ -483,7 +483,7 @@
483
483
  ""
484
484
  ],
485
485
  "Loading": [
486
- ""
486
+ "Carregando"
487
487
  ],
488
488
  "Loading...": [
489
489
  "Carregando..."
@@ -482,7 +482,7 @@
482
482
  ""
483
483
  ],
484
484
  "Loading": [
485
- ""
485
+ "Загружается"
486
486
  ],
487
487
  "Loading...": [
488
488
  "Загрузка..."
@@ -482,7 +482,7 @@
482
482
  ""
483
483
  ],
484
484
  "Loading": [
485
- ""
485
+ "Laddar"
486
486
  ],
487
487
  "Loading...": [
488
488
  ""
@@ -45,7 +45,7 @@
45
45
  "一直以來的 %s 报告"
46
46
  ],
47
47
  "%s selected hosts.": [
48
- ""
48
+ "%{failed} 所选的主机"
49
49
  ],
50
50
  "%s spool errors detected, inspect the appropriate file directly on proxy": [
51
51
  "发现了 %s 个 spool 错误,在代理上直接检查相关的文件"
@@ -66,7 +66,7 @@
66
66
  "OpenSCAP 策略报告摘要"
67
67
  ],
68
68
  "ALL selected hosts.": [
69
- ""
69
+ "所有选定的主机。"
70
70
  ],
71
71
  "Actions": [
72
72
  "操作"
@@ -87,19 +87,19 @@
87
87
  "对主机应用策略"
88
88
  ],
89
89
  "Assign": [
90
- ""
90
+ "分配"
91
91
  ],
92
92
  "Assign Compliance Policy": [
93
93
  "分配合规政策"
94
94
  ],
95
95
  "Assign OpenSCAP Proxy": [
96
- ""
96
+ "分配 OpenSCAP 代理"
97
97
  ],
98
98
  "Assign OpenSCAP Proxy for ": [
99
- ""
99
+ "分配 OpenSCAP 代理 "
100
100
  ],
101
101
  "Assign OpenSCAP Proxy to multiple hosts": [
102
- ""
102
+ "为多个主机分配 OpenSCAP 代理"
103
103
  ],
104
104
  "Back": [
105
105
  "返回"
@@ -318,8 +318,7 @@
318
318
  "保存失败 %s:"
319
319
  ],
320
320
  "Failed to assign OpenSCAP Proxy to %{failed} of %{total} host.": [
321
- "",
322
- ""
321
+ "将 OpenSCAP 代理分配给 %{total} 主机的 %{failed} 失败。"
323
322
  ],
324
323
  "Failed to delete %s compliance reports": [
325
324
  "刪除 %s 合规报告失败"
@@ -409,10 +408,10 @@
409
408
  "主机通过了这个规则"
410
409
  ],
411
410
  "Hosts to explicitly exclude in the action. All other hosts will be included in the action, unless an included parameter is passed as well.": [
412
- ""
411
+ "主机明确排除在操作之外。除非还传递了包含的参数,否则所有其他主机都将包含在操作中。"
413
412
  ],
414
413
  "Hosts to include in the action": [
415
- ""
414
+ "操作中要包含的主机"
416
415
  ],
417
416
  "How the policy should be deployed": [
418
417
  "应如何部署策略"
@@ -421,7 +420,7 @@
421
420
  "OpenSCAP 代理服务器的 ID"
422
421
  ],
423
422
  "ID of the OpenSCAP Proxy to assign to the hosts": [
424
- ""
423
+ "分配给主机的 OpenSCAP 代理的 ID"
425
424
  ],
426
425
  "In Foreman, a compliance policy checklist is defined via %s.": [
427
426
  "在 Foreman 中,合规策略检查清单通过 %s 定义。"
@@ -457,7 +456,7 @@
457
456
  "最新的政策报告:%s"
458
457
  ],
459
458
  "Line chart": [
460
- ""
459
+ "折线图"
461
460
  ],
462
461
  "List ARF reports": [
463
462
  "列出 ARF 报告"
@@ -475,13 +474,13 @@
475
474
  "列出 Tailoring 文件"
476
475
  ],
477
476
  "List of host ids to exclude and not perform the action on": [
478
- ""
477
+ "要排除的主机 ID 列表,不对其执行操作"
479
478
  ],
480
479
  "List of host ids to perform the action on": [
481
- ""
480
+ "要执行操作的主机 ID 列表"
482
481
  ],
483
482
  "Loading": [
484
- ""
483
+ "加载"
485
484
  ],
486
485
  "Loading...": [
487
486
  "载入中..."
@@ -529,7 +528,7 @@
529
528
  "此政策沒有 ARF 報告"
530
529
  ],
531
530
  "No OpenSCAP Proxies available. Please configure a Smart Proxy with the OpenSCAP feature.": [
532
- ""
531
+ "没有可用的 OpenSCAP 代理。请使用 OpenSCAP 功能配置智能代理。"
533
532
  ],
534
533
  "No OpenSCAP Proxy selected.": [
535
534
  "没有选择 OpenSCAP 代理。"
@@ -553,7 +552,7 @@
553
552
  "没有找到合规报告。"
554
553
  ],
555
554
  "No data available": [
556
- ""
555
+ "无可用数据"
557
556
  ],
558
557
  "No hosts selected": [
559
558
  "未选择主机"
@@ -619,13 +618,13 @@
619
618
  "OpenSCAP 代理"
620
619
  ],
621
620
  "OpenSCAP Proxy is set to %s": [
622
- ""
621
+ "OpenSCAP 代理被设置为 %s"
623
622
  ],
624
623
  "OpenSCAP Proxy to use for fetching SCAP content and uploading ARF reports. Leave blank and override appropriate parameters when using proxy load balancer.": [
625
624
  "用来获取 SCAP 内容以及上传 ARF 报告的 OpenSCAP 代理。如果为空,则在使用代理负责均衡器时覆盖相应的参数。"
626
625
  ],
627
626
  "OpenSCAP Proxy with id %s not found": [
628
- ""
627
+ "未找到 ID 为 %s 的 OpenSCAP 代理"
629
628
  ],
630
629
  "Openscap Proxy": [
631
630
  "Openscap 代理"
@@ -829,7 +828,7 @@
829
828
  "调度"
830
829
  ],
831
830
  "Search string describing which hosts to perform the action on": [
832
- ""
831
+ "搜索字符串,描述要对其执行操作的主机"
833
832
  ],
834
833
  "Select Action": [
835
834
  "选择操作"
@@ -913,8 +912,7 @@
913
912
  "成功删除了 ARF 报告。"
914
913
  ],
915
914
  "Successfully updated %{success} host.": [
916
- "",
917
- ""
915
+ "成功更新了 %{success} 主机。"
918
916
  ],
919
917
  "Summary from %{time} ago to now": [
920
918
  "从 %{time} 到现在的摘要"
@@ -959,7 +957,7 @@
959
957
  "作业已在所选主机上启动,您可以在详情页中检查作业的状态。"
960
958
  ],
961
959
  "The selected OpenSCAP Proxy does not have the OpenSCAP feature enabled.": [
962
- ""
960
+ "所选的 OpenSCAP 代理没有启用 OpenSCAP 功能。"
963
961
  ],
964
962
  "There are significant differences in deployment options.": [
965
963
  "部署选项之间存在重大差异。"
@@ -977,7 +975,7 @@
977
975
  "这个配置文件将用于覆盖 scap 内容中的配置文件"
978
976
  ],
979
977
  "This will change previous proxy assignments on the selected hosts.": [
980
- ""
978
+ "这将更改所选主机上的以前的代理分配。"
981
979
  ],
982
980
  "Title": [
983
981
  "提示"
@@ -482,7 +482,7 @@
482
482
  ""
483
483
  ],
484
484
  "Loading": [
485
- ""
485
+ "載入中"
486
486
  ],
487
487
  "Loading...": [
488
488
  "載入中…"
@@ -7,9 +7,10 @@ module Api::V2
7
7
  render_error(:custom_error, :status => :unprocessable_entity, :locals => { :message => exception.message })
8
8
  end
9
9
 
10
- before_action :find_editable_hosts, only: [:change_openscap_proxy]
10
+ before_action :find_editable_hosts, only: [:change_openscap_proxy, :assign_compliance_policy, :unassign_compliance_policy]
11
11
  before_action :find_openscap_proxy, only: [:change_openscap_proxy]
12
12
  before_action :validate_openscap_proxy_feature, only: [:change_openscap_proxy]
13
+ before_action :find_compliance_policy, only: [:assign_compliance_policy, :unassign_compliance_policy]
13
14
 
14
15
  def_param_group :bulk_host_ids do
15
16
  param :included, Hash, :desc => N_("Hosts to include in the action"), :required => true, :action_aware => true do
@@ -23,6 +24,33 @@ module Api::V2
23
24
  end
24
25
  end
25
26
 
27
+ api :PUT, "/compliance/hosts/bulk/assign_compliance_policy", N_("Assign compliance policy to multiple hosts")
28
+ param_group :bulk_host_ids
29
+ param :policy_id, :number, :required => true, :desc => N_("ID of the compliance policy to assign to the hosts")
30
+ def assign_compliance_policy
31
+ @policy.host_ids = @policy.host_ids + @hosts.pluck(:id)
32
+ if @policy.save
33
+ message = _("Assigned with compliance policy: %s") % @policy.name
34
+ process_response(true, {
35
+ :message => n_("Updated host: #{message}", "Updated hosts: #{message}", @hosts.count),
36
+ })
37
+ else
38
+ render_error(:custom_error, :status => :unprocessable_entity,
39
+ :locals => { :message => @policy.errors.full_messages.to_sentence })
40
+ end
41
+ end
42
+
43
+ api :PUT, "/compliance/hosts/bulk/unassign_compliance_policy", N_("Unassign compliance policy from multiple hosts")
44
+ param_group :bulk_host_ids
45
+ param :policy_id, :number, :required => true, :desc => N_("ID of the compliance policy to unassign from the hosts")
46
+ def unassign_compliance_policy
47
+ @policy.unassign_hosts(@hosts)
48
+ message = _("Unassigned from compliance policy '%s'") % @policy.name
49
+ process_response(true, {
50
+ :message => n_("Updated host: #{message}", "Updated hosts: #{message}", @hosts.count),
51
+ })
52
+ end
53
+
26
54
  api :PUT, "/hosts/bulk/change_openscap_proxy", N_("Assign OpenSCAP Proxy to multiple hosts")
27
55
  param_group :bulk_host_ids
28
56
  param :openscap_proxy_id, :number, :required => true, :desc => N_("ID of the OpenSCAP Proxy to assign to the hosts")
@@ -84,6 +112,15 @@ module Api::V2
84
112
  render_error(:custom_error, :status => :unprocessable_entity,
85
113
  :locals => { :message => _("The selected OpenSCAP Proxy does not have the OpenSCAP feature enabled.") })
86
114
  end
115
+
116
+ def find_compliance_policy
117
+ @policy = ::ForemanOpenscap::Policy.authorized(:assign_policies)
118
+ .find_by(:id => params.require(:policy_id))
119
+ return if @policy
120
+
121
+ render_error(:custom_error, :status => :unprocessable_entity,
122
+ :locals => { :message => _("Compliance policy with id %s not found") % params[:policy_id] })
123
+ end
87
124
  end
88
125
  end
89
126
  end
@@ -83,7 +83,7 @@ class PoliciesController < ApplicationController
83
83
  if policy.save
84
84
  success _("Updated hosts: Assigned with compliance policy: %s") % policy.name
85
85
  # We prefer to go back as this does not lose the current search
86
- return redirect_to hosts_path
86
+ redirect_to hosts_path
87
87
  else
88
88
  return process_error :object => policy, :redirect => hosts_path
89
89
  end
@@ -11,6 +11,8 @@ module ForemanOpenscap
11
11
 
12
12
  base.validate :openscap_proxy_in_taxonomy, :if => Proc.new { |host| host.openscap_proxy_id.present? }
13
13
 
14
+ base.after_update :reset_compliance_status_on_hostgroup_change, :if => :saved_change_to_hostgroup_id?
15
+
14
16
  base.scoped_search :relation => :policies, :on => :name, :complete_value => true, :rename => :compliance_policy,
15
17
  :only_explicit => true, :operators => ['= '], :ext_method => :search_by_policy_name
16
18
 
@@ -129,18 +131,22 @@ module ForemanOpenscap
129
131
  report_scope
130
132
  end
131
133
 
132
- def compliance_status(options = {})
133
- @compliance_status ||= get_status(ForemanOpenscap::ComplianceStatus).to_status(options)
134
+ def compliance_status(_options = {})
135
+ @compliance_status ||= get_status(ForemanOpenscap::ComplianceStatus).status
134
136
  end
135
137
 
136
- def compliance_status_label(options = {})
137
- @compliance_status_label ||= get_status(ForemanOpenscap::ComplianceStatus).to_label(options)
138
+ def compliance_status_label(_options = {})
139
+ @compliance_status_label ||= get_status(ForemanOpenscap::ComplianceStatus).to_label
138
140
  end
139
141
 
140
142
  def openscap_proxy_in_taxonomy
141
143
  validate_association_taxonomy(:openscap_proxy)
142
144
  end
143
145
 
146
+ def reset_compliance_status_on_hostgroup_change
147
+ ForemanOpenscap::ComplianceStatusResetter.to_inconclusive([id])
148
+ end
149
+
144
150
  module ClassMethods
145
151
  def search_by_removed_from_policy(key, operator, policy_name)
146
152
  policy = ForemanOpenscap::Policy.find_by :name => policy_name
@@ -8,12 +8,19 @@ module ForemanOpenscap
8
8
  has_many :assets, :as => :assetable, :class_name => "::ForemanOpenscap::Asset", dependent: :destroy
9
9
  has_many :asset_policies, :through => :assets, :class_name => "::ForemanOpenscap::AssetPolicy"
10
10
  has_many :policies, :through => :asset_policies, :class_name => "::ForemanOpenscap::Policy"
11
+
12
+ after_update :reset_compliance_status_on_ancestry_change, :if => :saved_change_to_ancestry?
11
13
  end
12
14
 
13
15
  def inherited_policies
14
16
  find_inherited_policies :policies
15
17
  end
16
18
 
19
+ def reset_compliance_status_on_ancestry_change
20
+ host_ids = ::Host.where(:hostgroup_id => subtree_ids).pluck(:id)
21
+ ForemanOpenscap::ComplianceStatusResetter.to_inconclusive(host_ids)
22
+ end
23
+
17
24
  def openscap_proxy
18
25
  return super if ancestry.nil? || self.openscap_proxy_id.present?
19
26
  ::SmartProxy.find_by(:id => inherited_openscap_proxy_id)
@@ -1,7 +1,9 @@
1
1
  module ForemanOpenscap
2
2
  class Asset < ApplicationRecord
3
3
  has_many :asset_policies, :dependent => :delete_all
4
- has_many :policies, :through => :asset_policies
4
+ has_many :policies, :through => :asset_policies,
5
+ :after_add => :reset_compliance_status,
6
+ :after_remove => :reset_compliance_status
5
7
  belongs_to :assetable, :polymorphic => true
6
8
 
7
9
  scope :hosts, lambda { where(:assetable_type => 'Host::Base') }
@@ -20,6 +22,24 @@ module ForemanOpenscap
20
22
 
21
23
  private
22
24
 
25
+ def reset_compliance_status(_policy)
26
+ ForemanOpenscap::ComplianceStatusResetter.to_inconclusive(host_ids_reached_by_asset)
27
+ end
28
+
29
+ def host_ids_reached_by_asset
30
+ case assetable_type
31
+ when 'Host::Base'
32
+ [assetable_id]
33
+ when 'Hostgroup'
34
+ hostgroup = Hostgroup.find_by(:id => assetable_id)
35
+ return [] unless hostgroup
36
+
37
+ Host.where(:hostgroup_id => hostgroup.subtree_ids).pluck(:id)
38
+ else
39
+ []
40
+ end
41
+ end
42
+
23
43
  def fetch_asset(type)
24
44
  assetable if assetable_type == type
25
45
  end
@@ -16,8 +16,8 @@ module ForemanOpenscap
16
16
  "#{ArfReport::BIT_NUM * ArfReport::METRIC.index(status)} & #{ArfReport::MAX}"
17
17
  end
18
18
 
19
- def to_label(options = {})
20
- case to_status
19
+ def to_label(_options = {})
20
+ case status
21
21
  when COMPLIANT
22
22
  N_('Compliant')
23
23
  when INCONCLUSIVE
@@ -29,8 +29,8 @@ module ForemanOpenscap
29
29
  end
30
30
  end
31
31
 
32
- def to_global(options = {})
33
- case to_status
32
+ def to_global(_options = {})
33
+ case status
34
34
  when COMPLIANT
35
35
  ::HostStatus::Global::OK
36
36
  when INCONCLUSIVE
@@ -40,17 +40,29 @@ module ForemanOpenscap
40
40
  end
41
41
  end
42
42
 
43
- def relevant?(options = {})
43
+ def relevant?(_options = {})
44
44
  # May fail host status during migration
45
45
  return false unless ForemanOpenscap::Asset.table_exists?
46
- host.combined_policies.present?
46
+ host.policies.any? || host_has_hostgroup_policies?
47
47
  end
48
48
 
49
- def to_status(options = {})
49
+ def to_status(_options = {})
50
50
  latest_reports = host.combined_policies.flat_map { |p| host.last_report_for_policy p }
51
51
  return INCOMPLIANT if latest_reports.any?(&:failed?)
52
52
  return INCONCLUSIVE if latest_reports.any?(&:othered?)
53
53
  COMPLIANT
54
54
  end
55
+
56
+ private
57
+
58
+ def host_has_hostgroup_policies?
59
+ return false if host.hostgroup_id.blank?
60
+
61
+ ids = [host.hostgroup_id] + host.hostgroup.ancestor_ids
62
+ ForemanOpenscap::Policy.joins(:assets)
63
+ .where('foreman_openscap_assets.assetable_type' => 'Hostgroup',
64
+ 'foreman_openscap_assets.assetable_id' => ids)
65
+ .exists?
66
+ end
55
67
  end
56
68
  end