Django Operator for Kubernetes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

195 lines
4.5 KiB

  1. package django
  2. import (
  3. blindagev1alpha1 "git.blindage.org/21h/django-operator/pkg/apis/blindage/v1alpha1"
  4. v1 "k8s.io/api/apps/v1"
  5. corev1 "k8s.io/api/core/v1"
  6. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  7. "k8s.io/apimachinery/pkg/util/intstr"
  8. )
  9. func generateService(cr *blindagev1alpha1.Django) corev1.Service {
  10. labels := map[string]string{
  11. "component": "service",
  12. }
  13. serviceAnnotations := map[string]string{}
  14. if cr.Spec.ServiceAnnotations != nil {
  15. serviceAnnotations = *cr.Spec.ServiceAnnotations
  16. }
  17. port := int32(8000)
  18. if cr.Spec.AppPort > 0 {
  19. port = cr.Spec.AppPort
  20. }
  21. service := corev1.Service{
  22. ObjectMeta: metav1.ObjectMeta{
  23. Name: cr.Name,
  24. Namespace: cr.Namespace,
  25. Labels: labels,
  26. Annotations: serviceAnnotations,
  27. },
  28. }
  29. service.Spec.Type = corev1.ServiceTypeClusterIP
  30. service.Spec.Ports = []corev1.ServicePort{
  31. {
  32. Name: "http",
  33. Port: port,
  34. Protocol: corev1.ProtocolTCP,
  35. TargetPort: intstr.FromString("http"),
  36. },
  37. }
  38. service.Spec.Selector = mergeLabels(baseLabels(cr),
  39. map[string]string{"component": "application"},
  40. )
  41. return service
  42. }
  43. func generateDeployment(cr *blindagev1alpha1.Django) v1.Deployment {
  44. podAnnotations := map[string]string{}
  45. if cr.Spec.PodAnnotations != nil {
  46. podAnnotations = *cr.Spec.PodAnnotations
  47. }
  48. // check affinity rules
  49. affinity := &corev1.Affinity{}
  50. if cr.Spec.Affinity != nil {
  51. affinity = cr.Spec.Affinity
  52. }
  53. resourcesLimits := corev1.ResourceList{}
  54. if cr.Spec.PodLimits != nil {
  55. resourcesLimits = *cr.Spec.PodLimits
  56. }
  57. resourcesRequests := corev1.ResourceList{}
  58. if cr.Spec.PodRequests != nil {
  59. resourcesRequests = *cr.Spec.PodRequests
  60. }
  61. port := int32(8000)
  62. if cr.Spec.AppPort > 0 {
  63. port = cr.Spec.AppPort
  64. }
  65. ports := []corev1.ContainerPort{
  66. {
  67. Name: "http",
  68. ContainerPort: port,
  69. Protocol: corev1.ProtocolTCP,
  70. },
  71. }
  72. image := ""
  73. if cr.Spec.Image != "" {
  74. image = cr.Spec.Image
  75. }
  76. pullPolicy := corev1.PullIfNotPresent
  77. if cr.Spec.PullPolicy != nil {
  78. pullPolicy = *cr.Spec.PullPolicy
  79. }
  80. appStaticPath := "/app/static"
  81. if cr.Spec.AppStaticPath != "" {
  82. appStaticPath = cr.Spec.AppStaticPath
  83. }
  84. deployment := v1.Deployment{
  85. ObjectMeta: metav1.ObjectMeta{
  86. Name: cr.Name,
  87. Namespace: cr.ObjectMeta.Namespace,
  88. Labels: baseLabels(cr),
  89. Annotations: podAnnotations,
  90. },
  91. Spec: v1.DeploymentSpec{
  92. Selector: &metav1.LabelSelector{
  93. MatchLabels: mergeLabels(baseLabels(cr),
  94. map[string]string{"component": "application"},
  95. ),
  96. },
  97. Replicas: &cr.Spec.Replicas,
  98. Strategy: v1.DeploymentStrategy{Type: v1.RollingUpdateDeploymentStrategyType, RollingUpdate: nil},
  99. Template: corev1.PodTemplateSpec{
  100. ObjectMeta: metav1.ObjectMeta{
  101. Labels: mergeLabels(baseLabels(cr),
  102. map[string]string{"component": "application"},
  103. ),
  104. Annotations: podAnnotations,
  105. },
  106. Spec: corev1.PodSpec{
  107. Affinity: affinity,
  108. Containers: []corev1.Container{
  109. {
  110. Name: "django",
  111. Image: image,
  112. ImagePullPolicy: pullPolicy,
  113. Ports: ports,
  114. Env: mergeENV(cr.Spec.AppEnv),
  115. Resources: corev1.ResourceRequirements{
  116. Limits: resourcesLimits,
  117. Requests: resourcesRequests,
  118. },
  119. VolumeMounts: []corev1.VolumeMount{
  120. {
  121. Name: "static",
  122. MountPath: appStaticPath,
  123. },
  124. },
  125. },
  126. },
  127. Volumes: []corev1.Volume{
  128. {
  129. Name: "static",
  130. VolumeSource: corev1.VolumeSource{
  131. EmptyDir: &corev1.EmptyDirVolumeSource{},
  132. },
  133. },
  134. },
  135. },
  136. },
  137. },
  138. }
  139. if cr.Spec.RunCollectStatic {
  140. deployment.Spec.Template.Spec.InitContainers = append(deployment.Spec.Template.Spec.InitContainers, corev1.Container{
  141. Name: "collectstatic",
  142. Image: image,
  143. ImagePullPolicy: pullPolicy,
  144. Command: []string{"python", "manage.py", "collectstatic", "--noinput"},
  145. Env: mergeENV(cr.Spec.AppEnv),
  146. VolumeMounts: []corev1.VolumeMount{
  147. {
  148. Name: "static",
  149. MountPath: appStaticPath,
  150. },
  151. },
  152. })
  153. }
  154. if cr.Spec.RunMigrate {
  155. deployment.Spec.Template.Spec.InitContainers = append(deployment.Spec.Template.Spec.InitContainers, corev1.Container{
  156. Name: "migrate",
  157. Image: image,
  158. ImagePullPolicy: pullPolicy,
  159. Command: []string{"python", "manage.py", "migrate"},
  160. Env: mergeENV(cr.Spec.AppEnv),
  161. VolumeMounts: []corev1.VolumeMount{
  162. {
  163. Name: "static",
  164. MountPath: appStaticPath,
  165. },
  166. },
  167. })
  168. }
  169. return deployment
  170. }