netscaler-certbot-hook 1.0.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.
@@ -0,0 +1,162 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [1.0.0] - 2025-01-11
9
+
10
+ ### Major Refactoring - Production Ready Release
11
+
12
+ This release represents a complete overhaul of the codebase, transforming it from a working script into a professional, production-ready Python application with comprehensive documentation, error handling, and modern development practices.
13
+
14
+ ### Added
15
+
16
+ #### Code Structure & Quality
17
+ - Complete refactoring into 14 well-structured functions
18
+ - `parse_arguments()` - Dedicated argument parsing
19
+ - `get_config()` - Configuration building with full validation
20
+ - `get_certificate_serial()` - Certificate parsing abstraction
21
+ - `process_chain_certificate()` - Chain certificate handling
22
+ - `process_certificate()` - Main certificate processing
23
+ - `install_or_update_certificate()` - Unified install/update logic
24
+ - `setup_logging()` - Configurable logging setup
25
+ - Proper `main()` function with `if __name__ == '__main__'` pattern
26
+
27
+ #### Logging Framework
28
+ - Python `logging` module integration (replaced all `print()` statements)
29
+ - `--verbose` flag for DEBUG level output
30
+ - `--quiet` flag for ERROR-only output
31
+ - Structured log messages with proper formatting
32
+ - Debug information for troubleshooting
33
+ - Cron-friendly logging options
34
+
35
+ #### Error Handling
36
+ - Specific exception types (no more bare `except:` blocks)
37
+ - `requests.exceptions.Timeout` - Request timeout handling
38
+ - `requests.exceptions.ConnectionError` - Connection failure handling
39
+ - `requests.exceptions.HTTPError` - HTTP error handling
40
+ - `requests.exceptions.RequestException` - General request errors
41
+ - File existence validation before operations
42
+ - URL format validation
43
+ - Empty credentials validation
44
+ - Certificate format validation
45
+ - 30-second timeout for all NITRO API requests
46
+
47
+ #### Documentation
48
+ - Comprehensive module-level docstrings (PEP 257)
49
+ - Google/NumPy style function docstrings for all functions
50
+ - Complete type hints throughout codebase
51
+ - Detailed API documentation for NITRO client
52
+
53
+ #### Project Files
54
+ - `requirements.txt` - Dependency specification
55
+ - `.gitignore` - Comprehensive Python gitignore with security patterns
56
+ - `setup.py` - PyPI-ready installation script
57
+ - `LICENSE` - MIT License
58
+ - `TODO.md` - Structured improvement roadmap
59
+
60
+ #### README Improvements
61
+ - Badges (License, Python version)
62
+ - Features list with checkmarks
63
+ - Architecture diagram reference
64
+ - Prerequisites section
65
+ - Installation instructions (pip and package modes)
66
+ - Environment variables table
67
+ - Command-line arguments table
68
+ - Logging documentation with examples
69
+ - Step-by-step usage guide
70
+ - Example output for multiple scenarios
71
+ - Security considerations section
72
+ - Comprehensive troubleshooting guide
73
+ - Exit codes documentation
74
+ - Cron automation examples
75
+
76
+ ### Changed
77
+
78
+ #### NITRO Client (`nitro.py`)
79
+ - Enhanced with comprehensive type hints
80
+ - Improved error messages with context (URLs, file paths)
81
+ - Better exception handling with specific types
82
+ - PEP 8 compliant formatting
83
+ - Complete docstrings for all 15 methods
84
+
85
+ #### Main Script (`netscaler-certbot-hook.py`)
86
+ - From ~271 lines to ~639 lines (with documentation)
87
+ - Eliminated ~80 lines of code duplication
88
+ - Better separation of concerns
89
+ - All functions are now independently testable
90
+ - Clear, descriptive function names
91
+
92
+ ### Fixed
93
+
94
+ #### Critical Bug Fixes
95
+ - **SSL Verification Bug**: Fixed `verify_ssl` boolean conversion
96
+ - Before: `os.getenv('NS_VERIFY_SSL', True)` always returned True (string)
97
+ - After: `os.getenv('NS_VERIFY_SSL', 'true').lower() in ('true', '1', 'yes')`
98
+ - Proper file validation before operations
99
+ - Configuration validation at startup
100
+ - Better URL parsing
101
+
102
+ ### Security
103
+
104
+ - SSL verification enabled by default
105
+ - Sensitive data excluded from `.gitignore` (certificates, keys, env files)
106
+ - Credentials not logged to output
107
+ - Certificate files validated before processing
108
+ - Chain certificates require manual approval for updates (prevents unexpected changes)
109
+
110
+ ### Technical Details
111
+
112
+ #### Statistics
113
+ - **Total additions**: ~813 lines of improvements and documentation
114
+ - **Main script**: 271 → 639 lines (+368 lines documentation)
115
+ - **NITRO client**: 99 → 334 lines (+235 lines documentation)
116
+ - **README**: 87 → 417 lines (+330 lines documentation)
117
+
118
+ #### Backward Compatibility
119
+ - 100% backward compatible
120
+ - Same command-line interface
121
+ - Same environment variables
122
+ - Same behavior
123
+ - No breaking changes
124
+
125
+ #### Dependencies
126
+ - `pyOpenSSL>=20.0.0` - SSL certificate handling
127
+ - `requests>=2.25.0` - NITRO API communication
128
+ - Python 3.6+ required
129
+
130
+ ### Migration Guide
131
+
132
+ No migration needed! The script works exactly as before. All changes are internal improvements.
133
+
134
+ Existing commands continue to work:
135
+ ```bash
136
+ # Still works exactly as before
137
+ python3 netscaler-certbot-hook.py --name example.com
138
+ ```
139
+
140
+ New optional flags available:
141
+ ```bash
142
+ # New: Verbose mode
143
+ python3 netscaler-certbot-hook.py --name example.com --verbose
144
+
145
+ # New: Quiet mode
146
+ python3 netscaler-certbot-hook.py --name example.com --quiet
147
+ ```
148
+
149
+ ## [0.0.1] - 2020-02-16
150
+
151
+ ### Initial Release
152
+
153
+ - Basic certificate installation and renewal functionality
154
+ - NITRO API integration
155
+ - Let's Encrypt certificate support
156
+ - Chain certificate handling
157
+ - Configuration via environment variables
158
+
159
+ ---
160
+
161
+ [1.0.0]: https://github.com/slauger/netscaler-certbot-hook/compare/v0.0.1...v1.0.0
162
+ [0.0.1]: https://github.com/slauger/netscaler-certbot-hook/releases/tag/v0.0.1
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 Simon Lauger
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,6 @@
1
+ include README.md
2
+ include LICENSE
3
+ include CHANGELOG.md
4
+ include requirements.txt
5
+ include pyproject.toml
6
+ recursive-include src *.py
@@ -0,0 +1,462 @@
1
+ Metadata-Version: 2.4
2
+ Name: netscaler-certbot-hook
3
+ Version: 1.0.0
4
+ Summary: Automated SSL certificate management for Citrix NetScaler ADC using Certbot
5
+ Author-email: Simon Lauger <simon@lauger.de>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/slauger/netscaler-certbot-hook
8
+ Project-URL: Documentation, https://github.com/slauger/netscaler-certbot-hook#readme
9
+ Project-URL: Repository, https://github.com/slauger/netscaler-certbot-hook
10
+ Project-URL: Issues, https://github.com/slauger/netscaler-certbot-hook/issues
11
+ Project-URL: Changelog, https://github.com/slauger/netscaler-certbot-hook/blob/master/CHANGELOG.md
12
+ Keywords: netscaler,citrix,adc,certbot,letsencrypt,ssl,certificate,automation
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: Intended Audience :: System Administrators
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.6
17
+ Classifier: Programming Language :: Python :: 3.7
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Operating System :: OS Independent
24
+ Classifier: Topic :: System :: Systems Administration
25
+ Classifier: Topic :: Security :: Cryptography
26
+ Classifier: Topic :: Utilities
27
+ Requires-Python: >=3.6
28
+ Description-Content-Type: text/markdown
29
+ License-File: LICENSE
30
+ Requires-Dist: pyOpenSSL>=20.0.0
31
+ Requires-Dist: requests>=2.25.0
32
+ Dynamic: license-file
33
+
34
+ # NetScaler Certbot Hook
35
+
36
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
37
+ [![Python 3.6+](https://img.shields.io/badge/python-3.6+-blue.svg)](https://www.python.org/downloads/)
38
+
39
+ Automated SSL certificate management for Citrix NetScaler ADC. This tool seamlessly integrates with Certbot to install and renew Let's Encrypt certificates on NetScaler appliances via the NITRO API.
40
+
41
+ Perfect for automating certificate lifecycle management in combination with DNS-01 challenges for fully automated, hands-free certificate renewals.
42
+
43
+ ## Features
44
+
45
+ - ✅ **Automated Certificate Installation** - Upload and install certificates with a single command
46
+ - ✅ **Smart Updates** - Only updates certificates when serial numbers differ
47
+ - ✅ **Chain Certificate Handling** - Automatic linking to intermediate certificates
48
+ - ✅ **Configuration Persistence** - Automatically saves NetScaler configuration
49
+ - ✅ **Idempotent Operations** - Safe to run repeatedly, only changes when needed
50
+ - ✅ **Custom Certificate Paths** - Supports non-standard certificate locations
51
+ - ✅ **Comprehensive Validation** - Pre-flight checks for files, credentials, and configuration
52
+ - ✅ **Detailed Error Messages** - Clear feedback when something goes wrong
53
+ - ✅ **Type-Safe** - Full type hints for IDE support and static analysis
54
+
55
+ ## Architecture
56
+
57
+ ![Architecture](architecture.png)
58
+
59
+ The script connects to your NetScaler via NITRO API, compares certificate serial numbers, and performs uploads/installations only when necessary. Chain certificates are handled separately for security reasons.
60
+
61
+ ## Prerequisites
62
+
63
+ - **Python** 3.6 or higher
64
+ - **Citrix NetScaler ADC** with NITRO API access
65
+ - **Certbot** (for Let's Encrypt certificate enrollment)
66
+ - **Network access** to NetScaler management interface
67
+
68
+ ## Installation
69
+
70
+ ### Option 1: From PyPI (Recommended)
71
+
72
+ ```bash
73
+ # Install directly from PyPI
74
+ pip install netscaler-certbot-hook
75
+ ```
76
+
77
+ After installation, the `netscaler-certbot-hook` command will be available system-wide.
78
+
79
+ ### Option 2: From Source
80
+
81
+ ```bash
82
+ # Clone the repository
83
+ git clone https://github.com/slauger/netscaler-certbot-hook.git
84
+ cd netscaler-certbot-hook
85
+
86
+ # Install in development mode
87
+ pip install -e .
88
+ ```
89
+
90
+ ### Option 3: Install dependencies only
91
+
92
+ ```bash
93
+ # For manual script execution
94
+ pip install -r requirements.txt
95
+ ```
96
+
97
+ ### Dependencies
98
+
99
+ - `pyOpenSSL>=20.0.0` - SSL certificate handling
100
+ - `requests>=2.25.0` - NITRO API communication
101
+
102
+ ## Configuration
103
+
104
+ ### Environment Variables
105
+
106
+ The script requires the following environment variables:
107
+
108
+ | Variable | Required | Default | Description |
109
+ |----------|----------|---------|-------------|
110
+ | `NS_URL` | Yes | - | NetScaler management URL (e.g., `https://192.168.10.10`) |
111
+ | `NS_LOGIN` | No | `nsroot` | NetScaler administrator username |
112
+ | `NS_PASSWORD` | No | `nsroot` | NetScaler administrator password |
113
+ | `NS_VERIFY_SSL` | No | `true` | Verify SSL certificate (`true`, `false`, `1`, `0`) |
114
+
115
+ **Example:**
116
+ ```bash
117
+ export NS_URL=https://192.168.10.10
118
+ export NS_LOGIN=nsroot
119
+ export NS_PASSWORD=your-secure-password
120
+ export NS_VERIFY_SSL=true
121
+ ```
122
+
123
+ ### Command-Line Arguments
124
+
125
+ ```bash
126
+ netscaler-certbot-hook --help
127
+ ```
128
+
129
+ **Note:** If installed from PyPI, use `netscaler-certbot-hook`. If running from source, use `netscaler-certbot-hook` or `python3 -m netscaler_certbot_hook`.
130
+
131
+ | Argument | Required | Default | Description |
132
+ |----------|----------|---------|-------------|
133
+ | `--name` | Yes | - | Certificate object name on NetScaler |
134
+ | `--chain` | No | `letsencrypt` | Chain certificate object name |
135
+ | `--cert` | No | `/etc/letsencrypt/live/<name>/cert.pem` | Path to certificate file |
136
+ | `--privkey` | No | `/etc/letsencrypt/live/<name>/privkey.pem` | Path to private key file |
137
+ | `--chain-cert` | No | `/etc/letsencrypt/live/<name>/chain.pem` | Path to chain certificate file |
138
+ | `--verbose` | No | `false` | Enable verbose output (DEBUG level) |
139
+ | `--quiet` | No | `false` | Suppress all output except errors |
140
+
141
+ ## Usage
142
+
143
+ ### Step 1: Enroll Certificate with Certbot
144
+
145
+ First, obtain a certificate from Let's Encrypt using Certbot with DNS-01 challenge:
146
+
147
+ #### Example with Cloudflare DNS:
148
+
149
+ ```bash
150
+ certbot --text --agree-tos --non-interactive certonly \
151
+ --cert-name 'example.com' \
152
+ -d 'example.com' \
153
+ -d 'www.example.com' \
154
+ -a dns-cloudflare \
155
+ --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
156
+ --keep-until-expiring
157
+ ```
158
+
159
+ #### Example with other DNS providers:
160
+
161
+ ```bash
162
+ # Route53 (AWS)
163
+ certbot certonly --dns-route53 -d example.com
164
+
165
+ # Google Cloud DNS
166
+ certbot certonly --dns-google -d example.com
167
+
168
+ # Manual DNS (for testing)
169
+ certbot certonly --manual --preferred-challenges dns -d example.com
170
+ ```
171
+
172
+ ### Step 2: Install Certificate on NetScaler
173
+
174
+ #### Basic Usage (Default Paths):
175
+
176
+ ```bash
177
+ netscaler-certbot-hook --name example.com
178
+ ```
179
+
180
+ #### Custom Certificate Paths:
181
+
182
+ ```bash
183
+ netscaler-certbot-hook --name example.com \
184
+ --cert /path/to/cert.pem \
185
+ --privkey /path/to/privkey.pem \
186
+ --chain-cert /path/to/chain.pem
187
+ ```
188
+
189
+ #### Custom Chain Certificate Name:
190
+
191
+ ```bash
192
+ netscaler-certbot-hook --name example.com --chain my-chain
193
+ ```
194
+
195
+ #### Verbose Output for Debugging:
196
+
197
+ ```bash
198
+ # Enable detailed DEBUG logging
199
+ netscaler-certbot-hook --name example.com --verbose
200
+ ```
201
+
202
+ #### Quiet Mode for Cron Jobs:
203
+
204
+ ```bash
205
+ # Suppress all output except errors
206
+ netscaler-certbot-hook --name example.com --quiet
207
+ ```
208
+
209
+ ### Step 3: Automate with Cron
210
+
211
+ Add to your crontab for automatic renewal:
212
+
213
+ ```bash
214
+ # Renew certificates daily and update NetScaler
215
+ 0 3 * * * certbot renew --quiet && netscaler-certbot-hook --name example.com
216
+ ```
217
+
218
+ Or create a Certbot deploy hook:
219
+
220
+ ```bash
221
+ # /etc/letsencrypt/renewal-hooks/deploy/netscaler-hook.sh
222
+ #!/bin/bash
223
+ export NS_URL=https://192.168.10.10
224
+ export NS_LOGIN=nsroot
225
+ export NS_PASSWORD=your-password
226
+
227
+ netscaler-certbot-hook --name $RENEWED_DOMAINS
228
+ ```
229
+
230
+ Make it executable:
231
+ ```bash
232
+ chmod +x /etc/letsencrypt/renewal-hooks/deploy/netscaler-hook.sh
233
+ ```
234
+
235
+ ## Logging
236
+
237
+ The script uses Python's built-in logging framework for structured output. You can control the verbosity with command-line flags:
238
+
239
+ ### Log Levels
240
+
241
+ | Flag | Log Level | Use Case |
242
+ |------|-----------|----------|
243
+ | *default* | `INFO` | Standard output showing progress |
244
+ | `--verbose` | `DEBUG` | Detailed output for troubleshooting |
245
+ | `--quiet` | `ERROR` | Minimal output, only errors |
246
+
247
+ ### Examples
248
+
249
+ **Standard Output (INFO level):**
250
+ ```bash
251
+ netscaler-certbot-hook --name example.com
252
+ ```
253
+ Shows all important operations and their status.
254
+
255
+ **Verbose Mode (DEBUG level):**
256
+ ```bash
257
+ netscaler-certbot-hook --name example.com --verbose
258
+ ```
259
+ Shows additional debugging information including:
260
+ - Connection details
261
+ - Configuration values
262
+ - Detailed operation steps
263
+
264
+ **Quiet Mode (ERROR level):**
265
+ ```bash
266
+ netscaler-certbot-hook --name example.com --quiet
267
+ ```
268
+ Only shows errors. Perfect for cron jobs where you only want to be notified of failures.
269
+
270
+ ### Logging for Cron Jobs
271
+
272
+ For automated cron jobs, use `--quiet` to suppress normal output:
273
+
274
+ ```bash
275
+ # Only log errors to file
276
+ 0 3 * * * netscaler-certbot-hook --name example.com --quiet 2>> /var/log/netscaler-cert-errors.log
277
+ ```
278
+
279
+ Or use standard output with log rotation:
280
+
281
+ ```bash
282
+ # Log all output with rotation
283
+ 0 3 * * * netscaler-certbot-hook --name example.com >> /var/log/netscaler-cert.log 2>&1
284
+ ```
285
+
286
+ ## Example Output
287
+
288
+ ### Initial Setup
289
+
290
+ When running for the first time:
291
+
292
+ ```
293
+ chain certificate letsencrypt not found
294
+ uploading chain certificate as letsencrypt-1581896753.crt
295
+ installing chain certificate with serial 13298795840390663119752826058995181320
296
+ certificate example.com not found
297
+ uploading certificate as example.com-1581896753.crt
298
+ uploading private key as example.com-1581896753.key
299
+ installing certificate with serial 409596789458967997345847308430335698529007
300
+ link certificate example.com to chain certificate letsencrypt
301
+ saving configuration
302
+ ```
303
+
304
+ ### Certificate Update
305
+
306
+ When certificate has been renewed:
307
+
308
+ ```
309
+ chain certificate letsencrypt found with serial 13298795840390663119752826058995181320
310
+ installed chain certificate matches our serial - nothing to do
311
+ certificate example.com found with serial 409596789458967997345847308430335698529007
312
+ uploading certificate as example.com-1581896812.crt
313
+ uploading private key as example.com-1581896812.key
314
+ update certificate example.com
315
+ link certificate example.com to chain certificate letsencrypt
316
+ certificate link was already present - nothing to do
317
+ saving configuration
318
+ ```
319
+
320
+ ### No Changes Needed
321
+
322
+ When certificate is already up-to-date:
323
+
324
+ ```
325
+ chain certificate letsencrypt found with serial 13298795840390663119752826058995181320
326
+ installed chain certificate matches our serial - nothing to do
327
+ certificate example.com found with serial 409596789458967997345847308430335698529007
328
+ installed certificate matches our serial - nothing to do
329
+ ```
330
+
331
+ ## Security Considerations
332
+
333
+ ### Chain Certificate Updates
334
+
335
+ For security reasons, the script does **not** automatically update chain certificates if the serial number differs. This prevents potential security issues from unexpected chain updates. Manual intervention is required if you need to update a chain certificate.
336
+
337
+ ### Credential Management
338
+
339
+ **Never commit credentials to version control!** Use environment variables or secure credential management:
340
+
341
+ ```bash
342
+ # Store in secure location
343
+ echo "export NS_PASSWORD='your-password'" > ~/.netscaler-credentials
344
+ chmod 600 ~/.netscaler-credentials
345
+
346
+ # Source when needed
347
+ source ~/.netscaler-credentials
348
+ ```
349
+
350
+ ### SSL Verification
351
+
352
+ Always enable SSL verification in production:
353
+
354
+ ```bash
355
+ export NS_VERIFY_SSL=true
356
+ ```
357
+
358
+ Only disable for testing or development environments.
359
+
360
+ ## Troubleshooting
361
+
362
+ ### Common Issues
363
+
364
+ #### "required environment variable NS_URL not set"
365
+
366
+ **Solution:** Set the required environment variable:
367
+ ```bash
368
+ export NS_URL=https://your-netscaler-ip
369
+ ```
370
+
371
+ #### "Certificate file not found"
372
+
373
+ **Solution:** Verify certificate path or let the script use default paths:
374
+ ```bash
375
+ ls /etc/letsencrypt/live/example.com/
376
+ ```
377
+
378
+ #### "Failed to connect to NetScaler"
379
+
380
+ **Possible causes:**
381
+ - NetScaler is not reachable (check network/firewall)
382
+ - Wrong IP address or URL
383
+ - SSL verification issues
384
+
385
+ **Solution:**
386
+ ```bash
387
+ # Test connectivity
388
+ ping your-netscaler-ip
389
+
390
+ # Temporary disable SSL verification for testing
391
+ export NS_VERIFY_SSL=false
392
+ ```
393
+
394
+ #### "HTTP error from NetScaler: 401"
395
+
396
+ **Solution:** Check credentials:
397
+ ```bash
398
+ export NS_LOGIN=correct-username
399
+ export NS_PASSWORD=correct-password
400
+ ```
401
+
402
+ #### "serial of installed chain certificate does not match"
403
+
404
+ **Solution:** Chain certificates cannot be auto-updated. Manually update or contact administrator.
405
+
406
+ ### Debug Mode
407
+
408
+ For detailed output, check the Python script directly or examine NetScaler logs.
409
+
410
+ ### Exit Codes
411
+
412
+ - `0` - Success (certificate installed, updated, or already current)
413
+ - `1` - Error (configuration, validation, or API error)
414
+
415
+ ## API Reference
416
+
417
+ The script uses the Citrix NetScaler NITRO API. For more information:
418
+ - [NetScaler NITRO API Documentation](https://docs.citrix.com/en-us/citrix-adc/current-release/nitro-api.html)
419
+
420
+ ## Development
421
+
422
+ ### Running Tests
423
+
424
+ Currently, the project focuses on production use. Unit tests are planned for future releases.
425
+
426
+ ### Contributing
427
+
428
+ Contributions are welcome! Please:
429
+ 1. Fork the repository
430
+ 2. Create a feature branch
431
+ 3. Make your changes
432
+ 4. Submit a pull request
433
+
434
+ ### Code Quality
435
+
436
+ The codebase follows:
437
+ - PEP 8 style guidelines
438
+ - Type hints throughout
439
+ - Comprehensive docstrings
440
+ - Professional error handling
441
+
442
+ ## License
443
+
444
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
445
+
446
+ ## Authors
447
+
448
+ - **Simon Lauger** - [@slauger](https://github.com/slauger)
449
+
450
+ ## Acknowledgments
451
+
452
+ - Citrix for the NetScaler NITRO API
453
+ - Let's Encrypt for free SSL certificates
454
+ - The Certbot team for excellent automation tools
455
+
456
+ ## Support
457
+
458
+ For issues, questions, or contributions, please use the [GitHub issue tracker](https://github.com/slauger/netscaler-certbot-hook/issues).
459
+
460
+ ---
461
+
462
+ **Made with ❤️ for automated certificate management**