[epa-orchestrator] epa-orchestrator charm for installing epa-orchestrator snap

The epa-orchestrator charm is an operator designed to configure and install epa-orchestrator snap.

Change-Id: Ib74ec522a67f8f06996d8ff4fdd1c87ae9311de3
Signed-off-by: Ahmad Hassan <ahmad.hassan@canonical.com>
This commit is contained in:
Ahmad Hassan
2025-06-24 16:02:58 +05:00
parent 0d41be650d
commit b9e31079a2
23 changed files with 1128 additions and 87 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
.cursor
venv/
build/
.idea/

View File

@@ -0,0 +1,6 @@
external-libraries:
- charms.operator_libs_linux.v2.snap
- charms.tempo_k8s.v2.tracing
- charms.tempo_k8s.v1.charm_tracing
internal-libraries: []
templates: []

View File

@@ -0,0 +1,35 @@
# Contributing
To make contributions to this charm, you'll need a working [development setup](https://juju.is/docs/sdk/dev-setup).
You can create an environment for development with `tox`:
```shell
virtualenv venv
source venv/bin/activate
```
## Testing
This project uses `tox` for managing test environments. There are some pre-configured environments
that can be used for linting and formatting code when you're preparing contributions to the charm:
```shell
tox run -e fmt
tox run -e linters
tox run -e pep8
tox -e py3 -- epa-orchestrator
```
## Smoke testing
```shell
tox -e func -- --smoke --test-directory=/root/sunbeam-charms/tests/machine/
```
## Build the charm
Build the charm in this git repository using:
```shell
tox -e build -- epa-orchestrator
```

View File

@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2025 ahmad
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,13 @@
# epa-orchestrator
## Description
The epa-orchestrator charm is an operator designed to manage the EPA (Enhanced Platform Awareness) orchestrator service as part of an OpenStack deployment. This charm installs and configures the epa-orchestrator snap, which provides enhanced platform awareness capabilities for OpenStack cloud.
### Testing
Run the unit tests:
```bash
tox -e py3 -- epa-orchestrator
```

View File

@@ -0,0 +1,15 @@
# Copyright 2025 Canonical Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Unit tests for charm."""

View File

@@ -0,0 +1,46 @@
type: charm
name: epa-orchestrator
title: Epa Orchestrator
summary: Deploy the epa-orchestrator snap.
description: |
Configures the epa-orchestrator snap as a part of the openstack deployment.
assumes:
- juju >= 3.1
base: ubuntu@24.04
platforms:
amd64:
config:
options:
snap-name:
default: epa-orchestrator
type: string
description: The name of the snap to install.
snap-channel:
default: latest/edge
type: string
description: The channel of the snap to install.
requires:
tracing:
interface: tracing
optional: true
limit: 1
parts:
charm:
build-packages:
- git
- libffi-dev
- libssl-dev
- rustc-1.80
- cargo-1.80
- pkg-config
charm-binary-python-packages:
- cryptography
- jsonschema
- pydantic
- jinja2
build-snaps: [astral-uv]
override-build: |
uv export --frozen --no-hashes --format=requirements-txt -o requirements.txt
craftctl default
charm-requirements: [requirements.txt]

View File

@@ -0,0 +1,17 @@
# Copyright 2025 Canonical Ltd.
# See LICENSE file for licensing details.
[project]
name = "epa-orchestrator"
version = "2025.1"
requires-python = "~=3.12.0"
dependencies = [
"cryptography",
"jinja2",
"jsonschema",
"pydantic",
"ops",
"tenacity", # From ops_sunbeam
"opentelemetry-api~=1.21.0", # charm_tracing library -> opentelemetry-sdk requires 1.21.0
]

View File

@@ -0,0 +1,3 @@
# This file is used to trigger a build.
# Change uuid to trigger a new build.
29a571a6-411d-49f0-80fb-07fa8c4f7e49

View File

@@ -0,0 +1,64 @@
#!/usr/bin/env python3
# Copyright 2023 Canonical Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""EPA Orchestrator Charm operator.
This charm is used to install the epa-orchestrator snap as a part of the openstack deployment.
"""
import logging
import charms.operator_libs_linux.v2.snap as snap
import ops
import ops_sunbeam.charm as sunbeam_charm
import ops_sunbeam.tracing as sunbeam_tracing
logger = logging.getLogger(__name__)
@sunbeam_tracing.trace_sunbeam_charm(extra_types=(snap.SnapCache, snap.Snap))
class EpaOrchestratorCharm(sunbeam_charm.OSBaseOperatorCharmSnap):
"""Charm the service."""
service_name = "epa-orchestrator"
@property
def snap_name(self) -> str:
"""Returns the snap name."""
return str(self.model.config["snap-name"])
@property
def snap_channel(self) -> str:
"""Returns the snap channel."""
return str(self.model.config["snap-channel"])
def ensure_services_running(self) -> None:
"""Override to prevent service start - this snap has no services."""
logger.debug(
"Skipping service start - %s snap has no services", self.snap_name
)
pass
def stop_services(self) -> None:
"""Override to prevent service stop - this snap has no services."""
logger.debug(
"Skipping service stop - %s snap has no services", self.snap_name
)
pass
if __name__ == "__main__": # pragma: nocover
ops.main(EpaOrchestratorCharm)

View File

@@ -0,0 +1,15 @@
# Copyright 2025 Canonical Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Unit tests for charm."""

View File

@@ -0,0 +1,88 @@
# Copyright 2023 Canonical Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests for EPA Orchestrator charm."""
import charm
import ops_sunbeam.test_utils as test_utils
class _EpaOrchestratorCharm(charm.EpaOrchestratorCharm):
"""EPA Orchestrator test charm."""
def __init__(self, framework):
super().__init__(framework)
class TestEpaOrchestratorCharm(test_utils.CharmTestCase):
"""Test charm to test EPA Orchestrator charm."""
PATCHES = []
def setUp(self):
"""Setup EPA Orchestrator tests."""
super().setUp(charm, self.PATCHES)
self.harness = test_utils.get_harness(
_EpaOrchestratorCharm,
container_calls=self.container_calls,
)
self.addCleanup(self.harness.cleanup)
def initial_setup(self):
"""Setting up configuration."""
self.harness.update_config(
{"snap-name": "epa-orchestrator", "snap-channel": "latest/edge"}
)
self.harness.begin_with_initial_hooks()
def test_snap_name_property_default(self):
"""Test snap_name property returns default value."""
self.harness.begin()
self.assertEqual(self.harness.charm.snap_name, "epa-orchestrator")
def test_snap_channel_property(self):
"""Test snap_channel property returns configured channel."""
self.harness.begin()
self.harness.update_config({"snap-channel": "latest/edge"})
self.assertEqual(self.harness.charm.snap_channel, "latest/edge")
def test_snap_channel_property_default(self):
"""Test snap_channel property returns default value."""
self.harness.begin()
self.assertEqual(self.harness.charm.snap_channel, "latest/edge")
def test_ensure_services_running_no_op(self):
"""Test ensure_services_running is a no-op and doesn't raise errors."""
self.harness.begin()
# This should not raise any exceptions
result = self.harness.charm.ensure_services_running()
# Should return None (no-op)
self.assertIsNone(result)
def test_stop_services_no_op(self):
"""Test stop_services is a no-op and doesn't raise errors."""
self.harness.begin()
# This should not raise any exceptions
result = self.harness.charm.stop_services()
# Should return None (no-op)
self.assertIsNone(result)

382
charms/epa-orchestrator/uv.lock generated Normal file
View File

@@ -0,0 +1,382 @@
version = 1
revision = 2
requires-python = ">=3.12.0, <3.13"
[[package]]
name = "annotated-types"
version = "0.7.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" },
]
[[package]]
name = "attrs"
version = "25.3.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032, upload-time = "2025-03-13T11:10:22.779Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload-time = "2025-03-13T11:10:21.14Z" },
]
[[package]]
name = "cffi"
version = "1.17.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pycparser" },
]
sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621, upload-time = "2024-09-04T20:45:21.852Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178, upload-time = "2024-09-04T20:44:12.232Z" },
{ url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840, upload-time = "2024-09-04T20:44:13.739Z" },
{ url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803, upload-time = "2024-09-04T20:44:15.231Z" },
{ url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850, upload-time = "2024-09-04T20:44:17.188Z" },
{ url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729, upload-time = "2024-09-04T20:44:18.688Z" },
{ url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256, upload-time = "2024-09-04T20:44:20.248Z" },
{ url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424, upload-time = "2024-09-04T20:44:21.673Z" },
{ url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568, upload-time = "2024-09-04T20:44:23.245Z" },
{ url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736, upload-time = "2024-09-04T20:44:24.757Z" },
{ url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448, upload-time = "2024-09-04T20:44:26.208Z" },
{ url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976, upload-time = "2024-09-04T20:44:27.578Z" },
]
[[package]]
name = "cryptography"
version = "45.0.4"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/fe/c8/a2a376a8711c1e11708b9c9972e0c3223f5fc682552c82d8db844393d6ce/cryptography-45.0.4.tar.gz", hash = "sha256:7405ade85c83c37682c8fe65554759800a4a8c54b2d96e0f8ad114d31b808d57", size = 744890, upload-time = "2025-06-10T00:03:51.297Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/cc/1c/92637793de053832523b410dbe016d3f5c11b41d0cf6eef8787aabb51d41/cryptography-45.0.4-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:425a9a6ac2823ee6e46a76a21a4e8342d8fa5c01e08b823c1f19a8b74f096069", size = 7055712, upload-time = "2025-06-10T00:02:38.826Z" },
{ url = "https://files.pythonhosted.org/packages/ba/14/93b69f2af9ba832ad6618a03f8a034a5851dc9a3314336a3d71c252467e1/cryptography-45.0.4-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:680806cf63baa0039b920f4976f5f31b10e772de42f16310a6839d9f21a26b0d", size = 4205335, upload-time = "2025-06-10T00:02:41.64Z" },
{ url = "https://files.pythonhosted.org/packages/67/30/fae1000228634bf0b647fca80403db5ca9e3933b91dd060570689f0bd0f7/cryptography-45.0.4-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4ca0f52170e821bc8da6fc0cc565b7bb8ff8d90d36b5e9fdd68e8a86bdf72036", size = 4431487, upload-time = "2025-06-10T00:02:43.696Z" },
{ url = "https://files.pythonhosted.org/packages/6d/5a/7dffcf8cdf0cb3c2430de7404b327e3db64735747d641fc492539978caeb/cryptography-45.0.4-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f3fe7a5ae34d5a414957cc7f457e2b92076e72938423ac64d215722f6cf49a9e", size = 4208922, upload-time = "2025-06-10T00:02:45.334Z" },
{ url = "https://files.pythonhosted.org/packages/c6/f3/528729726eb6c3060fa3637253430547fbaaea95ab0535ea41baa4a6fbd8/cryptography-45.0.4-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:25eb4d4d3e54595dc8adebc6bbd5623588991d86591a78c2548ffb64797341e2", size = 3900433, upload-time = "2025-06-10T00:02:47.359Z" },
{ url = "https://files.pythonhosted.org/packages/d9/4a/67ba2e40f619e04d83c32f7e1d484c1538c0800a17c56a22ff07d092ccc1/cryptography-45.0.4-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:ce1678a2ccbe696cf3af15a75bb72ee008d7ff183c9228592ede9db467e64f1b", size = 4464163, upload-time = "2025-06-10T00:02:49.412Z" },
{ url = "https://files.pythonhosted.org/packages/7e/9a/b4d5aa83661483ac372464809c4b49b5022dbfe36b12fe9e323ca8512420/cryptography-45.0.4-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:49fe9155ab32721b9122975e168a6760d8ce4cffe423bcd7ca269ba41b5dfac1", size = 4208687, upload-time = "2025-06-10T00:02:50.976Z" },
{ url = "https://files.pythonhosted.org/packages/db/b7/a84bdcd19d9c02ec5807f2ec2d1456fd8451592c5ee353816c09250e3561/cryptography-45.0.4-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:2882338b2a6e0bd337052e8b9007ced85c637da19ef9ecaf437744495c8c2999", size = 4463623, upload-time = "2025-06-10T00:02:52.542Z" },
{ url = "https://files.pythonhosted.org/packages/d8/84/69707d502d4d905021cac3fb59a316344e9f078b1da7fb43ecde5e10840a/cryptography-45.0.4-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:23b9c3ea30c3ed4db59e7b9619272e94891f8a3a5591d0b656a7582631ccf750", size = 4332447, upload-time = "2025-06-10T00:02:54.63Z" },
{ url = "https://files.pythonhosted.org/packages/f3/ee/d4f2ab688e057e90ded24384e34838086a9b09963389a5ba6854b5876598/cryptography-45.0.4-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b0a97c927497e3bc36b33987abb99bf17a9a175a19af38a892dc4bbb844d7ee2", size = 4572830, upload-time = "2025-06-10T00:02:56.689Z" },
{ url = "https://files.pythonhosted.org/packages/70/d4/994773a261d7ff98034f72c0e8251fe2755eac45e2265db4c866c1c6829c/cryptography-45.0.4-cp311-abi3-win32.whl", hash = "sha256:e00a6c10a5c53979d6242f123c0a97cff9f3abed7f064fc412c36dc521b5f257", size = 2932769, upload-time = "2025-06-10T00:02:58.467Z" },
{ url = "https://files.pythonhosted.org/packages/5a/42/c80bd0b67e9b769b364963b5252b17778a397cefdd36fa9aa4a5f34c599a/cryptography-45.0.4-cp311-abi3-win_amd64.whl", hash = "sha256:817ee05c6c9f7a69a16200f0c90ab26d23a87701e2a284bd15156783e46dbcc8", size = 3410441, upload-time = "2025-06-10T00:03:00.14Z" },
{ url = "https://files.pythonhosted.org/packages/ce/0b/2488c89f3a30bc821c9d96eeacfcab6ff3accc08a9601ba03339c0fd05e5/cryptography-45.0.4-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:964bcc28d867e0f5491a564b7debb3ffdd8717928d315d12e0d7defa9e43b723", size = 7031836, upload-time = "2025-06-10T00:03:01.726Z" },
{ url = "https://files.pythonhosted.org/packages/fe/51/8c584ed426093aac257462ae62d26ad61ef1cbf5b58d8b67e6e13c39960e/cryptography-45.0.4-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6a5bf57554e80f75a7db3d4b1dacaa2764611ae166ab42ea9a72bcdb5d577637", size = 4195746, upload-time = "2025-06-10T00:03:03.94Z" },
{ url = "https://files.pythonhosted.org/packages/5c/7d/4b0ca4d7af95a704eef2f8f80a8199ed236aaf185d55385ae1d1610c03c2/cryptography-45.0.4-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:46cf7088bf91bdc9b26f9c55636492c1cce3e7aaf8041bbf0243f5e5325cfb2d", size = 4424456, upload-time = "2025-06-10T00:03:05.589Z" },
{ url = "https://files.pythonhosted.org/packages/1d/45/5fabacbc6e76ff056f84d9f60eeac18819badf0cefc1b6612ee03d4ab678/cryptography-45.0.4-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:7bedbe4cc930fa4b100fc845ea1ea5788fcd7ae9562e669989c11618ae8d76ee", size = 4198495, upload-time = "2025-06-10T00:03:09.172Z" },
{ url = "https://files.pythonhosted.org/packages/55/b7/ffc9945b290eb0a5d4dab9b7636706e3b5b92f14ee5d9d4449409d010d54/cryptography-45.0.4-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:eaa3e28ea2235b33220b949c5a0d6cf79baa80eab2eb5607ca8ab7525331b9ff", size = 3885540, upload-time = "2025-06-10T00:03:10.835Z" },
{ url = "https://files.pythonhosted.org/packages/7f/e3/57b010282346980475e77d414080acdcb3dab9a0be63071efc2041a2c6bd/cryptography-45.0.4-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:7ef2dde4fa9408475038fc9aadfc1fb2676b174e68356359632e980c661ec8f6", size = 4452052, upload-time = "2025-06-10T00:03:12.448Z" },
{ url = "https://files.pythonhosted.org/packages/37/e6/ddc4ac2558bf2ef517a358df26f45bc774a99bf4653e7ee34b5e749c03e3/cryptography-45.0.4-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:6a3511ae33f09094185d111160fd192c67aa0a2a8d19b54d36e4c78f651dc5ad", size = 4198024, upload-time = "2025-06-10T00:03:13.976Z" },
{ url = "https://files.pythonhosted.org/packages/3a/c0/85fa358ddb063ec588aed4a6ea1df57dc3e3bc1712d87c8fa162d02a65fc/cryptography-45.0.4-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:06509dc70dd71fa56eaa138336244e2fbaf2ac164fc9b5e66828fccfd2b680d6", size = 4451442, upload-time = "2025-06-10T00:03:16.248Z" },
{ url = "https://files.pythonhosted.org/packages/33/67/362d6ec1492596e73da24e669a7fbbaeb1c428d6bf49a29f7a12acffd5dc/cryptography-45.0.4-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:5f31e6b0a5a253f6aa49be67279be4a7e5a4ef259a9f33c69f7d1b1191939872", size = 4325038, upload-time = "2025-06-10T00:03:18.4Z" },
{ url = "https://files.pythonhosted.org/packages/53/75/82a14bf047a96a1b13ebb47fb9811c4f73096cfa2e2b17c86879687f9027/cryptography-45.0.4-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:944e9ccf67a9594137f942d5b52c8d238b1b4e46c7a0c2891b7ae6e01e7c80a4", size = 4560964, upload-time = "2025-06-10T00:03:20.06Z" },
{ url = "https://files.pythonhosted.org/packages/cd/37/1a3cba4c5a468ebf9b95523a5ef5651244693dc712001e276682c278fc00/cryptography-45.0.4-cp37-abi3-win32.whl", hash = "sha256:c22fe01e53dc65edd1945a2e6f0015e887f84ced233acecb64b4daadb32f5c97", size = 2924557, upload-time = "2025-06-10T00:03:22.563Z" },
{ url = "https://files.pythonhosted.org/packages/2a/4b/3256759723b7e66380397d958ca07c59cfc3fb5c794fb5516758afd05d41/cryptography-45.0.4-cp37-abi3-win_amd64.whl", hash = "sha256:627ba1bc94f6adf0b0a2e35d87020285ead22d9f648c7e75bb64f367375f3b22", size = 3395508, upload-time = "2025-06-10T00:03:24.586Z" },
]
[[package]]
name = "deprecated"
version = "1.2.18"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "wrapt" },
]
sdist = { url = "https://files.pythonhosted.org/packages/98/97/06afe62762c9a8a86af0cfb7bfdab22a43ad17138b07af5b1a58442690a2/deprecated-1.2.18.tar.gz", hash = "sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d", size = 2928744, upload-time = "2025-01-27T10:46:25.7Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/6e/c6/ac0b6c1e2d138f1002bcf799d330bd6d85084fece321e662a14223794041/Deprecated-1.2.18-py2.py3-none-any.whl", hash = "sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec", size = 9998, upload-time = "2025-01-27T10:46:09.186Z" },
]
[[package]]
name = "epa-orchestrator"
version = "2025.1"
source = { virtual = "." }
dependencies = [
{ name = "cryptography" },
{ name = "jinja2" },
{ name = "jsonschema" },
{ name = "opentelemetry-api" },
{ name = "ops" },
{ name = "pydantic" },
{ name = "tenacity" },
]
[package.metadata]
requires-dist = [
{ name = "cryptography" },
{ name = "jinja2" },
{ name = "jsonschema" },
{ name = "opentelemetry-api", specifier = "~=1.21.0" },
{ name = "ops" },
{ name = "pydantic" },
{ name = "tenacity" },
]
[[package]]
name = "importlib-metadata"
version = "6.11.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "zipp" },
]
sdist = { url = "https://files.pythonhosted.org/packages/ee/eb/58c2ab27ee628ad801f56d4017fe62afab0293116f6d0b08f1d5bd46e06f/importlib_metadata-6.11.0.tar.gz", hash = "sha256:1231cf92d825c9e03cfc4da076a16de6422c863558229ea0b22b675657463443", size = 54593, upload-time = "2023-12-03T17:33:10.693Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/59/9b/ecce94952ab5ea74c31dcf9ccf78ccd484eebebef06019bf8cb579ab4519/importlib_metadata-6.11.0-py3-none-any.whl", hash = "sha256:f0afba6205ad8f8947c7d338b5342d5db2afbfd82f9cbef7879a9539cc12eb9b", size = 23427, upload-time = "2023-12-03T17:33:08.965Z" },
]
[[package]]
name = "jinja2"
version = "3.1.6"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "markupsafe" },
]
sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" },
]
[[package]]
name = "jsonschema"
version = "4.24.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "attrs" },
{ name = "jsonschema-specifications" },
{ name = "referencing" },
{ name = "rpds-py" },
]
sdist = { url = "https://files.pythonhosted.org/packages/bf/d3/1cf5326b923a53515d8f3a2cd442e6d7e94fcc444716e879ea70a0ce3177/jsonschema-4.24.0.tar.gz", hash = "sha256:0b4e8069eb12aedfa881333004bccaec24ecef5a8a6a4b6df142b2cc9599d196", size = 353480, upload-time = "2025-05-26T18:48:10.459Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/a2/3d/023389198f69c722d039351050738d6755376c8fd343e91dc493ea485905/jsonschema-4.24.0-py3-none-any.whl", hash = "sha256:a462455f19f5faf404a7902952b6f0e3ce868f3ee09a359b05eca6673bd8412d", size = 88709, upload-time = "2025-05-26T18:48:08.417Z" },
]
[[package]]
name = "jsonschema-specifications"
version = "2025.4.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "referencing" },
]
sdist = { url = "https://files.pythonhosted.org/packages/bf/ce/46fbd9c8119cfc3581ee5643ea49464d168028cfb5caff5fc0596d0cf914/jsonschema_specifications-2025.4.1.tar.gz", hash = "sha256:630159c9f4dbea161a6a2205c3011cc4f18ff381b189fff48bb39b9bf26ae608", size = 15513, upload-time = "2025-04-23T12:34:07.418Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/01/0e/b27cdbaccf30b890c40ed1da9fd4a3593a5cf94dae54fb34f8a4b74fcd3f/jsonschema_specifications-2025.4.1-py3-none-any.whl", hash = "sha256:4653bffbd6584f7de83a67e0d620ef16900b390ddc7939d56684d6c81e33f1af", size = 18437, upload-time = "2025-04-23T12:34:05.422Z" },
]
[[package]]
name = "markupsafe"
version = "3.0.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload-time = "2024-10-18T15:21:54.129Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274, upload-time = "2024-10-18T15:21:13.777Z" },
{ url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348, upload-time = "2024-10-18T15:21:14.822Z" },
{ url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149, upload-time = "2024-10-18T15:21:15.642Z" },
{ url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118, upload-time = "2024-10-18T15:21:17.133Z" },
{ url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993, upload-time = "2024-10-18T15:21:18.064Z" },
{ url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178, upload-time = "2024-10-18T15:21:18.859Z" },
{ url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319, upload-time = "2024-10-18T15:21:19.671Z" },
{ url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352, upload-time = "2024-10-18T15:21:20.971Z" },
{ url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097, upload-time = "2024-10-18T15:21:22.646Z" },
{ url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601, upload-time = "2024-10-18T15:21:23.499Z" },
]
[[package]]
name = "opentelemetry-api"
version = "1.21.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "deprecated" },
{ name = "importlib-metadata" },
]
sdist = { url = "https://files.pythonhosted.org/packages/4d/aa/1a10f310275fdd05a1062d4a8a641a5f041db2377956a80ff3c4dc325a6c/opentelemetry_api-1.21.0.tar.gz", hash = "sha256:d6185fd5043e000075d921822fd2d26b953eba8ca21b1e2fa360dd46a7686316", size = 56674, upload-time = "2023-11-07T23:16:23.155Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/51/3a/945e6c21f405ac4ea526f91ee09cc1568c04e0c95d3392903e6984c8f0e0/opentelemetry_api-1.21.0-py3-none-any.whl", hash = "sha256:4bb86b28627b7e41098f0e93280fe4892a1abed1b79a19aec6f928f39b17dffb", size = 57947, upload-time = "2023-11-07T23:15:46.656Z" },
]
[[package]]
name = "ops"
version = "2.22.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "importlib-metadata" },
{ name = "opentelemetry-api" },
{ name = "pyyaml" },
{ name = "websocket-client" },
]
sdist = { url = "https://files.pythonhosted.org/packages/1f/44/b13d1722ea3211390a9ba3c65acb7c8806168858d8568dcb52192fff161d/ops-2.22.0.tar.gz", hash = "sha256:bd1cd1229e83efb8ae2d97d8878c7db3deceb6819eb5a38fb6e235a959528ec2", size = 500975, upload-time = "2025-05-29T04:18:46.521Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/19/09/9636766721d4d34fc0fc768d0c74f006a772368d5e68ceba6b9c32407ce5/ops-2.22.0-py3-none-any.whl", hash = "sha256:ad44326bc065e33357b47e1cf4c73e811b2fdb3c89dd0c9bdf421a7a028bdcf7", size = 182680, upload-time = "2025-05-29T04:18:44.01Z" },
]
[[package]]
name = "pycparser"
version = "2.22"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736, upload-time = "2024-03-30T13:22:22.564Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552, upload-time = "2024-03-30T13:22:20.476Z" },
]
[[package]]
name = "pydantic"
version = "2.11.7"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "annotated-types" },
{ name = "pydantic-core" },
{ name = "typing-extensions" },
{ name = "typing-inspection" },
]
sdist = { url = "https://files.pythonhosted.org/packages/00/dd/4325abf92c39ba8623b5af936ddb36ffcfe0beae70405d456ab1fb2f5b8c/pydantic-2.11.7.tar.gz", hash = "sha256:d989c3c6cb79469287b1569f7447a17848c998458d49ebe294e975b9baf0f0db", size = 788350, upload-time = "2025-06-14T08:33:17.137Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/6a/c0/ec2b1c8712ca690e5d61979dee872603e92b8a32f94cc1b72d53beab008a/pydantic-2.11.7-py3-none-any.whl", hash = "sha256:dde5df002701f6de26248661f6835bbe296a47bf73990135c7d07ce741b9623b", size = 444782, upload-time = "2025-06-14T08:33:14.905Z" },
]
[[package]]
name = "pydantic-core"
version = "2.33.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195, upload-time = "2025-04-23T18:33:52.104Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/18/8a/2b41c97f554ec8c71f2a8a5f85cb56a8b0956addfe8b0efb5b3d77e8bdc3/pydantic_core-2.33.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc", size = 2009000, upload-time = "2025-04-23T18:31:25.863Z" },
{ url = "https://files.pythonhosted.org/packages/a1/02/6224312aacb3c8ecbaa959897af57181fb6cf3a3d7917fd44d0f2917e6f2/pydantic_core-2.33.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7", size = 1847996, upload-time = "2025-04-23T18:31:27.341Z" },
{ url = "https://files.pythonhosted.org/packages/d6/46/6dcdf084a523dbe0a0be59d054734b86a981726f221f4562aed313dbcb49/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025", size = 1880957, upload-time = "2025-04-23T18:31:28.956Z" },
{ url = "https://files.pythonhosted.org/packages/ec/6b/1ec2c03837ac00886ba8160ce041ce4e325b41d06a034adbef11339ae422/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011", size = 1964199, upload-time = "2025-04-23T18:31:31.025Z" },
{ url = "https://files.pythonhosted.org/packages/2d/1d/6bf34d6adb9debd9136bd197ca72642203ce9aaaa85cfcbfcf20f9696e83/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f", size = 2120296, upload-time = "2025-04-23T18:31:32.514Z" },
{ url = "https://files.pythonhosted.org/packages/e0/94/2bd0aaf5a591e974b32a9f7123f16637776c304471a0ab33cf263cf5591a/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88", size = 2676109, upload-time = "2025-04-23T18:31:33.958Z" },
{ url = "https://files.pythonhosted.org/packages/f9/41/4b043778cf9c4285d59742281a769eac371b9e47e35f98ad321349cc5d61/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1", size = 2002028, upload-time = "2025-04-23T18:31:39.095Z" },
{ url = "https://files.pythonhosted.org/packages/cb/d5/7bb781bf2748ce3d03af04d5c969fa1308880e1dca35a9bd94e1a96a922e/pydantic_core-2.33.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b", size = 2100044, upload-time = "2025-04-23T18:31:41.034Z" },
{ url = "https://files.pythonhosted.org/packages/fe/36/def5e53e1eb0ad896785702a5bbfd25eed546cdcf4087ad285021a90ed53/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1", size = 2058881, upload-time = "2025-04-23T18:31:42.757Z" },
{ url = "https://files.pythonhosted.org/packages/01/6c/57f8d70b2ee57fc3dc8b9610315949837fa8c11d86927b9bb044f8705419/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6", size = 2227034, upload-time = "2025-04-23T18:31:44.304Z" },
{ url = "https://files.pythonhosted.org/packages/27/b9/9c17f0396a82b3d5cbea4c24d742083422639e7bb1d5bf600e12cb176a13/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea", size = 2234187, upload-time = "2025-04-23T18:31:45.891Z" },
{ url = "https://files.pythonhosted.org/packages/b0/6a/adf5734ffd52bf86d865093ad70b2ce543415e0e356f6cacabbc0d9ad910/pydantic_core-2.33.2-cp312-cp312-win32.whl", hash = "sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290", size = 1892628, upload-time = "2025-04-23T18:31:47.819Z" },
{ url = "https://files.pythonhosted.org/packages/43/e4/5479fecb3606c1368d496a825d8411e126133c41224c1e7238be58b87d7e/pydantic_core-2.33.2-cp312-cp312-win_amd64.whl", hash = "sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2", size = 1955866, upload-time = "2025-04-23T18:31:49.635Z" },
{ url = "https://files.pythonhosted.org/packages/0d/24/8b11e8b3e2be9dd82df4b11408a67c61bb4dc4f8e11b5b0fc888b38118b5/pydantic_core-2.33.2-cp312-cp312-win_arm64.whl", hash = "sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab", size = 1888894, upload-time = "2025-04-23T18:31:51.609Z" },
]
[[package]]
name = "pyyaml"
version = "6.0.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873, upload-time = "2024-08-06T20:32:25.131Z" },
{ url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302, upload-time = "2024-08-06T20:32:26.511Z" },
{ url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154, upload-time = "2024-08-06T20:32:28.363Z" },
{ url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223, upload-time = "2024-08-06T20:32:30.058Z" },
{ url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542, upload-time = "2024-08-06T20:32:31.881Z" },
{ url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164, upload-time = "2024-08-06T20:32:37.083Z" },
{ url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611, upload-time = "2024-08-06T20:32:38.898Z" },
{ url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591, upload-time = "2024-08-06T20:32:40.241Z" },
{ url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338, upload-time = "2024-08-06T20:32:41.93Z" },
]
[[package]]
name = "referencing"
version = "0.36.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "attrs" },
{ name = "rpds-py" },
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/2f/db/98b5c277be99dd18bfd91dd04e1b759cad18d1a338188c936e92f921c7e2/referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", size = 74744, upload-time = "2025-01-25T08:48:16.138Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c1/b1/3baf80dc6d2b7bc27a95a67752d0208e410351e3feb4eb78de5f77454d8d/referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0", size = 26775, upload-time = "2025-01-25T08:48:14.241Z" },
]
[[package]]
name = "rpds-py"
version = "0.25.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/8c/a6/60184b7fc00dd3ca80ac635dd5b8577d444c57e8e8742cecabfacb829921/rpds_py-0.25.1.tar.gz", hash = "sha256:8960b6dac09b62dac26e75d7e2c4a22efb835d827a7278c34f72b2b84fa160e3", size = 27304, upload-time = "2025-05-21T12:46:12.502Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/7f/81/28ab0408391b1dc57393653b6a0cf2014cc282cc2909e4615e63e58262be/rpds_py-0.25.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b5ffe453cde61f73fea9430223c81d29e2fbf412a6073951102146c84e19e34c", size = 364647, upload-time = "2025-05-21T12:43:28.559Z" },
{ url = "https://files.pythonhosted.org/packages/2c/9a/7797f04cad0d5e56310e1238434f71fc6939d0bc517192a18bb99a72a95f/rpds_py-0.25.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:115874ae5e2fdcfc16b2aedc95b5eef4aebe91b28e7e21951eda8a5dc0d3461b", size = 350454, upload-time = "2025-05-21T12:43:30.615Z" },
{ url = "https://files.pythonhosted.org/packages/69/3c/93d2ef941b04898011e5d6eaa56a1acf46a3b4c9f4b3ad1bbcbafa0bee1f/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a714bf6e5e81b0e570d01f56e0c89c6375101b8463999ead3a93a5d2a4af91fa", size = 389665, upload-time = "2025-05-21T12:43:32.629Z" },
{ url = "https://files.pythonhosted.org/packages/c1/57/ad0e31e928751dde8903a11102559628d24173428a0f85e25e187defb2c1/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:35634369325906bcd01577da4c19e3b9541a15e99f31e91a02d010816b49bfda", size = 403873, upload-time = "2025-05-21T12:43:34.576Z" },
{ url = "https://files.pythonhosted.org/packages/16/ad/c0c652fa9bba778b4f54980a02962748479dc09632e1fd34e5282cf2556c/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d4cb2b3ddc16710548801c6fcc0cfcdeeff9dafbc983f77265877793f2660309", size = 525866, upload-time = "2025-05-21T12:43:36.123Z" },
{ url = "https://files.pythonhosted.org/packages/2a/39/3e1839bc527e6fcf48d5fec4770070f872cdee6c6fbc9b259932f4e88a38/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9ceca1cf097ed77e1a51f1dbc8d174d10cb5931c188a4505ff9f3e119dfe519b", size = 416886, upload-time = "2025-05-21T12:43:38.034Z" },
{ url = "https://files.pythonhosted.org/packages/7a/95/dd6b91cd4560da41df9d7030a038298a67d24f8ca38e150562644c829c48/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c2cd1a4b0c2b8c5e31ffff50d09f39906fe351389ba143c195566056c13a7ea", size = 390666, upload-time = "2025-05-21T12:43:40.065Z" },
{ url = "https://files.pythonhosted.org/packages/64/48/1be88a820e7494ce0a15c2d390ccb7c52212370badabf128e6a7bb4cb802/rpds_py-0.25.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1de336a4b164c9188cb23f3703adb74a7623ab32d20090d0e9bf499a2203ad65", size = 425109, upload-time = "2025-05-21T12:43:42.263Z" },
{ url = "https://files.pythonhosted.org/packages/cf/07/3e2a17927ef6d7720b9949ec1b37d1e963b829ad0387f7af18d923d5cfa5/rpds_py-0.25.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9fca84a15333e925dd59ce01da0ffe2ffe0d6e5d29a9eeba2148916d1824948c", size = 567244, upload-time = "2025-05-21T12:43:43.846Z" },
{ url = "https://files.pythonhosted.org/packages/d2/e5/76cf010998deccc4f95305d827847e2eae9c568099c06b405cf96384762b/rpds_py-0.25.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:88ec04afe0c59fa64e2f6ea0dd9657e04fc83e38de90f6de201954b4d4eb59bd", size = 596023, upload-time = "2025-05-21T12:43:45.932Z" },
{ url = "https://files.pythonhosted.org/packages/52/9a/df55efd84403736ba37a5a6377b70aad0fd1cb469a9109ee8a1e21299a1c/rpds_py-0.25.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a8bd2f19e312ce3e1d2c635618e8a8d8132892bb746a7cf74780a489f0f6cdcb", size = 561634, upload-time = "2025-05-21T12:43:48.263Z" },
{ url = "https://files.pythonhosted.org/packages/ab/aa/dc3620dd8db84454aaf9374bd318f1aa02578bba5e567f5bf6b79492aca4/rpds_py-0.25.1-cp312-cp312-win32.whl", hash = "sha256:e5e2f7280d8d0d3ef06f3ec1b4fd598d386cc6f0721e54f09109a8132182fbfe", size = 222713, upload-time = "2025-05-21T12:43:49.897Z" },
{ url = "https://files.pythonhosted.org/packages/a3/7f/7cef485269a50ed5b4e9bae145f512d2a111ca638ae70cc101f661b4defd/rpds_py-0.25.1-cp312-cp312-win_amd64.whl", hash = "sha256:db58483f71c5db67d643857404da360dce3573031586034b7d59f245144cc192", size = 235280, upload-time = "2025-05-21T12:43:51.893Z" },
{ url = "https://files.pythonhosted.org/packages/99/f2/c2d64f6564f32af913bf5f3f7ae41c7c263c5ae4c4e8f1a17af8af66cd46/rpds_py-0.25.1-cp312-cp312-win_arm64.whl", hash = "sha256:6d50841c425d16faf3206ddbba44c21aa3310a0cebc3c1cdfc3e3f4f9f6f5728", size = 225399, upload-time = "2025-05-21T12:43:53.351Z" },
]
[[package]]
name = "tenacity"
version = "9.1.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/0a/d4/2b0cd0fe285e14b36db076e78c93766ff1d529d70408bd1d2a5a84f1d929/tenacity-9.1.2.tar.gz", hash = "sha256:1169d376c297e7de388d18b4481760d478b0e99a777cad3a9c86e556f4b697cb", size = 48036, upload-time = "2025-04-02T08:25:09.966Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/e5/30/643397144bfbfec6f6ef821f36f33e57d35946c44a2352d3c9f0ae847619/tenacity-9.1.2-py3-none-any.whl", hash = "sha256:f77bf36710d8b73a50b2dd155c97b870017ad21afe6ab300326b0371b3b05138", size = 28248, upload-time = "2025-04-02T08:25:07.678Z" },
]
[[package]]
name = "typing-extensions"
version = "4.14.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d1/bc/51647cd02527e87d05cb083ccc402f93e441606ff1f01739a62c8ad09ba5/typing_extensions-4.14.0.tar.gz", hash = "sha256:8676b788e32f02ab42d9e7c61324048ae4c6d844a399eebace3d4979d75ceef4", size = 107423, upload-time = "2025-06-02T14:52:11.399Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/69/e0/552843e0d356fbb5256d21449fa957fa4eff3bbc135a74a691ee70c7c5da/typing_extensions-4.14.0-py3-none-any.whl", hash = "sha256:a1514509136dd0b477638fc68d6a91497af5076466ad0fa6c338e44e359944af", size = 43839, upload-time = "2025-06-02T14:52:10.026Z" },
]
[[package]]
name = "typing-inspection"
version = "0.4.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28", size = 75726, upload-time = "2025-05-21T18:55:23.885Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51", size = 14552, upload-time = "2025-05-21T18:55:22.152Z" },
]
[[package]]
name = "websocket-client"
version = "1.8.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/e6/30/fba0d96b4b5fbf5948ed3f4681f7da2f9f64512e1d303f94b4cc174c24a5/websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da", size = 54648, upload-time = "2024-04-23T22:16:16.976Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/5a/84/44687a29792a70e111c5c477230a72c4b957d88d16141199bf9acb7537a3/websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526", size = 58826, upload-time = "2024-04-23T22:16:14.422Z" },
]
[[package]]
name = "wrapt"
version = "1.17.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/c3/fc/e91cc220803d7bc4db93fb02facd8461c37364151b8494762cc88b0fbcef/wrapt-1.17.2.tar.gz", hash = "sha256:41388e9d4d1522446fe79d3213196bd9e3b301a336965b9e27ca2788ebd122f3", size = 55531, upload-time = "2025-01-14T10:35:45.465Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/a1/bd/ab55f849fd1f9a58ed7ea47f5559ff09741b25f00c191231f9f059c83949/wrapt-1.17.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d5e2439eecc762cd85e7bd37161d4714aa03a33c5ba884e26c81559817ca0925", size = 53799, upload-time = "2025-01-14T10:33:57.4Z" },
{ url = "https://files.pythonhosted.org/packages/53/18/75ddc64c3f63988f5a1d7e10fb204ffe5762bc663f8023f18ecaf31a332e/wrapt-1.17.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3fc7cb4c1c744f8c05cd5f9438a3caa6ab94ce8344e952d7c45a8ed59dd88392", size = 38821, upload-time = "2025-01-14T10:33:59.334Z" },
{ url = "https://files.pythonhosted.org/packages/48/2a/97928387d6ed1c1ebbfd4efc4133a0633546bec8481a2dd5ec961313a1c7/wrapt-1.17.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8fdbdb757d5390f7c675e558fd3186d590973244fab0c5fe63d373ade3e99d40", size = 38919, upload-time = "2025-01-14T10:34:04.093Z" },
{ url = "https://files.pythonhosted.org/packages/73/54/3bfe5a1febbbccb7a2f77de47b989c0b85ed3a6a41614b104204a788c20e/wrapt-1.17.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bb1d0dbf99411f3d871deb6faa9aabb9d4e744d67dcaaa05399af89d847a91d", size = 88721, upload-time = "2025-01-14T10:34:07.163Z" },
{ url = "https://files.pythonhosted.org/packages/25/cb/7262bc1b0300b4b64af50c2720ef958c2c1917525238d661c3e9a2b71b7b/wrapt-1.17.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d18a4865f46b8579d44e4fe1e2bcbc6472ad83d98e22a26c963d46e4c125ef0b", size = 80899, upload-time = "2025-01-14T10:34:09.82Z" },
{ url = "https://files.pythonhosted.org/packages/2a/5a/04cde32b07a7431d4ed0553a76fdb7a61270e78c5fd5a603e190ac389f14/wrapt-1.17.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc570b5f14a79734437cb7b0500376b6b791153314986074486e0b0fa8d71d98", size = 89222, upload-time = "2025-01-14T10:34:11.258Z" },
{ url = "https://files.pythonhosted.org/packages/09/28/2e45a4f4771fcfb109e244d5dbe54259e970362a311b67a965555ba65026/wrapt-1.17.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6d9187b01bebc3875bac9b087948a2bccefe464a7d8f627cf6e48b1bbae30f82", size = 86707, upload-time = "2025-01-14T10:34:12.49Z" },
{ url = "https://files.pythonhosted.org/packages/c6/d2/dcb56bf5f32fcd4bd9aacc77b50a539abdd5b6536872413fd3f428b21bed/wrapt-1.17.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:9e8659775f1adf02eb1e6f109751268e493c73716ca5761f8acb695e52a756ae", size = 79685, upload-time = "2025-01-14T10:34:15.043Z" },
{ url = "https://files.pythonhosted.org/packages/80/4e/eb8b353e36711347893f502ce91c770b0b0929f8f0bed2670a6856e667a9/wrapt-1.17.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e8b2816ebef96d83657b56306152a93909a83f23994f4b30ad4573b00bd11bb9", size = 87567, upload-time = "2025-01-14T10:34:16.563Z" },
{ url = "https://files.pythonhosted.org/packages/17/27/4fe749a54e7fae6e7146f1c7d914d28ef599dacd4416566c055564080fe2/wrapt-1.17.2-cp312-cp312-win32.whl", hash = "sha256:468090021f391fe0056ad3e807e3d9034e0fd01adcd3bdfba977b6fdf4213ea9", size = 36672, upload-time = "2025-01-14T10:34:17.727Z" },
{ url = "https://files.pythonhosted.org/packages/15/06/1dbf478ea45c03e78a6a8c4be4fdc3c3bddea5c8de8a93bc971415e47f0f/wrapt-1.17.2-cp312-cp312-win_amd64.whl", hash = "sha256:ec89ed91f2fa8e3f52ae53cd3cf640d6feff92ba90d62236a81e4e563ac0e991", size = 38865, upload-time = "2025-01-14T10:34:19.577Z" },
{ url = "https://files.pythonhosted.org/packages/2d/82/f56956041adef78f849db6b289b282e72b55ab8045a75abad81898c28d19/wrapt-1.17.2-py3-none-any.whl", hash = "sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8", size = 23594, upload-time = "2025-01-14T10:35:44.018Z" },
]
[[package]]
name = "zipp"
version = "3.23.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/e3/02/0f2892c661036d50ede074e376733dca2ae7c6eb617489437771209d4180/zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166", size = 25547, upload-time = "2025-06-08T17:06:39.4Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e", size = 10276, upload-time = "2025-06-08T17:06:38.034Z" },
]

View File

@@ -598,6 +598,14 @@ class TestOSBaseOperatorCharmSnap(test_utils.CharmTestCase):
self.harness.begin()
self.addCleanup(self.harness.cleanup)
def test_snap_name_property(self):
"""Test snap_name property returns configured snap name."""
self.assertEqual(self.harness.charm.snap_name, "mysnap")
def test_snap_channel_property_default(self):
"""Test snap_channel property returns default value."""
self.assertEqual(self.harness.charm.snap_channel, "latest/stable")
def test_set_snap_data(self) -> None:
"""Test snap set data."""
charm = self.harness.charm

View File

@@ -37,7 +37,7 @@ from jinja2 import (
test_directories = [dir_.name for dir_ in list(Path("tests").glob('*')) if dir_.name != "local"]
built_charms = glob.glob("*.charm")
context = {
charm.rstrip(".charm").replace("-", "_"): True for charm in built_charms
charm.replace(".charm", "").replace("-", "_"): True for charm in built_charms
}
print(f"Using context: {context}")

View File

@@ -0,0 +1,14 @@
# Copyright (c) 2025 Canonical Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.

View File

@@ -0,0 +1,80 @@
# Copyright (c) 2025 Canonical Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
import subprocess
import zaza.model as model
import zaza.openstack.charm_tests.test_utils as test_utils
class EpaOrchestratorTest(test_utils.BaseCharmTest):
"""Charm tests for epa-orchestrator."""
snap_name = "epa-orchestrator"
@classmethod
def setUpClass(cls):
"""Run class setup for running tests."""
super(EpaOrchestratorTest, cls).setUpClass(
application_name="epa-orchestrator"
)
def _get_units(self) -> list[str]:
"""Get the units."""
return [unit.name for unit in model.get_units(self.application_name)]
def _run_ssh_command(self, unit: str, command: list[str]):
"""Run a command on a unit via SSH."""
cmd = ["juju", "ssh", unit] + command
try:
stdout = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
return stdout.decode("utf-8").strip()
except subprocess.CalledProcessError as e:
logging.exception("Failed to run command on %s: %s", unit, e.output)
self.fail("Failed to run command on {}: {}".format(unit, e.output))
def _check_snap_installed(self, unit: str, snap_name: str) -> bool:
"""Check if a snap is installed on the unit."""
try:
output = self._run_ssh_command(unit, ["snap", "list", snap_name])
return snap_name in output
except Exception:
return False
def test_100_snap_installed(self):
"""Test that the epa-orchestrator snap is installed."""
units = self._get_units()
for unit in units:
with self.subTest(unit=unit):
logging.info("Checking if snap %s is installed on %s", self.snap_name, unit)
self.assertTrue(
self._check_snap_installed(unit, self.snap_name),
f"Snap {self.snap_name} is not installed on {unit}"
)
def test_200_charm_status_active(self):
"""Test that all units are in active status."""
units = self._get_units()
for unit in units:
with self.subTest(unit=unit):
model.block_until_unit_wl_status(unit, "active", timeout=60 * 5)
status = model.get_status()
unit_status = status.applications[self.application_name]["units"][unit]
current_status = unit_status.workload_status.status
self.assertEqual(
current_status,
"active",
f"Unit {unit} is not in active status, current: {current_status}"
)

View File

@@ -4,7 +4,7 @@ variables:
machines:
'0':
constraints: *constraints
base: ubuntu@22.04
base: ubuntu@24.04
applications:
sunbeam-machine:
@@ -14,7 +14,7 @@ applications:
charm: ch:sunbeam-machine
channel: 2025.1/edge
{% endif -%}
base: ubuntu@22.04
base: ubuntu@24.04
constraints: *constraints
scale: 1
to:
@@ -26,20 +26,32 @@ applications:
charm: ch:sunbeam-clusterd
channel: 2025.1/edge
{% endif -%}
base: ubuntu@22.04
base: ubuntu@24.04
constraints: *constraints
scale: 1
to:
- '0'
tls-operator:
charm: self-signed-certificates
channel: latest/beta
base: ubuntu@22.04
channel: 1/beta
base: ubuntu@24.04
scale: 1
options:
ca-common-name: internal-ca
to:
- '0'
epa-orchestrator:
{% if epa_orchestrator is defined and epa_orchestrator is sameas true -%}
charm: ../../../epa-orchestrator.charm
{% else -%}
charm: ch:epa-orchestrator
channel: latest/edge
{% endif -%}
base: ubuntu@24.04
constraints: *constraints
scale: 1
to:
- '0'
relations:
- - tls-operator:certificates

View File

@@ -6,6 +6,7 @@ configure:
- zaza.charm_tests.noop.setup.basic_setup
tests:
- zaza.sunbeam.charm_tests.clusterd.tests.ClusterdTest
- zaza.sunbeam.charm_tests.epa_orchestrator.tests.EpaOrchestratorTest
tests_options:
trust:
- smoke
@@ -26,3 +27,6 @@ target_deploy_status:
tls-operator:
workload-status: active
workload-status-message-regex: '^$'
epa-orchestrator:
workload-status: active
workload-status-message-regex: '^$'

View File

@@ -142,6 +142,18 @@
- rebuild
vars:
charm: cinder-ceph-k8s
- job:
name: charm-build-epa-orchestrator
description: Build sunbeam epa-orchestrator charm
run: playbooks/charm/build.yaml
timeout: 3600
match-on-config-updates: false
files:
- ops-sunbeam/ops_sunbeam/*
- charms/epa-orchestrator/*
- rebuild
vars:
charm: epa-orchestrator
- job:
name: charm-build-horizon-k8s
description: Build sunbeam horizon-k8s charm
@@ -601,10 +613,13 @@
soft: true
- name: charm-build-sunbeam-clusterd
soft: true
- name: charm-build-epa-orchestrator
soft: true
files:
- ops-sunbeam/ops_sunbeam/
- charms/sunbeam-machine/
- charms/sunbeam-clusterd/
- charms/epa-orchestrator/
- rebuild
- zuul.d/zuul.yaml
vars:
@@ -612,6 +627,7 @@
charm_jobs:
- charm-build-sunbeam-machine
- charm-build-sunbeam-clusterd
- charm-build-epa-orchestrator
test_dir: tests/machine
- job:
@@ -705,6 +721,19 @@
- charmhub_token
timeout: 3600
- job:
name: publish-charm-epa-orchestrator
description: |
Publish epa-orchestrator built in gate pipeline.
run: playbooks/charm/publish.yaml
files:
- ops-sunbeam/ops_sunbeam/
- charms/epa-orchestrator/
- rebuild
secrets:
- charmhub_token
timeout: 3600
- job:
name: publish-charm-designate-bind-k8s
description: |

View File

@@ -60,6 +60,8 @@
nodeset: ubuntu-jammy
- charm-build-cinder-volume-ceph:
nodeset: ubuntu-jammy
- charm-build-epa-orchestrator:
nodeset: ubuntu-jammy
- charm-build-horizon-k8s:
nodeset: ubuntu-jammy
- charm-build-heat-k8s:
@@ -123,6 +125,8 @@
nodeset: ubuntu-jammy
- charm-build-cinder-volume-ceph:
nodeset: ubuntu-jammy
- charm-build-epa-orchestrator:
nodeset: ubuntu-jammy
- charm-build-horizon-k8s:
nodeset: ubuntu-jammy
- charm-build-heat-k8s:
@@ -190,6 +194,8 @@
nodeset: ubuntu-jammy
- publish-charm-cinder-volume-ceph:
nodeset: ubuntu-jammy
- publish-charm-epa-orchestrator:
nodeset: ubuntu-jammy
- publish-charm-horizon-k8s:
nodeset: ubuntu-jammy
- publish-charm-heat-k8s:

View File

@@ -1,85 +1,85 @@
- secret:
name: charmhub_token
data:
# Generated on 2025-05-06T09:43:50+00:00 with 90 days ttl
# Generated on 2025-06-26T07:38:31+00:00 with 90 days ttl
value: !encrypted/pkcs1-oaep
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- Vs7uQfDjzYi2ESFz0OBuEKXin2VST7LNlVZO7RkISwPaSQ48o2VS7eGEH/u3yJPMSO7Qr
kwznPgzgWtLuW+vE17M3pqtrwbitPBa46uinezOsKnLEHUwhGaOl4EEWhWvrSwSwLsz1Z
oPSoG7EhNoiSKlhwGvZ5BbZI4ykwzERh6TS8mnNOz5cUCaiDiJ2D90L8j1BN05jsp+sb9
MxOg34mfAVKd8jDyR2hVfM+lL0YaA+eLqMoXDCd/6nqdoCaHaOR6SW5usVlRk73DgIHgw
KuKG1326sPD2L27zUWTepj0akRk7G23TVAja+3aV9fHCmxQEew1KlCFYGHFU+TXdrr7nx
77gWw5wM3CbOO5GALycIc6QN+Jx1brxfdwaP/F8XF3Zq2D0doPvoq8r3GrD8ITVtVQ82N
rHBY1ZXOrVeqmkvBwj24ZVxQdzxTqtQRXrzUBbqePRJgzsJ6gtzyfSdJLW6nD2vKJKHWg
Rq2kDdtqtrP3/H4GNWXmxdv6QgbpsowUiT0/cq+KLZQQCVYyAajradz/b/TA5hdA9OzL/
o9PLzdvwzJEmKZwJpg2wg5OUnjGQwLP7BK3SdasX6GaJVAF3PG380Eg/0tvaPNflSse5n
uWqVvhkOIlnqkMpae4ZaTbcrre7EZLk0Y/S7t3kit2Z3Vp9/LHA4TjON3CinTA=
- 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
- MMSWA0wsAms9XtBHQHLI9neQW2TgFVu/LGCFFizCtK9WR92EVLXKFSIlNC6vQF1aREdCC
rtgPos7FNcEkV9miObaPczyFbiCmZQatCd6dTnW7Un96LFLgh3GksjYxO5A8nnOu5fSQi
jG3FRz24aj5WtRlRkAWMpQZNcBJ4mSriYoMjHDbfSpp8HHQVpKuQWn1dwqYdGr6JLEJsF
efsaW3lDO3uUEZjYN9g4bdAKy/hUPWQ95TbtrnZeEC+bv+EsrNi0QemIAuwKCv2I09uOP
ndfPdFS/mDN8Oo0AFf0Rmo0S5/jdcFiB4JJVoDIxKvN+6YVOYDQdNF3+Qzzd5pO8KxwOg
aQcYbXJFpolET8FGKAE7zESvXs3Iibmu0SACXFFV1fLb70N6v0L1Ja+CblIVv7Alcwpg4
cxueSKbilINiW7Cz68GGQ2XOPBUonxpRCsNGsp2UyMRPDmYh2FkwSF+F5lkpVJZNu7DtH
gb4LYkUuZ7EMOdILPuc825F5Ca6I+2cYNlstXPN2g3gkex9HMwoS+YmdZTvtBqr2wX4ch
tkeOhIMlRKyT3151F02Ub2AuXMaOQHDn1ZX59XVAjF4S06cowvN74Nppqqf3RPkxk7iDX
MFGVCcBAhtvUNenMtt7n7SYQPwsSHtnY8lbqYHaj1HsXWJzi0bso0d7enVd7fE=

View File

@@ -50,3 +50,4 @@
sunbeam-clusterd: 2025.1/edge
tempest-k8s: 2025.1/edge
watcher-k8s: 2025.1/edge
epa-orchestrator: 2025.1/edge