You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
"description": "Configuration for creating a deployment environment\n\nThis is the top-level configuration object that contains all information\nneeded to create a new deployment environment. It deserializes from JSON\nconfiguration and provides type-safe conversion to domain parameters.\n\n# Examples\n\n```rust\nuse torrust_tracker_deployer_lib::application::command_handlers::create::config::{\n EnvironmentCreationConfig, EnvironmentSection, ProviderSection, LxdProviderSection\n};\n\nlet json = r#\"{\n \"environment\": {\n \"name\": \"dev\"\n },\n \"ssh_credentials\": {\n \"private_key_path\": \"fixtures/testing_rsa\",\n \"public_key_path\": \"fixtures/testing_rsa.pub\"\n },\n \"provider\": {\n \"provider\": \"lxd\",\n \"profile_name\": \"torrust-profile-dev\"\n },\n \"tracker\": {\n \"core\": {\n \"database\": {\n \"driver\": \"sqlite3\",\n \"database_name\": \"tracker.db\"\n },\n \"private\": false\n },\n \"udp_trackers\": [\n {\n \"bind_address\": \"0.0.0.0:6969\"\n }\n ],\n \"http_trackers\": [\n {\n \"bind_address\": \"0.0.0.0:7070\"\n }\n ],\n \"http_api\": {\n \"bind_address\": \"0.0.0.0:1212\",\n \"admin_token\": \"MyAccessToken\"\n }\n }\n}\"#;\n\nlet config: EnvironmentCreationConfig = serde_json::from_str(json)?;\n# Ok::<(), Box<dyn std::error::Error>>(())\n```",
4
+
"description": "Configuration for creating a deployment environment\n\nThis is the top-level configuration object that contains all information\nneeded to create a new deployment environment. It deserializes from JSON\nconfiguration and provides type-safe conversion to domain parameters.\n\n# Examples\n\n```rust\nuse torrust_tracker_deployer_lib::application::command_handlers::create::config::{\n EnvironmentCreationConfig, EnvironmentSection, ProviderSection, LxdProviderSection\n};\n\nlet json = r#\"{\n \"environment\": {\n \"name\": \"dev\"\n },\n \"ssh_credentials\": {\n \"private_key_path\": \"fixtures/testing_rsa\",\n \"public_key_path\": \"fixtures/testing_rsa.pub\"\n },\n \"provider\": {\n \"provider\": \"lxd\",\n \"profile_name\": \"torrust-profile-dev\"\n },\n \"tracker\": {\n \"core\": {\n \"database\": {\n \"driver\": \"sqlite3\",\n \"database_name\": \"tracker.db\"\n },\n \"private\": false\n },\n \"udp_trackers\": [\n {\n \"bind_address\": \"0.0.0.0:6969\"\n }\n ],\n \"http_trackers\": [\n {\n \"bind_address\": \"0.0.0.0:7070\"\n }\n ],\n \"http_api\": {\n \"bind_address\": \"0.0.0.0:1212\",\n \"admin_token\": \"MyAccessToken\"\n }\n },\n \"prometheus\": {\n \"scrape_interval_in_secs\": 15\n },\n \"grafana\": {\n \"admin_user\": \"admin\",\n \"admin_password\": \"admin\"\n }\n}\"#;\n\nlet config: EnvironmentCreationConfig = serde_json::from_str(json)?;\n# Ok::<(), Box<dyn std::error::Error>>(())\n```",
5
5
"type": "object",
6
6
"properties": {
7
7
"environment": {
8
8
"description": "Environment-specific settings",
9
9
"$ref": "#/$defs/EnvironmentSection"
10
10
},
11
+
"grafana": {
12
+
"description": "Grafana dashboard configuration (optional)\n\nWhen present, Grafana will be deployed for visualization.\n**Requires Prometheus to be configured** - Grafana depends on\nPrometheus as its data source.\n\nUses `GrafanaSection` for JSON parsing with String primitives.\nConverted to domain `GrafanaConfig` via `to_environment_params()`.",
13
+
"anyOf": [
14
+
{
15
+
"$ref": "#/$defs/GrafanaSection"
16
+
},
17
+
{
18
+
"type": "null"
19
+
}
20
+
],
21
+
"default": null
22
+
},
23
+
"prometheus": {
24
+
"description": "Prometheus monitoring configuration (optional)\n\nWhen present, Prometheus will be deployed to monitor the tracker.\nUses `PrometheusSection` for JSON parsing with String primitives.\nConverted to domain `PrometheusConfig` via `to_environment_params()`.",
25
+
"anyOf": [
26
+
{
27
+
"$ref": "#/$defs/PrometheusSection"
28
+
},
29
+
{
30
+
"type": "null"
31
+
}
32
+
],
33
+
"default": null
34
+
},
11
35
"provider": {
12
36
"description": "Provider-specific configuration (LXD, Hetzner, etc.)\n\nUses `ProviderSection` for JSON parsing with raw primitives.\nConverted to domain `ProviderConfig` via `to_environment_params()`.",
13
37
"$ref": "#/$defs/ProviderSection"
@@ -113,6 +137,24 @@
113
137
"name"
114
138
]
115
139
},
140
+
"GrafanaSection": {
141
+
"description": "Grafana configuration section (DTO)\n\nThis is a DTO that deserializes from JSON strings and validates\nwhen converting to the domain `GrafanaConfig`.\n\n# Security\n\nThe `admin_password` field uses `PlainPassword` type alias for string at\nDTO boundaries. It will be converted to `Password` (secrecy-wrapped) in\nthe domain layer.\n\n# Examples\n\n```json\n{\n\"admin_user\": \"admin\",\n\"admin_password\": \"admin\"\n}\n```",
142
+
"type": "object",
143
+
"properties": {
144
+
"admin_password": {
145
+
"description": "Grafana admin password (plain string at DTO boundary)\n\nThis will be converted to `Password` type in the domain layer\nto prevent accidental exposure in logs or debug output.",
146
+
"type": "string"
147
+
},
148
+
"admin_user": {
149
+
"description": "Grafana admin username",
150
+
"type": "string"
151
+
}
152
+
},
153
+
"required": [
154
+
"admin_user",
155
+
"admin_password"
156
+
]
157
+
},
116
158
"HetznerProviderSection": {
117
159
"description": "Hetzner-specific configuration section\n\nUses raw `String` fields for JSON deserialization. Convert to domain\n`HetznerConfig` via `ProviderSection::to_provider_config()`.\n\n# Examples\n\n```rust\nuse torrust_tracker_deployer_lib::application::command_handlers::create::config::HetznerProviderSection;\n\nlet section = HetznerProviderSection {\n api_token: \"your-api-token\".to_string(),\n server_type: \"cx22\".to_string(),\n location: \"nbg1\".to_string(),\n image: \"ubuntu-24.04\".to_string(),\n};\n```",
118
160
"type": "object",
@@ -180,6 +222,21 @@
180
222
"profile_name"
181
223
]
182
224
},
225
+
"PrometheusSection": {
226
+
"description": "Prometheus configuration section (DTO)\n\nThis is a simple DTO that deserializes from JSON numbers and validates\nwhen converting to the domain `PrometheusConfig`.\n\n# Examples\n\n```json\n{\n\"scrape_interval_in_secs\": 15\n}\n```",
227
+
"type": "object",
228
+
"properties": {
229
+
"scrape_interval_in_secs": {
230
+
"description": "Interval for Prometheus to scrape metrics from targets (in seconds)\n\nMust be greater than 0. The Prometheus template adds the 's' suffix.\nExamples: 15 (15 seconds), 30 (30 seconds), 60 (1 minute)",
231
+
"type": "integer",
232
+
"format": "uint32",
233
+
"minimum": 0
234
+
}
235
+
},
236
+
"required": [
237
+
"scrape_interval_in_secs"
238
+
]
239
+
},
183
240
"ProviderSection": {
184
241
"description": "Provider-specific configuration section\n\nEach variant contains the configuration fields specific to that provider\nusing **raw primitives** (`String`) for JSON deserialization.\n\nThis is a tagged enum that deserializes based on the `\"provider\"` field in JSON.\n\n# Conversion\n\nUse `to_provider_config()` to validate and convert to domain types.\n\n# Examples\n\n```rust\nuse torrust_tracker_deployer_lib::application::command_handlers::create::config::{\n ProviderSection, LxdProviderSection\n};\n\nlet section = ProviderSection::Lxd(LxdProviderSection {\n profile_name: \"torrust-profile-dev\".to_string(),\n});\n\nlet config = section.to_provider_config().unwrap();\nassert_eq!(config.provider_name(), \"lxd\");\n```",
"description": "Configuration for creating a deployment environment\n\nThis is the top-level configuration object that contains all information\nneeded to create a new deployment environment. It deserializes from JSON\nconfiguration and provides type-safe conversion to domain parameters.\n\n# Examples\n\n```rust\nuse torrust_tracker_deployer_lib::application::command_handlers::create::config::{\n EnvironmentCreationConfig, EnvironmentSection, ProviderSection, LxdProviderSection\n};\n\nlet json = r#\"{\n \"environment\": {\n \"name\": \"dev\"\n },\n \"ssh_credentials\": {\n \"private_key_path\": \"fixtures/testing_rsa\",\n \"public_key_path\": \"fixtures/testing_rsa.pub\"\n },\n \"provider\": {\n \"provider\": \"lxd\",\n \"profile_name\": \"torrust-profile-dev\"\n },\n \"tracker\": {\n \"core\": {\n \"database\": {\n \"driver\": \"sqlite3\",\n \"database_name\": \"tracker.db\"\n },\n \"private\": false\n },\n \"udp_trackers\": [\n {\n \"bind_address\": \"0.0.0.0:6969\"\n }\n ],\n \"http_trackers\": [\n {\n \"bind_address\": \"0.0.0.0:7070\"\n }\n ],\n \"http_api\": {\n \"bind_address\": \"0.0.0.0:1212\",\n \"admin_token\": \"MyAccessToken\"\n }\n }\n}\"#;\n\nlet config: EnvironmentCreationConfig = serde_json::from_str(json)?;\n# Ok::<(), Box<dyn std::error::Error>>(())\n```",
4
+
"description": "Configuration for creating a deployment environment\n\nThis is the top-level configuration object that contains all information\nneeded to create a new deployment environment. It deserializes from JSON\nconfiguration and provides type-safe conversion to domain parameters.\n\n# Examples\n\n```rust\nuse torrust_tracker_deployer_lib::application::command_handlers::create::config::{\n EnvironmentCreationConfig, EnvironmentSection, ProviderSection, LxdProviderSection\n};\n\nlet json = r#\"{\n \"environment\": {\n \"name\": \"dev\"\n },\n \"ssh_credentials\": {\n \"private_key_path\": \"fixtures/testing_rsa\",\n \"public_key_path\": \"fixtures/testing_rsa.pub\"\n },\n \"provider\": {\n \"provider\": \"lxd\",\n \"profile_name\": \"torrust-profile-dev\"\n },\n \"tracker\": {\n \"core\": {\n \"database\": {\n \"driver\": \"sqlite3\",\n \"database_name\": \"tracker.db\"\n },\n \"private\": false\n },\n \"udp_trackers\": [\n {\n \"bind_address\": \"0.0.0.0:6969\"\n }\n ],\n \"http_trackers\": [\n {\n \"bind_address\": \"0.0.0.0:7070\"\n }\n ],\n \"http_api\": {\n \"bind_address\": \"0.0.0.0:1212\",\n \"admin_token\": \"MyAccessToken\"\n }\n },\n \"prometheus\": {\n \"scrape_interval_in_secs\": 15\n },\n \"grafana\": {\n \"admin_user\": \"admin\",\n \"admin_password\": \"admin\"\n }\n}\"#;\n\nlet config: EnvironmentCreationConfig = serde_json::from_str(json)?;\n# Ok::<(), Box<dyn std::error::Error>>(())\n```",
5
5
"type": "object",
6
6
"properties": {
7
7
"environment": {
8
8
"description": "Environment-specific settings",
9
9
"$ref": "#/$defs/EnvironmentSection"
10
10
},
11
+
"grafana": {
12
+
"description": "Grafana dashboard configuration (optional)\n\nWhen present, Grafana will be deployed for visualization.\n**Requires Prometheus to be configured** - Grafana depends on\nPrometheus as its data source.\n\nUses `GrafanaSection` for JSON parsing with String primitives.\nConverted to domain `GrafanaConfig` via `to_environment_params()`.",
13
+
"anyOf": [
14
+
{
15
+
"$ref": "#/$defs/GrafanaSection"
16
+
},
17
+
{
18
+
"type": "null"
19
+
}
20
+
],
21
+
"default": null
22
+
},
23
+
"prometheus": {
24
+
"description": "Prometheus monitoring configuration (optional)\n\nWhen present, Prometheus will be deployed to monitor the tracker.\nUses `PrometheusSection` for JSON parsing with String primitives.\nConverted to domain `PrometheusConfig` via `to_environment_params()`.",
25
+
"anyOf": [
26
+
{
27
+
"$ref": "#/$defs/PrometheusSection"
28
+
},
29
+
{
30
+
"type": "null"
31
+
}
32
+
],
33
+
"default": null
34
+
},
11
35
"provider": {
12
36
"description": "Provider-specific configuration (LXD, Hetzner, etc.)\n\nUses `ProviderSection` for JSON parsing with raw primitives.\nConverted to domain `ProviderConfig` via `to_environment_params()`.",
13
37
"$ref": "#/$defs/ProviderSection"
@@ -66,7 +90,7 @@
66
90
"type": "string"
67
91
},
68
92
"password": {
69
-
"description": "Database password",
93
+
"description": "Database password (plain text during DTO serialization/deserialization)\n\nUses `PlainPassword` type alias to explicitly mark this as a temporarily visible secret.\nConverted to secure `Password` type in `to_database_config()` at the DTO-to-domain boundary.",
70
94
"type": "string"
71
95
},
72
96
"port": {
@@ -113,12 +137,30 @@
113
137
"name"
114
138
]
115
139
},
140
+
"GrafanaSection": {
141
+
"description": "Grafana configuration section (DTO)\n\nThis is a DTO that deserializes from JSON strings and validates\nwhen converting to the domain `GrafanaConfig`.\n\n# Security\n\nThe `admin_password` field uses `PlainPassword` type alias for string at\nDTO boundaries. It will be converted to `Password` (secrecy-wrapped) in\nthe domain layer.\n\n# Examples\n\n```json\n{\n\"admin_user\": \"admin\",\n\"admin_password\": \"admin\"\n}\n```",
142
+
"type": "object",
143
+
"properties": {
144
+
"admin_password": {
145
+
"description": "Grafana admin password (plain string at DTO boundary)\n\nThis will be converted to `Password` type in the domain layer\nto prevent accidental exposure in logs or debug output.",
146
+
"type": "string"
147
+
},
148
+
"admin_user": {
149
+
"description": "Grafana admin username",
150
+
"type": "string"
151
+
}
152
+
},
153
+
"required": [
154
+
"admin_user",
155
+
"admin_password"
156
+
]
157
+
},
116
158
"HetznerProviderSection": {
117
159
"description": "Hetzner-specific configuration section\n\nUses raw `String` fields for JSON deserialization. Convert to domain\n`HetznerConfig` via `ProviderSection::to_provider_config()`.\n\n# Examples\n\n```rust\nuse torrust_tracker_deployer_lib::application::command_handlers::create::config::HetznerProviderSection;\n\nlet section = HetznerProviderSection {\n api_token: \"your-api-token\".to_string(),\n server_type: \"cx22\".to_string(),\n location: \"nbg1\".to_string(),\n image: \"ubuntu-24.04\".to_string(),\n};\n```",
118
160
"type": "object",
119
161
"properties": {
120
162
"api_token": {
121
-
"description": "Hetzner API token (raw string).",
163
+
"description": "Hetzner API token in plain text format (DTO layer).\n\nThis uses [`PlainApiToken`] to mark it as a transparent secret during\ndeserialization. Convert to domain `ApiToken` at the DTO-to-domain boundary.",
122
164
"type": "string"
123
165
},
124
166
"image": {
@@ -180,6 +222,20 @@
180
222
"profile_name"
181
223
]
182
224
},
225
+
"PrometheusSection": {
226
+
"description": "Prometheus configuration section (DTO)\n\nThis is a simple DTO that deserializes from JSON integers and validates\nwhen converting to the domain `PrometheusConfig`.\n\n# Examples\n\n```json\n{\n\"scrape_interval_in_secs\": 15\n}\n```",
227
+
"type": "object",
228
+
"properties": {
229
+
"scrape_interval_in_secs": {
230
+
"description": "Interval in seconds for Prometheus to scrape metrics from targets\n\nMust be greater than 0.\nThe template automatically appends 's' suffix to create formats like '15s'.\nExamples: 15 (becomes \"15s\"), 30 (becomes \"30s\"), 60 (becomes \"60s\")",
231
+
"type": "integer",
232
+
"minimum": 1
233
+
}
234
+
},
235
+
"required": [
236
+
"scrape_interval_in_secs"
237
+
]
238
+
},
183
239
"ProviderSection": {
184
240
"description": "Provider-specific configuration section\n\nEach variant contains the configuration fields specific to that provider\nusing **raw primitives** (`String`) for JSON deserialization.\n\nThis is a tagged enum that deserializes based on the `\"provider\"` field in JSON.\n\n# Conversion\n\nUse `to_provider_config()` to validate and convert to domain types.\n\n# Examples\n\n```rust\nuse torrust_tracker_deployer_lib::application::command_handlers::create::config::{\n ProviderSection, LxdProviderSection\n};\n\nlet section = ProviderSection::Lxd(LxdProviderSection {\n profile_name: \"torrust-profile-dev\".to_string(),\n});\n\nlet config = section.to_provider_config().unwrap();\nassert_eq!(config.provider_name(), \"lxd\");\n```",
0 commit comments