diff --git a/.github/workflows/check-wip-pr.yml b/.github/workflows/check-wip-pr.yml new file mode 100644 index 00000000..a2c1ae2f --- /dev/null +++ b/.github/workflows/check-wip-pr.yml @@ -0,0 +1,14 @@ +# Perform "exit 1" if PR title starts with "WIP" to block accidental merges +name: Check "WIP" in PR Title + +on: + pull_request: + types: [opened, synchronize, reopened, edited] + +jobs: + WIP: + runs-on: ubuntu-latest + if: startsWith(github.event.pull_request.title, 'WIP') + steps: + - name: Must Exit + run: exit 1 diff --git a/.github/workflows/create-docker-prerelease.yml b/.github/workflows/create-docker-prerelease.yml new file mode 100644 index 00000000..1ebb5539 --- /dev/null +++ b/.github/workflows/create-docker-prerelease.yml @@ -0,0 +1,38 @@ +name: Build and push VMware Event Router Pre-Release Image to Docker Hub + +on: + push: + branches: + - release-* + +defaults: + run: + shell: bash + working-directory: ./vmware-event-router + +jobs: + build-push: + runs-on: ubuntu-latest + steps: + - name: checkout source (this.release branch) + uses: actions/checkout@master + - name: get the version from ref without prefixes + id: get_version + run: echo ::set-output name=VERSION::$(echo $GITHUB_REF | cut -d / -f 3) + - name: log in to Docker + env: + DOCKER_USER: ${{ secrets.DOCKER_USER }} + DOCKER_SECRET: ${{ secrets.DOCKER_SECRET }} + run: echo "${DOCKER_SECRET}" | docker login -u "${DOCKER_USER}" --password-stdin + - name: test and build pre-release image + env: + VERSION: ${{ steps.get_version.outputs.VERSION }} + run: | + echo "Building pre-release of vmware-event-router with version $VERSION" + make + docker tag vmware/veba-event-router:latest vmware/veba-event-router:$VERSION + - name: push just the pre-release image + env: + VERSION: ${{ steps.get_version.outputs.VERSION }} + run: | + docker push vmware/veba-event-router:$VERSION diff --git a/.github/workflows/protect-master.yml b/.github/workflows/protect-master.yml new file mode 100644 index 00000000..56a1f521 --- /dev/null +++ b/.github/workflows/protect-master.yml @@ -0,0 +1,19 @@ +# Even though branch protection rules might be in place, this is an additional +# safety net to protect against unwanted pull requests against "master" +name: Protect Master Branch + +# This workflow is triggered on PRs to the master branch +on: + pull_request: + branches: + - master + +jobs: + protect: + name: Reject + runs-on: ubuntu-latest + # sanity check + if: github.event_name == 'pull_request' && github.base_ref == 'master' + steps: + - name: Must reject PR + run: exit 1 diff --git a/.github/workflows/router-unit-tests.yml b/.github/workflows/router-unit-tests.yml new file mode 100644 index 00000000..9d8ba85f --- /dev/null +++ b/.github/workflows/router-unit-tests.yml @@ -0,0 +1,23 @@ +name: VMware Event Router Unit Tests + +# triggered on PRs but only when changes inside vmware-event-router (sub)dir(s) +on: + pull_request: + paths: + - 'vmware-event-router/**' + +# run all jobs with these defaults, unless specified otherwise +defaults: + run: + shell: bash + working-directory: ./vmware-event-router + +jobs: + unit-tests: + runs-on: ubuntu-latest + steps: + - name: checkout source + uses: actions/checkout@master + - name: run unit tests + run: make test + diff --git a/VERSION b/VERSION index fb7a04cf..5aff472d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v0.4.0 +v0.4.1 diff --git a/docs/.DS_Store b/docs/.DS_Store new file mode 100644 index 00000000..5008ddfc Binary files /dev/null and b/docs/.DS_Store differ diff --git a/docs/README.md b/docs/README.md index 5d1b3736..aca2e756 100644 --- a/docs/README.md +++ b/docs/README.md @@ -24,7 +24,7 @@ The website is hosted using [Github Pages](https://help.github.com/en/github/wor └── Gemfile > Plugins required for the website to be built by Jekyll ``` -In order for Jekyll to process the MD files and render them as html, you'll need to add the below to the beginning of the each MD file. +In order for Jekyll to process the MD files and render them as html, you'll need to add the below to the beginning of the each MD file. ```yaml --- @@ -62,6 +62,8 @@ rbenv install 2.6.3 gem install bundler ``` +*Note: if you hit a permissions error for the `gem install bundler` follow advice from the [bundler docs](https://bundler.io/doc/troubleshooting.html#permission-denied-when-installing-bundler)* + ### Dependencies for Linux If you are running a build on Ubuntu you will need the following packages: * ruby @@ -88,7 +90,7 @@ bundle install * Serve the site and watch for markup/sass changes `jekyll serve --livereload --incremental`. You may need to run `bundle exec jekyll serve --livereload --incremental`. * View your website at http://127.0.0.1:4000/ * Commit any changes and push everything to your fork. -* Once you're ready, submit a PR of your changes. +* Once you're ready, submit a PR of your changes. ## Troubleshooting * If you don't see your updates reflected on the website when running locally, try the following steps diff --git a/docs/_data/default.yml b/docs/_data/default.yml index a53342d4..899573ce 100644 --- a/docs/_data/default.yml +++ b/docs/_data/default.yml @@ -3,7 +3,7 @@ toc: subfolderitems: - page: About id: intro-about - url: /kb + url: /kb/ - page: Architecture id: intro-architecture url: /kb/architecture @@ -64,7 +64,10 @@ toc: - page: Using Harbor with VEBA id: site-resources external_url: https://rguske.github.io/post/using-harbor-with-the-vcenter-event-broker-appliance/ - + - page: Monitoring VEBA with vROps + id: site-resources + external_url: https://rguske.github.io/post/monitoring-the-vmware-event-broker-appliance-with-vrealize-operations-manager/ + - title: Troubleshoot subfolderitems: - page: Troubleshooting Appliance diff --git a/docs/_data/resources.yml b/docs/_data/resources.yml index ecdb8a7a..e2ba1fa5 100644 --- a/docs/_data/resources.yml +++ b/docs/_data/resources.yml @@ -16,15 +16,15 @@ links: author_name: Partheeban Kandasamy (PK) excerpt: Uptime and Reliability is more important now than ever during these times when Technology and Infrastructure is enabling us fight a global pandemic with work from home policies. It is no wonder that eyes lit up when you say PagerDuty and vCenter integration... - - title: Using Harbor with the vCenter Event Broker Appliance + - title: Monitoring the VMware Event Broker Appliance with vRealize Operations Manager display: true - details: + details: url_text: blog post - external_url: https://rguske.github.io/post/using-harbor-with-the-vcenter-event-broker-appliance/ - external_image: https://rguske.github.io/img/veba_harbor_cover.jpg + external_url: https://rguske.github.io/post/monitoring-the-vmware-event-broker-appliance-with-vrealize-operations-manager/ + external_image: https://rguske.github.io/img/posts/202005_vropsveba/CapturFiles-20200512_041624.jpg author_name: Robert Guske - excerpt: ...I wanted to use Harbor this time. In order to implement this, I have to replace the original image specification in the stack.yml and point to my Harbor instance, the corresponding project and the image with tag... - + excerpt: ...Let me demonstrate you how we can prepare VEBA to send the desired data (metrics) to vROPs and how we import a custom dashboard that provides you with plenty of interesting and useful information... + - title: vCenter Event Broker Appliance Updates – VMworld, Fling, Community & Open Source display: true details: @@ -74,6 +74,9 @@ otherlinks: - title: Blog post walkthrough of VEBA deployment url: https://www.patrickkremer.com/veba/ display: true + - title: Using Harbor with the vCenter Event Broker Appliance + url: https://rguske.github.io/post/using-harbor-with-the-vcenter-event-broker-appliance/ + display: true - title: Automate host maintenance with vCenter url: https://doogleit.github.io/2019/11/automate-host-maintenance-with-the-vcenter-event-broker-appliance/ display: true diff --git a/docs/kb/contribute-functions.md b/docs/kb/contribute-functions.md index 2c2f6f33..619e6cbc 100644 --- a/docs/kb/contribute-functions.md +++ b/docs/kb/contribute-functions.md @@ -11,13 +11,13 @@ cta: # Writing your own functions -The VMware Event Broker Appliance uses OpenFaaS as a Function-as-a-Service (FaaS) platform. If you are looking to understand the basics of functions, start [here](kb/functions). +The VMware Event Broker Appliance uses OpenFaaS as a Function-as-a-Service (FaaS) platform. If you are looking to understand the basics of functions, start [here](functions). You can also get started quickly with these quickstart [templates](https://github.com/pksrc/vebafn){:target="_blank"}. ## Instructions -> **ASSUMPTION:** The following steps assume VMware Event Broker Appliance has been [installed (configured with OpenFaaS)](/kb/install-openfaas) and is running. +> **ASSUMPTION:** The following steps assume VMware Event Broker Appliance has been [installed (configured with OpenFaaS)](install-openfaas) and is running. * Create a directory for your function and set up the secret config file diff --git a/docs/kb/contribute-start.md b/docs/kb/contribute-start.md index fd5beda7..65854b2f 100644 --- a/docs/kb/contribute-start.md +++ b/docs/kb/contribute-start.md @@ -8,10 +8,10 @@ cta: title: Join our community description: Earn a place amongst our top contributors [here](/community#contributors-veba) actions: - - text: Learn how you can contribute to our Appliance build process [here](/kb/contribute-appliance) - - text: Learn how you can contribute to our VMware Event Router [here](/kb/contribute-eventrouter) - - text: Learn how you can contribute to our Pre-built Functions [here](/kb/contribute-functions) - - text: Learn how you can contribute to our Website [here](/kb/contribute-site). + - text: Learn how you can contribute to our Appliance build process [here](contribute-appliance) + - text: Learn how you can contribute to our VMware Event Router [here](contribute-eventrouter) + - text: Learn how you can contribute to our Pre-built Functions [here](contribute-functions) + - text: Learn how you can contribute to our Website [here](contribute-site). --- # Contributing diff --git a/docs/kb/install-eventbridge.md b/docs/kb/install-eventbridge.md index 7b5d0919..36ba2d99 100644 --- a/docs/kb/install-eventbridge.md +++ b/docs/kb/install-eventbridge.md @@ -40,16 +40,17 @@ Customers looking to seamlessly extend their vCenter through native AWS componen * NTP Server - NTP Server(s) for proper time synchronization. If you have multiple DNS Servers, input needs to be **space separated**. #### **Proxy Settings** (Optional) - * HTTP Proxy Server - HTTP Proxy Server followed by the port and without typing http:// before (e.g. proxy.provider.com:3128) - * HTTPS Proxy - HTTPS Proxy Server followed by the port and without typing https:// before (e.g. proxy.provider.com:3128) + * HTTP Proxy Server - HTTP Proxy Server followed by the port (e.g. http://proxy.provider.com:3128) + * HTTPS Proxy - HTTPS Proxy Server followed by the port (e.g. http(s)://proxy.provider.com:3128) * Proxy Username - Optional Username for Proxy Server * Proxy Password - Optional Password for Proxy Server * No Proxy - Exclude internal domain suffix. Comma separated (localhost, 127.0.0.1, domain.local) #### **OS Credentials** (**Required**) * Root Password - This is the OS root password for the VMware Event Broker Appliance + * Enable SSH - Check the box to allow SSH to the Appliance (SSH to the appliance is disabled by default) -#### vSphere* (**Required**) +#### **vSphere** (**Required**) * vCenter Server - This FQDN or IP Address of your vCenter Server that you wish to associate this VMware Event Broker Appliance to for Event subscription * vCenter Username - The username to login to vCenter Server, as mentioned earlier, readOnly account is sufficient diff --git a/docs/kb/install-openfaas.md b/docs/kb/install-openfaas.md index 2b0d0b14..0ddd26ff 100644 --- a/docs/kb/install-openfaas.md +++ b/docs/kb/install-openfaas.md @@ -38,14 +38,15 @@ Customers looking to seamlessly extend their vCenter by either deploying our pre * NTP Server - NTP Server(s) for proper time synchronization. If you have multiple NTP Servers, input needs to be **space separated**. #### **Proxy Settings** (Optional) - * HTTP Proxy Server - HTTP Proxy Server followed by the port and without typing http:// before (e.g. proxy.provider.com:3128) - * HTTPS Proxy - HTTPS Proxy Server followed by the port and without typing https:// before (e.g. proxy.provider.com:3128) + * HTTP Proxy Server - HTTP Proxy Server followed by the port (e.g. http://proxy.provider.com:3128) + * HTTPS Proxy - HTTPS Proxy Server followed by the port (e.g. http(s)://proxy.provider.com:3128) * Proxy Username - Optional Username for Proxy Server * Proxy Password - Optional Password for Proxy Server * No Proxy - Exclude internal domain suffix. Comma separated (localhost, 127.0.0.1, domain.local) #### **OS Credentials** (**Required**) * Root Password - This is the OS root password for the VMware Event Broker Appliance + * Enable SSH - Check the box to allow SSH to the Appliance (SSH to the appliance is disabled by default) #### **vSphere** (**Required**) diff --git a/docs/kb/intro-about.md b/docs/kb/intro-about.md index 6f5e32cd..b0905ecb 100644 --- a/docs/kb/intro-about.md +++ b/docs/kb/intro-about.md @@ -3,7 +3,7 @@ layout: docs toc_id: intro-about title: VMware Event Broker Appliance - Introduction description: VMware Event Broker Appliance - Introduction -permalink: /kb +permalink: /kb/ cta: title: Getting Started description: Get started with VMware Event Broker Appliance and extend your vSphere SDDC in under 60 minutes diff --git a/docs/kb/troubleshoot-appliance.md b/docs/kb/troubleshoot-appliance.md index 7208eed4..30fef3f7 100644 --- a/docs/kb/troubleshoot-appliance.md +++ b/docs/kb/troubleshoot-appliance.md @@ -179,7 +179,7 @@ The SSH daemon will run but not automatically start with the next reboot. You ca Edit the configuration file with vi ```bash -vi /root/event-router-config.json +vi /root/config/event-router-config.json ``` The editor will open with output similar to this (truncated) diff --git a/docs/site/faq.md b/docs/site/faq.md index 394c20ed..0682d9ca 100644 --- a/docs/site/faq.md +++ b/docs/site/faq.md @@ -18,6 +18,10 @@ faqs: A: Instantaneous to a few seconds! The function execution itself is not considered in this answer since that is dependent on the logic that is being implemented. - Q: Can I setup the VMware Event Broker Appliance components on Kubernetes? A: Yes! Follow the steps provided [here](/kb/advanced-deploy-k8s). + - Q: Can I use a private registry like e.g. [Harbor](https://goharbor.io/) to have a source of truth for my functions (images)? + A: Yes! Follow the steps provided [here](https://rguske.github.io/post/using-harbor-with-the-vcenter-event-broker-appliance/). + - Q: How can I monitor the Appliance, the Kubernetes components as well as the functions (pods) in terms of utilization, performance and state? + A: vRealize Operations Manager provides these capabilities as described [here](https://rguske.github.io/post/monitoring-the-vmware-event-broker-appliance-with-vrealize-operations-manager/). - title: Common Questions - Functions id: function items: diff --git a/examples/powercli/datastore-usage-email/README.md b/examples/powercli/datastore-usage-email/README.md index 264966ca..6fe93062 100644 --- a/examples/powercli/datastore-usage-email/README.md +++ b/examples/powercli/datastore-usage-email/README.md @@ -16,7 +16,15 @@ git checkout master Step 2 - Update `stack.yml` and `vc-datastore-config.json` with your environment information -> **Note:** leave SMTP_USERNAME and SMTP_PASSWORD blank if you do not want to use authenticated SMTP +> **Note:** + Leave SMTP_USERNAME and SMTP_PASSWORD blank if you do not want to use authenticated SMTP + +The function supports pulling a To: email address from a custom attribute in vCenter. This allows administrators with vCenter access to configure email notifications without having to alter the JSON script configuration. To enable this feature, do the following: +- Create a custom attribute in vCenter, assign it to a datastore and give it an email address. For example, create a custom attribute named `NotifyEmail` and assign it a value of `admin@foo.com` +- In `vc-datastore-config.json`, add the name of the custom attribute `NotifyEmail` as the value for `DATASTORE_CUSTOM_PROP_EMAIL_TO` +- Add a vCenter URL and credentials to `VC`, `VC_USERNAME`, and `VC_PASSWORD` + +When this is configured, an email address found in the custom attribute will be added to the email already defined in the `EMAIL_TO` section of the JSON file. Step 3 - Login to the OpenFaaS gateway on VMware Event Broker Appliance diff --git a/examples/powercli/datastore-usage-email/handler/script.ps1 b/examples/powercli/datastore-usage-email/handler/script.ps1 index fba27669..b59b5015 100644 --- a/examples/powercli/datastore-usage-email/handler/script.ps1 +++ b/examples/powercli/datastore-usage-email/handler/script.ps1 @@ -36,25 +36,85 @@ if( ("$alarmName" -match "$($VC_CONFIG.VC_ALARM_NAME)") -and ([bool]($VC_CONFIG. } elseif($alarmStatus -eq "green") { $subject = "$($VC_CONFIG.EMAIL_SUBJECT)" $threshold = "normal" - } + } $Body = "$alarmName $datastoreName has reached $threshold threshold.`r`n" - - if ( $threshold -ne "normal" ) { - $Body = $Body + "Please log in to your VMware Cloud on AWS environment and ensure that everything is operating as expected.`r`n" - } + + if ( $threshold -ne "normal" ) + { + $Body = $Body + "Please log in to your VMware Cloud on AWS environment and ensure that everything is operating as expected.`r`n" + } - $Body = $Body + @" - vCenter Server: $vcenter + $Body = $Body + @" + vCenter Server: $vcenter Datacenter: $datacenter Datastore: $datastoreName "@ - if ($VC_CONFIG.SMTP_PASSWORD.length -gt 0 -and $VC_CONFIG.SMTP_USERNAME.length -gt 0) { - $password = ConvertTo-SecureString "$($VC_CONFIG.SMTP_PASSWORD)" -AsPlainText -Force - $credential = New-Object System.Management.Automation.PSCredential($($VC_CONFIG.SMTP_USERNAME), $password) - Send-MailMessage -From $($VC_CONFIG.EMAIL_FROM) -to $($VC_CONFIG.EMAIL_TO) -Subject $Subject -Body $Body -SmtpServer $($VC_CONFIG.SMTP_SERVER) -port $($VC_CONFIG.SMTP_PORT) -UseSsl -Credential $credential -Encoding UTF32 - } else { - Send-MailMessage -From $($VC_CONFIG.EMAIL_FROM) -to $($VC_CONFIG.EMAIL_TO) -Subject $Subject -Body $Body -SmtpServer $($VC_CONFIG.SMTP_SERVER) -port $($VC_CONFIG.SMTP_PORT) -Encoding UTF32 + + $emailTo = $VC_CONFIG.EMAIL_TO + + # If the JSON file has a custom property email field defined, log into vCenter to find the value + # This is used to allow admins within vCenter to add an email address for storage alarms independent of the EMAIL_TO value + if ($VC_CONFIG.DATASTORE_CUSTOM_PROP_EMAIL_TO.length -gt 0) + { + Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -DisplayDeprecationWarnings $false -ParticipateInCeip $false -Confirm:$false | Out-Null + + # Connect to vCenter Server + Write-Host "Connecting to vCenter Server ..." + Connect-VIServer -Server $($VC_CONFIG.VC) -User $($VC_CONFIG.VC_USERNAME) -Password $($VC_CONFIG.VC_PASSWORD) + + # This objet has all defined custom fields in the vCenter + $customFieldMgr = Get-View ($global:DefaultVIServer.ExtensionData.Content.CustomFieldsManager) + + $datastoreView = Get-View -ViewType Datastore -Property Name, Value -Filter @{"name"=$datastoreName} + + # Build 2 hash tables for the key-value pairs in the Custom Fields Manager, one to search by Custom Field ID and one to search by Name + $customKeyLookup = @{} + $customNameLookup = @{} + $customFieldMgr.Field | ForEach-Object { + $customKeyLookup.Add($_.Key, $_.Name) + $customNameLookup.Add($_.Name, $_.Key) + } + + # This is the custom field that we're looking to pull an email address out of + $emailKey = $customNameLookup[$($VC_CONFIG.DATASTORE_CUSTOM_PROP_EMAIL_TO)] + + #If we find one, this is the email address we will add to the "To" field in the email + $addEmailAddress = "" + foreach ($row in $datastoreView.Value) { + if ($env:function_debug -eq "true") { + Write-Host "`Datastore:" $datastoreName "has Custom Field:" $customKeyLookup[$row.Key] "with value:" $row.Value "`n" + } + if ($row.Key -eq $emailKey) + { + if ($env:function_debug -eq "true") { + write-host "Found key" $emailKey "with value" $row.value + } + $addEmailAddress = $row.value + } + + } + + if ($addEmailAddress.length -gt 0){ + $emailTo = $emailTo + $addEmailAddress + } + else { + Write-Host "DATASTORE_CUSTOM_PROP_EMAIL_TO value '"$VC_CONFIG.DATASTORE_CUSTOM_PROP_EMAIL_TO "' found in JSON config but not found on datastore" + } + Write-Host "Disconnecting from vCenter Server ..." + Disconnect-VIServer * -Confirm:$false + } -} + # If defined in the config file, send via authenticated SMTP, otherwise use standard SMTP + if ($VC_CONFIG.SMTP_PASSWORD.length -gt 0 -and $VC_CONFIG.SMTP_USERNAME.length -gt 0) + { + $password = ConvertTo-SecureString "$($VC_CONFIG.SMTP_PASSWORD)" -AsPlainText -Force + $credential = New-Object System.Management.Automation.PSCredential($($VC_CONFIG.SMTP_USERNAME), $password) + Send-MailMessage -From $($VC_CONFIG.EMAIL_FROM) -to $($emailTo) -Subject $Subject -Body $Body -SmtpServer $($VC_CONFIG.SMTP_SERVER) -port $($VC_CONFIG.SMTP_PORT) -UseSsl -Credential $credential -Encoding UTF32 + } + else + { + Send-MailMessage -From $($VC_CONFIG.EMAIL_FROM) -to $($emailTo) -Subject $Subject -Body $Body -SmtpServer $($VC_CONFIG.SMTP_SERVER) -port $($VC_CONFIG.SMTP_PORT) -Encoding UTF32 + } +} \ No newline at end of file diff --git a/examples/powercli/datastore-usage-email/vc-datastore-config.json b/examples/powercli/datastore-usage-email/vc-datastore-config.json index 5044f263..c9629216 100644 --- a/examples/powercli/datastore-usage-email/vc-datastore-config.json +++ b/examples/powercli/datastore-usage-email/vc-datastore-config.json @@ -7,5 +7,9 @@ "SMTP_PASSWORD" : "FILE-ME-IN-PLEASE", "EMAIL_SUBJECT" : "[VMC Datastore Notification Alarm]", "EMAIL_TO": ["admins@primp-industries.com"], - "EMAIL_FROM" : "vmc-notification-do-not-reply@primp-industries.com" + "EMAIL_FROM" : "vmc-notification-do-not-reply@primp-industries.com", + "DATASTORE_CUSTOM_PROP_EMAIL_TO" : "", + "VC" : "", + "VC_USERNAME" : "", + "VC_PASSWORD" : "" } diff --git a/examples/python/trigger-pagerduty-incident/README.MD b/examples/python/trigger-pagerduty-incident/README.MD index 8017ecad..6391e32c 100644 --- a/examples/python/trigger-pagerduty-incident/README.MD +++ b/examples/python/trigger-pagerduty-incident/README.MD @@ -46,7 +46,7 @@ functions: pdinvoke-fn: lang: python3 handler: ./handler - image: vmware/veba-pagerduty-invoke:latest + image: vmware/veba-python-pagerduty:latest environment: write_debug: true #function writes verbose entries to the log when set to true, also requires combine_output to be set to false to avoid debug messages from showing up in the response read_debug: true diff --git a/examples/python/trigger-pagerduty-incident/stack.yml b/examples/python/trigger-pagerduty-incident/stack.yml index 14b357eb..9a90b086 100644 --- a/examples/python/trigger-pagerduty-incident/stack.yml +++ b/examples/python/trigger-pagerduty-incident/stack.yml @@ -5,7 +5,7 @@ functions: pdinvoke-fn: lang: python3 handler: ./handler - image: vmware/veba-pagerduty-invoke:latest + image: vmware/veba-python-pagerduty:latest environment: write_debug: true read_debug: true diff --git a/files/setup-01-os.sh b/files/setup-01-os.sh index 817915dd..c9453752 100755 --- a/files/setup-01-os.sh +++ b/files/setup-01-os.sh @@ -6,8 +6,13 @@ set -euo pipefail -systemctl disable sshd -systemctl stop sshd +if [ "${ENABLE_SSH}" == "true" ]; then + systemctl enable sshd + systemctl start sshd +else + systemctl disable sshd + systemctl stop sshd +fi echo -e "\e[92mConfiguring OS Root password ..." > /dev/console echo "root:${ROOT_PASSWORD}" | /usr/sbin/chpasswd diff --git a/files/setup-02-proxy.sh b/files/setup-02-proxy.sh index 7110b506..e5eaa1a5 100755 --- a/files/setup-02-proxy.sh +++ b/files/setup-02-proxy.sh @@ -23,28 +23,42 @@ if [ -n "${HTTP_PROXY}" ] || [ -n "${HTTPS_PROXY}" ]; then fi if [ ! -z "${HTTP_PROXY}" ]; then - if [ $YES_CREDS -eq 1 ]; then - HTTP_PROXY_URL="http://${PROXY_USERNAME}:${PROXY_PASSWORD}@${HTTP_PROXY}" - else - HTTP_PROXY_URL="http://${HTTP_PROXY}" - fi - echo "HTTP_PROXY=\"${HTTP_PROXY_URL}\"" >> ${PROXY_CONF} - cat > ${DOCKER_PROXY}/http-proxy.conf << __HTTP_DOCKER_PROXY__ + a=($(printf '%s\n' "${HTTP_PROXY//\:\/\//$'\n'}")) + if [ ${#a[*]} -eq 2 ]; then + HTTP_PROXY_PROTOCOL=${a[0]} + HTTP_PROXY_SERVER_PORT=${a[1]} + if [ $YES_CREDS -eq 1 ]; then + HTTP_PROXY_URL="${HTTP_PROXY_PROTOCOL}://${PROXY_USERNAME}:${PROXY_PASSWORD}@${HTTP_PROXY_SERVER_PORT}" + else + HTTP_PROXY_URL="${HTTP_PROXY_PROTOCOL}://${HTTP_PROXY_SERVER_PORT}" + fi + echo "HTTP_PROXY=\"${HTTP_PROXY_URL}\"" >> ${PROXY_CONF} + cat > ${DOCKER_PROXY}/http-proxy.conf << __HTTP_DOCKER_PROXY__ [Service] Environment="HTTP_PROXY=${HTTP_PROXY_URL}" "NO_PROXY=${NO_PROXY}" __HTTP_DOCKER_PROXY__ + else + echo -e "\e[91mInvalid HTTP Proxy URL supplied" > /dev/console + fi fi if [ ! -z "${HTTPS_PROXY}" ]; then - if [ $YES_CREDS -eq 1 ]; then - HTTPS_PROXY_URL="https://${PROXY_USERNAME}:${PROXY_PASSWORD}@${HTTPS_PROXY}" - else - HTTPS_PROXY_URL="https://${HTTPS_PROXY}" - fi - echo "HTTPS_PROXY=\"${HTTPS_PROXY_URL}\"" >> ${PROXY_CONF} - cat > ${DOCKER_PROXY}/https-proxy.conf << __HTTPS_DOCKER_PROXY__ + a=($(printf '%s\n' "${HTTPS_PROXY//\:\/\//$'\n'}")) + if [ ${#a[*]} -eq 2 ]; then + HTTPS_PROXY_PROTOCOL=${a[0]} + HTTPS_PROXY_SERVER_PORT=${a[1]} + if [ $YES_CREDS -eq 1 ]; then + HTTPS_PROXY_URL="${HTTPS_PROXY_PROTOCOL}://${PROXY_USERNAME}:${PROXY_PASSWORD}@${HTTPS_PROXY_SERVER_PORT}" + else + HTTPS_PROXY_URL="${HTTPS_PROXY_PROTOCOL}://${HTTPS_PROXY_SERVER_PORT}" + fi + echo "HTTPS_PROXY=\"${HTTPS_PROXY_URL}\"" >> ${PROXY_CONF} + cat > ${DOCKER_PROXY}/https-proxy.conf << __HTTPS_DOCKER_PROXY__ [Service] Environment="HTTPS_PROXY=${HTTPS_PROXY_URL}" "NO_PROXY=${NO_PROXY}" __HTTPS_DOCKER_PROXY__ + else + echo -e "\e[91mInvalid HTTPS Proxy URL supplied" > /dev/console + fi fi -fi \ No newline at end of file +fi diff --git a/files/setup-05-event-processor.sh b/files/setup-05-event-processor.sh index 4d8a92ed..32f76b74 100755 --- a/files/setup-05-event-processor.sh +++ b/files/setup-05-event-processor.sh @@ -27,7 +27,7 @@ if [ "${EVENT_PROCESSOR_TYPE}" == "AWS EventBridge" ]; then ESCAPED_AWS_EVENTBRIDGE_ACCESS_KEY=$(echo -n ${AWS_EVENTBRIDGE_ACCESS_KEY} | python -c 'import sys,json;data=sys.stdin.read(); print json.dumps(data)[1:-1]') ESCAPED_AWS_EVENTBRIDGE_ACCESS_SECRET=$(echo -n ${AWS_EVENTBRIDGE_ACCESS_SECRET} | python -c 'import sys,json;data=sys.stdin.read(); print json.dumps(data)[1:-1]') - ESCAPED_AWS_EVENTBRIDGE_EVENT_BUS=$(echo -n ${VCENTER_USEAWS_EVENTBRIDGE_EVENT_BUSNAME} | python -c 'import sys,json;data=sys.stdin.read(); print json.dumps(data)[1:-1]') + ESCAPED_AWS_EVENTBRIDGE_EVENT_BUS=$(echo -n ${AWS_EVENTBRIDGE_EVENT_BUS} | python -c 'import sys,json;data=sys.stdin.read(); print json.dumps(data)[1:-1]') ESCAPED_AWS_EVENTBRIDGE_RULE_ARN=$(echo -n ${AWS_EVENTBRIDGE_RULE_ARN} | python -c 'import sys,json;data=sys.stdin.read(); print json.dumps(data)[1:-1]') cat > ${EVENT_ROUTER_CONFIG} << __AWS_EVENTBRIDGE_PROCESSOR__ diff --git a/files/setup.sh b/files/setup.sh index 55c806ac..1d9880f1 100755 --- a/files/setup.sh +++ b/files/setup.sh @@ -19,6 +19,7 @@ PROXY_USERNAME=$(vmtoolsd --cmd "info-get guestinfo.ovfEnv" | grep "guestinfo.pr PROXY_PASSWORD=$(vmtoolsd --cmd "info-get guestinfo.ovfEnv" | grep "guestinfo.proxy_password" | awk -F 'oe:value="' '{print $2}' | awk -F '"' '{print $1}') NO_PROXY=$(vmtoolsd --cmd "info-get guestinfo.ovfEnv" | grep "guestinfo.no_proxy" | awk -F 'oe:value="' '{print $2}' | awk -F '"' '{print $1}') ROOT_PASSWORD=$(vmtoolsd --cmd "info-get guestinfo.ovfEnv" | grep "guestinfo.root_password" | awk -F 'oe:value="' '{print $2}' | awk -F '"' '{print $1}') +ENABLE_SSH=$(vmtoolsd --cmd "info-get guestinfo.ovfEnv" | grep "guestinfo.enable_ssh" | awk -F 'oe:value="' '{print $2}' | awk -F '"' '{print $1}' | tr '[:upper:]' '[:lower:]') VCENTER_SERVER=$(vmtoolsd --cmd "info-get guestinfo.ovfEnv" | grep "guestinfo.vcenter_server" | awk -F 'oe:value="' '{print $2}' | awk -F '"' '{print $1}') VCENTER_USERNAME=$(vmtoolsd --cmd "info-get guestinfo.ovfEnv" | grep "guestinfo.vcenter_username" | awk -F 'oe:value="' '{print $2}' | awk -F '"' '{print $1}') VCENTER_PASSWORD=$(vmtoolsd --cmd "info-get guestinfo.ovfEnv" | grep "guestinfo.vcenter_password" | awk -F 'oe:value="' '{print $2}' | awk -F '"' '{print $1}') diff --git a/files/veba-dcui b/files/veba-dcui index fd28eea3..ebd22b1b 100755 Binary files a/files/veba-dcui and b/files/veba-dcui differ diff --git a/manual/photon.xml.template b/manual/photon.xml.template index 9bd0cdab..81ed5c1b 100644 --- a/manual/photon.xml.template +++ b/manual/photon.xml.template @@ -8,7 +8,7 @@ Networking - Hostname of system + Hostname (FQDN) of system @@ -37,11 +37,11 @@ Proxy Settings (optional) - Enter HTTP Proxy Server followed by the port and without typing "http://" before. Example: "proxy.provider.com:3128" + Enter HTTP Proxy URL followed by the port. Example: "http://proxy.provider.com:3128" - Enter HTTPS Proxy Server followed by the port and without typing "https://" before. Example: "proxy.provider.com:3128" + Enter HTTPS Proxy URL followed by the port. Example: "https://proxy.provider.com:3128" @@ -53,13 +53,17 @@ - No Proxy for e.g. your internal domain suffix. Comma separated (localhost, 127.0.0.1, domain.local) + No Proxy for e.g. your internal domain suffix. Adding the appliance IP address is recommended. Comma separated (localhost, 127.0.0.1, domain.local) OS Credentials Password to login in as root. Please use a secure password + + + Automatically start SSH daemon + vSphere diff --git a/photon.json b/photon.json index f3e8e1f0..6cf436be 100644 --- a/photon.json +++ b/photon.json @@ -44,7 +44,7 @@ "ethernet0.virtualDev": "vmxnet3", "ethernet0.addressType": "generated", "ethernet0.wakeOnPcktRcv": "FALSE", - "annotation": "Version: {{ user `version` }}" + "annotation": "Version: {{ user `VEBA_VERSION` }}" } } ], diff --git a/test/deploy_veba_eventbridge_processor.sh b/test/deploy_veba_eventbridge_processor.sh index 85b4672f..7091fc1a 100755 --- a/test/deploy_veba_eventbridge_processor.sh +++ b/test/deploy_veba_eventbridge_processor.sh @@ -23,6 +23,7 @@ VEBA_DNS="192.168.30.1" VEBA_DNS_DOMAIN="primp-industries.com" VEBA_NTP="pool.ntp.org" VEBA_OS_PASSWORD="VMware1!" +VEBA_ENABLE_SSH="False" VEBA_NETWORK="VM Network" VEBA_DATASTORE="sm-vsanDatastore" VEBA_DEBUG="True" @@ -35,6 +36,12 @@ VEBA_AWS_EVENTBRIDGE_ACCESS_SECRET="FILL_ME_IN_PLEASE" VEBA_AWS_EVENTBRIDGE_EVENT_BUS="FILL_ME_IN_PLEASE" VEBA_AWS_EVENTBRIDGE_REGION="us-west-2" VEBA_AWS_EVENTBRIDGE_RULE_ARN="FILL_ME_IN_PLEASE" +VEBA_HTTP_PROXY="" +VEBA_HTTPS_PROXY="" +VEBA_PROXY_USERNAME="" +VEBA_PROXY_PASSWORD="" +VEBA_NOPROXY="" + ### DO NOT EDIT BEYOND HERE ### @@ -54,7 +61,13 @@ VEBA_AWS_EVENTBRIDGE_RULE_ARN="FILL_ME_IN_PLEASE" --prop:guestinfo.dns=${VEBA_DNS} \ --prop:guestinfo.domain=${VEBA_DNS_DOMAIN} \ --prop:guestinfo.ntp=${VEBA_NTP} \ + --prop:guestinfo.http_proxy=${VEBA_HTTP_PROXY} \ + --prop:guestinfo.https_proxy=${VEBA_HTTPS_PROXY} \ + --prop:guestinfo.proxy_username=${VEBA_PROXY_USERNAME} \ + --prop:guestinfo.proxy_password=${VEBA_PROXY_PASSWORD} \ + --prop:guestinfo.no_proxy=${VEBA_NOPROXY} \ --prop:guestinfo.root_password=${VEBA_OS_PASSWORD} \ + --prop:guestinfo.enable_ssh=${VEBA_ENABLE_SSH} \ --prop:guestinfo.vcenter_server=${VEBA_VCENTER_SERVER} \ --prop:guestinfo.vcenter_username=${VEBA_VCENTER_USER} \ --prop:guestinfo.vcenter_password=${VEBA_VCENTER_PASS} \ diff --git a/test/deploy_veba_openfaas_processor.sh b/test/deploy_veba_openfaas_processor.sh index 59743028..1e822606 100755 --- a/test/deploy_veba_openfaas_processor.sh +++ b/test/deploy_veba_openfaas_processor.sh @@ -5,7 +5,7 @@ # Sample Shell Script to test deployment of VEBA w/OpenFaaS Processor OVFTOOL_BIN_PATH="/Applications/VMware OVF Tool/ovftool" -VEBA_OVA="../output-vmware-iso/vCenter_Event_Broker_Appliance_0.4.0.ova" +VEBA_OVA="../output-vmware-iso/vCenter_Event_Broker_Appliance_0.4.0-beta.ova" # vCenter DEPLOYMENT_TARGET_ADDRESS="192.168.30.200" @@ -15,7 +15,7 @@ DEPLOYMENT_TARGET_DATACENTER="Primp-Datacenter" DEPLOYMNET_TARGET_CLUSTER="Supermicro-Cluster" VEBA_NAME="VEBA-TEST-OPENFAAS-PROCESSOR" -VEBA_IP="192.168.30.170" +VEBA_IP="192.168.130.170" VEBA_HOSTNAME="veba.primp-industries.com" VEBA_PREFIX="24 (255.255.255.0)" VEBA_GW="192.168.30.1" @@ -23,6 +23,7 @@ VEBA_DNS="192.168.30.1" VEBA_DNS_DOMAIN="primp-industries.com" VEBA_NTP="pool.ntp.org" VEBA_OS_PASSWORD="VMware1!" +VEBA_ENABLE_SSH="True" VEBA_NETWORK="VM Network" VEBA_DATASTORE="sm-vsanDatastore" VEBA_DEBUG="True" @@ -32,6 +33,11 @@ VEBA_VCENTER_PASS="VMware1!" VEBA_VCENTER_DISABLE_TLS="True" VEBA_OPENFAAS_PASS="VMware1!" VEBA_DOCKER_NETWORK="172.26.0.1/16" +VEBA_HTTP_PROXY="" +VEBA_HTTPS_PROXY="" +VEBA_PROXY_USERNAME="" +VEBA_PROXY_PASSWORD="" +VEBA_NOPROXY="" ### DO NOT EDIT BEYOND HERE ### @@ -51,7 +57,13 @@ VEBA_DOCKER_NETWORK="172.26.0.1/16" --prop:guestinfo.dns=${VEBA_DNS} \ --prop:guestinfo.domain=${VEBA_DNS_DOMAIN} \ --prop:guestinfo.ntp=${VEBA_NTP} \ + --prop:guestinfo.http_proxy=${VEBA_HTTP_PROXY} \ + --prop:guestinfo.https_proxy=${VEBA_HTTPS_PROXY} \ + --prop:guestinfo.proxy_username=${VEBA_PROXY_USERNAME} \ + --prop:guestinfo.proxy_password=${VEBA_PROXY_PASSWORD} \ + --prop:guestinfo.no_proxy=${VEBA_NOPROXY} \ --prop:guestinfo.root_password=${VEBA_OS_PASSWORD} \ + --prop:guestinfo.enable_ssh=${VEBA_ENABLE_SSH} \ --prop:guestinfo.vcenter_server=${VEBA_VCENTER_SERVER} \ --prop:guestinfo.vcenter_username=${VEBA_VCENTER_USER} \ --prop:guestinfo.vcenter_password=${VEBA_VCENTER_PASS} \ diff --git a/veba-bom.json b/veba-bom.json new file mode 100644 index 00000000..cee55c83 --- /dev/null +++ b/veba-bom.json @@ -0,0 +1,106 @@ +{ + "veba": { + "version": "v0.4.1" + }, + "antrea": { + "version": "v0.6.0", + "containers": [{ + "name": "antrea/antrea-ubuntu", + "version": "v0.6.0" + }] + }, + "contour": { + "version": "v1.0.0-beta.1", + "containers": [{ + "name": "projectcontour/contour", + "version": "v1.0.0-beta.1" + }, + { + "name": "envoyproxy/envoy", + "version": "v1.11.1" + } + ] + }, + "kubernetes": { + "version": "v1.14.9", + "containers": [{ + "name": "k8s.gcr.io/kube-apiserver", + "version": "v1.14.9" + }, + { + "name": "k8s.gcr.io/kube-controller-manager", + "version": "v1.14.9" + }, + { + "name": "k8s.gcr.io/kube-scheduler", + "version": "v1.14.9" + }, + { + "name": "k8s.gcr.io/kube-proxy", + "version": "v1.14.9" + }, + { + "name": "k8s.gcr.io/pause", + "version": "3.1" + }, + { + "name": "k8s.gcr.io/etcd", + "version": "3.3.10" + }, + { + "name": "k8s.gcr.io/coredns", + "version": "1.3.1" + } + ] + }, + "openfaas": { + "version": "0.9.2", + "containers": [{ + "name": "openfaas/faas-netes", + "version": "0.9.0" + }, + { + "name": "openfaas/gateway", + "version": "0.17.4" + }, + { + "name": "openfaas/basic-auth-plugin", + "version": "0.17.0" + }, + { + "name": "openfaas/queue-worker", + "version": "0.8.0" + }, + { + "name": "openfaas/faas-idler", + "version": "0.2.1" + }, + { + "name": "prom/prometheus", + "version": "v2.11.0" + }, + { + "name": "prom/alertmanager", + "version": "v0.18.0" + }, + { + "name": "nats-streaming", + "version": "0.11.2" + } + ] + }, + "tinywww": { + "version": "latest", + "containers": [{ + "name": "embano1/tinywww", + "version": "latest" + }] + }, + "vmware-event-router": { + "version": "v0.4.1", + "containers": [{ + "name": "vmware/veba-event-router", + "version": "v0.4.1" + }] + } +} \ No newline at end of file diff --git a/vmware-event-router/Makefile b/vmware-event-router/Makefile index 7a909460..869c676e 100644 --- a/vmware-event-router/Makefile +++ b/vmware-event-router/Makefile @@ -41,7 +41,7 @@ binary: test tidy build: test tidy $(info Make: Building image "$(IMAGE_NAME)".) $(if $(GIT_NOT_CLEAN_CHECK), $(error "Dirty Git repository!")) - docker build -t $(BUILD_TAG) --build-arg COMMIT=$(COMMIT) --build-arg VERSION=$(VERSION) . + docker build -t $(LATEST_TAG) --build-arg COMMIT=$(COMMIT) --build-arg VERSION=$(VERSION) . gofmt: $(info Make: Checking code is gofmted.) @@ -51,9 +51,9 @@ test: gofmt GORACE=history_size=5 go test -race -timeout $(TIMEOUT)s -cover $(TESTPKGS) tag: - $(info Make: Tagging image "$(IMAGE_NAME)" with "$(BUILD_TAG)", "$(LATEST_TAG) and "$(VERSION_TAG)".) - @docker tag $(BUILD_TAG) $(LATEST_TAG) - @docker tag $(BUILD_TAG) $(VERSION_TAG) + $(info Make: Tagging image "$(LATEST_TAG)" with "$(BUILD_TAG)" and "$(VERSION_TAG)".) + @docker tag $(LATEST_TAG) $(BUILD_TAG) + @docker tag $(LATEST_TAG) $(VERSION_TAG) push: tag $(info Make: Pushing image "$(IMAGE_NAME)".) diff --git a/vmware-event-router/internal/processor/aws_event_bridge.go b/vmware-event-router/internal/processor/aws_event_bridge.go index cca54d18..6c1a1936 100644 --- a/vmware-event-router/internal/processor/aws_event_bridge.go +++ b/vmware-event-router/internal/processor/aws_event_bridge.go @@ -3,6 +3,7 @@ package processor import ( "context" "encoding/json" + "fmt" "log" "os" "sync" @@ -176,8 +177,9 @@ func NewAWSEventBridgeProcessor(ctx context.Context, cfg connection.Config, sour func (awsEventBridge *awsEventBridgeProcessor) Process(moref types.ManagedObjectReference, baseEvent []types.BaseEvent) error { batchInput, err := awsEventBridge.createPutEventsInput(baseEvent) if err != nil { - awsEventBridge.Printf("could not create PutEventsInput for event(s): %v", err) - return nil + errMsg := fmt.Errorf("could not create PutEventsInput for event(s): %v", err) + awsEventBridge.Println(errMsg) + return processorError(ProviderAWS, errMsg) } // nothing to send diff --git a/vmware-event-router/internal/processor/processor.go b/vmware-event-router/internal/processor/processor.go index 6e447191..12d0c23f 100644 --- a/vmware-event-router/internal/processor/processor.go +++ b/vmware-event-router/internal/processor/processor.go @@ -1,6 +1,8 @@ package processor import ( + "fmt" + "github.com/vmware/govmomi/vim25/types" ) @@ -11,3 +13,20 @@ import ( type Processor interface { Process(types.ManagedObjectReference, []types.BaseEvent) error } + +// Error struct contains the generic error content used by the processors +// it extends the simple error by providing context which processor gave +// the error +type Error struct { + processor string + err error +} + +func processorError(processor string, err error) error { + return &Error{ + processor: processor, + err: err, + } +} + +func (e *Error) Error() string { return fmt.Sprintf("%s: %s", e.processor, e.err.Error()) } diff --git a/vmware-event-router/internal/processor/processor_test.go b/vmware-event-router/internal/processor/processor_test.go new file mode 100644 index 00000000..e626232d --- /dev/null +++ b/vmware-event-router/internal/processor/processor_test.go @@ -0,0 +1,38 @@ +// +build unit + +package processor + +import ( + "fmt" + "testing" +) + +func Test_processor_error(t *testing.T) { + tests := []struct { + title string + provider string + errMessage error + expectedErr string + }{ + { + title: "Event Bridge unable to process VmPoweredOnEvent", + provider: ProviderAWS, + errMessage: fmt.Errorf("could not create PutEventsInput for event(s): VmPoweredOnEvent"), + expectedErr: "aws_event_bridge: could not create PutEventsInput for event(s): VmPoweredOnEvent", + }, + { + title: "OpenFaaS processor unable to handle VmPoweredOnEvent", + provider: ProviderOpenFaaS, + errMessage: fmt.Errorf("error handling event: VmPoweredOnEvent"), + expectedErr: "openfaas: error handling event: VmPoweredOnEvent", + }, + } + for _, test := range tests { + t.Run(test.title, func(t *testing.T) { + actualErr := processorError(test.provider, test.errMessage) + if actualErr.Error() != test.expectedErr { + t.Errorf("Expected error: %s got: %s", test.expectedErr, actualErr.Error()) + } + }) + } +}