github.com/openshift/installer@v1.4.17/upi/vsphere/powercli/upi-functions.ps1 (about)

     1  #!/usr/bin/pwsh
     2  
     3  function New-OpenShiftVM {
     4      param(
     5          [Parameter(Mandatory=$true)]
     6          $Datastore,
     7          $FailureDomain,
     8          [Parameter(Mandatory=$true)]
     9          [string]$IgnitionData,
    10          [switch]$LinkedClone,
    11          $Location,
    12          $MemoryMB,
    13          [Parameter(Mandatory=$true)]
    14          [string]$Name,
    15          $Network,
    16          $Networking,
    17          $NumCpu,
    18          $ReferenceSnapshot,
    19          $ResourcePool,
    20          $SecureBoot,
    21          $StoragePolicy,
    22          [Parameter(Mandatory=$true)]
    23          $Tag,
    24          [Parameter(Mandatory=$true)]
    25          $Template,
    26          $VMHost
    27      )
    28  
    29      #Write-Output $IgnitionData
    30  
    31      # Create arg collection for New-VM
    32      $args = $PSBoundParameters
    33      $args.Remove('Template') > $null
    34      $args.Remove('IgnitionData') > $null
    35      $args.Remove('Tag') > $null
    36      $args.Remove('Networking') > $null
    37      $args.Remove('Network') > $null
    38      $args.Remove('MemoryMB') > $null
    39      $args.Remove('NumCpu') > $null
    40      $args.Remove('SecureBoot') > $null
    41      foreach ($key in $args.Keys){
    42          if ($NULL -eq $($args.Item($key)) -or $($args.Item($key)) -eq "") {
    43              $args.Remove($key) > $null
    44          }
    45      }
    46  
    47      # If storage policy is set, lets pull the mo ref
    48      if ($NULL -ne $StoragePolicy -and $StoragePolicy -ne "")
    49      {
    50          $storagePolicyRef = Get-SpbmStoragePolicy -Id $StoragePolicy
    51          $args["StoragePolicy"] = $storagePolicyRef
    52      }
    53  
    54      # Clone the virtual machine from the imported template
    55      # $vm = New-VM -VM $Template -Name $Name -Datastore $Datastore -ResourcePool $ResourcePool #-Location $Folder #-LinkedClone -ReferenceSnapshot $Snapshot
    56      $vm = New-VM -VM $Template @args
    57  
    58      # Assign tag so we can later clean up
    59      New-TagAssignment -Entity $vm -Tag $Tag > $null
    60  
    61      # Update VM specs.  New-VM does not honor the passed in parameters due to Template being used.
    62      if ($null -ne $MemoryMB -And $null -ne $NumCpu)
    63      {
    64          Set-VM -VM $vm -MemoryMB $MemoryMB -NumCpu $NumCpu -CoresPerSocket 4 -Confirm:$false > $null
    65      }
    66      #Get-HardDisk -VM $vm | Select-Object -First 1 | Set-HardDisk -CapacityGB 120 -Confirm:$false > $null
    67      updateDisk -VM $vm -CapacityGB 120
    68  
    69      # Configure Network (Assuming template networking may not be correct if shared across clusters)
    70      $pg = Get-VirtualPortgroup -Name $Network -VMHost $(Get-VMHost -VM $vm) 2> $null
    71      $vm | Get-NetworkAdapter | Set-NetworkAdapter -Portgroup $pg -confirm:$false > $null
    72  
    73      # Assign advanced settings
    74      New-AdvancedSetting -Entity $vm -name "disk.enableUUID" -value "TRUE" -confirm:$false -Force > $null
    75      New-AdvancedSetting -Entity $vm -name "stealclock.enable" -value "TRUE" -confirm:$false -Force > $null
    76      New-AdvancedSetting -Entity $vm -name "guestinfo.ignition.config.data.encoding" -value "base64" -confirm:$false -Force > $null
    77      New-AdvancedSetting -Entity $vm -name "guestinfo.ignition.config.data" -value $IgnitionData -confirm:$false -Force > $null
    78      New-AdvancedSetting -Entity $vm -name "guestinfo.hostname" -value $Name -Confirm:$false -Force > $null
    79  
    80      # Create ip kargs
    81      # "guestinfo.afterburn.initrd.network-kargs" = "ip=${var.ipaddress}::${cidrhost(var.machine_cidr, 1)}:${cidrnetmask(var.machine_cidr)}:${var.vmname}:ens192:none:${join(":", var.dns_addresses)}"
    82      # Example: ip=<ip_address>::<gateway>:<netmask>:<hostname>:<iface>:<protocol>:<dns_address>
    83      if ($null -ne $Networking)
    84      {
    85          $kargs = "ip=$($Networking.ipAddress)::$($Networking.gateway):$($Networking.netmask):$($Networking.hostname):ens192:none:$($Networking.dns)"
    86          New-AdvancedSetting -Entity $vm -name "guestinfo.afterburn.initrd.network-kargs" -value $kargs -Confirm:$false -Force > $null
    87      }
    88  
    89      # Enable secure boot if needed
    90      if ($true -eq $SecureBoot)
    91      {
    92          Set-SecureBoot -VM $vm
    93      }
    94  
    95      return $vm
    96  }
    97  
    98  # This function was created to work around issue in vSphere 8.0 where vCenter crashed
    99  # when Set-HardDisk is called.
   100  function updateDisk {
   101      param (
   102          $CapacityGB,
   103          $VM
   104      )
   105  
   106      $newDiskSizeKB = $CapacityGB * 1024 * 1024
   107      $newDiskSizeBytes = $newDiskSizeKB * 1024
   108  
   109      $vmMo = get-view -id $VM.ExtensionData.MoRef
   110  
   111      $devices = $vmMo.Config.Hardware.Device
   112  
   113      $spec = New-Object VMware.Vim.VirtualMachineConfigSpec
   114      $spec.DeviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec[] (1)
   115      $spec.DeviceChange[0] = New-Object VMware.Vim.VirtualDeviceConfigSpec
   116      $spec.DeviceChange[0].Operation = 'edit'
   117  
   118      foreach($d in $devices) {
   119          if ($d.DeviceInfo.Label.Contains("Hard disk")) {
   120              $spec.DeviceChange[0].Device = $d
   121          }
   122      }
   123  
   124      $spec.DeviceChange[0].Device.CapacityInBytes = $newDiskSizeBytes
   125      $spec.DeviceChange[0].Device.CapacityInKB = $newDiskSizeKB
   126  
   127      $vmMo.ReconfigVM_Task($spec) > $null
   128  }
   129  
   130  function New-VMConfigs {
   131      $virtualMachines = @"
   132  {
   133      "virtualmachines": {}
   134  }
   135  "@ | ConvertFrom-Json -Depth 2
   136      $fds = ConvertFrom-Json $failure_domains
   137  
   138      # Generate Bootstrap
   139      $vm = createNode -FailureDomain $fds[0] -Type "bootstrap" -VCenter $vcenter -IPAddress $bootstrap_ip_address
   140      add-member -Name "bootstrap" -value $vm -MemberType NoteProperty -InputObject $virtualMachines.virtualmachines
   141  
   142      # Generate Control Plane
   143      for (($i =0); $i -lt $control_plane_count; $i++) {
   144          $vm = createNode -FailureDomain $fds[$i % $fds.Length] -Type "master" -VCenter $vcenter -IPAddress $control_plane_ip_addresses[$i]
   145          add-member -Name $control_plane_hostnames[$i] -value $vm -MemberType NoteProperty -InputObject $virtualMachines.virtualmachines
   146      }
   147  
   148      # Generate Compute
   149      for (($i =0); $i -lt $compute_count; $i++) {
   150          $vm = createNode -FailureDomain $fds[$i % $fds.Length] -Type "worker" -VCenter $vcenter -IPAddress $compute_ip_addresses[$i]
   151          add-member -Name $compute_hostnames[$i] -value $vm -MemberType NoteProperty -InputObject $virtualMachines.virtualmachines
   152      }
   153  
   154      return $virtualMachines | ConvertTo-Json
   155  }
   156  
   157  function createNode {
   158      param (
   159          $FailureDomain,
   160          $IPAddress,
   161          $Type,
   162          $VCenter
   163      )
   164  
   165      $vmConfig = @"
   166  {
   167      "server": "$($VCenter)",
   168      "datacenter": "$($FailureDomain. datacenter)",
   169      "cluster": "$($FailureDomain.cluster)",
   170      "network": "$($FailureDomain.network)",
   171      "datastore": "$($FailureDomain.datastore)",
   172      "type": "$($Type)",
   173      "ip": "$($IPAddress)"
   174  }
   175  "@
   176      return ConvertFrom-Json -InputObject $vmConfig
   177  }
   178  
   179  function New-LoadBalancerIgnition {
   180      param (
   181          [string]$sshKey
   182      )
   183  
   184      $haproxyService = (Get-Content -Path ./lb/haproxy.service -Raw) | ConvertTo-Json
   185  
   186      $api = $control_plane_ip_addresses + $bootstrap_ip_address
   187      if ($compute_count -gt 0)
   188      {
   189          $ingress = $compute_ip_addresses
   190      } else {
   191          $ingress = $control_plane_ip_addresses
   192      }
   193  
   194      $Binding = @{ 'lb_ip_address' = $lb_ip_address; 'api' = $api; 'ingress' = $ingress }
   195      $haproxyConfig = Invoke-EpsTemplate -Path "lb/haproxy.erb.tmpl" -Binding $Binding
   196  
   197      $haproxyConfig = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($haproxyConfig))
   198  
   199      $lbIgnition = @"
   200  {
   201    "ignition": { "version": "3.0.0" },
   202    "passwd": {
   203      "users": [
   204        {
   205          "name": "core",
   206          "sshAuthorizedKeys": [
   207            "$($sshKey)"
   208          ]
   209        }
   210      ]
   211    },
   212    "storage": {
   213      "files": [{
   214        "path": "/etc/haproxy/haproxy.conf",
   215        "mode": 420,
   216        "contents": { "source": "data:text/plain;charset=utf-8;base64,$($haproxyConfig)" }
   217      }]
   218    },
   219    "systemd": {
   220      "units": [{
   221        "name": "haproxy.service",
   222        "enabled": true,
   223        "contents": $($haproxyService)
   224      }]
   225    }
   226  }
   227  "@
   228      return $lbIgnition
   229  }
   230  
   231  function New-VMNetworkConfig {
   232      param(
   233          $DNS,
   234          $Gateway,
   235          $Hostname,
   236          $IPAddress,
   237          $Netmask
   238      )
   239      $network = $null
   240  
   241      $network = @"
   242  {
   243    "ipAddress": "$($IPAddress)",
   244    "netmask": "$($Netmask)",
   245    "dns": "$($DNS)",
   246    "hostname": "$($Hostname)",
   247    "gateway": "$($Gateway)"
   248  }
   249  "@
   250      return ConvertFrom-Json -InputObject $network
   251  }
   252  
   253  function New-OpenshiftVMs {
   254      param(
   255          $NodeType
   256      )
   257  
   258      Write-Output "Creating $($NodeType) VMs"
   259  
   260      $jobs = @()
   261      $vmStep = (100 / $vmHash.virtualmachines.Count)
   262      $vmCount = 1
   263      foreach ($key in $vmHash.virtualmachines.Keys) {
   264          $node = $vmHash.virtualmachines[$key]
   265  
   266          if ($NodeType -ne $node.type) {
   267              continue
   268          }
   269  
   270          $jobs += Start-ThreadJob -n "create-vm-$($metadata.infraID)-$($key)" -ScriptBlock {
   271              param($key,$node,$vm_template,$metadata,$tag,$scriptdir,$cliContext)
   272              . .\variables.ps1
   273              . ${scriptdir}\upi-functions.ps1
   274              Use-PowerCLIContext -PowerCLIContext $cliContext
   275  
   276              $name = "$($metadata.infraID)-$($key)"
   277              Write-Output "Creating $($name)"
   278  
   279              $rp = Get-ResourcePool -Name $($metadata.infraID) -Location $(Get-Cluster -Name $($node.cluster)) -Server $vcenter
   280              ##$datastore = Get-Datastore -Name $node.datastore -Server $node.server
   281              $datastoreInfo = Get-Datastore -Name $node.datastore -Location $node.datacenter
   282  
   283              # Pull network config for each node
   284              if ($node.type -eq "master") {
   285                  $numCPU = $control_plane_num_cpus
   286                  $memory = $control_plane_memory
   287              } elseif ($node.type -eq "worker") {
   288                  $numCPU = $compute_num_cpus
   289                  $memory = $compute_memory
   290              } else {
   291                  # should only be bootstrap
   292                  $numCPU = $control_plane_num_cpus
   293                  $memory = $control_plane_memory
   294              }
   295              $ip = $node.ip
   296              $network = New-VMNetworkConfig -Hostname $name -IPAddress $ip -Netmask $netmask -Gateway $gateway -DNS $dns
   297  
   298              # Get the content of the ignition file per machine type (bootstrap, master, worker)
   299              $bytes = Get-Content -Path "./$($node.type).ign" -AsByteStream
   300              $ignition = [Convert]::ToBase64String($bytes)
   301  
   302              # Get correct template / folder
   303              $folder = Get-Folder -Name $clustername -Location $node.datacenter
   304              $template = Get-VM -Name $vm_template -Location $($node.datacenter)
   305  
   306              # Clone the virtual machine from the imported template
   307              #$vm = New-OpenShiftVM -Template $template -Name $name -ResourcePool $rp -Datastore $datastoreInfo -Location $folder -LinkedClone -ReferenceSnapshot $snapshot -IgnitionData $ignition -Tag $tag -Networking $network -NumCPU $numCPU -MemoryMB $memory
   308              $vm = New-OpenShiftVM -Template $template -Name $name -ResourcePool $rp -Datastore $datastoreInfo -Location $folder -IgnitionData $ignition -Tag $tag -Networking $network -Network $node.network -SecureBoot $secureboot -StoragePolicy $storagepolicy -NumCPU $numCPU -MemoryMB $memory
   309  
   310              # Assign tag so we can later clean up
   311              # New-TagAssignment -Entity $vm -Tag $tag
   312              # New-AdvancedSetting -Entity $vm -name "guestinfo.ignition.config.data" -value $ignition -confirm:$false -Force > $null
   313              # New-AdvancedSetting -Entity $vm -name "guestinfo.hostname" -value $name -Confirm:$false -Force > $null
   314  
   315              if ($node.type -eq "master" -And $delayVMStart) {
   316                  # To give bootstrap some time to start, lets wait 2 minutes
   317                  Start-ThreadJob -ThrottleLimit 5 -InputObject $vm {
   318                      Start-Sleep -Seconds 90
   319                      $input | Start-VM
   320                  }
   321              } elseif ($node.type -eq "worker" -And $delayVMStart) {
   322                  # Workers are not needed right away, gotta wait till masters
   323                  # have started machine-server.  wait 7 minutes to start.
   324                  Start-ThreadJob -ThrottleLimit 5 -InputObject $vm {
   325                      Start-Sleep -Seconds 600
   326                      $input | Start-VM
   327                  }
   328              }
   329              else {
   330                  $vm | Start-VM
   331              }
   332          } -ArgumentList @($key,$node,$vm_template,$metadata,$tag,$SCRIPTDIR,$cliContext)
   333          Write-Progress -id 222 -Activity "Creating virtual machines" -PercentComplete ($vmStep * $vmCount)
   334          $vmCount++
   335      }
   336      Wait-Job -Job $jobs
   337      foreach ($job in $jobs) {
   338          Receive-Job -Job $job
   339      }
   340  }
   341  
   342  # This function is used to set secure boot.
   343  function Set-SecureBoot {
   344      param(
   345          $VM
   346      )
   347  
   348      $spec = New-Object VMware.Vim.VirtualMachineConfigSpec
   349      $spec.Firmware = [VMware.Vim.GuestOsDescriptorFirmwareType]::efi
   350  
   351      $boot = New-Object VMware.Vim.VirtualMachineBootOptions
   352      $boot.EfiSecureBootEnabled = $true
   353  
   354      $spec.BootOptions = $boot
   355  
   356      $VM.ExtensionData.ReconfigVM($spec)
   357  }