-
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 notification example using Telegram
Closes: #583 Signed-off-by: William Lam <wlam@vmware.com>
- Loading branch information
William Lam
committed
Sep 14, 2021
1 parent
34df8e1
commit 86a059f
Showing
11 changed files
with
442 additions
and
2 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
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,5 @@ | ||
FROM projects.registry.vmware.com/veba/ce-pcli-base:1.3 | ||
|
||
COPY handler.ps1 handler.ps1 | ||
|
||
CMD ["pwsh","./server.ps1"] |
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,149 @@ | ||
# kn-pcli-telegram | ||
Example Knative PowerCLI function for sending a [Telegram](https://telegram.org/) message when a VM is migrated and optionally filter by its location in a vSphere Resource Pool. | ||
|
||
![](screenshots/screenshots-01.png) | ||
|
||
# Step 1 - Build | ||
|
||
|
||
Create the container image locally to test your function logic. | ||
|
||
``` | ||
export TAG=<version> | ||
docker build -t <docker-username>/kn-pcli-telegram:${TAG} . | ||
``` | ||
|
||
# Step 2 - Test | ||
|
||
Verify the container image works by executing it locally. | ||
|
||
Change into the `test` directory | ||
```console | ||
cd test | ||
``` | ||
|
||
Update the following variable names within the `docker-test-env-variable` file | ||
|
||
* TELEGRAM_BOT_API_KEY - Telegram Bot API key | ||
* TELEGRAM_GROUP_CHAT_ID - Telegram Group Chat ID | ||
* VCENTER_RESOURCE_POOL_FILTER - Name of vSphere Resource Pool to filter for and only send Telegram if migrated VM is located in RP | ||
* VCENTER_SERVER - IP Address or FQDN of the vCenter Server to connect to check for parent vSphere Resource Pool | ||
* VCENTER_USERNAME - vCenter account with permission to check for parent vSphere Resource Pool | ||
* VCENTER_PASSWORD - vCenter credentials to account with permission to check for parent vSphere Resource Pool | ||
* VCENTER_CERTIFCATE_ACTION - Set-PowerCLIConfiguration Action to configure when connection fails due to certificate error, default is Fail. (Possible values: Fail, Ignore or Warn) | ||
|
||
Start the container image by running the following command: | ||
|
||
```console | ||
docker run -e FUNCTION_DEBUG=true -e PORT=8080 --env-file docker-test-env-variable -it --rm -p 8080:8080 <docker-username>/kn-pcli-telegram:${TAG} | ||
``` | ||
|
||
In a separate terminal, run either `send-cloudevent-test.ps1` (PowerShell Script) or `send-cloudevent-test.sh` (Bash Script) to simulate a CloudEvent payload being sent to the local container image | ||
|
||
```console | ||
Testing Function ... | ||
See docker container console for output | ||
|
||
# Output from docker container console | ||
08/11/2021 14:45:44 - PowerShell HTTP server start listening on 'http://*:8080/' | ||
08/11/2021 14:45:44 - Processing Init | ||
|
||
08/11/2021 14:45:44 - Configuring PowerCLI Configuration Settings | ||
|
||
08/11/2021 14:45:45 - Connecting to vCenter Server vcsa.primp-industries.local | ||
|
||
08/11/2021 14:46:15 - Successfully connected to vcsa.primp-industries.local | ||
|
||
08/11/2021 14:46:15 - Init Processing Completed | ||
|
||
08/11/2021 14:47:33 - DEBUG: K8s Secrets: | ||
{"TELEGRAM_BOT_API_KEY": "XXXXXX","TELEGRAM_GROUP_CHAT_ID": "XXXXXX","VCENTER_RESOURCE_POOL_FILTER": "Customer-A","VCENTER_SERVER": "vcsa.primp-industries.local","VCENTER_USERNAME" : "administrator@vsphere.local","VCENTER_PASSWORD" : "XXXXXX","VCENTER_CERTIFICATE_ACTION" : "Ignore"} | ||
|
||
08/11/2021 14:47:33 - DEBUG: CloudEventData | ||
|
||
Name Value | ||
---- ----- | ||
FullFormattedMessage Virtual machine TestVM-01 was migrated from host 192.168.30.101, vsanDatastore in … | ||
Dvs | ||
Net | ||
UserName VSPHERE.LOCAL\Administrator | ||
Datacenter {Name, Datacenter} | ||
CreatedTime 08/10/2021 18:20:24 | ||
ChainId 5636613 | ||
SourceHost {Name, Host} | ||
SourceDatacenter {Name, Datacenter} | ||
ComputeResource {Name, ComputeResource} | ||
Ds {Name, Datastore} | ||
Template False | ||
SourceDatastore {Name, Datastore} | ||
Key 5636626 | ||
ChangeTag | ||
Vm {Name, Vm} | ||
Host {Name, Host} | ||
|
||
|
||
|
||
08/11/2021 14:47:33 - Creating VM MoReF | ||
08/11/2021 14:47:33 - Retreiving parent Resource Pool | ||
08/11/2021 14:47:33 - Sending message to Telegram ... | ||
08/11/2021 14:47:33 - DEBUG: Telegram URL: | ||
https://api.telegram.org/botXXXXXX/sendMessage | ||
|
||
08/11/2021 14:47:33 - DEBUG: Telegram Message: | ||
TestVM-01 has been successfully migrated at 08/10/2021 18:20:24 | ||
|
||
08/11/2021 14:47:34 - Successfully sent Telegram message ... | ||
``` | ||
|
||
# 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-pcli-telegram:${TAG} | ||
``` | ||
|
||
Update the `telegram_secret.json` file with the required Telegram and vCenter Server configurations and then create the kubernetes secret which can then be accessed from within the function by using the environment variable named called `TELEGRAM_SECRET`. | ||
|
||
```console | ||
# create secret | ||
|
||
kubectl -n vmware-functions create secret generic telegram-secret --from-file=TELEGRAM_SECRET=telegram_secret.json | ||
|
||
# update label for secret to show up in VEBA UI | ||
kubectl -n vmware-functions label secret telegram-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 `VmMigratedEvent` 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 telegram-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,38 @@ | ||
apiVersion: serving.knative.dev/v1 | ||
kind: Service | ||
metadata: | ||
name: kn-pcli-telegram | ||
labels: | ||
app: veba-ui | ||
spec: | ||
template: | ||
metadata: | ||
annotations: | ||
autoscaling.knative.dev/maxScale: "1" | ||
autoscaling.knative.dev/minScale: "1" | ||
spec: | ||
containers: | ||
- image: projects.registry.vmware.com/veba/kn-pcli-telegram:1.0 | ||
envFrom: | ||
- secretRef: | ||
name: telegram-secret | ||
env: | ||
- name: FUNCTION_DEBUG | ||
value: "false" | ||
--- | ||
apiVersion: eventing.knative.dev/v1 | ||
kind: Trigger | ||
metadata: | ||
name: veba-pcli-telegram-trigger | ||
labels: | ||
app: veba-ui | ||
spec: | ||
broker: default | ||
filter: | ||
attributes: | ||
subject: VmMigratedEvent | ||
subscriber: | ||
ref: | ||
apiVersion: serving.knative.dev/v1 | ||
kind: Service | ||
name: kn-pcli-telegram |
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,134 @@ | ||
Function Process-Init { | ||
[CmdletBinding()] | ||
param() | ||
Write-Host "$(Get-Date) - Processing Init`n" | ||
|
||
try { | ||
$jsonSecrets = ${env:TELEGRAM_SECRET} | ConvertFrom-Json | ||
} catch { | ||
throw "`nK8s secrets `$env:TELEGRAM_SECRET does not look to be defined" | ||
} | ||
|
||
# Extract all telegram secrets for ease of use in function | ||
$VCENTER_SERVER = ${jsonSecrets}.VCENTER_SERVER | ||
$VCENTER_USERNAME = ${jsonSecrets}.VCENTER_USERNAME | ||
$VCENTER_PASSWORD = ${jsonSecrets}.VCENTER_PASSWORD | ||
$VCENTER_CERTIFICATE_ACTION = ${jsonSecrets}.VCENTER_CERTIFICATE_ACTION | ||
|
||
# Configure TLS 1.2/1.3 support as this is required for latest vSphere release | ||
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor [System.Net.SecurityProtocolType]::Tls12 -bor [System.Net.SecurityProtocolType]::Tls13 | ||
|
||
Write-Host "$(Get-Date) - Configuring PowerCLI Configuration Settings`n" | ||
Set-PowerCLIConfiguration -InvalidCertificateAction:${VCENTER_CERTIFICATE_ACTION} -ParticipateInCeip:$true -Confirm:$false | ||
|
||
Write-Host "$(Get-Date) - Connecting to vCenter Server $VCENTER_SERVER`n" | ||
|
||
try { | ||
Connect-VIServer -Server $VCENTER_SERVER -User $VCENTER_USERNAME -Password $VCENTER_PASSWORD | ||
} catch { | ||
Write-Error "$(Get-Date) - Failed to connect to vCenter Server" | ||
throw $_ | ||
} | ||
|
||
Write-Host "$(Get-Date) - Successfully connected to $VCENTER_SERVER`n" | ||
|
||
Write-Host "$(Get-Date) - Init Processing Completed`n" | ||
} | ||
|
||
Function Process-Shutdown { | ||
[CmdletBinding()] | ||
param() | ||
Write-Host "$(Get-Date) - Processing Shutdown`n" | ||
|
||
Write-Host "$(Get-Date) - Disconnecting from vCenter Server`n" | ||
|
||
try { | ||
Disconnect-VIServer * -Confirm:$false | ||
} catch { | ||
Write-Error "$(Get-Date) - Failed to Disconnect from vCenter Server" | ||
} | ||
|
||
Write-Host "$(Get-Date) - Shutdown Processing Completed`n" | ||
} | ||
|
||
Function Process-Handler { | ||
[CmdletBinding()] | ||
param( | ||
[Parameter(Position=0,Mandatory=$true)][CloudNative.CloudEvents.CloudEvent]$CloudEvent | ||
) | ||
|
||
# Decode CloudEvent | ||
try { | ||
$cloudEventData = $cloudEvent | Read-CloudEventJsonData -Depth 10 | ||
} catch { | ||
throw "`nPayload must be JSON encoded" | ||
} | ||
|
||
try { | ||
$jsonSecrets = ${env:TELEGRAM_SECRET} | ConvertFrom-Json | ||
} catch { | ||
throw "`nK8s secrets `$env:TELEGRAM_SECRET does not look to be defined" | ||
} | ||
|
||
if(${env:FUNCTION_DEBUG} -eq "true") { | ||
Write-Host "$(Get-Date) - DEBUG: K8s Secrets:`n${env:TELEGRAM_SECRET}`n" | ||
|
||
Write-Host "$(Get-Date) - DEBUG: CloudEventData`n $(${cloudEventData} | Out-String)`n" | ||
} | ||
|
||
$sendTelegram = $true | ||
|
||
# Ignore ResourcePool filter if not provided | ||
if(${jsonSecrets}.VCENTER_RESOURCE_POOL_FILTER -ne $NULL) { | ||
|
||
try { | ||
Write-Host "$(Get-Date) - Creating VM MoReF" | ||
|
||
# Construct VM Object given the MoRef ID from CloudEvent | ||
$moRef = New-Object VMware.Vim.ManagedObjectReference | ||
$moRef.Type = "VirtualMachine" | ||
$moRef.Value = ${cloudEventData}.Vm.Vm.Value | ||
|
||
$vm = Get-View $moRef | ||
} catch { | ||
throw "`Unable to construct VM Object using MoRef ID: $(${cloudEventData}.Vm.Vm.Value)" | ||
} | ||
|
||
# Retrieve the parent ResourcePool and only request the Name property | ||
try { | ||
Write-Host "$(Get-Date) - Retreiving parent Resource Pool" | ||
$rp = Get-View $vm.ResourcePool -Property Name | ||
} catch { | ||
throw "`Unable to retrieve parent Resource Pool" | ||
} | ||
|
||
# Check whether RP name matches filter, do not send telegram message if it does not match | ||
if($rp.name -ne ${jsonSecrets}.VCENTER_RESOURCE_POOL_FILTER) { | ||
$sendTelegram = $false | ||
} | ||
|
||
} | ||
|
||
$telegramMessage = "$(${cloudEventData}.Vm.Name) has been successfully migrated at $(${cloudEventData}.CreatedTime)" | ||
|
||
if($sendTelegram) { | ||
Write-Host "$(Get-Date) - Sending message to Telegram ..." | ||
$ProgressPreference = "SilentlyContinue" | ||
|
||
$telegramUrl = "https://api.telegram.org/bot$(${jsonSecrets}.TELEGRAM_BOT_API_KEY)/sendMessage" | ||
|
||
if(${env:FUNCTION_DEBUG} -eq "true") { | ||
Write-Host "$(Get-Date) - DEBUG: Telegram URL:`n`t${telegramUrl}`n" | ||
|
||
Write-Host "$(Get-Date) - DEBUG: Telegram Message:`n`t${telegramMessage}`n" | ||
} | ||
|
||
try { | ||
Invoke-WebRequest -Method POST -Uri $telegramUrl -ContentType "application/json;charset=utf-8" -Body (ConvertTo-Json -Compress -InputObject @{chat_id="$(${jsonSecrets}.TELEGRAM_GROUP_CHAT_ID)";text=$telegramMessage}) | ||
} catch { | ||
throw "$(Get-Date) - Failed to send SMS: $($_)" | ||
} | ||
|
||
Write-Host "$(Get-Date) - Successfully sent Telegram message ..." | ||
} | ||
} |
Binary file added
BIN
+51.8 KB
examples/knative/powercli/kn-pcli-telegram/screenshots/screenshots-01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions
9
examples/knative/powercli/kn-pcli-telegram/telegram_secret.json
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,9 @@ | ||
{ | ||
"TELEGRAM_BOT_API_KEY": "FILL-ME-IN", | ||
"TELEGRAM_GROUP_CHAT_ID": "FILL-ME-IN", | ||
"VCENTER_RESOURCE_POOL_FILTER": "FILL-ME-IN-OR-REMOVE-THIS-LINE", | ||
"VCENTER_SERVER": "FILL-ME-IN", | ||
"VCENTER_USERNAME" : "FILL-ME-IN", | ||
"VCENTER_PASSWORD" : "FILL-ME-IN", | ||
"VCENTER_CERTIFICATE_ACTION" : "Fail" | ||
} |
1 change: 1 addition & 0 deletions
1
examples/knative/powercli/kn-pcli-telegram/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 @@ | ||
TELEGRAM_SECRET={"TELEGRAM_BOT_API_KEY": "FILL-ME-IN","TELEGRAM_GROUP_CHAT_ID": "FILL-ME-IN","VCENTER_RESOURCE_POOL_FILTER": "FILL-ME-IN-OR-REMOVE-THIS-LINE","VCENTER_SERVER": "FILL-ME-IN","VCENTER_USERNAME" : "FILL-ME-IN","VCENTER_PASSWORD" : "FILL-ME-IN","VCENTER_CERTIFICATE_ACTION" : "Fail"} |
16 changes: 16 additions & 0 deletions
16
examples/knative/powercli/kn-pcli-telegram/test/send-cloudevent-test.ps1
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,16 @@ | ||
|
||
$headers = @{ | ||
"Content-Type" = "application/json"; | ||
"ce-specversion" = "1.0"; | ||
"ce-id" = "41289fef-0727-46f7-b1a9-b8145972c734"; | ||
"ce-source" = "https://vcenter.local/sdk"; | ||
"ce-type" = "com.vmware.event.router/event"; | ||
"ce-subject" = "VmMigratedEvent"; | ||
} | ||
|
||
$body = Get-Content -Raw -Path "./test-payload.json" | ||
|
||
Write-Host "Testing Function ..." | ||
Invoke-WebRequest -Uri http://localhost:8080 -Method POST -Headers $headers -Body $body | ||
|
||
Write-host "See docker container console for output" |
13 changes: 13 additions & 0 deletions
13
examples/knative/powercli/kn-pcli-telegram/test/send-cloudevent-test.sh
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,13 @@ | ||
#!/bin/bash | ||
|
||
echo "Testing Function ..." | ||
curl -i -vvv -d@test-payload.json \ | ||
-H "Content-Type: application/json" \ | ||
-H 'ce-specversion: 1.0' \ | ||
-H 'ce-id: 41289fef-0727-46f7-b1a9-b8145972c734' \ | ||
-H 'ce-source: https://vcenter.local/sdk' \ | ||
-H 'ce-type: com.vmware.event.router/event' \ | ||
-H 'ce-subject: VmMigratedEvent' \ | ||
-X POST localhost:8080 | ||
|
||
echo "See docker container console for output" |
Oops, something went wrong.