sansible 0.2.0__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 (69) hide show
  1. sansible-0.2.0/LICENSE +21 -0
  2. sansible-0.2.0/PKG-INFO +320 -0
  3. sansible-0.2.0/README.md +270 -0
  4. sansible-0.2.0/pyproject.toml +133 -0
  5. sansible-0.2.0/setup.cfg +4 -0
  6. sansible-0.2.0/src/sansible/__init__.py +27 -0
  7. sansible-0.2.0/src/sansible/cli/__init__.py +1 -0
  8. sansible-0.2.0/src/sansible/cli/inventory.py +136 -0
  9. sansible-0.2.0/src/sansible/cli/main.py +113 -0
  10. sansible-0.2.0/src/sansible/cli/playbook.py +213 -0
  11. sansible-0.2.0/src/sansible/compat_scan.py +470 -0
  12. sansible-0.2.0/src/sansible/connections/__init__.py +15 -0
  13. sansible-0.2.0/src/sansible/connections/base.py +176 -0
  14. sansible-0.2.0/src/sansible/connections/local.py +193 -0
  15. sansible-0.2.0/src/sansible/connections/ssh_asyncssh.py +269 -0
  16. sansible-0.2.0/src/sansible/connections/winrm_psrp.py +389 -0
  17. sansible-0.2.0/src/sansible/engine/__init__.py +35 -0
  18. sansible-0.2.0/src/sansible/engine/errors.py +170 -0
  19. sansible-0.2.0/src/sansible/engine/inventory.py +552 -0
  20. sansible-0.2.0/src/sansible/engine/playbook.py +631 -0
  21. sansible-0.2.0/src/sansible/engine/results.py +199 -0
  22. sansible-0.2.0/src/sansible/engine/runner.py +614 -0
  23. sansible-0.2.0/src/sansible/engine/scheduler.py +450 -0
  24. sansible-0.2.0/src/sansible/engine/templating.py +333 -0
  25. sansible-0.2.0/src/sansible/inventory/__init__.py +13 -0
  26. sansible-0.2.0/src/sansible/inventory/group.py +93 -0
  27. sansible-0.2.0/src/sansible/inventory/host.py +68 -0
  28. sansible-0.2.0/src/sansible/inventory/parser.py +316 -0
  29. sansible-0.2.0/src/sansible/modules/__init__.py +14 -0
  30. sansible-0.2.0/src/sansible/modules/base.py +300 -0
  31. sansible-0.2.0/src/sansible/modules/builtin_assert.py +69 -0
  32. sansible-0.2.0/src/sansible/modules/builtin_command.py +91 -0
  33. sansible-0.2.0/src/sansible/modules/builtin_copy.py +193 -0
  34. sansible-0.2.0/src/sansible/modules/builtin_debug.py +48 -0
  35. sansible-0.2.0/src/sansible/modules/builtin_fail.py +32 -0
  36. sansible-0.2.0/src/sansible/modules/builtin_file.py +250 -0
  37. sansible-0.2.0/src/sansible/modules/builtin_lineinfile.py +159 -0
  38. sansible-0.2.0/src/sansible/modules/builtin_raw.py +54 -0
  39. sansible-0.2.0/src/sansible/modules/builtin_set_fact.py +39 -0
  40. sansible-0.2.0/src/sansible/modules/builtin_setup.py +171 -0
  41. sansible-0.2.0/src/sansible/modules/builtin_shell.py +92 -0
  42. sansible-0.2.0/src/sansible/modules/builtin_stat.py +69 -0
  43. sansible-0.2.0/src/sansible/modules/builtin_template.py +159 -0
  44. sansible-0.2.0/src/sansible/modules/builtin_wait_for.py +129 -0
  45. sansible-0.2.0/src/sansible/modules/win_command.py +82 -0
  46. sansible-0.2.0/src/sansible/modules/win_copy.py +168 -0
  47. sansible-0.2.0/src/sansible/modules/win_file.py +205 -0
  48. sansible-0.2.0/src/sansible/modules/win_lineinfile.py +155 -0
  49. sansible-0.2.0/src/sansible/modules/win_service.py +156 -0
  50. sansible-0.2.0/src/sansible/modules/win_shell.py +81 -0
  51. sansible-0.2.0/src/sansible/modules/win_stat.py +96 -0
  52. sansible-0.2.0/src/sansible/modules/win_wait_for.py +130 -0
  53. sansible-0.2.0/src/sansible/platform/__init__.py +16 -0
  54. sansible-0.2.0/src/sansible/platform/concurrency.py +232 -0
  55. sansible-0.2.0/src/sansible/platform/fs.py +216 -0
  56. sansible-0.2.0/src/sansible/platform/locks.py +187 -0
  57. sansible-0.2.0/src/sansible/platform/paths.py +132 -0
  58. sansible-0.2.0/src/sansible/platform/proc.py +247 -0
  59. sansible-0.2.0/src/sansible/platform/tty.py +198 -0
  60. sansible-0.2.0/src/sansible/platform/users.py +161 -0
  61. sansible-0.2.0/src/sansible/py.typed +0 -0
  62. sansible-0.2.0/src/sansible/release.py +13 -0
  63. sansible-0.2.0/src/sansible/san_cli.py +206 -0
  64. sansible-0.2.0/src/sansible.egg-info/PKG-INFO +320 -0
  65. sansible-0.2.0/src/sansible.egg-info/SOURCES.txt +67 -0
  66. sansible-0.2.0/src/sansible.egg-info/dependency_links.txt +1 -0
  67. sansible-0.2.0/src/sansible.egg-info/entry_points.txt +6 -0
  68. sansible-0.2.0/src/sansible.egg-info/requires.txt +20 -0
  69. sansible-0.2.0/src/sansible.egg-info/top_level.txt +1 -0
sansible-0.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sansible Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,320 @@
1
+ Metadata-Version: 2.4
2
+ Name: sansible
3
+ Version: 0.2.0
4
+ Summary: Small Ansible - Minimal Ansible-compatible runner for Windows and Linux
5
+ Author: Sansible Contributors
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/small-ansible/sansible
8
+ Project-URL: Documentation, https://github.com/small-ansible/sansible/docs
9
+ Project-URL: Repository, https://github.com/small-ansible/sansible
10
+ Keywords: ansible,automation,configuration-management,windows,ssh,winrm,devops,infrastructure,small-ansible
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: System Administrators
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Operating System :: Microsoft :: Windows
18
+ Classifier: Operating System :: POSIX :: Linux
19
+ Classifier: Operating System :: MacOS
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3.9
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
+ Classifier: Programming Language :: Python :: Implementation :: CPython
27
+ Classifier: Topic :: System :: Systems Administration
28
+ Classifier: Topic :: System :: Installation/Setup
29
+ Classifier: Typing :: Typed
30
+ Requires-Python: >=3.9
31
+ Description-Content-Type: text/markdown
32
+ License-File: LICENSE
33
+ Requires-Dist: pyyaml>=6.0
34
+ Requires-Dist: jinja2>=3.0
35
+ Provides-Extra: ssh
36
+ Requires-Dist: asyncssh>=2.14.0; extra == "ssh"
37
+ Provides-Extra: winrm
38
+ Requires-Dist: pypsrp>=0.8.0; extra == "winrm"
39
+ Provides-Extra: all
40
+ Requires-Dist: sansible[ssh,winrm]; extra == "all"
41
+ Provides-Extra: dev
42
+ Requires-Dist: pytest>=7.0; extra == "dev"
43
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
44
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
45
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
46
+ Requires-Dist: mypy>=1.0; extra == "dev"
47
+ Requires-Dist: ansible-core>=2.15.0; extra == "dev"
48
+ Requires-Dist: docker>=6.0.0; extra == "dev"
49
+ Dynamic: license-file
50
+
51
+ # Sansible
52
+
53
+ [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
54
+ [![Pure Python](https://img.shields.io/badge/wheel-py3--none--any-green.svg)](https://pypi.org/project/sansible/)
55
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
56
+
57
+ **A minimal, pure-Python Ansible runner for Windows and Linux**
58
+
59
+ Sansible runs Ansible playbooks natively on Windows without WSL, targeting both Windows (WinRM) and Linux (SSH) hosts. It delivers 80% of Ansible's value with 20% of the code.
60
+
61
+ ## ✨ Highlights
62
+
63
+ - 🪟 **Windows Native** — Run as a control node on Windows, no WSL required
64
+ - 🐍 **Pure Python** — Ships as \`py3-none-any\` wheel, no compiled extensions
65
+ - 🚀 **Fast Setup** — \`pip install sansible\` and you're ready
66
+ - 📦 **Ansible Compatible** — Uses the same playbook/inventory syntax
67
+ - 🎯 **Focused** — Core features that cover most use cases
68
+
69
+ ## 🚀 Quick Start
70
+
71
+ ### Installation
72
+
73
+ \`\`\`bash
74
+ # Basic installation (local execution only)
75
+ pip install sansible
76
+
77
+ # With SSH support (Linux/Unix targets)
78
+ pip install "sansible[ssh]"
79
+
80
+ # With WinRM support (Windows targets)
81
+ pip install "sansible[winrm]"
82
+
83
+ # Full installation (all transports)
84
+ pip install "sansible[all]"
85
+ \`\`\`
86
+
87
+ ### Your First Playbook
88
+
89
+ Create \`hello.yml\`:
90
+
91
+ \`\`\`yaml
92
+ ---
93
+ - name: Hello World
94
+ hosts: localhost
95
+ gather_facts: false
96
+ tasks:
97
+ - name: Say hello
98
+ debug:
99
+ msg: "Hello from Sansible!"
100
+
101
+ - name: Run a command
102
+ command: echo "It works!"
103
+ register: result
104
+
105
+ - name: Show result
106
+ debug:
107
+ var: result.stdout
108
+ \`\`\`
109
+
110
+ Create \`inventory.ini\`:
111
+
112
+ \`\`\`ini
113
+ [local]
114
+ localhost ansible_connection=local
115
+ \`\`\`
116
+
117
+ Run it:
118
+
119
+ \`\`\`bash
120
+ san run -i inventory.ini hello.yml
121
+ \`\`\`
122
+
123
+ Output:
124
+
125
+ \`\`\`
126
+ PLAY [Hello World] ************************************************************
127
+
128
+ TASK [Say hello] **************************************************************
129
+ ok: [localhost]
130
+
131
+ TASK [Run a command] **********************************************************
132
+ changed: [localhost]
133
+
134
+ TASK [Show result] ************************************************************
135
+ ok: [localhost]
136
+
137
+ PLAY RECAP ********************************************************************
138
+ localhost : ok=3 changed=1 failed=0
139
+ \`\`\`
140
+
141
+ ## 📖 Examples
142
+
143
+ The \`examples/playbooks/\` directory contains runnable examples for all features:
144
+
145
+ | Playbook | Features |
146
+ |----------|----------|
147
+ | [01_basics.yml](examples/playbooks/01_basics.yml) | debug, set_fact, command, shell, copy |
148
+ | [02_conditionals.yml](examples/playbooks/02_conditionals.yml) | when, loop, register, changed_when |
149
+ | [03_file_management.yml](examples/playbooks/03_file_management.yml) | file, copy, stat, lineinfile |
150
+ | [04_handlers.yml](examples/playbooks/04_handlers.yml) | handlers, notify, listen |
151
+ | [05_blocks.yml](examples/playbooks/05_blocks.yml) | block, rescue, always |
152
+ | [06_become.yml](examples/playbooks/06_become.yml) | become (sudo) |
153
+ | [07_gather_facts.yml](examples/playbooks/07_gather_facts.yml) | gather_facts, setup |
154
+ | [08_wait_for.yml](examples/playbooks/08_wait_for.yml) | wait_for (port, file) |
155
+ | [09_assert_fail.yml](examples/playbooks/09_assert_fail.yml) | assert, fail |
156
+ | [10_roles.yml](examples/playbooks/10_roles.yml) | roles |
157
+ | [11_check_diff.yml](examples/playbooks/11_check_diff.yml) | --check, --diff modes |
158
+
159
+ **Windows Examples:**
160
+
161
+ | Playbook | Features |
162
+ |----------|----------|
163
+ | [win_01_basics.yml](examples/playbooks/win_01_basics.yml) | win_command, win_shell, win_copy |
164
+ | [win_02_services.yml](examples/playbooks/win_02_services.yml) | win_service |
165
+ | [win_03_files.yml](examples/playbooks/win_03_files.yml) | win_stat, win_lineinfile |
166
+
167
+ Run any example:
168
+
169
+ \`\`\`bash
170
+ san run -i examples/playbooks/inventory.ini examples/playbooks/01_basics.yml -l localhost
171
+ \`\`\`
172
+
173
+ ## 🛠 Supported Features
174
+
175
+ ### Modules
176
+
177
+ | Linux | Windows | Purpose |
178
+ |-------|---------|---------|
179
+ | \`command\` | \`win_command\` | Execute command |
180
+ | \`shell\` | \`win_shell\` | Execute shell/PowerShell |
181
+ | \`copy\` | \`win_copy\` | Copy files |
182
+ | \`file\` | \`win_file\` | Manage files/directories |
183
+ | \`template\` | — | Render Jinja2 templates |
184
+ | \`stat\` | \`win_stat\` | Get file info |
185
+ | \`lineinfile\` | \`win_lineinfile\` | Manage lines in files |
186
+ | \`wait_for\` | \`win_wait_for\` | Wait for port/file |
187
+ | \`setup\` | \`setup\` | Gather facts |
188
+ | \`debug\` | \`debug\` | Print messages |
189
+ | \`set_fact\` | \`set_fact\` | Set variables |
190
+ | \`fail\` | \`fail\` | Fail with message |
191
+ | \`assert\` | \`assert\` | Assert conditions |
192
+ | — | \`win_service\` | Manage Windows services |
193
+
194
+ ### Playbook Features
195
+
196
+ | Feature | Status | Notes |
197
+ |---------|--------|-------|
198
+ | Multiple plays | ✅ | Sequential execution |
199
+ | Variables (\`vars\`, \`vars_files\`) | ✅ | Full support |
200
+ | Conditionals (\`when\`) | ✅ | Jinja2 expressions |
201
+ | Loops (\`loop\`, \`with_items\`) | ✅ | List iteration |
202
+ | Handlers (\`notify\`, \`listen\`) | ✅ | Triggered on change |
203
+ | Error handling (\`block/rescue/always\`) | ✅ | Try/catch blocks |
204
+ | Privilege escalation (\`become\`) | ✅ | sudo, su |
205
+ | Fact gathering (\`gather_facts\`) | ✅ | OS info |
206
+ | Roles | ✅ | tasks, defaults, vars |
207
+ | Check mode (\`--check\`) | ✅ | Dry run |
208
+ | Diff mode (\`--diff\`) | ✅ | Show changes |
209
+ | JSON output (\`--json\`) | ✅ | Machine-readable |
210
+
211
+ ### Connections
212
+
213
+ | Type | Dependency | Platform |
214
+ |------|------------|----------|
215
+ | \`local\` | None | Control node |
216
+ | \`ssh\` | \`asyncssh\` | Linux/Unix |
217
+ | \`winrm\` | \`pypsrp\` | Windows |
218
+
219
+ ## 📋 CLI Reference
220
+
221
+ ### san run / sansible-playbook
222
+
223
+ \`\`\`bash
224
+ san run -i INVENTORY PLAYBOOK [OPTIONS]
225
+
226
+ Options:
227
+ -i, --inventory FILE Inventory file (required)
228
+ -l, --limit PATTERN Limit to hosts matching pattern
229
+ -t, --tags TAGS Only run tagged tasks
230
+ --skip-tags TAGS Skip tagged tasks
231
+ -e, --extra-vars VARS Extra variables (JSON or key=value)
232
+ -f, --forks N Parallel execution limit (default: 5)
233
+ -C, --check Dry-run mode (no changes)
234
+ --diff Show file differences
235
+ --json JSON output format
236
+ -v/-vv/-vvv Verbosity level
237
+ \`\`\`
238
+
239
+ ### Examples
240
+
241
+ \`\`\`bash
242
+ # Basic execution
243
+ san run -i inventory.ini playbook.yml
244
+
245
+ # Limit to specific hosts
246
+ san run -i inventory.ini playbook.yml -l webservers
247
+
248
+ # Check mode (dry run)
249
+ san run -i inventory.ini playbook.yml --check
250
+
251
+ # Show what would change
252
+ san run -i inventory.ini playbook.yml --check --diff
253
+
254
+ # Extra variables
255
+ san run -i inventory.ini playbook.yml -e "version=2.0"
256
+
257
+ # JSON output for scripting
258
+ san run -i inventory.ini playbook.yml --json
259
+ \`\`\`
260
+
261
+ ## ⚠️ Not Supported
262
+
263
+ Sansible focuses on core features. These are **not supported**:
264
+
265
+ - Ansible Galaxy / Collections
266
+ - \`include_tasks\`, \`import_tasks\`, \`import_role\`
267
+ - \`delegate_to\`
268
+ - \`async\` / \`poll\`
269
+ - Vault
270
+ - Callbacks / Plugins
271
+ - Dynamic inventory scripts
272
+
273
+ Unsupported features raise \`UnsupportedFeatureError\` with a clear message.
274
+
275
+ ## 🔧 Development
276
+
277
+ \`\`\`bash
278
+ # Clone repository
279
+ git clone https://github.com/your-org/sansible.git
280
+ cd sansible
281
+
282
+ # Install with dev dependencies
283
+ pip install -e ".[dev]"
284
+
285
+ # Run tests
286
+ pytest tests/unit/ -v
287
+
288
+ # Run a specific test
289
+ pytest tests/unit/test_become.py -v
290
+
291
+ # Build wheel
292
+ pip wheel . -w dist/
293
+
294
+ # Verify pure Python wheel
295
+ python -m tools.dep_audit
296
+ \`\`\`
297
+
298
+ ## 📊 Exit Codes
299
+
300
+ | Code | Meaning |
301
+ |------|---------|
302
+ | 0 | Success |
303
+ | 2 | Host failure(s) |
304
+ | 3 | Parse/syntax error |
305
+ | 4 | Unsupported feature |
306
+
307
+ ## 📚 Documentation
308
+
309
+ - [Architecture](docs/ARCHITECTURE.md) — System design
310
+ - [Compatibility](docs/COMPATIBILITY.md) — Feature matrix
311
+ - [Testing](docs/TESTING.md) — Test instructions
312
+ - [Contributing](docs/AI_HANDOFF.md) — Development guide
313
+
314
+ ## 📄 License
315
+
316
+ MIT License — See [LICENSE](LICENSE) for details.
317
+
318
+ ---
319
+
320
+ **Made with ❤️ for Windows DevOps engineers who just want to run playbooks.**
@@ -0,0 +1,270 @@
1
+ # Sansible
2
+
3
+ [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
4
+ [![Pure Python](https://img.shields.io/badge/wheel-py3--none--any-green.svg)](https://pypi.org/project/sansible/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ **A minimal, pure-Python Ansible runner for Windows and Linux**
8
+
9
+ Sansible runs Ansible playbooks natively on Windows without WSL, targeting both Windows (WinRM) and Linux (SSH) hosts. It delivers 80% of Ansible's value with 20% of the code.
10
+
11
+ ## ✨ Highlights
12
+
13
+ - 🪟 **Windows Native** — Run as a control node on Windows, no WSL required
14
+ - 🐍 **Pure Python** — Ships as \`py3-none-any\` wheel, no compiled extensions
15
+ - 🚀 **Fast Setup** — \`pip install sansible\` and you're ready
16
+ - 📦 **Ansible Compatible** — Uses the same playbook/inventory syntax
17
+ - 🎯 **Focused** — Core features that cover most use cases
18
+
19
+ ## 🚀 Quick Start
20
+
21
+ ### Installation
22
+
23
+ \`\`\`bash
24
+ # Basic installation (local execution only)
25
+ pip install sansible
26
+
27
+ # With SSH support (Linux/Unix targets)
28
+ pip install "sansible[ssh]"
29
+
30
+ # With WinRM support (Windows targets)
31
+ pip install "sansible[winrm]"
32
+
33
+ # Full installation (all transports)
34
+ pip install "sansible[all]"
35
+ \`\`\`
36
+
37
+ ### Your First Playbook
38
+
39
+ Create \`hello.yml\`:
40
+
41
+ \`\`\`yaml
42
+ ---
43
+ - name: Hello World
44
+ hosts: localhost
45
+ gather_facts: false
46
+ tasks:
47
+ - name: Say hello
48
+ debug:
49
+ msg: "Hello from Sansible!"
50
+
51
+ - name: Run a command
52
+ command: echo "It works!"
53
+ register: result
54
+
55
+ - name: Show result
56
+ debug:
57
+ var: result.stdout
58
+ \`\`\`
59
+
60
+ Create \`inventory.ini\`:
61
+
62
+ \`\`\`ini
63
+ [local]
64
+ localhost ansible_connection=local
65
+ \`\`\`
66
+
67
+ Run it:
68
+
69
+ \`\`\`bash
70
+ san run -i inventory.ini hello.yml
71
+ \`\`\`
72
+
73
+ Output:
74
+
75
+ \`\`\`
76
+ PLAY [Hello World] ************************************************************
77
+
78
+ TASK [Say hello] **************************************************************
79
+ ok: [localhost]
80
+
81
+ TASK [Run a command] **********************************************************
82
+ changed: [localhost]
83
+
84
+ TASK [Show result] ************************************************************
85
+ ok: [localhost]
86
+
87
+ PLAY RECAP ********************************************************************
88
+ localhost : ok=3 changed=1 failed=0
89
+ \`\`\`
90
+
91
+ ## 📖 Examples
92
+
93
+ The \`examples/playbooks/\` directory contains runnable examples for all features:
94
+
95
+ | Playbook | Features |
96
+ |----------|----------|
97
+ | [01_basics.yml](examples/playbooks/01_basics.yml) | debug, set_fact, command, shell, copy |
98
+ | [02_conditionals.yml](examples/playbooks/02_conditionals.yml) | when, loop, register, changed_when |
99
+ | [03_file_management.yml](examples/playbooks/03_file_management.yml) | file, copy, stat, lineinfile |
100
+ | [04_handlers.yml](examples/playbooks/04_handlers.yml) | handlers, notify, listen |
101
+ | [05_blocks.yml](examples/playbooks/05_blocks.yml) | block, rescue, always |
102
+ | [06_become.yml](examples/playbooks/06_become.yml) | become (sudo) |
103
+ | [07_gather_facts.yml](examples/playbooks/07_gather_facts.yml) | gather_facts, setup |
104
+ | [08_wait_for.yml](examples/playbooks/08_wait_for.yml) | wait_for (port, file) |
105
+ | [09_assert_fail.yml](examples/playbooks/09_assert_fail.yml) | assert, fail |
106
+ | [10_roles.yml](examples/playbooks/10_roles.yml) | roles |
107
+ | [11_check_diff.yml](examples/playbooks/11_check_diff.yml) | --check, --diff modes |
108
+
109
+ **Windows Examples:**
110
+
111
+ | Playbook | Features |
112
+ |----------|----------|
113
+ | [win_01_basics.yml](examples/playbooks/win_01_basics.yml) | win_command, win_shell, win_copy |
114
+ | [win_02_services.yml](examples/playbooks/win_02_services.yml) | win_service |
115
+ | [win_03_files.yml](examples/playbooks/win_03_files.yml) | win_stat, win_lineinfile |
116
+
117
+ Run any example:
118
+
119
+ \`\`\`bash
120
+ san run -i examples/playbooks/inventory.ini examples/playbooks/01_basics.yml -l localhost
121
+ \`\`\`
122
+
123
+ ## 🛠 Supported Features
124
+
125
+ ### Modules
126
+
127
+ | Linux | Windows | Purpose |
128
+ |-------|---------|---------|
129
+ | \`command\` | \`win_command\` | Execute command |
130
+ | \`shell\` | \`win_shell\` | Execute shell/PowerShell |
131
+ | \`copy\` | \`win_copy\` | Copy files |
132
+ | \`file\` | \`win_file\` | Manage files/directories |
133
+ | \`template\` | — | Render Jinja2 templates |
134
+ | \`stat\` | \`win_stat\` | Get file info |
135
+ | \`lineinfile\` | \`win_lineinfile\` | Manage lines in files |
136
+ | \`wait_for\` | \`win_wait_for\` | Wait for port/file |
137
+ | \`setup\` | \`setup\` | Gather facts |
138
+ | \`debug\` | \`debug\` | Print messages |
139
+ | \`set_fact\` | \`set_fact\` | Set variables |
140
+ | \`fail\` | \`fail\` | Fail with message |
141
+ | \`assert\` | \`assert\` | Assert conditions |
142
+ | — | \`win_service\` | Manage Windows services |
143
+
144
+ ### Playbook Features
145
+
146
+ | Feature | Status | Notes |
147
+ |---------|--------|-------|
148
+ | Multiple plays | ✅ | Sequential execution |
149
+ | Variables (\`vars\`, \`vars_files\`) | ✅ | Full support |
150
+ | Conditionals (\`when\`) | ✅ | Jinja2 expressions |
151
+ | Loops (\`loop\`, \`with_items\`) | ✅ | List iteration |
152
+ | Handlers (\`notify\`, \`listen\`) | ✅ | Triggered on change |
153
+ | Error handling (\`block/rescue/always\`) | ✅ | Try/catch blocks |
154
+ | Privilege escalation (\`become\`) | ✅ | sudo, su |
155
+ | Fact gathering (\`gather_facts\`) | ✅ | OS info |
156
+ | Roles | ✅ | tasks, defaults, vars |
157
+ | Check mode (\`--check\`) | ✅ | Dry run |
158
+ | Diff mode (\`--diff\`) | ✅ | Show changes |
159
+ | JSON output (\`--json\`) | ✅ | Machine-readable |
160
+
161
+ ### Connections
162
+
163
+ | Type | Dependency | Platform |
164
+ |------|------------|----------|
165
+ | \`local\` | None | Control node |
166
+ | \`ssh\` | \`asyncssh\` | Linux/Unix |
167
+ | \`winrm\` | \`pypsrp\` | Windows |
168
+
169
+ ## 📋 CLI Reference
170
+
171
+ ### san run / sansible-playbook
172
+
173
+ \`\`\`bash
174
+ san run -i INVENTORY PLAYBOOK [OPTIONS]
175
+
176
+ Options:
177
+ -i, --inventory FILE Inventory file (required)
178
+ -l, --limit PATTERN Limit to hosts matching pattern
179
+ -t, --tags TAGS Only run tagged tasks
180
+ --skip-tags TAGS Skip tagged tasks
181
+ -e, --extra-vars VARS Extra variables (JSON or key=value)
182
+ -f, --forks N Parallel execution limit (default: 5)
183
+ -C, --check Dry-run mode (no changes)
184
+ --diff Show file differences
185
+ --json JSON output format
186
+ -v/-vv/-vvv Verbosity level
187
+ \`\`\`
188
+
189
+ ### Examples
190
+
191
+ \`\`\`bash
192
+ # Basic execution
193
+ san run -i inventory.ini playbook.yml
194
+
195
+ # Limit to specific hosts
196
+ san run -i inventory.ini playbook.yml -l webservers
197
+
198
+ # Check mode (dry run)
199
+ san run -i inventory.ini playbook.yml --check
200
+
201
+ # Show what would change
202
+ san run -i inventory.ini playbook.yml --check --diff
203
+
204
+ # Extra variables
205
+ san run -i inventory.ini playbook.yml -e "version=2.0"
206
+
207
+ # JSON output for scripting
208
+ san run -i inventory.ini playbook.yml --json
209
+ \`\`\`
210
+
211
+ ## ⚠️ Not Supported
212
+
213
+ Sansible focuses on core features. These are **not supported**:
214
+
215
+ - Ansible Galaxy / Collections
216
+ - \`include_tasks\`, \`import_tasks\`, \`import_role\`
217
+ - \`delegate_to\`
218
+ - \`async\` / \`poll\`
219
+ - Vault
220
+ - Callbacks / Plugins
221
+ - Dynamic inventory scripts
222
+
223
+ Unsupported features raise \`UnsupportedFeatureError\` with a clear message.
224
+
225
+ ## 🔧 Development
226
+
227
+ \`\`\`bash
228
+ # Clone repository
229
+ git clone https://github.com/your-org/sansible.git
230
+ cd sansible
231
+
232
+ # Install with dev dependencies
233
+ pip install -e ".[dev]"
234
+
235
+ # Run tests
236
+ pytest tests/unit/ -v
237
+
238
+ # Run a specific test
239
+ pytest tests/unit/test_become.py -v
240
+
241
+ # Build wheel
242
+ pip wheel . -w dist/
243
+
244
+ # Verify pure Python wheel
245
+ python -m tools.dep_audit
246
+ \`\`\`
247
+
248
+ ## 📊 Exit Codes
249
+
250
+ | Code | Meaning |
251
+ |------|---------|
252
+ | 0 | Success |
253
+ | 2 | Host failure(s) |
254
+ | 3 | Parse/syntax error |
255
+ | 4 | Unsupported feature |
256
+
257
+ ## 📚 Documentation
258
+
259
+ - [Architecture](docs/ARCHITECTURE.md) — System design
260
+ - [Compatibility](docs/COMPATIBILITY.md) — Feature matrix
261
+ - [Testing](docs/TESTING.md) — Test instructions
262
+ - [Contributing](docs/AI_HANDOFF.md) — Development guide
263
+
264
+ ## 📄 License
265
+
266
+ MIT License — See [LICENSE](LICENSE) for details.
267
+
268
+ ---
269
+
270
+ **Made with ❤️ for Windows DevOps engineers who just want to run playbooks.**