xsoar-cli 2.4.1__tar.gz → 2.4.3__tar.gz

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 (173) hide show
  1. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/CHANGELOG.md +5 -0
  2. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/PKG-INFO +2 -2
  3. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/_version.py +2 -2
  4. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/manifest/commands.py +21 -0
  5. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/xsoar_client/artifact_providers/azure.py +7 -2
  6. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/xsoar_client/artifact_providers/base.py +8 -2
  7. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/xsoar_client/artifact_providers/s3.py +7 -2
  8. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/xsoar_client/packs.py +7 -5
  9. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/cli/test_manifest.py +64 -0
  10. xsoar_cli-2.4.3/tests/cli/test_pack.py +48 -0
  11. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/unit/test_artifact_azure.py +2 -3
  12. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/unit/test_artifact_s3.py +12 -3
  13. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/unit/test_packs.py +1 -1
  14. xsoar_cli-2.4.1/tests/cli/test_pack.py +0 -18
  15. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/.github/workflows/main.yml +0 -0
  16. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/.github/workflows/pull-request-open.yml +0 -0
  17. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/.github/workflows/release.yml +0 -0
  18. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/.github/workflows/update-changelog.yml +0 -0
  19. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/.gitignore +0 -0
  20. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/CLAUDE.md +0 -0
  21. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/CONTRIBUTING.md +0 -0
  22. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/LICENSE.txt +0 -0
  23. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/README.md +0 -0
  24. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/pyproject.toml +0 -0
  25. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/__init__.py +0 -0
  26. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/cli.py +0 -0
  27. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/__init__.py +0 -0
  28. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/case/README.md +0 -0
  29. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/case/__init__.py +0 -0
  30. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/case/commands.py +0 -0
  31. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/completions/README.md +0 -0
  32. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/completions/__init__.py +0 -0
  33. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/completions/commands.py +0 -0
  34. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/config/README.md +0 -0
  35. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/config/__init__.py +0 -0
  36. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/config/commands.py +0 -0
  37. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/content/README.md +0 -0
  38. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/content/__init__.py +0 -0
  39. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/content/commands.py +0 -0
  40. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/execute/README.md +0 -0
  41. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/execute/__init__.py +0 -0
  42. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/execute/commands.py +0 -0
  43. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/graph/README.md +0 -0
  44. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/graph/__init__.py +0 -0
  45. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/graph/commands.py +0 -0
  46. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/integration/README.md +0 -0
  47. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/integration/__init__.py +0 -0
  48. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/integration/commands.py +0 -0
  49. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/manifest/README.md +0 -0
  50. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/manifest/__init__.py +0 -0
  51. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/pack/README.md +0 -0
  52. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/pack/__init__.py +0 -0
  53. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/pack/commands.py +0 -0
  54. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/plugins/README.md +0 -0
  55. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/plugins/__init__.py +0 -0
  56. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/plugins/commands.py +0 -0
  57. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/rbac/README.md +0 -0
  58. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/rbac/__init__.py +0 -0
  59. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/commands/rbac/commands.py +0 -0
  60. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/configuration.py +0 -0
  61. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/error_handling/__init__.py +0 -0
  62. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/error_handling/connection.py +0 -0
  63. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/error_handling/http.py +0 -0
  64. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/log.py +0 -0
  65. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/plugins/README.md +0 -0
  66. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/plugins/__init__.py +0 -0
  67. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/plugins/manager.py +0 -0
  68. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/utilities/__init__.py +0 -0
  69. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/utilities/config_file.py +0 -0
  70. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/utilities/content.py +0 -0
  71. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/utilities/download_content_handlers.py +0 -0
  72. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/utilities/manifest.py +0 -0
  73. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/utilities/output.py +0 -0
  74. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/utilities/validators.py +0 -0
  75. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/utilities/version_check.py +0 -0
  76. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/xsoar_client/__init__.py +0 -0
  77. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/xsoar_client/artifact_providers/__init__.py +0 -0
  78. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/xsoar_client/cases.py +0 -0
  79. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/xsoar_client/client.py +0 -0
  80. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/xsoar_client/constants.py +0 -0
  81. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/xsoar_client/content.py +0 -0
  82. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/xsoar_client/execution.py +0 -0
  83. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/xsoar_client/integrations.py +0 -0
  84. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/src/xsoar_cli/xsoar_client/rbac.py +0 -0
  85. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/__init__.py +0 -0
  86. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/cli/__init__.py +0 -0
  87. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/cli/conftest.py +0 -0
  88. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/cli/test_base.py +0 -0
  89. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/cli/test_case.py +0 -0
  90. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/cli/test_completions.py +0 -0
  91. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/cli/test_config.py +0 -0
  92. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/cli/test_content.py +0 -0
  93. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/cli/test_execute.py +0 -0
  94. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/cli/test_graph.py +0 -0
  95. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/cli/test_plugins.py +0 -0
  96. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/conftest.py +0 -0
  97. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/fixtures/cases/create.json +0 -0
  98. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/fixtures/cases/get.json +0 -0
  99. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/fixtures/content/automation_search.json +0 -0
  100. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/fixtures/content/playbook_search.json +0 -0
  101. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/fixtures/content/user_commands.json +0 -0
  102. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/fixtures/integrations/instances.json +0 -0
  103. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/fixtures/manifest/manifest_base.json +0 -0
  104. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/fixtures/manifest/manifest_invalid.json +0 -0
  105. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/fixtures/manifest/manifest_with_pack_not_on_server.json +0 -0
  106. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/fixtures/manifest/server_base_response.json +0 -0
  107. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/fixtures/manifest/server_base_response_missing_one_pack.json +0 -0
  108. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/fixtures/manifest/server_base_response_with_updates.json +0 -0
  109. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/fixtures/manifest/server_base_response_with_updates_and_one_extra.json +0 -0
  110. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/fixtures/packs/installed.json +0 -0
  111. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/fixtures/packs/installed_expired.json +0 -0
  112. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/fixtures/rbac/roles.json +0 -0
  113. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/fixtures/rbac/user_groups.json +0 -0
  114. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/fixtures/rbac/users.json +0 -0
  115. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Download/playbook-empty.yml +0 -0
  116. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_CommonPlaybooks/.pack-ignore +0 -0
  117. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_CommonPlaybooks/.secrets-ignore +0 -0
  118. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_CommonPlaybooks/Author_image.png +0 -0
  119. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_CommonPlaybooks/Playbooks/GenericPlaybook.yml +0 -0
  120. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_CommonPlaybooks/README.md +0 -0
  121. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_CommonPlaybooks/pack_metadata.json +0 -0
  122. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_CommonScripts/.pack-ignore +0 -0
  123. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_CommonScripts/.secrets-ignore +0 -0
  124. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_CommonScripts/Author_image.png +0 -0
  125. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_CommonScripts/README.md +0 -0
  126. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_CommonScripts/Scripts/GenericScript/GenericScript.py +0 -0
  127. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_CommonScripts/Scripts/GenericScript/GenericScript.yml +0 -0
  128. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_CommonScripts/Scripts/GenericScript/README.md +0 -0
  129. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_CommonScripts/pack_metadata.json +0 -0
  130. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_EDR/.pack-ignore +0 -0
  131. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_EDR/.secrets-ignore +0 -0
  132. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_EDR/Author_image.png +0 -0
  133. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_EDR/Playbooks/EDR_InitialTriage.yml +0 -0
  134. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_EDR/README.md +0 -0
  135. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_EDR/Scripts/EDR_FetchFile/EDR_FetchFile.py +0 -0
  136. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_EDR/Scripts/EDR_FetchFile/EDR_FetchFile.yml +0 -0
  137. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_EDR/Scripts/EDR_FetchFile/README.md +0 -0
  138. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_EDR/Scripts/EDR_Triage/EDR_Triage.py +0 -0
  139. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_EDR/Scripts/EDR_Triage/EDR_Triage.yml +0 -0
  140. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_EDR/Scripts/EDR_Triage/README.md +0 -0
  141. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_EDR/Scripts/LegacyItem/LegacyItem.py +0 -0
  142. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_EDR/Scripts/LegacyItem/LegacyItem.yml +0 -0
  143. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_EDR/Scripts/LegacyItem/README.md +0 -0
  144. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_EDR/Scripts/LegacyItem/test_data/basescript-dummy.json +0 -0
  145. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_EDR/pack_metadata.json +0 -0
  146. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_Layouts/.pack-ignore +0 -0
  147. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_Layouts/.secrets-ignore +0 -0
  148. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_Layouts/Author_image.png +0 -0
  149. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_Layouts/Layouts/layoutscontainer-GenericLayout.json +0 -0
  150. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_Layouts/README.md +0 -0
  151. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/MyOrg_Layouts/pack_metadata.json +0 -0
  152. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/mock_content/Packs/Not_applicable/Playbooks/Empty.yml +0 -0
  153. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/unit/__init__.py +0 -0
  154. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/unit/conftest.py +0 -0
  155. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/unit/test_artifact_base.py +0 -0
  156. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/unit/test_case_commands.py +0 -0
  157. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/unit/test_cases.py +0 -0
  158. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/unit/test_client.py +0 -0
  159. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/unit/test_config_file.py +0 -0
  160. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/unit/test_content_domain.py +0 -0
  161. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/unit/test_content_filters.py +0 -0
  162. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/unit/test_content_handlers.py +0 -0
  163. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/unit/test_error_handling.py +0 -0
  164. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/unit/test_execution.py +0 -0
  165. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/unit/test_integrations.py +0 -0
  166. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/unit/test_main.py +0 -0
  167. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/unit/test_manifest_utils.py +0 -0
  168. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/unit/test_output.py +0 -0
  169. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/unit/test_plugin_manager.py +0 -0
  170. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/unit/test_rbac.py +0 -0
  171. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/unit/test_validators.py +0 -0
  172. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/tests/unit/test_version_check.py +0 -0
  173. {xsoar_cli-2.4.1 → xsoar_cli-2.4.3}/uv.lock +0 -0
@@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [2.4.2] - 2026-09-16
10
+
11
+ ## [2.4.1] - 2026-06-19
12
+
9
13
  ## [2.4.0] - 2026-06-17
10
14
 
11
15
  ### Added
@@ -31,6 +35,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
31
35
 
32
36
  ### Fixed
33
37
 
38
+ - `manifest update` no longer crashes with `ValueError: max() iterable argument is empty` when a custom pack is installed on the XSOAR server but has no artifacts in the configured artifact repository. The command now skips such packs (they are already reported in the pre-existing "installed but not found in artifacts repo" warning) and continues updating the remaining packs. As part of the fix, `S3ArtifactProvider.get_latest_version()` and `AzureArtifactProvider.get_latest_version()` now return `None` instead of raising when the pack has no versions in the repo, and `Packs.get_outdated()` was updated to treat `None` as the skip signal so `pack get-outdated` no longer crashes with `TypeError: unsupported format string passed to NoneType.__format__` on the same class of orphan pack.
34
39
  - `content get-detached` now returns only the content items that are actually detached. The previous query returned all system items, so the command reported every system script (or playbook) as detached instead of just the detached ones. Results are now filtered on each item's `detached` field.
35
40
 
36
41
  ## [2.3.0] - 2026-06-04
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: xsoar-cli
3
- Version: 2.4.1
3
+ Version: 2.4.3
4
4
  Summary: A command-line interface for managing Palo Alto Networks XSOAR (Cortex XSOAR)
5
5
  Project-URL: Documentation, https://github.com/tlium/xsoar-cli#readme
6
6
  Project-URL: Issues, https://github.com/tlium/xsoar-cli/issues
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '2.4.1'
22
- __version_tuple__ = version_tuple = (2, 4, 1)
21
+ __version__ = version = '2.4.3'
22
+ __version_tuple__ = version_tuple = (2, 4, 3)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -190,12 +190,33 @@ def update(ctx: click.Context, environment: str | None, manifest: str) -> None:
190
190
  click.echo(f" - {pack_id}", err=True)
191
191
 
192
192
  changes_made = False
193
+ skipped_custom_packs = set(result.skipped)
193
194
  for key in MANIFEST_KEYS:
194
195
  custom = key == "custom_packs"
195
196
  pack_type = "Custom" if custom else "Marketplace"
196
197
  for index, manifest_pack in enumerate(manifest_data[key]):
197
198
  if custom:
199
+ if manifest_pack["id"] in skipped_custom_packs:
200
+ # Pack is installed on the server but has no artifacts in the repo.
201
+ # Already surfaced to the user via the warning above.
202
+ logger.debug(
203
+ "%s pack '%s' skipped: not found in artifacts repo",
204
+ pack_type,
205
+ manifest_pack["id"],
206
+ )
207
+ continue
198
208
  latest = xsoar_client.artifact_provider.get_latest_version(manifest_pack["id"]) # ty: ignore[unresolved-attribute]
209
+ if latest is None:
210
+ # Defensive guard: the artifact provider reports no versions for this
211
+ # pack. This overlaps with the skipped_custom_packs check above, but
212
+ # keeps update() safe if a pack is missing from the repo without
213
+ # having been flagged by get_outdated().
214
+ logger.debug(
215
+ "%s pack '%s' skipped: no versions returned by artifact provider",
216
+ pack_type,
217
+ manifest_pack["id"],
218
+ )
219
+ continue
199
220
  else:
200
221
  pack = next((item for item in outdated_installed_packs if item["id"] == manifest_pack["id"]), None)
201
222
  if not pack:
@@ -58,9 +58,14 @@ class AzureArtifactProvider(BaseArtifactProvider):
58
58
  download_stream = self.container_client.download_blob(blob=key_name)
59
59
  return download_stream.readall()
60
60
 
61
- def get_latest_version(self, pack_id: str) -> str:
62
- """Fetch the latest version of a Pack"""
61
+ def get_latest_version(self, pack_id: str) -> str | None:
62
+ """Fetch the latest version of a Pack.
63
+
64
+ Returns None if the pack has no artifacts in the container.
65
+ """
63
66
  prefix = f"content/packs/{pack_id}/"
64
67
  iter_names = self.container_client.list_blob_names(name_starts_with=prefix)
65
68
  version_list = [x.split("/")[3] for x in list(iter_names)]
69
+ if not version_list:
70
+ return None
66
71
  return str(max(version_list, key=version.parse))
@@ -22,8 +22,14 @@ class BaseArtifactProvider(ABC):
22
22
  ...
23
23
 
24
24
  @abstractmethod
25
- def get_latest_version(self, pack_id: str) -> str:
26
- """Get the latest version of a pack."""
25
+ def get_latest_version(self, pack_id: str) -> str | None:
26
+ """Get the latest version of a pack.
27
+
28
+ Returns the highest available version string, or None if the pack has
29
+ no artifacts in the storage backend. Callers must handle the None case
30
+ (typically a pack installed on the server but missing from the artifact
31
+ repository).
32
+ """
27
33
  ...
28
34
 
29
35
  def get_pack_path(self, pack_id: str, pack_version: str) -> str:
@@ -49,8 +49,11 @@ class S3ArtifactProvider(BaseArtifactProvider):
49
49
  response = obj.get()
50
50
  return response["Body"].read()
51
51
 
52
- def get_latest_version(self, pack_id: str) -> str:
53
- """Fetch the latest version of a Pack."""
52
+ def get_latest_version(self, pack_id: str) -> str | None:
53
+ """Fetch the latest version of a Pack.
54
+
55
+ Returns None if the pack has no artifacts in the S3 bucket.
56
+ """
54
57
  client = self.session.client("s3", verify=self.verify_ssl)
55
58
  result = client.list_objects_v2(
56
59
  Bucket=self.bucket_name,
@@ -58,4 +61,6 @@ class S3ArtifactProvider(BaseArtifactProvider):
58
61
  Delimiter="/",
59
62
  )
60
63
  version_list = [x["Prefix"].split("/")[3] for x in result.get("CommonPrefixes", [])]
64
+ if not version_list:
65
+ return None
61
66
  return str(max(version_list, key=version.parse))
@@ -136,9 +136,8 @@ class Packs:
136
136
  if pack["author"] in self.custom_pack_authors:
137
137
  if not self.client.artifact_provider:
138
138
  raise RuntimeError("No artifact provider configured")
139
- try:
140
- latest_version = self.client.artifact_provider.get_latest_version(pack["id"])
141
- except ValueError:
139
+ latest_version = self.client.artifact_provider.get_latest_version(pack["id"])
140
+ if latest_version is None:
142
141
  logger.warning("Custom pack '%s' installed on XSOAR server, but cannot find pack in artifacts repo", pack["id"])
143
142
  skipped.append(pack["id"])
144
143
  continue
@@ -164,8 +163,11 @@ class Packs:
164
163
 
165
164
  return OutdatedResult(outdated=update_available, skipped=skipped)
166
165
 
167
- def get_latest_custom_version(self, pack_id: str) -> str:
168
- """Gets the latest version of a custom pack from the artifacts repository."""
166
+ def get_latest_custom_version(self, pack_id: str) -> str | None:
167
+ """Gets the latest version of a custom pack from the artifacts repository.
168
+
169
+ Returns None if the pack has no artifacts in the repository.
170
+ """
169
171
  if not self.client.artifact_provider:
170
172
  raise RuntimeError("No artifact provider configured")
171
173
  return self.client.artifact_provider.get_latest_version(pack_id)
@@ -115,6 +115,70 @@ class TestManifestValidate:
115
115
  assert mock_xsoar_env.client.packs.is_available.call_count == 2
116
116
 
117
117
 
118
+ class TestManifestUpdate:
119
+ """Tests for ``manifest update``."""
120
+
121
+ def test_skips_custom_pack_missing_from_artifacts(self, invoke: InvokeHelper, mock_xsoar_env, tmp_path: Path) -> None:
122
+ """Regression test: a custom pack installed on the server but missing from
123
+ the artifacts repo is surfaced in the warning and then skipped, without
124
+ crashing on an empty version list."""
125
+ from xsoar_cli.xsoar_client.packs import OutdatedResult
126
+
127
+ manifest = tmp_path / "xsoar_config.json"
128
+ manifest.write_text(
129
+ json.dumps(
130
+ {
131
+ "custom_packs": [{"id": "OrphanPack", "version": "1.0.0"}],
132
+ "marketplace_packs": [],
133
+ }
134
+ )
135
+ )
136
+ mock_xsoar_env.client.packs.get_outdated.return_value = OutdatedResult(
137
+ outdated=[],
138
+ skipped=["OrphanPack"],
139
+ )
140
+ # If get_latest_version is reached for the orphan pack, this would
141
+ # historically raise ValueError. The command must not call it.
142
+ mock_xsoar_env.client.artifact_provider.get_latest_version.return_value = None
143
+
144
+ result = invoke(["manifest", "update", str(manifest)])
145
+
146
+ assert result.exit_code == 0, result.output
147
+ assert "OrphanPack" in result.output
148
+ assert "installed but not found in artifacts repo" in result.output
149
+ mock_xsoar_env.client.artifact_provider.get_latest_version.assert_not_called()
150
+ # Manifest must remain unchanged.
151
+ assert json.loads(manifest.read_text()) == {
152
+ "custom_packs": [{"id": "OrphanPack", "version": "1.0.0"}],
153
+ "marketplace_packs": [],
154
+ }
155
+
156
+ def test_skips_when_provider_returns_none(self, invoke: InvokeHelper, mock_xsoar_env, tmp_path: Path) -> None:
157
+ """Defensive guard: even if a pack is not in the skipped list, a None from
158
+ the artifact provider is handled cleanly instead of raising."""
159
+ from xsoar_cli.xsoar_client.packs import OutdatedResult
160
+
161
+ manifest = tmp_path / "xsoar_config.json"
162
+ manifest.write_text(
163
+ json.dumps(
164
+ {
165
+ "custom_packs": [{"id": "MyOrg_EDR", "version": "1.0.0"}],
166
+ "marketplace_packs": [],
167
+ }
168
+ )
169
+ )
170
+ mock_xsoar_env.client.packs.get_outdated.return_value = OutdatedResult(
171
+ outdated=[],
172
+ skipped=[],
173
+ )
174
+ mock_xsoar_env.client.artifact_provider.get_latest_version.return_value = None
175
+
176
+ result = invoke(["manifest", "update", str(manifest)])
177
+
178
+ assert result.exit_code == 0, result.output
179
+ mock_xsoar_env.client.artifact_provider.get_latest_version.assert_called_once_with("MyOrg_EDR")
180
+
181
+
118
182
  class TestManifestValidateOnlyChanged:
119
183
  """Tests for ``manifest validate --only-changed``."""
120
184
 
@@ -0,0 +1,48 @@
1
+ """CLI integration tests for the ``pack`` command group."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING
6
+
7
+ if TYPE_CHECKING:
8
+ from tests.cli.conftest import InvokeHelper
9
+
10
+
11
+ class TestPackGroup:
12
+ def test_shows_help(self, invoke: InvokeHelper) -> None:
13
+ result = invoke(["pack"])
14
+ assert result.exit_code == 0
15
+
16
+ def test_help_flag(self, invoke: InvokeHelper) -> None:
17
+ result = invoke(["pack", "--help"])
18
+ assert result.exit_code == 0
19
+
20
+
21
+ class TestPackGetOutdated:
22
+ """Tests for ``pack get-outdated``."""
23
+
24
+ def test_reports_orphan_custom_pack_and_lists_outdated(self, invoke: InvokeHelper, mock_xsoar_env) -> None:
25
+ """Regression test: an orphan custom pack (installed on the server but
26
+ missing from the artifacts repo) is surfaced in the warning list and
27
+ does not cause a formatting crash on ``pack['latest']``."""
28
+ from xsoar_cli.xsoar_client.packs import OutdatedResult
29
+
30
+ mock_xsoar_env.client.packs.get_outdated.return_value = OutdatedResult(
31
+ outdated=[
32
+ {
33
+ "id": "CommonScripts",
34
+ "currentVersion": "1.14.20",
35
+ "latest": "1.15.0",
36
+ "author": "Upstream",
37
+ },
38
+ ],
39
+ skipped=["OrphanPack"],
40
+ )
41
+
42
+ result = invoke(["pack", "get-outdated"])
43
+
44
+ assert result.exit_code == 0, result.output
45
+ assert "OrphanPack" in result.output
46
+ assert "installed but not found in artifacts repo" in result.output
47
+ assert "CommonScripts" in result.output
48
+ assert "1.15.0" in result.output
@@ -225,11 +225,10 @@ class TestGetLatestVersion:
225
225
 
226
226
  assert result == "1.0.0"
227
227
 
228
- def test_raises_on_empty_listing(self) -> None:
228
+ def test_empty_listing_returns_none(self) -> None:
229
229
  provider = _make_provider()
230
230
  mock_container = MagicMock()
231
231
  mock_container.list_blob_names.return_value = []
232
232
  provider._container_client = mock_container
233
233
 
234
- with pytest.raises(ValueError):
235
- provider.get_latest_version("NonExistent")
234
+ assert provider.get_latest_version("NonExistent") is None
@@ -214,7 +214,7 @@ class TestGetLatestVersion:
214
214
 
215
215
  assert result == "1.0.0"
216
216
 
217
- def test_no_versions_raises(self) -> None:
217
+ def test_no_versions_returns_none(self) -> None:
218
218
  provider = _make_provider()
219
219
  mock_session = MagicMock()
220
220
  mock_client = MagicMock()
@@ -222,8 +222,17 @@ class TestGetLatestVersion:
222
222
  mock_session.client.return_value = mock_client
223
223
  provider._session = mock_session
224
224
 
225
- with pytest.raises(ValueError):
226
- provider.get_latest_version("MyPack")
225
+ assert provider.get_latest_version("MyPack") is None
226
+
227
+ def test_empty_common_prefixes_returns_none(self) -> None:
228
+ provider = _make_provider()
229
+ mock_session = MagicMock()
230
+ mock_client = MagicMock()
231
+ mock_client.list_objects_v2.return_value = {"CommonPrefixes": []}
232
+ mock_session.client.return_value = mock_client
233
+ provider._session = mock_session
234
+
235
+ assert provider.get_latest_version("MyPack") is None
227
236
 
228
237
  def test_respects_verify_ssl(self) -> None:
229
238
  provider = _make_provider(verify_ssl=False)
@@ -454,7 +454,7 @@ class TestGetOutdated:
454
454
  mock_client.make_request.return_value = _mock_response(_INSTALLED_EXPIRED)
455
455
 
456
456
  provider = MagicMock()
457
- provider.get_latest_version.side_effect = ValueError("Pack not found")
457
+ provider.get_latest_version.return_value = None
458
458
  mock_client.artifact_provider = provider
459
459
 
460
460
  packs = Packs(mock_client, custom_pack_authors=["MyOrg"])
@@ -1,18 +0,0 @@
1
- """CLI integration tests for the ``pack`` command group."""
2
-
3
- from __future__ import annotations
4
-
5
- from typing import TYPE_CHECKING
6
-
7
- if TYPE_CHECKING:
8
- from tests.cli.conftest import InvokeHelper
9
-
10
-
11
- class TestPackGroup:
12
- def test_shows_help(self, invoke: InvokeHelper) -> None:
13
- result = invoke(["pack"])
14
- assert result.exit_code == 0
15
-
16
- def test_help_flag(self, invoke: InvokeHelper) -> None:
17
- result = invoke(["pack", "--help"])
18
- assert result.exit_code == 0
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes