xsoar-cli 1.0.9__py3-none-any.whl

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.
xsoar_cli/utilities.py ADDED
@@ -0,0 +1,159 @@
1
+ import contextlib
2
+ import json
3
+ from collections.abc import Callable
4
+ from functools import update_wrapper
5
+ from pathlib import Path
6
+
7
+ import click
8
+ from xsoar_client.artifact_providers.azure import AzureArtifactProvider
9
+ from xsoar_client.artifact_providers.s3 import S3ArtifactProvider
10
+ from xsoar_client.config import ClientConfig
11
+ from xsoar_client.xsoar_client import Client
12
+
13
+
14
+ def parse_string_to_dict(input_string: str | None, delimiter: str) -> dict:
15
+ if not input_string:
16
+ return {}
17
+ # Parse a string into a python dictionary
18
+ pairs = [pair.split("=", 1) for pair in input_string.split(delimiter)]
19
+ # Filter pairs that have exactly 2 parts (key and value) after splitting by "="
20
+ valid_pairs = [pair for pair in pairs if len(pair) == 2] # noqa: PLR2004
21
+ return {key.strip(): value.strip() for key, value in valid_pairs}
22
+
23
+
24
+ def get_config_file_template_contents() -> dict:
25
+ return {
26
+ "default_environment": "dev",
27
+ "default_new_case_type": "",
28
+ "custom_pack_authors": ["SOMEONE"],
29
+ "server_config": {
30
+ "dev": {
31
+ "base_url": "https://xsoar.example.com",
32
+ "api_token": "YOUR API TOKEN HERE",
33
+ "artifacts_location": "S3",
34
+ "s3_bucket_name": "xsoar-cicd",
35
+ "verify_ssl": "/path/to/your/CA_bundle.pem",
36
+ "server_version": 6,
37
+ },
38
+ "prod": {
39
+ "base_url": "https://api-xsoar-v8.example.com",
40
+ "api_token": "YOUR API TOKEN HERE",
41
+ "artifacts_location": "S3",
42
+ "s3_bucket_name": "xsoar-cicd-prod",
43
+ "verify_ssl": False,
44
+ "server_version": 8,
45
+ "xsiam_auth_id": 123,
46
+ },
47
+ },
48
+ }
49
+
50
+
51
+ def validate_environments(*args, **kwargs) -> bool: # noqa: ANN002, ANN003
52
+ return all(env in kwargs["ctx"].obj["server_envs"] for env in args)
53
+
54
+
55
+ def get_config_file_path() -> Path:
56
+ homedir = Path.home()
57
+ config_file_path = homedir / ".config/xsoar-cli"
58
+ config_file_name = "config.json"
59
+ return Path(config_file_path / config_file_name)
60
+
61
+
62
+ def get_config_file_contents(filepath: Path): # noqa: ANN201
63
+ return json.load(filepath.open("r"))
64
+
65
+
66
+ def load_config(f: Callable) -> Callable:
67
+ """
68
+ This function is only to be used as a decorator for various xsoar-cli subcommands. Loads and parses the config file if
69
+ exists, or prompts the user to create one otherwise.
70
+ If an illegal environment is provided by the user, i.e by invoking "xsoar-cli command --environment illegal subcommand",
71
+ then prints out helpful error message and returns non-zero exit value.
72
+ """
73
+
74
+ @click.pass_context
75
+ def wrapper(ctx: click.Context, *args, **kwargs) -> Callable: # noqa: ANN002, ANN003
76
+ config_file_path = get_config_file_path()
77
+ if not config_file_path.is_file():
78
+ click.echo(
79
+ 'Config file not found. Please create a template config file using "xsoar-cli config create" and replace placeholder values before retrying.',
80
+ )
81
+ ctx.exit(1)
82
+ config = get_config_file_contents(config_file_path)
83
+ parse_config(config, ctx)
84
+ if (
85
+ "environment" in ctx.params
86
+ and ctx.params["environment"] not in ctx.obj["server_envs"]
87
+ and ctx.params["environment"] is not None
88
+ ):
89
+ click.echo(f"Invalid environment: {ctx.params['environment']}")
90
+ click.echo(f"Available environments as defined in config file are: {list(ctx.obj['server_envs'])}")
91
+ ctx.exit(1)
92
+ return ctx.invoke(f, *args, **kwargs)
93
+
94
+ return update_wrapper(wrapper, f)
95
+
96
+
97
+ def fail_if_no_artifacts_provider(f: Callable) -> Callable:
98
+ """
99
+ This function is only to be used as a decorator for various xsoar-cli subcommands, and only AFTER the load_config decorator has been called.
100
+ The intention is to fail gracefully if any subcommand is executed which requires an artifacts provider."
101
+ """
102
+
103
+ @click.pass_context
104
+ def wrapper(ctx: click.Context, *args, **kwargs) -> Callable: # noqa: ANN002, ANN003
105
+ if "environment" in ctx.params: # noqa: SIM108
106
+ key = ctx.params["environment"]
107
+ else:
108
+ key = ctx.obj["default_environment"]
109
+
110
+ with contextlib.suppress(KeyError):
111
+ location = ctx.obj["server_envs"][key].get("artifacts_location", None)
112
+ if not location:
113
+ click.echo("Command requires artifacts repository, but no artifacts_location defined in config.")
114
+ ctx.exit(1)
115
+ return ctx.invoke(f, *args, **kwargs)
116
+
117
+ return update_wrapper(wrapper, f)
118
+
119
+
120
+ def parse_config(config: dict, ctx: click.Context) -> None:
121
+ # Set the two XSOAR client objects in Click Context for use in later functions
122
+ ctx.obj = {}
123
+ ctx.obj["default_environment"] = config["default_environment"]
124
+ ctx.obj["custom_pack_authors"] = config["custom_pack_authors"]
125
+ ctx.obj["default_new_case_type"] = config["default_new_case_type"]
126
+ ctx.obj["server_envs"] = {}
127
+ for key in config["server_config"]:
128
+ ctx.obj["server_envs"][key] = {}
129
+ server_version = config["server_config"][key]["server_version"]
130
+ custom_pack_authors = config["custom_pack_authors"]
131
+
132
+ server_url = config["server_config"][key]["base_url"]
133
+ api_token = config["server_config"][key]["api_token"]
134
+ verify_ssl = config["server_config"][key]["verify_ssl"]
135
+ xsiam_auth_id = config["server_config"][key].get("xsiam_auth_id", "")
136
+
137
+ xsoar_client_config = ClientConfig(
138
+ server_version=server_version,
139
+ custom_pack_authors=custom_pack_authors,
140
+ api_token=api_token,
141
+ server_url=server_url,
142
+ xsiam_auth_id=xsiam_auth_id,
143
+ verify_ssl=verify_ssl,
144
+ )
145
+
146
+ artifacts_location = config["server_config"][key].get("artifacts_location", None)
147
+ if artifacts_location == "S3":
148
+ bucket_name = config["server_config"][key].get("s3_bucket_name", None)
149
+ artifact_provider = S3ArtifactProvider(bucket_name=bucket_name)
150
+ elif artifacts_location == "Azure":
151
+ url = config["server_config"][key]["azure_blobstore_url"]
152
+ container_name = config["server_config"][key]["azure_container_name"]
153
+ access_token = config["server_config"][key].get("azure_storage_access_token", "")
154
+ artifact_provider = AzureArtifactProvider(storage_account_url=url, container_name=container_name, access_token=access_token)
155
+ else:
156
+ artifact_provider = None
157
+ xsoar_client = Client(config=xsoar_client_config, artifact_provider=artifact_provider)
158
+
159
+ ctx.obj["server_envs"][key]["xsoar_client"] = xsoar_client
@@ -0,0 +1,209 @@
1
+ Metadata-Version: 2.4
2
+ Name: xsoar-cli
3
+ Version: 1.0.9
4
+ Project-URL: Documentation, https://github.com/tlium/xsoar-cli#readme
5
+ Project-URL: Issues, https://github.com/tlium/xsoar-cli/issues
6
+ Project-URL: Source, https://github.com/tlium/xsoar-cli
7
+ Author-email: Torbjørn Lium <torben@lium.org>
8
+ License-Expression: MIT
9
+ License-File: LICENSE.txt
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Programming Language :: Python
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: Implementation :: CPython
16
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
17
+ Requires-Python: <3.13,>=3.10
18
+ Requires-Dist: click==8.1.8
19
+ Requires-Dist: pyyaml>=6.0.2
20
+ Requires-Dist: xsoar-client>=2.0.0
21
+ Requires-Dist: xsoar-dependency-graph>=0.0.3
22
+ Description-Content-Type: text/markdown
23
+
24
+ # xsoar-cli
25
+
26
+ ![PyPI - Version](https://img.shields.io/pypi/v/xsoar-cli) [![Python](https://img.shields.io/pypi/pyversions/xsoar-cli.svg)](https://pypi.org/project/xsoar-cli/) [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
27
+
28
+ A command-line interface for managing Palo Alto Networks XSOAR (Cortex XSOAR) that streamlines content development and deployment workflows.
29
+
30
+ **Key Features:**
31
+ - **Content Management**: Validate and deploy content packs with declarative manifests
32
+ - **Case Operations**: Retrieve case details and clone cases between environments
33
+ - **Playbook Development**: Download playbooks for local editing and testing
34
+ - **Dependency Analysis**: Generate visual graphs of content pack dependencies
35
+ - **Plugin System**: Extend functionality with custom commands
36
+
37
+ Perfect for DevOps teams using CI/CD pipelines to manage XSOAR content stored in [content repositories](https://github.com/demisto/content-ci-cd-template).
38
+
39
+ Pull Requests are very welcome and appreciated! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
40
+
41
+ ## Quick Start
42
+
43
+ ```bash
44
+ # Install
45
+ pip install xsoar-cli
46
+
47
+ # Create configuration file
48
+ xsoar-cli config create
49
+
50
+ # Validate and deploy your content
51
+ xsoar-cli manifest validate ./xsoar_config.json
52
+ xsoar-cli manifest deploy ./xsoar_config.json
53
+
54
+ # Get help on available commands
55
+ xsoar-cli --help
56
+ ```
57
+
58
+ ## Important Notes
59
+
60
+ This CLI tool is made to be run from the root of a content repository. Some commands depend on files located in your content repository or expects a certain directory structure to be available from your currently working directory.
61
+
62
+ ## Requirements
63
+
64
+ ### Core Requirements
65
+ - XSOAR servers version 6 or 8
66
+ - Python 3.9+ (only tested with Python 3.12, earlier versions may work but are not guaranteed)
67
+
68
+ ### Additional Requirements
69
+ - **AWS SDK for Python (Boto3)** - Only required when working with custom content packs stored in S3.
70
+ - **Azure SDK for Python**
71
+
72
+
73
+ ## Installation
74
+
75
+ ```bash
76
+ pip install xsoar-cli
77
+ ```
78
+
79
+ ## Upgrading
80
+
81
+ ```bash
82
+ pip install --upgrade xsoar-cli
83
+ ```
84
+
85
+ ## Uninstalling
86
+
87
+ ```bash
88
+ pip uninstall xsoar-cli
89
+ ```
90
+
91
+ ## Configuration
92
+
93
+ The xsoar-cli config file is located in `~/.config/xsoar-cli/config.json`. To create a configuration file from template, please run:
94
+
95
+ ```bash
96
+ xsoar-cli config create
97
+ ```
98
+
99
+ ### Configuration File Structure
100
+
101
+ After creating the config file, edit it with your XSOAR server details:
102
+
103
+ ```json
104
+ {
105
+ "default_environment": "xsoar6",
106
+ "default_new_case_type": "",
107
+ "custom_pack_authors": ["SOMEONE"],
108
+ "server_config": {
109
+ "xsoar6": {
110
+ "base_url": "https://xsoar-v6.example.com",
111
+ "api_token": "YOUR API TOKEN HERE",
112
+ "artifacts_location": "S3",
113
+ "s3_bucket_name": "xsoar-cicd",
114
+ "verify_ssl": "/path/to/your/CA_bundle.pem",
115
+ "server_version": 6
116
+ },
117
+ "xsoar8": {
118
+ "base_url": "https://xsoar-v8.example.com",
119
+ "api_token": "YOUR API TOKEN HERE",
120
+ "artifacts_location": "Azure",
121
+ "azure_blobstore_url": "https://some/url",
122
+ "azure_container_name": "some-container-name",
123
+ "verify_ssl": false,
124
+ "server_version": 8,
125
+ "xsiam_auth_id": 123
126
+ }
127
+ }
128
+ }
129
+ ```
130
+
131
+ ### Configuration Options
132
+
133
+ - **default_environment**: Which environment to use by default (e.g., "xsoar6")
134
+ - **default_new_case_type**: Default case type when creating new cases
135
+ - **custom_pack_authors**: List of author names used in your custom content packs. This helps xsoar-cli distinguish between your custom packs and marketplace packs. Use the same values you have in `pack_metadata.json` files.
136
+
137
+ - **server_config**: Define multiple XSOAR environments (xsoar6, xsoar8, etc.)
138
+ - **base_url**: Your XSOAR server URL
139
+ - **api_token**: API token for authentication (see XSOAR documentation for creating API keys)
140
+ - **artifacts_location**: Where artifacts are stored ("Azure" and "S3" is currently supported)
141
+ - **s3_bucket_name**: S3 bucket where your custom content packs are stored (only applicable if using "S3" artifacts location)
142
+ - **azure_blobstore_url** URL to your Azure BlobStore location (only applicable if using "Azure" artifats location)
143
+ - **azure_container_name** Name of the container where blobs should be stored (only applicable if using "Azure" artifats location)
144
+ - **verify_ssl**: SSL certificate verification - use `false` for self-signed certificates, or path to CA bundle
145
+ - **server_version**: XSOAR server version (6 or 8)
146
+ - **xsiam_auth_id**: Required for XSOAR 8 (XSIAM) - the authentication ID for API access
147
+
148
+ ### Validation
149
+
150
+ Test your configuration with:
151
+
152
+ ```bash
153
+ xsoar-cli config validate
154
+ ```
155
+
156
+ This will verify connectivity to all configured XSOAR environments.
157
+
158
+ ## Usage
159
+
160
+ ```bash
161
+ xsoar-cli <command> <sub-command> <args>
162
+ ```
163
+
164
+ For information about available commands, run `xsoar-cli` without arguments.
165
+
166
+ For more information on a specific command execute `xsoar-cli <command> --help`.
167
+
168
+ ### Commands
169
+
170
+ - **[case](src/xsoar_cli/case/README.md)** - Retrieve case details and clone cases between environments
171
+ - **[config](src/xsoar_cli/config/README.md)** - Create, validate, and manage CLI configuration files
172
+ - **[graph](src/xsoar_cli/graph/README.md)** - Generate visual dependency graphs for content packs
173
+ - **[manifest](src/xsoar_cli/manifest/README.md)** - Validate and deploy content using declarative manifests
174
+ - **[pack](src/xsoar_cli/pack/README.md)** - Manage content pack operations and information
175
+ - **[playbook](src/xsoar_cli/playbook/README.md)** - Download playbooks for local editing and development
176
+ - **[plugins](src/xsoar_cli/plugins/README.md)** - Extend CLI functionality with custom commands
177
+
178
+ ## Plugin System
179
+
180
+ xsoar-cli supports a plugin system that allows you to extend the CLI with custom commands. For complete documentation, examples, and usage instructions, see [Plugin System Documentation](src/xsoar_cli/plugins/README.md).
181
+
182
+ ## Troubleshooting
183
+
184
+ ### Common Issues
185
+
186
+ **"Config file not found"**
187
+ - Run `xsoar-cli config create` to generate a template configuration file
188
+ - Ensure the file exists at `~/.config/xsoar-cli/config.json`
189
+
190
+ **"Failed to reach pack" or connection errors**
191
+ - Verify your XSOAR server URL and API token in the config file
192
+ - Check network connectivity to your XSOAR server
193
+ - For custom packs: Ensure AWS credentials are configured and S3 bucket is accessible
194
+
195
+ **"Invalid environment"**
196
+ - Check that the environment name matches exactly what's defined in your config file
197
+ - Use `xsoar-cli config validate` to verify your configuration
198
+
199
+ **Python compatibility issues**
200
+ - Ensure you're using Python 3.9 or later
201
+ - Consider using Python 3.12 for best compatibility
202
+
203
+ ## Contributing
204
+
205
+ We welcome all contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines on how to contribute to this project.
206
+
207
+ ## License
208
+
209
+ `xsoar-cli` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.
@@ -0,0 +1,31 @@
1
+ xsoar_cli/__about__.py,sha256=cTSznV8o6zwE_gWFgbw2V8Fv6kDBG0hajt9f9FHdlzw,127
2
+ xsoar_cli/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
3
+ xsoar_cli/cli.py,sha256=iAlSeZe2iR6ciTVrJYLt-CDZk7b5I-hzHFXbYoXhupA,1342
4
+ xsoar_cli/utilities.py,sha256=fQGRD_FfltMuH282-61A_tIv_CdGxq3XPNK5eHLr110,6779
5
+ xsoar_cli/case/README.md,sha256=Qpf-HUdkboYoHU5GDkQG1EsQpX2wF7LKsW0CKxmqG1M,1903
6
+ xsoar_cli/case/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ xsoar_cli/case/commands.py,sha256=06UEPoSKutrBtAIbgpp_g6YzYXW2N9zx_KtRi16nPlg,5135
8
+ xsoar_cli/config/README.md,sha256=v8xvmuTV-goDRDn48Ko7VG6YZRy89KajBsGx38Jfj_I,1718
9
+ xsoar_cli/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ xsoar_cli/config/commands.py,sha256=6geg5FWufdKfv8mjZ9WYnhLu7ESv5ew7MYHcEg8y1aM,4476
11
+ xsoar_cli/graph/README.md,sha256=kyWIGs2Sd-OdqAaCWJjyvGpAhXhFcuqQwVqFBgzgWzk,861
12
+ xsoar_cli/graph/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ xsoar_cli/graph/commands.py,sha256=LKOpUu8r6KThJ5HdyjZlhpwLKRgMcEu7btBOQXwDkMs,1069
14
+ xsoar_cli/manifest/README.md,sha256=HfdhHlpyJFIm9fC37YaWAwXlG9arhGwpQf2aWO5OewY,3607
15
+ xsoar_cli/manifest/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ xsoar_cli/manifest/commands.py,sha256=XF_IyfyDTSaXE8FXayec1l5a3Bim-Au67T5UeBuF1W4,12048
17
+ xsoar_cli/pack/README.md,sha256=YYVBjxGT4aCQAu1CE16Yo5AnjdL_uh6T9bpAD2eSpl8,891
18
+ xsoar_cli/pack/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
+ xsoar_cli/pack/commands.py,sha256=1vGF8_mMemZt75qCBTau_M3dihSr79vc2vea8xr5h_Y,2063
20
+ xsoar_cli/playbook/README.md,sha256=00ohD9gH_Dt4vWlnPGJIpl_GwVHb274Xao8fR9SHAVc,1474
21
+ xsoar_cli/playbook/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ xsoar_cli/playbook/commands.py,sha256=nauCczvYvDsb2d2Wd71zADos-7vvSism6p2bDkgRJ5o,2950
23
+ xsoar_cli/plugins/README.md,sha256=MHeEEqg9QWfAql2n1iX90DJpbz4j1G2_4mWb80vVQac,2209
24
+ xsoar_cli/plugins/__init__.py,sha256=81IZsMbZsqrLdB6TjA9t6s3yS8FkuihliBFX4xZUpTo,1753
25
+ xsoar_cli/plugins/commands.py,sha256=UuX-oHpEHZaDWz3JxD79o3vJkJ4jBdxCMAWDXr-5pAE,9513
26
+ xsoar_cli/plugins/manager.py,sha256=qhLEeOmNDLsByRBztsADv2QLQjoBTmWxiKsB9pvy7DU,11024
27
+ xsoar_cli-1.0.9.dist-info/METADATA,sha256=1Fmcz4E70F_k4qEP9U9RHFnE2we8BJqrmJRTw2eEtJ0,8089
28
+ xsoar_cli-1.0.9.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
29
+ xsoar_cli-1.0.9.dist-info/entry_points.txt,sha256=s6Klu4QRekXsmZaBxMyFlE4Q-4_jIA9uijk4qIYUPvE,48
30
+ xsoar_cli-1.0.9.dist-info/licenses/LICENSE.txt,sha256=l6xnqWKshqwwTXt6ayO6MX8Uvygq0YnkUuFTNnR3ba4,1097
31
+ xsoar_cli-1.0.9.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ xsoar-cli = xsoar_cli.cli:cli
@@ -0,0 +1,9 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-present Torbjørn Lium <torben@lium.org>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.