Skip to content

Commit bc8266e

Browse files
authored
Merge pull request #77 from dbroeglin/feature/ha
Add High-Availability support functions [Enable-NSHighAvailability] and [Get-NSHANode].
2 parents d5818de + 703da68 commit bc8266e

File tree

8 files changed

+304
-11
lines changed

8 files changed

+304
-11
lines changed

Contrib/CODE_GENERATION.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Notes about generating code for the module
2+
3+
## History
4+
5+
Our first shot a generating code for the module was to create an ad-hoc string interpolation based generator : `New-GetCmdlet.ps1`.
6+
7+
The actual generation process where we tell the cmdlet what to generate is defined
8+
in `New-GetCmdlets.ps1`
9+
10+
However, this approach is very cumbersome and leads to a very hard do maintain
11+
generator. The preferred approach now is to use a template base generator. The generator is still a work in progress but you can take a look at https://github.com/dbroeglin/Forge.Netscaler if you are interested.
12+
13+
## Updating FunctionsToExport
14+
15+
$list = (Get-ChildItem ./NetScaler/Public/ |
16+
Sort-Object Name |
17+
ForEach-Object {
18+
$_.name -replace '(.*).ps1', " '`$1'"
19+
}) -join ",`r`n"
20+
[System.IO.File]::WriteAllText(
21+
"./Netscaler/Netscaler.psd1", (
22+
(
23+
Get-Content -Encoding UTF8 ./NetScaler/NetScaler.psd1 -Raw
24+
) -replace "(?smi)(FunctionsToExport *= *@\()[^)]*(\))",
25+
"`$1`r`n$list`r`n`$2"))
26+
27+
28+
# Example code generation:
29+
30+
New-NSGet -Name HANode -Label "HA Node" -Filters ([ordered]@{
31+
"Name" = "name"
32+
"IPAddress" = "ipaddress"
33+
"State" = "state"
34+
"HAStatus" = "hastatus"
35+
"HASync" = "hasync"
36+
}) -ResourceIdParamName ID -Partial
37+
38+

NetScaler/NetScaler.psd1

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ FunctionsToExport = @(
9494
'Disable-NSMode',
9595
'Disconnect-NetScaler',
9696
'Enable-NSFeature',
97+
'Enable-NSHighAvailability',
9798
'Enable-NSLBMonitor',
9899
'Enable-NSLBServer',
99100
'Enable-NSLBVirtualServer',
@@ -113,10 +114,11 @@ FunctionsToExport = @(
113114
'Get-NSDnsNameServer',
114115
'Get-NSDnsSuffix',
115116
'Get-NSFeature',
117+
'Get-NSHANode',
116118
'Get-NSHardware',
117119
'Get-NSHostname',
118-
'Get-NSIPResource',
119120
'Get-NSIP6Resource',
121+
'Get-NSIPResource',
120122
'Get-NSKCDAccount',
121123
'Get-NSLBMonitor',
122124
'Get-NSLBServer',
@@ -135,18 +137,18 @@ FunctionsToExport = @(
135137
'Get-NSLBVirtualServerTrafficPolicyBinding',
136138
'Get-NSLDAPAuthenticationPolicy',
137139
'Get-NSLDAPAuthenticationServer',
140+
'Get-NSMode',
141+
'Get-NSNTPServer',
138142
'Get-NSResponderAction',
139143
'Get-NSResponderPolicy',
140144
'Get-NSRewriteAction',
141145
'Get-NSRewritePolicy',
142-
'Get-NSStat',
143-
'Get-NSMode',
144-
'Get-NSNTPServer',
145146
'Get-NSSAMLAuthenticationPolicy',
146147
'Get-NSSAMLAuthenticationServer',
147148
'Get-NSSSLCertificate',
148149
'Get-NSSSLCertificateLink',
149150
'Get-NSSSLProfile',
151+
'Get-NSStat',
150152
'Get-NSSystemFile',
151153
'Get-NSTimeZone',
152154
'Get-NSVersion',
@@ -175,7 +177,6 @@ FunctionsToExport = @(
175177
'New-NSResponderPolicy',
176178
'New-NSRewriteAction',
177179
'New-NSRewritePolicy',
178-
'New-NSNTPServer',
179180
'New-NSSSLProfile',
180181
'New-NSVPNSessionPolicy',
181182
'New-NSVPNSessionProfile',
@@ -186,9 +187,9 @@ FunctionsToExport = @(
186187
'Remove-NSLBServer',
187188
'Remove-NSLBServiceGroup',
188189
'Remove-NSLBServiceGroupMonitorBinding',
190+
'Remove-NSLBSSLVirtualServerProfile',
189191
'Remove-NSLBVirtualServer',
190192
'Remove-NSLBVirtualServerBinding',
191-
'Remove-NSLBSSLVirtualServerProfile',
192193
'Remove-NSLDAPAuthenticationPolicy',
193194
'Remove-NSLDAPAuthenticationServer',
194195
'Remove-NSResponderAction',
@@ -268,3 +269,5 @@ PrivateData = @{
268269

269270
}
270271

272+
273+

NetScaler/Private/_AssertSessionActive.ps1

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@ limitations under the License.
1515
#>
1616

1717
function _AssertSessionActive {
18-
$s = $script:session
19-
if ($null -eq $s ) {
18+
param(
19+
$Session = $script:session
20+
)
21+
22+
if ($null -eq $session) {
2023
throw 'Must be logged into NetScaler appliance first!'
2124
}
2225
}

NetScaler/Public/Add-NSSystemFile.ps1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ function Add-NSSystemFile {
4444
Suppress confirmation when creating the system file (this does not override a
4545
pre-existing file).
4646
47-
.Notes
47+
.NOTES
4848
Nitro implementation status: partial
4949
#>
5050
[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact='Low')]
@@ -85,4 +85,4 @@ function Add-NSSystemFile {
8585
}
8686
}
8787
}
88-
}
88+
}
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<#
2+
Copyright 2017 Dominique Broeglin
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
#>
16+
17+
function Enable-NSHighAvailability {
18+
<#
19+
.SYNOPSIS
20+
Enable high-availability between two NetScaler instances.
21+
22+
.DESCRIPTION
23+
Enable high-availability between two NetScaler instances.
24+
25+
.EXAMPLE
26+
Enable-NSHighAvailability -PrimarySession $ns1 -SecondarySession Session $ns2
27+
28+
Enable high-availability between the netscaler instances corresponding to
29+
the already opened $ns1 and $ns2.
30+
31+
.PARAMETER PrimarySession
32+
The NetScaler session object for the first NetScaler instance (will end up master).
33+
34+
.PARAMETER SecondarySession
35+
The NetScaler session object for the second NetScaler instance (will end up slave).
36+
37+
.PARAMETER PeerNodeId
38+
The node id used to denote the peer.
39+
40+
Default value: 1
41+
42+
.PARAMETER Timeout
43+
Time to wait, in secondes, for the synchronization to complete.
44+
45+
Default value: 300
46+
47+
.PARAMETER Save
48+
If true, wait for the synchronization to finish and save configurations.
49+
50+
.PARAMETER Force
51+
Suppress confirmation when activating high-availability.
52+
#>
53+
[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact='High')]
54+
param(
55+
[parameter(Mandatory)]
56+
$PrimarySession,
57+
58+
[parameter(Mandatory)]
59+
$SecondarySession,
60+
61+
[int]$PeerNodeId = 1,
62+
63+
[int]$Timeout = 300,
64+
65+
[switch]$Save,
66+
67+
[switch]$Force
68+
)
69+
70+
begin {
71+
_AssertSessionActive -Session $PrimarySession
72+
_AssertSessionActive -Session $SecondarySession
73+
}
74+
75+
process {
76+
if ($Force -or $PSCmdlet.ShouldProcess(
77+
"Enable high-availability of $($PrimarySession.Endpoint) and $($SecondarySession.Endpoint)")) {
78+
try {
79+
$primaryIp = $PrimarySession.Endpoint
80+
$secondaryIp = $SecondarySession.Endpoint
81+
82+
Write-Verbose "$primaryIp -> STAYPRIMARY..."
83+
_InvokeNSRestApi -Session $PrimarySession -Method PUT -Type hanode `
84+
-Payload @{ id = 0; hastatus = "STAYPRIMARY" }
85+
86+
Write-Verbose "$secondaryIp -> STAYSECONDARY..."
87+
_InvokeNSRestApi -Session $SecondarySession -Method PUT -Type hanode `
88+
-Payload @{ id = 0; hastatus = "STAYSECONDARY" }
89+
90+
Write-Verbose "$primaryIp -> set secondatory to $secondaryIp..."
91+
_InvokeNSRestApi -Session $PrimarySession -Method POST -Type hanode `
92+
-Payload @{ id = $PeerNodeId; ipaddress = $secondaryIp } -Action add
93+
94+
Write-Verbose "$secondaryIp -> set secondatory to $primaryIp..."
95+
_InvokeNSRestApi -Session $SecondarySession -Method POST -Type hanode `
96+
-Payload @{ id = $PeerNodeId; ipaddress = $primaryIp } -Action Add
97+
98+
Write-Verbose "$primaryIp -> ENABLED..."
99+
_InvokeNSRestApi -Session $PrimarySession -Method PUT -Type hanode `
100+
-Payload @{ id = 0; hastatus = "ENABLED" }
101+
102+
Write-Verbose "$secondaryIp -> ENABLED..."
103+
_InvokeNSRestApi -Session $SecondarySession -Method PUT -Type hanode `
104+
-Payload @{ id = 0; hastatus = "ENABLED" }
105+
106+
if ($Save) {
107+
$waitStart = Get-Date
108+
109+
while (((Get-Date) - $waitStart).TotalSeconds -lt $Timeout) {
110+
Write-Verbose "Waiting for synchronization to complete..."
111+
Start-Sleep -Seconds 5
112+
$HaNode = Get-NSHaNode -Session $PrimarySession -Id $PeerNodeId
113+
114+
if ($HaNode.hasync -match "IN PROGRESS|ENABLED") {
115+
Write-Verbose "Synchronizing..."
116+
continue
117+
} elseif ($HaNode.hasync -eq "SUCCESS") {
118+
Write-Verbose "Synchronization succesful. Saving configurations..."
119+
Save-NSConfig -Session $PrimarySession
120+
Save-NSConfig -Session $SecondarySession
121+
break
122+
} else {
123+
throw "Unexpected sync status '$($HaNode.hasync)'"
124+
}
125+
}
126+
127+
if ($HaNode.hasync -ne "SUCCESS") {
128+
throw "Timeout expired before the synchronization ended. Configurations will not be saved!"
129+
}
130+
}
131+
} catch {
132+
throw $_
133+
}
134+
}
135+
}
136+
}

NetScaler/Public/Get-NSConfig.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,6 @@ function Get-NSConfig {
5858
} else {
5959
$Config = (_InvokeNSRestApi -Session $Session -Method Get -Type nssavedconfig -Action GetAll).nssavedconfig.textblob
6060
}
61-
$Config -Split '\n' | ? { $_ -and !($_ -match "^( Done| *#)") }
61+
$Config -Split '\n' | Where-Object { $_ -and !($_ -match "^( Done| *#)") }
6262
}
6363
}

NetScaler/Public/Get-NSHANode.ps1

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
2+
<#
3+
Copyright $CopyrightYear $Author
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
#>
17+
18+
function Get-NSHANode {
19+
<#
20+
.SYNOPSIS
21+
Gets the specified HA Node object(s).
22+
23+
.DESCRIPTION
24+
Gets the specified HA Node object(s).
25+
Either returns a single object identified by its identifier (-ID parameter)
26+
or a collection of objects filtered by the other parameters. Those
27+
filter parameters accept either a literal value or a regexp in the form
28+
"/someregexp/".
29+
30+
.EXAMPLE
31+
Get-NSHANode
32+
33+
Get all HA Node objects.
34+
35+
.EXAMPLE
36+
Get-NSHANode -ID 'foobar'
37+
38+
Get the HA Node named 'foobar'.
39+
40+
.PARAMETER Session
41+
The NetScaler session object.
42+
43+
.PARAMETER ID
44+
The identifier/name or identifiers/names of the HA Nodes to get.
45+
46+
.PARAMETER IPAddress
47+
A filter to apply to the ipaddress property.
48+
49+
.PARAMETER HASync
50+
A filter to apply to the hasync property.
51+
52+
.PARAMETER Name
53+
A filter to apply to the name property.
54+
55+
.PARAMETER HAStatus
56+
A filter to apply to the hastatus property.
57+
58+
.PARAMETER State
59+
A filter to apply to the state property.
60+
61+
.NOTES
62+
Nitro implementation status: partial
63+
64+
#>
65+
[CmdletBinding(DefaultParameterSetName='get')]
66+
Param(
67+
$Session = $Script:Session,
68+
69+
[Parameter(Position=0, ParameterSetName='get')]
70+
[string[]]$ID = @(),
71+
72+
[Parameter(ParameterSetName='search')]
73+
[string]$IPAddress,
74+
75+
[Parameter(ParameterSetName='search')]
76+
[string]$HASync,
77+
78+
[Parameter(ParameterSetName='search')]
79+
[string]$Name,
80+
81+
[Parameter(ParameterSetName='search')]
82+
[string]$HAStatus,
83+
84+
[Parameter(ParameterSetName='search')]
85+
[string]$State
86+
87+
)
88+
Begin {
89+
_AssertSessionActive
90+
}
91+
92+
Process {
93+
# Contruct a filter hash if we specified any filters
94+
$Filters = @{}
95+
if ($PSBoundParameters.ContainsKey('IPAddress')) {
96+
$Filters['ipaddress'] = $IPAddress
97+
}
98+
if ($PSBoundParameters.ContainsKey('HASync')) {
99+
$Filters['hasync'] = $HASync
100+
}
101+
if ($PSBoundParameters.ContainsKey('Name')) {
102+
$Filters['name'] = $Name
103+
}
104+
if ($PSBoundParameters.ContainsKey('HAStatus')) {
105+
$Filters['hastatus'] = $HAStatus
106+
}
107+
if ($PSBoundParameters.ContainsKey('State')) {
108+
$Filters['state'] = $State
109+
}
110+
_InvokeNSRestApiGet -Session $Session -Type hanode -Name $ID -Filters $Filters
111+
112+
}
113+
}
File renamed without changes.

0 commit comments

Comments
 (0)