File size: 5,460 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
from typing import Dict, List, Optional, Union
from typing_extensions import Literal

from phi.k8s.create.core.v1.container import CreateContainer
from phi.k8s.create.core.v1.volume import CreateVolume
from phi.k8s.create.base import CreateK8sResource
from phi.k8s.enums.api_version import ApiVersion
from phi.k8s.enums.kind import Kind
from phi.k8s.enums.restart_policy import RestartPolicy
from phi.k8s.resource.apps.v1.deployment import (
    Deployment,
    DeploymentSpec,
    LabelSelector,
    PodTemplateSpec,
)
from phi.k8s.resource.core.v1.container import Container
from phi.k8s.resource.core.v1.pod_spec import PodSpec
from phi.k8s.resource.core.v1.volume import Volume
from phi.k8s.resource.core.v1.topology_spread_constraints import (
    TopologySpreadConstraint,
)
from phi.k8s.create.common.labels import create_component_labels_dict
from phi.k8s.resource.meta.v1.object_meta import ObjectMeta


class CreateDeployment(CreateK8sResource):
    deploy_name: str
    pod_name: str
    app_name: str
    namespace: Optional[str] = None
    service_account_name: Optional[str] = None
    replicas: Optional[int] = 1
    containers: List[CreateContainer]
    init_containers: Optional[List[CreateContainer]] = None
    pod_node_selector: Optional[Dict[str, str]] = None
    restart_policy: RestartPolicy = RestartPolicy.ALWAYS
    termination_grace_period_seconds: Optional[int] = None
    volumes: Optional[List[CreateVolume]] = None
    labels: Optional[Dict[str, str]] = None
    pod_annotations: Optional[Dict[str, str]] = None
    topology_spread_key: Optional[str] = None
    topology_spread_max_skew: Optional[int] = None
    topology_spread_when_unsatisfiable: Optional[Union[str, Literal["DoNotSchedule", "ScheduleAnyway"]]] = None
    # If True, recreate the resource on update
    # Used for deployments with EBS volumes
    recreate_on_update: bool = False

    def _create(self) -> Deployment:
        """Creates the Deployment resource"""

        deploy_name = self.deploy_name
        # logger.debug(f"Init Deployment resource: {deploy_name}")

        deploy_labels = create_component_labels_dict(
            component_name=deploy_name,
            app_name=self.app_name,
            labels=self.labels,
        )

        pod_name = self.pod_name
        pod_labels = create_component_labels_dict(
            component_name=pod_name,
            app_name=self.app_name,
            labels=self.labels,
        )

        containers: List[Container] = []
        for cc in self.containers:
            container = cc.create()
            if container is not None and isinstance(container, Container):
                containers.append(container)

        init_containers: Optional[List[Container]] = None
        if self.init_containers is not None:
            init_containers = []
            for ic in self.init_containers:
                _init_container = ic.create()
                if _init_container is not None and isinstance(_init_container, Container):
                    init_containers.append(_init_container)

        topology_spread_constraints: Optional[List[TopologySpreadConstraint]] = None
        if self.topology_spread_key is not None:
            topology_spread_constraints = [
                TopologySpreadConstraint(
                    topology_key=self.topology_spread_key,
                    max_skew=self.topology_spread_max_skew,
                    when_unsatisfiable=self.topology_spread_when_unsatisfiable,
                    label_selector=LabelSelector(match_labels=pod_labels),
                )
            ]

        volumes: Optional[List[Volume]] = None
        if self.volumes:
            volumes = []
            for cv in self.volumes:
                volume = cv.create()
                if volume and isinstance(volume, Volume):
                    volumes.append(volume)

        deployment = Deployment(
            name=deploy_name,
            api_version=ApiVersion.APPS_V1,
            kind=Kind.DEPLOYMENT,
            metadata=ObjectMeta(
                name=deploy_name,
                namespace=self.namespace,
                labels=deploy_labels,
            ),
            spec=DeploymentSpec(
                replicas=self.replicas,
                selector=LabelSelector(match_labels=pod_labels),
                template=PodTemplateSpec(
                    # TODO: fix this
                    metadata=ObjectMeta(
                        name=pod_name,
                        namespace=self.namespace,
                        labels=pod_labels,
                        annotations=self.pod_annotations,
                    ),
                    spec=PodSpec(
                        init_containers=init_containers,
                        node_selector=self.pod_node_selector,
                        service_account_name=self.service_account_name,
                        restart_policy=self.restart_policy,
                        containers=containers,
                        termination_grace_period_seconds=self.termination_grace_period_seconds,
                        topology_spread_constraints=topology_spread_constraints,
                        volumes=volumes,
                    ),
                ),
            ),
            recreate_on_update=self.recreate_on_update,
        )

        # logger.debug(
        #     f"Deployment {deploy_name}:\n{deployment.json(exclude_defaults=True, indent=2)}"
        # )
        return deployment