diff --git a/src/Aks/Aks/ChangeLog.md b/src/Aks/Aks/ChangeLog.md index a2686935fdaf..c9c8c7b887a2 100644 --- a/src/Aks/Aks/ChangeLog.md +++ b/src/Aks/Aks/ChangeLog.md @@ -18,6 +18,7 @@ - Additional information about change #1 --> ## Upcoming Release +* Added client side parameter validation logic for `New-AzAksCluster`, `Set-AzAksCluster` and `New-AzAksNodePool`. * Added parameter `GenerateSshKey` for `New-AzAksCluster`. * Updated api version to 2020-06-01. diff --git a/src/Aks/Aks/Commands/CreateOrUpdateKubeBase.cs b/src/Aks/Aks/Commands/CreateOrUpdateKubeBase.cs index 3e1790a4f93e..d21997cf3f60 100644 --- a/src/Aks/Aks/Commands/CreateOrUpdateKubeBase.cs +++ b/src/Aks/Aks/Commands/CreateOrUpdateKubeBase.cs @@ -83,7 +83,7 @@ public abstract class CreateOrUpdateKubeBase : KubeCmdletBase [Alias("AdminUserName")] public string LinuxProfileAdminUserName { get; set; } = "azureuser"; - [Parameter(Mandatory = false, HelpMessage = "The DNS name prefix for the cluster.")] + [Parameter(Mandatory = false, HelpMessage = "The DNS name prefix for the cluster. The length must be <= 9 if users plan to add windows container.")] public string DnsNamePrefix { get; set; } [Parameter(Mandatory = false, HelpMessage = "The version of Kubernetes to use for creating the cluster.")] diff --git a/src/Aks/Aks/Commands/NewAzureRmAks.cs b/src/Aks/Aks/Commands/NewAzureRmAks.cs index 06fa194bb3a2..f465a7aa694d 100644 --- a/src/Aks/Aks/Commands/NewAzureRmAks.cs +++ b/src/Aks/Aks/Commands/NewAzureRmAks.cs @@ -85,7 +85,26 @@ private void PreValidate() if (this.IsParameterBound(c => c.GenerateSshKey) && this.IsParameterBound(c => c.SshKeyValue)) { - throw new ArgumentException(string.Format(Resources.DonotUseGenerateSshKeyWithSshKeyValue)); + throw new ArgumentException(Resources.DonotUseGenerateSshKeyWithSshKeyValue); + } + + if ((this.IsParameterBound(c => c.WindowsProfileAdminUserName) && !this.IsParameterBound(c => c.WindowsProfileAdminUserPassword)) || + (!this.IsParameterBound(c => c.WindowsProfileAdminUserName) && this.IsParameterBound(c => c.WindowsProfileAdminUserPassword))) + { + throw new ArgumentException(Resources.WindowsUserNameAndPasswordShouldAppearTogether); + } + + if (this.IsParameterBound(c => c.WindowsProfileAdminUserName)) + { + if (!string.Equals(this.NetworkPlugin, "azure")) + { + throw new ArgumentException(Resources.NetworkPluginShouldBeAzure); + } + } + if (string.Equals(this.NodeOsType, "Windows")) + { + if (NodeName?.Length > 6) + throw new PSInvalidOperationException(Resources.WindowsNodePoolNameLengthLimitation); } } diff --git a/src/Aks/Aks/Commands/NewKubeBase.cs b/src/Aks/Aks/Commands/NewKubeBase.cs index 5ede0ac7cd30..5d61ed7960dc 100644 --- a/src/Aks/Aks/Commands/NewKubeBase.cs +++ b/src/Aks/Aks/Commands/NewKubeBase.cs @@ -17,6 +17,7 @@ using System.Management.Automation; using System.Security; using Microsoft.Azure.Commands.Aks.Properties; +using Microsoft.Azure.Commands.Aks.Utils; using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters; using Microsoft.Azure.Commands.ResourceManager.Common.Tags; using Microsoft.Azure.Management.ContainerService.Models; @@ -97,6 +98,7 @@ public abstract class NewKubeBase : CreateOrUpdateKubeBase [Parameter(Mandatory = false, HelpMessage = "The administrator password to use for Windows VMs. Password requirement:" + "At least one lower case, one upper case, one special character !@#$%^&*(), the minimum lenth is 12.")] + [ValidateSecureString(RegularExpression = "^(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%\\^&\\*\\(\\)])[a-zA-Z\\d!@#$%\\^&\\*\\(\\)]{12,123}$")] public SecureString WindowsProfileAdminUserPassword { get; set; } [CmdletParameterBreakingChange("NetworkPlugin", ChangeDescription = "Default value will be changed from None to azure.")] diff --git a/src/Aks/Aks/Properties/Resources.Designer.cs b/src/Aks/Aks/Properties/Resources.Designer.cs index 96e4506c25ef..73e735322239 100644 --- a/src/Aks/Aks/Properties/Resources.Designer.cs +++ b/src/Aks/Aks/Properties/Resources.Designer.cs @@ -429,6 +429,15 @@ internal static string LocationCannotBeUpdateForExistingCluster { } } + /// + /// Looks up a localized string similar to NetworkPlugin must be azure if you want to use Windows.. + /// + internal static string NetworkPluginShouldBeAzure { + get { + return ResourceManager.GetString("NetworkPluginShouldBeAzure", resourceCulture); + } + } + /// /// Looks up a localized string similar to No config file located at {0}. Creating Kube config.. /// @@ -564,6 +573,15 @@ internal static string RunningKubectlGetPodsKubeconfigNamespaceSelector { } } + /// + /// Looks up a localized string similar to Plain text of SecureString should match the patten {0}.. + /// + internal static string SecureStringNotValid { + get { + return ResourceManager.GetString("SecureStringNotValid", resourceCulture); + } + } + /// /// Looks up a localized string similar to Service Principal Create. /// @@ -851,5 +869,14 @@ internal static string WindowsNodePoolNameLengthLimitation { return ResourceManager.GetString("WindowsNodePoolNameLengthLimitation", resourceCulture); } } + + /// + /// Looks up a localized string similar to WindowsProfileAdminUser and WindowsProfileAdminUserPassword must appear together.. + /// + internal static string WindowsUserNameAndPasswordShouldAppearTogether { + get { + return ResourceManager.GetString("WindowsUserNameAndPasswordShouldAppearTogether", resourceCulture); + } + } } } diff --git a/src/Aks/Aks/Properties/Resources.resx b/src/Aks/Aks/Properties/Resources.resx index c38c4b40ac3c..c1ffa9b1b0c9 100644 --- a/src/Aks/Aks/Properties/Resources.resx +++ b/src/Aks/Aks/Properties/Resources.resx @@ -381,4 +381,13 @@ Updating NodePoolMode. + + Plain text of SecureString should match the patten {0}. + + + WindowsProfileAdminUser and WindowsProfileAdminUserPassword must appear together. + + + NetworkPlugin must be azure if you want to use Windows. + \ No newline at end of file diff --git a/src/Aks/Aks/Utils/ValidateSecureString.cs b/src/Aks/Aks/Utils/ValidateSecureString.cs new file mode 100644 index 000000000000..ad6945600d54 --- /dev/null +++ b/src/Aks/Aks/Utils/ValidateSecureString.cs @@ -0,0 +1,42 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + + +using Microsoft.Azure.Commands.Aks.Properties; +using Microsoft.WindowsAzure.Commands.Common; + +using System; +using System.Management.Automation; +using System.Runtime.InteropServices; +using System.Security; +using System.Text.RegularExpressions; + +namespace Microsoft.Azure.Commands.Aks.Utils +{ + public sealed class ValidateSecureString: ValidateEnumeratedArgumentsAttribute + { + public string RegularExpression { get; set; } + + protected override void ValidateElement(object element) + { + SecureString secureString = element as SecureString; + string content = secureString.ConvertToString(); + Regex regex = new Regex(RegularExpression); + if (!regex.IsMatch(content)) + { + throw new ArgumentException(string.Format(Resources.SecureStringNotValid, RegularExpression)); + } + } + } +} diff --git a/src/Aks/Aks/help/New-AzAksCluster.md b/src/Aks/Aks/help/New-AzAksCluster.md index 67dc170e0caa..0e7392239943 100644 --- a/src/Aks/Aks/help/New-AzAksCluster.md +++ b/src/Aks/Aks/help/New-AzAksCluster.md @@ -13,15 +13,15 @@ Create a new managed Kubernetes cluster. ## SYNTAX ``` -New-AzAksCluster [-Force] [-NodeVmSetType ] [-NodeVnetSubnetID ] [-NodeMaxPodCount ] - [-NodeOsType ] [-NodeSetPriority ] [-NodePoolMode ] +New-AzAksCluster [-Force] [-GenerateSshKey] [-NodeVmSetType ] [-NodeVnetSubnetID ] + [-NodeMaxPodCount ] [-NodeOsType ] [-NodeSetPriority ] [-NodePoolMode ] [-NodeScaleSetEvictionPolicy ] [-AcrNameToAttach ] [-EnableRbac] [-WindowsProfileAdminUserName ] [-WindowsProfileAdminUserPassword ] [-NetworkPlugin ] [-LoadBalancerSku ] [-ResourceGroupName] [-Name] [[-ServicePrincipalIdAndSecret] ] [-Location ] [-LinuxProfileAdminUserName ] [-DnsNamePrefix ] [-KubernetesVersion ] [-NodeName ] [-NodeMinCount ] [-NodeMaxCount ] [-EnableNodeAutoScaling] [-NodeCount ] [-NodeOsDiskSize ] - [-NodeVmSize ] [-SshKeyValue ] [-GenerateSshKey] [-AsJob] [-Tag ] + [-NodeVmSize ] [-SshKeyValue ] [-AsJob] [-Tag ] [-DefaultProfile ] [-WhatIf] [-Confirm] [] ``` @@ -95,7 +95,7 @@ Accept wildcard characters: False ``` ### -DnsNamePrefix -The DNS name prefix for the cluster. +The DNS name prefix for the cluster. The length must be <= 9 if users plan to add windows container. ```yaml Type: System.String