Skip to content

Commit

Permalink
Merge pull request #30 from AzCiS/set-assvd-new-params
Browse files Browse the repository at this point in the history
Add new params to SetASSVirtualDevice for snapshot mgr passwd and admin ...
  • Loading branch information
parvezah committed Mar 25, 2015
2 parents d860931 + 7ff6564 commit e1c3bcb
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,76 +31,77 @@ public class NewAzureStorSimpleNetworkConfig : StorSimpleCmdletBase
{
#region Parameters

/// <summary>
/// Interface alias of interface for which settings are being supplied. A value
/// from Data0 to Data5
/// </summary>
[Parameter(Mandatory = true, Position = 0, HelpMessage = StorSimpleCmdletHelpMessage.InterfaceAlias)]
[ValidateSetAttribute(new string[] { "Data0", "Data1", "Data2", "Data3", "Data4", "Data5" })]
public string InterfaceAlias { get; set; }

/// <summary>
/// Whether the net interface is iscsi enabled/disabled
/// </summary>
[Parameter(Mandatory=false, Position = 0, HelpMessage = StorSimpleCmdletHelpMessage.IsIscsiEnabled)]
[Parameter(Mandatory=false, Position = 1, HelpMessage = StorSimpleCmdletHelpMessage.IsIscsiEnabled)]
[ValidateNotNullOrEmpty]
public bool? EnableIscsi { get; set; }

/// <summary>
/// Whether the net interface is cloud enabled/disabled
/// </summary>
[Parameter(Mandatory = false, Position = 1, HelpMessage = StorSimpleCmdletHelpMessage.IsCloudEnabled)]
[Parameter(Mandatory = false, Position = 2, HelpMessage = StorSimpleCmdletHelpMessage.IsCloudEnabled)]
[ValidateNotNullOrEmpty]
public bool? EnableCloud { get; set; }

/// <summary>
/// IPv4Address for controller 0, should be used only with Data0 interface
/// </summary>
[Parameter(Mandatory = false, Position = 2, HelpMessage = StorSimpleCmdletHelpMessage.Controller0IPv4Address)]
[Parameter(Mandatory = false, Position = 3, HelpMessage = StorSimpleCmdletHelpMessage.Controller0IPv4Address)]
[ValidateNotNullOrEmpty]
public string Controller0IPv4Address { get; set; }

/// <summary>
/// IPv4Address for controller 1, should be used only with Data0 interface
/// </summary>
[Parameter(Mandatory = false, Position = 3, HelpMessage = StorSimpleCmdletHelpMessage.Controller1IPv4Address)]
[Parameter(Mandatory = false, Position = 4, HelpMessage = StorSimpleCmdletHelpMessage.Controller1IPv4Address)]
[ValidateNotNullOrEmpty]
public string Controller1IPv4Address { get; set; }

/// <summary>
/// IPv4 net mask for interface
/// </summary>
[Parameter(Mandatory = false, Position = 4, HelpMessage = StorSimpleCmdletHelpMessage.IPv6Gateway)]
[Parameter(Mandatory = false, Position = 5, HelpMessage = StorSimpleCmdletHelpMessage.IPv6Gateway)]
[ValidateNotNullOrEmpty]
public string IPv6Gateway { get; set; }

/// <summary>
/// IPv4 Address of gateway
/// </summary>
[Parameter(Mandatory = false, Position = 5, HelpMessage = StorSimpleCmdletHelpMessage.IPv4Gateway)]
[Parameter(Mandatory = false, Position = 6, HelpMessage = StorSimpleCmdletHelpMessage.IPv4Gateway)]
[ValidateNotNullOrEmpty]
public string IPv4Gateway { get; set; }

/// <summary>
/// IPv4 Address for the net interface
/// </summary>
[Parameter(Mandatory = false, Position = 6, HelpMessage = StorSimpleCmdletHelpMessage.IPv4Address)]
[Parameter(Mandatory = false, Position = 7, HelpMessage = StorSimpleCmdletHelpMessage.IPv4Address)]
[ValidateNotNullOrEmpty]
public string IPv4Address { get; set; }

/// <summary>
/// IPv6 Prefix for the net interface
/// </summary>
[Parameter(Mandatory = false, Position = 7, HelpMessage = StorSimpleCmdletHelpMessage.IPv6Prefix)]
[Parameter(Mandatory = false, Position = 8, HelpMessage = StorSimpleCmdletHelpMessage.IPv6Prefix)]
[ValidateNotNullOrEmpty]
public string IPv6Prefix { get; set; }

/// <summary>
/// IPv4 netmask for this interface
/// </summary>
[Parameter(Mandatory = false, Position = 8, HelpMessage = StorSimpleCmdletHelpMessage.IPv4Netmask)]
[Parameter(Mandatory = false, Position = 9, HelpMessage = StorSimpleCmdletHelpMessage.IPv4Netmask)]
[ValidateNotNullOrEmpty]
public string IPv4Netmask { get; set; }

/// <summary>
/// Interface alias of interface for which settings are being supplied. A value
/// from Data0 to Data5
/// </summary>
[Parameter(Mandatory = true, Position = 9, HelpMessage = StorSimpleCmdletHelpMessage.InterfaceAlias)]
[ValidateSetAttribute(new string[] { "Data0", "Data1", "Data2", "Data3", "Data4", "Data5" })]
public string InterfaceAlias { get; set; }
#endregion

private IPAddress controller0Address;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,25 +38,41 @@ public class SetAzureStorSimpleVirtualDevice : StorSimpleCmdletBase
[Parameter(Mandatory = true, Position = 0, HelpMessage = StorSimpleCmdletHelpMessage.DeviceName)]
[ValidateNotNullOrEmpty]
public string DeviceName { get; set; }

/// <summary>
/// TimeZone for the device.
/// </summary>
[Parameter(Mandatory = false, Position = 1, HelpMessage = StorSimpleCmdletHelpMessage.TimeZone, ValueFromPipeline=true)]
[ValidateNotNullOrEmpty]
public TimeZoneInfo TimeZone { get; set; }

/// <summary>
/// Service Encryption Key for the resource.
/// </summary>
[Parameter(Mandatory=true, Position = 2, HelpMessage = StorSimpleCmdletHelpMessage.SEK)]
[Parameter(Mandatory=true, Position = 1, HelpMessage = StorSimpleCmdletHelpMessage.SEK)]
[ValidateNotNullOrEmpty]
public string SecretKey { get; set; }

/// <summary>
/// Device administrator password
/// </summary>
[Parameter(Mandatory=true, Position=2, HelpMessage = StorSimpleCmdletHelpMessage.AdministratorPasswd)]
[ValidateNotNullOrEmpty]
public string AdministratorPassword { get; set; }

/// <summary>
/// Snapshot manager password
/// </summary>
[Parameter(Mandatory=true, Position=3, HelpMessage=StorSimpleCmdletHelpMessage.SnapshotManagerPasswd)]
[ValidateNotNullOrEmpty]
public string SnapshotManagerPassword { get; set; }

/// <summary>
/// TimeZone for the device.
/// </summary>
[Parameter(Mandatory = false, Position = 4, HelpMessage = StorSimpleCmdletHelpMessage.TimeZone, ValueFromPipeline = true)]
[ValidateNotNullOrEmpty]
public TimeZoneInfo TimeZone { get; set; }

public override void ExecuteCmdlet()
{
try
{
ValidateParams();

// Make sure we have a device for supplied name and get its device id.
var deviceId = StorSimpleClient.GetDeviceId(DeviceName);
if (deviceId == null)
Expand All @@ -73,7 +89,8 @@ public override void ExecuteCmdlet()
string cik = EncryptionCmdLetHelper.RetrieveCIK(this, StorSimpleContext.ResourceId);

// Update device details.
StorSimpleClient.UpdateVirtualDeviceDetails(deviceDetails, TimeZone, SecretKey, cik);
var cryptoManager = new StorSimpleCryptoManager(StorSimpleClient);
StorSimpleClient.UpdateVirtualDeviceDetails(deviceDetails, TimeZone, SecretKey, AdministratorPassword, SnapshotManagerPassword, cik, cryptoManager);

// Make request with updated data
WriteVerbose(string.Format(Resources.BeginningDeviceConfiguration, deviceDetails.DeviceProperties.FriendlyName));
Expand All @@ -92,7 +109,17 @@ public override void ExecuteCmdlet()
this.HandleException(exception);
}
}


/// <summary>
///
/// </summary>
/// <returns></returns>
private void ValidateParams() {
ValidateLength(AdministratorPassword, 8, 15, Resources.AdminPasswordLengthError);
ValidateLength(SnapshotManagerPassword, 14, 15, Resources.SnapshotPasswordLengthError);
ValidatePasswordComplexity(AdministratorPassword, "AdministratorPassword");
ValidatePasswordComplexity(SnapshotManagerPassword, "SnapshotManagerPassword");
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,21 @@
<data name="CIKInvalidWithException" xml:space="preserve">
<value>Invalid value for Registration Key. CIK provided couldnt be used to decrypt the secrets! The exact exception while decrypting is "{0}"!</value>
</data>
<data name="PasswordCharacterCriteriaError" xml:space="preserve">
<value>{0} is not complex enough. It must contain 3 of the following:
a lowercase character
an uppercase character
a number
a special character</value>
</data>
<data name="AdminPasswordLengthError" xml:space="preserve">
<value>The AdministratorPassword must be between 8 to 15 characters.</value>
</data>
<data name="SnapshotPasswordLengthError" xml:space="preserve">
<value>The SnapshotManagerPassword must be either 14 or 15 characters long</value>
</data>
<data name="SetAzureStorSimpleDeviceNoSettingsProvided" xml:space="preserve">
<value>No settings were provided for updating device details.</value>

</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ private void UpdateDeviceDetailsObject(DeviceDetails deviceDetails, string newNa
deviceDetails.WebProxy = null;
}

public void UpdateVirtualDeviceDetails(DeviceDetails details, TimeZoneInfo timeZone, string sek, string cik)
public void UpdateVirtualDeviceDetails(DeviceDetails details, TimeZoneInfo timeZone, string sek, string adminPasswd, string snapshotPasswd, string cik, StorSimpleCryptoManager cryptoManager)
{
if (timeZone != null)
{
Expand All @@ -215,10 +215,20 @@ public void UpdateVirtualDeviceDetails(DeviceDetails details, TimeZoneInfo timeZ

// Also set the CIK before making the request - service needs it.
var encryptedCik = this.EncryptWithDevicePublicKey(details.DeviceProperties.DeviceId, cik);

details.VirtualApplianceProperties.EncodedChannelIntegrityKey = encryptedCik;

details.VirtualApplianceProperties.IsServiceEncryptionKeySet = true;
// Set the admin password
string encryptedAdminPasswd = null;
cryptoManager.EncryptSecretWithRakPub(adminPasswd, out encryptedAdminPasswd);
details.RemoteMinishellSecretInfo.MinishellSecret = encryptedAdminPasswd;

// Set the snapshot manager password
string encryptedSnapshotManagerPasswd = null;
cryptoManager.EncryptSecretWithRakPub(snapshotPasswd, out encryptedSnapshotManagerPasswd);
details.Snapshot.SnapshotSecret = encryptedSnapshotManagerPasswd;

// Set the cert thumbprint for the key used.
details.SecretEncryptionCertThumbprint = cryptoManager.GetSecretsEncryptionThumbprint();

// mark everything that we dont intend to modify as null - indicating
// to the service that there has been no change
Expand All @@ -227,9 +237,6 @@ public void UpdateVirtualDeviceDetails(DeviceDetails details, TimeZoneInfo timeZ
details.DnsServer = null;
details.NetInterfaceList = null;
details.RemoteMgmtSettingsInfo = null;
details.RemoteMinishellSecretInfo = null;
details.SecretEncryptionCertThumbprint = null;
details.Snapshot = null;
details.WebProxy = null;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -518,5 +518,56 @@ internal bool IsValidAsciiString(string s)
{
return Regex.IsMatch(s, "[ -~]+");
}

/// <summary>
/// Validate that the string provided has length within the specified constraints.
///
/// Throws an ArgumentException with the specified error message if the validation fails.
/// </summary>
/// <param name="data">string to be validated</param>
/// <param name="minLength">minimum allowable length for the string</param>
/// <param name="maxLength">maximum allowable length for the string</param>
/// <param name="errorMessage">error message for the exception raised in case of invalid data</param>
internal void ValidateLength(string data, uint minLength, uint maxLength, string errorMessage)
{
if (data.Length < minLength || data.Length > maxLength)
{
throw new ArgumentException(errorMessage);
}
}

/// <summary>
/// Most of the passwords in the device must contain 3 of the following:
/// - a lowercase character
/// - an uppercase character
/// - a number
/// - a special character
///
/// Raises an ArgumentException with appropriate error message notifying the above
/// conditions when the validation fails.
/// </summary>
/// <param name="data"></param>
internal void ValidatePasswordComplexity(string data, string passwordName)
{
string errorMessage = string.Format(Resources.PasswordCharacterCriteriaError, passwordName);
var criteriaFulfilled = 0;
// Regular expressions for lowercase letter, uppercase letter, digit and special char
// respectively
string[] criteriaRegexs = { ".*[a-z]", ".*[A-Z]", ".*\\d", ".*\\W" };

foreach(var regexStr in criteriaRegexs){
// The static IsMatch method is supposed to use an Application-wide cache of compiled regexes
// and hence should save computation time (though not very significant because we are not doing tens of
// thousands of such tests)
if(Regex.IsMatch(data, regexStr)){
criteriaFulfilled += 1;
}
}

// If atleast 3 criteria have been fulfilled, then the password is complex enough
if(criteriaFulfilled < 3){
throw new ArgumentException(errorMessage);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ internal static class StorSimpleCmdletHelpMessage
public const string ToTime = "End of time interval for which to filter results.";
public const string DeviceJobStatus = "Status of job.";
public const string DeviceJobType = "Type of job.";

public const string AdministratorPasswd = "Administrator password for the device.";
public const string SnapshotManagerPasswd = "Password for snapshot manager";
}
}

0 comments on commit e1c3bcb

Please sign in to comment.