initial bundle
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*~
|
||||
11
Containerfile
Normal file
11
Containerfile
Normal file
@@ -0,0 +1,11 @@
|
||||
FROM docker.eenfach.de/olbohlen/kshbase:latest
|
||||
LABEL author="Olaf Bohlen <olbohlen@eenfach.de>"
|
||||
|
||||
COPY receipt-processor.ksh /usr/local/bin/receipt-processor.ksh
|
||||
RUN chmod 755 /usr/local/bin/receipt-processor.ksh && \
|
||||
useradd cookie && \
|
||||
dnf install -y jq curl
|
||||
|
||||
USER cookie
|
||||
|
||||
ENTRYPOINT ["/usr/local/bin/receipt-processor.ksh"]
|
||||
97
cookie-crd.yaml
Normal file
97
cookie-crd.yaml
Normal file
@@ -0,0 +1,97 @@
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: cookiereceipts.de.eenfach.olbohlen
|
||||
spec:
|
||||
group: de.eenfach.olbohlen
|
||||
names:
|
||||
kind: CookieReceipt
|
||||
plural: cookiereceipts
|
||||
singular: cookiereceipt
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1
|
||||
served: true
|
||||
storage: true
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: "The CookieReceipt CRD is a k8s demo for enhancing functionality, it will not (unfortunately) provide you real cookies in the end..."
|
||||
type: object
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
type: string
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
type: object
|
||||
properties:
|
||||
description:
|
||||
type: string
|
||||
description: please describe the cookie
|
||||
source:
|
||||
type: string
|
||||
description: where does this come from? (grandma, mum, the internet...)
|
||||
ingredients:
|
||||
description: this list provides required ingredients for this receipt
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: specifies the ingredient
|
||||
amount:
|
||||
type: number
|
||||
description: the amount
|
||||
unit:
|
||||
type: string
|
||||
description: the unit for the amount
|
||||
remarks:
|
||||
type: string
|
||||
description: additional remarks, i.e. "grandma always used to..."
|
||||
required:
|
||||
- name
|
||||
- amount
|
||||
- unit
|
||||
steps:
|
||||
description: the actual preparation steps
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
order:
|
||||
type: integer
|
||||
description: the order number of the step
|
||||
instruction:
|
||||
type: string
|
||||
description: the instruction text for this step
|
||||
required:
|
||||
- order
|
||||
- instruction
|
||||
temperature:
|
||||
type: integer
|
||||
description: temperature for the oven
|
||||
sanescale:
|
||||
type: boolean
|
||||
description: if true or not defined, use Celsius-scale, else use Fahrenheit
|
||||
preheat:
|
||||
type: boolean
|
||||
description: shall the oven be pre-heated, assume yes if undefined
|
||||
duration:
|
||||
type: integer
|
||||
description: the amount of time in minutes to bake the cookies
|
||||
required:
|
||||
- ingredients
|
||||
- steps
|
||||
- temperature
|
||||
- duration
|
||||
43
cookie-rbac.yaml
Normal file
43
cookie-rbac.yaml
Normal file
@@ -0,0 +1,43 @@
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: cookiereceipt-edit
|
||||
rules:
|
||||
- apiGroups:
|
||||
- de.eenfach.olbohlen
|
||||
resources:
|
||||
- cookiereceipts
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: cookiereceipt-view
|
||||
rules:
|
||||
- apiGroups:
|
||||
- de.eenfach.olbohlen
|
||||
resources:
|
||||
- cookiereceipts
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: cookiereceipt-edit
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: cookiereceipt-edit
|
||||
subjects:
|
||||
- apiGroup: rbac.authorization.k8s.io
|
||||
kind: Group
|
||||
name: system:authenticated:oauth
|
||||
19
cookieprocessor-sa.yaml
Normal file
19
cookieprocessor-sa.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: cookieprocessor
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: cookiereceipt-view
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: cookiereceipt-view
|
||||
subjects:
|
||||
- apiGroup: rbac.authorization.k8s.io
|
||||
kind: ServiceAccount
|
||||
name: cookieprocessor
|
||||
116
receipt-processor.ksh
Normal file
116
receipt-processor.ksh
Normal file
@@ -0,0 +1,116 @@
|
||||
#!/usr/bin/ksh
|
||||
# by Olaf Bohlen <olbohlen@eenfach.de>
|
||||
# licensed under BSD3 license
|
||||
|
||||
APIURL="https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT_HTTPS}"
|
||||
NAMESPACE=$(</run/secrets/kubernetes.io/serviceaccount/namespace)
|
||||
TOKEN=$(</run/secrets/kubernetes.io/serviceaccount/token)
|
||||
CACRT="/run/secrets/kubernetes.io/serviceaccount/ca.crt"
|
||||
|
||||
# some associate arrays we need
|
||||
typeset -A receiptname
|
||||
typeset -A receiptversion
|
||||
|
||||
CURLOPTS='-s --cacert ${CACRT} -H "Accept: application/json" -H "User-Agent: ksh93 receipt processor 0.1" -H "Authorization: Bearer ${TOKEN}"'
|
||||
|
||||
updatedreceipts=""
|
||||
|
||||
while sleep 5; do
|
||||
# MAIN loop
|
||||
|
||||
# get a CookieReceiptList item from the API and store the json in a variable
|
||||
respjson=$(curl -XGET ${CURLOPTS} '${APIURL}/apis/de.eenfach.olbohlen/v1/namespaces/${NAMESPACE}/cookiereceipts?limit=500')
|
||||
|
||||
# check if we got the expected resource:
|
||||
kind=$(echo "${respjson}" | jq .kind)
|
||||
if [ x${kind} != 'x"CookieReceiptList"' ]; then
|
||||
printf "Error: unexpected Result from API\n"
|
||||
break ## jump out of this loop iteration
|
||||
fi
|
||||
|
||||
# how many receipts are there?
|
||||
numreceipts=$(echo "${respjson}" | jq .items[].metadata.name | wc -l)
|
||||
|
||||
# populate the in memory arrays with json metadata, we need
|
||||
# - the name
|
||||
# - the uid
|
||||
# - the resourceVersion
|
||||
# for every receipt to figure out if we need to process them
|
||||
i=0
|
||||
while [ ${i} -lt ${numreceipts} ]; do
|
||||
##foo[${xid}]=$(echo "${RESPJSON}" | jq .items[1].metadata.name)
|
||||
receiptuid=$(echo "${respjson}" | jq .items[${i}].metadata.uid)
|
||||
receiptname[${receiptuid}]=$(echo "${respjson}" | jq .items[${i}].metadata.name)
|
||||
|
||||
#receiptversion[${receiptuid}]=$(echo "${respjson}" | jq .items[${i}].metadata.resourceVersion)
|
||||
# check if we already have processed this version of the receipt, if not
|
||||
# store the uid of that receipt in the updatedreceipts var
|
||||
newversion=$(echo "${respjson}" | jq .items[${i}].metadata.resourceVersion)
|
||||
if [ "x${newversion}" != "x${receiptversion[${receiptuid}]}" ]; then
|
||||
# we have an update!
|
||||
updatedreceipts="${updatedreceipts} ${newversion}"
|
||||
receiptsversion[${receiptuid}]="${newversion}"
|
||||
fi
|
||||
i=$(( ${i} + 1 ))
|
||||
done
|
||||
# now that we have a list of updated receipts, we are going to process them
|
||||
for r in ${updatedreceipts}; do
|
||||
# get the name for the UID and fetch only that object
|
||||
receipt=$( curl -XGET ${CURLOPTS} '${APIURL}/apis/de.eenfach.olbohlen/v1/namespaces/${NAMESPACE}/cookiereceipts/${receiptname[${r}]}' )
|
||||
|
||||
# receipt contains now the json for one receipt, now we parse that
|
||||
# we set scale to Fahrenheit if sanescale is false, else scale will use Celsius
|
||||
scale_b=$( echo "${receipt}" | jq .spec.sanescale )
|
||||
if [ "x${sanescale}" == "xfalse" ]; then
|
||||
scale=Fahrenheit
|
||||
fi
|
||||
|
||||
temperature=$( echo ${receipt} | jq .spec.temperature )
|
||||
|
||||
preheat_b=$( echo "${receipt}" | jq .spec.preheat )
|
||||
if [ "x${preheat_b}" == "xtrue" ]; then
|
||||
printf "Pre: we heat up the oven to %s degrees %s\n" "${temperature}" "${scale:-Celsius}"
|
||||
fi
|
||||
|
||||
# how many ingredients do we have?
|
||||
num_in=$(echo "${receipt}" | jq .spec.ingredients[].name | wc -l)
|
||||
|
||||
# list up that we fetch needed ingredients
|
||||
i=0
|
||||
while [ ${i} -lt ${num_in} ]; do
|
||||
in_name=$( echo "${receipt}" | jq .spec.ingredients[${i}].name )
|
||||
in_amount=$( echo "${receipt}" | jq .spec.ingredients[${i}].amount )
|
||||
in_unit=$( echo "${receipt}" | jq .spec.ingredients[${i}].unit )
|
||||
in_remarks=$( echo "${receipt}" | jq .spec.ingredients[${i}].remarks )
|
||||
|
||||
printf "Fetching %s%s of %s" ${in_amount} ${in_unit} ${in_name}
|
||||
if [ "x${in_remarks}" != "xnull" ]; then
|
||||
printf " (%s)" ${in_remarks}
|
||||
fi
|
||||
printf "\n"
|
||||
sleep 1
|
||||
i=$(( ${i} + 1 ))
|
||||
done
|
||||
|
||||
|
||||
# now we need to (unfortunately just!) simulate the processing
|
||||
# the order of the steps is important, but lists are not ordered, so we have
|
||||
# an "order" attribute in each list item, and we select on that.
|
||||
# first again, we need the amount of instructions...
|
||||
|
||||
num_steps=$(echo "${receipt}" | jq .spec.steps[].order | wc -l)
|
||||
|
||||
# now let's iterate over that
|
||||
i=0
|
||||
while [ ${i} -lt ${num_steps} ]; do
|
||||
instruction=$( echo "${receipt}" | jq ".spec.steps[] | select(.order == ${i}) | { instruction | join (' ')" )
|
||||
##echo "${receipt}" | jq '.spec.steps[] | select(.order == 5) | { instruction } | join (" ")'
|
||||
printf "Step %i/%i: %s..." $(( ${i} + 1 )) ${num_steps} "${instruction}"
|
||||
sleep $(( ${RANDOM} % 6 + 1 ))
|
||||
printf "done\n"
|
||||
sleep 1
|
||||
i=$(( ${i} + 1 ))
|
||||
done
|
||||
done
|
||||
done
|
||||
|
||||
112
sample-cookie.yaml
Normal file
112
sample-cookie.yaml
Normal file
@@ -0,0 +1,112 @@
|
||||
apiVersion: de.eenfach.olbohlen/v1
|
||||
kind: CookieReceipt
|
||||
metadata:
|
||||
name: vintage-chocolate-chip
|
||||
spec:
|
||||
description: >-
|
||||
An easy chocolate chip cookie recipe for soft biscuits with a
|
||||
squidgy middle that will impress family and friends. Make plenty
|
||||
as they're sure to be a hit.
|
||||
source: https://www.bbcgoodfood.com/recipes/vintage-chocolate-chip-cookies
|
||||
temperature: 190
|
||||
sanescale: true
|
||||
preheat: true
|
||||
duration: 8
|
||||
ingredients:
|
||||
- name: salted butter
|
||||
amount: 150
|
||||
unit: grams
|
||||
remarks: softened
|
||||
- name: light brown muscovado sugar
|
||||
amount: 80
|
||||
unit: grams
|
||||
- name: granulated sugar
|
||||
amount: 80
|
||||
unit: grams
|
||||
- name: vanilla extract
|
||||
amount: 2
|
||||
unit: tea spoons
|
||||
- name: egg
|
||||
amount: 1
|
||||
unit: pieces
|
||||
remarks: large
|
||||
- name: plain flour
|
||||
amount: 225
|
||||
unit: grams
|
||||
- name: bicarbonate of soda
|
||||
amount: 0.5
|
||||
unit: tea spoons
|
||||
- name: salt
|
||||
amount: 0.25
|
||||
unit: tea spoons
|
||||
- name: plain chocolate chips
|
||||
amount: 200
|
||||
unit: grams
|
||||
remarks: or cut chocolate into small chunks
|
||||
steps:
|
||||
- order: 1
|
||||
instruction: Heat the oven and line two baking sheets with non-stick baking paper.
|
||||
- order: 2
|
||||
instruction: Put 150g softened salted butter, 80g light brown muscovado sugar and 80g granulated sugar into a bowl and beat until creamy.
|
||||
- order: 3
|
||||
instruction: Beat in 2 tsp vanilla extract and 1 large egg.
|
||||
- order: 4
|
||||
instruction: Sift 225g plain flour, ½ tsp bicarbonate of soda and ¼ tsp salt into the bowl and mix it in with a wooden spoon.
|
||||
- order: 5
|
||||
instruction: Add 200g plain chocolate chips or chunks and stir well.
|
||||
- order: 6
|
||||
instruction: Use a teaspoon to make small scoops of the mixture, spacing them well apart on the baking trays. This mixture should make about 30 cookies.
|
||||
- order: 7
|
||||
instruction: Bake for 8–10 mins until they are light brown on the edges and still slightly soft in the centre if you press them.
|
||||
- order: 8
|
||||
instruction: Leave on the tray for a couple of mins to set and then lift onto a cooling rack.
|
||||
---
|
||||
apiVersion: de.eenfach.olbohlen/v1
|
||||
kind: CookieReceipt
|
||||
metadata:
|
||||
name: double-dipped-shortbread
|
||||
spec:
|
||||
description: >-
|
||||
What could be better than shortbread biscuits? Shortbread double-dipped in milk
|
||||
and white chocolate! They are sure to go down a storm with family and friends
|
||||
source: https://www.bbcgoodfood.com/recipes/double-dipped-shortbread-cookies
|
||||
temperature: 180
|
||||
sanescale: true
|
||||
preheat: true
|
||||
duration: 8
|
||||
ingredients:
|
||||
- name: salted butter
|
||||
amount: 200
|
||||
unit: grams
|
||||
remarks: softened
|
||||
- name: icing sugar
|
||||
amount: 100
|
||||
unit: grams
|
||||
- name: vanilla extract
|
||||
amount: 1
|
||||
unit: tea spoons
|
||||
- name: plain flour
|
||||
amount: 250
|
||||
unit: grams
|
||||
- name: milk
|
||||
amount: 1
|
||||
unit: table spoons
|
||||
remarks: plus extra if needed
|
||||
- name: white chocolate
|
||||
amount: 50
|
||||
unit: grams
|
||||
remarks: chopped
|
||||
- name: milk chocolate
|
||||
amount: 50
|
||||
unit: grams
|
||||
remarks: chopped
|
||||
steps:
|
||||
- order: 1
|
||||
instruction: >-
|
||||
Heat the oven to 180C/160C fan/gas 4. Beat the butter with the icing sugar using an electric whisk until the mixture is light and fluffy. Beat in the vanilla and flour (the mixture will stiffen and look like crumble as the flour is added). Add the milk and keep beating until the mixture softens and sticks together (add some more milk if needed).
|
||||
- order: 2
|
||||
instruction: >-
|
||||
Scoop the dough into a piping bag fitted with a large star nozzle and pipe swirled rings onto a baking sheet lined with baking parchment. If the mixture is too stiff to pipe easily, you can roll the dough into balls and put them on the sheet instead. The cookies will spread as they cook so don’t worry if there’s a small gap in the centre of the piped swirls, but ensure there is enough space between each cookie so they don’t stick together as they cook. Bake for 15 mins, or until lightly golden, then transfer to a wire rack to cool.
|
||||
- order: 3
|
||||
instruction: >-
|
||||
Put the white and milk chocolate in separate bowls and microwave each in 20-second bursts until melted. Dip the cookies into each chocolate, milk at one end and white on the other, then let any excess drip off before returning them to the rack to set. Will keep in an airtight tin for up to four days.
|
||||
Reference in New Issue
Block a user