File size: 8,418 Bytes
105b369
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
from pathlib import Path
from typing import Optional, List, Dict

from pydantic import field_validator, ValidationInfo
from pydantic_settings import BaseSettings, SettingsConfigDict

from phi.api.schemas.workspace import WorkspaceSchema


class WorkspaceSettings(BaseSettings):
    """
    -*- Workspace settings
    Initialize workspace settings by:
    1. Creating a WorkspaceSettings object
    2. Using Environment variables
    3. Using the .env file
    """

    # Workspace name: used for naming cloud resources
    ws_name: str
    # Path to the workspace root
    ws_root: Path
    # Workspace git repo url: used to git-sync DAGs and Charts
    ws_repo: Optional[str] = None
    # Path to important directories relative to the ws_root
    scripts_dir: str = "scripts"
    storage_dir: str = "storage"
    workflows_dir: str = "workflows"
    workspace_dir: str = "workspace"
    # default env for phi ws commands
    default_env: Optional[str] = "dev"
    # default infra for phi ws commands
    default_infra: Optional[str] = None
    #
    # -*- Image Settings
    #
    # Repository for images
    image_repo: str = "phidata"
    # Name:tag for the image
    image_name: Optional[str] = None
    # Build images locally
    build_images: bool = False
    # Push images after building
    push_images: bool = False
    # Skip cache when building images
    skip_image_cache: bool = False
    # Force pull images in FROM
    force_pull_images: bool = False
    #
    # -*- Dev settings
    #
    dev_env: str = "dev"
    # Dev git repo branch: used to git-sync DAGs and Charts
    dev_branch: str = "main"
    # Key for naming dev resources
    dev_key: Optional[str] = None
    # Tags for dev resources
    dev_tags: Optional[Dict[str, str]] = None
    # Domain for the dev platform
    dev_domain: Optional[str] = None
    #
    # -*- Dev Apps
    #
    dev_airflow_enabled: bool = False
    dev_api_enabled: bool = False
    dev_app_enabled: bool = False
    dev_db_enabled: bool = False
    dev_jupyter_enabled: bool = False
    dev_redis_enabled: bool = False
    dev_superset_enabled: bool = False
    dev_traefik_enabled: bool = False
    dev_qdrant_enabled: bool = False
    #
    # -*- Staging settings
    #
    stg_env: str = "stg"
    # Staging git repo branch: used to git-sync DAGs and Charts
    stg_branch: str = "main"
    # Key for naming staging resources
    stg_key: Optional[str] = None
    # Tags for staging resources
    stg_tags: Optional[Dict[str, str]] = None
    # Domain for the staging platform
    stg_domain: Optional[str] = None
    #
    # -*- Staging Apps
    #
    stg_airflow_enabled: bool = False
    stg_api_enabled: bool = False
    stg_app_enabled: bool = False
    stg_db_enabled: bool = False
    stg_jupyter_enabled: bool = False
    stg_redis_enabled: bool = False
    stg_superset_enabled: bool = False
    stg_traefik_enabled: bool = False
    stg_whoami_enabled: bool = False
    #
    # -*- Production settings
    #
    prd_env: str = "prd"
    # Production git repo branch: used to git-sync DAGs and Charts
    prd_branch: str = "main"
    # Key for naming production resources
    prd_key: Optional[str] = None
    # Tags for production resources
    prd_tags: Optional[Dict[str, str]] = None
    # Domain for the production platform
    prd_domain: Optional[str] = None
    #
    # -*- Production Apps
    #
    prd_airflow_enabled: bool = False
    prd_api_enabled: bool = False
    prd_app_enabled: bool = False
    prd_db_enabled: bool = False
    prd_jupyter_enabled: bool = False
    prd_redis_enabled: bool = False
    prd_superset_enabled: bool = False
    prd_traefik_enabled: bool = False
    prd_whoami_enabled: bool = False
    #
    # -*- AWS settings
    #
    # Region for AWS resources
    aws_region: Optional[str] = None
    # Availability Zones for AWS resources
    aws_az1: Optional[str] = None
    aws_az2: Optional[str] = None
    aws_az3: Optional[str] = None
    aws_az4: Optional[str] = None
    aws_az5: Optional[str] = None
    # Public subnets. 1 in each AZ.
    public_subnets: List[str] = []
    # Private subnets. 1 in each AZ.
    private_subnets: List[str] = []
    # Subnet IDs. 1 in each AZ.
    # Derived from public and private subnets if not provided.
    subnet_ids: Optional[List[str]] = None
    # Security Groups
    security_groups: Optional[List[str]] = None
    aws_profile: Optional[str] = None
    aws_config_file: Optional[str] = None
    aws_shared_credentials_file: Optional[str] = None
    # -*- Cli settings
    # Set to True if `phi` should continue creating
    # resources after a resource creation has failed
    continue_on_create_failure: bool = False
    # Set to True if `phi` should continue deleting
    # resources after a resource deleting has failed
    # Defaults to True because we normally want to continue deleting
    continue_on_delete_failure: bool = True
    # Set to True if `phi` should continue patching
    # resources after a resource patch has failed
    continue_on_patch_failure: bool = False
    #
    # -*- Other Settings
    #
    use_cache: bool = True
    # WorkspaceSchema provided by the api
    ws_schema: Optional[WorkspaceSchema] = None

    model_config = SettingsConfigDict(extra="allow")

    @field_validator("dev_key", mode="before")
    def set_dev_key(cls, dev_key, info: ValidationInfo):
        if dev_key is not None:
            return dev_key

        ws_name = info.data.get("ws_name")
        if ws_name is None:
            raise ValueError("ws_name invalid")

        dev_env = info.data.get("dev_env")
        if dev_env is None:
            raise ValueError("dev_env invalid")

        return f"{ws_name}-{dev_env}"

    @field_validator("dev_tags", mode="before")
    def set_dev_tags(cls, dev_tags, info: ValidationInfo):
        if dev_tags is not None:
            return dev_tags

        ws_name = info.data.get("ws_name")
        if ws_name is None:
            raise ValueError("ws_name invalid")

        dev_env = info.data.get("dev_env")
        if dev_env is None:
            raise ValueError("dev_env invalid")

        return {
            "Env": dev_env,
            "Project": ws_name,
        }

    @field_validator("stg_key", mode="before")
    def set_stg_key(cls, stg_key, info: ValidationInfo):
        if stg_key is not None:
            return stg_key

        ws_name = info.data.get("ws_name")
        if ws_name is None:
            raise ValueError("ws_name invalid")

        stg_env = info.data.get("stg_env")
        if stg_env is None:
            raise ValueError("stg_env invalid")

        return f"{ws_name}-{stg_env}"

    @field_validator("stg_tags", mode="before")
    def set_stg_tags(cls, stg_tags, info: ValidationInfo):
        if stg_tags is not None:
            return stg_tags

        ws_name = info.data.get("ws_name")
        if ws_name is None:
            raise ValueError("ws_name invalid")

        stg_env = info.data.get("stg_env")
        if stg_env is None:
            raise ValueError("stg_env invalid")

        return {
            "Env": stg_env,
            "Project": ws_name,
        }

    @field_validator("prd_key", mode="before")
    def set_prd_key(cls, prd_key, info: ValidationInfo):
        if prd_key is not None:
            return prd_key

        ws_name = info.data.get("ws_name")
        if ws_name is None:
            raise ValueError("ws_name invalid")

        prd_env = info.data.get("prd_env")
        if prd_env is None:
            raise ValueError("prd_env invalid")

        return f"{ws_name}-{prd_env}"

    @field_validator("prd_tags", mode="before")
    def set_prd_tags(cls, prd_tags, info: ValidationInfo):
        if prd_tags is not None:
            return prd_tags

        ws_name = info.data.get("ws_name")
        if ws_name is None:
            raise ValueError("ws_name invalid")

        prd_env = info.data.get("prd_env")
        if prd_env is None:
            raise ValueError("prd_env invalid")

        return {
            "Env": prd_env,
            "Project": ws_name,
        }

    @field_validator("subnet_ids", mode="before")
    def set_subnet_ids(cls, subnet_ids, info: ValidationInfo):
        if subnet_ids is not None:
            return subnet_ids

        public_subnets = info.data.get("public_subnets", [])
        private_subnets = info.data.get("private_subnets", [])

        return public_subnets + private_subnets