winspray.psm1
#TODO : validate config against JSON Schema #TODO : few synopsys $script:PSModule = $ExecutionContext.SessionState.Module $script:PSModuleRoot = $script:PSModule.ModuleBase $script:kubesprayVersion = "2.13.2" function Remove-Winspray-Cluster { Write-Host ( "# Winspray - destroying current cluster") if ( [System.IO.Directory]::Exists("$pwd\current") ) { if ( [System.IO.File]::Exists("$pwd\current\vagrant.vars.rb") ) { Write-Verbose ( "### Winspray - launching vagrant destroy -f" ) $env:WINSPRAYROOT=$script:PSModuleRoot vagrant destroy -f if (!$?) { throw ("Exiting $?") } # FIXME should exit and say use -Force and deal wit h this } $targetDir = "old-{0}" -f (Get-Date -Format "MM-dd-yyyy-HH-mm") Write-Verbose( "### Winspray - Moving current to $targetDir" ) Get-ChildItem -Path "$pwd/current" -Recurse | Move-Item -Destination "$targetDir" -Force Write-Host ( "## Winspray - destroy done `n" ) -ForegroundColor DarkGreen } else { Write-Host ( "## Winspray - nothing to destroy done. Remove VMs manually if needed `n" ) } } function Backup-Winspray-Cluster { [CmdletBinding()] Param( [parameter( ValueFromPipeline )] [string]$BackupName = "" ) Write-Host ("# Winspray - start backup with name '$BackupName'" ) Get-VM | Where-Object {$_.Name -like 'k8s-*'} | ForEach-Object -Process {Checkpoint-VM -Name $_.Name -SnapshotName "$BackupName"} if (!$?) { exit -1 } Write-Host ( "## Winspray - backup '$BackupName' ok `n") -ForegroundColor DarkGreen } function Restore-Winspray-Cluster{ [CmdletBinding()] Param( [parameter( ValueFromPipeline )] [string]$BackupName = "installed" ) Write-Host ("# Winspray - start restore with name '$BackupName'" ) Get-VM | Where-Object {$_.Name -like 'k8s-*'} | ForEach-Object -Process {Restore-VMSnapshot -Confirm:$false -Name "$BackupName" -VMName $_.Name } if (!$?) { exit -1 } Write-Host ( "## Winspray - restore '$BackupName' ok `n") -ForegroundColor DarkGreen } function Start-Winspray-Cluster { Write-Host ("# Winspray - start existing VMS" ) Get-VM | Where-Object {$_.Name -like 'k8s-*' -and $_.State -ne "Running" } | ForEach-Object -Process { Start-VM $_.Name } Write-Host ( "## Winspray - VMS started ok `n") -ForegroundColor DarkGreen } function Stop-Winspray-Cluster { Write-Host ("# Winspray - start existing VMS" ) Get-VM | Where-Object {$_.Name -like 'k8s-*'} | ForEach-Object -Process {Stop-VM $_.Name } Write-Host ( "## Winspray - VMS started ok `n") -ForegroundColor DarkGreen } function Prepare-Winspray-Cluster( ) { #FIXME : how to good inject Debug flag (from this direct cal plus from New-Winspray-Cluster) $AnsibleDebug = If ( $Debug ) {"-vvv"} Else {""} Write-Host ( "# Winspray - preparing VMs for kubernetes" ) Write-Verbose ( " ### Winspray - launching ansible-playbook --become -i /.../$KubernetesInfra.yaml /.../playbooks/prepare.yaml " ) # TODO : if existing docker/playbooks => use local docker run --rm -v "/var/run/docker.sock:/var/run/docker.sock" -e ANSIBLE_CONFIG=/winspray/ansible.cfg -v ${PWD}:/opt/winspray -t jseguillon/winspray:$script:kubesprayVersion bash -c "ansible-playbook $AnsibleDebug --become -i /opt/winspray/current/hosts.yaml /winspray/playbooks/prepare.yaml -e '@/opt/winspray/current/config/kubespray.vars.json' -e '@/opt/winspray/current/config/network.vars.json' -e '@/opt/winspray/current/config/authent.vars.json'" if (!$?) { throw "Exiting $?" } Write-Host ( "## Winspray - VMs prepared for kubespray `n" ) -ForegroundColor DarkGreen } function Install-Winspray-Cluster( ) { #FIXME : how to good inject Debug flag (from this direct cal plus from New-Winspray-Cluster) $AnsibleDebug = If ( $Debug ) {"-vvv"} Else {""} Write-Host ( "# Winspray - install kubernetes" ) Write-Verbose ( "** launching ansible-playbook --become -i /...$KubernetesInfra /.../cluster.yml" ) # TODO : if existing kubespray => use local docker run --rm -v "/var/run/docker.sock:/var/run/docker.sock" -e ANSIBLE_CONFIG=/winspray/ansible.cfg -v ${PWD}:/opt/winspray -t jseguillon/winspray:$script:kubesprayVersion bash -c "ansible-playbook $AnsibleDebug --become -i /opt/winspray/current/hosts.yaml -e '@/opt/winspray/current/config/kubespray.vars.json' -e '@/opt/winspray/current/config/network.vars.json' -e '@/opt/winspray/current/config/authent.vars.json' cluster.yml /winspray/playbooks/post-install.yml" if (!$?) { throw "Exiting $?" } Write-Host ( "## Winspray - kubernetes installed `n" ) -ForegroundColor DarkGreen } function Start-Winspray-Proxy( ) { [CmdletBinding()] Param( [parameter( ValueFromPipeline)] [string]$ProxyPort = "8082" ) $PortMap = "0.0.0.0:" + $ProxyPort +":8001" if ( (docker ps |Select-String -SimpleMatch "Winspray-proxy" | Measure-Object -Line).Lines -eq 0 ) { docker run --rm -d --name "Winspray-proxy" -p $PortMap -e KUBECONFIG=/opt/winspray/current/kube-config -v "/var/run/docker.sock:/var/run/docker.sock" -v ${PWD}:/opt/winspray -t jseguillon/winspray:$script:kubesprayVersion } Write-Host (" Dashboard acces : http://localhost:$ProxyPort/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#/login ") Write-Host (" Token : " ) Get-Content .\current\dashboard-token docker exec -d "Winspray-proxy" ssh -o StrictHostKeyChecking=no -4 -L 0.0.0.0:8001:localhost:8001 root@k8s-server-1.mshome.net '(((netstat -neap 2>/dev/null | grep 127.0.0.1:8001 >/dev/null) && echo "proxy already running" && sleep 3600) || sudo /usr/local/bin/kubectl proxy)&' } function Stop-Winspray-Proxy( ) { docker stop Winspray-proxy } function Do-Winspray-Bash( ) { Write-Host ( "" ) Write-Host ( "** Going to bash. Here are usefull commands : " ) Write-Host ( " pip install -r /opt/winspray/kubespray/requirements.txt" ) Write-Host ( " ansible-playbook --become -i /opt/winspray/current/hosts.yaml -e '@/opt/winspray/current/config/kubespray.vars.json' -e '@/opt/winspray/current/config/network.vars.json' -e '@/opt/winspray/current/config/authent.vars.json' /winspray/playbooks/post-install.yml" ) Write-Host ( "" ) docker run -it --rm -e KUBECONFIG=/opt/winspray/current/kube-config -v "/var/run/docker.sock:/var/run/docker.sock" -v ${PWD}:/opt/winspray -t jseguillon/winspray:$script:kubesprayVersion bash if (!$?) { throw "Exiting $?" } } function Test-Winspray-Env { Write-Host ("# Winspray - check env" ) $currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent()) if ( ! $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) ) { throw ( "** ERROR *** Please launch Powershell as administrator" ) } if( (Get-WindowsOptionalFeature -Online -FeatureName *hyperv* | Measure-Object -Line).Lines -eq 0 ) { throw ( "** ERROR *** Please install and acivate HyperV" ) } vagrant -v if(!$?) { throw ( "** ERROR *** Please install vagrant" ) } docker version if(!$?) { throw ( "** ERROR *** Please install and start docker" ) } Write-Host ( "## Winspray - check ok `n" ) -ForegroundColor DarkGreen } function New-Winspray-Inventory ( ) { [CmdletBinding()] Param( [parameter( ValueFromPipeline, Mandatory=$true )] [string]$KubernetesInfra ) Write-Host ("# Winspray - create kubespray inventory and vagant config" ) $FileName = (Get-Item $KubernetesInfra).Name if ( ! [System.IO.File]::Exists("$pwd/$FileName") ) { throw ( "** ERROR *** could not find infra file '$KubernetesInfra' in current '$pwd' path. Please ensure you launch Winspray commands in same path than infra file" ) } # launch ansible templates that renders in current/vagrant.vars.rb current/inventory.yaml + groups vars from example # TODO : if existing docker/playbooks => use local $NoPathInfra = (Get-Item $KubernetesInfra).Name docker run -v "/var/run/docker.sock:/var/run/docker.sock" --rm -v ${PWD}:/opt/winspray -it jseguillon/winspray:$script:kubesprayVersion ansible-playbook $AnsibleDebug --become --limit=localhost /winspray/playbooks/inventory_create.yaml -e "infra=$NoPathInfra" if (!$?) { throw ( "** ERROR *** Found error while creating inventory" ) } Write-Host ( "## Winspray - inventory and vagrant config created `n") -ForegroundColor DarkGreen } function New-Winspray-Cluster () { [CmdletBinding()] Param( [parameter( ValueFromPipeline, Mandatory=$true )] [string]$KubernetesInfra, [switch]$Force, [switch]$ContinueExisting ) $StartMs = Get-Date # FIXME debug [bool]$ContinueExisting = ( $PSBoundParameters.ContainsKey( 'ContinueExisting' ) ) [bool]$Force = ( $PSBoundParameters.ContainsKey( 'Force' ) ) Test-Winspray-Env # Existing current ? : ok to destroy if we got new target if ( [System.IO.Directory]::Exists("$pwd\current") -and (! $ContinueExisting ) ) { if ( $Force ) { Remove-Winspray-Cluster } else { Write-Host ( "Found existing cluster. Maybe you wanted to Start-Winspray-Cluster ?" ) throw "Please remove exiting cluster first or use -Force flag or start existing cluster " } } # Do not replay if going with ContinueExisting if ( ! [System.IO.File]::Exists("$pwd\current\vagrant.vars.rb") ) { New-Winspray-Inventory ($KubernetesInfra); Write-Host ("# Winspray - create new VMs" ) Write-Verbose ( "### Winspray - launching vagrant up" ) # Export root module path so vagrant can call script $env:WINSPRAYROOT=$script:PSModuleRoot vagrant up if (!$?) { throw "Exiting $?"; } Write-Host ( "## Winspray - VMs created ok `n" ) -ForegroundColor DarkGreen } # not new cluster ? quick start VMs for ContinueExisting mode else { Start-Winspray-Cluster } #cluster not yet prepared ? run prepare playbook if ( ! [System.IO.File]::Exists("$pwd\current\prepared.ok") ) { Prepare-Winspray-Cluster echo "ok" > $pwd\current\prepared.ok Backup-Winspray-Cluster ("prepared") } else { Write-Host ("# Winspray - VMS already prepared `n" ) } # kubernetes not installed ? run cluster playbook if ( ! [System.IO.File]::Exists("$pwd\current\installed.ok") ) { Install-Winspray-Cluster echo "ok" > $pwd\current\installed.ok Backup-Winspray-Cluster ("installed") } else { Write-Host ("# Winspray - Kubernetes already installed. Nothing to do `n" ) } $timeExec = (Get-Date) - $StartMs Write-Host ("# Winspray - kubernetes now running `n " ) -ForegroundColor DarkGreen Write-Host ("# Winspray - Time to start {0}h {1}m {2}s" -f ($timeExec.Hours, $timeExec.Minutes, $timeExec.Seconds )) } Export-ModuleMember -Function Start-Winspray-Proxy, Stop-Winspray-Proxy, Set-Winspray-Config, New-Winspray-Cluster, Remove-Winspray-Cluster, Start-Winspray-Cluster, Backup-Winspray-Cluster, Restore-Winspray-Cluster, Stop-Winspray-Cluster, Prepare-Winspray-Hosts, Install-Winspray-Hosts, New-Winspray-Inventory, Test-Winspray-Env, Set-Winspray-Inventory, Prepare-Winspray-Runtime, Do-Winspray-Bash |