-
Notifications
You must be signed in to change notification settings - Fork 68
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add kn-py-slack Python example
Signed-off-by: Scottie Ray <sray@vmware.com>
- Loading branch information
Scottie Ray
committed
May 25, 2021
1 parent
198dc4f
commit e3b02a5
Showing
10 changed files
with
268 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
web: FLASK_ENV=development FLASK_APP=handler.py python3 -m flask run --host=0.0.0.0 --port=$PORT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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=<docker-username>/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 <docker-username>/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/<your slack token will appear> 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 <docker-username>/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 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
home = /usr/local/bin | ||
include-system-site-packages = false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
flask==1.1.2 | ||
cloudevents==1.2.0 | ||
requests==2.7.0 |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<ENTER YOUR SLACK WEBHOOK URL> |
1 change: 1 addition & 0 deletions
1
examples/knative/python/kn-py-slack/test/docker-test-env-variable
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
SLACK_SECRET=<YOUR SLACK WEBHOOK URL> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" | ||
} |