base-deployment-controller 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,174 @@
1
+ """
2
+ Environment variables routes implemented with a class and dependency injection.
3
+ """
4
+ import logging
5
+
6
+ from fastapi import APIRouter, HTTPException
7
+
8
+ from ..models.environment import (
9
+ EnvVariable,
10
+ EnvVariablesResponse,
11
+ BulkEnvUpdateRequest,
12
+ EnvUpdateResponse,
13
+ )
14
+ from ..services.config import ConfigService
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ class EnvRoutes:
20
+ """
21
+ Environment variables router built with dependency injection.
22
+
23
+ Provides endpoints for retrieving and updating environment variables
24
+ defined in the compose.yaml x-env-vars schema.
25
+
26
+ Args:
27
+ config: Instance of `ConfigService` for file access and validation.
28
+
29
+ Attributes:
30
+ config: Injected configuration service.
31
+ router: Instance of `APIRouter` with `/envs` endpoints.
32
+ """
33
+
34
+ def __init__(self, config: ConfigService) -> None:
35
+ """
36
+ Initialize environment routes.
37
+
38
+ Args:
39
+ config: Configuration service instance for dependency injection.
40
+ """
41
+ self.config = config
42
+ self.router = self._build_router()
43
+
44
+ def _build_router(self) -> APIRouter:
45
+ """
46
+ Build and configure the router with environment variable endpoints.
47
+
48
+ Returns:
49
+ APIRouter configured with GET and PUT handlers for /envs.
50
+ """
51
+ router = APIRouter(prefix="/envs", tags=["Environment Variables"])
52
+ router.add_api_route(
53
+ "",
54
+ self.get_environment_variables,
55
+ methods=["GET"],
56
+ response_model=EnvVariablesResponse,
57
+ )
58
+ router.add_api_route(
59
+ "",
60
+ self.update_environment_variables,
61
+ methods=["PUT"],
62
+ response_model=EnvUpdateResponse,
63
+ )
64
+ return router
65
+
66
+ async def get_environment_variables(self) -> EnvVariablesResponse:
67
+ """
68
+ Get all environment variables with their metadata and current values.
69
+
70
+ Combines schema from x-env-vars in compose.yaml with current values from .env file.
71
+
72
+ Returns:
73
+ EnvVariablesResponse with list of all variables.
74
+
75
+ Raises:
76
+ HTTPException: If unable to load environment variables.
77
+ """
78
+ try:
79
+ logger.debug("Fetching environment variables schema and current values")
80
+ schema = self.config.get_env_vars_schema()
81
+ current_values = self.config.load_env_values()
82
+ variables = []
83
+ for var_name, var_schema in schema.items():
84
+ default_val = var_schema.get("default", "")
85
+ current_val = current_values.get(var_name)
86
+ value = current_val if current_val is not None else default_val
87
+ variables.append(
88
+ EnvVariable(
89
+ name=var_name,
90
+ description=var_schema.get("description", ""),
91
+ default=default_val,
92
+ value=value,
93
+ type=var_schema.get("type", "string"),
94
+ advanced=var_schema.get("advanced", False),
95
+ )
96
+ )
97
+ logger.info(f"Successfully fetched {len(variables)} environment variables")
98
+ return EnvVariablesResponse(variables=variables)
99
+ except Exception as e:
100
+ logger.error(f"Failed to load environment variables: {e}")
101
+ raise HTTPException(
102
+ status_code=500, detail=f"Failed to load environment variables: {e}"
103
+ )
104
+
105
+ async def update_environment_variables(
106
+ self, request: BulkEnvUpdateRequest
107
+ ) -> EnvUpdateResponse:
108
+ """
109
+ Update environment variables in .env file.
110
+
111
+ Args:
112
+ request: Bulk update request.
113
+
114
+ Returns:
115
+ EnvUpdateResponse with list of updated variables and restart results.
116
+
117
+ Raises:
118
+ HTTPException: If validation fails or variables cannot be updated.
119
+ """
120
+ try:
121
+ schema = self.config.get_env_vars_schema()
122
+ updates = request.variables
123
+ logger.debug(
124
+ "Bulk environment update request with %d variables", len(updates)
125
+ )
126
+ for var_name, var_value in updates.items():
127
+ if var_name not in schema:
128
+ logger.warning(f"Attempted to add unknown variable: {var_name}")
129
+ raise HTTPException(
130
+ status_code=400,
131
+ detail=f"Variable '{var_name}' not found in schema. Cannot add new variables.",
132
+ )
133
+ var_schema = schema[var_name]
134
+ try:
135
+ self.config.validate_variable_value(
136
+ var_name, var_value, var_schema["type"]
137
+ )
138
+ logger.debug(f"Validated variable {var_name} with value: {var_value}")
139
+ except ValueError as e:
140
+ logger.warning(f"Validation failed for {var_name}: {e}")
141
+ raise HTTPException(status_code=400, detail=str(e))
142
+ logger.info(f"Updating {len(updates)} environment variables")
143
+ self.config.update_env_file(updates)
144
+
145
+ # Restart affected services
146
+ affected_services = self.config.get_affected_services(list(updates.keys()))
147
+ logger.debug(f"Affected services: {affected_services}")
148
+ restart_results: dict[str, bool] = {}
149
+ if request.restart_services:
150
+ restart_results = self.config.restart_services(affected_services)
151
+ logger.info(
152
+ "Successfully updated %d variables. Restart results: %s",
153
+ len(updates),
154
+ restart_results,
155
+ )
156
+ else:
157
+ logger.info(
158
+ "Successfully updated %d variables. Restart skipped by request",
159
+ len(updates),
160
+ )
161
+
162
+ return EnvUpdateResponse(
163
+ success=True,
164
+ updated=list(updates.keys()),
165
+ message="Variables updated successfully",
166
+ restarted_services=restart_results,
167
+ )
168
+ except HTTPException:
169
+ raise
170
+ except Exception as e:
171
+ logger.error(f"Failed to update variables: {e}")
172
+ raise HTTPException(
173
+ status_code=500, detail=f"Failed to update variables: {e}"
174
+ )
@@ -0,0 +1,5 @@
1
+ """Service layer for configuration and Docker interactions."""
2
+
3
+ from .config import ConfigService
4
+
5
+ __all__ = ["ConfigService"]