Skip to content

Commit 2411789

Browse files
abhi7860Abhishek Shah
andauthored
[Bastion] Add support for Bastion features (#23404)
* Initial commit * Optimize for sku and features * Initial commit * Optimize for sku and features * Cleanup * Formatting and add test cases * Minor fixes * Fixing tests * Adding newly generated markdowns * Update ChangeLog.md * Mark "Kerberos is plural" as false positive --------- Co-authored-by: Abhishek Shah <[email protected]>
1 parent 443a3f2 commit 2411789

File tree

19 files changed

+10740
-3864
lines changed

19 files changed

+10740
-3864
lines changed

src/Network/Network.Test/ScenarioTests/BastionTests.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,13 @@ public void TestBastionIpObjectParam()
5757
{
5858
TestRunner.RunTestScript("Test-BastionIpObjectParam");
5959
}
60+
61+
[Fact]
62+
[Trait(Category.AcceptanceType, Category.CheckIn)]
63+
[Trait(Category.Owner, NrpTeamAlias.bastion)]
64+
public void TestBastionCreateWithFeatures()
65+
{
66+
TestRunner.RunTestScript("Test-BastionCreateWithFeatures");
67+
}
6068
}
6169
}

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

Lines changed: 207 additions & 100 deletions
Large diffs are not rendered by default.

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

Lines changed: 1646 additions & 1271 deletions
Large diffs are not rendered by default.

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

Lines changed: 6128 additions & 0 deletions
Large diffs are not rendered by default.

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

Lines changed: 666 additions & 733 deletions
Large diffs are not rendered by default.

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

Lines changed: 664 additions & 892 deletions
Large diffs are not rendered by default.

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

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

src/Network/Network/Bastion/BastionBaseCmdlet.cs

Lines changed: 144 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,29 @@
1-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
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.
211
// See the License for the specific language governing permissions and
312
// limitations under the License.
413
// ----------------------------------------------------------------------------------
5-
using System;
6-
using System.Collections;
7-
using System.Collections.Generic;
8-
using System.Net;
9-
using AutoMapper;
10-
using Microsoft.Azure.Commands.Network.Models;
11-
using Microsoft.Azure.Commands.ResourceManager.Common.Tags;
12-
using Microsoft.Azure.Management.Network;
13-
using MNM = Microsoft.Azure.Management.Network.Models;
1414

1515
namespace Microsoft.Azure.Commands.Network.Bastion
1616
{
17+
using System;
18+
using System.Collections.Generic;
19+
using System.Net;
20+
21+
using Microsoft.Azure.Commands.Network.Models;
22+
using Microsoft.Azure.Commands.Network.Models.Bastion;
23+
using Microsoft.Azure.Commands.ResourceManager.Common.Tags;
24+
using Microsoft.Azure.Management.Network;
25+
using MNM = Management.Network.Models;
26+
1727
public abstract class BastionBaseCmdlet : NetworkBaseCmdlet
1828
{
1929
public IBastionHostsOperations BastionClient
@@ -46,20 +56,38 @@ public bool IsResourcePresent(string resourceGroupName, string name)
4656
{
4757
GetBastion(resourceGroupName, name);
4858
}
49-
catch (Microsoft.Rest.Azure.CloudException exception)
59+
catch (Rest.Azure.CloudException exception)
5060
{
5161
if (exception.Response.StatusCode == HttpStatusCode.NotFound)
5262
{
5363
// Resource is not present
5464
return false;
5565
}
56-
5766
throw;
5867
}
5968

6069
return true;
6170
}
6271

72+
public bool TryGetBastion(string resourceGroupName, string name, out PSBastion psBastion)
73+
{
74+
psBastion = null;
75+
try
76+
{
77+
psBastion = GetBastion(resourceGroupName, name);
78+
}
79+
catch (Rest.Azure.CloudException exception)
80+
{
81+
if (exception.Response.StatusCode == HttpStatusCode.NotFound)
82+
{
83+
// Resource is not present
84+
return false;
85+
}
86+
throw;
87+
}
88+
return true;
89+
}
90+
6391
public PSBastion GetBastion(string resourceGroupName, string name)
6492
{
6593
var bastion = this.BastionClient.Get(resourceGroupName, name);
@@ -69,6 +97,11 @@ public PSBastion GetBastion(string resourceGroupName, string name)
6997
psBastion.Sku.Name = bastion.Sku.Name;
7098
psBastion.ScaleUnit = bastion.ScaleUnits;
7199
psBastion.Tag = TagsConversionHelper.CreateTagHashtable(bastion.Tags);
100+
psBastion.EnableKerberos = bastion.EnableKerberos;
101+
psBastion.DisableCopyPaste = bastion.DisableCopyPaste;
102+
psBastion.EnableTunneling = bastion.EnableTunneling;
103+
psBastion.EnableIpConnect = bastion.EnableIpConnect;
104+
psBastion.EnableShareableLink = bastion.EnableShareableLink;
72105

73106
return psBastion;
74107
}
@@ -79,6 +112,11 @@ public PSBastion ToPsBastion(MNM.BastionHost host)
79112
bastion.Sku.Name = host.Sku.Name;
80113
bastion.ScaleUnit = host.ScaleUnits;
81114
bastion.Tag = TagsConversionHelper.CreateTagHashtable(host.Tags);
115+
bastion.EnableKerberos = bastion.EnableKerberos;
116+
bastion.DisableCopyPaste = host.DisableCopyPaste;
117+
bastion.EnableTunneling = host.EnableTunneling;
118+
bastion.EnableIpConnect = host.EnableIpConnect;
119+
bastion.EnableShareableLink = host.EnableShareableLink;
82120

83121
return bastion;
84122
}
@@ -95,12 +133,105 @@ public List<PSBastion> ListBastions(string resourceGroupName)
95133
foreach (MNM.BastionHost bastion in bastions)
96134
{
97135
PSBastion bastionToReturn = ToPsBastion(bastion);
98-
bastionToReturn.ResourceGroupName = NetworkBaseCmdlet.GetResourceGroup(bastion.Id);
136+
bastionToReturn.ResourceGroupName = GetResourceGroup(bastion.Id);
99137
bastionsToReturn.Add(bastionToReturn);
100138
}
101139
}
102140

103141
return bastionsToReturn;
104142
}
143+
144+
public bool IsSkuDowngrade(PSBastion bastion, string sku)
145+
{
146+
if (PSBastionSku.TryGetSkuTier(sku, out string newSkuTier)
147+
&& PSBastionSku.TryGetSkuTier(bastion.Sku.Name, out string existingSkuTier))
148+
{
149+
switch (existingSkuTier)
150+
{
151+
case PSBastionSku.Basic:
152+
return false;
153+
// Standard -> Basic
154+
case PSBastionSku.Standard:
155+
if (newSkuTier == PSBastionSku.Basic)
156+
{
157+
return true;
158+
}
159+
return false;
160+
default:
161+
return true;
162+
}
163+
}
164+
165+
return true;
166+
}
167+
168+
public void ValidateScaleUnits(PSBastion bastion, int? scaleUnits = 2)
169+
{
170+
if (PSBastionSku.TryGetSkuTier(bastion.Sku.Name, out string skuTierValue))
171+
{
172+
switch (skuTierValue)
173+
{
174+
case PSBastionSku.Basic:
175+
if (scaleUnits != PSBastion.MinimumScaleUnits)
176+
{
177+
throw new ArgumentException($"Bastion scalable host is available on Standard SKU");
178+
}
179+
break;
180+
case PSBastionSku.Standard:
181+
if (scaleUnits < PSBastion.MinimumScaleUnits
182+
|| scaleUnits > PSBastion.MaximumScaleUnits)
183+
{
184+
throw new ArgumentException($"Please select scale units value between {PSBastion.MinimumScaleUnits} and {PSBastion.MaximumScaleUnits}");
185+
}
186+
break;
187+
default:
188+
throw new ArgumentException($"Please enter a valid value for Bastion SKU");
189+
}
190+
}
191+
else
192+
{
193+
throw new ArgumentException($"Please enter a valid value for Bastion SKU");
194+
}
195+
}
196+
197+
public void ValidateFeatures(PSBastion bastion,
198+
bool? disableCopyPaste = false,
199+
bool? enableTunneling = false,
200+
bool? enableIpConnect = false,
201+
bool? enableShareableLink = false)
202+
{
203+
if (PSBastionSku.TryGetSkuTier(bastion.Sku.Name, out string skuTierValue))
204+
{
205+
switch (skuTierValue)
206+
{
207+
case PSBastionSku.Basic:
208+
if (disableCopyPaste != null && disableCopyPaste != false)
209+
{
210+
throw new ArgumentException($"Toggling copy/paste is available on Standard SKU or higher");
211+
}
212+
if (enableTunneling != null && enableTunneling != false)
213+
{
214+
throw new ArgumentException($"Toggling tunneling is available on Standard SKU or higher");
215+
}
216+
if (enableIpConnect != null && enableIpConnect != false)
217+
{
218+
throw new ArgumentException($"Toggling IP connect is available on Standard SKU or higher");
219+
}
220+
if (enableShareableLink != null && enableShareableLink != false)
221+
{
222+
throw new ArgumentException($"Toggling shareable link is available on Standard SKU or higher");
223+
}
224+
break;
225+
case PSBastionSku.Standard:
226+
break;
227+
default:
228+
throw new ArgumentException($"Please enter a valid value for Bastion SKU");
229+
}
230+
}
231+
else
232+
{
233+
throw new ArgumentException($"Please enter a valid value for Bastion SKU");
234+
}
235+
}
105236
}
106237
}

src/Network/Network/Bastion/GetAzBastionCommand.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,16 @@
1212
// limitations under the License.
1313
// ----------------------------------------------------------------------------------
1414

15-
1615
namespace Microsoft.Azure.Commands.Network.Bastion
1716
{
17+
using System;
18+
using System.Collections.Generic;
19+
using System.Management.Automation;
20+
1821
using Microsoft.Azure.Commands.Network.Models;
1922
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
2023
using Microsoft.Azure.Management.Internal.Resources.Utilities.Models;
2124
using Microsoft.Azure.Management.Network.Models;
22-
using System;
23-
using System.Collections.Generic;
24-
using System.Management.Automation;
2525

2626
[Cmdlet(VerbsCommon.Get,
2727
ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "Bastion",
@@ -66,14 +66,14 @@ public override void Execute()
6666
{
6767
WriteObject(this.GetBastion(this.ResourceGroupName, this.Name));
6868
}
69-
else if ((ParameterSetName.Equals(BastionParameterSetNames.ByResourceId, StringComparison.OrdinalIgnoreCase)))
69+
else if (ParameterSetName.Equals(BastionParameterSetNames.ByResourceId, StringComparison.OrdinalIgnoreCase))
7070
{
7171
var parsedResourceId = new ResourceIdentifier(this.ResourceId);
7272
this.Name = parsedResourceId.ResourceName;
7373
this.ResourceGroupName = parsedResourceId.ResourceGroupName;
7474
WriteObject(this.GetBastion(this.ResourceGroupName, this.Name));
7575
}
76-
else
76+
else
7777
{
7878
WriteObject(TopLevelWildcardFilter(ResourceGroupName, Name, this.ListBastions(this.ResourceGroupName)), true);
7979
}

0 commit comments

Comments
 (0)