xsoar-cli 1.0.2__py3-none-any.whl → 1.0.4__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.

Potentially problematic release.


This version of xsoar-cli might be problematic. Click here for more details.

xsoar_cli/__about__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  # SPDX-FileCopyrightText: 2025-present Torbjørn Lium <torben@lium.org>
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
- __version__ = "1.0.2"
4
+ __version__ = "1.0.4"
@@ -20,7 +20,7 @@ def case() -> None:
20
20
  @click.pass_context
21
21
  @load_config
22
22
  def get(ctx: click.Context, casenumber: int, environment: str) -> None:
23
- xsoar_client: Client = ctx.obj["server_envs"][environment]
23
+ xsoar_client: Client = ctx.obj["server_envs"][environment]["xsoar_client"]
24
24
  response = xsoar_client.get_case(casenumber)
25
25
  if response["total"] == 0 and not response["data"]:
26
26
  click.echo(f"Cannot find case ID {casenumber}")
@@ -40,7 +40,7 @@ def clone(ctx: click.Context, casenumber: int, source: str, dest: str) -> None:
40
40
  if not valid_envs:
41
41
  click.echo(f"Error: cannot find environments {source} and/or {dest} in config")
42
42
  ctx.exit(1)
43
- xsoar_source_client: Client = ctx.obj["server_envs"][source]
43
+ xsoar_source_client: Client = ctx.obj["server_envs"][source]["xsoar_client"]
44
44
  results = xsoar_source_client.get_case(casenumber)
45
45
  data = results["data"][0]
46
46
  # Dbot mirror info is irrelevant. This will be added again if applicable by XSOAR after ticket creation in dev.
@@ -57,7 +57,7 @@ def clone(ctx: click.Context, casenumber: int, source: str, dest: str) -> None:
57
57
  # Ensure that playbooks run immediately when the case is created
58
58
  data["createInvestigation"] = True
59
59
 
60
- xsoar_dest_client: Client = ctx.obj["server_envs"][dest]
60
+ xsoar_dest_client: Client = ctx.obj["server_envs"][dest]["xsoar_client"]
61
61
  case_data = xsoar_dest_client.create_case(data=data)
62
62
  click.echo(json.dumps(case_data, indent=4))
63
63
 
@@ -71,7 +71,7 @@ def clone(ctx: click.Context, casenumber: int, source: str, dest: str) -> None:
71
71
  @load_config
72
72
  def create(ctx: click.Context, environment: str, casetype: str, name: str, details: str) -> None:
73
73
  """Creates a new case in XSOAR. If invalid case type is specified as a command option, XSOAR will default to using Unclassified."""
74
- xsoar_client: Client = ctx.obj["server_envs"][environment]
74
+ xsoar_client: Client = ctx.obj["server_envs"][environment]["xsoar_client"]
75
75
  if not casetype:
76
76
  casetype = ctx.obj["default_new_case_type"]
77
77
  data = {
@@ -8,7 +8,13 @@ if TYPE_CHECKING:
8
8
 
9
9
  import contextlib
10
10
 
11
- from xsoar_cli.utilities import get_config_file_contents, get_config_file_path, get_config_file_template_contents, load_config
11
+ from xsoar_cli.utilities import (
12
+ fail_if_no_artifacts_provider,
13
+ get_config_file_contents,
14
+ get_config_file_path,
15
+ get_config_file_template_contents,
16
+ load_config,
17
+ )
12
18
 
13
19
 
14
20
  @click.group(help="Create/validate etc")
@@ -35,6 +41,7 @@ def show(ctx: click.Context, masked: bool) -> None:
35
41
  @click.option("--only-test-environment", default=None, show_default=True, help="Environment as defined in config file")
36
42
  @click.pass_context
37
43
  @load_config
44
+ @fail_if_no_artifacts_provider
38
45
  def validate(ctx: click.Context, only_test_environment: str) -> None:
39
46
  """Validates that the configuration file is JSON and tests connectivity for each XSOAR Client environment defined."""
40
47
  return_code = 0
@@ -44,7 +51,7 @@ def validate(ctx: click.Context, only_test_environment: str) -> None:
44
51
  # what the user specified in option
45
52
  continue
46
53
  click.echo(f'Testing "{server_env}" environment...', nl=False)
47
- xsoar_client: Client = ctx.obj["server_envs"][server_env]
54
+ xsoar_client: Client = ctx.obj["server_envs"][server_env]["xsoar_client"]
48
55
  try:
49
56
  xsoar_client.test_connectivity()
50
57
  except ConnectionError as ex:
@@ -53,6 +60,9 @@ def validate(ctx: click.Context, only_test_environment: str) -> None:
53
60
  return_code = 1
54
61
  continue
55
62
  click.echo("OK")
63
+ if ctx.obj["default_environment"] not in ctx.obj["server_envs"]:
64
+ click.echo(f'Error: default environment "{ctx.obj["default_environment"]}" not found in server config.')
65
+ return_code = 1
56
66
  ctx.exit(return_code)
57
67
 
58
68
 
@@ -1,23 +1,269 @@
1
- # Manifest
1
+ # Manifest Commands
2
2
 
3
- ## Validate
4
- Verifies that the xsoar_config.json manifest is valid JSON. Does a HTTP HEAD calls to every upstream content pack defined. Checks
5
- custom content pack availability in AWS S3 artefact repository.
3
+ The manifest commands help you manage XSOAR content pack deployments using a declarative configuration file (`xsoar_config.json`). This file defines which content packs should be installed on your XSOAR server and their specific versions.
4
+
5
+ ## Prerequisites
6
+
7
+ - Valid XSOAR CLI configuration file (`~/.config/xsoar-cli/config.json`)
8
+ - Access to XSOAR server API
9
+ - For custom packs: AWS S3 credentials configured (AWS S3 is currently the only supported artifacts repository provider)
10
+ - Content repository with proper directory structure
11
+
12
+ ## Manifest File Structure
13
+
14
+ The `xsoar_config.json` file contains two main sections:
15
+
16
+ ```json
17
+ {
18
+ "custom_packs": [
19
+ {
20
+ "id": "MyCustomPack",
21
+ "version": "1.0.0",
22
+ "_comment": "Optional comment for documentation"
23
+ }
24
+ ],
25
+ "marketplace_packs": [
26
+ {
27
+ "id": "CommonScripts",
28
+ "version": "1.20.0"
29
+ }
30
+ ]
31
+ }
32
+ ```
33
+
34
+ - **custom_packs**: Content packs developed by your organization, stored in AWS S3 (currently the only supported artifacts repository provider; pull requests for new providers are welcome!)
35
+ - **marketplace_packs**: Official Palo Alto Networks content packs from the marketplace
36
+ - **_comment**: Optional field for documentation/notes about specific pack versions
37
+
38
+ ## Commands
39
+
40
+ ### validate
41
+ Validates the manifest file and verifies all specified content packs are available.
42
+
43
+ **Usage:**
44
+ ```bash
45
+ xsoar-cli manifest validate [OPTIONS] MANIFEST_PATH
46
+ ```
47
+
48
+ **Options:**
49
+ - `--environment TEXT`: Environment name from config file (default: dev)
50
+
51
+ **Examples:**
52
+ ```bash
53
+ # Validate manifest in current directory
54
+ xsoar-cli manifest validate ./xsoar_config.json
55
+
56
+ # Validate with specific environment
57
+ xsoar-cli manifest validate --environment prod ./xsoar_config.json
58
+ ```
59
+
60
+ **What it checks:**
61
+ - JSON syntax validity
62
+ - Custom pack availability in S3 artifact repository
63
+ - Marketplace pack availability via HTTP connectivity
64
+ - Local pack metadata consistency for new packs in development
65
+
66
+ **Sample output:**
6
67
  ```
7
- xsoar-cli manifest validate /my/full/path/to/xsoar_config.json
8
- xsoar-cli manifest validate relative/path/to/xsoar_config.json
68
+ Manifest is valid JSON
69
+ Checking custom_packs availability ........................done.
70
+ Checking marketplace_packs availability ........................done.
71
+ Manifest is valid JSON and all packs are reachable.
9
72
  ```
10
73
 
11
- ## Update
12
- Updates and prompts the user to write the xsoar_config.json manifest with the latest available content packs. Both upstream and custom content packs are checked.
74
+ ### update
75
+ Compares installed packs against available versions and updates the manifest with latest versions.
76
+
77
+ **Usage:**
78
+ ```bash
79
+ xsoar-cli manifest update [OPTIONS] MANIFEST_PATH
13
80
  ```
14
- xsoar-cli manifest update /my/full/path/to/xsoar_config.json
15
- xsoar-cli manifest update relative/path/to/xsoar_config.json
81
+
82
+ **Options:**
83
+ - `--environment TEXT`: Environment name from config file (default: dev)
84
+
85
+ **Examples:**
86
+ ```bash
87
+ # Update manifest with latest versions
88
+ xsoar-cli manifest update ./xsoar_config.json
89
+
90
+ # Interactive prompts for each pack upgrade
91
+ xsoar-cli manifest update --environment staging ./xsoar_config.json
16
92
  ```
17
93
 
18
- ## Diff
19
- Queries the XSOAR server for installed packages and compares them to what is defined in the manifest. Prints out the diff.
94
+ **Behavior:**
95
+ - Queries XSOAR server for outdated packs
96
+ - Displays upgrade candidates in tabular format
97
+ - Prompts for confirmation on each upgrade
98
+ - Preserves `_comment` fields but shows warnings
99
+ - Updates manifest file on disk
100
+
101
+ **Sample output:**
20
102
  ```
21
- xsoar-cli manifest diff /my/full/path/to/xsoar_config.json
22
- xsoar-cli manifest diff relative/path/to/xsoar_config.json
103
+ Fetching outdated packs from XSOAR server. This may take a minute...done.
104
+ Pack ID Installed version Latest available version
105
+ CommonScripts 1.19.0 1.20.0
106
+ Base 1.40.14 1.41.14
107
+ Total number of outdated content packs: 2
108
+ Upgrade CommonScripts from 1.19.0 to 1.20.0? [Y/n]: y
109
+ Upgrade Base from 1.40.14 to 1.41.14? [Y/n]: y
110
+ Written updated manifest to './xsoar_config.json'
23
111
  ```
112
+
113
+ ### diff
114
+ Compares the manifest definition against what's actually installed on the XSOAR server.
115
+
116
+ **Usage:**
117
+ ```bash
118
+ xsoar-cli manifest diff [OPTIONS] MANIFEST_PATH
119
+ ```
120
+
121
+ **Options:**
122
+ - `--environment TEXT`: Environment name from config file (default: dev)
123
+
124
+ **Examples:**
125
+ ```bash
126
+ # Show differences between manifest and server
127
+ xsoar-cli manifest diff ./xsoar_config.json
128
+
129
+ # Check production environment
130
+ xsoar-cli manifest diff --environment prod ./xsoar_config.json
131
+ ```
132
+
133
+ **Output shows:**
134
+ - Packs defined in manifest but not installed
135
+ - Version mismatches between manifest and installed packs
136
+ - Summary message when everything is up to date
137
+
138
+ **Sample output:**
139
+ ```
140
+ Pack MyCustomPack is not installed
141
+ Manifest states CommonScripts version 1.20.0 but version 1.19.0 is installed
142
+ ```
143
+
144
+ ### deploy
145
+ Installs or updates content packs on the XSOAR server according to the manifest.
146
+
147
+ **Usage:**
148
+ ```bash
149
+ xsoar-cli manifest deploy [OPTIONS] MANIFEST_PATH
150
+ ```
151
+
152
+ **Options:**
153
+ - `--environment TEXT`: Environment name from config file (default: dev)
154
+ - `--verbose`: Show detailed information about skipped packs
155
+ - `--yes`: Skip confirmation prompt
156
+
157
+ **Examples:**
158
+ ```bash
159
+ # Deploy with confirmation prompt
160
+ xsoar-cli manifest deploy ./xsoar_config.json
161
+
162
+ # Deploy to production without prompts
163
+ xsoar-cli manifest deploy --environment prod --yes ./xsoar_config.json
164
+
165
+ # Deploy with verbose output
166
+ xsoar-cli manifest deploy --verbose ./xsoar_config.json
167
+ ```
168
+
169
+ **Behavior:**
170
+ - Prompts for confirmation before deployment (unless --yes used)
171
+ - Only installs/updates packs that differ from current installation
172
+ - Shows progress for each pack installation
173
+ - Skips packs already at correct version
174
+
175
+ **Sample output:**
176
+ ```
177
+ WARNING: this operation will attempt to deploy all packs defined in the manifest to XSOAR dev environment. Continue? [y/N]: y
178
+ Fetching installed packs...done.
179
+ Installing MyCustomPack version 1.0.0...OK.
180
+ Installing CommonScripts version 1.20.0...OK.
181
+ Not installing Base version 1.41.14. Already installed.
182
+ ```
183
+
184
+ ## Common Workflows
185
+
186
+ ### Initial Setup
187
+ 1. Create manifest: `xsoar-cli manifest validate ./xsoar_config.json` (validates structure)
188
+ 2. Deploy: `xsoar-cli manifest deploy ./xsoar_config.json`
189
+
190
+ ### Regular Updates
191
+ 1. Check for updates: `xsoar-cli manifest update ./xsoar_config.json`
192
+ 2. Review changes in manifest file
193
+ 3. Deploy updates: `xsoar-cli manifest deploy ./xsoar_config.json`
194
+
195
+ ### Environment Consistency
196
+ 1. Check differences: `xsoar-cli manifest diff --environment prod ./xsoar_config.json`
197
+ 2. Deploy if needed: `xsoar-cli manifest deploy --environment prod ./xsoar_config.json`
198
+
199
+ ### CI/CD Pipeline Integration
200
+ ```bash
201
+ # Typical CI/CD workflow
202
+ xsoar-cli manifest validate ./xsoar_config.json # Fail fast on invalid manifest
203
+ xsoar-cli manifest diff --environment dev ./xsoar_config.json # Show what will change
204
+ xsoar-cli manifest deploy --yes --environment dev ./xsoar_config.json # Deploy changes
205
+ ```
206
+
207
+ ## Troubleshooting
208
+
209
+ ### Common Issues
210
+
211
+ **"Failed to decode JSON in {filepath}"**
212
+ - Check JSON syntax in manifest file
213
+ - Ensure no trailing commas or missing quotes
214
+ - Use a JSON validator to identify syntax errors
215
+
216
+ **"Failed to reach pack {pack_id} version {version}"**
217
+ - **For custom packs**: Check AWS S3 credentials and bucket access
218
+ - **For marketplace packs**: Verify internet connectivity to Palo Alto Networks CDN
219
+ - Ensure pack version exists in the artifact repository
220
+ - Check if pack is in development locally (may not be uploaded yet)
221
+
222
+ **"Pack {pack_id} not found in manifest"**
223
+ - Verify pack ID matches exactly (case-sensitive)
224
+ - Check that pack is in correct section (`custom_packs` vs `marketplace_packs`)
225
+ - Ensure pack ID in manifest matches the ID in pack metadata
226
+
227
+ **"Environment not found"**
228
+ - Check config file exists: `~/.config/xsoar-cli/config.json`
229
+ - Verify environment name matches configuration exactly
230
+ - Run `xsoar-cli config create` if configuration is missing
231
+ - Check server connectivity and API credentials
232
+
233
+ **"WARNING: comment found in manifest for {pack_id}: {comment}"**
234
+ - This is informational only - comments are preserved during updates
235
+ - Review the comment to understand why the version was pinned
236
+ - Decide whether to accept or decline the upgrade based on the comment
237
+
238
+ ### Performance Considerations
239
+
240
+ - **Large manifests**: Commands may take several minutes with 100+ packs
241
+ - **Network timeouts**: Custom pack validation requires S3 connectivity
242
+ - **Rate limiting**: XSOAR API calls are rate-limited; large deployments may be slower
243
+
244
+ ### Best Practices
245
+
246
+ 1. **Version Control**: Keep `xsoar_config.json` in version control
247
+ 2. **Comments**: Use `_comment` field to document version pin reasons
248
+ 3. **Testing**: Always validate before deploying to production
249
+ 4. **Environment Separation**: Consider different manifests for dev/staging/prod
250
+ 5. **Backup**: Run `diff` before `deploy` to understand changes
251
+ 6. **Incremental Updates**: Update and deploy frequently rather than large batch updates
252
+ 7. **Monitoring**: Check deployment results and verify pack functionality after updates
253
+
254
+ ### Development Workflow
255
+
256
+ When developing new custom packs:
257
+
258
+ 1. Add pack to manifest with new version
259
+ 2. Run `xsoar-cli manifest validate` - may show pack not available (expected)
260
+ 3. The validation will pass if local pack metadata matches manifest version
261
+ 4. Deploy pack artifacts to S3 repository
262
+ 5. Run `xsoar-cli manifest deploy` to install on XSOAR server
263
+
264
+ ### Security Notes
265
+
266
+ - AWS credentials should be configured securely (IAM roles, not hardcoded keys)
267
+ - XSOAR API keys should be stored in the configuration file with appropriate permissions
268
+ - Consider using different credentials for different environments
269
+ - Review pack sources and content before deploying to production systems
@@ -46,7 +46,7 @@ def manifest() -> None:
46
46
  @load_config
47
47
  def update(ctx: click.Context, environment: str, manifest: str) -> None:
48
48
  """Update manifest on disk with latest available content pack versions."""
49
- xsoar_client: Client = ctx.obj["server_envs"][environment]
49
+ xsoar_client: Client = ctx.obj["server_envs"][environment]["xsoar_client"]
50
50
  manifest_data = load_manifest(manifest)
51
51
  click.echo("Fetching outdated packs from XSOAR server. This may take a minute...", nl=False)
52
52
  results = xsoar_client.get_outdated_packs()
@@ -89,7 +89,7 @@ def update(ctx: click.Context, environment: str, manifest: str) -> None:
89
89
  def validate(ctx: click.Context, environment: str, manifest: str) -> None:
90
90
  """Validate manifest JSON and all pack availability. Validates upstream pack availability by doing HTTP CONNECT.
91
91
  Custom pack availability is implementation dependant."""
92
- xsoar_client: Client = ctx.obj["server_envs"][environment]
92
+ xsoar_client: Client = ctx.obj["server_envs"][environment]["xsoar_client"]
93
93
  manifest_data = load_manifest(manifest)
94
94
  click.echo("Manifest is valid JSON")
95
95
  keys = ["custom_packs", "marketplace_packs"]
@@ -129,7 +129,7 @@ def validate(ctx: click.Context, environment: str, manifest: str) -> None:
129
129
  def diff(ctx: click.Context, manifest: str, environment: str) -> None:
130
130
  """Prints out the differences (if any) between what is defined in the xsoar_config.json manifest and what is actually
131
131
  installed on the XSOAR server."""
132
- xsoar_client: Client = ctx.obj["server_envs"][environment]
132
+ xsoar_client: Client = ctx.obj["server_envs"][environment]["xsoar_client"]
133
133
  manifest_data = load_manifest(manifest)
134
134
  installed_packs = xsoar_client.get_installed_packs()
135
135
  all_good = True
@@ -170,7 +170,7 @@ def deploy(ctx: click.Context, environment: str, manifest: str, verbose: bool, y
170
170
  if not should_continue:
171
171
  ctx.exit()
172
172
 
173
- xsoar_client: Client = ctx.obj["server_envs"][environment]
173
+ xsoar_client: Client = ctx.obj["server_envs"][environment]["xsoar_client"]
174
174
  manifest_data = load_manifest(manifest)
175
175
  click.echo("Fetching installed packs...", err=True)
176
176
  installed_packs = xsoar_client.get_installed_packs()
@@ -191,7 +191,7 @@ def deploy(ctx: click.Context, environment: str, manifest: str, verbose: bool, y
191
191
  # Print message that install is skipped
192
192
 
193
193
  if none_installed:
194
- click.echo("No packs to install. XSOAR server is up to date with manifest.")
194
+ click.echo("No packs to install. All packs and versions in manifest is already installed on XSOAR server.")
195
195
 
196
196
 
197
197
  manifest.add_command(deploy)
@@ -22,7 +22,7 @@ def pack(ctx: click.Context) -> None:
22
22
  @load_config
23
23
  def delete(ctx: click.Context, environment: str, pack_id: str) -> None:
24
24
  """Deletes a content pack from the XSOAR server."""
25
- xsoar_client: Client = ctx.obj["server_envs"][environment]
25
+ xsoar_client: Client = ctx.obj["server_envs"][environment]["xsoar_client"]
26
26
  if not xsoar_client.is_installed(pack_id=pack_id):
27
27
  click.echo(f"Pack ID {pack_id} is not installed. Cannot delete.")
28
28
  sys.exit(1)
@@ -36,7 +36,7 @@ def delete(ctx: click.Context, environment: str, pack_id: str) -> None:
36
36
  @load_config
37
37
  def get_outdated(ctx: click.Context, environment: str) -> None:
38
38
  """Prints out a list of outdated content packs."""
39
- xsoar_client: Client = ctx.obj["server_envs"][environment]
39
+ xsoar_client: Client = ctx.obj["server_envs"][environment]["xsoar_client"]
40
40
  click.echo("Fetching outdated packs. This may take a little while...", err=True)
41
41
  outdated_packs = xsoar_client.get_outdated_packs()
42
42
  if not outdated_packs:
@@ -40,20 +40,20 @@ class MyPlugin(XSOARPlugin):
40
40
  @property
41
41
  def name(self) -> str:
42
42
  return "myplugin"
43
-
44
- @property
43
+
44
+ @property
45
45
  def version(self) -> str:
46
46
  return "1.0.0"
47
-
47
+
48
48
  @property
49
49
  def description(self) -> str:
50
50
  return "My custom plugin"
51
-
51
+
52
52
  def get_command(self) -> click.Command:
53
53
  @click.command(help="My custom command")
54
54
  def mycommand():
55
55
  click.echo("Hello from my plugin!")
56
-
56
+
57
57
  return mycommand
58
58
  ```
59
59
 
@@ -75,23 +75,23 @@ class MyCustomPlugin(XSOARPlugin):
75
75
  @property
76
76
  def name(self) -> str:
77
77
  return "mycustom"
78
-
78
+
79
79
  @property
80
80
  def version(self) -> str:
81
81
  return "1.0.0"
82
-
82
+
83
83
  @property
84
84
  def description(self) -> str:
85
85
  return "A custom plugin with multiple commands"
86
-
86
+
87
87
  def get_command(self) -> click.Command:
88
88
  """Return the main command group for this plugin."""
89
-
89
+
90
90
  @click.group(help="My custom commands")
91
91
  def mycustom():
92
92
  """Main command group for my custom plugin."""
93
93
  pass
94
-
94
+
95
95
  @click.command(help="Greet someone")
96
96
  @click.option("--name", default="World", help="Name to greet")
97
97
  @click.option("--times", default=1, help="Number of times to greet")
@@ -99,7 +99,7 @@ class MyCustomPlugin(XSOARPlugin):
99
99
  """Greet someone multiple times."""
100
100
  for i in range(times):
101
101
  click.echo(f"Hello, {name}!")
102
-
102
+
103
103
  @click.command(help="Show current status")
104
104
  @click.option("--verbose", "-v", is_flag=True, help="Verbose output")
105
105
  def status(verbose: bool):
@@ -108,7 +108,7 @@ class MyCustomPlugin(XSOARPlugin):
108
108
  if verbose:
109
109
  click.echo(f"Description: {self.description}")
110
110
  click.echo("Status: Active")
111
-
111
+
112
112
  @click.command(help="Process a file")
113
113
  @click.argument("filename", type=click.Path(exists=True))
114
114
  @click.option("--output", "-o", help="Output file")
@@ -118,18 +118,18 @@ class MyCustomPlugin(XSOARPlugin):
118
118
  if output:
119
119
  click.echo(f"Output will be saved to: {output}")
120
120
  # Your processing logic here
121
-
121
+
122
122
  # Add commands to the group
123
123
  mycustom.add_command(greet)
124
124
  mycustom.add_command(status)
125
125
  mycustom.add_command(process)
126
-
126
+
127
127
  return mycustom
128
-
128
+
129
129
  def initialize(self):
130
130
  """Initialize the plugin."""
131
131
  click.echo("My custom plugin initialized!")
132
-
132
+
133
133
  def cleanup(self):
134
134
  """Cleanup when the plugin is unloaded."""
135
135
  pass
@@ -176,7 +176,7 @@ from xsoar_cli.utilities import load_config
176
176
  @load_config
177
177
  def my_command(ctx: click.Context):
178
178
  # Access XSOAR client
179
- xsoar_client = ctx.obj["server_envs"]["dev"]
179
+ xsoar_client = ctx.obj["server_envs"]["dev"]["xsoar_client"]
180
180
  # Use the client...
181
181
  ```
182
182
 
@@ -284,11 +284,11 @@ class MyPlugin(XSOARPlugin):
284
284
  @click.group()
285
285
  def myplugin():
286
286
  pass
287
-
287
+
288
288
  @click.command()
289
289
  def case(): # ✅ Namespaced as 'myplugin case'
290
290
  click.echo("My case command")
291
-
291
+
292
292
  myplugin.add_command(case)
293
293
  return myplugin
294
294
  ```
@@ -297,7 +297,7 @@ class MyPlugin(XSOARPlugin):
297
297
 
298
298
  These command names are reserved by the core CLI:
299
299
  - `case` - Case/incident management
300
- - `config` - Configuration management
300
+ - `config` - Configuration management
301
301
  - `graph` - Dependency graphs
302
302
  - `manifest` - Manifest operations
303
303
  - `pack` - Content pack operations
@@ -330,7 +330,7 @@ def get_command(self) -> click.Command:
330
330
  except Exception as e:
331
331
  click.echo(f"Error: {e}", err=True)
332
332
  raise click.Abort()
333
-
333
+
334
334
  return mycommand
335
335
  ```
336
336
 
@@ -430,4 +430,4 @@ except ImportError:
430
430
 
431
431
  You can share plugins by simply sharing the Python file. Users can place it in their plugins directory and it will be automatically discovered.
432
432
 
433
- For more complex plugins, consider packaging them as proper Python packages that install the plugin file automatically.
433
+ For more complex plugins, consider packaging them as proper Python packages that install the plugin file automatically.
xsoar_cli/utilities.py CHANGED
@@ -1,7 +1,8 @@
1
+ import contextlib
1
2
  import json
3
+ from collections.abc import Callable
2
4
  from functools import update_wrapper
3
5
  from pathlib import Path
4
- from typing import Callable
5
6
 
6
7
  import click
7
8
  from xsoar_client.xsoar_client import Client
@@ -75,6 +76,29 @@ def load_config(f: Callable) -> Callable:
75
76
  return update_wrapper(wrapper, f)
76
77
 
77
78
 
79
+ def fail_if_no_artifacts_provider(f: Callable) -> Callable:
80
+ """
81
+ 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.
82
+ The intention is to fail gracefully if any subcommand is executed which requires an artifacts provider."
83
+ """
84
+
85
+ @click.pass_context
86
+ def wrapper(ctx: click.Context, *args, **kwargs) -> Callable: # noqa: ANN002, ANN003
87
+ if "environment" in ctx.params: # noqa: SIM108
88
+ key = ctx.params["environment"]
89
+ else:
90
+ key = ctx.obj["default_environment"]
91
+
92
+ with contextlib.suppress(KeyError):
93
+ location = ctx.obj["server_envs"][key].get("artifacts_location", None)
94
+ if not location:
95
+ click.echo("Command requires artifacts repository, but no artifacts_location defined in config.")
96
+ ctx.exit(1)
97
+ return ctx.invoke(f, *args, **kwargs)
98
+
99
+ return update_wrapper(wrapper, f)
100
+
101
+
78
102
  def parse_config(config: dict, ctx: click.Context) -> None:
79
103
  # Set the two XSOAR client objects in Click Context for use in later functions
80
104
  ctx.obj = {}
@@ -83,13 +107,15 @@ def parse_config(config: dict, ctx: click.Context) -> None:
83
107
  ctx.obj["default_new_case_type"] = config["default_new_case_type"]
84
108
  ctx.obj["server_envs"] = {}
85
109
  for key in config["server_config"]:
86
- ctx.obj["server_envs"][key] = Client(
110
+ ctx.obj["server_envs"][key] = {}
111
+ ctx.obj["server_envs"][key]["xsoar_client"] = Client(
87
112
  api_token=config["server_config"][key]["api_token"],
88
113
  server_url=config["server_config"][key]["base_url"],
89
114
  verify_ssl=config["server_config"][key]["verify_ssl"],
90
115
  custom_pack_authors=config["custom_pack_authors"],
91
116
  xsiam_auth_id=config["server_config"][key].get("xsiam_auth_id", ""),
92
117
  server_version=config["server_config"][key]["server_version"],
93
- artifacts_location=config["server_config"][key]["artifacts_location"],
94
- s3_bucket_name=config["server_config"][key]["s3_bucket_name"],
118
+ artifacts_location=config["server_config"][key].get("artifacts_location", None),
119
+ s3_bucket_name=config["server_config"][key].get("s3_bucket_name", None),
95
120
  )
121
+ ctx.obj["server_envs"][key]["artifacts_location"] = config["server_config"][key].get("artifacts_location", None)
@@ -0,0 +1,256 @@
1
+ Metadata-Version: 2.4
2
+ Name: xsoar-cli
3
+ Version: 1.0.4
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.12
13
+ Classifier: Programming Language :: Python :: Implementation :: CPython
14
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
15
+ Requires-Python: >=3.12
16
+ Requires-Dist: click==8.1.8
17
+ Requires-Dist: pyyaml>=6.0.2
18
+ Requires-Dist: xsoar-client>=1.0.0
19
+ Requires-Dist: xsoar-dependency-graph>=0.0.3
20
+ Description-Content-Type: text/markdown
21
+
22
+ # xsoar-cli
23
+
24
+ [![PyPI version](https://badge.fury.io/py/xsoar-cli.svg)](https://badge.fury.io/py/xsoar-cli) [![Python](https://img.shields.io/pypi/pyversions/xsoar-cli.svg)](https://pypi.org/project/xsoar-cli/) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
25
+
26
+ A command-line interface for managing Palo Alto Networks XSOAR (Cortex XSOAR) that streamlines content development and deployment workflows.
27
+
28
+ **Key Features:**
29
+ - **Content Management**: Validate and deploy content packs with declarative manifests
30
+ - **Case Operations**: Retrieve case details and clone cases between environments
31
+ - **Playbook Development**: Download playbooks for local editing and testing
32
+ - **Dependency Analysis**: Generate visual graphs of content pack dependencies
33
+ - **Plugin System**: Extend functionality with custom commands
34
+
35
+ Perfect for DevOps teams using CI/CD pipelines to manage XSOAR content stored in [content repositories](https://github.com/demisto/content-ci-cd-template).
36
+
37
+ Pull Requests are very welcome and appreciated! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
38
+
39
+ ## Quick Start
40
+
41
+ ```bash
42
+ # Install
43
+ pip install xsoar-cli
44
+
45
+ # Create configuration file
46
+ xsoar-cli config create
47
+
48
+ # Validate and deploy your content
49
+ xsoar-cli manifest validate ./xsoar_config.json
50
+ xsoar-cli manifest deploy ./xsoar_config.json
51
+
52
+ # Get help on available commands
53
+ xsoar-cli --help
54
+ ```
55
+
56
+ ## Important Notes
57
+
58
+ 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.
59
+
60
+ ## Requirements
61
+
62
+ ### Core Requirements
63
+ - XSOAR servers version 6 or 8
64
+ - Python 3.9+ (only tested with Python 3.12, earlier versions may work but are not guaranteed)
65
+
66
+ ### Additional Requirements (depending on usage)
67
+ - **AWS SDK for Python (Boto3)** - Only required when working with custom content packs stored in S3. You can use marketplace packs and other functionality without AWS setup.
68
+
69
+ **Note:** AWS S3 is currently the only available artifacts repository provider for custom packs. Pull requests for new providers are welcome!
70
+
71
+ ## Installation
72
+
73
+ ```bash
74
+ pip install xsoar-cli
75
+ ```
76
+
77
+ ## Upgrading
78
+
79
+ ```bash
80
+ pip install --upgrade xsoar-cli
81
+ ```
82
+
83
+ ## Uninstalling
84
+
85
+ ```bash
86
+ pip uninstall xsoar-cli
87
+ ```
88
+
89
+ ## Configuration
90
+
91
+ The xsoar-cli config file is located in `~/.config/xsoar-cli/config.json`. To create a configuration file from template, please run:
92
+
93
+ ```bash
94
+ xsoar-cli config create
95
+ ```
96
+
97
+ ### Configuration File Structure
98
+
99
+ After creating the config file, edit it with your XSOAR server details:
100
+
101
+ ```json
102
+ {
103
+ "default_environment": "xsoar6",
104
+ "default_new_case_type": "",
105
+ "custom_pack_authors": ["SOMEONE"],
106
+ "server_config": {
107
+ "xsoar6": {
108
+ "base_url": "https://xsoar-v6.example.com",
109
+ "api_token": "YOUR API TOKEN HERE",
110
+ "artifacts_location": "S3",
111
+ "s3_bucket_name": "xsoar-cicd",
112
+ "verify_ssl": "/path/to/your/CA_bundle.pem",
113
+ "server_version": 6
114
+ },
115
+ "xsoar8": {
116
+ "base_url": "https://xsoar-v8.example.com",
117
+ "api_token": "YOUR API TOKEN HERE",
118
+ "artifacts_location": "S3",
119
+ "s3_bucket_name": "xsoar-cicd-prod",
120
+ "verify_ssl": false,
121
+ "server_version": 8,
122
+ "xsiam_auth_id": 123
123
+ }
124
+ }
125
+ }
126
+ ```
127
+
128
+ ### Configuration Options
129
+
130
+ - **default_environment**: Which environment to use by default (e.g., "xsoar6")
131
+ - **default_new_case_type**: Default case type when creating new cases
132
+ - **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.
133
+
134
+ - **server_config**: Define multiple XSOAR environments (xsoar6, xsoar8, etc.)
135
+ - **base_url**: Your XSOAR server URL
136
+ - **api_token**: API token for authentication (see XSOAR documentation for creating API keys)
137
+ - **artifacts_location**: Where artifacts are stored (currently only "S3" is supported)
138
+ - **s3_bucket_name**: S3 bucket where your custom content packs are stored
139
+ - **verify_ssl**: SSL certificate verification - use `false` for self-signed certificates, or path to CA bundle
140
+ - **server_version**: XSOAR server version (6 or 8)
141
+ - **xsiam_auth_id**: Required for XSOAR 8 (XSIAM) - the authentication ID for API access
142
+
143
+ ### Validation
144
+
145
+ Test your configuration with:
146
+
147
+ ```bash
148
+ xsoar-cli config validate
149
+ ```
150
+
151
+ This will verify connectivity to all configured XSOAR environments.
152
+
153
+ ## Usage
154
+
155
+ ```bash
156
+ xsoar-cli <command> <sub-command> <args>
157
+ ```
158
+
159
+ For information about available commands, run `xsoar-cli` without arguments.
160
+
161
+ For more information on a specific command execute `xsoar-cli <command> --help`.
162
+
163
+ ### Commands
164
+
165
+ - **[case](src/xsoar_cli/case/README.md)** - Retrieve case details and clone cases between environments
166
+ - **[config](src/xsoar_cli/config/README.md)** - Create, validate, and manage CLI configuration files
167
+ - **[graph](src/xsoar_cli/graph/README.md)** - Generate visual dependency graphs for content packs
168
+ - **[manifest](src/xsoar_cli/manifest/README.md)** - Validate and deploy content using declarative manifests
169
+ - **[pack](src/xsoar_cli/pack/README.md)** - Manage content pack operations and information
170
+ - **[playbook](src/xsoar_cli/playbook/README.md)** - Download playbooks for local editing and development
171
+ - **[plugins](src/xsoar_cli/plugins/README.md)** - Extend CLI functionality with custom commands
172
+
173
+ ## Plugin System
174
+
175
+ xsoar-cli supports a plugin system that allows you to extend the CLI with custom commands. Plugins are Python files that you place in `~/.local/xsoar-cli/plugins/` and they're automatically discovered and loaded.
176
+
177
+ ### Quick Start with Plugins
178
+
179
+ 1. **Create an example plugin**:
180
+ ```bash
181
+ xsoar-cli plugins create-example
182
+ ```
183
+
184
+ 2. **List available plugins**:
185
+ ```bash
186
+ xsoar-cli plugins list
187
+ ```
188
+
189
+ 3. **Test the example plugin**:
190
+ ```bash
191
+ xsoar-cli example hello --name "World"
192
+ ```
193
+
194
+ ### Plugin Management Commands
195
+
196
+ - `xsoar-cli plugins list` - List all plugins
197
+ - `xsoar-cli plugins info <plugin>` - Show plugin information
198
+ - `xsoar-cli plugins validate` - Validate all plugins
199
+ - `xsoar-cli plugins reload <plugin>` - Reload a specific plugin
200
+ - `xsoar-cli plugins create-example` - Create an example plugin
201
+ - `xsoar-cli plugins open` - Open the plugins directory
202
+
203
+ ### Creating Your Own Plugins
204
+
205
+ Create a Python file in `~/.local/xsoar-cli/plugins/` that inherits from `XSOARPlugin`:
206
+
207
+ ```python
208
+ import click
209
+ from xsoar_cli.plugins import XSOARPlugin
210
+
211
+ class MyPlugin(XSOARPlugin):
212
+ @property
213
+ def name(self) -> str:
214
+ return "myplugin"
215
+
216
+ @property
217
+ def version(self) -> str:
218
+ return "1.0.0"
219
+
220
+ def get_command(self) -> click.Command:
221
+ @click.command(help="My custom command")
222
+ def mycommand():
223
+ click.echo("Hello from my plugin!")
224
+ return mycommand
225
+ ```
226
+
227
+ For detailed documentation, see [Plugin System Documentation](src/xsoar_cli/plugins/README.md).
228
+
229
+ ## Troubleshooting
230
+
231
+ ### Common Issues
232
+
233
+ **"Config file not found"**
234
+ - Run `xsoar-cli config create` to generate a template configuration file
235
+ - Ensure the file exists at `~/.config/xsoar-cli/config.json`
236
+
237
+ **"Failed to reach pack" or connection errors**
238
+ - Verify your XSOAR server URL and API token in the config file
239
+ - Check network connectivity to your XSOAR server
240
+ - For custom packs: Ensure AWS credentials are configured and S3 bucket is accessible
241
+
242
+ **"Invalid environment"**
243
+ - Check that the environment name matches exactly what's defined in your config file
244
+ - Use `xsoar-cli config validate` to verify your configuration
245
+
246
+ **Python compatibility issues**
247
+ - Ensure you're using Python 3.9 or later
248
+ - Consider using Python 3.12 for best compatibility
249
+
250
+ ## Contributing
251
+
252
+ We welcome all contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines on how to contribute to this project.
253
+
254
+ ## License
255
+
256
+ `xsoar-cli` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.
@@ -1,31 +1,31 @@
1
- xsoar_cli/__about__.py,sha256=cwkA9vKz4-QApCiApwquYub4oxcNxa_UUZycn3J1BsI,127
1
+ xsoar_cli/__about__.py,sha256=ppSrh4dfP4K0nr9jdlBQ1YkT9cD5CyaRnZQz5wDhG94,127
2
2
  xsoar_cli/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
3
3
  xsoar_cli/cli.py,sha256=iAlSeZe2iR6ciTVrJYLt-CDZk7b5I-hzHFXbYoXhupA,1342
4
- xsoar_cli/utilities.py,sha256=nmvb7aclp1Uil6gVtSBTy6wa-GfRLAWOsV_0a8Nc3Vk,3931
4
+ xsoar_cli/utilities.py,sha256=aW0lmPAf06YyGlq0ayQg0h2uCmvqgIHSuLdpCTJQN_0,5150
5
5
  xsoar_cli/case/README.md,sha256=MTfgVeW3qJXRPNFo8CkZvulm2vwbN8sgiW86V-qXRFw,1342
6
6
  xsoar_cli/case/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- xsoar_cli/case/commands.py,sha256=EWFld2BfLPgBhPJs5QqWsddlzrUvNIWmlKG4HwnpukU,3511
7
+ xsoar_cli/case/commands.py,sha256=UXXOrE3qmYF4z8mtKRkIP7onatib5x55fwprtbNxTBA,3575
8
8
  xsoar_cli/config/README.md,sha256=pcO858PDL9c0qtwj3_a6B8q2CGvcka3dwclVnwi2vlA,516
9
9
  xsoar_cli/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- xsoar_cli/config/commands.py,sha256=SJqIBUBq4tHmnXusycXuIOkmHhyc-vKvQwFMjIHh3Cc,3884
10
+ xsoar_cli/config/commands.py,sha256=i6lWaR0LjAzMpNVPZyCsDPaT0GMVqTUXdau6Id0iOrs,4193
11
11
  xsoar_cli/graph/README.md,sha256=kyWIGs2Sd-OdqAaCWJjyvGpAhXhFcuqQwVqFBgzgWzk,861
12
12
  xsoar_cli/graph/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  xsoar_cli/graph/commands.py,sha256=LKOpUu8r6KThJ5HdyjZlhpwLKRgMcEu7btBOQXwDkMs,1069
14
- xsoar_cli/manifest/README.md,sha256=Ha84Ozlj7KwSj9FsK42sSZVYoWllmPKsjtkB-53Anpg,913
14
+ xsoar_cli/manifest/README.md,sha256=0oiA6rZEAUQMOYM7VmtUBtW3PRo7-exfkjw5JLt_whU,9282
15
15
  xsoar_cli/manifest/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
- xsoar_cli/manifest/commands.py,sha256=jShmi0s7GOSXJt9DQbEoFSu4ZsC0Givv1vJj7qfwI2g,8697
16
+ xsoar_cli/manifest/commands.py,sha256=6IU9k-UFCeZUnM9CHNqafaouiTOrK3OXtWxsr3LTCV4,8792
17
17
  xsoar_cli/pack/README.md,sha256=CA7jAEphHxK0gh58rLRKL-u3wx29QgNAXojd_tGBXnY,46
18
18
  xsoar_cli/pack/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
- xsoar_cli/pack/commands.py,sha256=bLbKCC_TROqqysEfmk6G9qqKJuXkt0nqwUHoP_LauD8,1899
19
+ xsoar_cli/pack/commands.py,sha256=A1CYdzvdXNAy63rPVoBOAXddRzl8PRmuSCQOSDeRlRk,1931
20
20
  xsoar_cli/playbook/README.md,sha256=8y_YhvZtLP7KzYG83jiVBF-wBAEh8UTJcgmTOTynmbc,977
21
21
  xsoar_cli/playbook/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
22
  xsoar_cli/playbook/commands.py,sha256=mFmXJ3D8plvrUC9ylMlkrAa2T1yhydByEBhrBVbaZec,2729
23
- xsoar_cli/plugins/README.md,sha256=qQ_shzxcJcJKHuWfuN_cTVhtaew4BEGBEjn9wxaZG5c,11314
23
+ xsoar_cli/plugins/README.md,sha256=19AAhaYi2Rk6h95MkDGoh8n73KB-BcbaznQ0nfW2rpc,11220
24
24
  xsoar_cli/plugins/__init__.py,sha256=81IZsMbZsqrLdB6TjA9t6s3yS8FkuihliBFX4xZUpTo,1753
25
25
  xsoar_cli/plugins/commands.py,sha256=HC0sWu149uQG9Ztag4t2CNPKXTM4WJbEdLSvFMEjw80,10660
26
26
  xsoar_cli/plugins/manager.py,sha256=7RPk3lAYDifGMLOU-hFOqyPxTVk8ibBVzBqH7R8wy4g,13012
27
- xsoar_cli-1.0.2.dist-info/METADATA,sha256=Oqf719w5HhWZgyYifNZXktW90EyVk_L_tE6uErKj_2M,4659
28
- xsoar_cli-1.0.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
29
- xsoar_cli-1.0.2.dist-info/entry_points.txt,sha256=s6Klu4QRekXsmZaBxMyFlE4Q-4_jIA9uijk4qIYUPvE,48
30
- xsoar_cli-1.0.2.dist-info/licenses/LICENSE.txt,sha256=l6xnqWKshqwwTXt6ayO6MX8Uvygq0YnkUuFTNnR3ba4,1097
31
- xsoar_cli-1.0.2.dist-info/RECORD,,
27
+ xsoar_cli-1.0.4.dist-info/METADATA,sha256=cKIkFA52ep6NsbFDXtpcZLatvMtKs473AAAP2bfF-o0,9110
28
+ xsoar_cli-1.0.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
29
+ xsoar_cli-1.0.4.dist-info/entry_points.txt,sha256=s6Klu4QRekXsmZaBxMyFlE4Q-4_jIA9uijk4qIYUPvE,48
30
+ xsoar_cli-1.0.4.dist-info/licenses/LICENSE.txt,sha256=l6xnqWKshqwwTXt6ayO6MX8Uvygq0YnkUuFTNnR3ba4,1097
31
+ xsoar_cli-1.0.4.dist-info/RECORD,,
@@ -1,136 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: xsoar-cli
3
- Version: 1.0.2
4
- Project-URL: Documentation, https://github.com/tlium/xsoar-cli#readme
5
- Project-URL: Issues, https://github.com/tliumb/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.8
13
- Classifier: Programming Language :: Python :: 3.9
14
- Classifier: Programming Language :: Python :: 3.10
15
- Classifier: Programming Language :: Python :: 3.11
16
- Classifier: Programming Language :: Python :: 3.12
17
- Classifier: Programming Language :: Python :: Implementation :: CPython
18
- Classifier: Programming Language :: Python :: Implementation :: PyPy
19
- Requires-Python: >=3.8
20
- Requires-Dist: click==8.1.8
21
- Requires-Dist: pyyaml>=6.0.2
22
- Requires-Dist: xsoar-client>=1.0.0
23
- Requires-Dist: xsoar-dependency-graph>=0.0.3
24
- Description-Content-Type: text/markdown
25
-
26
- # xsoar-cli
27
- -----
28
- This tool is made to help provide a smoother workflow for developers, but also for power users to get useful information out of XSOAR from
29
- the terminal. It is mostly useful if you are using a CICD workflow to deploy your XSOAR content, and most of the functionality assumest that
30
- you have your content stored in a [content repository](https://github.com/demisto/content-ci-cd-template).
31
-
32
- Pull Requests are very welcome and appreciated!
33
-
34
-
35
- *IMPORTANT NOTE*
36
- This CLI tools is made to be run from the root of a content repository. Some commands depends on files located in your
37
- content repository or expects a certain directory structure to be available from your currently working directory.
38
-
39
- ## Installation
40
- ```
41
- pip install xsoar-cli
42
- ```
43
- ## Upgrading
44
- ```
45
- pip install --upgrade xsoar-cli
46
- ```
47
-
48
-
49
- ## Configuration
50
- The xsoar-cli config file is located in `~/.config/xsoar-cli/config.json`. To create a configuration file from template, please run
51
- ```
52
- xsoar-cli config create
53
- ```
54
- Open up the newly created configuration file and add values that correspond with your environment.
55
-
56
- *IMPORTANT NOTES*
57
- - The configuration key `"custom_pack_authors": ["SOMEONE"]` is needed in order for `xsoar-cli` to be able to determine which content packs
58
- are your own custom content packs and which are supplied from Palo Alto upstream. Use whatever values you may have set in pack_metadata.json
59
- in the content packs in your content repository.
60
-
61
- ## Usage
62
- ```
63
- xsoar-cli <command> <sub-command> <args>
64
- ```
65
- For information about available commands, run `xsoar-cli` without arguments.
66
-
67
- For more information on a specific command execute `xsoar-cli <command> --help.`
68
-
69
- ### Commands
70
- 1. [case](src/xsoar_cli/case/README.md)
71
- 2. [config](src/xsoar_cli/config/README.md)
72
- 3. [graph](src/xsoar_cli/graph/README.md)
73
- 4. [manifest](src/xsoar_cli/manifest/README.md)
74
- 5. [pack](src/xsoar_cli/pack/README.md)
75
- 6. [playbook](src/xsoar_cli/playbook/README.md)
76
- 7. [plugins](src/xsoar_cli/plugins/README.md)
77
-
78
- ## Plugin System
79
-
80
- xsoar-cli supports a plugin system that allows you to extend the CLI with custom commands. Plugins are Python files that you place in `~/.local/xsoar-cli/plugins/` and they're automatically discovered and loaded.
81
-
82
- ### Quick Start with Plugins
83
-
84
- 1. **Create an example plugin**:
85
- ```bash
86
- xsoar-cli plugins create-example
87
- ```
88
-
89
- 2. **List available plugins**:
90
- ```bash
91
- xsoar-cli plugins list
92
- ```
93
-
94
- 3. **Test the example plugin**:
95
- ```bash
96
- xsoar-cli example hello --name "World"
97
- ```
98
-
99
- ### Plugin Management Commands
100
-
101
- - `xsoar-cli plugins list` - List all plugins
102
- - `xsoar-cli plugins info <plugin>` - Show plugin information
103
- - `xsoar-cli plugins validate` - Validate all plugins
104
- - `xsoar-cli plugins reload <plugin>` - Reload a specific plugin
105
- - `xsoar-cli plugins create-example` - Create an example plugin
106
- - `xsoar-cli plugins open` - Open the plugins directory
107
-
108
- ### Creating Your Own Plugins
109
-
110
- Create a Python file in `~/.local/xsoar-cli/plugins/` that inherits from `XSOARPlugin`:
111
-
112
- ```python
113
- import click
114
- from xsoar_cli.plugins import XSOARPlugin
115
-
116
- class MyPlugin(XSOARPlugin):
117
- @property
118
- def name(self) -> str:
119
- return "myplugin"
120
-
121
- @property
122
- def version(self) -> str:
123
- return "1.0.0"
124
-
125
- def get_command(self) -> click.Command:
126
- @click.command(help="My custom command")
127
- def mycommand():
128
- click.echo("Hello from my plugin!")
129
- return mycommand
130
- ```
131
-
132
- For detailed documentation, see [Plugin System Documentation](src/xsoar_cli/plugins/README.md).
133
-
134
- ## License
135
-
136
- `xsoar-cli` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.