Skip to content

Commit 36d6759

Browse files
abhi7860Abhishek ShahNoriZC
authored
[Bastion] Add support for 'Premium' Sku and 'enableSessionRecording' feature flag (#25096)
* Init * Updating help * Minor fix * Updating tests * Update help * Update ChangeLog.md * Update ChangeLog.md --------- Co-authored-by: Abhishek Shah <[email protected]> Co-authored-by: NoriZC <[email protected]>
1 parent 058e890 commit 36d6759

File tree

17 files changed

+7160
-3628
lines changed

17 files changed

+7160
-3628
lines changed

src/Network/Network.Test/ScenarioTests/BastionTests.ps1

Lines changed: 73 additions & 24 deletions
Large diffs are not rendered by default.

src/Network/Network.Test/SessionRecords/Commands.Network.Test.ScenarioTests.BastionTests/TestBastionCRUD.json

Lines changed: 1183 additions & 1869 deletions
Large diffs are not rendered by default.

src/Network/Network.Test/SessionRecords/Commands.Network.Test.ScenarioTests.BastionTests/TestBastionCreateWithFeatures.json

Lines changed: 5533 additions & 1663 deletions
Large diffs are not rendered by default.

src/Network/Network/Bastion/BastionBaseCmdlet.cs

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ public PSBastion GetBastion(string resourceGroupName, string name)
102102
psBastion.EnableTunneling = bastion.EnableTunneling;
103103
psBastion.EnableIpConnect = bastion.EnableIPConnect;
104104
psBastion.EnableShareableLink = bastion.EnableShareableLink;
105+
psBastion.EnableSessionRecording = bastion.EnableSessionRecording;
105106

106107
return psBastion;
107108
}
@@ -117,6 +118,7 @@ public PSBastion ToPsBastion(MNM.BastionHost host)
117118
bastion.EnableTunneling = host.EnableTunneling;
118119
bastion.EnableIpConnect = host.EnableIPConnect;
119120
bastion.EnableShareableLink = host.EnableShareableLink;
121+
bastion.EnableSessionRecording = host.EnableSessionRecording;
120122

121123
return bastion;
122124
}
@@ -157,6 +159,13 @@ public bool IsSkuDowngrade(PSBastion bastion, string sku)
157159
return true;
158160
}
159161
return false;
162+
// Premium -> Basic or Standard
163+
case PSBastionSku.Premium:
164+
if (newSkuTier == PSBastionSku.Basic || newSkuTier == PSBastionSku.Standard)
165+
{
166+
return true;
167+
}
168+
return false;
160169
default:
161170
return true;
162171
}
@@ -165,40 +174,43 @@ public bool IsSkuDowngrade(PSBastion bastion, string sku)
165174
return true;
166175
}
167176

168-
public void ValidateScaleUnits(PSBastion bastion, int? scaleUnits = 2)
177+
public void ValidateScaleUnits(PSBastion bastion, int? scaleUnits = Constants.MinimumScaleUnits)
169178
{
179+
if (!scaleUnits.HasValue) return;
180+
170181
if (PSBastionSku.TryGetSkuTier(bastion.Sku.Name, out string skuTierValue))
171182
{
172183
switch (skuTierValue)
173184
{
174185
case PSBastionSku.Basic:
175-
if (scaleUnits != PSBastion.MinimumScaleUnits)
186+
if (scaleUnits != Constants.MinimumScaleUnits)
176187
{
177-
throw new ArgumentException($"Bastion scalable host is available on Standard SKU");
188+
throw new ArgumentException(Properties.Resources.BastionScaleUnitUpdateNotAllowedOnBasic);
178189
}
179190
break;
180191
case PSBastionSku.Standard:
181-
if (scaleUnits < PSBastion.MinimumScaleUnits
182-
|| scaleUnits > PSBastion.MaximumScaleUnits)
192+
if (scaleUnits < Constants.MinimumScaleUnits
193+
|| scaleUnits > Constants.MaximumScaleUnits)
183194
{
184-
throw new ArgumentException($"Please select scale units value between {PSBastion.MinimumScaleUnits} and {PSBastion.MaximumScaleUnits}");
195+
throw new ArgumentException(string.Format(Properties.Resources.BastionScaleUnitOutOfRange, Constants.MinimumScaleUnits, Constants.MaximumScaleUnits));
185196
}
186197
break;
187198
default:
188-
throw new ArgumentException($"Please enter a valid value for Bastion SKU");
199+
throw new ArgumentException(Properties.Resources.BastionSkuInvalidValue);
189200
}
190201
}
191202
else
192203
{
193-
throw new ArgumentException($"Please enter a valid value for Bastion SKU");
204+
throw new ArgumentException(Properties.Resources.BastionSkuInvalidValue);
194205
}
195206
}
196207

197208
public void ValidateFeatures(PSBastion bastion,
198209
bool? disableCopyPaste = false,
199210
bool? enableTunneling = false,
200211
bool? enableIpConnect = false,
201-
bool? enableShareableLink = false)
212+
bool? enableShareableLink = false,
213+
bool? enableSessionRecording = false)
202214
{
203215
if (PSBastionSku.TryGetSkuTier(bastion.Sku.Name, out string skuTierValue))
204216
{
@@ -207,30 +219,46 @@ public void ValidateFeatures(PSBastion bastion,
207219
case PSBastionSku.Basic:
208220
if (disableCopyPaste != null && disableCopyPaste != false)
209221
{
210-
throw new ArgumentException($"Toggling copy/paste is available on Standard SKU or higher");
222+
throw new ArgumentException(Properties.Resources.BastionCopyPasteInvalidValue);
211223
}
212224
if (enableTunneling != null && enableTunneling != false)
213225
{
214-
throw new ArgumentException($"Toggling tunneling is available on Standard SKU or higher");
226+
throw new ArgumentException(Properties.Resources.BastionTunnelingInvalidValue);
215227
}
216228
if (enableIpConnect != null && enableIpConnect != false)
217229
{
218-
throw new ArgumentException($"Toggling IP connect is available on Standard SKU or higher");
230+
throw new ArgumentException(Properties.Resources.BastionIpConnectInvalidValue);
219231
}
220232
if (enableShareableLink != null && enableShareableLink != false)
221233
{
222-
throw new ArgumentException($"Toggling shareable link is available on Standard SKU or higher");
234+
throw new ArgumentException(Properties.Resources.BastionShareableLinkInvalidValue);
235+
}
236+
if (enableSessionRecording != null && enableSessionRecording != false)
237+
{
238+
throw new ArgumentException(Properties.Resources.BastionSessionRecordingInvalidValue);
223239
}
224240
break;
225241
case PSBastionSku.Standard:
242+
if (enableSessionRecording != null && enableSessionRecording != false)
243+
{
244+
throw new ArgumentException(Properties.Resources.BastionSessionRecordingInvalidValue);
245+
}
246+
break;
247+
case PSBastionSku.Premium:
248+
if ((enableTunneling.GetValueOrDefault(false) && enableSessionRecording.GetValueOrDefault(false))
249+
|| (bastion.EnableTunneling.GetValueOrDefault(false) && enableSessionRecording.GetValueOrDefault(false))
250+
|| (enableTunneling.GetValueOrDefault(false)&& bastion.EnableSessionRecording.GetValueOrDefault(false)))
251+
{
252+
throw new ArgumentException(Properties.Resources.BastionTunnelingAndSessionRecordingNotAllowed);
253+
}
226254
break;
227255
default:
228-
throw new ArgumentException($"Please enter a valid value for Bastion SKU");
256+
throw new ArgumentException(Properties.Resources.BastionSkuInvalidValue);
229257
}
230258
}
231259
else
232260
{
233-
throw new ArgumentException($"Please enter a valid value for Bastion SKU");
261+
throw new ArgumentException(Properties.Resources.BastionSkuInvalidValue);
234262
}
235263
}
236264
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
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+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
namespace Microsoft.Azure.Commands.Network.Bastion
16+
{
17+
internal class Constants
18+
{
19+
// Bastion
20+
internal const string BastionResourceName = "Bastion";
21+
internal const string BastionResourceType = "Microsoft.Network/bastionHosts";
22+
internal const string BastionSubnetName = "AzureBastionSubnet";
23+
internal const string BastionIpConfigurationName = "IpConf";
24+
25+
// Scale Units
26+
internal const int MinimumScaleUnits = 2;
27+
internal const int MaximumScaleUnits = 50;
28+
}
29+
}

src/Network/Network/Bastion/GetAzBastionCommand.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ namespace Microsoft.Azure.Commands.Network.Bastion
2424
using Microsoft.Azure.Management.Network.Models;
2525

2626
[Cmdlet(VerbsCommon.Get,
27-
ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "Bastion",
27+
ResourceManager.Common.AzureRMConstants.AzureRMPrefix + Constants.BastionResourceName,
2828
DefaultParameterSetName = BastionParameterSetNames.ListBySubscription,
2929
SupportsShouldProcess = true),
3030
OutputType(typeof(PSBastion), typeof(IEnumerable<PSBastion>))]
@@ -55,7 +55,7 @@ public class GetAzBastionCommand : BastionBaseCmdlet
5555
Mandatory = true,
5656
ParameterSetName = BastionParameterSetNames.ByResourceGroupName + BastionParameterSetNames.ByName,
5757
HelpMessage = "The bastion resource name.")]
58-
[ResourceNameCompleter("Microsoft.Network/bastionHosts", "ResourceGroupName")]
58+
[ResourceNameCompleter(Constants.BastionResourceType, "ResourceGroupName")]
5959
[ValidateNotNullOrEmpty]
6060
public string Name { get; set; }
6161

src/Network/Network/Bastion/NewAzBastionCommand.cs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ namespace Microsoft.Azure.Commands.Network.Bastion
2828
using MNM = Management.Network.Models;
2929

3030
[Cmdlet(VerbsCommon.New,
31-
ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "Bastion",
31+
ResourceManager.Common.AzureRMConstants.AzureRMPrefix + Constants.BastionResourceName,
3232
DefaultParameterSetName = BastionParameterSetNames.ByIpObject + BastionParameterSetNames.ByVNObject,
3333
SupportsShouldProcess = true),
3434
OutputType(typeof(PSBastion))]
@@ -47,7 +47,7 @@ public class NewAzBastionCommand : BastionBaseCmdlet
4747
Mandatory = true,
4848
HelpMessage = "The Bastion resource name.")]
4949
[ValidateNotNullOrEmpty]
50-
[ResourceNameCompleter("Microsoft.Network/bastionHosts", "ResourceGroupName")]
50+
[ResourceNameCompleter(Constants.BastionResourceType, "ResourceGroupName")]
5151
public string Name { get; set; }
5252

5353
[Alias("PublicIpAddressObject")]
@@ -180,18 +180,19 @@ public class NewAzBastionCommand : BastionBaseCmdlet
180180
Mandatory = false,
181181
ValueFromPipeline = true,
182182
HelpMessage = "The Bastion Sku Tier")]
183-
[PSArgumentCompleter(PSBastionSku.Basic, PSBastionSku.Standard)]
183+
[PSArgumentCompleter(PSBastionSku.Basic, PSBastionSku.Standard, PSBastionSku.Premium)]
184184
[ValidateSet(
185185
MNM.BastionHostSkuName.Basic,
186186
MNM.BastionHostSkuName.Standard,
187+
MNM.BastionHostSkuName.Premium,
187188
IgnoreCase = false)]
188189
public string Sku { get; set; }
189190

190191
[Parameter(
191192
Mandatory = false,
192193
ValueFromPipeline = true,
193194
HelpMessage = "The Scale Units for Bastion")]
194-
[DefaultValue(2)]
195+
[DefaultValue(Constants.MinimumScaleUnits)]
195196
public int? ScaleUnit { get; set; }
196197

197198
[Parameter(
@@ -229,6 +230,13 @@ public class NewAzBastionCommand : BastionBaseCmdlet
229230
[DefaultValue(false)]
230231
public bool? EnableShareableLink { get; set; }
231232

233+
[Parameter(
234+
Mandatory = false,
235+
ValueFromPipeline = true,
236+
HelpMessage = "Session Recording")]
237+
[DefaultValue(false)]
238+
public bool? EnableSessionRecording { get; set; }
239+
232240
[Parameter(
233241
Mandatory = false,
234242
HelpMessage = "Run cmdlet in the background")]
@@ -267,7 +275,7 @@ private PSBastion CreateBastion()
267275
PSBastion bastion = new PSBastion(this.Name, this.ResourceGroupName, this.VirtualNetwork.Location, this.Sku);
268276

269277
#region Feature Validations
270-
ValidateFeatures(bastion, this.DisableCopyPaste, this.EnableTunneling, this.EnableIpConnect, this.EnableShareableLink);
278+
ValidateFeatures(bastion, this.DisableCopyPaste, this.EnableTunneling, this.EnableIpConnect, this.EnableShareableLink, this.EnableSessionRecording);
271279
if (this.EnableKerberos.HasValue)
272280
{
273281
bastion.EnableKerberos = this.EnableKerberos.Value;
@@ -288,6 +296,10 @@ private PSBastion CreateBastion()
288296
{
289297
bastion.EnableShareableLink = this.EnableShareableLink.Value;
290298
}
299+
if (this.EnableSessionRecording.HasValue)
300+
{
301+
bastion.EnableSessionRecording = this.EnableSessionRecording.Value;
302+
}
291303
#endregion
292304

293305
#region Scale Unit Validations

src/Network/Network/Bastion/RemoveAzBastionCommand.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ namespace Microsoft.Azure.Commands.Network.Bastion
2424
using System.Management.Automation;
2525

2626
[Cmdlet(VerbsCommon.Remove,
27-
ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "Bastion",
27+
ResourceManager.Common.AzureRMConstants.AzureRMPrefix + Constants.BastionResourceName,
2828
DefaultParameterSetName = BastionParameterSetNames.ByResourceGroupName,
2929
SupportsShouldProcess = true),
3030
OutputType(typeof(bool))]
@@ -44,7 +44,7 @@ public class RemoveAzBastionCommand : BastionBaseCmdlet
4444
ParameterSetName = BastionParameterSetNames.ByResourceGroupName,
4545
Mandatory = true,
4646
HelpMessage = "The bastion resource name to be deleted.")]
47-
[ResourceNameCompleter("Microsoft.Network/bastionHosts", "ResourceGroupName")]
47+
[ResourceNameCompleter(Constants.BastionResourceType, "ResourceGroupName")]
4848
[ValidateNotNullOrEmpty]
4949
public string Name { get; set; }
5050

@@ -64,7 +64,7 @@ public class RemoveAzBastionCommand : BastionBaseCmdlet
6464
ValueFromPipelineByPropertyName = true,
6565
HelpMessage = "The Azure resource ID for the Bastion to be deleted.")]
6666
[ValidateNotNullOrEmpty]
67-
[ResourceIdCompleter("Microsoft.Network/bastionHosts")]
67+
[ResourceIdCompleter(Constants.BastionResourceType)]
6868
public string ResourceId { get; set; }
6969

7070
[Parameter(

src/Network/Network/Bastion/SetAzBastionCommand.cs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ namespace Microsoft.Azure.Commands.Network.Bastion
2626
using MNM = Management.Network.Models;
2727

2828
[Cmdlet(VerbsCommon.Set,
29-
ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "Bastion",
29+
ResourceManager.Common.AzureRMConstants.AzureRMPrefix + Constants.BastionResourceName,
3030
DefaultParameterSetName = BastionParameterSetNames.ByBastionObject,
3131
SupportsShouldProcess = true),
3232
OutputType(typeof(PSBastion))]
@@ -43,10 +43,11 @@ public class SetAzBastionCommand : BastionBaseCmdlet
4343
Mandatory = false,
4444
ValueFromPipeline = true,
4545
HelpMessage = "Bastion Sku")]
46-
[PSArgumentCompleter("Basic", "Standard")]
46+
[PSArgumentCompleter(PSBastionSku.Basic, PSBastionSku.Standard, PSBastionSku.Premium)]
4747
[ValidateSet(
4848
MNM.BastionHostSkuName.Basic,
4949
MNM.BastionHostSkuName.Standard,
50+
MNM.BastionHostSkuName.Premium,
5051
IgnoreCase = false)]
5152
public string Sku { get; set; }
5253

@@ -86,6 +87,12 @@ public class SetAzBastionCommand : BastionBaseCmdlet
8687
HelpMessage = "Shareable Link")]
8788
public bool? EnableShareableLink { get; set; }
8889

90+
[Parameter(
91+
Mandatory = false,
92+
ValueFromPipeline = true,
93+
HelpMessage = "Session Recording")]
94+
public bool? EnableSessionRecording { get; set; }
95+
8996
[Parameter(
9097
Mandatory = false,
9198
ValueFromPipeline = true,
@@ -122,7 +129,7 @@ public override void Execute()
122129
// Check if InputObject Sku is being downgraded
123130
if (IsSkuDowngrade(this.InputObject, this.Sku))
124131
{
125-
throw new ArgumentException("Downgrading Sku is not allowed");
132+
throw new ArgumentException(Properties.Resources.BastionSkuDowngradeNotAllowed);
126133
}
127134

128135
this.InputObject.Sku = new PSBastionSku(this.Sku);
@@ -133,15 +140,15 @@ public override void Execute()
133140
// Check if getBastionHost Sku is being downgraded from InputObject by setting InputObject.Sku.Name
134141
if (IsSkuDowngrade(getBastionHost, this.InputObject.Sku.Name))
135142
{
136-
throw new ArgumentException("Downgrading Sku is not allowed");
143+
throw new ArgumentException(Properties.Resources.BastionSkuDowngradeNotAllowed);
137144
}
138145

139146
this.InputObject.Sku = new PSBastionSku(getBastionHost.Sku.Name);
140147
}
141148
#endregion
142149

143150
#region Feature validations and updates
144-
ValidateFeatures(this.InputObject, this.DisableCopyPaste, this.EnableTunneling, this.EnableIpConnect, this.EnableShareableLink);
151+
ValidateFeatures(this.InputObject, this.DisableCopyPaste, this.EnableTunneling, this.EnableIpConnect, this.EnableShareableLink, this.EnableSessionRecording);
145152
if (this.EnableKerberos.HasValue)
146153
{
147154
this.InputObject.EnableKerberos = this.EnableKerberos.Value;
@@ -162,6 +169,10 @@ public override void Execute()
162169
{
163170
this.InputObject.EnableShareableLink = this.EnableShareableLink.Value;
164171
}
172+
if (this.EnableSessionRecording.HasValue)
173+
{
174+
this.InputObject.EnableSessionRecording = this.EnableSessionRecording.Value;
175+
}
165176
#endregion
166177

167178
#region Scale unit validations and update

src/Network/Network/ChangeLog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
--->
2020

2121
## Upcoming Release
22+
* Updated Network.Management SDK to consume newer Swagger version
23+
* Updated cmdlet to add 'Premium' as a valid value for 'Sku' parameter and 'enableSessionRecording' feature for Bastion resources
24+
- `New-AzBastion`
25+
- `Set-AzBastion`
2226
* Updated cmdlet `Add-AzVirtualNetworkSubnetConfig`, `Set-AzVirtualNetworkSubnetConfig` and `New-AzVirtualNetworkSubnetConfig` to support Network Identifier for Subnet Service Endpoint.
2327
* Added cmdlet `Restart-AzNetworkVirtualAppliance` for allowing a restart of Network Virtual Appliance instances from the customer subscription.
2428
* Fixed a bug in `Update-AzNetworkVirtualApplianceConnection`

0 commit comments

Comments
 (0)