diff --git a/src/Aks/Aks/ChangeLog.md b/src/Aks/Aks/ChangeLog.md index c3594c5b4e5d..a2686935fdaf 100644 --- a/src/Aks/Aks/ChangeLog.md +++ b/src/Aks/Aks/ChangeLog.md @@ -18,7 +18,8 @@ - Additional information about change #1 --> ## Upcoming Release -* Update api version to 2020-06-01. +* Added parameter `GenerateSshKey` for `New-AzAksCluster`. +* Updated api version to 2020-06-01. ## Version 1.2.0 * Removed `ClientIdAndSecret` to `ServicePrincipalIdAndSecret` and set `ClientIdAndSecret` as an alias [#12381]. diff --git a/src/Aks/Aks/Commands/NewAzureRmAks.cs b/src/Aks/Aks/Commands/NewAzureRmAks.cs index 9066d99aec6f..06fa194bb3a2 100644 --- a/src/Aks/Aks/Commands/NewAzureRmAks.cs +++ b/src/Aks/Aks/Commands/NewAzureRmAks.cs @@ -13,7 +13,11 @@ // ---------------------------------------------------------------------------------- using System; +using System.Diagnostics; +using System.IO; using System.Management.Automation; +using System.Runtime.InteropServices; + using Microsoft.Azure.Commands.Aks.Models; using Microsoft.Azure.Commands.Aks.Properties; using Microsoft.Azure.Management.ContainerService; @@ -31,10 +35,16 @@ public class NewAzureRmAks : NewKubeBase [Parameter(Mandatory = false, HelpMessage = "Create cluster even if it already exists")] public SwitchParameter Force { get; set; } + [Parameter( + Mandatory = false, + HelpMessage = "Generate ssh key file to {HOME}/.ssh/id_rsa.")] + public SwitchParameter GenerateSshKey { get; set; } + public override void ExecuteCmdlet() { base.ExecuteCmdlet(); PreValidate(); + PrepareParameter(); Action action = () => { @@ -72,6 +82,76 @@ private void PreValidate() if ((this.IsParameterBound(c => c.NodeMinCount) || this.IsParameterBound(c => c.NodeMaxCount) || this.EnableNodeAutoScaling.IsPresent) && !(this.IsParameterBound(c => c.NodeMinCount) && this.IsParameterBound(c => c.NodeMaxCount) && this.EnableNodeAutoScaling.IsPresent)) throw new PSInvalidCastException(Resources.AksNodePoolAutoScalingParametersMustAppearTogether); + + if (this.IsParameterBound(c => c.GenerateSshKey) && this.IsParameterBound(c => c.SshKeyValue)) + { + throw new ArgumentException(string.Format(Resources.DonotUseGenerateSshKeyWithSshKeyValue)); + } + } + + private void VerifySshKeyGenBinaryExist() + { + using (Process process = new Process()) + { + if ((RuntimeInformation.IsOSPlatform(OSPlatform.Windows))) + { + process.StartInfo.FileName = "where.exe"; + } + else + { + process.StartInfo.FileName = "whereis"; + } + process.StartInfo.Arguments = "ssh-keygen"; + process.StartInfo.UseShellExecute = false; + process.StartInfo.RedirectStandardOutput = true; + + process.Start(); + process.WaitForExit(); + + string result = process.StandardOutput.ReadLine(); + if (result.Contains("not found") || result.Contains("Could not find") || result.Trim().Equals("ssh-keygen:")) + { + throw new ArgumentException(Resources.EnableSsh); + } + + if (process.ExitCode != 0) + { + throw new ArgumentException(Resources.EnableSsh); + } + } + } + + private string GenerateSshKeyValue() + { + VerifySshKeyGenBinaryExist(); + String generateSshKeyPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".ssh", "id_rsa"); ; + if (File.Exists(generateSshKeyPath)) + { + throw new ArgumentException(string.Format(Resources.DefaultSshKeyAlreadyExist)); + } + using (Process process = new Process()) + { + process.StartInfo.FileName = "ssh-keygen"; + process.StartInfo.Arguments = String.Format("-f \"{0}\"", generateSshKeyPath); + process.StartInfo.UseShellExecute = false; + process.StartInfo.RedirectStandardInput = true; + process.StartInfo.RedirectStandardError = true; + process.StartInfo.RedirectStandardOutput = true; + process.Start(); + + Console.WriteLine(process.StandardOutput.ReadToEnd()); + + process.WaitForExit(); + } + return GetSshKey(generateSshKeyPath); + } + + protected void PrepareParameter() + { + if (this.IsParameterBound(c => c.GenerateSshKey)) + { + SshKeyValue = GenerateSshKeyValue(); + } } } } diff --git a/src/Aks/Aks/Properties/Resources.Designer.cs b/src/Aks/Aks/Properties/Resources.Designer.cs index 06616ab4d154..96e4506c25ef 100644 --- a/src/Aks/Aks/Properties/Resources.Designer.cs +++ b/src/Aks/Aks/Properties/Resources.Designer.cs @@ -240,6 +240,15 @@ internal static string CreatingClusterAgentPool { } } + /// + /// Looks up a localized string similar to Default ssh key already exists. Please use -SshKeyVaule.. + /// + internal static string DefaultSshKeyAlreadyExist { + get { + return ResourceManager.GetString("DefaultSshKeyAlreadyExist", resourceCulture); + } + } + /// /// Looks up a localized string similar to Deploying your managed Kubernetes cluster.. /// @@ -258,6 +267,15 @@ internal static string DidNotFindJob { } } + /// + /// Looks up a localized string similar to Don't use -GenerateSshKey and -SshKeyVaule at the same time.. + /// + internal static string DonotUseGenerateSshKeyWithSshKeyValue { + get { + return ResourceManager.GetString("DonotUseGenerateSshKeyWithSshKeyValue", resourceCulture); + } + } + /// /// Looks up a localized string similar to Downloading kubectl from internet. /// @@ -321,6 +339,15 @@ internal static string DoYouWantToOverwriteExistingFile { } } + /// + /// Looks up a localized string similar to Cannot find ssh-keygen. Please enable OpenSSH on your local machine.. + /// + internal static string EnableSsh { + get { + return ResourceManager.GetString("EnableSsh", resourceCulture); + } + } + /// /// Looks up a localized string similar to Fetching the clusterAdmin kubectl config. /// diff --git a/src/Aks/Aks/Properties/Resources.resx b/src/Aks/Aks/Properties/Resources.resx index ce15b6db3778..c38c4b40ac3c 100644 --- a/src/Aks/Aks/Properties/Resources.resx +++ b/src/Aks/Aks/Properties/Resources.resx @@ -369,6 +369,15 @@ Windows agent pool name can not be longer than 6 characters. + + Don't use -GenerateSshKey and -SshKeyVaule at the same time. + + + Default ssh key already exists. Please use -SshKeyVaule. + + + Cannot find ssh-keygen. Please enable OpenSSH on your local machine. + Updating NodePoolMode. diff --git a/src/Aks/Aks/help/Az.Aks.md b/src/Aks/Aks/help/Az.Aks.md index 7d6121602855..2d1031952943 100644 --- a/src/Aks/Aks/help/Az.Aks.md +++ b/src/Aks/Aks/help/Az.Aks.md @@ -49,3 +49,4 @@ Stop the Kubectl SSH tunnel created in Start-AzKubernetesDashboard. ### [Update-AzAksNodePool](Update-AzAksNodePool.md) Update node pool in a managed cluster. + diff --git a/src/Aks/Aks/help/New-AzAksCluster.md b/src/Aks/Aks/help/New-AzAksCluster.md index d5fc06f482b4..67dc170e0caa 100644 --- a/src/Aks/Aks/help/New-AzAksCluster.md +++ b/src/Aks/Aks/help/New-AzAksCluster.md @@ -21,7 +21,7 @@ New-AzAksCluster [-Force] [-NodeVmSetType ] [-NodeVnetSubnetID ] [[-ServicePrincipalIdAndSecret] ] [-Location ] [-LinuxProfileAdminUserName ] [-DnsNamePrefix ] [-KubernetesVersion ] [-NodeName ] [-NodeMinCount ] [-NodeMaxCount ] [-EnableNodeAutoScaling] [-NodeCount ] [-NodeOsDiskSize ] - [-NodeVmSize ] [-SshKeyValue ] [-AsJob] [-Tag ] + [-NodeVmSize ] [-SshKeyValue ] [-GenerateSshKey] [-AsJob] [-Tag ] [-DefaultProfile ] [-WhatIf] [-Confirm] [] ``` @@ -154,6 +154,21 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -GenerateSshKey +Generate ssh key file to {HOME}/.ssh/id_rsa. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -KubernetesVersion The version of Kubernetes to use for creating the cluster.