blob: 9360062df20eb214c44d286ff6e3d1160027877b [file] [view]
# Configuration Parsing Library
This directory contains a shared configuration parsing and marshalling framework
used by various ATS components including `traffic_server` and `traffic_ctl`.
## Architecture Overview
Each configuration file type (ssl_multicert, etc.) follows the same pattern:
```
include/config/<config_name>.h - Header with data types, parser, marshaller
src/config/<config_name>.cc - Implementation
```
### Components
For each configuration type, there are three main components:
1. **Entry struct** - A POD (plain old data) type representing a single
configuration entry (e.g., `SSLMultiCertEntry`).
2. **Parser class** - Reads configuration files and returns parsed entries.
Supports both YAML and legacy formats with automatic format detection.
3. **Marshaller class** - Serializes configuration to YAML or JSON format.
### Example: ssl_multicert
```
include/config/ssl_multicert.h
├── SSLMultiCertEntry - Single certificate entry
├── SSLMultiCertConfig - Vector of entries (type alias)
├── ConfigResult<T> - Parse result with error handling
├── SSLMultiCertParser - Parser for .yaml and .config formats
└── SSLMultiCertMarshaller - Serializer to YAML/JSON
```
## Usage
### Parsing a Configuration File
```cpp
#include "config/ssl_multicert.h"
config::SSLMultiCertParser parser;
auto result = parser.parse("/path/to/ssl_multicert.yaml");
if (!result.ok()) {
// Handle error - result.errata contains error details
return;
}
for (const auto& entry : result.value) {
// Use entry.ssl_cert_name, entry.dest_ip, etc.
}
```
### Marshalling to YAML/JSON
```cpp
config::SSLMultiCertMarshaller marshaller;
std::string yaml = marshaller.to_yaml(result.value);
std::string json = marshaller.to_json(result.value);
```
## Format Detection
The parser automatically detects the configuration format:
1. **By file extension**: `.yaml`/`.yml` → YAML, `.config` → Legacy
2. **By content inspection**: Looks for `ssl_multicert:` (YAML) vs `key=value` (Legacy)
## Adding a New Configuration Type
To add support for a new configuration (maybe, `logging.yaml`):
1. Create `include/config/logging.h`:
- Define `LoggingEntry` struct with fields matching the config
- Define `LoggingConfig = std::vector<LoggingEntry>`
- Declare `LoggingParser` and `LoggingMarshaller` classes
2. Create `src/config/logging.cc`:
- Implement YAML parsing using yaml-cpp
- Implement legacy format parsing if applicable
- Implement YAML and JSON marshalling
3. Update `src/config/CMakeLists.txt`:
- Add `logging.cc` to the library sources
- Add header to `CONFIG_PUBLIC_HEADERS`
4. Integrate with consumers (traffic_ctl, traffic_server, etc.)
## Error Handling
All parsers return `ConfigResult<T>` which contains:
- `value` - The parsed configuration (valid even on partial failure)
- `errata` - Error/warning information using `swoc::Errata`
- `ok()` - Returns true if no errors occurred
```cpp
if (!result.ok()) {
if (!result.errata.empty()) {
std::cerr << result.errata.front().text() << std::endl;
}
}
```
## Dependencies
- **yaml-cpp** - YAML parsing
- **libswoc** - Error handling (`swoc::Errata`)
## Running Unit Tests
Build with testing enabled and run:
```bash
cmake -B build -DBUILD_TESTING=ON ...
cmake --build build --target test_tsconfig
ctest --test-dir build -R test_tsconfig
```