From 92c1ad2ce9e5dd00bf29b5b3932e7ded693050ec Mon Sep 17 00:00:00 2001 From: Scott Beddall Date: Mon, 13 May 2024 11:19:31 -0700 Subject: [PATCH 1/3] allow breakglass scenario for pushing --- .../CommandOptions/OptionsGenerator.cs | 8 +++++++- .../CommandOptions/PushOptions.cs | 8 ++++++-- .../Azure.Sdk.Tools.TestProxy/Store/GitStore.cs | 10 +++++++--- .../Azure.Sdk.Tools.TestProxy/Store/IAssetsStore.cs | 3 ++- .../Azure.Sdk.Tools.TestProxy/Store/NullStore.cs | 2 +- 5 files changed, 23 insertions(+), 8 deletions(-) diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/OptionsGenerator.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/OptionsGenerator.cs index 8f0ad59bb8b..2d985806d7f 100644 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/OptionsGenerator.cs +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/OptionsGenerator.cs @@ -55,6 +55,11 @@ public static RootCommand GenerateCommandLineOptions(Func getDefaultValue: () => false); universalOption.AddAlias("-u"); + var breakGlassOption = new Option( + name: "--breakGlass", + description: "Flag; Ignore secret push protection results when pushing.", + getDefaultValue: () => false); + breakGlassOption.AddAlias("-b"); var collectedArgs = new Argument("args") { @@ -92,9 +97,10 @@ public static RootCommand GenerateCommandLineOptions(Func root.Add(startCommand); var pushCommand = new Command("push", "Push the assets, referenced by assets.json, into git."); + pushCommand.AddOption(breakGlassOption); pushCommand.AddOption(assetsJsonPathOption); pushCommand.SetHandler(async (pushOpts) => await callback(pushOpts), - new PushOptionsBinder(storageLocationOption, storagePluginOption, assetsJsonPathOption) + new PushOptionsBinder(storageLocationOption, storagePluginOption, assetsJsonPathOption, breakGlassOption) ); root.Add(pushCommand); diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/PushOptions.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/PushOptions.cs index 71f76b5aa99..c12dd889ee3 100644 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/PushOptions.cs +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/PushOptions.cs @@ -8,6 +8,7 @@ namespace Azure.Sdk.Tools.TestProxy.CommandOptions /// public class PushOptions : CLICommandOptions { + public bool BreakGlass { get; set; } } public class PushOptionsBinder : BinderBase @@ -15,12 +16,14 @@ public class PushOptionsBinder : BinderBase private readonly Option _storageLocationOption; private readonly Option _storagePluginOption; private readonly Option _assetsJsonPathOption; + private readonly Option _breakGlassOption; - public PushOptionsBinder(Option storageLocationOption, Option storagePluginOption, Option assetsJsonPathOption) + public PushOptionsBinder(Option storageLocationOption, Option storagePluginOption, Option assetsJsonPathOption, Option breakGlassOption) { _storageLocationOption = storageLocationOption; _storagePluginOption = storagePluginOption; _assetsJsonPathOption = assetsJsonPathOption; + _breakGlassOption = breakGlassOption; } protected override PushOptions GetBoundValue(BindingContext bindingContext) => @@ -28,7 +31,8 @@ protected override PushOptions GetBoundValue(BindingContext bindingContext) => { StorageLocation = bindingContext.ParseResult.GetValueForOption(_storageLocationOption), StoragePlugin = bindingContext.ParseResult.GetValueForOption(_storagePluginOption), - AssetsJsonPath = bindingContext.ParseResult.GetValueForOption(_assetsJsonPathOption) + AssetsJsonPath = bindingContext.ParseResult.GetValueForOption(_assetsJsonPathOption), + BreakGlass = bindingContext.ParseResult.GetValueForOption(_breakGlassOption), }; } } diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/GitStore.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/GitStore.cs index 0f3c5339131..86baa650a4f 100644 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/GitStore.cs +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/GitStore.cs @@ -121,8 +121,9 @@ public bool CheckForSecrets(GitAssetsConfiguration assetsConfiguration, string[] /// Pushes a set of changed files to the assets repo. Honors configuration of assets.json passed into it. /// /// + /// /// - public async Task Push(string pathToAssetsJson) { + public async Task Push(string pathToAssetsJson, bool ignoreSecretProtection = false) { var config = await ParseConfigurationFile(pathToAssetsJson); var initialized = IsAssetsRepoInitialized(config); @@ -145,8 +146,11 @@ public async Task Push(string pathToAssetsJson) { { if (CheckForSecrets(config, pendingChanges)) { - Environment.ExitCode = -1; - return; + if (!ignoreSecretProtection) + { + Environment.ExitCode = -1; + return; + } } try diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/IAssetsStore.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/IAssetsStore.cs index 62e971283a0..5a8a3569845 100644 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/IAssetsStore.cs +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/IAssetsStore.cs @@ -11,7 +11,8 @@ public interface IAssetsStore /// Given a configuration, push the changes made by the test-proxy into the remote store. /// /// - public abstract Task Push(string pathToAssetsJson); + /// + public abstract Task Push(string pathToAssetsJson, bool ignoreSecretProtection = false); /// /// Given a configuration, pull any remote resources down into the provided contextPath. diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/NullStore.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/NullStore.cs index 2b90c851884..665ed7bcc75 100644 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/NullStore.cs +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/NullStore.cs @@ -9,7 +9,7 @@ namespace Azure.Sdk.Tools.TestProxy.Store { public class NullStore : IAssetsStore { - public Task Push(string pathToAssetsJson) { return null; } + public Task Push(string pathToAssetsJson, bool ignoreSecretProtection = false) { return null; } public Task Restore(string pathToAssetsJson) { return null; } From 68470dff169b4352546659162304a8bcaf04113e Mon Sep 17 00:00:00 2001 From: Scott Beddall <45376673+scbedd@users.noreply.github.com> Date: Tue, 14 May 2024 09:23:33 -0700 Subject: [PATCH 2/3] Apply suggestions from code review Co-authored-by: Ben Broderick Phillips --- .../CommandOptions/OptionsGenerator.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/OptionsGenerator.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/OptionsGenerator.cs index 2d985806d7f..3ad5748f5ca 100644 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/OptionsGenerator.cs +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/OptionsGenerator.cs @@ -56,10 +56,9 @@ public static RootCommand GenerateCommandLineOptions(Func universalOption.AddAlias("-u"); var breakGlassOption = new Option( - name: "--breakGlass", + name: "--break-glass", description: "Flag; Ignore secret push protection results when pushing.", getDefaultValue: () => false); - breakGlassOption.AddAlias("-b"); var collectedArgs = new Argument("args") { From 0c9d357fa1c4520d8c86a8a5383d483037fdde7f Mon Sep 17 00:00:00 2001 From: "Scott Beddall (from Dev Box)" Date: Wed, 15 May 2024 10:33:28 -0700 Subject: [PATCH 3/3] exit code returned all the way down the stack --- tools/test-proxy/Azure.Sdk.Tools.TestProxy/Startup.cs | 5 ++++- .../Azure.Sdk.Tools.TestProxy/Store/GitStore.cs | 9 ++++----- .../Azure.Sdk.Tools.TestProxy/Store/IAssetsStore.cs | 3 ++- .../Azure.Sdk.Tools.TestProxy/Store/NullStore.cs | 2 +- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Startup.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Startup.cs index b4285640fec..6e021b99187 100644 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Startup.cs +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Startup.cs @@ -62,11 +62,12 @@ public static async Task Main(string[] args = null) Environment.Exit(resultCode); } - private static async Task Run(object commandObj) + private static async Task Run(object commandObj) { var assembly = System.Reflection.Assembly.GetExecutingAssembly(); var semanticVersion = assembly.GetCustomAttribute().InformationalVersion; System.Console.WriteLine($"Running proxy version is Azure.Sdk.Tools.TestProxy {semanticVersion}"); + int returnCode = 0; new GitProcessHandler().VerifyGitMinVersion(); DefaultOptions defaultOptions = (DefaultOptions)commandObj; @@ -124,6 +125,8 @@ private static async Task Run(object commandObj) default: throw new ArgumentException($"Unable to parse the argument set: {string.Join(" ", storedArgs)}"); } + + return returnCode; } private static void StartServer(StartOptions startOptions) diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/GitStore.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/GitStore.cs index 86baa650a4f..afecf527627 100644 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/GitStore.cs +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/GitStore.cs @@ -123,7 +123,7 @@ public bool CheckForSecrets(GitAssetsConfiguration assetsConfiguration, string[] /// /// /// - public async Task Push(string pathToAssetsJson, bool ignoreSecretProtection = false) { + public async Task Push(string pathToAssetsJson, bool ignoreSecretProtection = false) { var config = await ParseConfigurationFile(pathToAssetsJson); var initialized = IsAssetsRepoInitialized(config); @@ -133,8 +133,7 @@ public async Task Push(string pathToAssetsJson, bool ignoreSecretProtection = fa _consoleWrapper.WriteLine($"The targeted assets.json \"{config.AssetsJsonRelativeLocation}\" has not been restored prior to attempting push. " + $"Are you certain you're pushing the correct assets.json? Please invoke \'test-proxy restore \"{config.AssetsJsonRelativeLocation}\"\' prior to invoking a push operation."); - Environment.ExitCode = -1; - return; + return -1; } SetOrigin(config); @@ -148,8 +147,7 @@ public async Task Push(string pathToAssetsJson, bool ignoreSecretProtection = fa { if (!ignoreSecretProtection) { - Environment.ExitCode = -1; - return; + return -1; } } @@ -243,6 +241,7 @@ public async Task Push(string pathToAssetsJson, bool ignoreSecretProtection = fa } HideOrigin(config); + return 0; } /// diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/IAssetsStore.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/IAssetsStore.cs index 5a8a3569845..4d3eafd20ae 100644 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/IAssetsStore.cs +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/IAssetsStore.cs @@ -12,7 +12,8 @@ public interface IAssetsStore /// /// /// - public abstract Task Push(string pathToAssetsJson, bool ignoreSecretProtection = false); + /// An integer representing the status of the push command. + public abstract Task Push(string pathToAssetsJson, bool ignoreSecretProtection = false); /// /// Given a configuration, pull any remote resources down into the provided contextPath. diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/NullStore.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/NullStore.cs index 665ed7bcc75..3290ff774c6 100644 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/NullStore.cs +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/NullStore.cs @@ -9,7 +9,7 @@ namespace Azure.Sdk.Tools.TestProxy.Store { public class NullStore : IAssetsStore { - public Task Push(string pathToAssetsJson, bool ignoreSecretProtection = false) { return null; } + public Task Push(string pathToAssetsJson, bool ignoreSecretProtection = false) { return null; } public Task Restore(string pathToAssetsJson) { return null; }