Skip to content

Commit c03b699

Browse files
committed
Add creation handler
- Add models to support creation of resources - Rearrange old project files
1 parent e16e558 commit c03b699

21 files changed

+720
-71
lines changed

deploy/cr.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ metadata:
55
spec:
66
image: example-image
77
imagePullPolicy: Never
8-
appName: celery-example
8+
appName: example
99
celeryApp: 'app:celery_app'
1010
celeryVersion: "4.X"
1111
workerReplicas: 3

deploy/crd.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ spec:
6969
items:
7070
description: "Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell"
7171
type: string
72-
envs:
72+
env:
7373
items:
7474
description: EnvVar represents an environment variable present in
7575
a Container.
@@ -208,7 +208,7 @@ spec:
208208
items:
209209
description: "Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell"
210210
type: string
211-
envs:
211+
env:
212212
items:
213213
description: EnvVar represents an environment variable present in
214214
a Container.

deploy/detailed_cr.yaml

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
apiVersion: celeryproject.org/v1alpha1
2+
kind: Celery
3+
metadata:
4+
name: example-celery-obj
5+
spec:
6+
image: example-image
7+
imagePullPolicy: Never
8+
imagePullSecrets:
9+
- name: dockerhub-creds
10+
appName: example-app
11+
celeryApp: 'app:celery_app'
12+
celeryVersion: "4.X"
13+
workerReplicas: 3
14+
flowerReplicas: 2
15+
workerSpec:
16+
args: [ "--loglevel", "INFO", "-Ofair", "-Q", "celery", "-c", "2" ]
17+
env:
18+
- name: STATSD_HOST
19+
valueFrom:
20+
fieldRef:
21+
apiVersion: v1
22+
fieldPath: status.hostIP
23+
- name: ENV
24+
valueFrom:
25+
configMapKeyRef:
26+
key: ENV
27+
name: global
28+
- name: C_FORCE_ROOT
29+
value: "true"
30+
- name: APP_RELEASE_VERSION
31+
value: 8bdd66
32+
nodeSelector:
33+
disktype: ssd
34+
resources:
35+
requests:
36+
cpu: "100m"
37+
memory: "64Mi"
38+
limits:
39+
cpu: "200m"
40+
memory: "128Mi"
41+
flowerSpec:
42+
service:
43+
metadata:
44+
name: celery-example-flower
45+
namespace: default
46+
labels:
47+
app: celery-example-flower
48+
spec:
49+
type: NodePort
50+
ports:
51+
- port: 5555
52+
protocol: TCP
53+
selector:
54+
run: celery-example-flower
55+
args: [ "--loglevel", "INFO" ]
56+
nodeSelector:
57+
disktype: ssd
58+
env:
59+
- name: STATSD_HOST
60+
valueFrom:
61+
fieldRef:
62+
apiVersion: v1
63+
fieldPath: status.hostIP
64+
- name: ENV
65+
valueFrom:
66+
configMapKeyRef:
67+
key: ENV
68+
name: global
69+
- name: C_FORCE_ROOT
70+
value: "true"
71+
- name: APP_RELEASE_VERSION
72+
value: 8bdd66
73+
resources:
74+
requests:
75+
cpu: "100m"
76+
memory: "64Mi"
77+
limits:
78+
cpu: "200m"
79+
memory: "128Mi"
80+
initContainers:
81+
- args:
82+
- -template
83+
- /configmap/nginx.conf.ctmpl:/config/nginx.conf
84+
- -log-level
85+
- trace
86+
- -once
87+
env:
88+
- name: CONSUL_ADDR
89+
valueFrom:
90+
fieldRef:
91+
apiVersion: v1
92+
fieldPath: status.hostIP
93+
- name: CONSUL_TEMPLATE_PREFIX
94+
valueFrom:
95+
configMapKeyRef:
96+
key: CONSUL_TEMPLATE_PREFIX
97+
name: global
98+
image: docker-hub.foo.bar/consul-template
99+
imagePullPolicy: Always
100+
name: consul-template
101+
resources:
102+
limits:
103+
cpu: 550m
104+
memory: 400Mi
105+
requests:
106+
cpu: 500m
107+
memory: 200Mi
108+
terminationMessagePath: /dev/termination-log
109+
terminationMessagePolicy: File
110+
volumeMounts:
111+
- mountPath: /configmap
112+
name: foo-configmap
113+
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
114+
name: default-token
115+
readOnly: true
116+
volumeMounts:
117+
- mountPath: /code/settings.py
118+
name: foo-config
119+
subPath: settings.py
120+
- mountPath: /code/application/gunicorn.conf
121+
name: bar-config
122+
subPath: gunicorn.conf
123+
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
124+
name: default-token
125+
readOnly: true
126+
volumes:
127+
- name: test-volume
128+
# This AWS EBS volume must already exist.
129+
awsElasticBlockStore:
130+
volumeID: "<volume id>"
131+
fsType: ext4
132+
- name: default-token
133+
secret:
134+
defaultMode: 420
135+
secretName: default-token
136+
- configMap:
137+
defaultMode: 420
138+
name: foo-configmap
139+
name: foo-configmap
140+
livenessProbe:
141+
failureThreshold: 5
142+
httpGet:
143+
path: /my-app/health
144+
port: 80
145+
scheme: HTTP
146+
initialDelaySeconds: 5
147+
periodSeconds: 20
148+
successThreshold: 1
149+
timeoutSeconds: 10
150+
readinessProbe:
151+
failureThreshold: 5
152+
httpGet:
153+
path: /my-app/health
154+
port: 80
155+
scheme: HTTP
156+
initialDelaySeconds: 5
157+
periodSeconds: 20
158+
successThreshold: 1
159+
timeoutSeconds: 10

docs/crd.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ It currently supports these parameters-
1212
- `flowerReplicas` - Number of flower pods to be run. Default is 1
1313
- `workerSpec` - Worker deployment-specific parameters
1414
+ `args` - Arguments to the celery worker command. The docker image's CMD is used if this is not provided. Similar to: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell
15-
+ `envs` - EnvVar represents an environment variable present in a Container. Similar to: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/
15+
+ `env` - EnvVar represents an environment variable present in a Container. Similar to: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/
1616
+ `nodeSelector` - A map of key-value pairs. For the pod/worker to be eligible to run on a node, the node must have each of the indicated key-value pairs as labels. Read more: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/
1717
+ `resources` - Compute Resources required by the worker container. Cannot be updated. Read more: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/
1818
- `flowerSpec` - Flower deployment specific parameters
1919
+ `args` - Arguments to the celery flower command. Similar to: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell
20-
+ `envs` - EnvVar represents an environment variable present in a Container. Similar to: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/
20+
+ `env` - EnvVar represents an environment variable present in a Container. Similar to: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/
2121
+ `nodeSelector` - A map of key-value pairs. For the pod/worker to be eligible to run on a node, the node must have each of the indicated key-value pairs as labels. Read more: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/
2222
+ `resources` - Compute Resources required by the worker container. Cannot be updated. Read more: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/
2323
+ `service` - Service defines the template for the associated Kubernetes Service object for exposing Flower UI. Read more: https://kubernetes.io/docs/concepts/services-networking/service/

handlers.py

Lines changed: 37 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,65 @@
1-
import os
2-
import kopf
3-
import kubernetes
4-
import requests
5-
import constants
61
from math import ceil
72
from collections import namedtuple
3+
import requests
4+
import kubernetes
5+
import kopf
6+
import constants
7+
from models.celery_custom_resource import celery_custom_resource_from_dict
8+
from kubernetes_utils.worker_deployment_generator import WorkerDeploymentGenerator
9+
from kubernetes_utils.flower_deployment_generator import FlowerDeploymentGenerator
810

9-
from deployment_utils import (
11+
from utilities.deployments import (
1012
deploy_celery_workers,
1113
deploy_flower,
1214
expose_flower_service
1315
)
14-
from update_utils import (
16+
from utilities.patching import (
1517
update_all_deployments,
1618
update_worker_deployment,
1719
update_flower_deployment
1820
)
1921

2022

2123
@kopf.on.create('celeryproject.org', 'v1alpha1', 'celery')
22-
def create_fn(spec, name, namespace, logger, **kwargs):
24+
def create_fn(spec, namespace, logger, **kwargs):
2325
"""
2426
Celery custom resource creation handler
2527
"""
26-
27-
# 1. Validation of spec
28-
val, err_msg = validate_spec(spec)
29-
if err_msg:
30-
status = 'Failed validation'
31-
raise kopf.PermanentError(f"{err_msg}. Got {val}")
32-
3328
api = kubernetes.client.CoreV1Api()
3429
apps_api_instance = kubernetes.client.AppsV1Api()
35-
36-
# 2. Deployment for celery workers
37-
worker_deployment = deploy_celery_workers(
38-
apps_api_instance, namespace, spec, logger
30+
try:
31+
celery_cr = celery_custom_resource_from_dict(dict(spec))
32+
except Exception as e:
33+
raise kopf.PermanentError(e)
34+
35+
# deploy worker
36+
worker_deployment = WorkerDeploymentGenerator(
37+
namespace=namespace, celery_cr=celery_cr
38+
).get_worker_deployment()
39+
kopf.adopt(worker_deployment)
40+
apps_api_instance.create_namespaced_deployment(
41+
namespace=namespace,
42+
body=worker_deployment
3943
)
4044

41-
# 3. Deployment for flower
42-
flower_deployment = deploy_flower(
43-
apps_api_instance, namespace, spec, logger
45+
# deploy flower
46+
flower_dep_gen_instance = FlowerDeploymentGenerator(
47+
namespace=namespace, celery_cr=celery_cr
4448
)
45-
46-
# 4. Expose flower service
47-
flower_svc = expose_flower_service(
48-
api, namespace, spec, logger
49+
flower_deployment = flower_dep_gen_instance.get_flower_deployment()
50+
kopf.adopt(flower_deployment)
51+
apps_api_instance.create_namespaced_deployment(
52+
namespace=namespace,
53+
body=flower_deployment
4954
)
5055

51-
children = [
52-
{
53-
'name': worker_deployment.metadata.name,
54-
'replicas': worker_deployment.spec.replicas,
55-
'kind': constants.DEPLOYMENT_KIND,
56-
'type': constants.WORKER_TYPE
57-
},
58-
{
59-
'name': flower_deployment.metadata.name,
60-
'replicas': flower_deployment.spec.replicas,
61-
'kind': constants.DEPLOYMENT_KIND,
62-
'type': constants.FLOWER_TYPE
63-
},
64-
{
65-
'name': flower_svc.metadata.name,
66-
'spec': flower_svc.spec.to_dict(),
67-
'kind': constants.SERVICE_KIND,
68-
'type': constants.FLOWER_TYPE
69-
}
70-
]
56+
# expose service
57+
flower_svc = flower_dep_gen_instance.get_flower_svc()
58+
kopf.adopt(flower_svc)
59+
api.create_namespaced_service(namespace=namespace, body=flower_svc)
7160

7261
return {
73-
'children': children,
74-
'children_count': len(children),
62+
'children': 3,
7563
'status': constants.STATUS_CREATED
7664
}
7765

@@ -172,7 +160,7 @@ def get_flower_svc_host(status):
172160

173161

174162
@kopf.timer('celeryproject.org', 'v1alpha1', 'celery',
175-
initial_delay=5, interval=10, idle=10)
163+
initial_delay=50000, interval=10000, idle=10)
176164
def message_queue_length(spec, status, **kwargs):
177165
flower_svc_host = get_flower_svc_host(status)
178166
if not flower_svc_host:
@@ -251,14 +239,3 @@ def validate_stuff(spec):
251239
2. Response and spec classes and enums
252240
"""
253241
pass
254-
255-
256-
def validate_spec(spec):
257-
"""
258-
Validates the incoming spec
259-
@returns - True/False, Error Message
260-
"""
261-
# size = spec.get('size')
262-
# if not size:
263-
# return size, "Size must be set"
264-
return None, None

kubernetes_utils/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)