Skip to content

Commit be78c13

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

21 files changed

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