Init Commit of VMNetworkAdapter builds

This commit is contained in:
dcuomo 2019-05-28 18:28:06 -07:00
Родитель 354a1c147f
Коммит 569be4bc16
9 изменённых файлов: 529 добавлений и 0 удалений

2
.gitignore поставляемый
Просмотреть файл

@ -3,6 +3,8 @@
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
DSCResource.Tests/
# User-specific files
*.suo
*.user

Просмотреть файл

@ -1,3 +1,10 @@
# Data Center Bridging
DSC PowerShell module intended to deploy virtual NIC settings using https://aka.ms/Validate-DCB
## :star: More by the Microsoft Core Networking team
Find more by the core networking team using the [MSFTNet](https://github.com/topics/msftnet) topic
# Contributing

131
VMNetworkAdapter.psd1 Normal file
Просмотреть файл

@ -0,0 +1,131 @@
#
# Module manifest for module 'VMNetworkAdapter'
#
# Generated by: Microsoft Core Networking Team
#
# Generated on: 2/9/2019
#
@{
# Script module or binary module file associated with this manifest.
RootModule = 'VMNetworkAdapter.psm1'
# Version number of this module.
ModuleVersion = '0.4'
# Supported PSEditions
# CompatiblePSEditions = @()
# ID used to uniquely identify this module
GUID = '6548364b-e45f-4bed-8796-776bdf5fc900'
# Author of this module
Author = 'Dan Cuomo'
# Company or vendor of this module
CompanyName = 'Microsoft'
# Copyright statement for this module
Copyright = '(c) 2019 Microsoft. All rights reserved.'
# Description of the functionality provided by this module
Description = 'This module provides DSCResources to configure VMNetworkAdapters on your system(s)'
# Minimum version of the Windows PowerShell engine required by this module
# PowerShellVersion = ''
# Name of the Windows PowerShell host required by this module
# PowerShellHostName = ''
# Minimum version of the Windows PowerShell host required by this module
# PowerShellHostVersion = ''
# Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
# DotNetFrameworkVersion = ''
# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
# CLRVersion = ''
# Processor architecture (None, X86, Amd64) required by this module
# ProcessorArchitecture = ''
# Modules that must be imported into the global environment prior to importing this module
# RequiredModules = @()
# Assemblies that must be loaded prior to importing this module
# RequiredAssemblies = @()
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
# ScriptsToProcess = @()
# Type files (.ps1xml) to be loaded when importing this module
# TypesToProcess = @()
# Format files (.ps1xml) to be loaded when importing this module
# FormatsToProcess = @()
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
# NestedModules = @()
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
FunctionsToExport = @()
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
CmdletsToExport = @()
# Variables to export from this module
VariablesToExport = '*'
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
AliasesToExport = @()
# DSC resources to export from this module
DscResourcesToExport = 'VMNetworkAdapterTeamMapping', 'VMNetworkAdapterSettings', 'VMNetworkAdapterIsolation'
# List of all modules packaged with this module
# ModuleList = @()
# List of all files packaged with this module
# FileList = @()
# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
PrivateData = @{
PSData = @{
# Tags applied to this module. These help with module discovery in online galleries.
Tags = 'MSFTNetworking','Validate-DCB'
# A URL to the license for this module.
# LicenseUri = ''
# A URL to the main website for this project.
ProjectUri = 'https://github.com/microsoft/VMNetworkAdapter'
# A URL to an icon representing this module.
# IconUri = ''
# ReleaseNotes of this module
# ReleaseNotes = ''
# Prerelease string of this module
# Prerelease = ''
# Flag to indicate whether the module requires explicit user acceptance for install/update
# RequireLicenseAcceptance = $false
# External dependent modules of this module
# ExternalModuleDependencies = @()
} # End of PSData hashtable
} # End of PrivateData hashtable
# HelpInfo URI of this module
# HelpInfoURI = ''
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
# DefaultCommandPrefix = ''
}

181
VMNetworkAdapter.psm1 Normal file
Просмотреть файл

@ -0,0 +1,181 @@
enum Ensure {
Absent
Present
}
[DscResource()]
Class VMNetworkAdapterTeamMapping {
[DscProperty(Mandatory)]
[Ensure] $Ensure
[DscProperty(Key)]
[String] $PhysicalNetAdapterName
[DscProperty(Key)]
[String] $VMNetworkAdapterName
[VMNetworkAdapterTeamMapping] Get() {
$VMNetworkAdapterTeamMapping = Get-VMNetworkAdapterTeamMapping -ManagementOS -VMNetworkAdapterName $this.VMNetworkAdapterName
$this.PhysicalNetAdapterName = $VMNetworkAdapterTeamMapping.NetAdapterName
$this.VMNetworkAdapterName = $VMNetworkAdapterTeamMapping.ParentAdapter.Name
return $this
}
[bool] Test() {
$VMNetworkAdapterTeamMapping = Get-VMNetworkAdapterTeamMapping -ManagementOS -VMNetworkAdapterName $this.VMNetworkAdapterName
$testState = $false
if ($this.Ensure -eq [Ensure]::Present) {
If ($VMNetworkAdapterTeamMapping.NetAdapterName -eq $this.PhysicalNetAdapterName -and
$VMNetworkAdapterTeamMapping.ParentAdapter.Name -eq $this.VMNetworkAdapterName) {
$testState = $true
}
Else { $testState = $false }
}
elseif ($this.Ensure -eq [Ensure]::Absent) {
If ($VMNetworkAdapterTeamMapping) { $testState = $false }
Else { $testState = $true }
}
Return $testState
}
[Void] Set() {
if ($this.Ensure -eq [Ensure]::Present) {
Write-Verbose "Mapping $($this.VMNetworkAdapterName) to $($this.PhysicalNetAdapterName)"
Set-VMNetworkAdapterTeamMapping -ManagementOS -VMNetworkAdapterName $this.VMNetworkAdapterName -PhysicalNetAdapterName $this.PhysicalNetAdapterName
Write-Verbose "$($this.VMNetworkAdapterName) is now mapped to $($this.PhysicalNetAdapterName)"
}
elseif ($this.Ensure -eq [Ensure]::Absent) {
Write-Verbose "Removing team mapping for $($this.VMNetworkAdapterName)"
Remove-VMNetworkAdapterTeamMapping -ManagementOS -Name $this.VMNetworkAdapterName
Write-Verbose "Team mapping for $($this.VMNetworkAdapterName) is now removed"
}
}
}
[DscResource()]
Class VMNetworkAdapterSettings {
[DscProperty(Key)]
[String] $VMNetworkAdapterName
[DscProperty(Mandatory)]
[String] $VMName = 'ManagementOS'
[DscProperty()]
[ValidateSet('On','Off')]
[String] $IeeePriorityTag = 'Off'
[VMNetworkAdapterSettings] Get() {
$params = @{}
if ($this.VMName -eq 'ManagementOS') {
$params.Add('ManagementOS', $true)
}
else { $params.Add('VMName', $this.VMName)}
$VMNetworkAdapter = Get-VMNetworkAdapter -VMNetworkAdapterName $this.VMNetworkAdapterName @params -ErrorAction SilentlyContinue
$this.VMNetworkAdapterName = $VMNetworkAdapter.Name
$this.IeeePriorityTag = $VMNetworkAdapter.IeeePriorityTag
return $this
}
[bool] Test() {
$params = @{}
if ($this.VMName -eq 'ManagementOS') {$params.Add('ManagementOS', $true)}
else {$params.Add('VMName', $this.VMName)}
$VMNetworkAdapter = Get-VMNetworkAdapter -VMNetworkAdapterName $this.VMNetworkAdapterName @params -ErrorAction SilentlyContinue
$testState = $false
If ($this.IeeePriorityTag -eq $VMNetworkAdapter.IeeePriorityTag) { $testState = $true }
Else { $testState = $false }
Return $testState
}
[Void] Set() {
$params = @{}
if ($this.VMName -eq 'ManagementOS') {$params.Add('ManagementOS', $true)}
else {$params.Add('VMName', $this.VMName)}
$VMNetworkAdapter = Get-VMNetworkAdapter -VMNetworkAdapterName $this.VMNetworkAdapterName @params -ErrorAction SilentlyContinue
if ($this.IeeePriorityTag -ne $VMNetworkAdapter.IeeePriorityTag) {
Write-Verbose "Configuring IEEEPriorityTag on vNIC $($VMNetworkAdapter.Name) to $($this.IeeePriorityTag)"
Set-VMNetworkAdapter -VMNetworkAdapterName $this.VMNetworkAdapterName @params -IeeePriorityTag $this.IeeePriorityTag
Write-Verbose "IEEEPriorityTag on vNIC $($VMNetworkAdapter.Name) is now $($this.IeeePriorityTag)"
}
}
}
[DscResource()]
Class VMNetworkAdapterIsolation {
[DscProperty(Mandatory)]
[Ensure] $Ensure
[DscProperty(Key)]
[String] $VMNetworkAdapterName
[DscProperty(Mandatory)]
[ValidateRange(0,4096)]
[uint16] $DefaultIsolationID
[DscProperty()]
[Boolean] $AllowUntaggedTraffic
[DscProperty()]
[ValidateSet('Vlan','None')]
[String] $IsolationMode
[VMNetworkAdapterIsolation] Get() {
$VMNetworkAdapterIsolation = Get-VMNetworkAdapterIsolation -ManagementOS -VMNetworkAdapterName $this.VMNetworkAdapterName
$this.IsolationMode = $VMNetworkAdapterIsolation.IsolationMode
$this.DefaultIsolationID = $VMNetworkAdapterIsolation.DefaultIsolationID
$this.AllowUntaggedTraffic = $VMNetworkAdapterIsolation.AllowUntaggedTraffic
return $this
}
[bool] Test() {
$VMNetworkAdapterIsolation = Get-VMNetworkAdapterIsolation -ManagementOS -VMNetworkAdapterName $this.VMNetworkAdapterName
$testState = $false
if ($this.Ensure -eq [Ensure]::Present) {
if ( $VMNetworkAdapterIsolation.IsolationMode -eq $this.IsolationMode `
-and $VMNetworkAdapterIsolation.AllowUntaggedTraffic -eq $this.AllowUntaggedTraffic `
-and $VMNetworkAdapterIsolation.DefaultIsolationID -eq $this.DefaultIsolationID )
{ $testState = $true }
else { $testState = $false }
}
elseif ($this.Ensure -eq [Ensure]::Absent) {
If ($VMNetworkAdapterIsolation) { $testState = $false }
Else { $testState = $true }
}
Return $testState
}
[Void] Set() {
if ($this.Ensure -eq [Ensure]::Present) {
Write-Verbose "Removing VMNetworkAdapterVlan if configured on $($this.VMNetworkAdapterName)"
Set-VMNetworkAdapterVlan -ManagementOS -VMNetworkAdapterName $this.VMNetworkAdapterName -Untagged
Write-Verbose "Configuring Isolation for $($this.VMNetworkAdapterName)"
Set-VMNetworkAdapterIsolation -ManagementOS -IsolationMode $this.IsolationMode -DefaultIsolationID $this.DefaultIsolationID`
-AllowUntaggedTraffic $this.AllowUntaggedTraffic -VMNetworkAdapterName $this.VMNetworkAdapterName
Write-Verbose "VLAN Isolation for $($this.VMNetworkAdapterName) is now configured"
}
elseif ($this.Ensure -eq [Ensure]::Absent) {
Write-Verbose "Resetting Isolation for $($this.VMNetworkAdapterName)"
Set-VMNetworkAdapterIsolation -ManagementOS -VMNetworkAdapterName $this.VMNetworkAdapterName -IsolationMode 'None'
Write-Verbose "Isolation for $($this.VMNetworkAdapterName) is now reset"
}
}
}

53
appveyor.yml Normal file
Просмотреть файл

@ -0,0 +1,53 @@
# YAML Reference Guide : https://www.appveyor.com/docs/appveyor-yml/
# Environmental Variables Guide : https://www.appveyor.com/docs/environment-variables/
# YAML Validator : https://ci.appveyor.com/tools/validate-yaml
# AppVeyor Build Pipeline : https://www.appveyor.com/docs/build-configuration/
# GitHub push with tokens : https://www.appveyor.com/docs/how-to/git-push/
init:
- ps: $Env:repoName = $($env:APPVEYOR_REPO_NAME.Split('/')[1])
# Install script prior to running tests
install:
- ps: . .\tests\setup\install.ps1
# Initiate tests
test_script:
- ps: . .\tests\setup\initiate-tests.ps1
# finalize build
deploy_script:
- ps: . .\tests\setup\deploy.ps1
version: 0.0.0.{build}
# Repo cloned into this folder on the build worker
clone_folder: c:\projects\MSFTNetworking.Tools
# Environment variables for PowerShell Gallery (NuGetAPIKey) and GitHub (GitHubKey) API key for publishing updates
# - The "secure:" value is the Appveyor encryption of the key
# - GitHub update occurs to ensure that the module version is incremented based on the build number
environment:
NuGetApiKey:
secure: 8zTIgzkh0lIeJ+PZRLSS047LFbQqLbbm2YDdqwgTs4ctfGKtZAKQNDyEtn2geNtq
GitHubKey:
secure: BTbC1Dgv/DE7g/n+/emm4FiSiRTjsRYnsqRUiF2NEhuwHvKkS35zCRsFm27g8OR4
CODECOV_TOKEN:
secure: hSsf4xeuX4TrtB0u6R+3ogaz1GQhfRV0yQmzlisNPBUub9ErR47NSlIg3GpfCucpEFZ8P06pCcAN0h2XBDPe5cnBXkRSYboBuP1blEtv7dc=
# Disable automatic builds; Without this, the following error shows up:
# "Specify a project or solution file. The directory does not contain a project or solution file."
build: "off"
max_jobs: 1
# Ignore testing a commit if specific strings used in commit message: updated readme, update readme, update docs, update version, update appveyor
skip_commits:
message: /updated readme.*|update readme.*s|update docs.*|update version.*|update appveyor.*/
files:
- README.md
# There's no need to alter the build number for a Pull Request (PR) since they don't modify anything
pull_requests:
do_not_increment_build_number: true

98
tests/setup/deploy.ps1 Normal file
Просмотреть файл

@ -0,0 +1,98 @@
git config --global credential.helper store
Add-Content "$env:USERPROFILE\.git-credentials" "https://$($env:GitHubKey):x-oauth-basic@github.com`n"
git config --global user.email "dcuomo@outlook.com"
git config --global user.name "Dan Cuomo"
git config --global core.autocrlf false
git config --global core.safecrlf false
# Line break for readability in AppVeyor console
Write-Host -Object ''
# Make sure we're using the Master branch and that it's not a pull request
# Environmental Variables Guide: https://www.appveyor.com/docs/environment-variables/
if ($env:APPVEYOR_REPO_BRANCH -ne 'master')
{
Write-Warning -Message "Skipping version increment and publish for branch $env:APPVEYOR_REPO_BRANCH"
}
elseif ($env:APPVEYOR_PULL_REQUEST_NUMBER -gt 0)
{
Write-Warning -Message "Skipping version increment and publish for pull request #$env:APPVEYOR_PULL_REQUEST_NUMBER"
}
else
{
# We're going to add 1 to the revision value since a new commit has been merged to Master
# This means that the major / minor / build values will be consistent across GitHub and the Gallery
Try
{
# This is where the module manifest lives
$manifestPath = ".\$($env:RepoName).psd1"
# Start by importing the manifest to determine the version, then add 1 to the revision
$manifest = Test-ModuleManifest -Path $manifestPath -ErrorAction SilentlyContinue
[System.Version]$version = $manifest.Version
Write-Output "Old Version: $version"
[String]$newVersion = New-Object -TypeName System.Version -ArgumentList ($version.Major, $version.Minor, $version.Build, $env:APPVEYOR_BUILD_NUMBER)
Write-Output "New Version: $newVersion"
# Update the manifest with the new version value and fix the weird string replace bug
#$functionList = ((Get-ChildItem -Path .\$($env:RepoName)).BaseName)
$splat = @{
'Path' = $manifestPath
'ModuleVersion' = $newVersion
#'FunctionsToExport' = $functionList
'Copyright' = "(c) $( (Get-Date).Year ) Inc. All rights reserved."
}
Update-ModuleManifest @splat -ErrorAction SilentlyContinue
(Get-Content -Path $manifestPath) -replace "PSGet_$($env:RepoName)", "$($env:RepoName)" | Set-Content -Path $manifestPath
(Get-Content -Path $manifestPath) -replace 'NewManifest', "$($env:RepoName)" | Set-Content -Path $manifestPath
#(Get-Content -Path $manifestPath) -replace 'FunctionsToExport = ', 'FunctionsToExport = @(' | Set-Content -Path $manifestPath -Force
#(Get-Content -Path $manifestPath) -replace "$($functionList[-1])'", "$($functionList[-1])')" | Set-Content -Path $manifestPath -Force
}
catch
{
throw $_
}
# Publish the new version to the PowerShell Gallery
Try
{
# Build a splat containing the required details and make sure to Stop for errors which will trigger the catch
$PM = @{
Path = '.'
NuGetApiKey = $env:NuGetApiKey
ErrorAction = 'Stop'
Force = $true
}
Publish-Module @PM
Write-Host "$($env:RepoName) PowerShell Module version $newVersion published to the PowerShell Gallery." -ForegroundColor Cyan
}
Catch
{
Write-Warning "Publishing update $newVersion to the PowerShell Gallery failed."
throw $_
}
# Publish the new version back to Master on GitHub
Try
{
# Set up a path to the git.exe cmd, import posh-git to give us control over git, and then push changes to GitHub
# Note that "update version" is included in the appveyor.yml file's "skip a build" regex to avoid a loop
$env:Path += ";$env:ProgramFiles\Git\cmd"
Import-Module posh-git -ErrorAction Stop
git checkout master -q
git add --all
git status
git commit -s -m "Update version to $newVersion"
git push origin master -q
Write-Host "$($env:RepoName) PowerShell Module version $newVersion published to GitHub." -ForegroundColor Cyan
}
Catch
{
Write-Warning "Publishing update $newVersion to GitHub failed."
throw $_
}
}

Просмотреть файл

@ -0,0 +1,14 @@
# Invoke Pester to run tests, then save the results in NUnitXML to populate the AppVeyor tests section
# Pester : https://github.com/pester/Pester/wiki
# Pester Code Coverage : https://info.sapien.com/index.php/scripting/scripting-modules/testing-pester-code-coverage
New-Item -Path .\tests -Name results -ItemType Directory -Force
$testResultPath = '.\tests\results\TestResults.xml'
# This is a manifest so no code coverage is possible. Original line kept below:
#...\results\TestsResults.xml -PassThru -CodeCoverage .\MSFTNetworking.Tools.psd1
$res = Invoke-Pester -Path ".\tests\unit" -OutputFormat NUnitXml -OutputFile $testResultPath -PassThru
(New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path $testResultPath))
if ($res.FailedCount -gt 0) { throw "$($res.FailedCount) tests failed." }

29
tests/setup/install.ps1 Normal file
Просмотреть файл

@ -0,0 +1,29 @@
git clone -q https://github.com/PowerShell/DscResource.Tests
Import-Module -Name "$env:APPVEYOR_BUILD_FOLDER\DscResource.Tests\AppVeyor.psm1"
Invoke-AppveyorInstallTask
[string[]]$PowerShellModules = @("Pester", 'posh-git', 'psake', 'poshspec', 'PSScriptAnalyzer')
$ModuleManifest = Test-ModuleManifest .\$($env:RepoName).psd1 -ErrorAction SilentlyContinue
$repoRequiredModules = $ModuleManifest.RequiredModules.Name
$PowerShellModules += $repoRequiredModules
# This section is taken care of by Invoke-AppVeyorInstallTask
<#[string[]]$PackageProviders = @('NuGet', 'PowerShellGet')
# Install package providers for PowerShell Modules
ForEach ($Provider in $PackageProviders) {
If (!(Get-PackageProvider $Provider -ErrorAction SilentlyContinue)) {
Install-PackageProvider $Provider -Force -ForceBootstrap -Scope CurrentUser
}
}#>
# Install the PowerShell Modules
ForEach ($Module in $PowerShellModules) {
If (!(Get-Module -ListAvailable $Module -ErrorAction SilentlyContinue)) {
Install-Module $Module -Scope CurrentUser -Force -Repository PSGallery
}
Import-Module $Module
}

14
tests/unit/unit.tests.ps1 Normal file
Просмотреть файл

@ -0,0 +1,14 @@
$DataFile = Import-PowerShellDataFile .\MSFTNetworking.Tools.psd1 -ErrorAction SilentlyContinue
$TestModule = Test-ModuleManifest .\MSFTNetworking.Tools.psd1 -ErrorAction SilentlyContinue
Describe "$($env:APPVEYOR_BUILD_FOLDER)-Manifest" {
Context Validation {
It "[Import-PowerShellDataFile] - $($env:APPVEYOR_BUILD_FOLDER).psd1 is a valid PowerShell Data File" {
$DataFile | Should Not BeNullOrEmpty
}
It "[Test-ModuleManifest] - $($env:APPVEYOR_BUILD_FOLDER).psd1 should pass the basic test" {
$TestModule | Should Not BeNullOrEmpty
}
}
}