Beispiel #1
1
def create_deployment(project_name: str,
                      images: list,
                      ports: dict = {},
                      envs: dict = {}):
    # parameter : project_name:str, images:list, ports:dict {image_name: port_list}, envs:dict (image_name: env)
    # label name --> project name + etc..
    # readinessProbe .. tcp or http
    # envs --> image_name : env --> env: list of dict ({name: xxx, value: xxx})
    containers = list()
    for image in images:
        name = image.split(":")[0]
        tag = image.split(":")[1]
        container_ports = [client.V1ContainerPort(p) for p in ports[image]
                           ] if ports and ports.get(image) else None
        # print(envs)
        container_envs = [client.V1EnvVar(name=e.get("name"), value=e.get("value")) for e in envs.get(image)]\
            if envs.get(image) else None
        image = REGISTRY_PREFIX + image

        containers.append(
            client.V1Container(
                name=name,
                image=image,
                # ports=container_ports,
                env=container_envs,
                readiness_probe=client.V1Probe(
                    initial_delay_seconds=10,
                    period_seconds=15,
                    tcp_socket=client.V1TCPSocketAction(
                        port=container_ports[0].container_port)),
                image_pull_policy="Always"
                if tag == "latest" else "IfNotPresent"))
    # print(containers)

    project_hash = hashlib.sha256(project_name.encode()).hexdigest()[:16]
    labels = {"identifier": project_hash}
    template = client.V1PodTemplateSpec(
        metadata=client.V1ObjectMeta(labels=labels),
        spec=client.V1PodSpec(containers=containers))

    spec = client.V1DeploymentSpec(
        replicas=1,  # default
        template=template,
        selector={'matchLabels': labels},
    )

    deployment = client.V1Deployment(
        api_version="apps/v1",
        kind="Deployment",
        metadata=client.V1ObjectMeta(name=project_hash + "-deployment"),
        spec=spec)

    v1 = client.AppsV1Api()
    resp = v1.create_namespaced_deployment(body=deployment,
                                           namespace="default")
    # print(resp)
    return resp
Beispiel #2
0
    def _create_deployment(self):
        REPLICAS = 1

        container_port = k8s.V1ContainerPort(name=self.uid[-14:],
                                             container_port=os.getenv(
                                                 "OPENVAS_OMP_PORT", 9390))
        resources = k8s.V1ResourceRequirements(
            limits={
                "cpu": KubernetesDeployer.CONTAINER_USE_CPU_LIMIT,
                "memory": KubernetesDeployer.CONTAINER_USE_MEMORY_LIMIT,
            })
        readiness_probe = k8s.V1Probe(
            _exec=k8s.V1ExecAction(
                command=KubernetesDeployer.OPENVAS_HEALTHCHECK_COMMAND),
            initial_delay_seconds=300,
            period_seconds=30,
        )
        liveness_probe = k8s.V1Probe(
            tcp_socket=k8s.V1TCPSocketAction(
                port=container_port.container_port),
            initial_delay_seconds=180,
            period_seconds=30,
            failure_threshold=3,
            timeout_seconds=5,
        )
        container = k8s.V1Container(
            image=KubernetesDeployer.OPENVAS_CONTAINER_IMAGE,
            name=self.uid,
            image_pull_policy="IfNotPresent",
            ports=[container_port],
            resources=resources,
            readiness_probe=readiness_probe,
            liveness_probe=liveness_probe,
        )
        toleration = k8s.V1Toleration(effect="NoSchedule",
                                      key="Scanners",
                                      operator="Exists")
        pod_spec = k8s.V1PodSpec(containers=[container],
                                 tolerations=[toleration])
        pod_metadata = k8s.V1ObjectMeta(
            name=self.uid,
            labels={"app.kubernetes.io/name": self.uid},
            annotations={
                "cluster-autoscaler.kubernetes.io/safe-to-evict": "false"
            },
        )
        pod_template = k8s.V1PodTemplateSpec(spec=pod_spec,
                                             metadata=pod_metadata)
        selector = k8s.V1LabelSelector(
            match_labels={"app.kubernetes.io/name": self.uid})
        deployment_spec = k8s.V1DeploymentSpec(replicas=REPLICAS,
                                               selector=selector,
                                               template=pod_template)
        deployment_metadata = k8s.V1ObjectMeta(
            name=self.uid, labels={"app.kubernetes.io/name": self.uid})
        deployment = k8s.V1Deployment(spec=deployment_spec,
                                      metadata=deployment_metadata)
        return k8s.AppsV1Api(self.client).create_namespaced_deployment(
            self.namespace, deployment)
Beispiel #3
0
def update_deployment(project_name: str,
                      images: list,
                      ports: dict = {},
                      envs: dict = {},
                      namespace: str = "default"):
    # update deployment image tag
    # image add / replace
    project_hash = hashlib.sha256(project_name.encode()).hexdigest()[:16]
    deployment_name = f"{project_hash}-deployment"
    prev_deployment = describe_deployment(name=deployment_name)

    prev_containers = prev_deployment.spec.template.spec.containers
    # print(prev_containers)
    prev_images = list()
    for prev_container in prev_containers:
        prev_images.append(prev_container.image.replace(REGISTRY_PREFIX, ""))
    prev_image_names = [p.split(":")[0] for p in prev_images]

    add_patch, replace_patch = list(), list()
    for idx, image in enumerate(images):
        # different name
        if image.split(":")[0] not in prev_image_names:
            add_patch.append(image)
            continue
        # different tag or latest
        for i, prev_image in enumerate(prev_images):
            if prev_image.split(":")[0] == image.split(":")[0]:
                replace_patch.append((i, image))
    v1 = client.AppsV1Api()

    for add_p in add_patch:
        new_container = client.V1Container(
            name=add_p.split(":")[0],
            image=REGISTRY_PREFIX + add_p,
            readiness_probe=client.V1Probe(
                initial_delay_seconds=10,
                period_seconds=20,
                tcp_socket=client.V1TCPSocketAction(
                    port=client.V1ContainerPort(8080))))
        # prev_deployment.spec.template.spec.containers.append(new_container)

    for replace_p in replace_patch:
        if replace_p[1].split(':')[1] == 'latest':
            prev_is = prev_deployment.spec.template.spec.containers[
                replace_p[0]].readiness_probe.initial_delay_seconds
            now_is = 10 if prev_is > 10 else 15
            prev_deployment.spec.template.spec.containers[
                replace_p[0]].readiness_probe.initial_delay_seconds = now_is
        else:
            prev_deployment.spec.template.spec.containers[
                replace_p[0]].image = REGISTRY_PREFIX + replace_p[1]
    # print(prev_deployment)
    resp = v1.patch_namespaced_deployment(name=deployment_name,
                                          namespace=namespace,
                                          body=prev_deployment)
    return resp
Beispiel #4
0
 def export_deployment(self):
     # Configureate Pod template container
     container = client.V1Container(
         name=self.dm_name,
         image=self.image,
         ports=[
             client.V1ContainerPort(container_port=int(port))
             for port in self.container_port
         ],
         image_pull_policy='Always',
         env=[
             client.V1EnvVar(name='LANG', value='en_US.UTF-8'),
             client.V1EnvVar(name='LC_ALL', value='en_US.UTF-8')
         ],
         resources=client.V1ResourceRequirements(limits=self.re_limits,
                                                 requests=self.re_requests),
         volume_mounts=[
             client.V1VolumeMount(mount_path='/opt/logs', name='logs')
         ],
         liveness_probe=client.V1Probe(
             initial_delay_seconds=5,
             tcp_socket=client.V1TCPSocketAction(
                 port=int(self.container_port[0]))))
     # Create and configurate a spec section
     secrets = client.V1LocalObjectReference('registrysecret')
     volume = client.V1Volume(
         name='logs',
         host_path=client.V1HostPathVolumeSource(path='/opt/logs'))
     template = client.V1PodTemplateSpec(
         metadata=client.V1ObjectMeta(labels={"project": self.dm_name}),
         spec=client.V1PodSpec(containers=[container],
                               image_pull_secrets=[secrets],
                               volumes=[volume]))
     selector = client.V1LabelSelector(
         match_labels={"project": self.dm_name})
     # Create the specification of deployment
     spec = client.ExtensionsV1beta1DeploymentSpec(replicas=int(
         self.replicas),
                                                   template=template,
                                                   selector=selector,
                                                   min_ready_seconds=3)
     # Instantiate the deployment object
     deployment = client.ExtensionsV1beta1Deployment(
         api_version="extensions/v1beta1",
         kind="Deployment",
         metadata=client.V1ObjectMeta(name=self.dm_name),
         spec=spec)
     return deployment
Beispiel #5
0
 def export_deployment(self):
     # Configureate Pod template container
     volume_mounts = []
     containers = []
     volumes = []
     volume_mounts.append(
         client.V1VolumeMount(mount_path='/docker/logs', name='logs'))
     volumes.append(
         client.V1Volume(name='logs',
                         host_path=client.V1HostPathVolumeSource(
                             path='/opt/logs', type='DirectoryOrCreate')))
     if self.mounts:
         for path in self.mounts:
             volume_mounts.append(
                 client.V1VolumeMount(mount_path=path,
                                      name=self.mounts[path]))
             volumes.append(
                 client.V1Volume(name=self.mounts[path],
                                 host_path=client.V1HostPathVolumeSource(
                                     path=path, type='DirectoryOrCreate')))
     liveness_probe = client.V1Probe(initial_delay_seconds=15,
                                     tcp_socket=client.V1TCPSocketAction(
                                         port=int(self.container_port[0])))
     readiness_probe = client.V1Probe(initial_delay_seconds=15,
                                      tcp_socket=client.V1TCPSocketAction(
                                          port=int(self.container_port[0])))
     if self.healthcheck:
         liveness_probe = client.V1Probe(initial_delay_seconds=15,
                                         http_get=client.V1HTTPGetAction(
                                             path=self.healthcheck,
                                             port=int(
                                                 self.container_port[0])))
         readiness_probe = client.V1Probe(initial_delay_seconds=15,
                                          http_get=client.V1HTTPGetAction(
                                              path=self.healthcheck,
                                              port=int(
                                                  self.container_port[0])))
     Env = [
         client.V1EnvVar(name='LANG', value='en_US.UTF-8'),
         client.V1EnvVar(name='LC_ALL', value='en_US.UTF-8'),
         client.V1EnvVar(name='POD_NAME',
                         value_from=client.V1EnvVarSource(
                             field_ref=client.V1ObjectFieldSelector(
                                 field_path='metadata.name'))),
         client.V1EnvVar(name='POD_IP',
                         value_from=client.V1EnvVarSource(
                             field_ref=client.V1ObjectFieldSelector(
                                 field_path='status.podIP'))),
     ]
     container = client.V1Container(
         name=self.dm_name,
         image=self.image,
         ports=[
             client.V1ContainerPort(container_port=int(port))
             for port in self.container_port
         ],
         image_pull_policy='Always',
         env=Env,
         resources=client.V1ResourceRequirements(limits=self.re_limits,
                                                 requests=self.re_requests),
         volume_mounts=volume_mounts,
         liveness_probe=liveness_probe,
         readiness_probe=readiness_probe)
     containers.append(container)
     if self.sidecar:
         sidecar_container = client.V1Container(
             name='sidecar-%s' % self.dm_name,
             image=self.sidecar,
             image_pull_policy='Always',
             env=Env,
             resources=client.V1ResourceRequirements(
                 limits=self.re_limits, requests=self.re_requests),
             volume_mounts=volume_mounts)
         containers.append(sidecar_container)
     # Create and configurate a spec section
     secrets = client.V1LocalObjectReference('registrysecret')
     template = client.V1PodTemplateSpec(
         metadata=client.V1ObjectMeta(labels={"project": self.dm_name}),
         spec=client.V1PodSpec(
             containers=containers,
             image_pull_secrets=[secrets],
             volumes=volumes,
             affinity=client.V1Affinity(node_affinity=client.V1NodeAffinity(
                 preferred_during_scheduling_ignored_during_execution=[
                     client.V1PreferredSchedulingTerm(
                         preference=client.V1NodeSelectorTerm(
                             match_expressions=[
                                 client.V1NodeSelectorRequirement(
                                     key='project',
                                     operator='In',
                                     values=['moji'])
                             ]),
                         weight=30),
                     client.V1PreferredSchedulingTerm(
                         preference=client.V1NodeSelectorTerm(
                             match_expressions=[
                                 client.V1NodeSelectorRequirement(
                                     key='deploy',
                                     operator='In',
                                     values=[self.dm_name])
                             ]),
                         weight=70)
                 ]))))
     selector = client.V1LabelSelector(
         match_labels={"project": self.dm_name})
     # Create the specification of deployment
     spec = client.ExtensionsV1beta1DeploymentSpec(replicas=int(
         self.replicas),
                                                   template=template,
                                                   selector=selector,
                                                   min_ready_seconds=3)
     # Instantiate the deployment object
     deployment = client.ExtensionsV1beta1Deployment(
         api_version="extensions/v1beta1",
         kind="Deployment",
         metadata=client.V1ObjectMeta(name=self.dm_name),
         spec=spec)
     return deployment
Beispiel #6
0
    def test_sanitize_k8s_container_attribute(self):
        # test cases for implicit type sanitization(conversion)
        op = dsl.ContainerOp(name='echo', image='image', command=['sh', '-c'],
                           arguments=['echo test | tee /tmp/message.txt'],
                           file_outputs={'merged': '/tmp/message.txt'})
        op.container \
                .add_volume_mount(k8s_client.V1VolumeMount(
                    mount_path='/secret/gcp-credentials',
                    name='gcp-credentials')) \
                .add_env_variable(k8s_client.V1EnvVar(
                    name=80,
                    value=80)) \
                .add_env_variable(k8s_client.V1EnvVar(
                    name=80,
                    value_from=k8s_client.V1EnvVarSource(
                        config_map_key_ref=k8s_client.V1ConfigMapKeySelector(key=80, name=8080, optional='False'),
                        field_ref=k8s_client.V1ObjectFieldSelector(api_version=80, field_path=8080),
                        resource_field_ref=k8s_client.V1ResourceFieldSelector(container_name=80, divisor=8080, resource=8888),
                        secret_key_ref=k8s_client.V1SecretKeySelector(key=80, name=8080, optional='False')
                    )
                )) \
                .add_env_from(k8s_client.V1EnvFromSource(
                    config_map_ref=k8s_client.V1ConfigMapEnvSource(name=80, optional='True'),
                    prefix=999
                )) \
                .add_env_from(k8s_client.V1EnvFromSource(
                    secret_ref=k8s_client.V1SecretEnvSource(name=80, optional='True'),
                    prefix=888
                )) \
                .add_volume_mount(k8s_client.V1VolumeMount(
                    mount_path=111,
                    mount_propagation=222,
                    name=333,
                    read_only='False',
                    sub_path=444,
                    sub_path_expr=555
                )) \
                .add_volume_devices(k8s_client.V1VolumeDevice(
                    device_path=111,
                    name=222
                )) \
                .add_port(k8s_client.V1ContainerPort(
                    container_port='8080',
                    host_ip=111,
                    host_port='8888',
                    name=222,
                    protocol=333
                )) \
                .set_security_context(k8s_client.V1SecurityContext(
                    allow_privilege_escalation='True',
                    capabilities=k8s_client.V1Capabilities(add=[11, 22], drop=[33, 44]),
                    privileged='False',
                    proc_mount=111,
                    read_only_root_filesystem='False',
                    run_as_group='222',
                    run_as_non_root='True',
                    run_as_user='******',
                    se_linux_options=k8s_client.V1SELinuxOptions(level=11, role=22, type=33, user=44),
                    windows_options=k8s_client.V1WindowsSecurityContextOptions(
                        gmsa_credential_spec=11, gmsa_credential_spec_name=22)
                )) \
                .set_stdin(stdin='False') \
                .set_stdin_once(stdin_once='False') \
                .set_termination_message_path(termination_message_path=111) \
                .set_tty(tty='False') \
                .set_readiness_probe(readiness_probe=k8s_client.V1Probe(
                    _exec=k8s_client.V1ExecAction(command=[11, 22, 33]),
                    failure_threshold='111',
                    http_get=k8s_client.V1HTTPGetAction(
                        host=11,
                        http_headers=[k8s_client.V1HTTPHeader(name=22, value=33)],
                        path=44,
                        port='55',
                        scheme=66),
                    initial_delay_seconds='222',
                    period_seconds='333',
                    success_threshold='444',
                    tcp_socket=k8s_client.V1TCPSocketAction(host=555, port='666'),
                    timeout_seconds='777'
                )) \
                .set_liveness_probe(liveness_probe=k8s_client.V1Probe(
                    _exec=k8s_client.V1ExecAction(command=[11, 22, 33]),
                    failure_threshold='111',
                    http_get=k8s_client.V1HTTPGetAction(
                        host=11,
                        http_headers=[k8s_client.V1HTTPHeader(name=22, value=33)],
                        path=44,
                        port='55',
                        scheme=66),
                    initial_delay_seconds='222',
                    period_seconds='333',
                    success_threshold='444',
                    tcp_socket=k8s_client.V1TCPSocketAction(host=555, port='666'),
                    timeout_seconds='777'
                )) \
                .set_lifecycle(lifecycle=k8s_client.V1Lifecycle(
                    post_start=k8s_client.V1Handler(
                        _exec=k8s_client.V1ExecAction(command=[11, 22, 33]),
                        http_get=k8s_client.V1HTTPGetAction(
                            host=11,
                            http_headers=[k8s_client.V1HTTPHeader(name=22, value=33)],
                            path=44,
                            port='55',
                            scheme=66),
                        tcp_socket=k8s_client.V1TCPSocketAction(host=555, port='666')
                    ),
                    pre_stop=k8s_client.V1Handler(
                        _exec=k8s_client.V1ExecAction(command=[11, 22, 33]),
                        http_get=k8s_client.V1HTTPGetAction(
                            host=11,
                            http_headers=[k8s_client.V1HTTPHeader(name=22, value=33)],
                            path=44,
                            port='55',
                            scheme=66),
                        tcp_socket=k8s_client.V1TCPSocketAction(host=555, port='666')
                    )
                ))

        sanitize_k8s_object(op.container)

        for e in op.container.env:
            self.assertIsInstance(e.name, str)
            if e.value:
                self.assertIsInstance(e.value, str)
            if e.value_from:
                if e.value_from.config_map_key_ref:
                    self.assertIsInstance(e.value_from.config_map_key_ref.key, str)
                    if e.value_from.config_map_key_ref.name:
                        self.assertIsInstance(e.value_from.config_map_key_ref.name, str)
                    if e.value_from.config_map_key_ref.optional:
                        self.assertIsInstance(e.value_from.config_map_key_ref.optional, bool)
                if e.value_from.field_ref:
                    self.assertIsInstance(e.value_from.field_ref.field_path, str)
                    if e.value_from.field_ref.api_version:
                        self.assertIsInstance(e.value_from.field_ref.api_version, str)
                if e.value_from.resource_field_ref:
                    self.assertIsInstance(e.value_from.resource_field_ref.resource, str)
                    if e.value_from.resource_field_ref.container_name:
                        self.assertIsInstance(e.value_from.resource_field_ref.container_name, str)
                    if e.value_from.resource_field_ref.divisor:
                        self.assertIsInstance(e.value_from.resource_field_ref.divisor, str)
                if e.value_from.secret_key_ref:
                    self.assertIsInstance(e.value_from.secret_key_ref.key, str)
                    if e.value_from.secret_key_ref.name:
                        self.assertIsInstance(e.value_from.secret_key_ref.name, str)
                    if e.value_from.secret_key_ref.optional:
                        self.assertIsInstance(e.value_from.secret_key_ref.optional, bool)

        for e in op.container.env_from:
            if e.prefix:
                self.assertIsInstance(e.prefix, str)
            if e.config_map_ref:
                if e.config_map_ref.name:
                    self.assertIsInstance(e.config_map_ref.name, str)
                if e.config_map_ref.optional:
                    self.assertIsInstance(e.config_map_ref.optional, bool)
            if e.secret_ref:
                if e.secret_ref.name:
                    self.assertIsInstance(e.secret_ref.name, str)
                if e.secret_ref.optional:
                    self.assertIsInstance(e.secret_ref.optional, bool)

        for e in op.container.volume_mounts:
            if e.mount_path:
                self.assertIsInstance(e.mount_path, str)
            if e.mount_propagation:
                self.assertIsInstance(e.mount_propagation, str)
            if e.name:
                self.assertIsInstance(e.name, str)
            if e.read_only:
                self.assertIsInstance(e.read_only, bool)
            if e.sub_path:
                self.assertIsInstance(e.sub_path, str)
            if e.sub_path_expr:
                self.assertIsInstance(e.sub_path_expr, str)

        for e in op.container.volume_devices:
            if e.device_path:
                self.assertIsInstance(e.device_path, str)
            if e.name:
                self.assertIsInstance(e.name, str)

        for e in op.container.ports:
            if e.container_port:
                self.assertIsInstance(e.container_port, int)
            if e.host_ip:
                self.assertIsInstance(e.host_ip, str)
            if e.host_port:
                self.assertIsInstance(e.host_port, int)
            if e.name:
                self.assertIsInstance(e.name, str)
            if e.protocol:
                self.assertIsInstance(e.protocol, str)

        if op.container.security_context:
            e = op.container.security_context
            if e.allow_privilege_escalation:
                self.assertIsInstance(e.allow_privilege_escalation, bool)
            if e.capabilities:
                for a in e.capabilities.add:
                    self.assertIsInstance(a, str)
                for d in e.capabilities.drop:
                    self.assertIsInstance(d, str)
            if e.privileged:
                self.assertIsInstance(e.privileged, bool)
            if e.proc_mount:
                self.assertIsInstance(e.proc_mount, str)
            if e.read_only_root_filesystem:
                self.assertIsInstance(e.read_only_root_filesystem, bool)
            if e.run_as_group:
                self.assertIsInstance(e.run_as_group, int)
            if e.run_as_non_root:
                self.assertIsInstance(e.run_as_non_root, bool)
            if e.run_as_user:
                self.assertIsInstance(e.run_as_user, int)
            if e.se_linux_options:
                if e.se_linux_options.level:
                    self.assertIsInstance(e.se_linux_options.level, str)
                if e.se_linux_options.role:
                    self.assertIsInstance(e.se_linux_options.role, str)
                if e.se_linux_options.type:
                    self.assertIsInstance(e.se_linux_options.type, str)
                if e.se_linux_options.user:
                    self.assertIsInstance(e.se_linux_options.user, str)
            if e.windows_options:
                if e.windows_options.gmsa_credential_spec:
                    self.assertIsInstance(e.windows_options.gmsa_credential_spec, str)
                if e.windows_options.gmsa_credential_spec_name:
                    self.assertIsInstance(e.windows_options.gmsa_credential_spec_name, str)
            
        if op.container.stdin:
            self.assertIsInstance(op.container.stdin, bool)

        if op.container.stdin_once:
            self.assertIsInstance(op.container.stdin_once, bool)
        
        if op.container.termination_message_path:
            self.assertIsInstance(op.container.termination_message_path, str)

        if op.container.tty:
            self.assertIsInstance(op.container.tty, bool)

        for e in [op.container.readiness_probe, op.container.liveness_probe]:
            if e:
                if e._exec:
                    for c in e._exec.command:
                        self.assertIsInstance(c, str)
                if e.failure_threshold:
                    self.assertIsInstance(e.failure_threshold, int)
                if e.http_get:
                    if e.http_get.host:
                        self.assertIsInstance(e.http_get.host, str)
                    if e.http_get.http_headers:
                        for h in e.http_get.http_headers:
                            if h.name:
                                self.assertIsInstance(h.name, str)
                            if h.value:
                                self.assertIsInstance(h.value, str)
                    if e.http_get.path:
                        self.assertIsInstance(e.http_get.path, str)
                    if e.http_get.port:
                        self.assertIsInstance(e.http_get.port, (str, int))
                    if e.http_get.scheme:
                        self.assertIsInstance(e.http_get.scheme, str)
                if e.initial_delay_seconds:
                    self.assertIsInstance(e.initial_delay_seconds, int)
                if e.period_seconds:
                    self.assertIsInstance(e.period_seconds, int)
                if e.success_threshold:
                    self.assertIsInstance(e.success_threshold, int)
                if e.tcp_socket:
                    if e.tcp_socket.host:
                        self.assertIsInstance(e.tcp_socket.host, str)
                    if e.tcp_socket.port:
                        self.assertIsInstance(e.tcp_socket.port, (str, int))
                if e.timeout_seconds:
                    self.assertIsInstance(e.timeout_seconds, int)
        if op.container.lifecycle:
            for e in [op.container.lifecycle.post_start, op.container.lifecycle.pre_stop]:
                if e:
                    if e._exec:
                        for c in e._exec.command:
                            self.assertIsInstance(c, str)
                    if e.http_get:
                        if e.http_get.host:
                            self.assertIsInstance(e.http_get.host, str)
                        if e.http_get.http_headers:
                            for h in e.http_get.http_headers:
                                if h.name:
                                    self.assertIsInstance(h.name, str)
                                if h.value:
                                    self.assertIsInstance(h.value, str)
                        if e.http_get.path:
                            self.assertIsInstance(e.http_get.path, str)
                        if e.http_get.port:
                            self.assertIsInstance(e.http_get.port, (str, int))
                        if e.http_get.scheme:
                            self.assertIsInstance(e.http_get.scheme, str)
                    if e.tcp_socket:
                        if e.tcp_socket.host:
                            self.assertIsInstance(e.tcp_socket.host, str)
                        if e.tcp_socket.port:
                            self.assertIsInstance(e.tcp_socket.port, (str, int))

        # test cases for checking value after sanitization
        check_value_op = dsl.ContainerOp(name='echo', image='image', command=['sh', '-c'],
                           arguments=['echo test | tee /tmp/message.txt'],
                           file_outputs={'merged': '/tmp/message.txt'})
        check_value_op.container \
                .add_env_variable(k8s_client.V1EnvVar(
                    name=80,
                    value=8080)) \
                .set_security_context(k8s_client.V1SecurityContext(
                    allow_privilege_escalation='true',
                    capabilities=k8s_client.V1Capabilities(add=[11, 22], drop=[33, 44]),
                    privileged='false',
                    proc_mount=111,
                    read_only_root_filesystem='False',
                    run_as_group='222',
                    run_as_non_root='True',
                    run_as_user='******',
                    se_linux_options=k8s_client.V1SELinuxOptions(level=11, role=22, type=33, user=44),
                    windows_options=k8s_client.V1WindowsSecurityContextOptions(
                        gmsa_credential_spec=11, gmsa_credential_spec_name=22)
                ))
        
        sanitize_k8s_object(check_value_op.container)

        self.assertEqual(check_value_op.container.env[0].name, '80')
        self.assertEqual(check_value_op.container.env[0].value, '8080')
        self.assertEqual(check_value_op.container.security_context.allow_privilege_escalation, True)
        self.assertEqual(check_value_op.container.security_context.capabilities.add[0], '11')
        self.assertEqual(check_value_op.container.security_context.capabilities.add[1], '22')
        self.assertEqual(check_value_op.container.security_context.capabilities.drop[0], '33')
        self.assertEqual(check_value_op.container.security_context.capabilities.drop[1], '44')
        self.assertEqual(check_value_op.container.security_context.privileged, False)
        self.assertEqual(check_value_op.container.security_context.proc_mount, '111')
        self.assertEqual(check_value_op.container.security_context.read_only_root_filesystem, False)
        self.assertEqual(check_value_op.container.security_context.run_as_group, 222)
        self.assertEqual(check_value_op.container.security_context.run_as_non_root, True)
        self.assertEqual(check_value_op.container.security_context.run_as_user, 333)
        self.assertEqual(check_value_op.container.security_context.se_linux_options.level, '11')
        self.assertEqual(check_value_op.container.security_context.se_linux_options.role, '22')
        self.assertEqual(check_value_op.container.security_context.se_linux_options.type, '33')
        self.assertEqual(check_value_op.container.security_context.se_linux_options.user, '44')
        self.assertEqual(check_value_op.container.security_context.windows_options.gmsa_credential_spec, '11')
        self.assertEqual(check_value_op.container.security_context.windows_options.gmsa_credential_spec_name, '22')

        # test cases for exception
        with self.assertRaises(ValueError, msg='Invalid boolean string 2. Should be boolean.'):
            exception_op = dsl.ContainerOp(name='echo', image='image')
            exception_op.container \
                    .set_security_context(k8s_client.V1SecurityContext(
                        allow_privilege_escalation=1
                    ))
            sanitize_k8s_object(exception_op.container)

        with self.assertRaises(ValueError, msg='Invalid boolean string Test. Should be "true" or "false".'):
            exception_op = dsl.ContainerOp(name='echo', image='image')
            exception_op.container \
                    .set_security_context(k8s_client.V1SecurityContext(
                        allow_privilege_escalation='Test'
                    ))
            sanitize_k8s_object(exception_op.container)

        with self.assertRaises(ValueError, msg='Invalid test. Should be integer.'):
            exception_op = dsl.ContainerOp(name='echo', image='image')
            exception_op.container \
                    .set_security_context(k8s_client.V1SecurityContext(
                        run_as_group='test',
                    ))
            sanitize_k8s_object(exception_op.container)
Beispiel #7
0
def create_deploy():
    error = ""
    if request.method == "POST":
        data = json.loads(request.get_data().decode("utf-8"))
        project = data.get("project").strip()
        environment = data.get("environment").strip()
        cluster = data.get("cluster").strip()

        imageRepo = data.get("imageRepo").strip()
        imageName = data.get("imageName").strip()
        imageTag = data.get("imageTag").strip()

        imagePullPolicy = data.get("imagePullPolicy").strip()
        imagePullSecret = data.get("imagePullSecret").strip()
        containerPort = str_to_int(data.get("containerPort").strip())
        replicas = data.get("replicas").strip()
        cpu = data.get("cpu").strip()
        memory = data.get("memory").strip()
        label_key1 = data.get("label_key1").strip()
        label_value1 = data.get("label_value1").strip()
        label_key2 = data.get("label_key2").strip()
        label_value2 = data.get("label_value2").strip()

        env = data.get("env").strip()
        volumeMount = data.get("volumeMount").strip()
        updateType = data.get("updateType").strip()

        probeType = data.get("probeType").strip()
        healthCheck = data.get("healthCheck").strip()
        healthPath = data.get("healthPath").strip()
        initialDelaySeconds = str_to_int(
            data.get("initialDelaySeconds").strip())
        periodSeconds = str_to_int(data.get("periodSeconds").strip())
        failureThreshold = str_to_int(data.get("failureThreshold").strip())
        healthTimeout = str_to_int(data.get("healthTimeout").strip())
        healthCmd = data.get("healthCmd").strip()

        liveness_probe = None
        readiness_probe = None
        if (healthCheck == "true"):
            if (probeType == "tcp"):
                liveness_probe = client.V1Probe(initial_delay_seconds=initialDelaySeconds,\
                    period_seconds = periodSeconds,\
                    timeout_seconds   = healthTimeout ,\
                    failure_threshold = failureThreshold,\
                    tcp_socket=client.V1TCPSocketAction(port=containerPort))
                readiness_probe = liveness_probe
            elif (probeType == "http"):
                liveness_probe = client.V1Probe(initial_delay_seconds=initialDelaySeconds,\
                    period_seconds = periodSeconds,\
                    timeout_seconds   = healthTimeout ,\
                    failure_threshold = failureThreshold,\
                    http_get=client.V1HTTPGetAction(path=healthPath,port=containerPort))
                readiness_probe = liveness_probe
            elif (probeType == "cmd"):
                pass

            else:
                pass
        if (containerPort == 1):
            error = "容器端口不能为空"
        if (imageRepo == "" or project == "" or environment == ""
                or imageName == "" or imageTag == ""):
            error = "镜像相关不能为空"
        if (label_key1 == "" or label_value1 == ""):
            error = "label相关数据不能为空(至少输入一对key/value)"
        replicas = str_to_int(replicas)

        cpu = int(1000 * (str_to_float(cpu)))
        memory = int(1024 * (str_to_float(memory)))

        if (error != ""):
            # print(error)
            return jsonify({"error": 1002, "msg": error})
        #ms-dev
        namespace = project + "-" + environment
        # myhub.mydocker.com/ms-dev/base:v1.0
        image = imageRepo + "/" + project + "-" + environment + "/" + imageName + ":" + imageTag
        labels = {label_key1: label_value1}
        if (label_key2 != "" and label_value2 != ""):
            labels[label_key2] = label_value2
        myclient = client.AppsV1Api()
        deployment = create_deployment_object(name=imageName,namespace=namespace,image=image,port=containerPort,\
            image_pull_policy=imagePullPolicy,imagePullSecret=imagePullSecret ,labels=labels,replicas=replicas,cpu=cpu,memory=memory,\
            liveness_probe=liveness_probe,readiness_probe=readiness_probe)
        # print(type(deployment))
        to_yaml = yaml.load(json.dumps(deployment, indent=4, cls=MyEncoder))
        file = os.path.join(dir_path, "demo-deployment.yaml")
        stream = open(file, 'w')
        yaml.safe_dump(to_yaml, stream, default_flow_style=False)
        status = create_deployment(api_instance=myclient,
                                   namespace=namespace,
                                   deployment=deployment)
        return json.dumps(deployment, indent=4, cls=MyEncoder)

    return jsonify({'a': 1})
Beispiel #8
0
 def export_deployment(self):
     # Configureate Pod template container
     volume_mounts = []
     containers = []
     volumes = []
     ports = []
     liveness_probe = None
     readiness_probe = None
     volume_mounts.append(
         client.V1VolumeMount(mount_path='/docker/logs', name='logs'))
     volumes.append(
         client.V1Volume(name='logs',
                         host_path=client.V1HostPathVolumeSource(
                             path='/opt/logs', type='DirectoryOrCreate')))
     if self.mounts:
         for path in self.mounts:
             volume_mounts.append(
                 client.V1VolumeMount(mount_path=path,
                                      name=self.mounts[path]))
             volumes.append(
                 client.V1Volume(name=self.mounts[path],
                                 host_path=client.V1HostPathVolumeSource(
                                     path=path, type='DirectoryOrCreate')))
     if self.container_port:
         ports = [
             client.V1ContainerPort(container_port=int(port))
             for port in self.container_port
         ]
         liveness_probe = client.V1Probe(
             initial_delay_seconds=15,
             tcp_socket=client.V1TCPSocketAction(
                 port=int(self.container_port[0])))
         readiness_probe = client.V1Probe(
             initial_delay_seconds=15,
             tcp_socket=client.V1TCPSocketAction(
                 port=int(self.container_port[0])))
         if self.healthcheck:
             liveness_probe = client.V1Probe(
                 initial_delay_seconds=15,
                 http_get=client.V1HTTPGetAction(
                     path=self.healthcheck,
                     port=int(self.container_port[0])))
             readiness_probe = client.V1Probe(
                 initial_delay_seconds=15,
                 http_get=client.V1HTTPGetAction(
                     path=self.healthcheck,
                     port=int(self.container_port[0])))
     Env = [
         client.V1EnvVar(name='LANG', value='en_US.UTF-8'),
         client.V1EnvVar(name='LC_ALL', value='en_US.UTF-8'),
         client.V1EnvVar(name='POD_NAME',
                         value_from=client.V1EnvVarSource(
                             field_ref=client.V1ObjectFieldSelector(
                                 field_path='metadata.name'))),
         client.V1EnvVar(name='POD_IP',
                         value_from=client.V1EnvVarSource(
                             field_ref=client.V1ObjectFieldSelector(
                                 field_path='status.podIP'))),
     ]
     container = client.V1Container(name=self.dm_name,
                                    image=self.image,
                                    ports=ports,
                                    image_pull_policy='Always',
                                    env=Env,
                                    resources=client.V1ResourceRequirements(
                                        limits=self.re_limits,
                                        requests=self.re_requests),
                                    volume_mounts=volume_mounts)
     if liveness_probe and readiness_probe:
         container = client.V1Container(
             name=self.dm_name,
             image=self.image,
             ports=ports,
             image_pull_policy='Always',
             env=Env,
             resources=client.V1ResourceRequirements(
                 limits=self.re_limits, requests=self.re_requests),
             volume_mounts=volume_mounts,
             liveness_probe=liveness_probe,
             readiness_probe=readiness_probe)
     containers.append(container)
     if self.sidecar:
         sidecar_container = client.V1Container(
             name='sidecar-%s' % self.dm_name,
             image=self.sidecar,
             image_pull_policy='Always',
             env=Env,
             resources=client.V1ResourceRequirements(
                 limits=self.re_limits, requests=self.re_requests),
             volume_mounts=volume_mounts)
         containers.append(sidecar_container)
     # Create and configurate a spec section
     secrets = client.V1LocalObjectReference('registrysecret')
     preference_key = self.dm_name
     project_values = ['xxxx']
     host_aliases = []
     db_docker_hosts = db_op.docker_hosts
     values = db_docker_hosts.query.with_entities(
         db_docker_hosts.ip, db_docker_hosts.hostname).filter(
             and_(db_docker_hosts.deployment == self.dm_name,
                  db_docker_hosts.context == self.context)).all()
     db_op.DB.session.remove()
     if values:
         ips = []
         for value in values:
             try:
                 ip, hostname = value
                 key = "op_docker_hosts_%s" % ip
                 Redis.lpush(key, hostname)
                 ips.append(ip)
             except Exception as e:
                 logging.error(e)
         for ip in set(ips):
             try:
                 key = "op_docker_hosts_%s" % ip
                 if Redis.exists(key):
                     hostnames = Redis.lrange(key, 0, -1)
                     if hostnames:
                         host_aliases.append(
                             client.V1HostAlias(hostnames=hostnames, ip=ip))
                 Redis.delete(key)
             except Exception as e:
                 logging.error(e)
     if self.labels:
         if 'deploy' in self.labels:
             preference_key = self.labels['deploy']
         if 'project' in self.labels:
             project_values = [self.labels['project']]
     template = client.V1PodTemplateSpec(
         metadata=client.V1ObjectMeta(labels={"project": self.dm_name}),
         spec=client.V1PodSpec(
             containers=containers,
             image_pull_secrets=[secrets],
             volumes=volumes,
             host_aliases=host_aliases,
             affinity=client.V1Affinity(node_affinity=client.V1NodeAffinity(
                 preferred_during_scheduling_ignored_during_execution=[
                     client.V1PreferredSchedulingTerm(
                         preference=client.V1NodeSelectorTerm(
                             match_expressions=[
                                 client.V1NodeSelectorRequirement(
                                     key=preference_key,
                                     operator='In',
                                     values=['mark'])
                             ]),
                         weight=100)
                 ],
                 required_during_scheduling_ignored_during_execution=client.
                 V1NodeSelector(node_selector_terms=[
                     client.V1NodeSelectorTerm(match_expressions=[
                         client.V1NodeSelectorRequirement(
                             key='project',
                             operator='In',
                             values=project_values)
                     ])
                 ])))))
     selector = client.V1LabelSelector(
         match_labels={"project": self.dm_name})
     # Create the specification of deployment
     spec = client.ExtensionsV1beta1DeploymentSpec(replicas=int(
         self.replicas),
                                                   template=template,
                                                   selector=selector,
                                                   min_ready_seconds=3)
     # Instantiate the deployment object
     deployment = client.ExtensionsV1beta1Deployment(
         api_version="extensions/v1beta1",
         kind="Deployment",
         metadata=client.V1ObjectMeta(name=self.dm_name),
         spec=spec)
     return deployment
Beispiel #9
0
    def createStatefulSet(cls, cluster_object: V1MongoClusterConfiguration) -> client.V1beta1StatefulSet:
        """
        Creates a the stateful set configuration for the given cluster.
        :param cluster_object: The cluster object from the YAML file.
        :return: The stateful set object.
        """

        # Parse cluster data object.
        name = cluster_object.metadata.name
        namespace = cluster_object.metadata.namespace
        replicas = cluster_object.spec.mongodb.replicas
        storage_mount_path = cluster_object.spec.mongodb.host_path or cls.DEFAULT_STORAGE_MOUNT_PATH
        host_path = cluster_object.spec.mongodb.host_path
        cpu_limit = cluster_object.spec.mongodb.cpu_limit or cls.DEFAULT_CPU_LIMIT
        memory_limit = cluster_object.spec.mongodb.memory_limit or cls.DEFAULT_MEMORY_LIMIT
        run_as_user = cluster_object.spec.mongodb.run_as_user or cls.DEFAULT_RUN_AS_USER
        service_account = cluster_object.spec.mongodb.service_account or cls.DEFAULT_SERVICE_ACCOUNT
        wired_tiger_cache_size = cluster_object.spec.mongodb.wired_tiger_cache_size or cls.DEFAULT_CACHE_SIZE
        secret_name = cls.ADMIN_SECRET_NAME_FORMAT.format(name)

        # create container
        mongo_container = client.V1Container(
            name=name,
            env=[client.V1EnvVar(
                name="POD_IP",
                value_from=client.V1EnvVarSource(
                    field_ref = client.V1ObjectFieldSelector(
                        api_version = "v1",
                        field_path = "status.podIP"
                    )
                )
            ),
            client.V1EnvVar(
                name="MONGODB_PASSWORD",
                value_from=client.V1EnvVarSource(
                    secret_key_ref=client.V1SecretKeySelector(
                        key="database-password",
                        name=secret_name
                    )
                )
            ),
            client.V1EnvVar(
                name="MONGODB_USER",
                value_from=client.V1EnvVarSource(
                    secret_key_ref=client.V1SecretKeySelector(
                        key="database-user",
                        name=secret_name
                    )
                )
            ),
            client.V1EnvVar(
                name="MONGODB_DATABASE",
                value_from=client.V1EnvVarSource(
                    secret_key_ref=client.V1SecretKeySelector(
                        key="database-name",
                        name=secret_name
                    )
                )
            ),
            client.V1EnvVar(
                name="MONGODB_ADMIN_PASSWORD",
                value_from=client.V1EnvVarSource(
                    secret_key_ref=client.V1SecretKeySelector(
                        key="database-admin-password",
                        name=secret_name
                    )
                )
            ),
            client.V1EnvVar(
              name="WIREDTIGER_CACHE_SIZE",
              value=wired_tiger_cache_size
            ),
            client.V1EnvVar(
                name="MONGODB_REPLICA_NAME",
                value=name
            ),
            client.V1EnvVar(
                name="MONGODB_SERVICE_NAME",
                value="svc-" + name + "-internal"
            ),
            client.V1EnvVar(
                name="MONGODB_KEYFILE_VALUE",
                value="supersecretkeyfile123"
            )],
            liveness_probe=client.V1Probe(failure_threshold=3,
                                          initial_delay_seconds=30,
                                          period_seconds=30,
                                          success_threshold=1,
                                          tcp_socket=client.V1TCPSocketAction(port=cls.MONGO_PORT),
                                          timeout_seconds=1
            ),
            command=cls.MONGO_COMMAND.split(),
            image=cls.MONGO_IMAGE,
            image_pull_policy="Always",
            ports=[client.V1ContainerPort(
                name="mongodb",
                container_port=cls.MONGO_PORT,
                protocol="TCP"
            )],
            readiness_probe=client.V1Probe(_exec=client.V1ExecAction(command=["/bin/sh", "-i", "-c", "mongo 127.0.0.1:27017/$MONGODB_DATABASE -u $MONGODB_USER -p $MONGODB_PASSWORD --eval=\"quit()\""]),
                                           failure_threshold=3,
                                           initial_delay_seconds=10,
                                           period_seconds=10,
                                           success_threshold=1,
                                           timeout_seconds=1
                                           ),
            security_context=client.V1SecurityContext(
                run_as_user=int(run_as_user),
                se_linux_options=client.V1SELinuxOptions(
                    level="s0",
                    type="spc_t"
                )
            ),
            termination_message_path="/dev/termination-log",
            volume_mounts=[client.V1VolumeMount(
                name="mongo-data",
                read_only=False,
                mount_path=storage_mount_path
            )],
            resources=client.V1ResourceRequirements(
                limits={"cpu": cpu_limit, "memory": memory_limit},
                requests={"cpu": cpu_limit, "memory": memory_limit}
            )
        )

        #create affinity rules
        affinity = client.V1Affinity(
            pod_anti_affinity=client.V1PodAntiAffinity(
                required_during_scheduling_ignored_during_execution=[
                    client.V1PodAffinityTerm(label_selector=client.V1LabelSelector(
                        match_expressions=[client.V1LabelSelectorRequirement(
                            key="app",
                            operator="In",
                            values=[name]
                        )]
                    ),
                     topology_key="kubernetes.io/hostname")
                ]
            )
        )

        volumes = [client.V1Volume(
            name="mongo-data",
            host_path=client.V1HostPathVolumeSource(path=host_path)
        )]

        # Create stateful set.
        return client.V1beta1StatefulSet(
            metadata = client.V1ObjectMeta(annotations={"service.alpha.kubernetes.io/tolerate-unready-endpoints": "true"},
                                           name=name,
                                           namespace=namespace,
                                           labels=cls.createDefaultLabels(name)),
            spec = client.V1beta1StatefulSetSpec(
                replicas = replicas,
                service_name = "svc-" + name + "-internal",
                template = client.V1PodTemplateSpec(
                    metadata = client.V1ObjectMeta(labels=cls.createDefaultLabels(name)),
                    spec = client.V1PodSpec(affinity = affinity,
                                            containers=[mongo_container],
                                            node_selector={"compute":"mongodb"},
                                            service_account=service_account,
                                            #restart_policy="Never",
                                            volumes=volumes
                    )
                ),
            ),
        )
Beispiel #10
0
 def export_deployment(self):
     # Configureate Pod template container
     volume_mounts = []
     volume_mounts.append(
         client.V1VolumeMount(mount_path='/opt/logs', name='logs'))
     if self.dm_name == 'launch':
         volume_mounts.append(
             client.V1VolumeMount(mount_path='/opt/%s/conf' % self.dm_name,
                                  name=self.dm_name))
     container = client.V1Container(
         name=self.dm_name,
         image=self.image,
         ports=[
             client.V1ContainerPort(container_port=int(port))
             for port in self.container_port
         ],
         image_pull_policy='Always',
         env=[
             client.V1EnvVar(name='LANG', value='en_US.UTF-8'),
             client.V1EnvVar(name='LC_ALL', value='en_US.UTF-8')
         ],
         resources=client.V1ResourceRequirements(limits=self.re_limits,
                                                 requests=self.re_requests),
         volume_mounts=volume_mounts,
         liveness_probe=client.V1Probe(
             initial_delay_seconds=30,
             tcp_socket=client.V1TCPSocketAction(
                 port=int(self.container_port[0]))),
         readiness_probe=client.V1Probe(
             initial_delay_seconds=30,
             tcp_socket=client.V1TCPSocketAction(
                 port=int(self.container_port[0]))))
     # Create and configurate a spec section
     secrets = client.V1LocalObjectReference('registrysecret')
     volumes = []
     volume = client.V1Volume(
         name='logs',
         host_path=client.V1HostPathVolumeSource(path='/opt/logs'))
     volumes.append(volume)
     template = client.V1PodTemplateSpec(
         metadata=client.V1ObjectMeta(labels={"project": self.dm_name}),
         spec=client.V1PodSpec(
             containers=[container],
             image_pull_secrets=[secrets],
             volumes=volumes,
             affinity=client.V1Affinity(node_affinity=client.V1NodeAffinity(
                 preferred_during_scheduling_ignored_during_execution=[
                     client.V1PreferredSchedulingTerm(
                         preference=client.V1NodeSelectorTerm(
                             match_expressions=[
                                 client.V1NodeSelectorRequirement(
                                     key='project',
                                     operator='In',
                                     values=['moji'])
                             ]),
                         weight=30),
                     client.V1PreferredSchedulingTerm(
                         preference=client.V1NodeSelectorTerm(
                             match_expressions=[
                                 client.V1NodeSelectorRequirement(
                                     key='deploy',
                                     operator='In',
                                     values=[self.dm_name])
                             ]),
                         weight=70)
                 ]))))
     selector = client.V1LabelSelector(
         match_labels={"project": self.dm_name})
     # Create the specification of deployment
     spec = client.ExtensionsV1beta1DeploymentSpec(replicas=int(
         self.replicas),
                                                   template=template,
                                                   selector=selector,
                                                   min_ready_seconds=3)
     # Instantiate the deployment object
     deployment = client.ExtensionsV1beta1Deployment(
         api_version="extensions/v1beta1",
         kind="Deployment",
         metadata=client.V1ObjectMeta(name=self.dm_name),
         spec=spec)
     return deployment
Beispiel #11
0
    def specifications(self):
        """
        Set the deployment specifications.
        :returns: The deployment specifications.
        :rtype:  client.ExtensionsV1beta1Deployment
        """
        #1. Set the ports
        ports = [client.V1ContainerPort(container_port=port['number'], protocol=port['protocol']) for port in self.definition['ports']]
        #2. Set the resources
        #resources = {'cpu':self.definition['cpu'], 'memory': self.definition['memory']}
        resources = {'cpu':'100m', 'memory': '100Mi'}
        resources = client.V1ResourceRequirements(limits=resources, requests=resources)
        #3. Set healthchecks
        readiness = None
        liveness = None
        for health in self.definition['healthchecks']:
            _exec, tcp_socket, http_get = None, None, None
            if health['command'] == 'COMMAND':
                _exec = client.V1ExecAction(command=health['value'])
            elif health['command'] == 'TCP':
                tcp_socket = client.V1TCPSocketAction(port=health['port'])
            else:
                http_get = client.V1HTTPGetAction(path=health['path'], port=health['port'], scheme=health['command'])

            probe = client.V1Probe(failure_threshold=self.definition['failure_threshold'],
                    initial_delay_seconds=self.definition['initial_delay_seconds'],
                    period_seconds=self.definition['interval_seconds'],
                    success_threshold=self.definition['success_threshold'],
                    timeout_seconds=self.definition['timeout_seconds'],
                    _exec=_exec,
                    tcp_socket=tcp_socket,
                    http_get=http_get
                    )
            if health['type'] == 'readiness':
                readiness = probe
            else:
                liveness = probe
        #4. Security context
        security = client.V1SecurityContext(allow_privilege_escalation=False, run_as_non_root=True)
        #5. Set the container
        container = client.V1Container(
            name=self.definition['repo'],
            image=self.definition['tag'],
            ports=ports,
            resources=resources,
            readiness_probe=readiness,
            liveness_probe=liveness,
            security_context=security,
            env=None)#No need to setup envs : already done in the dockerfile
        #6. The pod template
        template = client.V1PodTemplateSpec(
            client.V1ObjectMeta(labels={"name": self.definition['repo'], "repo": self.definition['repo'], "owner": self.definition['owner'], "branch": self.definition['branch'], "fullname": self.definition['name']}),
            spec=client.V1PodSpec(containers=[container]))
        #7. The rolling update strategy
        strategy = client.ExtensionsV1beta1DeploymentStrategy(
            type='RollingUpdate',
            rolling_update=client.ExtensionsV1beta1RollingUpdateDeployment(
                max_surge=1,
                max_unavailable=1
            )
        )
        #8. The deployment spec
        spec = client.ExtensionsV1beta1DeploymentSpec(
                #replicas=self.definition['instances'],
                replicas=1,
                strategy=strategy,
                template=template)
        #9. The deployment object
        deployment = client.ExtensionsV1beta1Deployment(
                api_version="extensions/v1beta1",
                kind="Deployment",
                metadata=client.V1ObjectMeta(name=self.definition['repo'], labels={"uid": self.definition['uid'], "repo": self.definition['repo'], "owner": self.definition['owner'], "branch": self.definition['branch'], "fullname": self.definition['name'], "name": self.definition['repo']}),
                spec=spec)
        return deployment