-
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: PowerCLI example function to enforce VDS pg configs
Closes #771 Signed-off-by: Patrick Kremer <pkremer@vmware.com>
- Loading branch information
Patrick Kremer
committed
Feb 7, 2022
1 parent
02101d0
commit fdf5c64
Showing
9 changed files
with
508 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,5 @@ | ||
FROM us.gcr.io/daisy-284300/veba/ce-pcli-base:1.4 | ||
|
||
COPY handler.ps1 handler.ps1 | ||
|
||
CMD ["pwsh","./server.ps1"] |
187 changes: 187 additions & 0 deletions
187
examples/knative/powercli/kn-pcli-vds-pg-config/README.md
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,187 @@ | ||
# kn-pcli-vds-pg-config | ||
Example Knative PowerCLI function for enforcing specific VDS portgroup configuration - automatically reset portgroup `Notify Switches` value to desired state | ||
|
||
# Step 1 - Build | ||
|
||
> **Note:** This step is only required if you made code changes to `handler.ps1` | ||
> or `Dockerfile`. | ||
Create the container image locally to test your function logic. | ||
|
||
Mac/Linux | ||
``` | ||
# change the IMAGE name accordingly, example below for Docker | ||
export IMAGE=<docker-username>/kn-pcli-vds-pg-config:1.0 | ||
docker build -t ${IMAGE} . | ||
``` | ||
|
||
Windows | ||
``` | ||
# change the IMAGE name accordingly, example below for Docker | ||
$IMAGE="<docker-username>/kn-pcli-vds-pg-config:1.0" | ||
docker build -t ${IMAGE} . | ||
``` | ||
# 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 | ||
|
||
* `VCENTER_SERVER` - IP Address or FQDN of the vCenter Server to connect to | ||
* `VCENTER_USERNAME` - vCenter account with permission to reconfigure distributed virtual switches | ||
* `VCENTER_PASSWORD` - vCenter password associated with the username | ||
* `VCENTER_CERTIFCATE_ACTION` - Set-PowerCLIConfiguration Action to configure when connection fails due to certificate error, default is Fail. (Possible values: Fail, Ignore or Warn) | ||
* `NOTIFY_SWITCHES` - Enforce this teaming policy configuration (Possible values: True, False)) | ||
|
||
If you built a custom image in Step 1, comment out the default `IMAGE` command below - the `docker run` command will then use use the value previously stored in the `IMAGE` variable. Otherwise, use the default image as shown below. Start the container image by running the following commands: | ||
|
||
Mac/Linux | ||
```console | ||
export IMAGE=us.gcr.io/daisy-284300/veba/kn-pcli-vds-pg-config:1.0 | ||
docker run -e FUNCTION_DEBUG=true -e PORT=8080 --env-file docker-test-env-variable -it --rm -p 8080:8080 ${IMAGE} | ||
``` | ||
Windows | ||
```console | ||
IMAGE="us.gcr.io/daisy-284300/veba/kn-pcli-vds-pg-config:1.0" | ||
docker run -e FUNCTION_DEBUG=true -e PORT=8080 --env-file docker-test-env-variable -it --rm -p 8080:8080 ${IMAGE} | ||
``` | ||
|
||
In the `test` directory, edit `test-payload.json`. Locate the `Dvs` section of the JSON file. Change the `Name:` property from `REPLACE-ME` to the name of a distributed virtual switch currently in your vCenter inventory. Locate the `Net` section of the JSON file. Change the `Name:` property to the name of a distributed portgroup on the distributed virtual switch from the previous step. If you do not make these changes, the function will still be invoked, but the configuration operation will fail because the objects will not be found. | ||
|
||
```json | ||
"Net": { | ||
"Name": "REPLACE-ME", | ||
"Network": { | ||
"Type": "DistributedVirtualPortgroup", | ||
"Value": "dvportgroup-7007" | ||
} | ||
}, | ||
"Dvs": { | ||
"Name": "REPLACE-ME", | ||
"Dvs": { | ||
"Type": "DistributedVirtualSwitch", | ||
"Value": "dvs-7005" | ||
} | ||
} | ||
``` | ||
**WARNING** - This function will reconfigure your distributed virtual switch - it will set the `Notify Switches` property of the portgroup to the value specified in `vds_pg_secret.json` | ||
|
||
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 | ||
05/26/2021 13:46:44 - PowerShell HTTP server start listening on 'http://*:8080/' | ||
05/26/2021 13:46:44 - Processing Init | ||
|
||
05/26/2021 13:46:44 - Configuring PowerCLI Configuration Settings | ||
|
||
05/26/2021 13:46:44 - Connecting to vCenter Server vcsa.primp-industries.local | ||
|
||
05/26/2021 13:47:19 - Successfully connected to vcsa.primp-industries.local | ||
|
||
05/26/2021 13:47:19 - Init Processing Completed | ||
|
||
05/26/2021 13:47:32 - Processing Handler | ||
|
||
05/26/2021 13:47:32 - Start CloudEvent Decode | ||
|
||
05/26/2021 13:47:32 - CloudEvent Decode Complete | ||
|
||
DEBUG: K8s Secrets: | ||
{"VCENTER_SERVER":"vcsa.primp-industries.local","VCENTER_USERNAME":"administrator@vsphere.local","VCENTER_PASSWORD":"****","VCENTER_TAG_NAME":"Demo"} | ||
|
||
DEBUG: CloudEventData | ||
|
||
Name Value | ||
---- ----- | ||
Dvs {Dvs, Name} | ||
UserName VSPHERE.LOCAL\Administrator | ||
Host | ||
ConfigSpec {MaxPorts, ExtensionKey, Host, Name…} | ||
Key 567176 | ||
ComputeResource | ||
Ds | ||
Vm | ||
ConfigChanges {Modified, Added, Deleted} | ||
ChangeTag | ||
Net | ||
CreatedTime 12/19/2021 21:01:35 | ||
FullFormattedMessage The vSphere Distributed Switch dvsTest in HomeLab was reconfigured. … | ||
Datacenter {Datacenter, Name} | ||
ChainId 567175 | ||
|
||
Found VDS name dvsTest | ||
Setting Notify Switches to False | ||
|
||
12/19/2021 21:01:39 - VDS portgroup reconfig operation complete ... | ||
|
||
12/19/2021 21:01:39 - Handler Processing Completed ... | ||
``` | ||
|
||
> Pro Tip - If you are rapidly iterating on the code and want to easily rebuild and launch the container, | ||
> you can chain all of the commands together with ampersands. This will allow you to re-run | ||
> the commands by simply pressing the `up` arrow and `Enter`. | ||
```console | ||
cd .. && docker build -t ${IMAGE} . && cd test && docker run -e FUNCTION_DEBUG=true -e PORT=8080 --env-file docker-test-env-variable -it --rm -p 8080:8080 ${IMAGE} | ||
``` | ||
# 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. | ||
|
||
If you built a custom image, push it to an accessible registry such as Docker once you're done developing and testing your function logic. | ||
|
||
```console | ||
docker push ${IMAGE} | ||
``` | ||
|
||
Update the `vds_pg_secret.json` file with your vCenter Server credentials and configurations and then create the kubernetes secret which can then be accessed from within the function by using the environment variable named called `VDS_SECRET`. | ||
|
||
```console | ||
# create secret | ||
|
||
kubectl -n vmware-functions create secret generic vds-pg-secret --from-file=VDS_SECRET=vds_pg_secret.json | ||
|
||
# update label for secret to show up in VEBA UI | ||
kubectl -n vmware-functions label secret vds-pg-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 `DvsReconfiguredEvent` 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 vds-pg-secret | ||
``` |
39 changes: 39 additions & 0 deletions
39
examples/knative/powercli/kn-pcli-vds-pg-config/function.yaml
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,39 @@ | ||
apiVersion: serving.knative.dev/v1 | ||
kind: Service | ||
metadata: | ||
name: kn-pcli-vds-pg-config | ||
labels: | ||
app: veba-ui | ||
spec: | ||
template: | ||
metadata: | ||
annotations: | ||
autoscaling.knative.dev/maxScale: "1" | ||
autoscaling.knative.dev/minScale: "1" | ||
spec: | ||
containers: | ||
- image: us.gcr.io/daisy-284300/veba/kn-pcli-vds-pg-config:1.0 | ||
envFrom: | ||
- secretRef: | ||
name: vds-pg-secret | ||
env: | ||
- name: FUNCTION_DEBUG | ||
value: "true" | ||
--- | ||
apiVersion: eventing.knative.dev/v1 | ||
kind: Trigger | ||
metadata: | ||
name: veba-pcli-vds-pg-config-trigger | ||
labels: | ||
app: veba-ui | ||
spec: | ||
broker: default | ||
filter: | ||
attributes: | ||
type: com.vmware.event.router/event | ||
subject: DVPortgroupReconfiguredEvent | ||
subscriber: | ||
ref: | ||
apiVersion: serving.knative.dev/v1 | ||
kind: Service | ||
name: kn-pcli-vds-pg-config |
128 changes: 128 additions & 0 deletions
128
examples/knative/powercli/kn-pcli-vds-pg-config/handler.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,128 @@ | ||
Function Process-Init { | ||
[CmdletBinding()] | ||
param() | ||
Write-Host "$(Get-Date) - Processing Init`n" | ||
|
||
try { | ||
$jsonSecrets = ${env:VDS_SECRET} | ConvertFrom-Json | ||
} | ||
catch { | ||
throw "`nK8s secret `$env:VDS_SECRET does not look to be defined" | ||
} | ||
|
||
# Extract all tag 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:VDS_SECRET} | ConvertFrom-Json | ||
} | ||
catch { | ||
throw "`nK8s secret `$env:VDS_SECRET does not look to be defined" | ||
} | ||
|
||
$NOTIFY_SWITCHES = ${jsonSecrets}.NOTIFY_SWITCHES | ||
try { | ||
$NOTIFY_SWITCHES = [System.Convert]::ToBoolean($NOTIFY_SWITCHES) | ||
} | ||
catch { | ||
Write-Host "$(Get-Date) - ERROR: Unable to convert NOTIFY_SWITCHES value to boolean" | ||
throw $_ | ||
} | ||
|
||
# Extract VM Name from event | ||
$vdsName = $cloudEventData.Dvs['Name'] | ||
$pgName = $cloudEventData.Net['Name'] | ||
if(${env:FUNCTION_DEBUG} -eq "true") { | ||
Write-Host "$(Get-Date) - DEBUG: Found VDS name $vdsName" | ||
Write-Host "$(Get-Date) - DEBUG: Found VDS pg name $pgName" | ||
} | ||
|
||
try { | ||
$vswitch = Get-VDSwitch $vdsName | ||
} | ||
catch { | ||
Write-Host "$(Get-Date) - ERROR: Could not load distributed virtual switch $vdsName" | ||
throw $_ | ||
} | ||
|
||
try { | ||
$pg = Get-VDPortgroup -VDSwitch $vswitch -Name $pgName | ||
} | ||
catch { | ||
Write-Host "$(Get-Date) - ERROR: Could not load distributed virtual portgroup $pgName" | ||
throw $_ | ||
} | ||
$policy = Get-VDUplinkTeamingPolicy -VDPortgroup $pg | ||
if ($policy.NotifySwitches -ne $NOTIFY_SWITCHES) { | ||
Write-Host "$(Get-Date) - INFO: Setting Notify Switches to $NOTIFY_SWITCHES" | ||
try { | ||
Set-VDUplinkTeamingPolicy -Policy $policy -NotifySwitches $NOTIFY_SWITCHES | ||
} | ||
catch { | ||
Write-Host "$(Get-Date) - ERROR: Failed to set Notify Switches value to $NOTIFY_SWITCHES" | ||
throw $_ | ||
} | ||
} | ||
else { | ||
Write-Host "$(Get-Date) - INFO: Notify Switches already set to $NOTIFY_SWITCHES, no changes made" | ||
} | ||
|
||
Write-Host "$(Get-Date) - VDS portgroup reconfig operation complete ...`n" | ||
|
||
Write-Host "$(Get-Date) - Handler Processing Completed ...`n" | ||
} |
1 change: 1 addition & 0 deletions
1
examples/knative/powercli/kn-pcli-vds-pg-config/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 @@ | ||
VDS_SECRET={"VCENTER_SERVER":"FILL-ME-IN","VCENTER_USERNAME":"FILL-ME-IN","VCENTER_PASSWORD":"FILL-ME-IN","VCENTER_CERTIFICATE_ACTION":"Ignore","NOTIFY_SWITCHES":"False"} |
16 changes: 16 additions & 0 deletions
16
examples/knative/powercli/kn-pcli-vds-pg-config/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" = "id-123"; | ||
"ce-source" = "source-123"; | ||
"ce-type" = "com.vmware.event.router/event"; | ||
"ce-subject" = "DvsReconfiguredEvent"; | ||
} | ||
|
||
$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-vds-pg-config/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 -d@test-payload.json \ | ||
-H "Content-Type: application/json" \ | ||
-H 'ce-specversion: 1.0' \ | ||
-H 'ce-id: d70079f9-fddd-4b7f-aa76-1193f28b0611' \ | ||
-H 'ce-source: https://vcenter.local/sdk' \ | ||
-H 'ce-type: com.vmware.event.router/event' \ | ||
-H 'ce-subject: DvsReconfiguredEvent' \ | ||
-X POST localhost:8080 | ||
|
||
echo "See docker container console for output" |
Oops, something went wrong.