Add PAIF-N automation example (#629)
* Adding PAIF-N demo scripts * Removing Confidential from headers * Addressing review comments --------- Co-authored-by: Lyuboslav Asenov <lasenov@vmware.com>
This commit is contained in:
344
Scripts/PAIF-N/01-deploy-vcf-workload-domain.ps1
Normal file
344
Scripts/PAIF-N/01-deploy-vcf-workload-domain.ps1
Normal file
@@ -0,0 +1,344 @@
|
|||||||
|
<#
|
||||||
|
# © 2024 Broadcom. All Rights Reserved. Broadcom. The term "Broadcom" refers to
|
||||||
|
# Broadcom Inc. and/or its subsidiaries.
|
||||||
|
#>
|
||||||
|
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
|
||||||
|
This script deploys a VI workload domain
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
|
||||||
|
This script creates a VI workload domain using the PowerCLI SDK module for VCF SDDC Manager.
|
||||||
|
|
||||||
|
The script can be broken into two main parts. First, the ESXi hosts are being commissioned.
|
||||||
|
Then, the actual VI domain is created using the commissioned ESXi hosts.
|
||||||
|
|
||||||
|
Both steps - ESXi host commissioning and VI domain creations - are three-stage operations themselves.
|
||||||
|
The commissioning/creation specs are constructed. The specs are validated. The actual operation is invoked.
|
||||||
|
The validation and operation invocation are long-running tasks. This requires awaiting and status tracking
|
||||||
|
until their completion. The waiting for validation and the actual operation is done using helper cmdlets -
|
||||||
|
Wait-VcfValidation and Wait-VcfTask, located in utils sub-folder.
|
||||||
|
|
||||||
|
On completion a new VI workload domain reflecting the given parameters should be created.
|
||||||
|
|
||||||
|
.NOTES
|
||||||
|
|
||||||
|
Prerequisites:
|
||||||
|
- A VCF Management Domain
|
||||||
|
- A minimum of three free hosts marked with the appropriate storage and at least 4 NICs.
|
||||||
|
Two of the NICs will be used for Frontend/Management and the other two for workloads.
|
||||||
|
|
||||||
|
"Global parameters", "Host commissioning parameters", "Workload domain creation parameters" should be updated to
|
||||||
|
reflect the environment they are run in. This may require altering the spec creation script.
|
||||||
|
|
||||||
|
#>
|
||||||
|
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
$SCRIPTROOT = ($PWD.ProviderPath, $PSScriptRoot)[!!$PSScriptRoot]
|
||||||
|
. (Join-Path $SCRIPTROOT 'utils/Wait-VcfTask.ps1')
|
||||||
|
. (Join-Path $SCRIPTROOT 'utils/Wait-VcfValidation.ps1')
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
# Global parameters
|
||||||
|
# --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Organization name of the workload domain
|
||||||
|
$OrgName = 'VMware'
|
||||||
|
|
||||||
|
# Name of the workload domain - used as a prefix for nested inventory items
|
||||||
|
$domainName = 'sfo-w01'
|
||||||
|
|
||||||
|
$domain = 'vrack.vsphere.local'
|
||||||
|
$gateway = '10.0.0.250'
|
||||||
|
$sddcManager = @{
|
||||||
|
Fqdn = "sddc-manager.$domain"
|
||||||
|
User = 'administrator@vsphere.local'
|
||||||
|
Password = 'VMware123!'
|
||||||
|
}
|
||||||
|
|
||||||
|
############################################################################################################################
|
||||||
|
# Host commissioning
|
||||||
|
############################################################################################################################
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
# Host commissioning parameters
|
||||||
|
|
||||||
|
$esxiHosts = @(
|
||||||
|
@{
|
||||||
|
Fqdn = "esxi-5.$domain"
|
||||||
|
Username = 'root'
|
||||||
|
Password = "ESXiSddc123!"
|
||||||
|
StorageType = "VSAN"
|
||||||
|
LicenseKey = 'XXXXX-XXXXX-XXXXX-XXXXX-XXXXX'
|
||||||
|
}
|
||||||
|
@{
|
||||||
|
Fqdn = "esxi-6.$domain"
|
||||||
|
Username = 'root'
|
||||||
|
Password = "ESXiSddc123!"
|
||||||
|
StorageType = "VSAN"
|
||||||
|
LicenseKey = 'XXXXX-XXXXX-XXXXX-XXXXX-XXXXX'
|
||||||
|
}
|
||||||
|
@{
|
||||||
|
Fqdn = "esxi-7.$domain"
|
||||||
|
Username = 'root'
|
||||||
|
Password = "ESXiSddc123!"
|
||||||
|
StorageType = "VSAN"
|
||||||
|
LicenseKey = 'XXXXX-XXXXX-XXXXX-XXXXX-XXXXX'
|
||||||
|
}
|
||||||
|
@{
|
||||||
|
Fqdn = "esxi-8.$domain"
|
||||||
|
Username = 'root'
|
||||||
|
Password = "ESXiSddc123!"
|
||||||
|
StorageType = "VSAN"
|
||||||
|
LicenseKey = 'XXXXX-XXXXX-XXXXX-XXXXX-XXXXX'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# The network pool to associate the host with
|
||||||
|
$networkPoolName = 'networkpool'
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Connect to SDDC manager
|
||||||
|
$sddcConn = Connect-VcfSddcManagerServer `
|
||||||
|
-Server $sddcManager.Fqdn `
|
||||||
|
-User $sddcManager.User `
|
||||||
|
-Password $sddcManager.Password
|
||||||
|
|
||||||
|
## Host commissioning spec construction
|
||||||
|
$NetworkPool = Invoke-VcfGetNetworkPool | `
|
||||||
|
Select-Object -ExpandProperty Elements | `
|
||||||
|
Where-Object { $_.Name -eq $NetworkPoolName }
|
||||||
|
|
||||||
|
$hostCommissionSpecs = $esxiHosts | % {
|
||||||
|
Initialize-VcfHostCommissionSpec -Fqdn $_.Fqdn `
|
||||||
|
-NetworkPoolId $NetworkPool.Id `
|
||||||
|
-Password $_.Password `
|
||||||
|
-StorageType $_.StorageType `
|
||||||
|
-Username $_.Username
|
||||||
|
}
|
||||||
|
|
||||||
|
## Host commissioning validation
|
||||||
|
$hostValidationResult = Invoke-VcfValidateHostCommissionSpec -HostCommissionSpecs $hostCommissionSpecs
|
||||||
|
$hostValidationResult = Wait-VcfValidation `
|
||||||
|
-Validation $hostValidationResult `
|
||||||
|
-UpdateValidation { param($id) Invoke-VcfGetHostCommissionValidationByID -id $id } `
|
||||||
|
-UpdateValidationArguments $hostValidationResult.Id `
|
||||||
|
-ThrowOnError
|
||||||
|
|
||||||
|
## Host commissioning
|
||||||
|
$commisionTask = Invoke-VcfCommissionHosts -hostCommissionSpecs $hostCommissionSpecs
|
||||||
|
$commisionTask = Wait-VcfTask $commisionTask -ThrowOnError
|
||||||
|
|
||||||
|
|
||||||
|
############################################################################################################################
|
||||||
|
# Workload domain creation
|
||||||
|
############################################################################################################################
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
# Workload domain creation parameters
|
||||||
|
|
||||||
|
$domainSpec = @{
|
||||||
|
DomainName = $DomainName
|
||||||
|
OrgName = $OrgName
|
||||||
|
VCenterSpec = @{
|
||||||
|
Name = "$DomainName-vc01"
|
||||||
|
DatacenterName = "$DomainName-dc01"
|
||||||
|
RootPassword = "VMware123!"
|
||||||
|
NetworkDetailsSpec = @{
|
||||||
|
DnsName = "$DomainName-vc01.$domain"
|
||||||
|
IpAddress = "10.0.0.40"
|
||||||
|
SubnetMask = "255.255.255.0"
|
||||||
|
Gateway = $gateway
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ComputeSpec = @{
|
||||||
|
ClusterSpecs = @(
|
||||||
|
@{
|
||||||
|
DatastoreSpec = @{
|
||||||
|
VSanDatastoreSpec = @{
|
||||||
|
DatastoreName = "$DomainName-ds01"
|
||||||
|
FailuresToTolerate = 1
|
||||||
|
LicenseKey = "XXXXX-XXXXX-XXXXX-XXXXX-XXXXX"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NetworkSpec = @{
|
||||||
|
VdsSpecs = @(
|
||||||
|
@{
|
||||||
|
Name = "$DomainName-vds01"
|
||||||
|
PortGroups = @(
|
||||||
|
@{
|
||||||
|
Name = 'vSAN'
|
||||||
|
TransportType = 'VSAN'
|
||||||
|
}
|
||||||
|
@{
|
||||||
|
Name = 'management'
|
||||||
|
TransportType = 'MANAGEMENT'
|
||||||
|
}
|
||||||
|
@{
|
||||||
|
Name = 'vmotion'
|
||||||
|
TransportType = 'VMOTION'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@{
|
||||||
|
Name = "$DomainName-vds02"
|
||||||
|
IsUsedByNsxt = $true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
NsxClusterSpec = @{
|
||||||
|
NsxTClusterSpec = @{
|
||||||
|
GeneveVlanId = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Name = "$DomainName-cl01"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
NsxTSpec = @{
|
||||||
|
NsxManagerSpecs = @(
|
||||||
|
@{
|
||||||
|
Name = "$domainName-nsx01a"
|
||||||
|
NetworkDetailsSpec = @{
|
||||||
|
DnsName = "$domainName-nsx01a.$domain"
|
||||||
|
IpAddress = "10.0.0.41"
|
||||||
|
SubnetMask = "255.255.255.0"
|
||||||
|
Gateway = $gateway
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@{
|
||||||
|
Name = "$domainName-nsx01b"
|
||||||
|
NetworkDetailsSpec = @{
|
||||||
|
DnsName = "$domainName-nsx01b.$domain"
|
||||||
|
IpAddress = "10.0.0.42"
|
||||||
|
SubnetMask = "255.255.255.0"
|
||||||
|
Gateway = $gateway
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@{
|
||||||
|
Name = "$domainName-nsx01c"
|
||||||
|
NetworkDetailsSpec = @{
|
||||||
|
DnsName = "$domainName-nsx01c.$domain"
|
||||||
|
IpAddress = "10.0.0.43"
|
||||||
|
SubnetMask = "255.255.255.0"
|
||||||
|
Gateway = $gateway
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
FormFactor = 'large'
|
||||||
|
LicenseKey = 'XXXXX-XXXXX-XXXXX-XXXXX-XXXXX'
|
||||||
|
NSXManagerAdminPassword = "VMware123!123"
|
||||||
|
Vip = '10.0.0.44'
|
||||||
|
VipFqdn = "$domainName-nsx01.$domain"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
## Workload domain spec construction
|
||||||
|
$esxiFqdns = $esxiHosts | Select-Object -ExpandProperty Fqdn
|
||||||
|
$VcfHost = Invoke-VcfGetHosts -status "UNASSIGNED_USEABLE" | `
|
||||||
|
Select-Object -ExpandProperty Elements | `
|
||||||
|
Where-Object { $esxiFqdns -contains $_.Fqdn }
|
||||||
|
|
||||||
|
$ComputeSpec = Initialize-VcfComputeSpec -ClusterSpecs (
|
||||||
|
$domainSpec.ComputeSpec.ClusterSpecs | ForEach-Object {
|
||||||
|
$_clusterSpec = $_
|
||||||
|
|
||||||
|
Initialize-VcfClusterSpec `
|
||||||
|
-DatastoreSpec (
|
||||||
|
Initialize-VcfDatastoreSpec `
|
||||||
|
-VsanDatastoreSpec (
|
||||||
|
Initialize-VcfVsanDatastoreSpec `
|
||||||
|
-DatastoreName $_.DatastoreSpec.VSanDatastoreSpec.DatastoreName `
|
||||||
|
-FailuresToTolerate $_.DatastoreSpec.VSanDatastoreSpec.FailuresToTolerate `
|
||||||
|
-LicenseKey $_.DatastoreSpec.VSanDatastoreSpec.LicenseKey
|
||||||
|
)) `
|
||||||
|
-HostSpecs (
|
||||||
|
$VcfHost | ForEach-Object {
|
||||||
|
$esxiHost = $esxiHosts | Where-Object { $_.Fqdn -eq $_.Fqdn } | Select-Object -First 1
|
||||||
|
|
||||||
|
Initialize-VcfHostSpec `
|
||||||
|
-Id $_.Id `
|
||||||
|
-LicenseKey $esxiHost.LicenseKey `
|
||||||
|
-HostNetworkSpec (
|
||||||
|
Initialize-VcfHostNetworkSpec -VmNics @(
|
||||||
|
Initialize-VcfVmNic -Id 'vmnic0' -VdsName $_clusterSpec.NetworkSpec.VdsSpecs[0].Name
|
||||||
|
Initialize-VcfVmNic -Id 'vmnic1' -VdsName $_clusterSpec.NetworkSpec.VdsSpecs[0].Name
|
||||||
|
Initialize-VcfVmNic -Id 'vmnic2' -VdsName $_clusterSpec.NetworkSpec.VdsSpecs[1].Name
|
||||||
|
Initialize-VcfVmNic -Id 'vmnic3' -VdsName $_clusterSpec.NetworkSpec.VdsSpecs[1].Name
|
||||||
|
))
|
||||||
|
}
|
||||||
|
) `
|
||||||
|
-Name $_.Name `
|
||||||
|
-NetworkSpec (
|
||||||
|
Initialize-VcfNetworkSpec `
|
||||||
|
-NsxClusterSpec (
|
||||||
|
Initialize-VcfNsxClusterSpec -NsxTClusterSpec (
|
||||||
|
Initialize-VcfNsxTClusterSpec `
|
||||||
|
-GeneveVlanId $_.NetworkSpec.NsxClusterSpec.NsxTClusterSpec.GeneveVlanId
|
||||||
|
)
|
||||||
|
) `
|
||||||
|
-VdsSpecs @(
|
||||||
|
Initialize-VcfVdsSpec -Name $_.NetworkSpec.VdsSpecs[0].Name `
|
||||||
|
-PortGroupSpecs (
|
||||||
|
$_.NetworkSpec.VdsSpecs[0].PortGroups | ForEach-Object {
|
||||||
|
Initialize-VcfPortgroupSpec `
|
||||||
|
-Name $_.Name `
|
||||||
|
-TransportType $_.TransportType
|
||||||
|
})
|
||||||
|
Initialize-VcfVdsSpec -Name $_.NetworkSpec.VdsSpecs[1].Name `
|
||||||
|
-IsUsedByNsxt $_.NetworkSpec.VdsSpecs[1].IsUsedByNsxt
|
||||||
|
))
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
$DomainCreationSpec = Initialize-VcfDomainCreationSpec `
|
||||||
|
-ComputeSpec $ComputeSpec `
|
||||||
|
-DomainName $domainSpec.DomainName `
|
||||||
|
-NsxTSpec (
|
||||||
|
Initialize-VcfNsxTSpec `
|
||||||
|
-FormFactor $domainSpec.NsxTSpec.FormFactor `
|
||||||
|
-LicenseKey $domainSpec.NsxTSpec.LicenseKey `
|
||||||
|
-NsxManagerAdminPassword $domainSpec.NsxTSpec.NSXManagerAdminPassword `
|
||||||
|
-NsxManagerSpecs (
|
||||||
|
$domainSpec.NsxTSpec.NsxManagerSpecs | ForEach-Object {
|
||||||
|
Initialize-VcfNsxManagerSpec `
|
||||||
|
-Name $_.Name `
|
||||||
|
-NetworkDetailsSpec (
|
||||||
|
Initialize-VcfNetworkDetailsSpec `
|
||||||
|
-DnsName $_.NetworkDetailsSpec.DnsName `
|
||||||
|
-IpAddress $_.NetworkDetailsSpec.IpAddress `
|
||||||
|
-SubnetMask $_.NetworkDetailsSpec.SubnetMask `
|
||||||
|
-Gateway $_.NetworkDetailsSpec.Gateway)
|
||||||
|
}
|
||||||
|
) `
|
||||||
|
-Vip $domainSpec.NsxTSpec.Vip `
|
||||||
|
-VipFqdn $domainSpec.NsxTSpec.VipFqdn) `
|
||||||
|
-OrgName $domainSpec.OrgName `
|
||||||
|
-VcenterSpec (
|
||||||
|
Initialize-VcfVcenterSpec `
|
||||||
|
-DatacenterName $domainSpec.VCenterSpec.DatacenterName `
|
||||||
|
-Name $domainSpec.VCenterSpec.Name `
|
||||||
|
-NetworkDetailsSpec (
|
||||||
|
Initialize-VcfNetworkDetailsSpec `
|
||||||
|
-DnsName $domainSpec.VCenterSpec.NetworkDetailsSpec.DnsName `
|
||||||
|
-IpAddress $domainSpec.VCenterSpec.NetworkDetailsSpec.IpAddress `
|
||||||
|
-SubnetMask $domainSpec.VCenterSpec.NetworkDetailsSpec.SubnetMask `
|
||||||
|
-Gateway $domainSpec.VCenterSpec.NetworkDetailsSpec.Gateway
|
||||||
|
) `
|
||||||
|
-RootPassword $domainSpec.VCenterSpec.RootPassword)
|
||||||
|
|
||||||
|
# Workload domain spec validation
|
||||||
|
$domainValidationResult = Invoke-VcfValidateDomainCreationSpec -domainCreationSpec $DomainCreationSpec
|
||||||
|
$domainValidationResult = Wait-VcfValidation `
|
||||||
|
-Validation $domainValidationResult `
|
||||||
|
-ThrowOnError
|
||||||
|
|
||||||
|
# Workload domain creation
|
||||||
|
$creationTask = Invoke-VcfCreateDomain -domainCreationSpec $DomainCreationSpec
|
||||||
|
$creationTask = Wait-VcfTask $creationTask -ThrowOnError
|
||||||
|
|
||||||
|
Disconnect-VcfSddcManagerServer $sddcConn
|
||||||
195
Scripts/PAIF-N/02-install-nvidia-driver-vlcm.ps1
Normal file
195
Scripts/PAIF-N/02-install-nvidia-driver-vlcm.ps1
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
<#
|
||||||
|
# © 2024 Broadcom. All Rights Reserved. Broadcom. The term "Broadcom" refers to
|
||||||
|
# Broadcom Inc. and/or its subsidiaries.
|
||||||
|
#>
|
||||||
|
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
|
||||||
|
This script configures the ESXi host for AI workloads
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
|
||||||
|
This script configures the ESXi host for AI workloads which includes installing the
|
||||||
|
NVIDIA AI Enterprise vGPU driver and NVIDIA GPU Management Daemon on the ESXi hosts.
|
||||||
|
vLCM is used for that purpose.
|
||||||
|
|
||||||
|
The script changes the default graphics type of the GPU devices to Shared Direct. The Xorg
|
||||||
|
service is then restarted. Finally, the vLCM is used to install the NVIDIA GPU driver and
|
||||||
|
management daemon.
|
||||||
|
|
||||||
|
.NOTES
|
||||||
|
|
||||||
|
Prerequisites:
|
||||||
|
- VI workload domain (vCenter server instance)
|
||||||
|
- ESXi hosts with GPUs
|
||||||
|
|
||||||
|
"Global parameters", "Workload domain parameters", "GPU parameters" should be updated to
|
||||||
|
reflect the environment they are run in. This may require altering the spec creation script.
|
||||||
|
|
||||||
|
#>
|
||||||
|
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
# Global parameters
|
||||||
|
# --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Name of the workload domain - used as a prefix for nested inventory items
|
||||||
|
$domainName = 'sfo-w01'
|
||||||
|
|
||||||
|
$domain = 'vrack.vsphere.local'
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
# Workload domain parameters - stripped down version of $domainSpec from 01-deploy-vcf-workload-domain.ps1
|
||||||
|
|
||||||
|
$domainSpec = @{
|
||||||
|
VCenterSpec = @{
|
||||||
|
RootPassword = "VMware123!"
|
||||||
|
NetworkDetailsSpec = @{
|
||||||
|
DnsName = "$DomainName-vc01.$domain"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ComputeSpec = @{
|
||||||
|
ClusterSpecs = @(
|
||||||
|
@{
|
||||||
|
Name = "$DomainName-cl01"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
# GPU parameters
|
||||||
|
|
||||||
|
$nvidiaDriverLocation = "http://NVIDIA-VGPU-DRIVER-LOCATION/"
|
||||||
|
$gpuParameters = @{
|
||||||
|
EsxiImageName = "8.0 U2b - 23305546"
|
||||||
|
NVIDIA = @(
|
||||||
|
@{
|
||||||
|
Location = "$nvidiaDriverLocation/NVD-AIE-800_550.54.16-1OEM.800.1.0.20613240_23471877.zip"
|
||||||
|
Name = "NVIDIA AI Enterprise vGPU driver for VMWare ESX-8.0.0"
|
||||||
|
Version = "550.54.16"
|
||||||
|
Description = 'NVIDIA AI Enterprise vGPU driver for VMWare ESX-8.0.0'
|
||||||
|
},
|
||||||
|
@{
|
||||||
|
Location = "$nvidiaDriverLocation/nvd-gpu-mgmt-daemon_550.54.16-0.0.0000_23475823.zip"
|
||||||
|
Name = "NVIDIA GPU monitoring and management daemon"
|
||||||
|
Version = "550.54.16 - Build 0000"
|
||||||
|
Description = "NVIDIA GPU monitoring and management daemon"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
GraphicsType = 'sharedDirect'
|
||||||
|
HostDefaultGraphicsType = 'sharedDirect'
|
||||||
|
SharedPassthruAssignmentPolicy = 'performance'
|
||||||
|
}
|
||||||
|
# --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Connect to the VC of the workload domain
|
||||||
|
$vcConn = Connect-VIServer `
|
||||||
|
-Server $domainSpec.VCenterSpec.NetworkDetailsSpec.DnsName `
|
||||||
|
-User 'administrator@vsphere.local' `
|
||||||
|
-Password $domainSpec.VCenterSpec.RootPassword
|
||||||
|
|
||||||
|
$esxHosts = $domainSpec.ComputeSpec.ClusterSpecs | ForEach-Object { Get-VMHost -Location $_.Name }
|
||||||
|
|
||||||
|
# Preparing the GPU Device for the vGPU Driver
|
||||||
|
$esxHosts | ForEach-Object {
|
||||||
|
$graphicsManager = Get-View -Id $_.ExtensionData.ConfigManager.GraphicsManager
|
||||||
|
|
||||||
|
# Preparing the GPU Device for the vGPU Driver
|
||||||
|
# change the default graphics type to Shared Direct
|
||||||
|
$_.ExtensionData.Config.GraphicsInfo | `
|
||||||
|
Where-Object { $_.GraphicsType -ne $gpuParameters.GraphicsType } | `
|
||||||
|
ForEach-Object {
|
||||||
|
$config = New-Object VMware.Vim.HostGraphicsConfig
|
||||||
|
$config.DeviceType = New-Object VMware.Vim.HostGraphicsConfigDeviceType[] (1)
|
||||||
|
$config.DeviceType[0] = New-Object VMware.Vim.HostGraphicsConfigDeviceType
|
||||||
|
$config.DeviceType[0].DeviceId = $_.PciId
|
||||||
|
$config.DeviceType[0].GraphicsType = $gpuParameters.GraphicsType
|
||||||
|
$config.HostDefaultGraphicsType = $gpuParameters.HostDefaultGraphicsType
|
||||||
|
$config.SharedPassthruAssignmentPolicy = $gpuParameters.SharedPassthruAssignmentPolicy
|
||||||
|
$graphicsManager.UpdateGraphicsConfig($config)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Restart xorg service
|
||||||
|
$_this = Get-View -Id $_.ExtensionData.ConfigManager.ServiceSystem
|
||||||
|
$_this.RestartService('xorg')
|
||||||
|
}
|
||||||
|
|
||||||
|
$uploadTasksId = $gpuParameters.NVIDIA | ForEach-Object {
|
||||||
|
# Upload the driver to vLCM
|
||||||
|
$SettingsDepotsOfflineCreateSpec = Initialize-SettingsDepotsOfflineCreateSpec `
|
||||||
|
-SourceType "PULL" `
|
||||||
|
-Location $_.Location `
|
||||||
|
-Description $_.Description
|
||||||
|
|
||||||
|
Invoke-CreateDepotsOfflineAsync -SettingsDepotsOfflineCreateSpec $SettingsDepotsOfflineCreateSpec
|
||||||
|
}
|
||||||
|
|
||||||
|
$uploadTasks = $uploadTasksId | ForEach-Object { Invoke-GetTask -task $_ }
|
||||||
|
|
||||||
|
Write-Progress -Id 0 "Uploading NVIDIA vGPU driver into vLCM"
|
||||||
|
$inProgress = $true
|
||||||
|
while ($inProgress) {
|
||||||
|
Write-Verbose "Waiting for NVIDIA driver upload into vLCM"
|
||||||
|
$uploadTasks | ConvertTo-Json -Depth 5 | Write-Verbose
|
||||||
|
|
||||||
|
$subprocess = ''
|
||||||
|
$completed = 0
|
||||||
|
$total = 0
|
||||||
|
|
||||||
|
$inProgress = $false
|
||||||
|
|
||||||
|
foreach ($t in $uploadTasks) {
|
||||||
|
if ($t -and $t.status -ne 'SUCCEEDED' -and $t.status -ne 'FAILED') {
|
||||||
|
$inProgress = $true
|
||||||
|
|
||||||
|
if ($t.progress) {
|
||||||
|
if ($t.progress.message -and `
|
||||||
|
$t.progress.message.default_message) {
|
||||||
|
if ($subprocess.Length -gt 0) {
|
||||||
|
$subprocess += ','
|
||||||
|
}
|
||||||
|
$subprocess += $t.progress.message.default_message
|
||||||
|
}
|
||||||
|
$completed += $t.progress.completed
|
||||||
|
$total += $t.progress.total
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($total -eq 0) { $total = 100 }
|
||||||
|
|
||||||
|
Write-Progress -Id 0 "Uploading NVIDIA vGPU driver into vLCM" -Status $subprocess -PercentComplete (($completed * 100) / $total)
|
||||||
|
|
||||||
|
Start-Sleep -Seconds 1
|
||||||
|
$uploadTasks = $uploadTasksId | ForEach-Object { Invoke-GetTask -task $_ }
|
||||||
|
}
|
||||||
|
Write-Progress -Id 0 "Uploading NVIDIA vGPU driver into vLCM" -Completed
|
||||||
|
|
||||||
|
# 3 vSphere LifeCycle Management Configuration
|
||||||
|
$esxiBaseImage = Get-LcmImage `
|
||||||
|
-Type BaseImage `
|
||||||
|
-Version $gpuParameters.EsxiImageName
|
||||||
|
$allComponents = Get-LcmImage -Type Component
|
||||||
|
$components = $gpuParameters.NVIDIA | ForEach-Object {
|
||||||
|
$nvd = $_
|
||||||
|
$allComponents | `
|
||||||
|
Where-Object {
|
||||||
|
$_.Name -eq $nvd.Name -and `
|
||||||
|
$_.Version -eq $nvd.Version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($components -isnot [array]) -or ($components.Length -ne $gpuParameters.NVIDIA.Length)) {
|
||||||
|
throw "Not all Nvidia components found"
|
||||||
|
}
|
||||||
|
|
||||||
|
$domainSpec.ComputeSpec.ClusterSpecs | ForEach-Object {
|
||||||
|
$cluster = Get-Cluster -Name $_.Name
|
||||||
|
$cluster = $cluster | Set-Cluster -BaseImage $esxiBaseImage -Component $components -Confirm:$false
|
||||||
|
$cluster = $cluster | Set-Cluster -AcceptEULA -Remediate -Confirm:$false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Disconnect-VIServer $vcConn
|
||||||
226
Scripts/PAIF-N/03-deploy-edge-cluster.ps1
Normal file
226
Scripts/PAIF-N/03-deploy-edge-cluster.ps1
Normal file
@@ -0,0 +1,226 @@
|
|||||||
|
<#
|
||||||
|
# © 2024 Broadcom. All Rights Reserved. Broadcom. The term "Broadcom" refers to
|
||||||
|
# Broadcom Inc. and/or its subsidiaries.
|
||||||
|
#>
|
||||||
|
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
|
||||||
|
This script creates a NSX edge cluster on a cluster in a VI workload domain
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
|
||||||
|
This script creates an NSX edge cluster on a cluster in a VI workload domain to provide connectivity
|
||||||
|
from external networks to Supervisor Cluster objects.
|
||||||
|
|
||||||
|
To create NSX Edge Cluster on multiple VI workload domain clusters the script should be modified and
|
||||||
|
executed multiple times.
|
||||||
|
|
||||||
|
.NOTES
|
||||||
|
|
||||||
|
Prerequisites:
|
||||||
|
- VI workload domain (vCenter server instance)
|
||||||
|
- VI workload domain cluster
|
||||||
|
|
||||||
|
"Global parameters", "Workload domain parameters", "Edge Cluster deployment parameters" should be updated to
|
||||||
|
reflect the environment they are run in. This may require altering the spec creation script.
|
||||||
|
|
||||||
|
#>
|
||||||
|
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
$SCRIPTROOT = ($PWD.ProviderPath, $PSScriptRoot)[!!$PSScriptRoot]
|
||||||
|
. (Join-Path $SCRIPTROOT 'utils/Wait-VcfTask.ps1')
|
||||||
|
. (Join-Path $SCRIPTROOT 'utils/Wait-VcfValidation.ps1')
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
# Global parameters
|
||||||
|
# --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
$domainName = 'sfo-w01'
|
||||||
|
|
||||||
|
$domain = 'vrack.vsphere.local'
|
||||||
|
$sddcManager = @{
|
||||||
|
Fqdn = "sddc-manager.$domain"
|
||||||
|
User = 'administrator@vsphere.local'
|
||||||
|
Password = 'VMware123!'
|
||||||
|
}
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
# Workload domain parameters - stripped down version of $domainSpec from 01-deploy-vcf-workload-domain.ps1
|
||||||
|
$domainSpec = @{
|
||||||
|
VCenterSpec = @{
|
||||||
|
RootPassword = "VMware123!"
|
||||||
|
NetworkDetailsSpec = @{
|
||||||
|
DnsName = "$DomainName-vc01.$domain"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Connect to SDDC manager
|
||||||
|
$sddcConn = Connect-VcfSddcManagerServer `
|
||||||
|
-Server $sddcManager.Fqdn `
|
||||||
|
-User $sddcManager.User `
|
||||||
|
-Password $sddcManager.Password
|
||||||
|
|
||||||
|
############################################################################################################################
|
||||||
|
# Deploy Edge Cluster in the created workload domain
|
||||||
|
############################################################################################################################
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
# Edge Cluster deployment parameters
|
||||||
|
|
||||||
|
# The VI workload cluster on which the NSX Edge Cluster will be created
|
||||||
|
$ClusterName = "$DomainName-cl01"
|
||||||
|
|
||||||
|
$edgeName = "$ClusterName-ec01"
|
||||||
|
|
||||||
|
$vcfCluster = Invoke-VcfGetClusters | `
|
||||||
|
Select-Object -ExpandProperty Elements | `
|
||||||
|
Where-Object { $_.Name -eq $ClusterName } | `
|
||||||
|
Select-Object -First 1
|
||||||
|
|
||||||
|
$EdgeClusterParams = @{
|
||||||
|
Asn = 65004
|
||||||
|
EdgeAdminPassword = 'VMware123!VMware123!'
|
||||||
|
EdgeAuditPassword = 'VMware123!VMware123!'
|
||||||
|
EdgeClusterName = $edgeName
|
||||||
|
EdgeClusterProfileType = "CUSTOM"
|
||||||
|
EdgeClusterType = "NSX-T"
|
||||||
|
EdgeFormFactor = "MEDIUM"
|
||||||
|
EdgeNodeSpecs = @(
|
||||||
|
@{
|
||||||
|
ClusterId = $vcfCluster.Id
|
||||||
|
EdgeNodeName = "$edgeName-en01.vrack.vsphere.local"
|
||||||
|
EdgeTep1IP = "192.168.52.12/24"
|
||||||
|
EdgeTep2IP = "192.168.52.13/24"
|
||||||
|
EdgeTepGateway = "192.168.52.1"
|
||||||
|
EdgeTepVlan = 1252
|
||||||
|
InterRackCluster = $false
|
||||||
|
ManagementGateway = "10.0.0.250"
|
||||||
|
ManagementIP = "10.0.0.52/24"
|
||||||
|
UplinkNetwork = @(
|
||||||
|
@{
|
||||||
|
UplinkInterfaceIP = "192.168.18.2/24"
|
||||||
|
UplinkVlan = 2083
|
||||||
|
AsnPeer = 65001
|
||||||
|
PeerIP = "192.168.18.10/24"
|
||||||
|
BgpPeerPassword = "VMware1!"
|
||||||
|
}
|
||||||
|
@{
|
||||||
|
UplinkInterfaceIP = "192.168.19.2/24"
|
||||||
|
UplinkVlan = 2084
|
||||||
|
AsnPeer = 65001
|
||||||
|
PeerIP = "192.168.19.10/24"
|
||||||
|
BgpPeerPassword = "VMware1!"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@{
|
||||||
|
ClusterId = $vcfCluster.Id
|
||||||
|
EdgeNodeName = "$edgeName-en02.vrack.vsphere.local"
|
||||||
|
EdgeTep1IP = "192.168.52.14/24"
|
||||||
|
EdgeTep2IP = "192.168.52.15/24"
|
||||||
|
EdgeTepGateway = "192.168.52.1"
|
||||||
|
EdgeTepVlan = 1252
|
||||||
|
InterRackCluster = $false
|
||||||
|
ManagementGateway = "10.0.0.250"
|
||||||
|
ManagementIP = "10.0.0.53/24"
|
||||||
|
UplinkNetwork = @(
|
||||||
|
@{
|
||||||
|
UplinkInterfaceIP = "192.168.18.3/24"
|
||||||
|
UplinkVlan = 2083
|
||||||
|
AsnPeer = 65001
|
||||||
|
PeerIP = "192.168.18.10/24"
|
||||||
|
BgpPeerPassword = "VMware1!"
|
||||||
|
}
|
||||||
|
@{
|
||||||
|
UplinkInterfaceIP = "192.168.19.3/24"
|
||||||
|
UplinkVlan = 2084
|
||||||
|
AsnPeer = 65001
|
||||||
|
PeerIP = "192.168.19.10/24"
|
||||||
|
BgpPeerPassword = "VMware1!"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
EdgeRootPassword = 'VMware123!VMware123!'
|
||||||
|
Mtu = 9000
|
||||||
|
SkipTepRoutabilityCheck = $true
|
||||||
|
Tier0Name = "$edgeName-t0"
|
||||||
|
Tier0RoutingType = "EBGP"
|
||||||
|
Tier0ServicesHighAvailability = "ACTIVE_ACTIVE"
|
||||||
|
Tier1Name = "$edgeName-t1"
|
||||||
|
EdgeClusterProfileSpec = @{
|
||||||
|
BfdAllowedHop = 255
|
||||||
|
BfdDeclareDeadMultiple = 3
|
||||||
|
BfdProbeInterval = 1000
|
||||||
|
EdgeClusterProfileName = "$ClusterName-ecp01"
|
||||||
|
StandbyRelocationThreshold = 30
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Edge cluster deployment spec construction
|
||||||
|
$edgeClusterCreationSpec = Initialize-VcfEdgeClusterCreationSpec `
|
||||||
|
-Asn $EdgeClusterParams.Asn `
|
||||||
|
-EdgeAdminPassword $EdgeClusterParams.EdgeAdminPassword `
|
||||||
|
-EdgeAuditPassword $EdgeClusterParams.EdgeAuditPassword `
|
||||||
|
-EdgeClusterName $EdgeClusterParams.EdgeClusterName `
|
||||||
|
-EdgeClusterProfileType "CUSTOM" `
|
||||||
|
-EdgeClusterType "NSX-T" `
|
||||||
|
-EdgeFormFactor $EdgeClusterParams.EdgeFormFactor `
|
||||||
|
-EdgeNodeSpecs (
|
||||||
|
$EdgeClusterParams.EdgeNodeSpecs | ForEach-Object {
|
||||||
|
Initialize-VcfNsxTEdgeNodeSpec `
|
||||||
|
-ClusterId $_.ClusterId `
|
||||||
|
-EdgeNodeName $_.EdgeNodeName `
|
||||||
|
-EdgeTep1IP $_.EdgeTep1IP `
|
||||||
|
-EdgeTep2IP $_.EdgeTep2IP `
|
||||||
|
-EdgeTepGateway $_.EdgeTepGateway `
|
||||||
|
-EdgeTepVlan $_.EdgeTepVlan `
|
||||||
|
-InterRackCluster $_.InterRackCluster `
|
||||||
|
-ManagementGateway $_.ManagementGateway `
|
||||||
|
-ManagementIP $_.ManagementIP `
|
||||||
|
-UplinkNetwork (
|
||||||
|
$_.UplinkNetwork | ForEach-Object {
|
||||||
|
Initialize-VcfNsxTEdgeUplinkNetwork `
|
||||||
|
-UplinkInterfaceIP $_.UplinkInterfaceIP `
|
||||||
|
-UplinkVlan $_.UplinkVlan `
|
||||||
|
-AsnPeer $_.AsnPeer `
|
||||||
|
-PeerIP $_.PeerIP `
|
||||||
|
-BgpPeerPassword $_.BgpPeerPassword
|
||||||
|
})
|
||||||
|
}
|
||||||
|
) `
|
||||||
|
-EdgeRootPassword $EdgeClusterParams.EdgeRootPassword `
|
||||||
|
-Mtu $EdgeClusterParams.Mtu `
|
||||||
|
-SkipTepRoutabilityCheck $EdgeClusterParams.SkipTepRoutabilityCheck `
|
||||||
|
-Tier0Name $EdgeClusterParams.Tier0Name `
|
||||||
|
-Tier0RoutingType $EdgeClusterParams.Tier0RoutingType `
|
||||||
|
-Tier0ServicesHighAvailability $EdgeClusterParams.Tier0ServicesHighAvailability `
|
||||||
|
-Tier1Name $EdgeClusterParams.Tier1Name `
|
||||||
|
-EdgeClusterProfileSpec (Initialize-VcfNsxTEdgeClusterProfileSpec `
|
||||||
|
-BfdAllowedHop $EdgeClusterParams.EdgeClusterProfileSpec.BfdAllowedHop `
|
||||||
|
-BfdDeclareDeadMultiple $EdgeClusterParams.EdgeClusterProfileSpec.BfdDeclareDeadMultiple `
|
||||||
|
-BfdProbeInterval $EdgeClusterParams.EdgeClusterProfileSpec.BfdProbeInterval `
|
||||||
|
-EdgeClusterProfileName $EdgeClusterParams.EdgeClusterProfileSpec.EdgeClusterProfileName `
|
||||||
|
-StandbyRelocationThreshold $EdgeClusterParams.EdgeClusterProfileSpec.StandbyRelocationThreshold)
|
||||||
|
|
||||||
|
$edgeClusterCreationSpec.EdgeClusterProfileType = $EdgeClusterParams.EdgeClusterProfileType
|
||||||
|
if ($EdgeClusterParams.EdgeClusterProfileType -eq "DEFAULT") {
|
||||||
|
$edgeClusterCreationSpec.EdgeClusterProfileSpec = $null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Edge cluster deployment spec validation
|
||||||
|
$edgeValidationResult = Invoke-VcfValidateEdgeClusterCreationSpec -edgeCreationSpec $edgeClusterCreationSpec
|
||||||
|
$edgeValidationResult = Wait-VcfValidation `
|
||||||
|
-Validation $edgeValidationResult `
|
||||||
|
-UpdateValidation { param($id) Invoke-VcfGetEdgeClusterValidationByID -id $id } `
|
||||||
|
-UpdateValidationArguments $edgeValidationResult.Id `
|
||||||
|
-ThrowOnError
|
||||||
|
|
||||||
|
# Edge cluster deployment
|
||||||
|
$taskResult = Invoke-VcfCreateEdgeCluster -edgeCreationSpec $edgeClusterCreationSpec
|
||||||
|
$taskResult = Wait-VcfTask $taskResult -ThrowOnError
|
||||||
|
|
||||||
|
Disconnect-VcfSddcManagerServer $sddcConn
|
||||||
283
Scripts/PAIF-N/04-enable-wcp.ps1
Normal file
283
Scripts/PAIF-N/04-enable-wcp.ps1
Normal file
@@ -0,0 +1,283 @@
|
|||||||
|
<#
|
||||||
|
# © 2024 Broadcom. All Rights Reserved. Broadcom. The term "Broadcom" refers to
|
||||||
|
# Broadcom Inc. and/or its subsidiaries.
|
||||||
|
#>
|
||||||
|
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
|
||||||
|
This script enables Workload Management (Kubernetes)
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
|
||||||
|
This script enables Workload Management (Kubernetes) and sets it up for AI workloads.
|
||||||
|
|
||||||
|
The script:
|
||||||
|
|
||||||
|
1. Enables the Supervisor cluster
|
||||||
|
2. Creates content library for the deep learning VM template
|
||||||
|
3. Creates GPU-enabled VMClass
|
||||||
|
4. Creates namespace(s) and assigns the created VMClass and assigns deep learning VM content library
|
||||||
|
|
||||||
|
.NOTES
|
||||||
|
|
||||||
|
Prerequisites:
|
||||||
|
- VI workload domain (vCenter server instance)
|
||||||
|
- NSX Edge Cluster
|
||||||
|
|
||||||
|
"Global parameters", "Workload domain parameters", "WCP enablement parameters" should be updated to
|
||||||
|
reflect the environment they are run in. This may require altering the spec creation script.
|
||||||
|
|
||||||
|
#>
|
||||||
|
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
$SCRIPTROOT = ($PWD.ProviderPath, $PSScriptRoot)[!!$PSScriptRoot]
|
||||||
|
. (Join-Path $SCRIPTROOT 'utils/Wait-VcfTask.ps1')
|
||||||
|
. (Join-Path $SCRIPTROOT 'utils/Wait-VcfValidation.ps1')
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
# Global parameters
|
||||||
|
# --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
$domainName = 'sfo-w01'
|
||||||
|
|
||||||
|
$dnsServer = '10.0.0.250'
|
||||||
|
$ntpServer = '10.0.0.250'
|
||||||
|
|
||||||
|
$domain = 'vrack.vsphere.local'
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
# Workload domain parameters - stripped down version of $domainSpec from 01-deploy-vcf-workload-domain.ps1
|
||||||
|
$domainSpec = @{
|
||||||
|
VCenterSpec = @{
|
||||||
|
RootPassword = "VMware123!"
|
||||||
|
NetworkDetailsSpec = @{
|
||||||
|
DnsName = "$DomainName-vc01.$domain"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ComputeSpec = @{
|
||||||
|
ClusterSpecs = @(
|
||||||
|
@{
|
||||||
|
DatastoreSpec = @{
|
||||||
|
VSanDatastoreSpec = @{
|
||||||
|
DatastoreName = "$DomainName-ds01"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Name = "$DomainName-cl01"
|
||||||
|
NetworkSpec = @{
|
||||||
|
VdsSpecs = @(
|
||||||
|
@{
|
||||||
|
Name = "$DomainName-vds01"
|
||||||
|
PortGroups = @(
|
||||||
|
@{
|
||||||
|
Name = 'management'
|
||||||
|
TransportType = 'MANAGEMENT'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@{
|
||||||
|
Name = "$DomainName-vds02"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
NsxTSpec = @{
|
||||||
|
NSXManagerAdminPassword = "VMware123!123"
|
||||||
|
VipFqdn = "$domainName-nsx01.$domain"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$EdgeClusterParams = @{
|
||||||
|
EdgeClusterName = "$($domainSpec.ComputeSpec.ClusterSpecs[0].Name)-ec01"
|
||||||
|
}
|
||||||
|
|
||||||
|
############################################################################################################################
|
||||||
|
# Enable WCP
|
||||||
|
############################################################################################################################
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
# WCP enablement parameters
|
||||||
|
$ContentLibraryParams = @{
|
||||||
|
Name = "$DomainName-lib01"
|
||||||
|
Url = 'https://wp-content.vmware.com/v2/latest/lib.json'
|
||||||
|
SslThumbprint = 'AD:DA:3D:B9:99:75:1D:FF:2E:28:CA:92:83:64:38:20:5B:55:94:DC'
|
||||||
|
DownloadOnDemand = $true
|
||||||
|
Datastore = $domainSpec.ComputeSpec.ClusterSpecs[0].DatastoreSpec.VSanDatastoreSpec.DatastoreName
|
||||||
|
}
|
||||||
|
$DeepLearningVMContentLibraryParams = @{
|
||||||
|
Name = "$DomainName-lib02"
|
||||||
|
Url = 'https://packages.vmware.com/dl-vm/lib.json'
|
||||||
|
SslThumbprint = 'AD:DA:3D:B9:99:75:1D:FF:2E:28:CA:92:83:64:38:20:5B:55:94:DC'
|
||||||
|
DownloadOnDemand = $true
|
||||||
|
Datastore = $domainSpec.ComputeSpec.ClusterSpecs[0].DatastoreSpec.VSanDatastoreSpec.DatastoreName
|
||||||
|
}
|
||||||
|
|
||||||
|
$ClusterName = $domainSpec.ComputeSpec.ClusterSpecs[0].Name
|
||||||
|
|
||||||
|
$WcpClusterParams = @{
|
||||||
|
SizeHint = 'Small'
|
||||||
|
ManagementNetwork = @{
|
||||||
|
Name = (
|
||||||
|
$domainSpec.ComputeSpec.ClusterSpecs[0].
|
||||||
|
NetworkSpec.VdsSpecs[0].
|
||||||
|
PortGroups | Where-Object {$_.TransportType -eq 'MANAGEMENT'} | ForEach-Object { $_.Name } )
|
||||||
|
Mode = 'StaticRange'
|
||||||
|
StartIpAddress = "10.0.0.150"
|
||||||
|
Gateway = "10.0.0.250"
|
||||||
|
SubnetMask = '255.255.255.0'
|
||||||
|
RangeSize = 5
|
||||||
|
}
|
||||||
|
MasterDnsNames = @(, "$ClusterName.$domain")
|
||||||
|
MasterNtpServer = @(, $ntpServer)
|
||||||
|
Cluster = $ClusterName
|
||||||
|
EphemeralStoragePolicy = "$ClusterName vSAN Storage Policy"
|
||||||
|
ImageStoragePolicy = "$ClusterName vSAN Storage Policy"
|
||||||
|
MasterStoragePolicy = "$ClusterName vSAN Storage Policy"
|
||||||
|
NcpClusterNetworkSpec = @{
|
||||||
|
NsxEdgeClusterId = ''
|
||||||
|
DistributedSwitch = $domainSpec.ComputeSpec.ClusterSpecs[0].NetworkSpec.VdsSpecs[1].Name
|
||||||
|
PodCIDRs = @(, "10.244.10.0/23")
|
||||||
|
ExternalIngressCIDRs = @(, "10.10.11.0/24")
|
||||||
|
ExternalEgressCIDRs = @(, "10.10.10.0/24")
|
||||||
|
}
|
||||||
|
ServiceCIDR = "10.10.12.0/24"
|
||||||
|
WorkerDnsServer = @(, $dnsServer)
|
||||||
|
MasterDnsServerIpAddress = @(, $dnsServer)
|
||||||
|
MasterDnsSearchDomain = @(, $domain)
|
||||||
|
ContentLibrary = $null
|
||||||
|
LicenseKey = "XXXXX-XXXXX-XXXXX-XXXXX-XXXXX"
|
||||||
|
Namespace = @("$DomainName-wmn01", "$DomainName-tkc01")
|
||||||
|
NamespaceStoragePolicy = "$ClusterName vSAN Storage Policy"
|
||||||
|
NamespaceEditUserGroup = "gg-kub-admins"
|
||||||
|
NamespaceViewUserGroup = "gg-kub-readonly"
|
||||||
|
VmClassNamespace = @{
|
||||||
|
"$DomainName-tkc01" = @(, "best-effort-small-vgpu")
|
||||||
|
}
|
||||||
|
ContentLibraryNamespace = @{
|
||||||
|
"$DomainName-tkc01" = @()
|
||||||
|
}
|
||||||
|
VmClass = @(
|
||||||
|
@{
|
||||||
|
Id = "best-effort-small-vgpu"
|
||||||
|
CpuCount = 2
|
||||||
|
MemoryMB = 4096
|
||||||
|
MemoryReservation = 100
|
||||||
|
VGpuProfiles = @(
|
||||||
|
'grid_a100-4c',
|
||||||
|
'grid_a100-8c'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
# --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Get Edge cluster Id from NSXt manager
|
||||||
|
$nsxtConn = Connect-NsxtServer -Server $domainSpec.ComputeSpec.NsxTSpec.vipFqdn -User 'admin' -password $domainSpec.ComputeSpec.NsxTSpec.NSXManagerAdminPassword
|
||||||
|
$svc = Get-NsxtService 'com.vmware.nsx.edge_clusters'
|
||||||
|
$nsxEdgeCluster = $svc.list().results | Where-Object { $_.display_name -eq $EdgeClusterParams.EdgeClusterName }
|
||||||
|
$WcpClusterParams.NcpClusterNetworkSpec.NsxEdgeClusterId = $nsxEdgeCluster.Id
|
||||||
|
$nsxtConn | Disconnect-NsxtServer -Confirm:$false
|
||||||
|
|
||||||
|
# Connect to the VCF Workload domain VC
|
||||||
|
$vcConn = Connect-ViServer -Server $domainSpec.VCenterSpec.NetworkDetailsSpec.DnsName `
|
||||||
|
-User administrator@vsphere.local `
|
||||||
|
-Password $domainSpec.VCenterSpec.RootPassword
|
||||||
|
|
||||||
|
# Create subscribed content library to https://wp-content.vmware.com/v2/latest/lib.json
|
||||||
|
$contentLibrary = New-ContentLibrary `
|
||||||
|
-Name $ContentLibraryParams.Name `
|
||||||
|
-Datastore $ContentLibraryParams.Datastore `
|
||||||
|
-SubscriptionUrl $ContentLibraryParams.Url `
|
||||||
|
-DownloadContentOnDemand:($ContentLibraryParams.DownloadOnDemand) `
|
||||||
|
-SslThumbprint $ContentLibraryParams.SslThumbprint
|
||||||
|
|
||||||
|
$WcpClusterParams.ContentLibrary = $contentLibrary
|
||||||
|
|
||||||
|
# Create subscribed content library to https://packages.vmware.com/dl-vm/lib.json
|
||||||
|
$dlvmContentLibrary = New-ContentLibrary `
|
||||||
|
-Name $DeepLearningVMContentLibraryParams.Name `
|
||||||
|
-Datastore $DeepLearningVMContentLibraryParams.Datastore `
|
||||||
|
-SubscriptionUrl $DeepLearningVMContentLibraryParams.Url `
|
||||||
|
-DownloadContentOnDemand:($DeepLearningVMContentLibraryParams.DownloadOnDemand) `
|
||||||
|
-SslThumbprint $DeepLearningVMContentLibraryParams.SslThumbprint
|
||||||
|
|
||||||
|
$WcpClusterParams.ContentLibraryNamespace["$DomainName-tkc01"] = @(, $dlvmContentLibrary.Id)
|
||||||
|
|
||||||
|
# Enable WCP in the VCF workload domain VC
|
||||||
|
$wcpCluster = Enable-WMCluster `
|
||||||
|
-SizeHint $WcpClusterParams.SizeHint `
|
||||||
|
-ManagementVirtualNetwork (Get-VirtualNetwork -Name $WcpClusterParams.ManagementNetwork.Name) `
|
||||||
|
-ManagementNetworkMode $WcpClusterParams.ManagementNetwork.Mode `
|
||||||
|
-ManagementNetworkStartIpAddress $WcpClusterParams.ManagementNetwork.StartIpAddress `
|
||||||
|
-ManagementNetworkAddressRangeSize $WcpClusterParams.ManagementNetwork.RangeSize `
|
||||||
|
-ManagementNetworkGateway $WcpClusterParams.ManagementNetwork.Gateway `
|
||||||
|
-ManagementNetworkSubnetMask $WcpClusterParams.ManagementNetwork.SubnetMask `
|
||||||
|
-MasterDnsNames $WcpClusterParams.MasterDnsNames `
|
||||||
|
-MasterNtpServer $WcpClusterParams.MasterNtpServer `
|
||||||
|
-Cluster (Get-Cluster -Name $WcpClusterParams.Cluster) `
|
||||||
|
-EphemeralStoragePolicy (Get-SpbmStoragePolicy -Name $WcpClusterParams.EphemeralStoragePolicy) `
|
||||||
|
-ImageStoragePolicy (Get-SpbmStoragePolicy -Name $WcpClusterParams.ImageStoragePolicy) `
|
||||||
|
-MasterStoragePolicy (Get-SpbmStoragePolicy -Name $WcpClusterParams.MasterStoragePolicy) `
|
||||||
|
-NsxEdgeClusterId $WcpClusterParams.NcpClusterNetworkSpec.NsxEdgeClusterId `
|
||||||
|
-DistributedSwitch (Get-VDSwitch -Name $WcpClusterParams.NcpClusterNetworkSpec.DistributedSwitch) `
|
||||||
|
-PodCIDRs $WcpClusterParams.NcpClusterNetworkSpec.PodCIDRs `
|
||||||
|
-ServiceCIDR $WcpClusterParams.ServiceCIDR `
|
||||||
|
-ExternalIngressCIDRs $WcpClusterParams.NcpClusterNetworkSpec.ExternalIngressCIDRs `
|
||||||
|
-ExternalEgressCIDRs $WcpClusterParams.NcpClusterNetworkSpec.ExternalEgressCIDRs `
|
||||||
|
-WorkerDnsServer $WcpClusterParams.WorkerDnsServer `
|
||||||
|
-MasterDnsServerIpAddress $WcpClusterParams.MasterDnsServerIpAddress `
|
||||||
|
-MasterDnsSearchDomain $WcpClusterParams.MasterDnsSearchDomain `
|
||||||
|
-ContentLibrary $contentLibrary
|
||||||
|
|
||||||
|
# Create VM classes
|
||||||
|
$WcpClusterParams.VmClass | ForEach-Object {
|
||||||
|
Invoke-CreateNamespaceManagementVirtualMachineClasses `
|
||||||
|
-NamespaceManagementVirtualMachineClassesCreateSpec (
|
||||||
|
Initialize-NamespaceManagementVirtualMachineClassesCreateSpec `
|
||||||
|
-Id $_.Id `
|
||||||
|
-CpuCount $_.CpuCount `
|
||||||
|
-MemoryMB $_.MemoryMB `
|
||||||
|
-MemoryReservation $_.MemoryReservation `
|
||||||
|
-Devices (
|
||||||
|
Initialize-NamespaceManagementVirtualMachineClassesVirtualDevices `
|
||||||
|
-VgpuDevices (
|
||||||
|
$_.VGpuProfiles | ForEach-Object {
|
||||||
|
Initialize-NamespaceManagementVirtualMachineClassesVGPUDevice -ProfileName $_
|
||||||
|
})))
|
||||||
|
}
|
||||||
|
|
||||||
|
# Deploy Namespaces
|
||||||
|
$WcpClusterParams.Namespace | ForEach-Object {
|
||||||
|
$wmNamespace = New-WMNamespace `
|
||||||
|
-Name $_ `
|
||||||
|
-Cluster (Get-Cluster -Name $WcpClusterParams.Cluster)
|
||||||
|
$wmNamespace | New-WMNamespaceStoragePolicy `
|
||||||
|
-StoragePolicy (Get-SpbmStoragePolicy -Name $WcpClusterParams.NamespaceStoragePolicy) | Out-Null
|
||||||
|
|
||||||
|
# Assign the Supervisor Namespace Roles to Active Directory Groups
|
||||||
|
$wmNamespace | New-WMNamespacePermission `
|
||||||
|
-Role 'Edit' `
|
||||||
|
-Domain $domain `
|
||||||
|
-PrincipalType 'Group' `
|
||||||
|
-PrincipalName $WcpClusterParams.NamespaceEditUserGroup `
|
||||||
|
-ErrorAction SilentlyContinue | Out-Null
|
||||||
|
|
||||||
|
$wmNamespace | New-WMNamespacePermission `
|
||||||
|
-Role 'View' `
|
||||||
|
-Domain $domain `
|
||||||
|
-PrincipalType 'Group' `
|
||||||
|
-PrincipalName $WcpClusterParams.NamespaceViewUserGroup `
|
||||||
|
-ErrorAction SilentlyContinue | Out-Null
|
||||||
|
|
||||||
|
if ($WcpClusterParams.VmClassNamespace.ContainsKey($_)) {
|
||||||
|
Invoke-UpdateNamespaceInstances -Namespace $_ -NamespacesInstancesUpdateSpec (
|
||||||
|
Initialize-NamespacesInstancesUpdateSpec -VmServiceSpec (
|
||||||
|
Initialize-NamespacesInstancesVMServiceSpec -VmClasses $WcpClusterParams.VmClassNamespace[$_] -ContentLibraries $WcpClusterParams.ContentLibraryNamespace[$_]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$vcConn | Disconnect-VIServer -Confirm:$false
|
||||||
38
Scripts/PAIF-N/README.md
Normal file
38
Scripts/PAIF-N/README.md
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# VMware Private AI Foundation with NVIDIA Guide
|
||||||
|
|
||||||
|
This example demonstrates how a VI admin would:
|
||||||
|
|
||||||
|
* instantiate a new VCF workload domain for data scientist teams
|
||||||
|
* setup the following infrastructure configuration required for **PAIF-N** workload domain
|
||||||
|
|
||||||
|
## Deploying a VI workload domain
|
||||||
|
|
||||||
|
This script creates a VI workload domain using the **PowerCLI** SDK module for **VCF SDDC Manager**.
|
||||||
|
|
||||||
|
The script can be broken into two main parts. First, the ESXi hosts are being commissioned. Then, the actual VI domain is created using the commissioned ESXi hosts.
|
||||||
|
|
||||||
|
Both steps - ESXi host commissioning and VI domain creations - are three-stage operations themselves. The commissioning/creation specs are constructed. The specs are validated. The actual operation is invoked. The validation and operation invocation are long-running tasks. This requires awaiting and status tracking until their completion. The waiting for validation and the actual operation is done using helper cmdlets -
|
||||||
|
Wait-VcfValidation and Wait-VcfTask, located in `utils` sub-folder.
|
||||||
|
|
||||||
|
On completion, a new VI workload domain reflecting the given parameters should be created.
|
||||||
|
|
||||||
|
## ESXi hosts configuration for AI workloads
|
||||||
|
|
||||||
|
This script configures the ESXi host for AI workloads which includes installing the Nvidia AI Enterprise vGPU driver and Nvidia GPU Management Daemon on the ESXi hosts. vLCM is used for that purpose.
|
||||||
|
|
||||||
|
The script changes the default graphics type of the GPU devices to Shared Direct. The Xorg service is then restarted. Finally, the vLCM is used to install the NVIDIA GPU driver and management daemon.
|
||||||
|
|
||||||
|
## NSX Edge Cluster creation
|
||||||
|
|
||||||
|
This script creates an NSX edge cluster to provide connectivity from external networks to Supervisor Cluster objects.
|
||||||
|
|
||||||
|
## Workload Management enablement and configuration
|
||||||
|
|
||||||
|
This script enables Workload Management (Kubernetes) and sets it up for AI workloads.
|
||||||
|
|
||||||
|
The script:
|
||||||
|
|
||||||
|
1. Enables the Supervisor cluster
|
||||||
|
2. Creates content library for the deep learning VM template
|
||||||
|
3. Creates GPU-enabled VMClass
|
||||||
|
4. Creates namespace(s) and assigns the created VMClass and assigns deep learning VM content library
|
||||||
109
Scripts/PAIF-N/utils/Wait-VcfTask.ps1
Normal file
109
Scripts/PAIF-N/utils/Wait-VcfTask.ps1
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
<#
|
||||||
|
# © 2024 Broadcom. All Rights Reserved. Broadcom. The term "Broadcom" refers to
|
||||||
|
# Broadcom Inc. and/or its subsidiaries.
|
||||||
|
#>
|
||||||
|
|
||||||
|
using namespace VMware.Bindings.Vcf.SddcManager.Model
|
||||||
|
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
|
||||||
|
This cmdlet waits for VCF task to complete or fail.
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
|
||||||
|
This cmdlet waits for VCF task to complete or fail.
|
||||||
|
|
||||||
|
.PARAMETER Task
|
||||||
|
Specifies the task to be waited for.
|
||||||
|
|
||||||
|
.PARAMETER ThrowOnError
|
||||||
|
Specifies if an error will be thrown if the task fails.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
PS C:\> Wait-VcfTask -Task $task -ThrowOnError
|
||||||
|
|
||||||
|
Waits for the $task to complete or fails.
|
||||||
|
|
||||||
|
.OUTPUTS
|
||||||
|
Zero or more VMware.Bindings.Vcf.SddcManager.Model.Task object
|
||||||
|
|
||||||
|
.LINK
|
||||||
|
|
||||||
|
#>
|
||||||
|
|
||||||
|
function Wait-VcfTask {
|
||||||
|
[CmdletBinding(
|
||||||
|
ConfirmImpact = "None",
|
||||||
|
DefaultParameterSetName = "Default",
|
||||||
|
SupportsPaging = $false,
|
||||||
|
PositionalBinding = $false,
|
||||||
|
RemotingCapability = "None",
|
||||||
|
SupportsShouldProcess = $false,
|
||||||
|
SupportsTransactions = $false)]
|
||||||
|
[OutputType([VMware.Bindings.Vcf.SddcManager.Model.Task])]
|
||||||
|
|
||||||
|
Param (
|
||||||
|
[Parameter(
|
||||||
|
Mandatory = $true,
|
||||||
|
Position = 0)]
|
||||||
|
[VMware.Bindings.Vcf.SddcManager.Model.Task]
|
||||||
|
$Task,
|
||||||
|
|
||||||
|
[Parameter()]
|
||||||
|
[switch]
|
||||||
|
$ThrowOnError
|
||||||
|
)
|
||||||
|
|
||||||
|
$Task | ConvertTo-Json -Depth 10 | Write-Verbose
|
||||||
|
|
||||||
|
$taskName = $Task.Name
|
||||||
|
|
||||||
|
Write-Progress -Id 0 $taskName
|
||||||
|
|
||||||
|
while ($Task.Status -eq "In Progress" -or $Task.Status -eq 'IN_PROGRESS' -or $Task.Status -eq 'PENDING' -or $Task.Status -eq 'Pending') {
|
||||||
|
|
||||||
|
Write-Verbose "$taskName in progress"
|
||||||
|
$Task | ConvertTo-Json -Depth 10 | Write-Verbose
|
||||||
|
|
||||||
|
if ($Task.SubTasks -and $Task.SubTasks.Count -gt 0) {
|
||||||
|
$completedSubTask = $Task.SubTasks | Where-Object {
|
||||||
|
$_.Status -eq 'SUCCESSFUL' -or $_.Status -eq 'Successful'
|
||||||
|
} | Measure-Object | Select-Object -ExpandProperty Count
|
||||||
|
|
||||||
|
$currentSubTaskName = $Task.SubTasks | Where-Object {
|
||||||
|
$_.Status -eq 'RUNNING' -or $_.Status -eq 'Running' -or $_.Status -eq "IN_PROGRESS" -or $_.Status -eq "In Progress"
|
||||||
|
} | Select-Object -First 1 -ExpandProperty Name
|
||||||
|
|
||||||
|
if ($currentSubTaskName) {
|
||||||
|
Write-Progress -Id 0 $taskName -Status $currentSubTaskName -PercentComplete (($completedSubTask * 100) / $Task.SubTasks.Count)
|
||||||
|
} else {
|
||||||
|
Write-Progress -Id 0 $taskName -PercentComplete (($completedSubTask * 100) / $Task.SubTasks.Count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Start-Sleep -Seconds 1
|
||||||
|
$Task = Invoke-VcfGetTask -id $Task.Id
|
||||||
|
$taskName = $Task.Name
|
||||||
|
}
|
||||||
|
if ($Task.Status -ne "Successful" -and $Task.Status -ne 'SUCCESSFUL') {
|
||||||
|
Write-Progress -Id 0 "$taskName failed" -Completed
|
||||||
|
Write-Verbose "$taskName failed"
|
||||||
|
$Task | ConvertTo-Json -Depth 10 | Write-Verbose
|
||||||
|
|
||||||
|
$Task.SubTasks | ForEach-Object {
|
||||||
|
Write-Verbose "[$(if($_.Status -eq 'SUCCESSFUL' -or $_.Status -eq "Successful"){"+"}else{"-"})] $($_.Description)"
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($ThrowOnError) {
|
||||||
|
throw $Task
|
||||||
|
} else {
|
||||||
|
Write-Output $Task
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Progress -Id 0 "$taskName succeeded" -Completed
|
||||||
|
Write-Verbose "$taskName succeeded"
|
||||||
|
|
||||||
|
Write-Output $Task
|
||||||
|
}
|
||||||
|
}
|
||||||
123
Scripts/PAIF-N/utils/Wait-VcfValidation.ps1
Normal file
123
Scripts/PAIF-N/utils/Wait-VcfValidation.ps1
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
<#
|
||||||
|
# © 2024 Broadcom. All Rights Reserved. Broadcom. The term "Broadcom" refers to
|
||||||
|
# Broadcom Inc. and/or its subsidiaries.
|
||||||
|
#>
|
||||||
|
|
||||||
|
using namespace VMware.Bindings.Vcf.SddcManager.Model
|
||||||
|
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
|
||||||
|
This cmdlet waits for VCF task to complete or fail.
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
|
||||||
|
This cmdlet waits for VCF task to complete or fail.
|
||||||
|
|
||||||
|
.PARAMETER Task
|
||||||
|
Specifies the task to be waited for.
|
||||||
|
|
||||||
|
.PARAMETER ThrowOnError
|
||||||
|
Specifies if an error will be thrown if the task fails.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
PS C:\> Wait-VcfTask -Task $task -ThrowOnError
|
||||||
|
|
||||||
|
Waits for the $task to complete or fails.
|
||||||
|
|
||||||
|
.OUTPUTS
|
||||||
|
Zero or more VMware.Bindings.Vcf.SddcManager.Model.Task object
|
||||||
|
|
||||||
|
.LINK
|
||||||
|
|
||||||
|
#>
|
||||||
|
|
||||||
|
function Wait-VcfValidation {
|
||||||
|
[CmdletBinding(
|
||||||
|
ConfirmImpact = "None",
|
||||||
|
DefaultParameterSetName = "Default",
|
||||||
|
SupportsPaging = $false,
|
||||||
|
PositionalBinding = $false,
|
||||||
|
RemotingCapability = "None",
|
||||||
|
SupportsShouldProcess = $false,
|
||||||
|
SupportsTransactions = $false)]
|
||||||
|
[OutputType([VMware.Bindings.Vcf.SddcManager.Model.Validation])]
|
||||||
|
|
||||||
|
Param (
|
||||||
|
[Parameter(
|
||||||
|
Mandatory = $true,
|
||||||
|
ValueFromPipeline = $true,
|
||||||
|
Position = 0)]
|
||||||
|
[VMware.Bindings.Vcf.SddcManager.Model.Validation]
|
||||||
|
$Validation,
|
||||||
|
|
||||||
|
[Parameter(
|
||||||
|
Position = 1)]
|
||||||
|
[scriptblock]
|
||||||
|
$UpdateValidation,
|
||||||
|
|
||||||
|
[Parameter(
|
||||||
|
Position = 2)]
|
||||||
|
[object[]]
|
||||||
|
$UpdateValidationArguments,
|
||||||
|
|
||||||
|
[Parameter()]
|
||||||
|
[switch]
|
||||||
|
$ThrowOnError
|
||||||
|
)
|
||||||
|
|
||||||
|
$Validation | ConvertTo-Json -Depth 10 | Write-Verbose
|
||||||
|
|
||||||
|
$validationDescription = $Validation.Description
|
||||||
|
|
||||||
|
Write-Progress -Id 0 $validationDescription
|
||||||
|
|
||||||
|
while ($Validation.ExecutionStatus -eq 'IN_PROGRESS' -or $Validation.ExecutionStatus -eq 'CANCELLATION_IN_PROGRESS') {
|
||||||
|
|
||||||
|
Write-Verbose "$validationDescription in progress"
|
||||||
|
$Validation | ConvertTo-Json -Depth 10 | Write-Verbose
|
||||||
|
|
||||||
|
if ($Validation.ValidationChecks -and $Validation.ValidationChecks.Count -gt 0) {
|
||||||
|
$completedSubTask = $Validation.ValidationChecks | Where-Object {
|
||||||
|
$_.ResultStatus -eq 'SUCCEEDED'
|
||||||
|
} | Measure-Object | Select-Object -ExpandProperty Count
|
||||||
|
|
||||||
|
$currentSubTaskName = $Validation.ValidationChecks | Where-Object {
|
||||||
|
$_.ResultStatus -eq 'IN_PROGRESS'
|
||||||
|
} | Select-Object -First 1 -ExpandProperty Name
|
||||||
|
|
||||||
|
if ($currentSubTaskName) {
|
||||||
|
Write-Progress -Id 0 $validationDescription -Status $currentSubTaskName -PercentComplete (($completedSubTask * 100) / $Validation.ValidationChecks.Count)
|
||||||
|
} else {
|
||||||
|
Write-Progress -Id 0 $validationDescription -PercentComplete (($completedSubTask * 100) / $Validation.ValidationChecks.Count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Start-Sleep -Seconds 1
|
||||||
|
if ($UpdateValidation) {
|
||||||
|
$Validation = Invoke-Command -ScriptBlock $UpdateValidation -ArgumentList $UpdateValidationArguments
|
||||||
|
}
|
||||||
|
$validationDescription = $Validation.Description
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($Validation.ResultStatus -ne 'SUCCEEDED') {
|
||||||
|
Write-Progress -Id 0 "$validationDescription failed" -Completed
|
||||||
|
Write-Verbose "$validationDescription failed"
|
||||||
|
$Validation | ConvertTo-Json -Depth 10 | Write-Verbose
|
||||||
|
|
||||||
|
$Validation.validationChecks | ForEach-Object {
|
||||||
|
Write-Verbose "[$(if($_.ResultStatus -eq 'SUCCEEDED'){"+"}else{"-"})][$($_.Severity)] $($_.Description)"
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($ThrowOnError) {
|
||||||
|
throw $Validation
|
||||||
|
} else {
|
||||||
|
Write-Output $Validation
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Progress -Id 0 "$validationDescription succeeded" -Completed
|
||||||
|
Write-Verbose "$validationDescription succeeded"
|
||||||
|
|
||||||
|
Write-Output $Validation
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user