Skip to content

Commit

Permalink
Merge branch 'dev' into DontPackageLogs
Browse files Browse the repository at this point in the history
  • Loading branch information
Ted Glaza committed Jan 13, 2012
2 parents 306d5bd + 8605861 commit 35a3c03
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
// 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 AzureDeploymentCmdlets.Model;
using AzureDeploymentCmdlets.Test.Utilities;
// ----------------------------------------------------------------------------------

using System;
using AzureDeploymentCmdlets.Model;
using AzureDeploymentCmdlets.Test.Utilities;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;

namespace AzureDeploymentCmdlets.Test.Tests.Model
{
Expand All @@ -27,6 +27,49 @@ public void ServiceSettingsTest()
{
ServiceSettings settings = new ServiceSettings();
AzureAssert.AreEqualServiceSettings(string.Empty, string.Empty, string.Empty, string.Empty, settings);
}

/// <summary>
/// Verify that using an invalid storage account name throws an
/// exception.
/// </summary>
[TestMethod]
public void InvalidStorageAccountName()
{
// Create a temp directory that we'll use to "publish" our service
using (FileSystemHelper files = new FileSystemHelper(this) { EnableMonitoring = true })
{
// Import our default publish settings
files.CreateAzureSdkDirectoryAndImportPublishSettings();

string serviceName = null;
Testing.AssertThrows<ArgumentException>(() =>
ServiceSettings.LoadDefault(null, null, null, null, "I HAVE INVALID CHARACTERS !@#$%", null, null, out serviceName));
Testing.AssertThrows<ArgumentException>(() =>
ServiceSettings.LoadDefault(null, null, null, null, "ihavevalidcharsbutimjustwaytooooooooooooooooooooooooooooooooooooooooolong", null, null, out serviceName));
}
}

/// <summary>
/// Verify that a service name with invalid characters is correctly
/// sanitized to a storage account name.
/// </summary>
[TestMethod]
public void SanitizeServiceNameForStorageAccountName()
{
// Create a temp directory that we'll use to "publish" our service
using (FileSystemHelper files = new FileSystemHelper(this) { EnableMonitoring = true })
{
// Import our default publish settings
files.CreateAzureSdkDirectoryAndImportPublishSettings();

string serviceName = null;
ServiceSettings settings = ServiceSettings.LoadDefault(null, null, null, null, null, "My-Custom-Service!", null, out serviceName);
Assert.AreEqual("myx2dcustomx2dservicex21", settings.StorageAccountName);

settings = ServiceSettings.LoadDefault(null, null, null, null, null, "MyCustomServiceIsWayTooooooooooooooooooooooooLong", null, out serviceName);
Assert.AreEqual("mycustomserviceiswaytooo", settings.StorageAccountName);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,33 @@
// 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 System;
using System.IO;
using AzureDeploymentCmdlets.Properties;
// ----------------------------------------------------------------------------------

using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Web.Script.Serialization;
using AzureDeploymentCmdlets.Properties;
using AzureDeploymentCmdlets.Utilities;
using System.Web.Script.Serialization;

namespace AzureDeploymentCmdlets.Model
{
public class ServiceSettings
{
{
/// <summary>
/// Minimum length of a valid storage account name.
/// http://msdn.microsoft.com/en-us/library/windowsazure/hh264518.aspx
/// </summary>
private const int MinimumStorageAccountNameLength = 3;

/// <summary>
/// Maximum length of a valid storage account name.
/// http://msdn.microsoft.com/en-us/library/windowsazure/hh264518.aspx
/// </summary>
private const int MaximumStorageAccountNameLength = 24;

// Flag indicating whether the ServiceSettings have already been loaded
// and should begin validating any properties (which is used to allow
// the deserializer to set empty values without tripping validation)
Expand Down Expand Up @@ -165,32 +180,84 @@ private static string GetServiceName(string suppliedServiceName, string serviceD
}

private static string GetDefaultStorageName(string localStorageName, string globalStorageAccountName, string storageAccountName, string serviceName)
{
{
Debug.Assert(serviceName != null, "serviceName cannot be null.");

string name = serviceName;

// If user supplied value as parameter then return it
//
if (!string.IsNullOrEmpty(storageAccountName))
{
return storageAccountName;
name = storageAccountName;
}
// User already has value in local service settings
//
else if (!string.IsNullOrEmpty(localStorageName))
{
return localStorageName;
name = localStorageName;
}
// User already has value in global service settings
//
else if (!string.IsNullOrEmpty(globalStorageAccountName))
{
return globalStorageAccountName;
name = globalStorageAccountName;
}
// If none of previous succeed, use service name as storage account name
//
else if (!String.IsNullOrEmpty(serviceName))
{
serviceName = serviceName.Replace("-", "x2d");
}
return serviceName;
else if (!string.IsNullOrEmpty(serviceName))
{
name = SanitizeStorageAccountName(serviceName);
}

name = name.ToLower();
ValidateStorageAccountName(name);

return name;
}

/// <summary>
/// Sanitize a name for use as a storage account name.
/// </summary>
/// <param name="name">The potential storage account name.</param>
/// <returns>The sanitized storage account name.</returns>
private static string SanitizeStorageAccountName(string name)
{
// Replace any non-letters or non-digits with their hex equivalent
StringBuilder builder = new StringBuilder(name.Length);
foreach (char ch in name)
{
if (char.IsLetter(ch) || char.IsDigit(ch))
{
builder.Append(ch);
}
else
{
builder.AppendFormat("x{0:X}", (ushort)ch);
}
}

// Trim the sanitized name to at most 24 characters.
name = builder.ToString(
0,
Math.Min(builder.Length, MaximumStorageAccountNameLength));

return name;
}

/// <summary>
/// Validate that the storage account name contains only lower case
/// letters or numbers and is between 3 and 24 characters in length
/// (per http://msdn.microsoft.com/en-us/library/windowsazure/hh264518.aspx)
/// unless the string is empty (which can happen if it wasn't provided
/// or generated).
/// </summary>
/// <param name="name">The storage account name.</param>
private static void ValidateStorageAccountName(string name)
{
if (!string.IsNullOrEmpty(name) &&
(!name.All(c => char.IsLower(c) || char.IsDigit(c)) ||
name.Length < MinimumStorageAccountNameLength ||
name.Length > MaximumStorageAccountNameLength))
{
throw new ArgumentException(string.Format(Properties.Resources.ServiceSettings_ValidateStorageAccountName_InvalidName, name));
}
}

private static string GetDefaultSubscription(string localSubscription, string globalSubscription, string subscription)
Expand Down

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 @@ -614,5 +614,7 @@
<data name="CertificatePrivateKeyAccessError" xml:space="preserve">
<value>Your account does not have access to the private key for certificate {0}</value>
</data>

<data name="ServiceSettings_ValidateStorageAccountName_InvalidName" xml:space="preserve">
<value>The storage account name '{0}' is invalid. Storage account names must be between 3 and 24 characters in length and use numbers and lower-case letters only.</value>
</data>
</root>

0 comments on commit 35a3c03

Please sign in to comment.