From e3b02a5ac2c1c9bf5241c6e135d80ae0fec51e67 Mon Sep 17 00:00:00 2001 From: Scottie Ray Date: Tue, 25 May 2021 14:19:05 -0500 Subject: [PATCH] feat: Add kn-py-slack Python example Signed-off-by: Scottie Ray --- examples/knative/python/kn-py-slack/Procfile | 1 + examples/knative/python/kn-py-slack/README.md | 115 ++++++++++++++++++ .../knative/python/kn-py-slack/function.yaml | 40 ++++++ .../knative/python/kn-py-slack/handler.py | 56 +++++++++ .../knative/python/kn-py-slack/pyvenv.cfg | 2 + .../python/kn-py-slack/requirements.txt | 3 + .../kn-py-slack/screenshots/Test_Event.png | Bin 0 -> 41653 bytes .../python/kn-py-slack/slack_secret.txt | 1 + .../kn-py-slack/test/docker-test-env-variable | 1 + .../python/kn-py-slack/test/testevent.json | 49 ++++++++ 10 files changed, 268 insertions(+) create mode 100644 examples/knative/python/kn-py-slack/Procfile create mode 100644 examples/knative/python/kn-py-slack/README.md create mode 100644 examples/knative/python/kn-py-slack/function.yaml create mode 100644 examples/knative/python/kn-py-slack/handler.py create mode 100644 examples/knative/python/kn-py-slack/pyvenv.cfg create mode 100644 examples/knative/python/kn-py-slack/requirements.txt create mode 100644 examples/knative/python/kn-py-slack/screenshots/Test_Event.png create mode 100644 examples/knative/python/kn-py-slack/slack_secret.txt create mode 100644 examples/knative/python/kn-py-slack/test/docker-test-env-variable create mode 100644 examples/knative/python/kn-py-slack/test/testevent.json diff --git a/examples/knative/python/kn-py-slack/Procfile b/examples/knative/python/kn-py-slack/Procfile new file mode 100644 index 00000000..760d3af1 --- /dev/null +++ b/examples/knative/python/kn-py-slack/Procfile @@ -0,0 +1 @@ +web: FLASK_ENV=development FLASK_APP=handler.py python3 -m flask run --host=0.0.0.0 --port=$PORT \ No newline at end of file diff --git a/examples/knative/python/kn-py-slack/README.md b/examples/knative/python/kn-py-slack/README.md new file mode 100644 index 00000000..fbeefe69 --- /dev/null +++ b/examples/knative/python/kn-py-slack/README.md @@ -0,0 +1,115 @@ +# kn-py-slack +Example Knative Python function for sending to a Slack webhook when a Virtual Machine is powered off. + +# Step 1 - Build with `pack` + +[Buildpacks](https://buildpacks.io) are used to create the container image. + +```bash +IMAGE=/kn-py-slack:1.0 +pack build -B gcr.io/buildpacks/builder:v1 ${IMAGE} +``` + + +# Step 2 - Test + +Verify the container image works by executing it locally. + +Change into the `test` directory +```console +cd test +``` + +Update the `docker-test-env-variable` file with your Slack webook URL. + +Start the container image by running the following command: + +```console +docker run -e PORT=8080 --env-file docker-test-env-variable -it --rm -p 8080:8080 /kn-py-slack:1.0 + +Serving Flask app "handler.py" (lazy loading) + * Environment: development + * Debug mode: on + * Running on all addresses. + WARNING: This is a development server. Do not use it in a production deployment. + * Running on http://172.17.0.2:8080/ (Press CTRL+C to quit) + * Restarting with stat + * Debugger is active! + ``` + +In a separate terminal window, go to the test directory and use the `testevent.json` file to validate the function is working. You should see output similar to this below. + +``` +curl -i -d@testevent.json localhost:8080 + +HTTP/1.1 100 Continue + +HTTP/1.0 200 OK +Content-Type: application/json +Content-Length: 3 +Server: Werkzeug/1.0.1 Python/3.9.0 +Date: Tue, 25 May 2021 13:59:31 GMT +``` +Return to the previous terminal window where you started the docker image, and you should see something similar to the following: + +``` +2021-05-25 08:59:28,400 INFO werkzeug MainThread : * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) +2021-05-25 08:59:31,423 DEBUG urllib3.connectionpool Thread-1 : Starting new HTTPS connection (1): hooks.slack.com:443 +2021-05-25 08:59:31,614 DEBUG urllib3.connectionpool Thread-1 : https://hooks.slack.com:443 "POST /services/ HTTP/1.1" 200 22 +2021-05-25 08:59:31,618 INFO werkzeug Thread-1 : 127.0.0.1 - - [25/May/2021 08:59:31] "POST / HTTP/1.1" 200 - +``` + + +Finally, check your Slack channel to see if the test event posted. + +![](screenshots/Test_Event.png) + +# Step 3 - Deploy + +> **Note:** The following steps assume a working Knative environment using the +`default` Rabbit `broker`. The Knative `service` and `trigger` will be installed in the +`vmware-functions` Kubernetes namespace, assuming that the `broker` is also available there. + +Push your container image to an accessible registry such as Docker once you're done developing and testing your function logic. + +```console +docker push /kn-py-slack:1.0 +``` + +Update the `slack_secret.json` file with your Slack webhook configurations and then create the kubernetes secret which can then be accessed from within the function by using the environment variable named called `SLACK_SECRET`. + +```console +# create secret +kubectl -n vmware-functions create secret generic slack-secret --from-file=SLACK_SECRET=slack_secret.txt + +# update label for secret to show up in VEBA UI +kubectl -n vmware-functions label secret slack-secret app=veba-ui +``` + +Edit the `function.yaml` file with the name of the container image from Step 1 if you made any changes. If not, the default VMware container image will suffice. By default, the function deployment will filter on the `VmPoweredOffEvent` vCenter Server Event. If you wish to change this, update the `subject` field within `function.yaml` to the desired event type. + + +Deploy the function to the VMware Event Broker Appliance (VEBA). + +```console +# deploy function +kubectl -n vmware-functions apply -f function.yaml +``` + +For testing purposes, the `function.yaml` contains the following annotations, which will ensure the Knative Service Pod will always run **exactly** one instance for debugging purposes. Functions deployed through through the VMware Event Broker Appliance UI defaults to scale to 0, which means the pods will only run when it is triggered by an vCenter Event. + +```yaml +annotations: + autoscaling.knative.dev/maxScale: "1" + autoscaling.knative.dev/minScale: "1" +``` + +# Step 4 - Undeploy + +```console +# undeploy function +kubectl -n vmware-functions delete -f function.yaml + +# delete secret +kubectl -n vmware-functions delete secret slack-secret +``` diff --git a/examples/knative/python/kn-py-slack/function.yaml b/examples/knative/python/kn-py-slack/function.yaml new file mode 100644 index 00000000..2363714d --- /dev/null +++ b/examples/knative/python/kn-py-slack/function.yaml @@ -0,0 +1,40 @@ +apiVersion: serving.knative.dev/v1 +kind: Service +metadata: + name: kn-py-slack + labels: + app: veba-ui + template: + metadata: + annotations: + autoscaling.knative.dev/maxScale: "1" + autoscaling.knative.dev/minScale: "1" +spec: + template: + metadata: + spec: + containers: + - image: projects.registry.vmware.com/veba/kn-py-slack:1.0 + envFrom: + - secretRef: + name: slack-secret + +--- +apiVersion: eventing.knative.dev/v1 +kind: Trigger +metadata: + name: veba-py-slack-trigger + labels: + app: veba-ui +spec: + broker: default + filter: + attributes: + type: com.vmware.event.router/event + subject: VmPoweredOffEvent + subscriber: + ref: + apiVersion: serving.knative.dev/v1 + kind: Service + name: kn-py-slack + diff --git a/examples/knative/python/kn-py-slack/handler.py b/examples/knative/python/kn-py-slack/handler.py new file mode 100644 index 00000000..16ac1ddb --- /dev/null +++ b/examples/knative/python/kn-py-slack/handler.py @@ -0,0 +1,56 @@ +from flask import Flask, request, jsonify +import os +import requests +from cloudevents.http import from_http +import logging,json + +logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(levelname)s %(name)s %(threadName)s : %(message)s') + +app = Flask(__name__) +#Change the value to match the secret key in the VEBA appliance where you enter the Slack webook url information +#url = os.environ.get('SLACK_SECRET') + +@app.route('/', methods=['POST']) +def slack(): + + try: + event = from_http(request.headers, request.get_data(),None) + + data = event.data + attrs = event._attributes + + #this section uses the Slack formatting to present the events in the format you would like. You can modify as needed to add, remove or re-order the elements in a message + payload = { "text": f"*CLOUDEVENT_ID*:\n {attrs['id']}\n\n Source: {attrs['source']}\n Type: {attrs['type']}\n *Subject*: *{attrs['subject']}*\n Time: {attrs['time']}\n\n *EVENT DATA*:\n key: {data['Key']}\n user: {data['UserName']}\n datacenter: {data['Datacenter']['Name']}\n Host: {data['Host']['Name']}\n VM: {data['Vm']['Name']}\n\n Message: {data['FullFormattedMessage']}" } + + requests.post(url=url, json=payload) + + # app.logger.info(f'"***cloud event*** {json.dumps(e)}') + return {}, 200 + + except KeyError as e: + sc = 400 + msg = f'could not decode cloud event: {e}' + app.logger.error(msg) + message = { + 'status': sc, + 'error': msg, + } + resp = jsonify(message) + resp.status_code = sc + return resp + + except Exception as e: + sc = 500 + msg = f'could not send message: {e}' + app.logger.error(msg) + message = { + 'status': sc, + 'error': msg, + } + resp = jsonify(message) + resp.status_code = sc + return resp + +# hint: run with FLASK_ENV=development FLASK_APP=handler.py flask run +if __name__ == "__main__": + app.run() diff --git a/examples/knative/python/kn-py-slack/pyvenv.cfg b/examples/knative/python/kn-py-slack/pyvenv.cfg new file mode 100644 index 00000000..44b2a58c --- /dev/null +++ b/examples/knative/python/kn-py-slack/pyvenv.cfg @@ -0,0 +1,2 @@ +home = /usr/local/bin +include-system-site-packages = false \ No newline at end of file diff --git a/examples/knative/python/kn-py-slack/requirements.txt b/examples/knative/python/kn-py-slack/requirements.txt new file mode 100644 index 00000000..d4ac1ed0 --- /dev/null +++ b/examples/knative/python/kn-py-slack/requirements.txt @@ -0,0 +1,3 @@ +flask==1.1.2 +cloudevents==1.2.0 +requests==2.7.0 \ No newline at end of file diff --git a/examples/knative/python/kn-py-slack/screenshots/Test_Event.png b/examples/knative/python/kn-py-slack/screenshots/Test_Event.png new file mode 100644 index 0000000000000000000000000000000000000000..224ec1d13cd032a041b628efa1e723e22e5353f2 GIT binary patch literal 41653 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 W6?(SMtEbn%pPG{9qY4Gf@c#kt$gb@G literal 0 HcmV?d00001 diff --git a/examples/knative/python/kn-py-slack/slack_secret.txt b/examples/knative/python/kn-py-slack/slack_secret.txt new file mode 100644 index 00000000..6983a0a5 --- /dev/null +++ b/examples/knative/python/kn-py-slack/slack_secret.txt @@ -0,0 +1 @@ + diff --git a/examples/knative/python/kn-py-slack/test/docker-test-env-variable b/examples/knative/python/kn-py-slack/test/docker-test-env-variable new file mode 100644 index 00000000..4c429654 --- /dev/null +++ b/examples/knative/python/kn-py-slack/test/docker-test-env-variable @@ -0,0 +1 @@ +SLACK_SECRET= diff --git a/examples/knative/python/kn-py-slack/test/testevent.json b/examples/knative/python/kn-py-slack/test/testevent.json new file mode 100644 index 00000000..8507c32f --- /dev/null +++ b/examples/knative/python/kn-py-slack/test/testevent.json @@ -0,0 +1,49 @@ +{ + "id": "08179137-b8e0-4973-b05f-8f212bf5003b", + "source": "https://10.0.0.1:443/sdk", + "specversion": "1.0", + "type": "com.vmware.event.router/event", + "subject": "VmPoweredOffEvent", + "time": "2020-02-11T21:29:54.9052539Z", + "data": { + "Key": 9902, + "ChainId": 9895, + "CreatedTime": "2020-02-11T21:28:23.677595Z", + "UserName": "VSPHERE.LOCAL\\Administrator", + "Datacenter": { + "Name": "testDC", + "Datacenter": { + "Type": "Datacenter", + "Value": "datacenter-2" + } + }, + "ComputeResource": { + "Name": "cls", + "ComputeResource": { + "Type": "ClusterComputeResource", + "Value": "domain-c7" + } + }, + "Host": { + "Name": "10.185.22.74", + "Host": { + "Type": "HostSystem", + "Value": "host-21" + } + }, + "Vm": { + "Name": "test-01", + "Vm": { + "Type": "VirtualMachine", + "Value": "vm-56" + } + }, + "Ds": null, + "Net": null, + "Dvs": null, + "FullFormattedMessage": "test-01 on 10.0.0.1 in testDC is powered off", + "ChangeTag": "", + "Template": false + }, + "datacontenttype": "application/json" +}