-
Notifications
You must be signed in to change notification settings - Fork 865
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add processing of target inputs in decorator task (#3550)
* Add check of runtime secrets in decorator task input * Remove extra changes * add separate method for checking * Better messaging * Move logic for inputs validation to the separate method * Resolved comments * Change name * Revert changes in dev.sh * Resolve comments * Removed extra code * Removed extra changes part 2 * Fix string.json * Resolve comments * Remove extra quote
- Loading branch information
1 parent
9839e29
commit 2b45edd
Showing
3 changed files
with
111 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
|
||
namespace Microsoft.VisualStudio.Services.Agent.Worker | ||
{ | ||
[ServiceLocator(Default = typeof(TaskDecoratorManager))] | ||
public interface ITaskDecoratorManager : IAgentService | ||
{ | ||
bool IsInjectedTaskForTarget(string taskName); | ||
bool IsInjectedInputsContainsSecrets(Dictionary<string, string> inputs, out List<string> inputsWithSecrets); | ||
string GenerateTaskResultMessage(List<string> inputsWithSecrets); | ||
} | ||
|
||
public sealed class TaskDecoratorManager : AgentService, ITaskDecoratorManager | ||
{ | ||
/// <summary> | ||
/// Checks if current task is injected by decorator with posttargettask or pretargettask target | ||
/// </summary> | ||
/// <param name="taskName">Name of the task to check</param> | ||
/// <returns>Returns `true` if task is injected by decorator for target task, otherwise `false`</returns> | ||
public bool IsInjectedTaskForTarget(string taskName) | ||
{ | ||
return taskName.StartsWith(InjectedTasksNamesPrefixes.PostTargetTask) | ||
|| taskName.StartsWith(InjectedTasksNamesPrefixes.PreTargetTask); | ||
} | ||
|
||
/// <summary> | ||
/// Verifies that there are inputs with secrets, if secrets were found task will be marked as skipped and won't be executed | ||
/// </summary> | ||
/// <param name="inputs">Inputs presented as a dictionary with input name as key and input's value as the value of the corresponding key</param> | ||
/// <param name="inputsWithSecrets">Out value that will contain the list of task inputs with secrets</param> | ||
/// <returns> Return `true` if task contains injected inputs with secrets, otherwise `false`</returns> | ||
public bool IsInjectedInputsContainsSecrets(Dictionary<string, string> inputs, out List<string> inputsWithSecrets) | ||
{ | ||
inputsWithSecrets = this.GetInputsWithSecrets(inputs); | ||
|
||
return inputsWithSecrets.Count > 0; | ||
} | ||
|
||
/// <summary> | ||
/// Generates list of inputs that should be included into task result message | ||
/// </summary> | ||
/// <param name="inputsWithSecrets">List of inputs with secrets, that should be included in message</param> | ||
public string GenerateTaskResultMessage(List<string> inputsWithSecrets) | ||
{ | ||
string inputsForReport = string.Join(Environment.NewLine, | ||
inputsWithSecrets.Select(input => string.Join("\n", input))); | ||
|
||
return inputsForReport; | ||
} | ||
|
||
/// <summary> | ||
/// Used to check if provided input value contain any secret | ||
/// </summary> | ||
/// <param name="inputValue">Value of input to check</param> | ||
/// <returns>Returns `true` if provided string contain secret, otherwise `false`</returns> | ||
private bool ContainsSecret(string inputValue) | ||
{ | ||
string maskedString = HostContext.SecretMasker.MaskSecrets(inputValue); | ||
return maskedString != inputValue; | ||
} | ||
|
||
/// <summary> | ||
/// Used to get list of inputs in injected task that started with target_ prefix and contain secrets, | ||
/// such inputs are autoinjected from target tasks | ||
/// </summary> | ||
/// <param name="inputs">Inputs presented as a dictionary with input name as key and input's value as the value of the corresponding key</param> | ||
/// <returns>Returns list of inputs' names that contain secret values</returns> | ||
private List<string> GetInputsWithSecrets(Dictionary<string, string> inputs) | ||
{ | ||
var inputsWithSecrets = new List<string>(); | ||
foreach (var input in inputs) | ||
{ | ||
if (input.Key.StartsWith("target_") && this.ContainsSecret(input.Value)) | ||
{ | ||
inputsWithSecrets.Add(input.Key); | ||
} | ||
} | ||
|
||
return inputsWithSecrets; | ||
} | ||
} | ||
|
||
internal static class InjectedTasksNamesPrefixes | ||
{ | ||
public static readonly String PostTargetTask = "__system_posttargettask_"; | ||
public static readonly String PreTargetTask = "__system_pretargettask_"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters