@@ -38,12 +38,13 @@ A complete special agent plugin consists of four parts:
3838
3939```
4040~/local/lib/python3/cmk_addons/plugins/my_plugin/
41+ ├── __init__.py # Package marker
4142├── libexec/
4243│ └── agent_my_plugin # 1. Executable data collector
4344├── server_side_calls/
44- │ └── special_agent .py # 2. Command builder
45+ │ └── my_plugin .py # 2. Command builder
4546├── rulesets/
46- │ └── special_agent .py # 3. GUI configuration
47+ │ └── my_plugin .py # 3. GUI configuration
4748└── agent_based/
4849 └── my_plugin.py # 4. Check plugin (data processor)
4950```
@@ -114,20 +115,27 @@ if __name__ == "__main__":
114115 chmod 755 agent_my_plugin
115116 ```
116117
117- 2 . ** Password Handling** : Always call ` replace_passwords() ` first
118+ 2 . ** Entry Point** : Must include ` if __name__ == "__main__": ` block
119+ ``` python
120+ if __name__ == " __main__" :
121+ sys.exit(main())
122+ ```
123+ ** Without this, the script will not execute when called from the command line!**
124+
125+ 3 . ** Password Handling** : Always call ` replace_passwords() ` first
118126 ``` python
119127 from cmk.utils.password_store import replace_passwords
120128 replace_passwords() # Must be FIRST thing in main()
121129 ```
122130
123- 3 . ** Output Format** : Standard CheckMK agent output
131+ 4 . ** Output Format** : Standard CheckMK agent output
124132 ``` python
125133 print (" <<<section_name>>>" )
126134 print (" key1 value1" )
127135 print (" key2 value2" )
128136 ```
129137
130- 4 . ** Error Handling** : Write errors to stderr, return non-zero on failure
138+ 5 . ** Error Handling** : Write errors to stderr, return non-zero on failure
131139
132140### JSON Output Pattern
133141
@@ -164,20 +172,21 @@ Converts GUI ruleset parameters into command-line arguments for the special agen
164172### Basic Implementation
165173
166174``` python
167- # File: ~/local/lib/python3/cmk_addons/plugins/my_plugin/server_side_calls/special_agent .py
175+ # File: ~/local/lib/python3/cmk_addons/plugins/my_plugin/server_side_calls/my_plugin .py
168176
169177from collections.abc import Iterator
170178from pydantic import BaseModel
171179from cmk.server_side_calls.v1 import (
172180 HostConfig,
181+ Secret,
173182 SpecialAgentCommand,
174183 SpecialAgentConfig,
175184)
176185
177186class Params (BaseModel ):
178187 """ Type-safe parameter model"""
179188 username: str
180- password: tuple[ str , str ] # ("password", "stored_password_id") or ("store", "id")
189+ password: Secret
181190 port: int | None = None
182191 protocol: str = " https"
183192
@@ -188,9 +197,9 @@ def commands_function(
188197 """ Build command-line arguments"""
189198
190199 # Build argument list
191- args: list[ str | tuple[ str , str , str ]] = [
200+ args = [
192201 " -u" , params.username,
193- " -p" , params.password, # Tuple for password store
202+ " -p" , params.password.unsafe() , # Extract password from Secret
194203 ]
195204
196205 # Optional parameters
@@ -257,7 +266,7 @@ host_config.macros # Custom macros
257266### Basic Ruleset
258267
259268``` python
260- # File: ~/local/lib/python3/cmk_addons/plugins/my_plugin/rulesets/special_agent .py
269+ # File: ~/local/lib/python3/cmk_addons/plugins/my_plugin/rulesets/my_plugin .py
261270
262271from cmk.rulesets.v1 import Title, Help, Label
263272from cmk.rulesets.v1.form_specs import (
@@ -518,19 +527,20 @@ if __name__ == "__main__":
518527 sys.exit(main())
519528```
520529
521- ### 2. Server-Side Calls (server_side_calls/special_agent .py)
530+ ### 2. Server-Side Calls (server_side_calls/my_plugin .py)
522531
523532``` python
524533from collections.abc import Iterator
525534from pydantic import BaseModel
526535from cmk.server_side_calls.v1 import (
527536 HostConfig,
537+ Secret,
528538 SpecialAgentCommand,
529539 SpecialAgentConfig,
530540)
531541
532542class Params (BaseModel ):
533- api_key: tuple[ str , str ]
543+ api_key: Secret
534544 location: str
535545 units: str = " metric"
536546
@@ -539,7 +549,7 @@ def commands_function(
539549 host_config : HostConfig,
540550) -> Iterator[SpecialAgentCommand]:
541551 yield SpecialAgentCommand(command_arguments = [
542- " -k" , params.api_key,
552+ " -k" , params.api_key.unsafe() ,
543553 " -l" , params.location,
544554 " --units" , params.units,
545555 host_config.primary_ip_config.address or " api.weather.com" ,
@@ -554,7 +564,7 @@ special_agent_acme_weather = SpecialAgentConfig(
554564)
555565```
556566
557- ### 3. Ruleset (rulesets/special_agent .py)
567+ ### 3. Ruleset (rulesets/my_plugin .py)
558568
559569``` python
560570from cmk.rulesets.v1 import Title, Help
@@ -818,18 +828,20 @@ local/share/check_mk/web/plugins/wato/my_plugin.py # GUI
818828### New Structure (CheckMK 2.3+)
819829```
820830local/lib/python3/cmk_addons/plugins/my_plugin/
831+ ├── __init__.py
821832├── libexec/agent_my_plugin
822- ├── server_side_calls/special_agent .py
823- ├── rulesets/special_agent .py
833+ ├── server_side_calls/my_plugin .py
834+ ├── rulesets/my_plugin .py
824835└── agent_based/my_plugin.py
825836```
826837
827838### Migration Steps
828- 1 . Move agent to ` libexec/agent_<name> `
829- 2 . Create ` server_side_calls/special_agent.py ` from old ` special_agent_info `
830- 3 . Convert WATO ruleset to ` rulesets/special_agent.py `
831- 4 . Update check plugin imports (v1 → v2)
832- 5 . Test thoroughly
839+ 1 . Create ` __init__.py ` package marker
840+ 2 . Move agent to ` libexec/agent_<name> `
841+ 3 . Create ` server_side_calls/<name>.py ` from old ` special_agent_info `
842+ 4 . Convert WATO ruleset to ` rulesets/<name>.py `
843+ 5 . Update check plugin imports (v1 → v2)
844+ 6 . Test thoroughly
833845
834846---
835847
0 commit comments