-
Notifications
You must be signed in to change notification settings - Fork 4k
AzureCP PR - Fix Extension ID Issue #387 #1792
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
34b3c5b
0fe7d69
fc0027f
1d42e41
bf33468
d942e42
bf8744b
92b92e0
555090d
62134ac
5aa7a89
6c3386c
c8a6c1b
74014ad
f07dd07
ca8b901
e47eed3
98ac14b
95849b2
59f49f1
3b94797
d07b1eb
877045e
343836e
39d97c2
02c0288
31111f4
8ae38ce
1e67e6c
37faca8
fbee436
f99c1fb
3118a0e
b7ecf11
a42e515
99e7994
579cd16
c03048b
c19a050
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using Microsoft.IdentityModel.Clients.ActiveDirectory; | ||
using Microsoft.Rest.ClientRuntime.Azure.TestFramework; | ||
using Xunit; | ||
|
||
namespace Microsoft.Azure.Commands.Compute.Test.ScenarioTests | ||
{ | ||
public class RunnerTests | ||
{ | ||
[Fact] | ||
public void ExecuteRunnerTests() | ||
{ | ||
var mode = Environment.GetEnvironmentVariable("AZURE_TEST_MODE"); | ||
var csmAuth = Environment.GetEnvironmentVariable("TEST_CSM_ORGID_AUTHENTICATION"); | ||
|
||
if (mode == null || csmAuth == null || mode.ToLower() != "record") | ||
{ | ||
return; | ||
} | ||
|
||
Assert.False(string.IsNullOrEmpty(csmAuth)); | ||
Assert.True(csmAuth.Contains("AADTenant")); | ||
|
||
var envDictionary = TestUtilities.ParseConnectionString(csmAuth); | ||
var testEnv = new TestEnvironment(envDictionary); | ||
Assert.NotNull(testEnv.Tenant); | ||
Assert.NotNull(testEnv.SubscriptionId); | ||
Assert.NotNull(testEnv.ClientId); | ||
Assert.True(envDictionary.ContainsKey("ApplicationSecret")); | ||
|
||
var authenticationContext = new AuthenticationContext("https://login.windows.net/" + testEnv.Tenant); | ||
var credential = new ClientCredential(testEnv.ClientId, envDictionary["ApplicationSecret"]); | ||
|
||
var result = authenticationContext.AcquireToken("https://management.core.windows.net/", clientCredential: credential); | ||
|
||
Assert.NotNull(result.AccessToken); | ||
envDictionary["RawToken"] = result.AccessToken; | ||
|
||
FixCSMAuthEnvVariable(envDictionary); | ||
|
||
Console.WriteLine(Environment.GetEnvironmentVariable("TEST_CSM_ORGID_AUTHENTICATION")); | ||
|
||
var testFile = File.ReadAllLines("ScenarioTests\\RunnerTests.csv"); | ||
foreach (var line in testFile) | ||
{ | ||
var tokens = line.Split(';'); | ||
var className = tokens[0]; | ||
var type = Type.GetType(className); | ||
var constructorInfo = type.GetConstructor(Type.EmptyTypes); | ||
for (int i = 1; i < tokens.Length; i++) | ||
{ | ||
var method = tokens[i]; | ||
var testClassInstance = constructorInfo.Invoke(new object[] {}); | ||
var testMethod = type.GetMethod(method); | ||
|
||
Console.WriteLine("Invoking method : " + testMethod); | ||
|
||
testMethod.Invoke(testClassInstance, new object[] {}); | ||
|
||
Console.WriteLine("Method " + testMethod + " has finished"); | ||
} | ||
} | ||
} | ||
|
||
private void FixCSMAuthEnvVariable(IDictionary<string, string> envDictionary) | ||
{ | ||
var str = string.Empty; | ||
foreach (var entry in envDictionary) | ||
{ | ||
if (entry.Key != "AADClientId" && entry.Key != "ApplicationSecret") | ||
{ | ||
str += string.Format("{0}={1};", entry.Key, entry.Value); | ||
} | ||
} | ||
|
||
Environment.SetEnvironmentVariable("TEST_CSM_ORGID_AUTHENTICATION", str); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Microsoft.Azure.Commands.Compute.Test.ScenarioTests.VMDynamicTests;RunVMDynamicTests |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
// ---------------------------------------------------------------------------------- | ||
// | ||
// 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.WindowsAzure.Commands.ServiceManagement.Extensions; | ||
using System; | ||
using Xunit; | ||
|
||
namespace Microsoft.WindowsAzure.Commands.ScenarioTest | ||
{ | ||
public partial class ServiceManagementTests | ||
{ | ||
[Fact] | ||
[Trait(Category.Service, Category.ServiceManagement)] | ||
[Trait(Category.AcceptanceType, Category.CheckIn)] | ||
[Trait(Category.AcceptanceType, Category.BVT)] | ||
public void TestExtensionRoleNames() | ||
{ | ||
var roleNames = new string[] | ||
{ | ||
"test Role Name", | ||
"!!!!! _____ test Role Name ~~~", | ||
"testRoleName", | ||
" testRoleName", | ||
"testRoleName ", | ||
" testRoleName" | ||
}; | ||
var expectedPrefixName = "testRoleName"; | ||
var expectedExtensionId = "testRoleName-test-test-Ext-0"; | ||
foreach (var roleName in roleNames) | ||
{ | ||
ExtensionRole er = new ExtensionRole(roleName); | ||
Assert.Equal(er.RoleName, roleName.Trim()); | ||
Assert.Equal(er.PrefixName, expectedPrefixName); | ||
Assert.Equal(er.GetExtensionId("test", "test", 0), expectedExtensionId); | ||
} | ||
|
||
var longRoleNames = new string[] | ||
{ | ||
"A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789", | ||
" A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789 ~~~" | ||
}; | ||
|
||
// PrefixName = A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789 | ||
// Extension Name = test | ||
// Slot = test | ||
// Index = 0 | ||
// Extension ID Format = {prefix_name_part}-{extension_name_part}-{slot}-Ext-{index} | ||
// Extenion ID's Max Length: 60 = 43 + 1 + 4 + 1 + 4 + 1 + 5 | ||
// i.e. 'A123...E123' + '-' + 'test' + '-' + 'test' + '-' + 'Ext-0' | ||
// L=43 L=1 L=4 L=1 L=4 L=1 L=5 | ||
expectedPrefixName = longRoleNames[0]; | ||
expectedExtensionId = "A123456789B123456789C123456789D123456789E123-test-test-Ext-0"; | ||
foreach (var roleName in longRoleNames) | ||
{ | ||
ExtensionRole er = new ExtensionRole(roleName); | ||
Assert.Equal(er.RoleName, roleName.Trim()); | ||
Assert.Equal(er.PrefixName, expectedPrefixName); | ||
Assert.Equal(er.GetExtensionId("test", "test", 0), expectedExtensionId); | ||
} | ||
|
||
|
||
var longExtensionNames = longRoleNames; | ||
// PrefixName = Default | ||
// Extension Name = A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789 | ||
// Slot = test | ||
// Index = 1 | ||
// Extension ID Format = {prefix_name_part}-{extension_name_part}-{slot}-Ext-{index} | ||
// Extenion ID's Max Length: 60 = 1 + 1 + 47 + 1 + 4 + 1 + 5 | ||
// i.e. 'D' + '-' + 'A123...456' + '-' + 'test' + '-' + 'Ext-0' | ||
// L=1 L=1 L=47 L=1 L=4 L=1 L=5 | ||
expectedExtensionId = "D-A123456789B123456789C123456789D123456789E123456-test-Ext-1"; | ||
foreach (var extensionName in longExtensionNames) | ||
{ | ||
ExtensionRole er = new ExtensionRole(); | ||
Assert.Equal(er.RoleName, string.Empty); | ||
Assert.Equal(er.PrefixName, "Default"); | ||
Assert.Equal(er.GetExtensionId(extensionName, "test", 1), expectedExtensionId); | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ | |
|
||
using System; | ||
using System.Text; | ||
using System.Text.RegularExpressions; | ||
|
||
namespace Microsoft.WindowsAzure.Commands.ServiceManagement.Extensions | ||
{ | ||
|
@@ -22,12 +23,21 @@ public class ExtensionRole | |
protected const string DefaultExtensionIdPrefixStr = "Default"; | ||
protected const string ExtensionIdSuffixTemplate = "-{0}-{1}-Ext-{2}"; | ||
protected const int MaxExtensionIdLength = 60; | ||
protected const int MinRoleNamePartLength = 1; | ||
protected const int MaxSuffixLength = MaxExtensionIdLength - MinRoleNamePartLength; | ||
|
||
public string RoleName { get; private set; } | ||
public string PrefixName { get; private set; } | ||
public ExtensionRoleType RoleType { get; private set; } | ||
public bool Default { get; private set; } | ||
|
||
private static string RemoveDisallowedCharacters(string roleName) | ||
{ | ||
// Remove characters that are not allowed in the extension id | ||
var disallowedCharactersRegex = new Regex(@"[^A-Za-z0-9\-]"); | ||
return disallowedCharactersRegex.Replace(roleName, string.Empty); | ||
} | ||
|
||
public ExtensionRole() | ||
{ | ||
RoleName = string.Empty; | ||
|
@@ -48,9 +58,7 @@ public ExtensionRole(string roleName) | |
else | ||
{ | ||
PrefixName = RoleName = roleName.Trim(); | ||
PrefixName = PrefixName.Replace(".", string.Empty); | ||
PrefixName = PrefixName.Replace(" ", string.Empty); | ||
PrefixName = PrefixName.Replace("_", string.Empty); | ||
PrefixName = RemoveDisallowedCharacters(PrefixName); | ||
RoleType = ExtensionRoleType.NamedRoles; | ||
Default = false; | ||
} | ||
|
@@ -63,13 +71,21 @@ public override string ToString() | |
|
||
public string GetExtensionId(string extensionName, string slot, int index) | ||
{ | ||
var normalizedExtName = extensionName.Replace(".", string.Empty); | ||
normalizedExtName = normalizedExtName.Replace(" ", string.Empty); | ||
normalizedExtName = normalizedExtName.Replace("_", string.Empty); | ||
var normalizedExtName = RemoveDisallowedCharacters(extensionName); | ||
|
||
var suffix = new StringBuilder(); | ||
// Suffix format: -{extension_name_part}-{slot}-Ext-{index} | ||
suffix.AppendFormat(ExtensionIdSuffixTemplate, normalizedExtName, slot, index); | ||
if (suffix.Length > MaxSuffixLength) | ||
{ | ||
// If the suffix is too long, truncate the {extension_name_part} | ||
int lenDiff = suffix.Length - MaxSuffixLength; | ||
int startIndex = 1; // Suffix starts with '-' | ||
suffix.Remove(startIndex + normalizedExtName.Length - lenDiff, lenDiff); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what do you want to achieve here? string.Remove returns a new string which you do not use anywhere. The original string will remain unchanged. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BTW, please cover this case in the tests as well ;) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it's actually covered, :-)... -- The test case is to validate that a very long extension name will be truncated in the suffix, while the other parts, i.e. slot & number are preserved. |
||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this for limiting the length of the string? If so, this should be enough
right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually no... So the format of the extension ID is I want to limit the |
||
|
||
// Calculate the prefix length by the difference between the suffix and the max ID length. | ||
// The difference should always be at least 1. | ||
int prefixSubStrLen = Math.Min(Math.Max(MaxExtensionIdLength - suffix.Length, 0), PrefixName.Length); | ||
|
||
var result = new StringBuilder(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this method seems too complex for the thing it is doing.
Just put following on line 37 and you should be good: