From 66053e9b93aedc522ca05212db8c8e76a6a1a762 Mon Sep 17 00:00:00 2001 From: breimers Date: Mon, 6 Apr 2020 19:33:01 -0700 Subject: [PATCH] docs --- docs/source/getting_started.rst | 132 ++++++++ kubernetes_manager/migrations/0001_initial.py | 281 ++++++++++++++++++ kubernetes_manager/migrations/__init__.py | 0 3 files changed, 413 insertions(+) create mode 100644 kubernetes_manager/migrations/0001_initial.py create mode 100644 kubernetes_manager/migrations/__init__.py diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst index 1005308..985a564 100644 --- a/docs/source/getting_started.rst +++ b/docs/source/getting_started.rst @@ -62,3 +62,135 @@ Quickstart "exists": true } ] + +Sample Use-cases +----------------- +* Creating a labelled namespace for a client project: + +.. code-block:: python + + from kubernetes_manager.models import KubernetesNamespace, TargetCluster + from django.db import models + from django_extensions.models import TitleDescriptionModel + + class AppNamespace(TitleDescriptionModel): + project = models.OneToOneField("client.Project", on_delete=models.CASCADE) + organization = models.ForeignKey("client.Org", on_delete=models.CASCADE) + cluster = models.ForeignKey("kubernetes_manager.TargetCluster", on_delete=models.CASCADE) + namespace = models.ForeignKey("kubernetes_manager.KubernetesNamespace", null=True, blank=True, on_delete=models.CASCADE) + status = models.CharField(max_length = 128, null=True, blank=True) + + def save(self, *args, **kwargs): + if not self.status == "{'phase': 'Active'}": + self.namespace = KubernetesNamespace.objects.create( + title = "ns-" + self.organization.slug + "-" + self.project.slug, + cluster = self.cluster, + labels = {"organization":self.organization.slug, "project": self.project.slug}, + kind = "Namespace" + ) + self.status = self.namespace.deploy() + super().save(*args, **kwargs) + + def remove(self, *args, **kwargs): + self.status = self.namespace.k_delete() + + def delete(self, *args, **kwargs): + self.remove() + super().delete(*args, **kwargs) + + + +* Creating a two-container deployment: + +.. code-block:: python + + from kubernetes_manager.models import KubernetesNamespace, TargetCluster + from django.db import models + from django_extensions.models import TitleDescriptionModel + + from .ns import AppNamespace + + class FileServer(TitleDescriptionModel): + name = models.CharField(max_length=128) + organization = models.ForeignKey("client.Org", on_delete=models.CASCADE) + project = models.ForeignKey("client.Project", on_delete=models.CASCADE) + cluster = models.ForeignKey("kubernetes_manager.TargetCluster", on_delete=models.CASCADE) + namespace = models.ForeignKey(AppNamespace, on_delete=models.CASCADE) + file = models.ForeignKey("library.FileItem", on_delete=models.CASCADE) + docker_image = models.CharField(max_length=256, help_text="Docker repo path for image") + docker_tag = models.CharField(max_length=16, help_text="Docker tag for image") + definition = JSONField(null=True, blank=True) + + # define volume + def vol(self, *args, **kwargs): + volume = KubernetesVolume.objects.create( + title = self.name + "-vol", + cluster = self.cluster + ) + return volume + + # create primary container + def container_spec(self, *args, **kwargs): + container = KubernetesContainer.objects.create( + title = self.name, + cluster = self.cluster, + image_name = self.docker_image, + image_tag = self.docker_tag, + volume_mount = KubernetesVolumeMount.objects.create( + title = self.name + "-vol", + cluster = self.cluster + ) if not kwargs.get("mount", None) else kwargs.get("mount"), + command = "ls", + args ="/media" + ) + return container + + # create download sidecar + def sidecar_spec(self, *args, **kwargs): + sidecar = KubernetesContainer.objects.create( + title = self.name, + cluster = self.cluster, + image_name = "curlimages/curl", + image_tag = "7.69.1", + volume_mount = KubernetesVolumeMount.objects.create( + title = self.name + "-vol", + cluster = self.cluster + ) if not kwargs.get("mount", None) else kwargs.get("mount"), + command = "/bin/sh", + args = '-c,curl -oL {} {}'.format(self.file.name, self.file.url) + ) + return sidecar + + # create pod template + def pod_template_spec(self, *args, **kwargs): + volume_mount = KubernetesVolumeMount.objects.create( + title = self.name + "-vol", + cluster = self.cluster + ) + pod = KubernetesPodTemplate.objects.create( + title = self.name, + cluster = self.cluster, + volume = self.vol(), + primary_container = self.container_spec(mount=volume_mount), + secondary_container = self.sidecar_spec(mount=volume_mount), + restart_policy = "Always", + labels = {"project": self.project.slug} + ) + return pod + + # tie it up and deplioy + def deploy(self): + pod = self.pod_template_spec() + deployment = KubernetesDeployment.objects.create( + title = self.name, + cluster = self.cluster, + api_version = "apps/v1", + kind = "Deployment", + namespace = self.namespace.namespace.slug, + labels = {"project": self.project.slug}, + selector = {"project": self.project.slug}, + pod_template = pod + ) + self.definition = deployment.get_obj().to_dict() + self.save() + return deployment.deploy() diff --git a/kubernetes_manager/migrations/0001_initial.py b/kubernetes_manager/migrations/0001_initial.py new file mode 100644 index 0000000..6033372 --- /dev/null +++ b/kubernetes_manager/migrations/0001_initial.py @@ -0,0 +1,281 @@ +# Generated by Django 3.0.5 on 2020-04-07 00:33 + +import django.contrib.postgres.fields.jsonb +from django.db import migrations, models +import django.db.models.deletion +import django_extensions.db.fields +import uuid + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='KubernetesContainer', + fields=[ + ('title', models.CharField(max_length=255, verbose_name='title')), + ('description', models.TextField(blank=True, null=True, verbose_name='description')), + ('slug', django_extensions.db.fields.AutoSlugField(blank=True, editable=False, populate_from='title', verbose_name='slug')), + ('id', models.UUIDField(default=uuid.uuid4, editable=False, help_text='UUID Auto field.', primary_key=True, serialize=False)), + ('config', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict, help_text='Pass in extra parameters here.', null=True)), + ('deployed', models.DateTimeField(blank=True, help_text='Time when object is applied to cluster.', null=True)), + ('removed', models.DateTimeField(blank=True, help_text='Time when object is removed from cluster.', null=True)), + ('image_name', models.CharField(db_index=True, default='debian', help_text='Properly qualified image name.', max_length=200)), + ('image_tag', models.CharField(db_index=True, default='latest', help_text='Tag name for the image to be used for this job', max_length=100)), + ('image_pull_policy', models.CharField(choices=[('Always', 'Always'), ('IfNotPresent', 'IfNotPresent'), ('Never', 'Never')], default='IfNotPresent', max_length=16)), + ('command', models.TextField(blank=True, help_text='Command to run when start container', null=True)), + ('args', models.TextField(blank=True, help_text='Comma separated args to run with command when instantiating container.', null=True)), + ('port', models.IntegerField(default=80)), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='KubernetesNamespace', + fields=[ + ('title', models.CharField(max_length=255, verbose_name='title')), + ('description', models.TextField(blank=True, null=True, verbose_name='description')), + ('slug', django_extensions.db.fields.AutoSlugField(blank=True, editable=False, populate_from='title', verbose_name='slug')), + ('id', models.UUIDField(default=uuid.uuid4, editable=False, help_text='UUID Auto field.', primary_key=True, serialize=False)), + ('config', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict, help_text='Pass in extra parameters here.', null=True)), + ('deployed', models.DateTimeField(blank=True, help_text='Time when object is applied to cluster.', null=True)), + ('removed', models.DateTimeField(blank=True, help_text='Time when object is removed from cluster.', null=True)), + ('labels', django.contrib.postgres.fields.jsonb.JSONField(default=dict, help_text='Dictionary store equivalent to Labels in Kubernetes API')), + ('annotations', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict, help_text='Dictionary store equivalent to Annotations in Kubernetes API', null=True)), + ('api_version', models.CharField(default='v1', max_length=16)), + ('kind', models.CharField(default='Namespace', max_length=16)), + ('exists', models.BooleanField(default=False)), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='TargetCluster', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=255, verbose_name='title')), + ('description', models.TextField(blank=True, null=True, verbose_name='description')), + ('slug', django_extensions.db.fields.AutoSlugField(blank=True, editable=False, populate_from='title', verbose_name='slug')), + ('api_endpoint', models.URLField(help_text='Cluster Endpoint URL')), + ('telemetry_endpoint', models.URLField(help_text='Telemetry Endpoint URL')), + ('telemetry_source', models.CharField(choices=[('p', 'Prometheus')], default='p', max_length=5)), + ('config', django.contrib.postgres.fields.jsonb.JSONField(help_text='Configuration data stored as an encrypted blob in the database', null=True)), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='KubernetesVolumeMount', + fields=[ + ('title', models.CharField(max_length=255, verbose_name='title')), + ('description', models.TextField(blank=True, null=True, verbose_name='description')), + ('slug', django_extensions.db.fields.AutoSlugField(blank=True, editable=False, populate_from='title', verbose_name='slug')), + ('id', models.UUIDField(default=uuid.uuid4, editable=False, help_text='UUID Auto field.', primary_key=True, serialize=False)), + ('config', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict, help_text='Pass in extra parameters here.', null=True)), + ('deployed', models.DateTimeField(blank=True, help_text='Time when object is applied to cluster.', null=True)), + ('removed', models.DateTimeField(blank=True, help_text='Time when object is removed from cluster.', null=True)), + ('mount_path', models.CharField(default='/media', max_length=255)), + ('sub_path', models.CharField(blank=True, default=None, max_length=255, null=True)), + ('cluster', models.ForeignKey(help_text='ForeignKey to TargetCluster object.', null=True, on_delete=django.db.models.deletion.SET_NULL, to='kubernetes_manager.TargetCluster')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='KubernetesVolume', + fields=[ + ('title', models.CharField(max_length=255, verbose_name='title')), + ('description', models.TextField(blank=True, null=True, verbose_name='description')), + ('slug', django_extensions.db.fields.AutoSlugField(blank=True, editable=False, populate_from='title', verbose_name='slug')), + ('id', models.UUIDField(default=uuid.uuid4, editable=False, help_text='UUID Auto field.', primary_key=True, serialize=False)), + ('config', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict, help_text='Pass in extra parameters here.', null=True)), + ('deployed', models.DateTimeField(blank=True, help_text='Time when object is applied to cluster.', null=True)), + ('removed', models.DateTimeField(blank=True, help_text='Time when object is removed from cluster.', null=True)), + ('cluster', models.ForeignKey(help_text='ForeignKey to TargetCluster object.', null=True, on_delete=django.db.models.deletion.SET_NULL, to='kubernetes_manager.TargetCluster')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='KubernetesService', + fields=[ + ('title', models.CharField(max_length=255, verbose_name='title')), + ('description', models.TextField(blank=True, null=True, verbose_name='description')), + ('slug', django_extensions.db.fields.AutoSlugField(blank=True, editable=False, populate_from='title', verbose_name='slug')), + ('id', models.UUIDField(default=uuid.uuid4, editable=False, help_text='UUID Auto field.', primary_key=True, serialize=False)), + ('config', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict, help_text='Pass in extra parameters here.', null=True)), + ('deployed', models.DateTimeField(blank=True, help_text='Time when object is applied to cluster.', null=True)), + ('removed', models.DateTimeField(blank=True, help_text='Time when object is removed from cluster.', null=True)), + ('labels', django.contrib.postgres.fields.jsonb.JSONField(default=dict, help_text='Dictionary store equivalent to Labels in Kubernetes API')), + ('annotations', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict, help_text='Dictionary store equivalent to Annotations in Kubernetes API', null=True)), + ('api_version', models.CharField(default='v1', help_text='API version used to deploy child object.', max_length=16)), + ('kind', models.CharField(help_text='String representation of Kubernetes object kind', max_length=16)), + ('port', models.IntegerField(default=80, help_text='Port object will expose')), + ('kuid', models.CharField(blank=True, help_text="Object's UID in the cluster", max_length=48, null=True)), + ('selector', django.contrib.postgres.fields.jsonb.JSONField(default=dict)), + ('target_port', models.IntegerField(default=80)), + ('cluster', models.ForeignKey(help_text='ForeignKey to TargetCluster object.', null=True, on_delete=django.db.models.deletion.SET_NULL, to='kubernetes_manager.TargetCluster')), + ('namespace', models.ForeignKey(help_text='Live namespace the object is associated with.', on_delete=django.db.models.deletion.CASCADE, to='kubernetes_manager.KubernetesNamespace')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='KubernetesPodTemplate', + fields=[ + ('title', models.CharField(max_length=255, verbose_name='title')), + ('description', models.TextField(blank=True, null=True, verbose_name='description')), + ('slug', django_extensions.db.fields.AutoSlugField(blank=True, editable=False, populate_from='title', verbose_name='slug')), + ('id', models.UUIDField(default=uuid.uuid4, editable=False, help_text='UUID Auto field.', primary_key=True, serialize=False)), + ('config', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict, help_text='Pass in extra parameters here.', null=True)), + ('deployed', models.DateTimeField(blank=True, help_text='Time when object is applied to cluster.', null=True)), + ('removed', models.DateTimeField(blank=True, help_text='Time when object is removed from cluster.', null=True)), + ('labels', django.contrib.postgres.fields.jsonb.JSONField(default=dict, help_text='Dictionary store equivalent to Labels in Kubernetes API')), + ('annotations', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict, help_text='Dictionary store equivalent to Annotations in Kubernetes API', null=True)), + ('restart_policy', models.CharField(choices=[('Always', 'Always'), ('OnFailure', 'OnFailure'), ('Never', 'Never')], default='Never', max_length=16)), + ('cluster', models.ForeignKey(help_text='ForeignKey to TargetCluster object.', null=True, on_delete=django.db.models.deletion.SET_NULL, to='kubernetes_manager.TargetCluster')), + ('primary_container', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='primary_container', to='kubernetes_manager.KubernetesContainer')), + ('secondary_container', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='secondary_container', to='kubernetes_manager.KubernetesContainer')), + ('volume', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='kubernetes_manager.KubernetesVolume')), + ], + options={ + 'abstract': False, + }, + ), + migrations.AddField( + model_name='kubernetesnamespace', + name='cluster', + field=models.ForeignKey(help_text='ForeignKey to TargetCluster object.', null=True, on_delete=django.db.models.deletion.SET_NULL, to='kubernetes_manager.TargetCluster'), + ), + migrations.CreateModel( + name='KubernetesJob', + fields=[ + ('title', models.CharField(max_length=255, verbose_name='title')), + ('description', models.TextField(blank=True, null=True, verbose_name='description')), + ('slug', django_extensions.db.fields.AutoSlugField(blank=True, editable=False, populate_from='title', verbose_name='slug')), + ('id', models.UUIDField(default=uuid.uuid4, editable=False, help_text='UUID Auto field.', primary_key=True, serialize=False)), + ('config', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict, help_text='Pass in extra parameters here.', null=True)), + ('deployed', models.DateTimeField(blank=True, help_text='Time when object is applied to cluster.', null=True)), + ('removed', models.DateTimeField(blank=True, help_text='Time when object is removed from cluster.', null=True)), + ('labels', django.contrib.postgres.fields.jsonb.JSONField(default=dict, help_text='Dictionary store equivalent to Labels in Kubernetes API')), + ('annotations', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict, help_text='Dictionary store equivalent to Annotations in Kubernetes API', null=True)), + ('api_version', models.CharField(default='v1', help_text='API version used to deploy child object.', max_length=16)), + ('kind', models.CharField(help_text='String representation of Kubernetes object kind', max_length=16)), + ('port', models.IntegerField(default=80, help_text='Port object will expose')), + ('kuid', models.CharField(blank=True, help_text="Object's UID in the cluster", max_length=48, null=True)), + ('object_status', models.CharField(blank=True, help_text='status of the object in Kubernetes', max_length=128, null=True)), + ('average_cpu_usage', models.DecimalField(blank=True, decimal_places=4, help_text='Average PIT CPU units consumed', max_digits=8, null=True)), + ('average_mem_usage', models.IntegerField(blank=True, help_text='Average PIT bytes consumed', null=True)), + ('cpu_usage_seconds', models.DecimalField(blank=True, decimal_places=4, help_text='Average cpu usage * seconds live', max_digits=8, null=True)), + ('mem_usage_seconds', models.IntegerField(blank=True, help_text='Average mem usage * seconds live', null=True)), + ('backoff_limit', models.IntegerField(default=3)), + ('cluster', models.ForeignKey(help_text='ForeignKey to TargetCluster object.', null=True, on_delete=django.db.models.deletion.SET_NULL, to='kubernetes_manager.TargetCluster')), + ('namespace', models.ForeignKey(help_text='Live namespace the object is associated with.', on_delete=django.db.models.deletion.CASCADE, to='kubernetes_manager.KubernetesNamespace')), + ('pod_template', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='kubernetes_manager.KubernetesPodTemplate')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='KubernetesIngress', + fields=[ + ('title', models.CharField(max_length=255, verbose_name='title')), + ('description', models.TextField(blank=True, null=True, verbose_name='description')), + ('slug', django_extensions.db.fields.AutoSlugField(blank=True, editable=False, populate_from='title', verbose_name='slug')), + ('id', models.UUIDField(default=uuid.uuid4, editable=False, help_text='UUID Auto field.', primary_key=True, serialize=False)), + ('config', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict, help_text='Pass in extra parameters here.', null=True)), + ('deployed', models.DateTimeField(blank=True, help_text='Time when object is applied to cluster.', null=True)), + ('removed', models.DateTimeField(blank=True, help_text='Time when object is removed from cluster.', null=True)), + ('labels', django.contrib.postgres.fields.jsonb.JSONField(default=dict, help_text='Dictionary store equivalent to Labels in Kubernetes API')), + ('annotations', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict, help_text='Dictionary store equivalent to Annotations in Kubernetes API', null=True)), + ('api_version', models.CharField(default='v1', help_text='API version used to deploy child object.', max_length=16)), + ('kind', models.CharField(help_text='String representation of Kubernetes object kind', max_length=16)), + ('port', models.IntegerField(default=80, help_text='Port object will expose')), + ('kuid', models.CharField(blank=True, help_text="Object's UID in the cluster", max_length=48, null=True)), + ('hostname', models.CharField(default='localhost', max_length=255)), + ('path', models.CharField(default='/', max_length=255)), + ('cluster', models.ForeignKey(help_text='ForeignKey to TargetCluster object.', null=True, on_delete=django.db.models.deletion.SET_NULL, to='kubernetes_manager.TargetCluster')), + ('namespace', models.ForeignKey(help_text='Live namespace the object is associated with.', on_delete=django.db.models.deletion.CASCADE, to='kubernetes_manager.KubernetesNamespace')), + ('target_service', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='kubernetes_manager.KubernetesService')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='KubernetesDeployment', + fields=[ + ('title', models.CharField(max_length=255, verbose_name='title')), + ('description', models.TextField(blank=True, null=True, verbose_name='description')), + ('slug', django_extensions.db.fields.AutoSlugField(blank=True, editable=False, populate_from='title', verbose_name='slug')), + ('id', models.UUIDField(default=uuid.uuid4, editable=False, help_text='UUID Auto field.', primary_key=True, serialize=False)), + ('config', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict, help_text='Pass in extra parameters here.', null=True)), + ('deployed', models.DateTimeField(blank=True, help_text='Time when object is applied to cluster.', null=True)), + ('removed', models.DateTimeField(blank=True, help_text='Time when object is removed from cluster.', null=True)), + ('labels', django.contrib.postgres.fields.jsonb.JSONField(default=dict, help_text='Dictionary store equivalent to Labels in Kubernetes API')), + ('annotations', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict, help_text='Dictionary store equivalent to Annotations in Kubernetes API', null=True)), + ('api_version', models.CharField(default='v1', help_text='API version used to deploy child object.', max_length=16)), + ('kind', models.CharField(help_text='String representation of Kubernetes object kind', max_length=16)), + ('port', models.IntegerField(default=80, help_text='Port object will expose')), + ('kuid', models.CharField(blank=True, help_text="Object's UID in the cluster", max_length=48, null=True)), + ('object_status', models.CharField(blank=True, help_text='status of the object in Kubernetes', max_length=128, null=True)), + ('average_cpu_usage', models.DecimalField(blank=True, decimal_places=4, help_text='Average PIT CPU units consumed', max_digits=8, null=True)), + ('average_mem_usage', models.IntegerField(blank=True, help_text='Average PIT bytes consumed', null=True)), + ('cpu_usage_seconds', models.DecimalField(blank=True, decimal_places=4, help_text='Average cpu usage * seconds live', max_digits=8, null=True)), + ('mem_usage_seconds', models.IntegerField(blank=True, help_text='Average mem usage * seconds live', null=True)), + ('selector', django.contrib.postgres.fields.jsonb.JSONField(default=dict)), + ('replicas', models.IntegerField(default=1)), + ('cluster', models.ForeignKey(help_text='ForeignKey to TargetCluster object.', null=True, on_delete=django.db.models.deletion.SET_NULL, to='kubernetes_manager.TargetCluster')), + ('namespace', models.ForeignKey(help_text='Live namespace the object is associated with.', on_delete=django.db.models.deletion.CASCADE, to='kubernetes_manager.KubernetesNamespace')), + ('pod_template', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='kubernetes_manager.KubernetesPodTemplate')), + ], + options={ + 'abstract': False, + }, + ), + migrations.AddField( + model_name='kubernetescontainer', + name='cluster', + field=models.ForeignKey(help_text='ForeignKey to TargetCluster object.', null=True, on_delete=django.db.models.deletion.SET_NULL, to='kubernetes_manager.TargetCluster'), + ), + migrations.AddField( + model_name='kubernetescontainer', + name='volume_mount', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='kubernetes_manager.KubernetesVolumeMount'), + ), + migrations.CreateModel( + name='KubernetesConfigMap', + fields=[ + ('title', models.CharField(max_length=255, verbose_name='title')), + ('description', models.TextField(blank=True, null=True, verbose_name='description')), + ('slug', django_extensions.db.fields.AutoSlugField(blank=True, editable=False, populate_from='title', verbose_name='slug')), + ('id', models.UUIDField(default=uuid.uuid4, editable=False, help_text='UUID Auto field.', primary_key=True, serialize=False)), + ('config', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict, help_text='Pass in extra parameters here.', null=True)), + ('deployed', models.DateTimeField(blank=True, help_text='Time when object is applied to cluster.', null=True)), + ('removed', models.DateTimeField(blank=True, help_text='Time when object is removed from cluster.', null=True)), + ('labels', django.contrib.postgres.fields.jsonb.JSONField(default=dict, help_text='Dictionary store equivalent to Labels in Kubernetes API')), + ('annotations', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict, help_text='Dictionary store equivalent to Annotations in Kubernetes API', null=True)), + ('kind', models.CharField(default='ConfigMap', max_length=16)), + ('data', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict, null=True)), + ('binary', models.BinaryField(blank=True, null=True)), + ('override_name', models.CharField(blank=True, default='ConfigMap', max_length=32, null=True)), + ('cluster', models.ForeignKey(help_text='ForeignKey to TargetCluster object.', null=True, on_delete=django.db.models.deletion.SET_NULL, to='kubernetes_manager.TargetCluster')), + ('namespace', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='kubernetes_manager.KubernetesNamespace')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/kubernetes_manager/migrations/__init__.py b/kubernetes_manager/migrations/__init__.py new file mode 100644 index 0000000..e69de29