Compare commits

...
Author SHA1 Message Date
PhyriosandGitHub e47235bd7f Mise à jour des jalons 2026-09-15 12:33:15 +02:00
Johan LEROY 4c72fbbb69 docs: fonde les vues d'architecture du monorepo
Cinq vues Mermaid dans docs/architecture (vue d'ensemble, infra, backend,
frontend, donnees), plus leur index, les conventions de statut et la regle
de maintenance en PR.

Reprend les jalons J1-J4, disparus de dev lors de la reecriture du README
(2670483) et restes seulement sur main : plus rien sur la branche de travail
ne disait ce que le projet doit prouver.

Fige les decisions du module Terraform k3s, qui ne vivaient jusqu'ici que
dans des commentaires de code et des description de variables : version
epinglee obligatoire, Traefik desactive, kubeconfig en 600/root, state local.

Corrige trois affirmations devenues fausses : le frontend classe
"a initialiser" alors que le squelette existe depuis 49f4697, le port 4200
dit attendu par docker-compose.yml qui n'a aucun service frontend, et
l'arborescence core/ prescrite par TESTING.md sans exister.
2026-09-15 11:56:18 +02:00
Johan LEROYandGitHub 57c16c77f7 Merge pull request #66 from ineszang/18-provisionner-un-cluster-k8s-single-node-k3s-via-terraform
18 provisionner un cluster k8s single node k3s via terraform
2026-09-15 11:44:37 +02:00
Dorian PESCE 1103c6e1a6 Merge branch '18-provisionner-un-cluster-k8s-single-node-k3s-via-terraform' of https://github.com/ineszang/ProjetPiscine_EnerVision into 18-provisionner-un-cluster-k8s-single-node-k3s-via-terraform 2026-09-15 11:29:38 +02:00
Dorian PESCE b910e747ec fix: terraform & module 2026-09-15 11:29:34 +02:00
PhyriosandGitHub 4692f1d604 Merge branch 'dev' into 18-provisionner-un-cluster-k8s-single-node-k3s-via-terraform 2026-09-15 10:37:22 +02:00
Dorian PESCE 239efc8ee6 docs/update README 2026-09-15 10:32:22 +02:00
Johan LEROYandGitHub 0ca429ff3d Merge pull request #65 from ineszang/test/preparer-les-tests-unitaires-backend
Test/preparer les tests unitaires backend
2026-09-15 10:29:03 +02:00
Dorian PESCE a2727f9b5a chore/k8s-single-node-k3s via Terraform
Se connecte à la machine on-premise via SSH et installe k3s single-node puis instancie le module.

apply reste à faire une fois la machine prête.
2026-09-15 10:13:41 +02:00
ValentinDeFariaandGitHub 8f237f6d6f Merge pull request #62 from ineszang/test/préparer-les-tests-unitaires-frontend
Outillage tests unitaires frontend : couverture Vitest, scripts npm, …
2026-09-15 09:58:41 +02:00
valentin 34890b2b04 Outillage tests unitaires frontend : couverture Vitest, scripts npm, conventions TESTING.md. 2026-09-14 16:41:45 +02:00
34 changed files with 1305 additions and 1413 deletions
+4 -1
View File
@@ -24,7 +24,7 @@ yarn-error.log*
# Terraform # Terraform
.terraform/ .terraform/
.terraform.lock.hcl # .terraform.lock.hcl est versionne (pas ignore) pour figer les versions de provider entre contributeurs/CI
*.tfstate *.tfstate
*.tfstate.* *.tfstate.*
*.tfplan *.tfplan
@@ -33,6 +33,9 @@ override.tf
override.tf.json override.tf.json
*_override.tf *_override.tf
*_override.tf.json *_override.tf.json
*.tfvars
!*.tfvars.example
kubeconfig
# Airflow # Airflow
etl/airflow/logs/ etl/airflow/logs/
-23
View File
@@ -1,23 +0,0 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/kreuzwerker/docker" {
version = "3.9.0"
constraints = "~> 3.0"
hashes = [
"h1:MmhVJBgNpE2Fbksv/XObZJncwm4th4mFE7Ai+6LiIy4=",
"zh:0ead8281830e9b9496651282235d9a139ba1b1b6ff79e395eb8c78658dc446b9",
"zh:0f17d37d8d3872df3fb75c68b5272e0c981343f53b506a9675b4405191edd3ef",
"zh:11d50b37323874427c6d2a08b737d3c7707c8301fdd236c94485cf2828d0b14b",
"zh:32f6f9b847446054e2db3d72886ef2f1d1aa51a6d0dac42340b07dad18e3f28f",
"zh:5ea5c67668b5dcbda560dc6104b788a9bfc974d52f02f7886889b77cc0e5d248",
"zh:5fb19a0b07edc344cd3ddeeb9cfb3d183089deb7a6a94a7b22a583aa1712596b",
"zh:602a7ece444e2a142ec5245abb98e7a1a990a68afae2df63b6c85ec084f0c5d7",
"zh:693dce278524ad8a6d6c9dd7a01bcd63bb85189639198f8d0b044ab0e5099401",
"zh:72e9911568103576c6a78fa38841cfd45eeb88ad22a2c649eb140a377a5b3c26",
"zh:956b62b6857cbb467b50158601f01b1203daa34cbd447dcc7f044c327e878b68",
"zh:9d372bac0d4479868b34485fb4966ba7bb525938f818b6a625f4977004ea83f9",
"zh:e06658a51427f9f53dbdb06263406fc1bc56d1a4fb5e7eb660d7cdfc22f596bd",
"zh:eee38dadf672b946419af25160eae7c03fc2afbb14f39f2f1d2a7404d647e2f7",
]
}
@@ -1,870 +0,0 @@
<a name="v3.9.0"></a>
## [v3.9.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v3.8.0...v3.9.0) (2025-11-09)
### Chore
* Add file requested by hashicorp ([#813](https://github.com/kreuzwerker/terraform-provider-docker/issues/813))
* Prepare release v3.8.0 ([#806](https://github.com/kreuzwerker/terraform-provider-docker/issues/806))
### Feat
* Implement caching of docker provider ([#808](https://github.com/kreuzwerker/terraform-provider-docker/issues/808))
### Fix
* test attribute of docker_service healthcheck is not required ([#815](https://github.com/kreuzwerker/terraform-provider-docker/issues/815))
* docker_service label can be updated without recreate ([#814](https://github.com/kreuzwerker/terraform-provider-docker/issues/814))
<a name="v3.8.0"></a>
## [v3.8.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v3.7.0...v3.8.0) (2025-10-08)
### Feat
* Add build attribute for docker_registry_image ([#805](https://github.com/kreuzwerker/terraform-provider-docker/issues/805))
* Add build option for additional contexts ([#798](https://github.com/kreuzwerker/terraform-provider-docker/issues/798))
* implement mac_address for networks_advanced ([#794](https://github.com/kreuzwerker/terraform-provider-docker/issues/794))
* Implement docker cluster volume ([#793](https://github.com/kreuzwerker/terraform-provider-docker/issues/793))
<a name="v3.7.0"></a>
## [v3.7.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v3.6.2...v3.7.0) (2025-08-19)
### Chore
* Prepare release v3.7.0 ([#774](https://github.com/kreuzwerker/terraform-provider-docker/issues/774))
### Feat
* Implement memory_reservation and network_mode enhancements ([#773](https://github.com/kreuzwerker/terraform-provider-docker/issues/773))
* Implement cache_from and cache_to for docker_image ([#772](https://github.com/kreuzwerker/terraform-provider-docker/issues/772))
### Fix
* Correctly get and set nanoCPUs for docker_container ([#771](https://github.com/kreuzwerker/terraform-provider-docker/issues/771))
<a name="v3.6.2"></a>
## [v3.6.2](https://github.com/kreuzwerker/terraform-provider-docker/compare/v3.6.1...v3.6.2) (2025-06-13)
### Chore
* Prepare release v3.6.2 ([#750](https://github.com/kreuzwerker/terraform-provider-docker/issues/750))
### Feat
* Allow digest in image name ([#744](https://github.com/kreuzwerker/terraform-provider-docker/issues/744))
### Fix
* Remove wrong buildkit version assignment ([#747](https://github.com/kreuzwerker/terraform-provider-docker/issues/747))
* Reading non existant volume should recreate ([#749](https://github.com/kreuzwerker/terraform-provider-docker/issues/749))
* Typo in cgroup_parent handling ([#746](https://github.com/kreuzwerker/terraform-provider-docker/issues/746))
<a name="v3.6.1"></a>
## [v3.6.1](https://github.com/kreuzwerker/terraform-provider-docker/compare/v3.6.0...v3.6.1) (2025-06-05)
### Chore
* Prepare release v3.6.1 ([#743](https://github.com/kreuzwerker/terraform-provider-docker/issues/743))
### Feat
* allow to set the cgroup parent for container ([#609](https://github.com/kreuzwerker/terraform-provider-docker/issues/609))
<a name="v3.6.0"></a>
## [v3.6.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v3.5.0...v3.6.0) (2025-05-25)
### Chore
* Prepare release v3.6.0 ([#735](https://github.com/kreuzwerker/terraform-provider-docker/issues/735))
### Feat
* Implement correct cpu scheduler settings ([#732](https://github.com/kreuzwerker/terraform-provider-docker/issues/732))
* Add implementaion of capabilities in docker servic ([#727](https://github.com/kreuzwerker/terraform-provider-docker/issues/727))
* implement Buildx builder resource ([#724](https://github.com/kreuzwerker/terraform-provider-docker/issues/724))
### Fix
* Implement buildx fixes for general buildkit support and platform handling ([#734](https://github.com/kreuzwerker/terraform-provider-docker/issues/734))
* Make endpoint validation less strict ([#733](https://github.com/kreuzwerker/terraform-provider-docker/issues/733))
<a name="v3.5.0"></a>
## [v3.5.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v3.4.0...v3.5.0) (2025-05-06)
### Chore
* Prepare release v3.5.0 ([#721](https://github.com/kreuzwerker/terraform-provider-docker/issues/721))
### Feat
* Implement using of buildx for docker_image ([#717](https://github.com/kreuzwerker/terraform-provider-docker/issues/717))
* Support registries that return empty auth scope [#646](https://github.com/kreuzwerker/terraform-provider-docker/issues/646)
* Implement registry_image_manifests data source ([#714](https://github.com/kreuzwerker/terraform-provider-docker/issues/714))
* Implement healthcheck start interval ([#713](https://github.com/kreuzwerker/terraform-provider-docker/issues/713))
<a name="v3.4.0"></a>
## [v3.4.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v3.3.0...v3.4.0) (2025-04-25)
### Chore
* Prepare release v3.4.0 ([#712](https://github.com/kreuzwerker/terraform-provider-docker/issues/712))
### Feat
* Implement volume_options subpath ([#710](https://github.com/kreuzwerker/terraform-provider-docker/issues/710))
### Fix
* Prevent recreation of image name is intentionally set to a fixed value ([#711](https://github.com/kreuzwerker/terraform-provider-docker/issues/711))
* Improve container wait handling ([#709](https://github.com/kreuzwerker/terraform-provider-docker/issues/709))
* Use auth_config block also for registry_image delete functionality ([#708](https://github.com/kreuzwerker/terraform-provider-docker/issues/708))
<a name="v3.3.0"></a>
## [v3.3.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v3.2.0...v3.3.0) (2025-04-19)
### Chore
* Prepare release v3.3.0 ([#705](https://github.com/kreuzwerker/terraform-provider-docker/issues/705))
* Update terraform-plugin-sdk/v2 dependency ([#699](https://github.com/kreuzwerker/terraform-provider-docker/issues/699))
* Update docker/docker and docker/cli to newest stable ([#695](https://github.com/kreuzwerker/terraform-provider-docker/issues/695))
### Feat
* Implement support for docker context ([#704](https://github.com/kreuzwerker/terraform-provider-docker/issues/704))
* disable_docker_daemon_check for provider ([#703](https://github.com/kreuzwerker/terraform-provider-docker/issues/703))
* Implement tag triggers for docker_tag resource ([#702](https://github.com/kreuzwerker/terraform-provider-docker/issues/702))
* Implement auth_config for docker_registry_image ([#701](https://github.com/kreuzwerker/terraform-provider-docker/issues/701))
### Fix
* Store correctly ports from server ([#698](https://github.com/kreuzwerker/terraform-provider-docker/issues/698))
<a name="v3.2.0"></a>
## [v3.2.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v3.1.2...v3.2.0) (2025-04-16)
### Chore
* Prepare release v3.2.0 ([#694](https://github.com/kreuzwerker/terraform-provider-docker/issues/694))
* Upgrade golangci-lint to next major version ([#686](https://github.com/kreuzwerker/terraform-provider-docker/issues/686))
### Docs
* Consolidated update of docs from several PRs ([#691](https://github.com/kreuzwerker/terraform-provider-docker/issues/691))
### Feat
* Implement upload permissions in docker_container resource ([#693](https://github.com/kreuzwerker/terraform-provider-docker/issues/693))
* Implement docker_image timeouts ([#692](https://github.com/kreuzwerker/terraform-provider-docker/issues/692))
* Add support for build-secrets ([#604](https://github.com/kreuzwerker/terraform-provider-docker/issues/604))
### Fix
* Authentication to ECR public ([#690](https://github.com/kreuzwerker/terraform-provider-docker/issues/690))
<a name="v3.1.2"></a>
## [v3.1.2](https://github.com/kreuzwerker/terraform-provider-docker/compare/v3.1.1...v3.1.2) (2025-04-15)
### Chore
* prepare release 3.1.2 ([#688](https://github.com/kreuzwerker/terraform-provider-docker/issues/688))
<a name="v3.1.1"></a>
## [v3.1.1](https://github.com/kreuzwerker/terraform-provider-docker/compare/v3.1.0...v3.1.1) (2025-04-14)
### Chore
* Prepare release 3.1.1 ([#687](https://github.com/kreuzwerker/terraform-provider-docker/issues/687))
<a name="v3.1.0"></a>
## [v3.1.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v3.0.2...v3.1.0) (2025-04-14)
### Chore
* Prepare release 3.1.0 ([#685](https://github.com/kreuzwerker/terraform-provider-docker/issues/685))
* update Go version to 1.22 for consistency across workflows, jo… ([#613](https://github.com/kreuzwerker/terraform-provider-docker/issues/613))
### Feat
* support setting cpu shares ([#575](https://github.com/kreuzwerker/terraform-provider-docker/issues/575))
### Fix
* Use build_args everywhere and update documentation ([#681](https://github.com/kreuzwerker/terraform-provider-docker/issues/681))
* Compress build context before sending it to Docker ([#461](https://github.com/kreuzwerker/terraform-provider-docker/issues/461))
* Set correct default network driver and fix a test ([#677](https://github.com/kreuzwerker/terraform-provider-docker/issues/677))
### Typo
* s/presend/present/ ([#606](https://github.com/kreuzwerker/terraform-provider-docker/issues/606))
<a name="v3.0.2"></a>
## [v3.0.2](https://github.com/kreuzwerker/terraform-provider-docker/compare/v3.0.1...v3.0.2) (2023-03-17)
### Chore
* Prepare release v3.0.2
### Docs
* correct spelling of "networks_advanced" ([#517](https://github.com/kreuzwerker/terraform-provider-docker/issues/517))
### Fix
* Implement proxy support. ([#529](https://github.com/kreuzwerker/terraform-provider-docker/issues/529))
<a name="v3.0.1"></a>
## [v3.0.1](https://github.com/kreuzwerker/terraform-provider-docker/compare/v3.0.0...v3.0.1) (2023-01-13)
### Chore
* Prepare release v3.0.1
### Fix
* Access health of container correctly. ([#506](https://github.com/kreuzwerker/terraform-provider-docker/issues/506))
<a name="v3.0.0"></a>
## [v3.0.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.25.0...v3.0.0) (2023-01-13)
### Chore
* Prepare release v3.0.0
### Docs
* Update documentation.
* Add migration guide and update README ([#502](https://github.com/kreuzwerker/terraform-provider-docker/issues/502))
### Feat
* Prepare v3 release ([#503](https://github.com/kreuzwerker/terraform-provider-docker/issues/503))
<a name="v2.25.0"></a>
## [v2.25.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.24.0...v2.25.0) (2023-01-05)
### Chore
* Prepare release v2.25.0
### Docs
* Add documentation of remote hosts. ([#498](https://github.com/kreuzwerker/terraform-provider-docker/issues/498))
### Feat
* Migrate build block to `docker_image` ([#501](https://github.com/kreuzwerker/terraform-provider-docker/issues/501))
* Add platform attribute to docker_image resource ([#500](https://github.com/kreuzwerker/terraform-provider-docker/issues/500))
* Add sysctl implementation to container of docker_service. ([#499](https://github.com/kreuzwerker/terraform-provider-docker/issues/499))
<a name="v2.24.0"></a>
## [v2.24.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.23.1...v2.24.0) (2022-12-23)
### Chore
* Prepare release v2.24.0
### Docs
* Fix generated website.
* Update command typo ([#487](https://github.com/kreuzwerker/terraform-provider-docker/issues/487))
### Feat
* cgroupns support ([#497](https://github.com/kreuzwerker/terraform-provider-docker/issues/497))
* Add triggers attribute to docker_registry_image ([#496](https://github.com/kreuzwerker/terraform-provider-docker/issues/496))
* Support registries with disabled auth ([#494](https://github.com/kreuzwerker/terraform-provider-docker/issues/494))
* add IPAM options block for docker networks ([#491](https://github.com/kreuzwerker/terraform-provider-docker/issues/491))
### Fix
* Pin data source specific tag test to older tag.
### Tests
* Add test for parsing auth headers.
<a name="v2.23.1"></a>
## [v2.23.1](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.23.0...v2.23.1) (2022-11-23)
### Chore
* Prepare release v2.23.1
### Fix
* Update shasum of busybox:1.35.0 tag in test.
* Handle Auth Header Scopes ([#482](https://github.com/kreuzwerker/terraform-provider-docker/issues/482))
* Set OS_ARCH from GOHOSTOS and GOHOSTARCH ([#477](https://github.com/kreuzwerker/terraform-provider-docker/issues/477))
<a name="v2.23.0"></a>
## [v2.23.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.22.0...v2.23.0) (2022-11-02)
### Chore
* Prepare release v2.23.0
### Feat
* wait container healthy state ([#467](https://github.com/kreuzwerker/terraform-provider-docker/issues/467))
* add docker logs data source ([#471](https://github.com/kreuzwerker/terraform-provider-docker/issues/471))
### Fix
* Update shasum of busybox:1.35.0 tag in test.
* Update shasum of busybox:1.35.0 tag
* Correct provider name to match the public registry ([#462](https://github.com/kreuzwerker/terraform-provider-docker/issues/462))
<a name="v2.22.0"></a>
## [v2.22.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.21.0...v2.22.0) (2022-09-20)
### Chore
* Prepare release v2.22.0
### Feat
* Configurable timeout for docker_container resource stateChangeConf ([#454](https://github.com/kreuzwerker/terraform-provider-docker/issues/454))
### Fix
* oauth authorization support for azurecr ([#451](https://github.com/kreuzwerker/terraform-provider-docker/issues/451))
<a name="v2.21.0"></a>
## [v2.21.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.20.3...v2.21.0) (2022-09-05)
### Chore
* Prepare release v2.21.0
### Docs
* Fix docker config example.
### Feat
* Add image_id attribute to docker_image resource. ([#450](https://github.com/kreuzwerker/terraform-provider-docker/issues/450))
* Update used goversion to 1.18. ([#449](https://github.com/kreuzwerker/terraform-provider-docker/issues/449))
### Fix
* Replace deprecated .latest attribute with new image_id. ([#453](https://github.com/kreuzwerker/terraform-provider-docker/issues/453))
* Remove reading part of docker_tag resource. ([#448](https://github.com/kreuzwerker/terraform-provider-docker/issues/448))
* Fix repo_digest value for DockerImageDatasource test.
<a name="v2.20.3"></a>
## [v2.20.3](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.20.2...v2.20.3) (2022-08-31)
### Chore
* Prepare release v2.20.3
### Fix
* Docker Registry Image data source use HEAD request to query image digest ([#433](https://github.com/kreuzwerker/terraform-provider-docker/issues/433))
* Adding Support for Windows Paths in Bash ([#438](https://github.com/kreuzwerker/terraform-provider-docker/issues/438))
<a name="v2.20.2"></a>
## [v2.20.2](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.20.1...v2.20.2) (2022-08-10)
### Chore
* Prepare release v2.20.2
### Fix
* Check the operating system for determining the default Docker socket ([#427](https://github.com/kreuzwerker/terraform-provider-docker/issues/427))
### Reverts
* fix(deps): update module github.com/golangci/golangci-lint to v1.48.0 ([#423](https://github.com/kreuzwerker/terraform-provider-docker/issues/423))
<a name="v2.20.1"></a>
## [v2.20.1](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.20.0...v2.20.1) (2022-08-10)
### Chore
* Prepare release v2.20.1
* Reduce time to setup AccTests ([#430](https://github.com/kreuzwerker/terraform-provider-docker/issues/430))
### Docs
* Improve docker network usage documentation [skip-ci]
### Feat
* Implement triggers attribute for docker_image. ([#425](https://github.com/kreuzwerker/terraform-provider-docker/issues/425))
### Fix
* Add ForceTrue to docker_image name attribute. ([#421](https://github.com/kreuzwerker/terraform-provider-docker/issues/421))
<a name="v2.20.0"></a>
## [v2.20.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.19.0...v2.20.0) (2022-07-28)
### Chore
* Prepare release v2.20.0
* Fix release targets in Makefile.
### Feat
* Implementation of `docker_tag` resource. ([#418](https://github.com/kreuzwerker/terraform-provider-docker/issues/418))
* Implement support for insecure registries ([#414](https://github.com/kreuzwerker/terraform-provider-docker/issues/414))
<a name="v2.19.0"></a>
## [v2.19.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.18.1...v2.19.0) (2022-07-15)
### Chore
* Prepare release v2.19.0
### Feat
* Add gpu flag to docker_container resource ([#405](https://github.com/kreuzwerker/terraform-provider-docker/issues/405))
### Fix
* Enable authentication to multiple registries again. ([#400](https://github.com/kreuzwerker/terraform-provider-docker/issues/400))
* ECR authentication ([#409](https://github.com/kreuzwerker/terraform-provider-docker/issues/409))
<a name="v2.18.1"></a>
## [v2.18.1](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.18.0...v2.18.1) (2022-07-14)
### Chore
* Prepare release v2.18.1
* Automate changelog generation [skip ci]
### Fix
* Improve searchLocalImages error handling. ([#407](https://github.com/kreuzwerker/terraform-provider-docker/issues/407))
* Throw errors when any part of docker config file handling goes wrong. ([#406](https://github.com/kreuzwerker/terraform-provider-docker/issues/406))
* Enables having a Dockerfile outside the context ([#402](https://github.com/kreuzwerker/terraform-provider-docker/issues/402))
<a name="v2.18.0"></a>
## [v2.18.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.17.0...v2.18.0) (2022-07-11)
### Chore
* prepare release v2.18.0
### Feat
* add runtime, stop_signal and stop_timeout properties to the docker_container resource ([#364](https://github.com/kreuzwerker/terraform-provider-docker/issues/364))
### Fix
* Correctly handle build files and context for docker_registry_image ([#398](https://github.com/kreuzwerker/terraform-provider-docker/issues/398))
* Switch to proper go tools mechanism to fix website-* workflows. ([#399](https://github.com/kreuzwerker/terraform-provider-docker/issues/399))
* compare relative paths when excluding, fixes kreuzwerker[#280](https://github.com/kreuzwerker/terraform-provider-docker/issues/280) ([#397](https://github.com/kreuzwerker/terraform-provider-docker/issues/397))
<a name="v2.17.0"></a>
## [v2.17.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.16.0...v2.17.0) (2022-06-23)
### Chore
* prepare release v2.17.0
* Exclude examples directory from renovate.
* remove the workflow to close stale issues and pull requests ([#371](https://github.com/kreuzwerker/terraform-provider-docker/issues/371))
### Fix
* update go package files directly on master to fix build.
* correct authentication for ghcr.io registry([#349](https://github.com/kreuzwerker/terraform-provider-docker/issues/349))
<a name="v2.16.0"></a>
## [v2.16.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.15.0...v2.16.0) (2022-01-24)
### Chore
* prepare release v2.16.0
### Docs
* fix service options ([#337](https://github.com/kreuzwerker/terraform-provider-docker/issues/337))
* update registry_image.md ([#321](https://github.com/kreuzwerker/terraform-provider-docker/issues/321))
* fix r/registry_image truncated docs ([#304](https://github.com/kreuzwerker/terraform-provider-docker/issues/304))
### Feat
* add parameter for SSH options ([#335](https://github.com/kreuzwerker/terraform-provider-docker/issues/335))
### Fix
* pass container rm flag ([#322](https://github.com/kreuzwerker/terraform-provider-docker/issues/322))
* add nil check of DriverConfig ([#315](https://github.com/kreuzwerker/terraform-provider-docker/issues/315))
* fmt of go files for go 1.17
<a name="v2.15.0"></a>
## [v2.15.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.14.0...v2.15.0) (2021-08-11)
### Chore
* prepare release v2.15.0
* re go gets terraform-plugin-docs
### Docs
* corrects authentication misspell. Closes [#264](https://github.com/kreuzwerker/terraform-provider-docker/issues/264)
### Feat
* add container storage opts ([#258](https://github.com/kreuzwerker/terraform-provider-docker/issues/258))
### Fix
* add current timestamp for file upload to container ([#259](https://github.com/kreuzwerker/terraform-provider-docker/issues/259))
<a name="v2.14.0"></a>
## [v2.14.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.13.0...v2.14.0) (2021-07-09)
### Chore
* prepare release v2.14.0
### Docs
* update to absolute path for registry image context ([#246](https://github.com/kreuzwerker/terraform-provider-docker/issues/246))
* update readme with logos and subsections ([#235](https://github.com/kreuzwerker/terraform-provider-docker/issues/235))
### Feat
* support terraform v1 ([#242](https://github.com/kreuzwerker/terraform-provider-docker/issues/242))
### Fix
* Update the URL of the docker hub registry ([#230](https://github.com/kreuzwerker/terraform-provider-docker/issues/230))
<a name="v2.13.0"></a>
## [v2.13.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.12.2...v2.13.0) (2021-06-22)
### Chore
* prepare release v2.13.0
### Docs
* fix a few typos ([#216](https://github.com/kreuzwerker/terraform-provider-docker/issues/216))
* fix typos in docker_image example usage ([#213](https://github.com/kreuzwerker/terraform-provider-docker/issues/213))
<a name="v2.12.2"></a>
## [v2.12.2](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.12.1...v2.12.2) (2021-05-26)
### Chore
* prepare release v2.12.2
<a name="v2.12.1"></a>
## [v2.12.1](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.12.0...v2.12.1) (2021-05-26)
### Chore
* update changelog for v2.12.1
### Fix
* add service host flattener with space split ([#205](https://github.com/kreuzwerker/terraform-provider-docker/issues/205))
* service state upgradeV2 for empty auth
<a name="v2.12.0"></a>
## [v2.12.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.11.0...v2.12.0) (2021-05-23)
### Chore
* update changelog for v2.12.0
* ignore dist folder
* configure actions/stale ([#157](https://github.com/kreuzwerker/terraform-provider-docker/issues/157))
* add the guide about Terraform Configuration in Bug Report ([#139](https://github.com/kreuzwerker/terraform-provider-docker/issues/139))
* bump docker dependency to v20.10.5 ([#119](https://github.com/kreuzwerker/terraform-provider-docker/issues/119))
### Ci
* run acceptance tests with multiple Terraform versions ([#129](https://github.com/kreuzwerker/terraform-provider-docker/issues/129))
### Docs
* update for v2.12.0
* add releasing steps
* format `Guide of Bug report` ([#159](https://github.com/kreuzwerker/terraform-provider-docker/issues/159))
* add an example to build an image with docker_image ([#158](https://github.com/kreuzwerker/terraform-provider-docker/issues/158))
* add a guide about writing issues to CONTRIBUTING.md ([#149](https://github.com/kreuzwerker/terraform-provider-docker/issues/149))
* fix Github repository URL in README ([#136](https://github.com/kreuzwerker/terraform-provider-docker/issues/136))
### Feat
* support darwin arm builds and golang 1.16 ([#140](https://github.com/kreuzwerker/terraform-provider-docker/issues/140))
* migrate to terraform-sdk v2 ([#102](https://github.com/kreuzwerker/terraform-provider-docker/issues/102))
### Fix
* rewriting tar header fields ([#198](https://github.com/kreuzwerker/terraform-provider-docker/issues/198))
* test spaces for windows ([#190](https://github.com/kreuzwerker/terraform-provider-docker/issues/190))
* replace for loops with StateChangeConf ([#182](https://github.com/kreuzwerker/terraform-provider-docker/issues/182))
* skip sign on compile action
* assign map to rawState when it is nil to prevent panic ([#180](https://github.com/kreuzwerker/terraform-provider-docker/issues/180))
* search local images with Docker image ID ([#151](https://github.com/kreuzwerker/terraform-provider-docker/issues/151))
* set "ForceNew: true" to labelSchema ([#152](https://github.com/kreuzwerker/terraform-provider-docker/issues/152))
<a name="v2.11.0"></a>
## [v2.11.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.10.0...v2.11.0) (2021-01-22)
### Chore
* update changelog for v2.11.0
* updates changelog for v2.10.0
### Docs
* fix legacy configuration style ([#126](https://github.com/kreuzwerker/terraform-provider-docker/issues/126))
### Feat
* add properties -it (tty and stdin_opn) to docker container
<a name="v2.10.0"></a>
## [v2.10.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.9.0...v2.10.0) (2021-01-08)
### Chore
* updates changelog for 2.10.0
* ignores testing folders
* adds separate bug and ft req templates
### Ci
* bumps to docker version 20.10.1
* pins workflows to ubuntu:20.04 image
### Docs
* add labels to arguments of docker_service ([#105](https://github.com/kreuzwerker/terraform-provider-docker/issues/105))
* cleans readme
* adds coc and contributing
### Feat
* supports Docker plugin ([#35](https://github.com/kreuzwerker/terraform-provider-docker/issues/35))
* support max replicas of Docker Service Task Spec ([#112](https://github.com/kreuzwerker/terraform-provider-docker/issues/112))
* add force_remove option to r/image ([#104](https://github.com/kreuzwerker/terraform-provider-docker/issues/104))
* add local semantic commit validation ([#99](https://github.com/kreuzwerker/terraform-provider-docker/issues/99))
* add ability to lint/check of links in documentation locally ([#98](https://github.com/kreuzwerker/terraform-provider-docker/issues/98))
### Fix
* set "latest" to tag when tag isn't specified ([#117](https://github.com/kreuzwerker/terraform-provider-docker/issues/117))
* image label for workflows
* remove all azure cps
### Pull Requests
* Merge pull request [#38](https://github.com/kreuzwerker/terraform-provider-docker/issues/38) from kreuzwerker/ci-ubuntu2004-workflow
* Merge pull request [#36](https://github.com/kreuzwerker/terraform-provider-docker/issues/36) from kreuzwerker/chore-gh-issue-tpl
<a name="v2.9.0"></a>
## [v2.9.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.8.0...v2.9.0) (2020-12-25)
### Chore
* updates changelog for 2.9.0
* update changelog 2.8.0 release date
* introduces golangci-lint ([#32](https://github.com/kreuzwerker/terraform-provider-docker/issues/32))
* fix changelog links
### Ci
* add gofmt's '-s' option
* remove unneeded make tasks
* fix test of website
### Doc
* devices is a block, not a boolean
### Feat
* adds support for OCI manifests ([#316](https://github.com/kreuzwerker/terraform-provider-docker/issues/316))
* adds security_opts to container config. ([#308](https://github.com/kreuzwerker/terraform-provider-docker/issues/308))
* adds support for init process injection for containers. ([#300](https://github.com/kreuzwerker/terraform-provider-docker/issues/300))
### Fix
* changing mounts requires ForceNew ([#314](https://github.com/kreuzwerker/terraform-provider-docker/issues/314))
* allow healthcheck to be computed as container can specify ([#312](https://github.com/kreuzwerker/terraform-provider-docker/issues/312))
* treat null user as a no-op ([#318](https://github.com/kreuzwerker/terraform-provider-docker/issues/318))
* workdir null behavior ([#320](https://github.com/kreuzwerker/terraform-provider-docker/issues/320))
### Style
* format with gofumpt
### Pull Requests
* Merge pull request [#33](https://github.com/kreuzwerker/terraform-provider-docker/issues/33) from brandonros/patch-1
* Merge pull request [#11](https://github.com/kreuzwerker/terraform-provider-docker/issues/11) from suzuki-shunsuke/format-with-gofumpt
* Merge pull request [#26](https://github.com/kreuzwerker/terraform-provider-docker/issues/26) from kreuzwerker/ci/fix-website-ci
* Merge pull request [#8](https://github.com/kreuzwerker/terraform-provider-docker/issues/8) from dubo-dubon-duponey/patch1
<a name="v2.8.0"></a>
## v2.8.0 (2020-11-11)
### Chore
* updates changelog for 2.8.0
* removes travis.yml
* deactivates travis
* removes vendor dir ([#298](https://github.com/kreuzwerker/terraform-provider-docker/issues/298))
* bump go 115 ([#297](https://github.com/kreuzwerker/terraform-provider-docker/issues/297))
* documentation updates ([#286](https://github.com/kreuzwerker/terraform-provider-docker/issues/286))
* updates link syntax ([#287](https://github.com/kreuzwerker/terraform-provider-docker/issues/287))
* fix typo ([#292](https://github.com/kreuzwerker/terraform-provider-docker/issues/292))
### Ci
* reactivats all workflows
* fix website
* only run website workflow
* exports gopath manually
* fix absolute gopath for website
* make website check separate workflow
* fix workflow names
* adds website test to unit test
* adds acc test
* adds compile
* adds go version and goproxy env
* enables unit tests for master branch
* adds unit test workflow
* adds goreleaser and gh action
* bumps docker and ubuntu versions ([#241](https://github.com/kreuzwerker/terraform-provider-docker/issues/241))
* removes debug option from acc tests
* skips test which is flaky only on travis
### Deps
* github.com/hashicorp/terraform[@sdk](https://github.com/sdk)-v0.11-with-go-modules Updated via: go get github.com/hashicorp/terraform[@sdk](https://github.com/sdk)-v0.11-with-go-modules and go mod tidy
* use go modules for dep mgmt run go mod tidy remove govendor from makefile and travis config set appropriate env vars for go modules
### Docker
* improve validation of runtime constraints
### Docs
* update container.html.markdown ([#278](https://github.com/kreuzwerker/terraform-provider-docker/issues/278))
* update service.html.markdown ([#281](https://github.com/kreuzwerker/terraform-provider-docker/issues/281))
* update restart_policy for service. Closes [#228](https://github.com/kreuzwerker/terraform-provider-docker/issues/228)
* adds new label structure. Closes [#214](https://github.com/kreuzwerker/terraform-provider-docker/issues/214)
* update anchors with -1 suffix ([#178](https://github.com/kreuzwerker/terraform-provider-docker/issues/178))
* Fix misspelled words
* Fix exported attribute name in docker_registry_image
* Fix example for docker_registry_image ([#8308](https://github.com/kreuzwerker/terraform-provider-docker/issues/8308))
* provider/docker - network settings attrs
### Feat
* conditionally adding port binding ([#293](https://github.com/kreuzwerker/terraform-provider-docker/issues/293)).
* adds docker Image build feature ([#283](https://github.com/kreuzwerker/terraform-provider-docker/issues/283))
* adds complete support for Docker credential helpers ([#253](https://github.com/kreuzwerker/terraform-provider-docker/issues/253))
* Expose IPv6 properties as attributes
* allow use of source file instead of content / content_base64 ([#240](https://github.com/kreuzwerker/terraform-provider-docker/issues/240))
* supports to update docker_container ([#236](https://github.com/kreuzwerker/terraform-provider-docker/issues/236))
* support to import some docker_container's attributes ([#234](https://github.com/kreuzwerker/terraform-provider-docker/issues/234))
* adds config file content as plain string ([#232](https://github.com/kreuzwerker/terraform-provider-docker/issues/232))
* make UID, GID, & mode for secrets and configs configurable ([#231](https://github.com/kreuzwerker/terraform-provider-docker/issues/231))
* adds import for resources ([#196](https://github.com/kreuzwerker/terraform-provider-docker/issues/196))
* add container ipc mode. ([#182](https://github.com/kreuzwerker/terraform-provider-docker/issues/182))
* adds container working dir ([#181](https://github.com/kreuzwerker/terraform-provider-docker/issues/181))
### Fix
* ignores 'remove_volumes' on container import
* duplicated buildImage function
* port objects with the same internal port but different protocol trigger recreation of container ([#274](https://github.com/kreuzwerker/terraform-provider-docker/issues/274))
* panic to migrate schema of docker_container from v1 to v2 ([#271](https://github.com/kreuzwerker/terraform-provider-docker/issues/271)). Closes [#264](https://github.com/kreuzwerker/terraform-provider-docker/issues/264)
* pins docker registry for tests to v2.7.0
* prevent force recreate of container about some attributes ([#269](https://github.com/kreuzwerker/terraform-provider-docker/issues/269))
* service endpoint spec flattening
* corrects IPAM config read on the data provider ([#229](https://github.com/kreuzwerker/terraform-provider-docker/issues/229))
* replica to 0 in current schema. Closes [#221](https://github.com/kreuzwerker/terraform-provider-docker/issues/221)
* label for network and volume after improt
* binary upload as base 64 content ([#194](https://github.com/kreuzwerker/terraform-provider-docker/issues/194))
* service env truncation for multiple delimiters ([#193](https://github.com/kreuzwerker/terraform-provider-docker/issues/193))
* destroy_grace_seconds are considered ([#179](https://github.com/kreuzwerker/terraform-provider-docker/issues/179))
### Make
* Add website + website-test targets
### Provider
* Ensured Go 1.11 in TravisCI and README provider: Run go fix provider: Run go fmt provider: Encode go version 1.11.5 to .go-version file
* Require Go 1.11 in TravisCI and README provider: Run go fix provider: Run go fmt
### Tests
* Skip test if swap limit isn't available ([#136](https://github.com/kreuzwerker/terraform-provider-docker/issues/136))
* Simplify Dockerfile(s)
### Vendor
* github.com/hashicorp/terraform/...[@v0](https://github.com/v0).10.0
* Ignore github.com/hashicorp/terraform/backend
### Website
* Docs sweep for lists & maps
* note on docker
* docker docs
### Pull Requests
* Merge pull request [#134](https://github.com/kreuzwerker/terraform-provider-docker/issues/134) from terraform-providers/go-modules-2019-03-01
* Merge pull request [#135](https://github.com/kreuzwerker/terraform-provider-docker/issues/135) from terraform-providers/t-simplify-dockerfile
* Merge pull request [#47](https://github.com/kreuzwerker/terraform-provider-docker/issues/47) from captn3m0/docker-link-warning
* Merge pull request [#60](https://github.com/kreuzwerker/terraform-provider-docker/issues/60) from terraform-providers/f-make-website
* Merge pull request [#23](https://github.com/kreuzwerker/terraform-provider-docker/issues/23) from JamesLaverack/patch-1
* Merge pull request [#18](https://github.com/kreuzwerker/terraform-provider-docker/issues/18) from terraform-providers/vendor-tf-0.10
* Merge pull request [#5046](https://github.com/kreuzwerker/terraform-provider-docker/issues/5046) from tpounds/use-built-in-schema-string-hash
* Merge pull request [#3761](https://github.com/kreuzwerker/terraform-provider-docker/issues/3761) from ryane/f-provider-docker-improvements
* Merge pull request [#3383](https://github.com/kreuzwerker/terraform-provider-docker/issues/3383) from apparentlymart/docker-container-command-docs
* Merge pull request [#1564](https://github.com/kreuzwerker/terraform-provider-docker/issues/1564) from nickryand/docker_links
@@ -1,373 +0,0 @@
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.
@@ -1,117 +0,0 @@
<a href="https://docker.com">
<img src="https://raw.githubusercontent.com/kreuzwerker/terraform-provider-docker/master/assets/docker-logo.png" alt="Docker logo" title="Docker" align="right" height="100" />
</a>
<a href="https://terraform.io">
<img src="https://raw.githubusercontent.com/kreuzwerker/terraform-provider-docker/master/assets/terraform-logo.png" alt="Terraform logo" title="Terraform" align="right" height="100" />
</a>
<a href="https://kreuzwerker.de">
<img src="https://raw.githubusercontent.com/kreuzwerker/terraform-provider-docker/master/assets/xw-logo.png" alt="Kreuzwerker logo" title="Kreuzwerker" align="right" height="100" />
</a>
# Terraform Provider for Docker
[![Release](https://img.shields.io/github/v/release/kreuzwerker/terraform-provider-docker)](https://github.com/kreuzwerker/terraform-provider-docker/releases)
[![Installs](https://img.shields.io/badge/dynamic/json?logo=terraform&label=installs&query=$.data.attributes.downloads&url=https%3A%2F%2Fregistry.terraform.io%2Fv2%2Fproviders%2F713)](https://registry.terraform.io/providers/kreuzwerker/docker)
[![Registry](https://img.shields.io/badge/registry-doc%40latest-lightgrey?logo=terraform)](https://registry.terraform.io/providers/kreuzwerker/docker/latest/docs)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/kreuzwerker/terraform-provider-docker/blob/main/LICENSE)
[![Go Status](https://github.com/kreuzwerker/terraform-provider-docker/workflows/Acc%20Tests/badge.svg)](https://github.com/kreuzwerker/terraform-provider-docker/actions)
[![Lint Status](https://github.com/kreuzwerker/terraform-provider-docker/workflows/golangci-lint/badge.svg)](https://github.com/kreuzwerker/terraform-provider-docker/actions)
[![Go Report Card](https://goreportcard.com/badge/github.com/kreuzwerker/terraform-provider-docker)](https://goreportcard.com/report/github.com/kreuzwerker/terraform-provider-docker)
## Documentation
The documentation for the provider is available on the [Terraform Registry](https://registry.terraform.io/providers/kreuzwerker/docker/latest/docs).
Do you want to migrate from `v2.x` to `v3.x`? Please read the [migration guide](docs/v2_v3_migration.md)
## Example usage
Take a look at the examples in the [documentation](https://registry.terraform.io/providers/kreuzwerker/docker/3.9.0/docs) of the registry
or use the following example:
```hcl
# Set the required provider and versions
terraform {
required_providers {
# We recommend pinning to the specific version of the Docker Provider you're using
# since new versions are released frequently
docker = {
source = "kreuzwerker/docker"
version = "3.9.0"
}
}
}
# Configure the docker provider
provider "docker" {
}
# Create a docker image resource
# -> docker pull nginx:latest
resource "docker_image" "nginx" {
name = "nginx:latest"
keep_locally = true
}
# Create a docker container resource
# -> same as 'docker run --name nginx -p8080:80 -d nginx:latest'
resource "docker_container" "nginx" {
name = "nginx"
image = docker_image.nginx.image_id
ports {
external = 8080
internal = 80
}
}
# Or create a service resource
# -> same as 'docker service create -d -p 8081:80 --name nginx-service --replicas 2 nginx:latest'
resource "docker_service" "nginx_service" {
name = "nginx-service"
task_spec {
container_spec {
image = docker_image.nginx.repo_digest
}
}
mode {
replicated {
replicas = 2
}
}
endpoint_spec {
ports {
published_port = 8081
target_port = 80
}
}
}
```
## Building The Provider
[Go](https://golang.org/doc/install) 1.18.x (to build the provider plugin)
```sh
$ git clone git@github.com:kreuzwerker/terraform-provider-docker
$ make build
```
## Contributing
The Terraform Docker Provider is the work of many of contributors. We appreciate your help!
To contribute, please read the contribution guidelines: [Contributing to Terraform - Docker Provider](CONTRIBUTING.md)
## License
The Terraform Provider Docker is available to everyone under the terms of the Mozilla Public License Version 2.0. [Take a look the LICENSE file](LICENSE).
## Stargazers over time
[![Stargazers over time](https://starchart.cc/kreuzwerker/terraform-provider-docker.svg)](https://starchart.cc/kreuzwerker/terraform-provider-docker)
+20 -4
View File
@@ -3,20 +3,35 @@
Monorepo de la plateforme EnerVision : collecte, stockage, analyse et restitution de Monorepo de la plateforme EnerVision : collecte, stockage, analyse et restitution de
series temporelles energetiques, deployee sur une machine on-premise. series temporelles energetiques, deployee sur une machine on-premise.
## Jalons
| Jalon | Intitulé |
|-------|----------------------------------------------------------|
| J1 | Valider la préparation de l'environnement et du repo |
| J2 | Valider le périmètre retenu et les choix technologiques |
| J3 | Valider l'architecture et la gestion de la sécurité |
| J4 | Valider la robustesse et assurer les livrables |
Ce que la documentation apporte à chacun : [docs/architecture/00-vue-ensemble.md](docs/architecture/00-vue-ensemble.md).
## Stack cible ## Stack cible
| Domaine | Technologie | Emplacement | Etat | | Domaine | Technologie | Emplacement | Etat |
|------------|-------------------------------------|---------------------|---------------| |------------|-------------------------------------|---------------------|---------------|
| Backend | FastAPI, Python 3.14 | `apps/backend` | Initialise | | Backend | FastAPI, Python 3.14 | `apps/backend` | Initialise |
| Frontend | Angular, Node 24 LTS | `apps/frontend` | A initialiser | | Frontend | Angular 22, Node 24 LTS | `apps/frontend` | Squelette |
| Base | PostgreSQL 17 + TimescaleDB | `db` | Initialise | | Base | PostgreSQL 17 + TimescaleDB | `db` | Initialise |
| ETL | Apache Airflow | `etl/airflow` | A initialiser | | ETL | Apache Airflow | `etl/airflow` | A initialiser |
| Infra | Terraform | `infra/terraform` | A initialiser | | Infra | Terraform (k3s single-node) | `infra/terraform` | Initialise |
| CI/CD | GitHub Actions | `.github/workflows` | A initialiser | | CI/CD | GitHub Actions | `.github/workflows` | A initialiser |
| Monitoring | Prometheus, Grafana, Alertmanager | `monitoring` | A initialiser | | Monitoring | Prometheus, Grafana, Alertmanager | `monitoring` | A initialiser |
Le backend et la base sont initialises a ce stade. Les autres dossiers portent Le backend, la base et l'infrastructure (Terraform/k3s) sont initialises a ce stade. Le frontend
l'arborescence et un README de cadrage, leur contenu fait l'objet d'un ticket dedie. porte le squelette Angular, sans code metier : aucune route, aucun appel d'API. Les autres dossiers
portent l'arborescence et un README de cadrage, leur contenu fait l'objet d'un ticket dedie.
L'etat detaille de chaque brique et les vues d'architecture sont dans
[docs/architecture](docs/architecture/README.md).
## Arborescence ## Arborescence
@@ -82,3 +97,4 @@ curl -s localhost:8000/api/v1/health/ready
- Branches : `feat/`, `fix/`, `chore/`, `docs/`, `test/` suivi d'un libelle court. - Branches : `feat/`, `fix/`, `chore/`, `docs/`, `test/` suivi d'un libelle court.
- Commits : Conventional Commits, portee = dossier de premier niveau concerne. - Commits : Conventional Commits, portee = dossier de premier niveau concerne.
- Toute decision structurante donne lieu a un ADR dans `docs/adr`. - Toute decision structurante donne lieu a un ADR dans `docs/adr`.
- Toute PR qui change un composant met a jour sa vue dans `docs/architecture`, dans la meme PR.
+2 -1
View File
@@ -72,7 +72,8 @@ Points à vérifier après toute regénération :
1. Pointer l'API dans `src/environments/` sur `http://localhost:8000/api/v1`. 1. Pointer l'API dans `src/environments/` sur `http://localhost:8000/api/v1`.
2. Ajouter le proxy de développement (`proxy.conf.json`) vers le backend. 2. Ajouter le proxy de développement (`proxy.conf.json`) vers le backend.
3. Vérifier que `npm start` sert bien sur le port 4200 attendu par `docker-compose.yml`. 3. Vérifier que `npm start` sert bien sur le port 4200, valeur par défaut d'`APP_CORS_ORIGINS`
côté backend. Le `docker-compose.yml` n'a aucun service frontend.
4. Ajouter le `Dockerfile` multi-stage (build Angular puis service statique nginx). 4. Ajouter le `Dockerfile` multi-stage (build Angular puis service statique nginx).
## Additional Resources ## Additional Resources
+85
View File
@@ -0,0 +1,85 @@
# Conventions de tests unitaires — Frontend
## Outil
Vitest (intégré nativement à Angular CLI, pas d'installation à faire).
## Où écrire les tests
Un fichier `*.spec.ts` à côté de chaque fichier testé (convention Angular CLI
par défaut, respectée automatiquement par `ng generate`).
## Structure attendue (Arrange / Act / Assert)
```typescript
it('devrait faire X quand Y', () => {
// Arrange : préparer les données et les mocks
const input = { valeur: 42 };
// Act : exécuter le code testé
const result = service.doSomething(input);
// Assert : vérifier le résultat
expect(result).toBe(true);
});
```
## Ce qui doit être testé en priorité
- Services (`core/services/`) : logique métier, gestion des erreurs
- Guards et interceptors (`core/guards/`, `core/interceptors/`) : chaque branche de décision
- Composants avec logique (formulaires, conditions d'affichage) — pas nécessaire pour
un composant 100% template, sans logique
`core/services/`, `core/guards/` et `core/interceptors/` n'existent pas encore : c'est
l'arborescence cible, décrite dans
[docs/architecture/30-frontend.md](../../docs/architecture/30-frontend.md).
## Gabarit — tester un service avec appel HTTP
```typescript
import { TestBed } from '@angular/core/testing';
import { provideHttpClient } from '@angular/common/http';
import { provideHttpClientTesting, HttpTestingController } from '@angular/common/http/testing';
import { MonService } from './mon.service';
describe('MonService', () => {
let service: MonService;
let httpMock: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [MonService, provideHttpClient(), provideHttpClientTesting()],
});
service = TestBed.inject(MonService);
httpMock = TestBed.inject(HttpTestingController);
});
afterEach(() => httpMock.verify());
it('devrait récupérer les données', () => {
service.getData().subscribe();
const req = httpMock.expectOne('/api/v1/...');
expect(req.request.method).toBe('GET');
req.flush({ /* réponse simulée */ });
});
});
```
## Gabarit — tester un composant standalone
```typescript
import { TestBed } from '@angular/core/testing';
import { MonComposant } from './mon-composant';
describe('MonComposant', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [MonComposant],
}).compileComponents();
});
it('devrait se créer', () => {
const fixture = TestBed.createComponent(MonComposant);
expect(fixture.componentInstance).toBeTruthy();
});
});
```
## Lancer les tests
- Développement (mode watch) : `npm test`
- Rapport de couverture (CI) : `npm run test:ci -- --coverage`, puis ouvrir `coverage/index.html`
+18 -1
View File
@@ -77,7 +77,24 @@
"defaultConfiguration": "development" "defaultConfiguration": "development"
}, },
"test": { "test": {
"builder": "@angular/build:unit-test" "builder": "@angular/build:unit-test",
"options": {
"coverage": true,
"coverageReporters": [
"text-summary",
"lcov",
"html"
],
"reporters": [
"default",
[
"junit",
{
"outputFile": "test-results/junit.xml"
}
]
]
}
} }
} }
} }
+201
View File
@@ -21,6 +21,7 @@
"@angular/build": "^22.1.8", "@angular/build": "^22.1.8",
"@angular/cli": "^22.1.8", "@angular/cli": "^22.1.8",
"@angular/compiler-cli": "^22.1.0", "@angular/compiler-cli": "^22.1.0",
"@vitest/coverage-v8": "^4.1.11",
"jsdom": "^28.0.0", "jsdom": "^28.0.0",
"prettier": "^3.8.1", "prettier": "^3.8.1",
"typescript": "~6.0.2", "typescript": "~6.0.2",
@@ -733,6 +734,16 @@
"node": "^22.18.0 || >=24.11.0" "node": "^22.18.0 || >=24.11.0"
} }
}, },
"node_modules/@bcoe/v8-coverage": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz",
"integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
}
},
"node_modules/@bramus/specificity": { "node_modules/@bramus/specificity": {
"version": "2.4.2", "version": "2.4.2",
"resolved": "https://registry.npmjs.org/@bramus/specificity/-/specificity-2.4.2.tgz", "resolved": "https://registry.npmjs.org/@bramus/specificity/-/specificity-2.4.2.tgz",
@@ -3692,6 +3703,37 @@
"vite": "^6.0.0 || ^7.0.0 || ^8.0.0" "vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
} }
}, },
"node_modules/@vitest/coverage-v8": {
"version": "4.1.11",
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.11.tgz",
"integrity": "sha512-8MVGEFnJIcdGjcbfKmeq8z0pZHH0JlVtoVZH9Q/qwUp6wyFnEJUBMrw9DCaj+ra3vShGmhavjalMIhPNxZAUcw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@bcoe/v8-coverage": "^1.0.2",
"@vitest/utils": "4.1.11",
"ast-v8-to-istanbul": "^1.0.0",
"istanbul-lib-coverage": "^3.2.2",
"istanbul-lib-report": "^3.0.1",
"istanbul-reports": "^3.2.0",
"magicast": "^0.5.2",
"obug": "^2.1.1",
"std-env": "^4.0.0-rc.1",
"tinyrainbow": "^3.1.0"
},
"funding": {
"url": "https://opencollective.com/vitest"
},
"peerDependencies": {
"@vitest/browser": "4.1.11",
"vitest": "4.1.11"
},
"peerDependenciesMeta": {
"@vitest/browser": {
"optional": true
}
}
},
"node_modules/@vitest/expect": { "node_modules/@vitest/expect": {
"version": "4.1.11", "version": "4.1.11",
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.11.tgz", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.11.tgz",
@@ -3943,6 +3985,18 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/ast-v8-to-istanbul": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.6.tgz",
"integrity": "sha512-fvpl29helSO2w/z7utIbrkNXILdrLwDwAMH2I/zPKlGf5244+gf+B4cyS1sANcrPY2h+hWCGSgC8N61s/+AF9A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/trace-mapping": "^0.3.31",
"estree-walker": "^3.0.3",
"js-tokens": "^10.0.0"
}
},
"node_modules/baseline-browser-mapping": { "node_modules/baseline-browser-mapping": {
"version": "2.11.23", "version": "2.11.23",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.23.tgz", "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.23.tgz",
@@ -5077,6 +5131,16 @@
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/has-symbols": { "node_modules/has-symbols": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
@@ -5139,6 +5203,13 @@
"node": "^20.19.0 || ^22.12.0 || >=24.0.0" "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
} }
}, },
"node_modules/html-escaper": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
"dev": true,
"license": "MIT"
},
"node_modules/htmlparser2": { "node_modules/htmlparser2": {
"version": "10.1.0", "version": "10.1.0",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz",
@@ -5382,6 +5453,45 @@
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
"node_modules/istanbul-lib-coverage": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
"integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=8"
}
},
"node_modules/istanbul-lib-report": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
"integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"istanbul-lib-coverage": "^3.0.0",
"make-dir": "^4.0.0",
"supports-color": "^7.1.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/istanbul-reports": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz",
"integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"html-escaper": "^2.0.0",
"istanbul-lib-report": "^3.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/jose": { "node_modules/jose": {
"version": "6.2.12", "version": "6.2.12",
"resolved": "https://registry.npmjs.org/jose/-/jose-6.2.12.tgz", "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.12.tgz",
@@ -5886,6 +5996,84 @@
"@jridgewell/sourcemap-codec": "^1.5.5" "@jridgewell/sourcemap-codec": "^1.5.5"
} }
}, },
"node_modules/magicast": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.5.tgz",
"integrity": "sha512-UicdXN8zQ3JHlxVq+28afMXPr1z7WNY6+7EJnzTdQWkTAlMLF5fNCCKxJHBQwGaNGR11581EiQmQzx73+MvszA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.29.7",
"@babel/types": "^7.29.7",
"source-map-js": "^1.2.1"
}
},
"node_modules/magicast/node_modules/@babel/helper-string-parser": {
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
"integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/magicast/node_modules/@babel/helper-validator-identifier": {
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
"integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/magicast/node_modules/@babel/parser": {
"version": "7.29.8",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz",
"integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.29.8"
},
"bin": {
"parser": "bin/babel-parser.js"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/magicast/node_modules/@babel/types": {
"version": "7.29.8",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz",
"integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-string-parser": "^7.29.7",
"@babel/helper-validator-identifier": "^7.29.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/make-dir": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
"integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
"dev": true,
"license": "MIT",
"dependencies": {
"semver": "^7.5.3"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/math-intrinsics": { "node_modules/math-intrinsics": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
@@ -7088,6 +7276,19 @@
"url": "https://github.com/chalk/strip-ansi?sponsor=1" "url": "https://github.com/chalk/strip-ansi?sponsor=1"
} }
}, },
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/symbol-tree": { "node_modules/symbol-tree": {
"version": "3.2.4", "version": "3.2.4",
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
+3 -1
View File
@@ -6,7 +6,8 @@
"start": "ng serve", "start": "ng serve",
"build": "ng build", "build": "ng build",
"watch": "ng build --watch --configuration development", "watch": "ng build --watch --configuration development",
"test": "ng test" "test": "ng test",
"test:ci": "ng test --watch=false"
}, },
"private": true, "private": true,
"packageManager": "npm@11.19.0", "packageManager": "npm@11.19.0",
@@ -24,6 +25,7 @@
"@angular/build": "^22.1.8", "@angular/build": "^22.1.8",
"@angular/cli": "^22.1.8", "@angular/cli": "^22.1.8",
"@angular/compiler-cli": "^22.1.0", "@angular/compiler-cli": "^22.1.0",
"@vitest/coverage-v8": "^4.1.11",
"jsdom": "^28.0.0", "jsdom": "^28.0.0",
"prettier": "^3.8.1", "prettier": "^3.8.1",
"typescript": "~6.0.2", "typescript": "~6.0.2",
+9
View File
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" ?>
<testsuites name="vitest tests" tests="2" failures="0" errors="0" time="0.0699261">
<testsuite name="src/app/app.spec.ts" timestamp="2026-09-14T14:27:28.895Z" hostname="76SE37-GL5HHZ3" tests="2" failures="0" errors="0" skipped="0" time="0.0699261">
<testcase classname="src/app/app.spec.ts" name="App &gt; should create the app" time="0.0527847">
</testcase>
<testcase classname="src/app/app.spec.ts" name="App &gt; should render title" time="0.015831">
</testcase>
</testsuite>
</testsuites>
+1 -1
View File
@@ -1,4 +1,4 @@
# Documentation # Documentation
- `adr` : decisions d'architecture, une par fichier, numerotees et immuables. - `adr` : decisions d'architecture, une par fichier, numerotees et immuables.
- `architecture` : schemas et vues d'ensemble. - `architecture` : les vues du systeme. Point d'entree : [architecture/README.md](architecture/README.md).
View File
+137
View File
@@ -0,0 +1,137 @@
# Vue d'ensemble
EnerVision collecte, stocke, analyse et restitue des séries temporelles énergétiques, sur une
machine on-premise.
## Cadre du projet
Quatre jalons ont été posés à l'ouverture du projet. Ils ont disparu du `README.md` lors de la
réécriture de l'arborescence (`2670483`) et ne subsistaient que sur `main`. Ils sont repris ici
parce qu'ils disent ce que le projet doit prouver, et donc à quoi sert chaque décision technique.
| Jalon | Intitulé | Ce que la documentation apporte |
|---|---|---|
| J1 | Valider la préparation de l'environnement et du repo | `10-infra.md` décrit la stack du poste de développement et la commande qui la démarre |
| J2 | Valider le périmètre retenu et les choix technologiques | Les ADR (`../adr/`) portent les choix ; `40-data.md` liste les questions de périmètre encore ouvertes |
| J3 | Ingestion & backend | `20-backend.md` |
| J4 | Architecture, sécurité & frontend | Les cinq vues, et la section « Sécurité » ci-dessous qui consolide les surfaces exposées |
| J5 | Valider la robustesse et assurer les livrables | `20-backend.md` et `30-frontend.md` renvoient aux conventions de tests de chaque application |
## Contexte
Statut : `Cible`. Les acteurs et les sources de mesures ne sont pas arrêtés, c'est l'objet du
jalon J2.
```mermaid
flowchart LR
exploitant["Exploitant<br/>consulte les courbes"]
admin["Administrateur<br/>exploite la plateforme"]
sources["Sources de mesures<br/>à définir en J2"]
subgraph systeme["EnerVision"]
plateforme["Collecte, stockage,<br/>analyse et restitution<br/>de séries temporelles"]
end
sources -.-> plateforme
exploitant -.-> plateforme
admin -.-> plateforme
```
## Conteneurs
Trait plein pour ce qui tourne, pointillé pour ce qui est cible.
```mermaid
flowchart TB
navigateur["Navigateur"]
subgraph machine["Machine on-premise"]
front["Frontend Angular 22<br/>apps/frontend"]
api["API FastAPI<br/>apps/backend"]
db[("PostgreSQL 17<br/>TimescaleDB")]
airflow["Airflow<br/>etl/airflow"]
prom["Prometheus"]
grafana["Grafana"]
end
navigateur --> front
front -.-> api
api --> db
airflow -.-> db
prom -.-> api
grafana -.-> db
grafana -.-> prom
```
Le lien `front -.-> api` est en pointillé à dessein : le frontend n'appelle aujourd'hui aucune
API, `provideHttpClient` n'est pas encore installé. Voir [30-frontend.md](30-frontend.md).
Le lien `prom -.-> api` de même : l'API expose bien `/metrics` au format Prometheus, mais aucun
collecteur ne vient le lire.
## État de la stack
| Domaine | Technologie | Emplacement | Statut | Ce qui existe réellement |
|---|---|---|---|---|
| Backend | FastAPI, Python 3.14 | `apps/backend` | `En cours` | Factory, configuration, journalisation, 2 sondes de santé, `/metrics`. Aucune couche métier |
| Frontend | Angular 22, Node 24 | `apps/frontend` | `En cours` | Squelette `ng new` standalone, routes vides, aucun service HTTP |
| Base | PostgreSQL 17 + TimescaleDB | `db` | `Fait` | Bootstrap de l'extension, base de test, chaîne Alembic. Aucune table applicative |
| Infra | Terraform, k3s single-node | `infra/terraform` | `En cours` | Module d'installation du cluster. Jamais appliqué, aucune ressource Kubernetes déclarée |
| Monitoring | Prometheus, Grafana, Alertmanager | `monitoring` | `Cible` | Rien, hors le `/metrics` exposé par l'API |
| ETL | Apache Airflow | `etl/airflow` | `Cible` | Rien |
| CI/CD | GitHub Actions | `.github/workflows` | `Cible` | Rien |
## Flux bout en bout
Statut : `Cible`. Aucun maillon de cette chaîne n'existe aujourd'hui, à l'exception de la base.
```mermaid
sequenceDiagram
participant S as Source de mesures
participant A as Airflow
participant T as TimescaleDB
participant API as FastAPI
participant U as Angular
S->>A: mesures horodatées
A->>T: insertion dans l'hypertable
T->>T: rafraîchissement de l'agrégat continu
U->>API: GET /api/v1/...
API->>T: agrégation sur la fenêtre demandée
T-->>API: lignes
API-->>U: JSON
```
## Sécurité
Section rattachée au jalon J3. Le détail par brique est dans chaque document ; voici la vue
consolidée.
### En place
- **Les secrets n'ont pas de valeur par défaut.** `APP_SECRET_KEY` et `DATABASE_URL` sont requis
sans repli : l'application refuse de démarrer si l'un manque, plutôt que de tourner avec une
valeur de démonstration. `.env` reste hors dépôt, `.env.example` est versionné.
- **CORS conditionnel** : le middleware n'est ajouté que si `APP_CORS_ORIGINS` est renseigné.
- **Documentation interactive fermée en production** : `/docs`, `/redoc` et `/openapi.json` sont
désactivés dès que `APP_ENV=prod`.
- **Conteneur backend non-root**, déclaré dans `apps/backend/Dockerfile`.
- **Côté infrastructure** : la clé SSH est marquée `sensitive`, le kubeconfig reste en `600/root`
sur la machine cible et n'est lu que par `sudo`, `*.tfvars` est ignoré par git sauf les
`.example`.
### Absent
- **Aucune authentification ni autorisation.** Les deux endpoints exposés sont publics. Rien
n'est encore décidé sur ce point.
- Pas de TLS, pas de limitation de débit, pas de journalisation des accès, pas de rotation des
secrets.
- Aucune analyse de dépendances ni de conteneur, faute de CI.
## Décisions structurantes
Elles vivent dans `../adr/`, pas ici.
| ADR | Objet |
|---|---|
| [0001](../adr/0001-postgresql-timescaledb.md) | PostgreSQL 17 avec l'extension TimescaleDB, et la frontière `db/` vs `alembic/` |
+132
View File
@@ -0,0 +1,132 @@
# Infrastructure
Deux topologies coexistent et ne servent pas la même chose. Ce document dit laquelle vaut dans
quel contexte, quelles décisions sont arrêtées, et ce qui manque encore entre les deux.
| Topologie | Sert à | Statut |
|---|---|---|
| Docker Compose | Développer et recetter sur le poste | `Fait` |
| k3s single-node | Déployer sur le serveur on-premise | `En cours` |
## Poste de développement
Statut : `Fait`. Défini par `docker-compose.yml`, projet `enervision`.
```mermaid
flowchart TB
subgraph poste["Poste de développement"]
ng["ng serve<br/>:4200"]
api["uvicorn --reload<br/>:8000"]
end
subgraph compose["docker compose"]
back["service backend<br/>image construite depuis apps/backend"]
db[("service db<br/>timescale/timescaledb-ha:pg17")]
end
ng -.->|"proxy /api"| api
api -->|"hôte :5433 vers conteneur :5432"| db
back -->|"réseau interne, db:5432"| db
```
| Service | Image | Points notables |
|---|---|---|
| `db` | `timescale/timescaledb-ha:pg17` | Publié sur **5433** côté hôte, 5432 souvent déjà pris. `healthcheck` `pg_isready`, 12 tentatives, `start_period` 40s |
| `backend` | Construite depuis `apps/backend` | `depends_on: db, condition: service_healthy`. **N'embarque pas le source** : toute modification impose `docker compose up -d --build backend` |
**La boucle de développement n'utilise pas le service `backend`.** `make db-up` puis `make dev` :
seule la base tourne en conteneur, l'API tourne sur le poste avec le rechargement à chaud. Le
service `backend` sert la stack complète et la recette. Les deux occupent le port 8000, ils ne se
lancent donc pas ensemble.
Deux pièges sont documentés en tête du `docker-compose.yml`, ils ne se devinent pas :
- `PGDATA` vaut `/home/postgres/pgdata/data` pour l'image `-ha`, et non le chemin habituel de
l'image `postgres`. Monté ailleurs, le volume ne retient rien, sans le moindre message.
- `db/init` est monté **fichier par fichier**. Monter le dossier masquerait les scripts d'init de
l'image, dont `timescaledb-tune`. Ajouter un fichier dans `db/init/` impose donc une ligne dans
le compose. Voir [`db/README.md`](../../db/README.md).
## Cible de déploiement
Statut : `En cours`. Le module `infra/terraform/modules/k3s/` installe le cluster. Il n'a jamais
été appliqué.
```mermaid
flowchart LR
poste["Poste<br/>terraform apply"]
kube["kubeconfig local"]
subgraph serveur["Serveur on-premise"]
k3s["k3s server single-node<br/>Traefik désactivé"]
charges["Charges de travail<br/>aucune déclarée"]
end
poste -->|"SSH, get.k3s.io"| k3s
k3s -->|"cat /etc/rancher/k3s/k3s.yaml"| kube
k3s -.-> charges
```
### Ce que le Terraform fait
```mermaid
sequenceDiagram
participant TF as terraform apply
participant SRV as Serveur on-premise
participant L as Poste local
TF->>SRV: SSH, curl get.k3s.io puis install server
TF->>SRV: attend /etc/rancher/k3s/k3s.yaml
TF->>SRV: ssh cat k3s.yaml
SRV-->>L: kubeconfig, 127.0.0.1 réécrit en ssh_host
```
### Ce que le Terraform ne fait pas
Il déclare le provider `null` et **lui seul** : ni `kubernetes`, ni `helm`. Aucun namespace,
aucun déploiement, aucun service, aucun ingress. À l'issue d'un `apply`, on dispose d'un cluster
vide et d'un kubeconfig, rien de plus.
## Décisions figées
Ces arbitrages sont pris. Ils ne vivaient jusqu'ici que dans des commentaires de code et des
`description` de variables, c'est-à-dire qu'ils ne survivaient pas au premier remaniement.
| Décision | Raison | Où elle est appliquée |
|---|---|---|
| k3s single-node plutôt que Kubernetes complet | Une seule machine on-premise, pas de plan de contrôle à répartir | `modules/k3s/main.tf` |
| `k3s_version` obligatoire, valeur vide refusée | Sans épinglage, `get.k3s.io` installe la dernière version à chaque exécution : le déploiement cesse d'être reproductible | `validation` dans `modules/k3s/variables.tf` |
| Traefik désactivé | Le choix d'ingress reste ouvert, on ne veut pas en subir un par défaut | `k3s_disable_components`, défaut `["traefik"]` |
| Kubeconfig laissé en `600/root`, lu par `sudo` | `--write-kubeconfig-mode 644` exposerait `cluster-admin` à tout utilisateur local de la machine | Commentaire et `fetch_kubeconfig` dans `modules/k3s/main.tf` |
| State Terraform en backend `local` | Un seul opérateur, pas d'exécution concurrente, pas de dépendance à un stockage distant | `environments/dev/versions.tf` |
| `.terraform.lock.hcl` versionné | Fige les versions de provider entre contributeurs et future CI | Commentaire dans `.gitignore` |
| `*.tfvars` ignoré, `*.tfvars.example` versionné | Les tfvars portent l'adresse du serveur et le chemin de la clé | `.gitignore` |
| Désinstallation gérée au `destroy` | `k3s-uninstall.sh` en `on_failure = continue` : un serveur injoignable ne bloque pas le `destroy` | `modules/k3s/main.tf` |
| Deux racines, `dev` et `prod` | Séparation des états et des variables par environnement | `environments/` |
## Ports et noms
| Quoi | Valeur | Remarque |
|---|---|---|
| PostgreSQL, côté hôte | `5433` | Redirigé vers 5432 dans le conteneur. 5432 est souvent déjà pris |
| PostgreSQL, côté réseau Compose | `db:5432` | Nom de service, utilisé par `DATABASE_URL` du service `backend` |
| API | `8000` | Identique en conteneur et hors conteneur |
| Frontend, `ng serve` | `4200` | Valeur par défaut d'`APP_CORS_ORIGINS`. Le compose n'a aucun service frontend |
| SSH du serveur | `22` par défaut | `ssh_port`, redéfinissable |
| Base applicative | `enervision` | Variable `POSTGRES_DB` |
| Base de test | `enervision_test` | Créée par `db/init/110-test-database.sql`, nom attendu en dur par `apps/backend/tests/conftest.py` |
## Le trou entre les deux topologies
Rien ne relie aujourd'hui ce qui est construit par Compose et ce qui tournerait sur k3s. Compose
construit une image backend localement ; k3s ne saurait pas où la trouver. C'est la première
question à trancher, avant toute ressource Kubernetes.
## Questions ouvertes
- **Quel ingress** remplace Traefik, et qui termine le TLS.
- **Quel registre d'images**, et comment il est alimenté sans CI.
- **Quel stockage persistant** côté Kubernetes pour PostgreSQL, et si la base tourne dans le
cluster ou à côté.
- **Quelle stratégie de sauvegarde et de restauration** des données de mesure.
- **Que devient `environments/prod/`**, aujourd'hui réduit à un `.gitkeep`.
+163
View File
@@ -0,0 +1,163 @@
# Backend
API FastAPI, Python 3.14, SQLAlchemy asynchrone sur `asyncpg`. Source dans `apps/backend`.
## Couches
La doctrine est posée dans [`apps/backend/README.md`](../../apps/backend/README.md) et
[`TESTING.md`](../../apps/backend/TESTING.md) : `endpoints` appelle `services`, qui appelle
`repositories`, qui seuls touchent les `models`. Le sens de dépendance ne s'inverse jamais.
Dans les faits, trois de ces couches sont des dossiers vides.
```mermaid
flowchart TB
ep["endpoints<br/>2 routes"]
sc["schemas<br/>2 modèles Pydantic"]
sv["services<br/>vide"]
rp["repositories<br/>vide"]
md["models<br/>vide"]
db[("PostgreSQL")]
ep --> sc
ep -.-> sv
sv -.-> rp
rp -.-> md
ep -->|"SQL brut, état actuel"| db
rp -.-> db
```
Le trait plein de `endpoints` vers la base n'est pas une erreur de dessin : `/health/ready`
exécute aujourd'hui son `SELECT` directement, sans repository. C'est acceptable pour une sonde
d'infrastructure, qui vérifie la base elle-même et non une donnée métier. Ce raccourci ne doit
pas servir de modèle au premier endpoint métier.
`app/models/__init__.py` ne contient qu'un avertissement, qui mérite d'être connu avant la
première migration : tout modèle absent de ce module reste invisible d'un
`alembic revision --autogenerate`, qui produirait alors un `drop` de sa table.
## Démarrage
Point d'entrée : **une factory**, `uvicorn app.main:create_app --factory`. Aucune configuration
n'est lue à l'import du module, ce qui rend l'application testable et les migrations
indépendantes de l'environnement d'exécution.
```mermaid
sequenceDiagram
participant U as uvicorn --factory
participant F as create_app
participant S as get_settings
participant A as FastAPI
U->>F: create_app()
F->>S: Settings depuis .env et variables APP_*
S-->>F: resolved
F->>F: configure_logging(resolved)
F->>A: FastAPI, docs fermés si prod
F->>A: CORSMiddleware, seulement si allowed_origins
F->>A: Instrumentator, expose /metrics
F->>A: include_router, préfixe /api/v1
A-->>U: application
```
**Le `lifespan` n'ouvre aucune connexion.** Au démarrage il journalise le nom, la version et
l'environnement ; à l'arrêt il libère l'engine. L'engine lui-même est construit paresseusement au
premier appel de `get_engine()`, mis en cache par `lru_cache`. Conséquence directe : une API qui
démarre ne prouve rien sur la base, la première connexion réelle a lieu au premier
`GET /api/v1/health/ready`. C'est ce qui rend cette sonde indispensable.
## Configuration
`Settings` est un `BaseSettings` Pydantic, lu depuis `.env` avec le préfixe `APP_`.
| Variable | Défaut | Rôle |
|---|---|---|
| `APP_SECRET_KEY` | **aucun** | Secret applicatif, `SecretStr` |
| `DATABASE_URL` | **aucun** | Chaîne de connexion, `postgresql+asyncpg://...` |
| `APP_ENV` | `local` | `local`, `dev`, `staging` ou `prod` |
| `APP_DEBUG` | `false` | Active aussi l'écho SQL de l'engine |
| `APP_LOG_LEVEL` | `INFO` | |
| `APP_CORS_ORIGINS` | `""` | Liste séparée par des virgules. Vide, aucun middleware CORS n'est posé |
| `APP_API_PREFIX` | `/api/v1` | |
| `APP_DATABASE_POOL_SIZE` | `5` | |
| `APP_DATABASE_MAX_OVERFLOW` | `10` | |
Deux pièges :
- **`DATABASE_URL` ne prend pas le préfixe `APP_`.** C'est le seul réglage dans ce cas, par
`validation_alias`, pour rester compatible avec la convention d'Alembic et des hébergeurs.
- **`APP_SECRET_KEY` et `DATABASE_URL` n'ont pas de valeur par défaut.** L'application refuse de
démarrer si l'un manque. C'est délibéré : mieux vaut un échec au démarrage qu'un service qui
tourne avec un secret de démonstration.
Deux fichiers d'environnement, deux usages : `.env` à la racine alimente `docker-compose.yml`,
`apps/backend/.env` alimente l'API lancée sur le poste.
## Routes exposées
| Méthode | Chemin | Dans l'OpenAPI | Rôle |
|---|---|---|---|
| GET | `/api/v1/health/live` | oui | Le processus répond. Ne touche pas la base |
| GET | `/api/v1/health/ready` | oui | La base répond **et** l'extension TimescaleDB est chargée |
| GET | `/metrics` | non | Format Prometheus, exposé par l'instrumentator |
| GET | `/docs`, `/redoc`, `/openapi.json` | non | Désactivés quand `APP_ENV=prod` |
Aucune route métier n'existe à ce jour.
### `/health/ready`
Cette sonde porte une garde décrite dans l'[ADR 0001](../adr/0001-postgresql-timescaledb.md) : un
bootstrap de base sauté ne se voit pas au démarrage de l'API, elle le rend visible.
```mermaid
sequenceDiagram
participant C as Client
participant R as readiness
participant E as get_engine
participant D as PostgreSQL
C->>R: GET /api/v1/health/ready
R->>E: session, engine créé au premier appel
R->>D: SELECT extversion FROM pg_extension WHERE extname = 'timescaledb'
alt base injoignable
D--xR: SQLAlchemyError ou OSError
R-->>C: 503 Base de donnees injoignable
else extension absente
D-->>R: NULL
R-->>C: 503 Extension TimescaleDB absente
else
D-->>R: version de l'extension
R-->>C: 200 status ready
end
```
## Sécurité
Voir la vue consolidée dans [00-vue-ensemble.md](00-vue-ensemble.md). Côté backend :
- **Aucune authentification, aucune autorisation.** Les deux routes sont publiques. Le premier
endpoint métier imposera de trancher ce point.
- Le CORS n'autorise que les origines listées, et n'existe pas si la liste est vide.
- `/docs`, `/redoc` et `/openapi.json` disparaissent en production.
- Le conteneur tourne en utilisateur non-root, avec un `HEALTHCHECK` sur `/api/v1/health/live`.
- Ni limitation de débit, ni journalisation des accès, ni en-têtes de sécurité.
## Observabilité
- Journalisation par `dictConfig` : format console en développement, JSON dès `APP_ENV=prod`.
`sqlalchemy.engine` est forcé à `WARNING` pour ne pas noyer les journaux.
- `/metrics` au format Prometheus. **Aucun collecteur ne le lit** : `monitoring/` est vide.
## Tests
Conventions, gabarits et arborescence : [`apps/backend/TESTING.md`](../../apps/backend/TESTING.md).
Deux points structurants y sont fixés : les doubles passent par `app.dependency_overrides` et
jamais par `unittest.mock`, et les tests qui touchent la vraie base portent le marqueur
`integration`, exclu par défaut.
## Questions ouvertes
- **Authentification et autorisation** : quel mécanisme, quelle granularité.
- **Pagination et fenêtrage** des lectures de séries temporelles, qui conditionnent la forme des
endpoints métier.
- **Politique de versionnement de l'API** au-delà du préfixe `/api/v1`.
+114
View File
@@ -0,0 +1,114 @@
# Frontend
Application Angular 22, 100 % standalone, testée avec Vitest. Source dans `apps/frontend`.
## État actuel
Statut : `En cours`. Le projet est un `ng new` intact. Le tableau de la
[vue d'ensemble](00-vue-ensemble.md) le classe désormais correctement, le `README.md` racine le
disait encore « à initialiser » alors que le squelette existe depuis `49f4697`.
Ce qui est en place :
- Bootstrap par `bootstrapApplication(App, appConfig)`, **aucun `NgModule`** dans le dépôt.
- `app.config.ts` fournit `provideBrowserGlobalErrorListeners()` et `provideRouter(routes)`.
- Vitest via le builder `@angular/build:unit-test`, couverture activée, un fichier de test.
- Prettier configuré, parser `angular` pour les gabarits HTML.
Ce qui n'existe pas encore :
- `routes` est un tableau vide. Aucune page, aucune navigation.
- **`provideHttpClient` n'est pas fourni** et `@angular/common/http` n'est importé nulle part :
l'application n'appelle aucune API.
- `app.html` est la page d'accueil Angular par défaut, commentaires de remplacement compris.
- Aucune bibliothèque de graphiques, aucun kit d'interface, aucune gestion d'état.
- Aucun lint : ESLint n'est pas installé.
## Arborescence cible
Statut : `Cible`. Elle n'est pas inventée ici : [`TESTING.md`](../../apps/frontend/TESTING.md) la
prescrit déjà dans ses gabarits de tests.
```mermaid
flowchart TB
subgraph src["src/app"]
core["core/<br/>services, guards, interceptors"]
features["features/<br/>un dossier par domaine"]
shared["shared/<br/>composants réutilisables"]
end
features -.-> core
features -.-> shared
core -.-> env["environments/<br/>apiUrl"]
```
Un service HTTP par domaine dans `core/services`, les composants de page dans `features`, et rien
d'autre que du réutilisable dans `shared`. Les composants n'appellent jamais `HttpClient`
directement : ils passent par un service, ce qui rend le double de test trivial.
## Flux HTTP
Statut : `Cible`. Le chemin est câblé, rien ne l'emprunte encore.
```mermaid
sequenceDiagram
participant C as Composant
participant S as Service Angular
participant P as ng serve, proxy
participant A as FastAPI
C->>S: appel de méthode
S->>P: GET /api/v1/...
P->>A: http://localhost:8000/api/v1/...
A-->>S: JSON
S-->>C: modèle typé
```
En développement, `proxy.conf.json` redirige tout `/api` vers `http://localhost:8000`. C'est ce
qui évite le CORS sur le poste, et c'est pourquoi `environment.development.ts` se contente d'un
`apiUrl` relatif, `/api/v1`.
En production, il n'y a pas de proxy : `environment.ts` porte une URL absolue. Angular substitue
le fichier via `fileReplacements`, et la configuration `production` est celle par défaut.
**Dette connue.** `src/environments/environment.ts`, qui est la configuration de production,
pointe `http://localhost:8000/api/v1` en dur. La valeur est celle du poste de développement :
telle quelle, un build de production ne joindra jamais l'API. À corriger avant le premier
déploiement, en même temps que sera tranchée la question de l'ingress dans
[10-infra.md](10-infra.md).
## Exécution
| Commande | Effet |
|---|---|
| `npm ci` | Installe les dépendances. `node_modules/` n'est pas présent par défaut |
| `npm start` | `ng serve` sur le port 4200, proxy actif |
| `npm run build` | Build de production |
| `npm run test` | Vitest en mode observateur |
| `npm run test:ci` | Vitest en une passe |
Le frontend **n'a pas de cible dans le `Makefile` racine** et **aucun service dans
`docker-compose.yml`** : il se pilote uniquement par `npm`, depuis `apps/frontend`. Le port 4200
n'apparaît dans le compose que comme valeur par défaut d'`APP_CORS_ORIGINS`, côté backend.
Un `Dockerfile` frontend existe sur la branche `feat/pipeline-cd`, mais il est mono-étage et sans
`CMD` : il construit sans rien servir. Le `README.md` de l'application demande un multi-étage
avec un service statique, il reste à écrire.
## Sécurité
- Le frontend ne détient aucun secret : `environment.ts` ne porte qu'une URL.
- L'authentification n'existe pas côté API, donc pas de garde ni d'intercepteur de jeton à ce
stade. `core/guards` et `core/interceptors` sont prévus pour cela.
## Tests
Conventions et gabarits : [`apps/frontend/TESTING.md`](../../apps/frontend/TESTING.md).
## Questions ouvertes
- **Quelle bibliothèque de graphiques** pour les séries temporelles, et si Grafana en couvre déjà
une partie du besoin.
- **Gestion d'état** : signaux seuls, ou une bibliothèque dédiée.
- **Comment `apiUrl` est injecté en production** : build par environnement, ou configuration lue
au démarrage.
+143
View File
@@ -0,0 +1,143 @@
# Données
PostgreSQL 17 avec l'extension TimescaleDB. Le choix, ses alternatives et ses conséquences sont
dans l'[ADR 0001](../adr/0001-postgresql-timescaledb.md), qui fait foi. Ce document décrit le
système qui en découle.
## Avertissement
**Aucune table applicative n'existe à ce jour.** `Base.metadata` est vide, `app/models/` ne
contient qu'un commentaire, l'unique révision Alembic ne crée aucune table, et aucune hypertable
n'a été déclarée. Tout ce qui suit sous le statut `Cible` est une proposition de structure, pas un
relevé du code. Le modèle sera arrêté au jalon J2.
## Trois emplacements, trois rôles
C'est la règle que l'ADR 0001 existe surtout pour fixer. La confondre coûte cher : un script placé
au mauvais endroit ne s'exécute jamais, ou s'exécute deux fois.
| Emplacement | Contenu | Quand ça s'exécute |
|---|---|---|
| `db/init/` | Extensions, bases annexes | **Une seule fois**, à la première initialisation du conteneur, quand `PGDATA` est vide. Ne rejoue jamais |
| `db/migrations/` | SQL versionné qui ne découle pas du schéma applicatif : rétention, compression | À la main, aujourd'hui vide |
| `apps/backend/alembic/` | Le schéma exposé par l'API, et lui seul | `alembic upgrade head`, c'est `Base.metadata` qui fait foi |
Une hypertable relève des deux derniers : **Alembic crée la table, et le `create_hypertable()`
vit dans la même révision**. Les séparer rendrait le schéma irreproductible depuis un seul
`alembic upgrade head`.
Détail de `db/init/` et du piège de montage : [`db/README.md`](../../db/README.md).
## Ce qui existe
Statut : `Fait`.
- `db/init/100-extensions.sql` crée l'extension `timescaledb`.
- `db/init/110-test-database.sql` crée `enervision_test`, dont le nom est attendu en dur par
`apps/backend/tests/conftest.py`.
- Une révision Alembic, `5353c0e4f094`, qui **ne crée aucune table**. Elle établit
`alembic_version` et refuse de s'appliquer si l'extension manque :
```sql
IF NOT EXISTS (SELECT 1 FROM pg_extension WHERE extname = 'timescaledb') THEN
RAISE EXCEPTION 'extension timescaledb absente, voir db/init et db/README.md';
END IF;
```
Cette garde forme paire avec le 503 de `/api/v1/health/ready`. Un bootstrap sauté ne se voit pas
au démarrage de l'API : ces deux gardes le rendent visible tôt, des deux côtés.
## Cycle de vie d'une mesure
Statut : `Cible`. Aucun de ces maillons n'existe.
```mermaid
flowchart LR
src["Source de mesures"] -.-> ing["Ingestion Airflow"]
ing -.-> hy[("Hypertable mesure")]
hy -.-> agg[("Agrégat continu")]
hy -.-> comp["Compression"]
hy -.-> ret["Rétention"]
agg -.-> api["API FastAPI"]
agg -.-> graf["Grafana"]
```
Les lectures de l'API et de Grafana visent l'agrégat continu, pas la table brute : c'est tout
l'intérêt de TimescaleDB, et cela doit rester vrai quand les volumes augmenteront.
## Modèle
Statut : `Cible`. Les entités ci-dessous sont des **candidates**, à valider en J2. Elles
s'appuient sur les gabarits de [`apps/backend/TESTING.md`](../../apps/backend/TESTING.md), qui
évoquent déjà un modèle `Site`, un `SiteRepository` et un `ConsumptionService` exposant un
`total_kwh(site_id)`.
```mermaid
erDiagram
SITE ||--o{ POINT_DE_MESURE : porte
POINT_DE_MESURE ||--o{ MESURE : produit
SITE {
int id PK
string nom
}
POINT_DE_MESURE {
int id PK
int site_id FK
string libelle
string unite
}
MESURE {
timestamptz horodatage PK
int point_id PK
double valeur
}
```
`MESURE` est la table destinée à devenir une hypertable, partitionnée sur `horodatage`. Sa clé
primaire doit inclure la colonne de temps : TimescaleDB l'exige, une clé sur le seul identifiant
de point serait refusée.
## Gabarit de révision créant une hypertable
Conforme à la règle de l'ADR 0001 : table et hypertable dans la même révision.
```python
def upgrade() -> None:
op.create_table(
"mesure",
sa.Column("horodatage", sa.DateTime(timezone=True), nullable=False),
sa.Column("point_id", sa.Integer(), sa.ForeignKey("point_de_mesure.id"), nullable=False),
sa.Column("valeur", sa.Float(), nullable=False),
sa.PrimaryKeyConstraint("horodatage", "point_id"),
)
op.execute("SELECT create_hypertable('mesure', by_range('horodatage'))")
def downgrade() -> None:
op.drop_table("mesure")
```
`drop_table` suffit au retour arrière : supprimer la table supprime l'hypertable et ses partitions.
## Conventions
- **Noms au singulier**, en minuscules, sans préfixe de table.
- **Toute colonne de temps en `timestamptz`.** Jamais de `timestamp` nu : une mesure sans fuseau
devient ininterprétable dès le premier changement d'heure.
- **La colonne de partitionnement s'appelle `horodatage`** et entre dans la clé primaire.
- **Les politiques de rétention et de compression** vont dans `db/migrations/`, pas dans Alembic :
elles ne découlent pas du schéma applicatif.
- **Tout modèle doit être importé dans `app/models/__init__.py`**, sans quoi
`alembic revision --autogenerate` ne le voit pas et génère un `drop` de sa table.
## Questions ouvertes
Elles relèvent du jalon J2, « valider le périmètre retenu », et bloquent le modèle définitif.
- **Quelles sources de mesures**, et selon quel protocole elles sont collectées.
- **Quelle granularité** à l'ingestion : la seconde, la minute, le quart d'heure.
- **Quels agrégats continus**, et sur quelles fenêtres.
- **Quelle profondeur de rétention** en données brutes, et à partir de quand on compresse.
- **Quelles unités** sont manipulées, et si une même table les mélange.
- **Multi-tenant ou non** : un site appartient-il à un client, et faut-il cloisonner les lectures.
+58
View File
@@ -0,0 +1,58 @@
# Architecture
Les vues d'architecture d'EnerVision. Un ADR (`../adr/`) **décide** et date une décision
structurante ; une vue d'architecture **décrit** le système qui en résulte. Quand les deux se
contredisent, c'est l'ADR qui fait foi et la vue qui est en retard.
## Les documents
| Document | Ce qu'il couvre |
|---|---|
| [00-vue-ensemble.md](00-vue-ensemble.md) | Jalons du projet, contexte, conteneurs, sécurité, flux bout en bout |
| [10-infra.md](10-infra.md) | Poste de développement, cible k3s, décisions figées, ports et noms |
| [20-backend.md](20-backend.md) | Couches FastAPI, séquence de démarrage, routes, configuration |
| [30-frontend.md](30-frontend.md) | Angular, arborescence cible, flux HTTP |
| [40-data.md](40-data.md) | Frontières `db/` et `alembic/`, cycle de vie d'une mesure, modèle |
L'observabilité, la sécurité et la CI/CD n'ont pas de document propre : ce sont des sections des
cinq ci-dessus, tant que `monitoring/`, `.github/workflows/` et `etl/airflow/` ne contiennent que
des `.gitkeep`. Elles en sortiront le jour où elles auront de la matière. Un fichier vide de plus
n'aide personne.
## Conventions
### Mermaid, et rien d'autre
GitHub rend Mermaid nativement dans les fichiers `.md`. Un diagramme est donc du texte : il se
relit en revue, il se diffe, et il ne se périme pas dans un binaire que plus personne ne sait
rouvrir six mois plus tard. Aucune image exportée, aucun `.drawio`, aucun `.png`.
### Chaque section porte son statut
Une large part de la stack n'est pas écrite. Une vue qui mélange l'existant et la cible sans le
dire devient fausse sans prévenir.
| Statut | Sens |
|---|---|
| `Fait` | Le code existe et tourne |
| `En cours` | Commencé, incomplet |
| `Cible` | Décidé, pas encore écrit |
### Légende des diagrammes
Trait plein pour ce qui tourne, trait pointillé pour ce qui est cible.
```mermaid
flowchart LR
A[Composant en place] --> B[Composant en place]
B -.-> C[Composant cible]
```
## Maintenance
**Toute PR qui change un composant met à jour sa vue dans la même PR.** Une vue qu'on promet de
mettre à jour plus tard ne l'est jamais.
Une documentation fausse coûte plus cher qu'une documentation absente : on la lit, on la croit, et
on construit dessus. Si une section ne peut plus être tenue à jour, elle est supprimée plutôt que
laissée à dériver.
+17 -1
View File
@@ -1,6 +1,22 @@
# Infrastructure # Infrastructure
Provisionnement Terraform de la machine on-premise. Non initialise, voir le ticket dedie. Provisionnement Terraform de la machine on-premise (serveur physique, accessible en SSH).
- `terraform/modules` : modules reutilisables. - `terraform/modules` : modules reutilisables.
- `k3s` : installe un cluster k3s single-node sur une machine distante via SSH
(script officiel `get.k3s.io`) et rapatrie le kubeconfig en local.
- `terraform/environments/<env>` : racines Terraform, une par environnement. - `terraform/environments/<env>` : racines Terraform, une par environnement.
- `dev` : instancie le module `k3s` sur le serveur de l'ecole.
- `prod` : non initialise, voir le ticket dedie.
## Usage (environments/dev)
```bash
cd infra/terraform/environments/dev
cp terraform.tfvars.example terraform.tfvars # renseigner ssh_host / ssh_private_key_path
terraform init
terraform apply
```
Le kubeconfig est ecrit localement au chemin defini par `kubeconfig_output_path`
(par defaut `./kubeconfig`, ignore par git).
+11
View File
@@ -0,0 +1,11 @@
module "k3s" {
source = "../../modules/k3s"
ssh_host = var.ssh_host
ssh_port = var.ssh_port
ssh_user = var.ssh_user
ssh_private_key_path = var.ssh_private_key_path
k3s_version = var.k3s_version
k3s_disable_components = var.k3s_disable_components
kubeconfig_output_path = var.kubeconfig_output_path
}
@@ -0,0 +1,9 @@
output "kubeconfig_path" {
description = "Chemin local du kubeconfig recupere apres installation."
value = module.k3s.kubeconfig_path
}
output "node_host" {
description = "Adresse du serveur sur lequel k3s est installe."
value = module.k3s.node_host
}
@@ -0,0 +1,8 @@
ssh_host = "10.0.0.10"
ssh_port = 22
ssh_user = "root"
ssh_private_key_path = "~/.ssh/id_ed25519_enervision"
# Epingler une version reelle avant apply : https://github.com/k3s-io/k3s/releases
k3s_version = "v1.31.5+k3s1"
k3s_disable_components = ["traefik"]
kubeconfig_output_path = "./kubeconfig"
@@ -0,0 +1,39 @@
variable "ssh_host" {
type = string
description = "Adresse IP ou nom d'hote du serveur on-premise de l'ecole."
}
variable "ssh_port" {
type = number
description = "Port SSH du serveur."
default = 22
}
variable "ssh_user" {
type = string
description = "Utilisateur SSH utilise pour l'installation."
default = "root"
}
variable "ssh_private_key_path" {
type = string
description = "Chemin local vers la cle privee SSH."
sensitive = true
}
variable "k3s_version" {
type = string
description = "Version k3s a epingler pour un deploiement reproductible (ex: v1.31.5+k3s1). Voir https://github.com/k3s-io/k3s/releases."
}
variable "k3s_disable_components" {
type = list(string)
description = "Composants embarques k3s a desactiver."
default = ["traefik"]
}
variable "kubeconfig_output_path" {
type = string
description = "Chemin local ou ecrire le kubeconfig recupere apres installation."
default = "./kubeconfig"
}
@@ -0,0 +1,14 @@
terraform {
required_version = ">= 1.7"
required_providers {
null = {
source = "hashicorp/null"
version = "~> 3.2"
}
}
backend "local" {
path = "terraform.tfstate"
}
}
View File
+55
View File
@@ -0,0 +1,55 @@
locals {
sudo_prefix = var.ssh_user == "root" ? "" : "sudo "
install_env = "INSTALL_K3S_VERSION=${var.k3s_version} "
disable_flags = join(" ", [for c in var.k3s_disable_components : "--disable=${c}"])
kubeconfig_cmd = "${local.sudo_prefix}cat /etc/rancher/k3s/k3s.yaml"
}
resource "null_resource" "k3s_install" {
triggers = {
ssh_host = var.ssh_host
k3s_version = var.k3s_version
disable_components = join(",", var.k3s_disable_components)
}
connection {
type = "ssh"
host = var.ssh_host
port = var.ssh_port
user = var.ssh_user
private_key = file(var.ssh_private_key_path)
}
provisioner "remote-exec" {
inline = [
"${local.sudo_prefix}sh -c 'curl -sfL https://get.k3s.io | ${local.install_env}sh -s - server ${local.disable_flags}'",
"until ${local.sudo_prefix}test -f /etc/rancher/k3s/k3s.yaml; do sleep 2; done",
]
}
# Le kubeconfig est lu via sudo (fetch_kubeconfig), pas besoin de --write-kubeconfig-mode :
# il reste 600/root par defaut, ce qui evite d'exposer les droits cluster-admin a tout utilisateur local.
provisioner "remote-exec" {
when = destroy
on_failure = continue
inline = [
"${local.sudo_prefix}sh -c 'test -x /usr/local/bin/k3s-uninstall.sh && /usr/local/bin/k3s-uninstall.sh || true'",
]
}
}
resource "null_resource" "fetch_kubeconfig" {
depends_on = [null_resource.k3s_install]
triggers = {
install_id = null_resource.k3s_install.id
}
provisioner "local-exec" {
interpreter = ["bash", "-c"]
command = <<-EOT
ssh -i "${var.ssh_private_key_path}" -p ${var.ssh_port} -o StrictHostKeyChecking=accept-new ${var.ssh_user}@${var.ssh_host} '${local.kubeconfig_cmd}' \
| sed 's/127.0.0.1/${var.ssh_host}/' > "${var.kubeconfig_output_path}"
EOT
}
}
+9
View File
@@ -0,0 +1,9 @@
output "kubeconfig_path" {
description = "Chemin local du kubeconfig recupere apres installation."
value = var.kubeconfig_output_path
}
output "node_host" {
description = "Adresse de la machine sur laquelle k3s est installe."
value = var.ssh_host
}
+43
View File
@@ -0,0 +1,43 @@
variable "ssh_host" {
type = string
description = "Adresse IP ou nom d'hote de la machine on-premise cible."
}
variable "ssh_port" {
type = number
description = "Port SSH de la machine cible."
default = 22
}
variable "ssh_user" {
type = string
description = "Utilisateur SSH. Si different de root, les commandes d'installation sont prefixees par sudo."
default = "root"
}
variable "ssh_private_key_path" {
type = string
description = "Chemin local vers la cle privee SSH utilisee pour se connecter a la machine cible."
sensitive = true
}
variable "k3s_version" {
type = string
description = "Version k3s a epingler pour un deploiement reproductible (ex: v1.31.5+k3s1). Voir https://github.com/k3s-io/k3s/releases."
validation {
condition = length(trimspace(var.k3s_version)) > 0
error_message = "k3s_version doit etre epinglee explicitement, pas de valeur vide (sinon k3s.io installerait la derniere version a chaque run, non reproductible)."
}
}
variable "k3s_disable_components" {
type = list(string)
description = "Composants embarques a desactiver a l'installation (ex: traefik, servicelb)."
default = ["traefik"]
}
variable "kubeconfig_output_path" {
type = string
description = "Chemin local ou ecrire le kubeconfig recupere apres installation."
}
+10
View File
@@ -0,0 +1,10 @@
terraform {
required_version = ">= 1.7"
required_providers {
null = {
source = "hashicorp/null"
version = "~> 3.2"
}
}
}
-19
View File
@@ -1,19 +0,0 @@
# Provider Docker
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 3.0"
}
}
}
provider "docker" {
host = "unix:///var/run/docker.sock"
}
# Image Docker
resource "docker_image" "python" {
name = "python:3.14.7"
keep_locally = true
}
-1
View File
@@ -1 +0,0 @@
coucou