Skip to content

Commit 578aafd

Browse files
authored
Merge branch 'alexy_ck_job_5' into alexy_ck_job_6
2 parents 577e204 + d3f1735 commit 578aafd

4 files changed

Lines changed: 24 additions & 93 deletions

File tree

roles/telemetry_chargeback/README.md

Lines changed: 23 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -36,32 +36,12 @@ These variables can be overridden when importing the role or set at the play lev
3636
| Variable | Default Value | Description |
3737
|----------|---------------|-------------|
3838
| `openstack_cmd` | `openstack` | The command used to execute OpenStack CLI calls. This can be customized if the binary is not in the standard PATH. |
39-
| `cloudkitty_debug` | `false` | Enable debug mode for the role. |
39+
| `cloudkitty_debug` | `false` | Enable debug mode for CloudKitty database dumps. |
4040
| `logs_dir_zuul` | `{{ ansible_env.HOME }}/ci-framework-data/logs` | Directory for log files. |
41-
| `artifacts_dir_zuul` | `{{ ansible_env.HOME }}/ci-framework-data/artifacts` | Directory for generated artifacts. |
42-
| `cert_dir` | `{{ ansible_user_dir }}/ck-certs` | Local directory for extracted ingest/query certs. |
43-
| `local_cert_dir` | `{{ ansible_env.HOME }}/ci-framework-data/flush_certs` | Local directory for flush certs (removed by cleanup_ck.yml after the run). |
44-
| `remote_cert_dir` | `osp-certs` | Directory inside the OpenStack pod for certs. |
45-
| `cert_secret_name` | `cert-cloudkitty-client-internal` | OpenShift secret name for client certificates. |
46-
| `client_secret` | `secret/cloudkitty-lokistack-gateway-client-http` | Secret for flush client certs. |
47-
| `ca_configmap` | `cm/cloudkitty-lokistack-ca-bundle` | ConfigMap for CA bundle. |
48-
| `logql_query` | `{service="cloudkitty"}` (overridable via `loki_query`) | LogQL query for Loki. |
49-
| `cloudkitty_namespace` | `openstack` | OpenShift namespace for Cloudkitty/Loki resources. |
50-
| `openstackpod` | `openstackclient` | OpenStack client pod name for exec/cp. |
51-
| `lookback` | `6` | Days lookback for Loki query time range. |
52-
| `limit` | `50` | Limit for Loki query results. |
53-
| `cloudkitty_test_scenarios` | `[]` | List of test scenario files to run (default: auto-discover all `test_*.yml` files). |
54-
55-
**Example: Overriding variables when importing the role**
56-
```yaml
57-
- name: "Run chargeback tests"
58-
ansible.builtin.import_role:
59-
name: telemetry_chargeback
60-
vars:
61-
cloudkitty_namespace: "my-custom-namespace"
62-
lookback: 10
63-
cloudkitty_debug: true
64-
```
41+
| `artifacts_dir_zuul` | `{{ ansible_env.HOME }}/ci-framework-data/artifacts` | Directory for generated artifacts and test output. |
42+
| `cert_dir` | `{{ ansible_user_dir }}/ck-certs` | Directory for CloudKitty client certificates. |
43+
| `local_cert_dir` | `{{ ansible_env.HOME }}/ci-framework-data/flush_certs` | Local directory for certificate extraction. |
44+
| `cloudkitty_namespace` | `openstack` | Kubernetes namespace where CloudKitty is deployed. |
6545

6646
How It Works
6747
------------
@@ -71,7 +51,7 @@ The role executes the following workflow:
7151
1. **CloudKitty Validation** - Enables the hashmap rating module and sets its priority to 100.
7252
2. **Loki Environment Setup** - Extracts Loki route information and certificates from the OpenShift cluster.
7353
3. **Admin Credentials** - Retrieves admin project ID and user ID for test data generation.
74-
4. **Scenario Discovery** - Finds all `test_*.yml` scenario files in the scenario directory (unless overridden by `cloudkitty_test_scenarios`).
54+
4. **Scenario Discovery** - Finds all `test_*.yml` scenario files in the scenario directory.
7555
5. **Scenario Loop** - For each scenario file found (exposed as `{{ scenario_name }}`):
7656
- Generates synthetic Loki log data based on the scenario configuration
7757
- Calculates expected chargeback metrics from the generated data
@@ -80,72 +60,33 @@ The role executes the following workflow:
8060

8161
The role uses `{{ scenario_name }}` as the loop variable when processing multiple test scenarios, making it easy to track which scenario is currently being executed.
8262

83-
### Synthetic Data Scripts
84-
85-
**gen_synth_loki_data.py** — Generates Loki-format JSON from a scenario YAML and template.
86-
87-
| Option | Description |
88-
|--------|--------------|
89-
| `--tmpl` | Path to the Jinja2 template (e.g. `loki_data_templ.j2`). |
90-
| `-t`, `--test` | Path to the scenario YAML (e.g. `test_dyn_basic.yml`). |
91-
| `-o`, `--output` | Path to the output JSON file. |
92-
| `-p`, `--project-id` | Optional; overrides `groupby.project_id` in every log entry. |
93-
| `-u`, `--user-id` | Optional; overrides `groupby.user_id` in every log entry. |
94-
| `--ascending` | Sort timestamps in ascending order (oldest first, newest last). |
95-
| `--descending` | Sort timestamps in descending order (newest first, oldest last) - **default**. |
96-
| `--debug` | Enable debug logging to stdout. |
97-
98-
By default, the script generates data in descending order (newest timestamps first), which is the expected format for Loki ingestion.
99-
100-
**gen_db_summary.py** — Parses Loki-style JSON (streams or `data.result`), sorts entries by timestamp, and writes a YAML summary. This script is invoked by the role for **both** synthetic totals (in `gen_synth_loki_data.yml`) and Loki-retrieved totals (in `retrieve_loki_data.yml`). It applies rate calculations with support for `factor`, `offset`, and `mutate` transformations.
101-
102-
| Option | Description |
103-
|--------|--------------|
104-
| `-j`, `--json` | Path to the input JSON file (required). |
105-
| `-o`, `--output` | Path to the output YAML file (default: `<input_stem>_total.yml`). |
106-
| `--debug` | Enable debug mode (writes `<stem>_diff.txt` with one `[ts,log]` JSON per line). |
107-
| `--debug_dir` | Directory for debug output files (default: same directory as `-o` output file). |
108-
109-
Output YAML structure:
110-
111-
* **time** — `begin_step` / `end_step`, each with `nanosec` (nanosecond timestamp), `begin`, `end` (ISO window strings from the log payload). The `nanosec` values are used for Loki query time range.
112-
* **data_summary** — `total_timesteps`, `metrics_per_step`, `log_count`, `total_rating`.
113-
* **by_type** — `rate` (flat list with `Begin`, `End`, `Qty`, `Rate`, `Type` for each metric type). Rate calculated as `Σ((qty_mutated * factor + offset) * price)` where `qty_mutated` is the quantity after applying the `mutate` transformation.
114-
115-
### Dynamically Set Variables
116-
117-
Set in **main.yml** from the OpenStack CLI (`openstack project show admin` / `openstack user show admin`):
118-
119-
| Variable | Description |
120-
|----------|-------------|
121-
| `cloudkitty_project_id` | ID of the OpenStack project named `admin` (empty string if not found). Passed as `-p` to the synthetic data generator when non-empty. |
122-
| `cloudkitty_user_id` | ID of the OpenStack user named `admin` (empty string if not found). Passed as `-u` to the synthetic data generator when non-empty. |
123-
124-
Set in **gen_synth_loki_data.yml** for each scenario file during the loop:
125-
126-
| Variable | Description |
127-
|----------|-------------|
128-
| `cloudkitty_data_file` | Local path for generated JSON data (`{{ artifacts_dir_zuul }}/{{ scenario_name }}-synth_data.json`) |
129-
| `cloudkitty_synth_totals_file` | Local path for calculated metric totals (`{{ artifacts_dir_zuul }}/{{ scenario_name }}-synth_metrics_summary.yml`) |
130-
| `cloudkitty_test_file` | Path to the scenario configuration file (`{{ role_path }}/files/{{ scenario_name }}.yml`) |
131-
13263
Scenario Configuration
13364
----------------------
134-
The synthetic data generation is controlled by YAML configuration files in the `files/` directory. Any file matching `test_*.yml` will be automatically discovered and processed. Files whose names start with an underscore (e.g. `_test_*.yml`) are **not** discovered by the role; they can be used as reference or for manual runs.
65+
The synthetic data generation is controlled by YAML configuration files in the `files/` directory. Any file matching the pattern `test_*.yml` will be automatically discovered and executed.
13566

13667
**Available scenarios:**
68+
- `test_static.yml` - Static test scenario with predefined values
13769
- `test_dyn_basic.yml` - Dynamic test scenario with variable values over time
13870

13971
Each scenario file defines:
14072

141-
* **generation** — Time range configuration (days, step_seconds).
142-
* **log_types** — List of log type definitions. Each entry has **type** (identifier and value in output), unit, description, qty, price, groupby, and metadata. The **groupby** dict typically includes dimension keys (e.g. resource, user, project); the generator merges **date_fields** into groupby at run time.
143-
* **required_fields** — Top-level keys required for each log type (e.g. type, unit, qty, price, groupby).
144-
* **date_fields** — Date field names to merge into groupby (week_of_the_year, day_of_the_year, month, year).
145-
* **loki_stream** — Loki stream configuration (service name).
146-
14773
**groupby.resource** should be consistent by metric type across scenario files so that the same type always uses the same resource identifier.
14874

75+
### Data Generation Script Options
76+
77+
The `gen_synth_loki_data.py` script supports the following options:
78+
79+
* `--tmpl` - Path to the Jinja2 template file (required)
80+
* `-t, --test` - Path to the scenario YAML file (required)
81+
* `-o, --output` - Path for the output JSON file (required)
82+
* `-p, --project-id` - Optional project ID to override the scenario file value
83+
* `-u, --user-id` - Optional user ID to override the scenario file value
84+
* `--ascending` - Sort timestamps in ascending order (oldest first, newest last)
85+
* `--descending` - Sort timestamps in descending order (newest first, oldest last) - **default**
86+
* `--debug` - Enable debug logging
87+
88+
By default, the script generates data in descending order (newest timestamps first), which is the expected format for Loki ingestion.
89+
14990
Dependencies
15091
------------
15192
This role has no direct hard dependencies on other Ansible roles.

roles/telemetry_chargeback/defaults/main.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,3 @@ openstackpod: "openstackclient"
2828
# Time window settings
2929
lookback: 6
3030
limit: 50
31-
32-
# List of test scenario files to run
33-
cloudkitty_test_scenarios: []

roles/telemetry_chargeback/files/gen_db_summary.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -350,13 +350,6 @@ def main() -> None:
350350
doc = build_summary(pairs)
351351
write_yaml(out_path, doc)
352352

353-
if doc["data_summary"]["metrics_per_step"] == "ERROR":
354-
per_ts = Counter(ts for ts, _ in pairs)
355-
exp = next(iter(per_ts.values()), 0)
356-
for ts in sorted(per_ts, key=int):
357-
if per_ts[ts] != exp:
358-
print(ts, per_ts[ts], file=sys.stdout)
359-
360353

361354
if __name__ == "__main__":
362355
main()

roles/telemetry_chargeback/tasks/gen_synth_loki_data.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
python3 "{{ cloudkitty_summary_script }}"
2828
-j "{{ cloudkitty_data_file }}"
2929
-o "{{ cloudkitty_synth_totals_file }}"
30-
{% if cloudkitty_debug | bool %}--debug --debug_dir "{{ cloudkitty_debug_dir }}"{% endif %}
30+
--debug "{{ cloudkitty_debug_dir }}"
3131
register: synth_rating_info
3232
when: not file_preexists.stat.exists | bool
3333
changed_when: synth_rating_info.rc == 0

0 commit comments

Comments
 (0)