<commit_before>"""Kubernetes integration for Pib."""

from pyrsistent import PClass, field, pset_field, pset, pmap_field


class RenderingOptions(PClass):
    """Define how objects should be rendered."""
    tag_overrides = pmap_field(str,
                               str)  # map service name to Docker image tag
    # TODO: eventually ClusterIP vs NodePort can go here


class AddressConfigMap(PClass):
    """Kubernetes ConfigMap representation pointing at an InternalService.

    This will be used to give a envfile service the addresses of envfile
    deployments.
    """
    # TODO: When we support external services (e.g. AWS RDS) this may point at
    # those as well.
    # type=InternalService blows up pyrsistent :(
    backend_service = field(mandatory=True)
    resource_name = field(mandatory=True, type=str)  # original resource name

    def render(self, options):
        """Convert to a Kubernetes YAML/JSON config (as Python objects)."""
        return {
            "apiVersion": "v1",
            "kind": "ConfigMap",
            "metadata": {
                "name": self.backend_service.deployment.name,
            },
            "data": {
                "host": self.backend_service.deployment.name,
                "port": str(self.backend_service.deployment.port)
            }
        }


class Deployment(PClass):
    """Kubernetes Deployment represenation."""
    name = field(mandatory=True, type=str)
    docker_image = field(mandatory=True, type=str)
    port = field(mandatory=True, type=int)
    address_configmaps = pset_field(AddressConfigMap)

    def render(self, options):
        docker_image = self.docker_image
        tag = options.tag_overrides.get(self.name)
        if tag is not None:
            image_parts = self.docker_image.split(":")
            image_parts[-1] = tag
            docker_image = ":".join(image_parts)
        result = {
            'spec': {
                'replicas': 1,
                'template': {
                    'spec': {
                        'containers': [{
                            'name': self.name,
                            'imagePullPolicy': 'IfNotPresent',
                            'ports': [{
                                'containerPort': self.port,
                            }],
                            'image': docker_image,
                        }]
                    },
                    'metadata': {
                        'labels': {
                            'name': self.name
                        }
                    }
                }
            },
            'kind': 'Deployment',
            'metadata': {
                'labels': {
                    'name': self.name
                },
                'name': self.name
            },
            'apiVersion': 'extensions/v1beta1'
        }
        env = []
        for configmap in self.address_configmaps:
            for value in ["host", "port"]:
                # Notice that the environment variables are based on the
                # original name of the resource, not the namespaced Kubernetes
                # variant; from the service's point of view the original name
                # is what counts.
                name = configmap.resource_name
                env.append({
                    "name":
                    "{}_RESOURCE_{}".format(name.upper().replace("-", "_"),
                                             value.upper()),
                    "valueFrom": {
                        "configMapKeyRef": {
                            # ConfigMap k8s object has same name as the
                            # Deployment it points at:<commit_msg>Fix lint problem.<commit_after>"""Kubernetes integration for Pib."""

from pyrsistent import PClass, field, pset_field, pset, pmap_field


class RenderingOptions(PClass):
    """Define how objects should be rendered."""
    tag_overrides = pmap_field(str,
                               str)  # map service name to Docker image tag
    # TODO: eventually ClusterIP vs NodePort can go here


class AddressConfigMap(PClass):
    """Kubernetes ConfigMap representation pointing at an InternalService.

    This will be used to give a envfile service the addresses of envfile
    deployments.
    """
    # TODO: When we support external services (e.g. AWS RDS) this may point at
    # those as well.
    # type=InternalService blows up pyrsistent :(
    backend_service = field(mandatory=True)
    resource_name = field(mandatory=True, type=str)  # original resource name

    def render(self, options):
        """Convert to a Kubernetes YAML/JSON config (as Python objects)."""
        return {
            "apiVersion": "v1",
            "kind": "ConfigMap",
            "metadata": {
                "name": self.backend_service.deployment.name,
            },
            "data": {
                "host": self.backend_service.deployment.name,
                "port": str(self.backend_service.deployment.port)
            }
        }


class Deployment(PClass):
    """Kubernetes Deployment represenation."""
    name = field(mandatory=True, type=str)
    docker_image = field(mandatory=True, type=str)
    port = field(mandatory=True, type=int)
    address_configmaps = pset_field(AddressConfigMap)

    def render(self, options):
        docker_image = self.docker_image
        tag = options.tag_overrides.get(self.name)
        if tag is not None:
            image_parts = self.docker_image.split(":")
            image_parts[-1] = tag
            docker_image = ":".join(image_parts)
        result = {
            'spec': {
                'replicas': 1,
                'template': {
                    'spec': {
                        'containers': [{
                            'name': self.name,
                            'imagePullPolicy': 'IfNotPresent',
                            'ports': [{
                                'containerPort': self.port,
                            }],
                            'image': docker_image,
                        }]
                    },
                    'metadata': {
                        'labels': {
                            'name': self.name
                        }
                    }
                }
            },
            'kind': 'Deployment',
            'metadata': {
                'labels': {
                    'name': self.name
                },
                'name': self.name
            },
            'apiVersion': 'extensions/v1beta1'
        }
        env = []
        for configmap in self.address_configmaps:
            for value in ["host", "port"]:
                # Notice that the environment variables are based on the
                # original name of the resource, not the namespaced Kubernetes
                # variant; from the service's point of view the original name
                # is what counts.
                name = configmap.resource_name
                env.append({
                    "name":
                    "{}_RESOURCE_{}".format(name.upper().replace("-", "_"),
                                            value.upper()),
                    "valueFrom": {
                        "configMapKeyRef": {
                            # ConfigMap k8s object has same name as the
                            # Deployment it points at:
{'fraction_non_alphanumeric': 0.09810858620220438, 'fraction_numerical': 0.0016328752211185195, 'mean_word_length': 1.3671497584541064, 'pattern_counts': {'":': 24, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2924085', 'n_tokens_mistral': 1874, 'n_tokens_neox': 1771, 'n_words': 479}