Merge pull request #356 from lamw/master

Add VyOS and VCSA PowerCLI Module
This commit is contained in:
Kyle Ruddy
2020-03-05 14:08:32 -05:00
committed by GitHub
4 changed files with 537 additions and 3 deletions

View File

@@ -36,4 +36,33 @@ Function Get-VCSAPasswordPolicy {
} else {
Write-Host "`nUnable to find VCSA named $VCSAName"
}
}
Function Get-VCSAIdentitySource {
<#
.DESCRIPTION Retrieves vCenter Server Appliance Identity Source Configuration
.NOTES Author: William Lam
.PARAMETER VCSAName
Inventory name of the VCSA VM
.PARAMETER VCSARootPassword
Root password for VCSA VM
.EXAMPLE
Get-VCSAIdentitySource -VCSAName "MGMT-VCSA-01" -VCSARootPassword "VMware1!"
#>
Param (
[Parameter(Mandatory=$true)][String]$VCSAName,
[Parameter(Mandatory=$true)][String]$VCSARootPassword
)
$vm = Get-Vm -Name $VCSAName
if($vm) {
$identitySources = Invoke-VMScript -ScriptText "/opt/vmware/bin/sso-config.sh -get_identity_sources 2> /dev/null | sed -ne '/^*/,$ p'" -vm $vm -GuestUser "root" -GuestPassword $VCSARootPassword
Write-Host -ForegroundColor green "`nIdentity Sources: "
$identitySources
} else {
Write-Host "`nUnable to find VCSA named $VCSAName"
}
}

View File

@@ -120,10 +120,12 @@ Function Get-NSXTSegment {
$network = $subnets.network
$gateway = $subnets.gateway_address
$dhcpRange = $subnets.dhcp_ranges
$type = $segment.type
$tmp = [pscustomobject] @{
Name = $segment.display_name;
ID = $segment.Id;
TYPE = $type;
Network = $network;
Gateway = $gateway;
DHCPRange = $dhcpRange;
@@ -156,6 +158,8 @@ Function New-NSXTSegment {
New-NSXTSegment -Name "sddc-cgw-network-4" -Gateway "192.168.4.1/24" -DHCP -DHCPRange "192.168.4.2-192.168.4.254" -DomainName 'vmc.local'
.EXAMPLE
New-NSXTSegment -Name "sddc-cgw-network-5" -Gateway "192.168.5.1/24"
.EXAMPLE
New-NSXTSegment -Name "sddc-cgw-network-5" -Gateway "192.168.5.1/24" -Disconnected
#>
Param (
[Parameter(Mandatory=$True)]$Name,
@@ -163,6 +167,7 @@ Function New-NSXTSegment {
[Parameter(Mandatory=$False)]$DHCPRange,
[Parameter(Mandatory=$False)]$DomainName,
[Switch]$DHCP,
[Switch]$Disconnected,
[Switch]$Troubleshoot
)
@@ -178,9 +183,21 @@ Function New-NSXTSegment {
}
}
$payload = @{
display_name = $Name;
subnets = @($subnets)
if($Disconnected) {
$payload = @{
display_name = $Name;
subnets = @($subnets)
advanced_config = @{
local_egress = "False"
connectivity = "OFF";
}
type = "DISCONNECTED";
}
} else {
$payload = @{
display_name = $Name;
subnets = @($subnets)
}
}
if($DomainName) {
@@ -221,6 +238,98 @@ Function New-NSXTSegment {
}
}
Function Set-NSXTSegment {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 03/04/2018
Organization: VMware
Blog: http://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
Set a NSX-T Segment (Logical Networks) to either connected or disconnected
.DESCRIPTION
This cmdlet set an NSX-T Segment (Logical Networks) to either connected or disconnected
.EXAMPLE
New-NSXTSegment -Name "sddc-cgw-network-4" -Disconnected
.EXAMPLE
New-NSXTSegment -Name "sddc-cgw-network-4" -Connected
#>
Param (
[Parameter(Mandatory=$True)]$Name,
[Switch]$Disconnected,
[Switch]$Connected,
[Switch]$Troubleshoot
)
If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else {
$SegmentId = (Get-NSXTSegment -Name $Name).Id
if($Disconnected) {
$type = "DISCONNECTED"
$connectivity = "OFF"
$localEgress = "False"
$gateway = (Get-NSXTSegment -Name $Name).Gateway
}
If($Connected) {
$type = "ROUTED"
$connectivity = "ON"
$localEgress = "True"
$gateway = (Get-NSXTSegment -Name $Name).Gateway
}
$subnets = @{
gateway_address = $gateway;
}
$payload = @{
advanced_config = @{
local_egress = $localEgress;
connectivity = $connectivity;
}
type = $type;
subnets = @($subnets)
}
$body = $payload | ConvertTo-Json -depth 4
$method = "PATCH"
$aegmentsURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/tier-1s/cgw/segments/$SegmentId"
if($Troubleshoot) {
Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$newSegmentsURL`n"
Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n"
}
try {
if($PSVersionTable.PSEdition -eq "Core") {
$requests = Invoke-WebRequest -Uri $aegmentsURL -Body $body -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck
} else {
$requests = Invoke-WebRequest -Uri $aegmentsURL -Body $body -Method $method -Headers $global:nsxtProxyConnection.headers
}
} catch {
if($_.Exception.Response.StatusCode -eq "Unauthorized") {
Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n"
break
} else {
Write-Error "Error in updating NSX-T Segment connectivity"
Write-Error "`n($_.Exception.Message)`n"
break
}
}
if($requests.StatusCode -eq 200) {
Write-Host "Successfully updated NSX-T Segment $Name"
($requests.Content | ConvertFrom-Json) | select display_name, id
}
}
}
Function Remove-NSXTSegment {
<#
.NOTES

330
Modules/VyOS/VyOS.psm1 Normal file
View File

@@ -0,0 +1,330 @@
Function Set-VMKeystrokes {
param(
[Parameter(Mandatory=$true)][String]$VMName,
[Parameter(Mandatory=$true)][String]$StringInput,
[Parameter(Mandatory=$false)][Boolean]$ReturnCarriage,
[Parameter(Mandatory=$false)][Boolean]$DebugOn
)
# Map subset of USB HID keyboard scancodes
# https://gist.github.com/MightyPork/6da26e382a7ad91b5496ee55fdc73db2
$hidCharacterMap = @{
"a"="0x04";
"b"="0x05";
"c"="0x06";
"d"="0x07";
"e"="0x08";
"f"="0x09";
"g"="0x0a";
"h"="0x0b";
"i"="0x0c";
"j"="0x0d";
"k"="0x0e";
"l"="0x0f";
"m"="0x10";
"n"="0x11";
"o"="0x12";
"p"="0x13";
"q"="0x14";
"r"="0x15";
"s"="0x16";
"t"="0x17";
"u"="0x18";
"v"="0x19";
"w"="0x1a";
"x"="0x1b";
"y"="0x1c";
"z"="0x1d";
"1"="0x1e";
"2"="0x1f";
"3"="0x20";
"4"="0x21";
"5"="0x22";
"6"="0x23";
"7"="0x24";
"8"="0x25";
"9"="0x26";
"0"="0x27";
"!"="0x1e";
"@"="0x1f";
"#"="0x20";
"$"="0x21";
"%"="0x22";
"^"="0x23";
"&"="0x24";
"*"="0x25";
"("="0x26";
")"="0x27";
"_"="0x2d";
"+"="0x2e";
"{"="0x2f";
"}"="0x30";
"|"="0x31";
":"="0x33";
"`""="0x34";
"~"="0x35";
"<"="0x36";
">"="0x37";
"?"="0x38";
"-"="0x2d";
"="="0x2e";
"["="0x2f";
"]"="0x30";
"\"="0x31";
"`;"="0x33";
"`'"="0x34";
","="0x36";
"."="0x37";
"/"="0x38";
" "="0x2c";
}
$vm = Get-View -ViewType VirtualMachine -Filter @{"Name"="^$($VMName)$"}
# Verify we have a VM or fail
if(!$vm) {
Write-host "Unable to find VM $VMName"
return
}
$hidCodesEvents = @()
foreach($character in $StringInput.ToCharArray()) {
# Check to see if we've mapped the character to HID code
if($hidCharacterMap.ContainsKey([string]$character)) {
$hidCode = $hidCharacterMap[[string]$character]
$tmp = New-Object VMware.Vim.UsbScanCodeSpecKeyEvent
# Add leftShift modifer for capital letters and/or special characters
if( ($character -cmatch "[A-Z]") -or ($character -match "[!|@|#|$|%|^|&|(|)|_|+|{|}|||:|~|<|>|?|*]") ) {
$modifer = New-Object Vmware.Vim.UsbScanCodeSpecModifierType
$modifer.LeftShift = $true
$tmp.Modifiers = $modifer
}
# Convert to expected HID code format
$hidCodeHexToInt = [Convert]::ToInt64($hidCode,"16")
$hidCodeValue = ($hidCodeHexToInt -shl 16) -bor 0007
$tmp.UsbHidCode = $hidCodeValue
$hidCodesEvents+=$tmp
if($DebugOn) {
Write-Host "Character: $character -> HIDCode: $hidCode -> HIDCodeValue: $hidCodeValue"
}
} else {
Write-Host "The following character `"$character`" has not been mapped, you will need to manually process this character"
break
}
}
# Add return carriage to the end of the string input (useful for logins or executing commands)
if($ReturnCarriage) {
# Convert return carriage to HID code format
$hidCodeHexToInt = [Convert]::ToInt64("0x28","16")
$hidCodeValue = ($hidCodeHexToInt -shl 16) + 7
$tmp = New-Object VMware.Vim.UsbScanCodeSpecKeyEvent
$tmp.UsbHidCode = $hidCodeValue
$hidCodesEvents+=$tmp
}
# Call API to send keystrokes to VM
$spec = New-Object Vmware.Vim.UsbScanCodeSpec
$spec.KeyEvents = $hidCodesEvents
Write-Host "Sending `'$StringInput`' ...`n"
$results = $vm.PutUsbScanCodes($spec)
}
Function New-VyOSInstallation {
<#
.NOTES
===========================================================================
Created by: William Lam
Organization: VMware
Blog: www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.DESCRIPTION
This function automates the installation and configuration of VyOS from ISO
.PARAMETER VMName
The name of the VyOS VM
.PARAMETER ManagementPassword
The password to configure for the vyos user
.EXAMPLE
New-VyOSInstallation -VMName VyOS-Router -ManagementPassword VMware1!
#>
param(
[Parameter(Mandatory=$true)][String]$VMName,
[Parameter(Mandatory=$true)][String]$ManagementPassword
)
# Login to console and install VyOS before starting configuration
Set-VMKeystrokes -VMName $VMName -StringInput "vyos" -ReturnCarriage $true
Set-VMKeystrokes -VMName $VMName -StringInput "vyos" -ReturnCarriage $true
Set-VMKeystrokes -VMName $VMName -StringInput "install image" -ReturnCarriage $true
Set-VMKeystrokes -VMName $VMName -StringInput "yes" -ReturnCarriage $true
Start-Sleep -Seconds 5
Set-VMKeystrokes -VMName $VMName -StringInput "Auto" -ReturnCarriage $true
Start-Sleep -Seconds 1
Set-VMKeystrokes -VMName $VMName -StringInput "sda" -ReturnCarriage $true
Start-Sleep -Seconds 5
Set-VMKeystrokes -VMName $VMName -StringInput "yes" -ReturnCarriage $true
Start-Sleep -Seconds 5
Set-VMKeystrokes -VMName $VMName -StringInput " " -ReturnCarriage $true
Start-Sleep -Seconds 10
Set-VMKeystrokes -VMName $VMName -StringInput "vyos-router" -ReturnCarriage $true
Start-Sleep -Seconds 5
Set-VMKeystrokes -VMName $VMName -StringInput " " -ReturnCarriage $true
Start-Sleep -Seconds 10
Set-VMKeystrokes -VMName $VMName -StringInput "$ManagementPassword" -ReturnCarriage $true
Start-Sleep -Seconds 5
Set-VMKeystrokes -VMName $VMName -StringInput "$ManagementPassword" -ReturnCarriage $true
Start-Sleep -Seconds 5
Set-VMKeystrokes -VMName $VMName -StringInput "sda" -ReturnCarriage $true
Start-Sleep -Seconds 5
Set-VMKeystrokes -VMName $VMName -StringInput "reboot" -ReturnCarriage $true
Start-Sleep -Seconds 5
Set-VMKeystrokes -VMName $VMName -StringInput "y" -ReturnCarriage $true
Start-Sleep -Seconds 5
Get-VM $VMName | Get-CDDrive | Set-CDDrive -Connected $false -Confirm:$false -ErrorAction Ignore -WarningAction Ignore | Out-Null
Write-Host -ForegroundColor Green "VyOS has been installed, VM will reboot for changes to go into effect"
}
Function New-VyOSConfiguration {
<#
.NOTES
===========================================================================
Created by: William Lam
Organization: VMware
Blog: www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.DESCRIPTION
This function automates the installation and configuration of VyOS from ISO
.PARAMETER VMName
The name of the VyOS VM
.PARAMETER ManagementPassword
The password to configure for the vyos user
.PARAMETER ConfigFile
The path to VyOS configuration file
.PARAMETER ManagementAddress
The IP Address of the OUTSIDE Interface (eth0)
.PARAMETER ManagementGateway
The Gateway Addrss of the OUTSIDE Interface (eth0)
.PARAMETER ManagementDNSDomain
The DNS Domain on the WAN network
.PARAMETER ManagementDNSServer
The DNS Server on the WAN Network
.PARAMETER ManagementJumpHostIP
The IP Address of Windows Jumphost that can be used to RDP into various VLANs
.EXAMPLE
New-VyOSConfiguration -VMName VyOS-Router -ConfigFile vyos.template -ManagementAddress 192.168.30.156/24 -ManagementGateway 192.168.30.1 -ManagementDNSDomain primp-industries.com -ManagementDNSServer 192.168.30.2 -ManagementJumpHostIP 192.168.30.199 -ManagementPassword VMware1!
#>
param(
[Parameter(Mandatory=$true)][String]$VMName,
[Parameter(Mandatory=$true)][String]$ConfigFile,
[Parameter(Mandatory=$true)][String]$ManagementAddress,
[Parameter(Mandatory=$true)][String]$ManagementGateway,
[Parameter(Mandatory=$true)][String]$ManagementDNSDomain,
[Parameter(Mandatory=$true)][String]$ManagementDNSServer,
[Parameter(Mandatory=$true)][String]$ManagementJumpHostIP,
[Parameter(Mandatory=$true)][String]$ManagementPassword
)
# Login to console and install VyOS before starting configuration
Set-VMKeystrokes -VMName $VMName -StringInput "vyos" -ReturnCarriage $true
Set-VMKeystrokes -VMName $VMName -StringInput "$ManagementPassword" -ReturnCarriage $true
foreach ($cmd in Get-Content -Path $ConfigFile | Where-Object { $_.Trim() -ne '' }) {
if($cmd.Contains('[MANAGEMENT_ADDRESS]')) {
$cmd = $cmd.replace('[MANAGEMENT_ADDRESS]',$ManagementAddress)
if($Troubleshoot) {
$cmd
} else {
Set-VMKeystrokes -VMName $VMName -StringInput $cmd -ReturnCarriage $true
Start-Sleep -Seconds 1
}
} elseif($cmd.Contains('[MANAGEMENT_IP]')) {
$ManagementAddress = $ManagementAddress.substring(0,$ManagementAddress.IndexOf('/'))
$cmd = $cmd.replace('[MANAGEMENT_IP]',$ManagementAddress)
if($Troubleshoot) {
$cmd
} else {
Set-VMKeystrokes -VMName $VMName -StringInput $cmd -ReturnCarriage $true
Start-Sleep -Seconds 1
}
} elseif($cmd.Contains('[MANAGEMENT_GATEWAY]')) {
$cmd = $cmd.replace('[MANAGEMENT_GATEWAY]',$ManagementGateway)
if($Troubleshoot) {
$cmd
} else {
Set-VMKeystrokes -VMName $VMName -StringInput $cmd -ReturnCarriage $true
Start-Sleep -Seconds 1
}
} elseif($cmd.Contains('[JUMPHOST_VM_IP]')) {
$cmd = $cmd.replace('[JUMPHOST_VM_IP]',$ManagementJumpHostIP)
if($Troubleshoot) {
$cmd
} else {
Set-VMKeystrokes -VMName $VMName -StringInput $cmd -ReturnCarriage $true
Start-Sleep -Seconds 1
}
} elseif($cmd.Contains('[MANAGEMENT_DNS_DOMAIN]')) {
$cmd = $cmd.replace('[MANAGEMENT_DNS_DOMAIN]',$ManagementDNSDomain)
$cmd = $cmd.replace('[MANAGEMENT_DNS_SERVER]',$ManagementDNSServer)
if($Troubleshoot) {
$cmd
} else {
Set-VMKeystrokes -VMName $VMName -StringInput $cmd -ReturnCarriage $true
Start-Sleep -Seconds 1
}
} elseif($cmd.Contains('[MANAGEMENT_DNS_SERVER]')) {
$cmd = $cmd.replace('[MANAGEMENT_DNS_SERVER]',$ManagementDNSServer)
if($Troubleshoot) {
$cmd
} else {
Set-VMKeystrokes -VMName $VMName -StringInput $cmd -ReturnCarriage $true
Start-Sleep -Seconds 1
}
} else {
if($Troubleshoot) {
$cmd
} else {
Set-VMKeystrokes -VMName $VMName -StringInput $cmd -ReturnCarriage $true
Start-Sleep -Seconds 1
}
}
}
<#
# Configure and Enable VyOS REST API
# REST API not very functional, no GET operatoin and a bit kludgey on setup
$httpApiConf = "http-api.conf"
$config = @"
{
"listen_address": "$($ManagementAddress.substring(0,$ManagementAddress.IndexOf('/')))",
"port": 8080,
"debug": true,
"api_keys": [
{"id": "powercli", "key": "${ManagementPassword}"}
]
}
"@
$config | Set-Content "$httpApiConf"
Get-Item "$httpApiConf" | Copy-VMGuestFile -LocalToGuest -Destination "/home/vyos/${httpApiConf}" -VM (Get-VM $VMName) -GuestUser "vyos" -GuestPassword "$ManagementPassword" -Force
Write-Host "Creating VyOS REST API Configuration /etc/vyos/${httpApiConf} ..."
$scriptText = "echo `"${ManagementPassword}`" | sudo -S cp /home/vyos/${httpApiConf} /etc/vyos/${httpApiConf}"
Invoke-VMScript -ScriptText $scriptText -vm (Get-VM $VMName) -GuestUser "vyos" -GuestPassword $ManagementPassword
Write-Host "Starting VyOS REST API ..."
$scriptText = "echo `"${ManagementPassword}`" | sudo -S systemctl start vyos-http-api"
Invoke-VMScript -ScriptText $scriptText -vm (Get-VM $VMName) -GuestUser "vyos" -GuestPassword $ManagementPassword
#>
}

View File

@@ -0,0 +1,66 @@
configure
set service ssh port 22
set interfaces ethernet eth0 address '[MANAGEMENT_ADDRESS]'
set interfaces ethernet eth0 description 'Outside'
set interfaces ethernet eth1 address '192.168.0.1/24'
set interfaces ethernet eth1 description 'Inside'
set nat source rule 100 outbound-interface 'eth0'
set nat source rule 100 translation address '[MANAGEMENT_IP]'
set nat source rule 100 translation address 'masquerade'
set protocols static route 0.0.0.0/0 next-hop [MANAGEMENT_GATEWAY]
set interfaces ethernet eth1 mtu '1700'
set interfaces ethernet eth1 vif 10 address '172.30.10.1/24'
set interfaces ethernet eth1 vif 10 description 'VLAN 10 for MGMT'
set interfaces ethernet eth1 vif 20 address '172.30.20.1/24'
set interfaces ethernet eth1 vif 20 description 'VLAN 20 for HOST VTEP'
set interfaces ethernet eth1 vif 20 mtu '1700'
set interfaces ethernet eth1 vif 30 address '172.30.30.1/24'
set interfaces ethernet eth1 vif 30 description 'VLAN 30 for EDGE VTEP'
set interfaces ethernet eth1 vif 30 mtu '1700'
set interfaces ethernet eth1 vif 40 address '172.30.40.1/24'
set interfaces ethernet eth1 vif 40 description 'VLAN 40 for EDGE UPLINK'
set interfaces ethernet eth1 vif 40 mtu '1700'
set nat destination rule 100 description 'RDP to [JUMPHOST_VM_IP]:3389'
set nat destination rule 100 destination port '3389'
set nat destination rule 100 inbound-interface 'eth0'
set nat destination rule 100 protocol 'tcp'
set nat destination rule 100 translation address '192.168.0.10'
set nat destination rule 100 translation port '3389'
set service dns forwarding domain [MANAGEMENT_DNS_DOMAIN] server [MANAGEMENT_DNS_SERVER]
set service dns forwarding domain 10.30.172.in-addr.arpa. server [MANAGEMENT_DNS_SERVER]
set service dns forwarding domain 20.30.172.in-addr.arpa. server [MANAGEMENT_DNS_SERVER]
set service dns forwarding domain 30.30.172.in-addr.arpa. server [MANAGEMENT_DNS_SERVER]
set service dns forwarding domain 40.30.172.in-addr.arpa. server [MANAGEMENT_DNS_SERVER]
set service dns forwarding allow-from 0.0.0.0/0
set service dns forwarding listen-address 192.168.0.1
set service dns forwarding listen-address 172.30.10.1
set service dns forwarding listen-address 172.30.20.1
set service dns forwarding listen-address 172.30.30.1
set service dns forwarding listen-address 172.30.40.1
set service dns forwarding name-server 8.8.8.8
set service dns forwarding name-server 8.8.8.4
set nat source rule 10 outbound-interface eth0
set nat source rule 10 source address 172.30.10.0/24
set nat source rule 10 translation address masquerade
set nat source rule 20 outbound-interface eth0
set nat source rule 20 source address 172.30.20.0/24
set nat source rule 20 translation address masquerade
set nat source rule 30 outbound-interface eth0
set nat source rule 30 source address 172.30.30.0/24
set nat source rule 30 translation address masquerade
set nat source rule 40 outbound-interface eth0
set nat source rule 40 source address 172.30.40.0/24
set nat source rule 40 translation address masquerade
commit
save
exit