Skip to content

Commit

Permalink
Mask URL with credentials on publish telemetry
Browse files Browse the repository at this point in the history
  • Loading branch information
ismayilov-ismayil committed Oct 25, 2024
1 parent 42229c7 commit d24d8fe
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/Agent.Worker/JobExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,7 @@ private void PublishKnobsInfo(IExecutionContext jobContext)
var value = knob.GetValue(jobContext);
if (value.Source.GetType() != typeof(BuiltInDefaultKnobSource))
{
var stringValue = value.AsString();
var stringValue = HostContext.SecretMasker.MaskSecrets(value.AsString());
telemetryData.Add($"{knob.Name}-{value.Source.GetDisplayString()}", stringValue);
}
}
Expand Down
1 change: 1 addition & 0 deletions src/Test/L0/TestHostContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public TestHostContext(object testClass, [CallerMemberName] string testName = ""
_secretMasker.AddValueEncoder(ValueEncoders.JsonStringEscape);
_secretMasker.AddValueEncoder(ValueEncoders.UriDataEscape);
_secretMasker.AddValueEncoder(ValueEncoders.BackslashEscape);
_secretMasker.AddRegex(AdditionalMaskingRegexes.UrlSecretPattern);
_traceManager = new TraceManager(traceListener, _secretMasker);
_trace = GetTrace(nameof(TestHostContext));

Expand Down
62 changes: 60 additions & 2 deletions src/Test/L0/Worker/JobExtensionL0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
using Xunit;
using System.Threading;
using Pipelines = Microsoft.TeamFoundation.DistributedTask.Pipelines;
using Microsoft.VisualStudio.Services.Agent.Worker.Telemetry;
using Microsoft.VisualStudio.Services.WebPlatform;

namespace Microsoft.VisualStudio.Services.Agent.Tests.Worker
{
Expand Down Expand Up @@ -61,6 +63,8 @@ public override void InitializeJobExtension(IExecutionContext context, IList<Pip
private Mock<IPagingLogger> _logger;
private Mock<IExpressionManager> _express;
private Mock<IContainerOperationProvider> _containerProvider;
private Mock<ICustomerIntelligenceServer> _mockCiService;
private Mock<IAsyncCommandContext> _asyncCommandContext;
private TestHostContext CreateTestContext(CancellationTokenSource _tokenSource, [CallerMemberName] String testName = "")
{
var hc = new TestHostContext(this, testName);
Expand Down Expand Up @@ -291,6 +295,9 @@ private TestHostContext CreateMSITestContext(CancellationTokenSource _tokenSourc
_express = new Mock<IExpressionManager>();
_containerProvider = new Mock<IContainerOperationProvider>();
_logPlugin = new Mock<IAgentLogPlugin>();
_mockCiService = new Mock<ICustomerIntelligenceServer>();
_asyncCommandContext = new Mock<IAsyncCommandContext>();


TaskRunner step1 = new TaskRunner();
TaskRunner step2 = new TaskRunner();
Expand Down Expand Up @@ -333,7 +340,7 @@ private TestHostContext CreateMSITestContext(CancellationTokenSource _tokenSourc
Url = new Uri("https://test.visualstudio.com"),
Authorization = new EndpointAuthorization()
{
Scheme = "ManagedServiceIdentity",
Scheme = "OAuth",
}
};
environment.SystemConnection.Authorization.Parameters["AccessToken"] = "token";
Expand Down Expand Up @@ -462,6 +469,7 @@ private TestHostContext CreateMSITestContext(CancellationTokenSource _tokenSourc
hc.SetSingleton(_express.Object);
hc.SetSingleton(_containerProvider.Object);
hc.SetSingleton(_logPlugin.Object);
hc.SetSingleton(_mockCiService.Object);
hc.EnqueueInstance<IPagingLogger>(_logger.Object); // jobcontext logger
hc.EnqueueInstance<IPagingLogger>(_logger.Object); // init step logger
hc.EnqueueInstance<IPagingLogger>(_logger.Object); // step 1
Expand Down Expand Up @@ -762,5 +770,55 @@ public async Task JobExtensionManagementScriptStepMSI()
Environment.SetEnvironmentVariable("VSTS_AGENT_CLEANUP_INTERNAL_TEMP_HACK", "");
}
}
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
[Trait("SkipOn", "darwin")]
[Trait("SkipOn", "linux")]
public async Task JobExtensionTelemetryPublisherSecretValue()
{
using CancellationTokenSource tokenSource = new CancellationTokenSource();
using TestHostContext hc = CreateMSITestContext(tokenSource);

hc.EnqueueInstance<IAsyncCommandContext>(_asyncCommandContext.Object);
hc.EnqueueInstance<IAsyncCommandContext>(_asyncCommandContext.Object);
hc.EnqueueInstance<IAsyncCommandContext>(_asyncCommandContext.Object);

hc.SetSingleton(new TaskRestrictionsChecker() as ITaskRestrictionsChecker);

Environment.SetEnvironmentVariable("http_proxy", "http://admin:[email protected]");
Environment.SetEnvironmentVariable("AGENT_DISABLE_NODE6_TASKS", "true");

var expectedEvents = new List<Dictionary<string, object>>()
{
new Dictionary<string, object>() { { "JobId", "" }, { "ImageVersion", null } },
new Dictionary<string, object>() {
{ "JobId", null },
{ "ProxyAddress-${http_proxy}", "http://admin:***@localhost.com"},
{ "DisableNode6Tasks-${AGENT_DISABLE_NODE6_TASKS}","true"}
}
};

var actualEvents = new List<CustomerIntelligenceEvent[]>();

_mockCiService.Setup(s => s.PublishEventsAsync(It.IsAny<CustomerIntelligenceEvent[]>()))
.Callback<CustomerIntelligenceEvent[]>(actualEvents.Add)
.Returns(Task.CompletedTask);


TestJobExtension testExtension = new TestJobExtension();
testExtension.Initialize(hc);
List<IStep> result = await testExtension.InitializeJob(_jobEc, _message);

Assert.Equal(expectedEvents.Count, actualEvents.Count);
for (int i = 0; i < expectedEvents.Count; i++)
{
Assert.True(
expectedEvents[i].Count == actualEvents[i][0].Properties.Count &&
!expectedEvents[i].Except(actualEvents[i][0].Properties).Any(),
$"Event at index {i} does not match. "
);
}
}
}
}
}

0 comments on commit d24d8fe

Please sign in to comment.