From f5218f8f96fb8c1a295caafaee7a78fb630b75aa Mon Sep 17 00:00:00 2001 From: sirh3e Date: Wed, 18 Nov 2020 21:37:10 +0100 Subject: [PATCH] Refactor core validate secret step (#787) * ValidateSecretStep remove nested if * applied format * added both missing nit nit: prefer braces around ifs --- src/Microsoft.Tye.Core/ValidateSecretStep.cs | 222 ++++++++++--------- 1 file changed, 112 insertions(+), 110 deletions(-) diff --git a/src/Microsoft.Tye.Core/ValidateSecretStep.cs b/src/Microsoft.Tye.Core/ValidateSecretStep.cs index 332b466b..7a887af2 100644 --- a/src/Microsoft.Tye.Core/ValidateSecretStep.cs +++ b/src/Microsoft.Tye.Core/ValidateSecretStep.cs @@ -41,142 +41,144 @@ namespace Microsoft.Tye foreach (var binding in bindings.Bindings) { - if (binding is SecretInputBinding secretInputBinding) + if (!(binding is SecretInputBinding secretInputBinding)) { - if (!Secrets.Add(secretInputBinding.Name)) - { - output.WriteDebugLine($"Already validated secret '{secretInputBinding.Name}'."); - continue; - } + continue; + } - output.WriteDebugLine($"Validating secret '{secretInputBinding.Name}'."); + if (!Secrets.Add(secretInputBinding.Name)) + { + output.WriteDebugLine($"Already validated secret '{secretInputBinding.Name}'."); + continue; + } - var config = KubernetesClientConfiguration.BuildDefaultConfig(); + output.WriteDebugLine($"Validating secret '{secretInputBinding.Name}'."); - // If namespace is null, set it to default - config.Namespace ??= "default"; + var config = KubernetesClientConfiguration.BuildDefaultConfig(); - var kubernetes = new Kubernetes(config); + // If namespace is null, set it to default + config.Namespace ??= "default"; - try - { - var result = await kubernetes.ReadNamespacedSecretWithHttpMessagesAsync(secretInputBinding.Name, config.Namespace); - output.WriteInfoLine($"Found existing secret '{secretInputBinding.Name}'."); - continue; - } - catch (HttpOperationException ex) when (ex.Response.StatusCode == HttpStatusCode.NotFound) - { - // The kubernetes client uses exceptions for 404s. - } - catch (Exception ex) - { - output.WriteDebugLine("Failed to query secret."); - output.WriteDebugLine(ex.ToString()); - throw new CommandException("Unable connect to kubernetes.", ex); - } + var kubernetes = new Kubernetes(config); - if (Force) - { - output.WriteDebugLine("Skipping because force was specified."); - continue; - } + try + { + var result = await kubernetes.ReadNamespacedSecretWithHttpMessagesAsync(secretInputBinding.Name, config.Namespace); + output.WriteInfoLine($"Found existing secret '{secretInputBinding.Name}'."); + continue; + } + catch (HttpOperationException ex) when (ex.Response.StatusCode == HttpStatusCode.NotFound) + { + // The kubernetes client uses exceptions for 404s. + } + catch (Exception ex) + { + output.WriteDebugLine("Failed to query secret."); + output.WriteDebugLine(ex.ToString()); + throw new CommandException("Unable connect to kubernetes.", ex); + } - if (!Interactive && secretInputBinding is SecretConnectionStringInputBinding) - { - throw new CommandException( - $"The secret '{secretInputBinding.Name}' used for service '{secretInputBinding.Service.Name}' is missing from the deployment environment. " + - $"Rerun the command with --interactive to specify the value interactively, or with --force to skip validation. Alternatively " + - $"use the following command to manually create the secret." + System.Environment.NewLine + - $"kubectl create secret generic {secretInputBinding.Name} --namespace {config.Namespace} --from-literal=connectionstring="); - } + if (Force) + { + output.WriteDebugLine("Skipping because force was specified."); + continue; + } + + if (!Interactive && secretInputBinding is SecretConnectionStringInputBinding) + { + throw new CommandException( + $"The secret '{secretInputBinding.Name}' used for service '{secretInputBinding.Service.Name}' is missing from the deployment environment. " + + $"Rerun the command with --interactive to specify the value interactively, or with --force to skip validation. Alternatively " + + $"use the following command to manually create the secret." + System.Environment.NewLine + + $"kubectl create secret generic {secretInputBinding.Name} --namespace {config.Namespace} --from-literal=connectionstring="); + } - if (!Interactive && secretInputBinding is SecretUrlInputBinding) + if (!Interactive && secretInputBinding is SecretUrlInputBinding) + { + throw new CommandException( + $"The secret '{secretInputBinding.Name}' used for service '{secretInputBinding.Service.Name}' is missing from the deployment environment. " + + $"Rerun the command with --interactive to specify the value interactively, or with --force to skip validation. Alternatively " + + $"use the following command to manually create the secret." + System.Environment.NewLine + + $"kubectl create secret generic {secretInputBinding.Name} --namespace {config.Namespace} --from-literal=protocol= --from-literal=host= --from-literal=port="); + } + + V1Secret secret; + if (secretInputBinding is SecretConnectionStringInputBinding) + { + // If we get here then we should create the secret. + var text = output.Prompt($"Enter the connection string to use for service '{secretInputBinding.Service.Name}'", allowEmpty: true); + if (string.IsNullOrWhiteSpace(text)) { - throw new CommandException( - $"The secret '{secretInputBinding.Name}' used for service '{secretInputBinding.Service.Name}' is missing from the deployment environment. " + - $"Rerun the command with --interactive to specify the value interactively, or with --force to skip validation. Alternatively " + - $"use the following command to manually create the secret." + System.Environment.NewLine + - $"kubectl create secret generic {secretInputBinding.Name} --namespace {config.Namespace} --from-literal=protocol= --from-literal=host= --from-literal=port="); + output.WriteAlwaysLine($"Skipping creation of secret for '{secretInputBinding.Service.Name}'. This may prevent creation of pods until secrets are created."); + output.WriteAlwaysLine($"Manually create a secret with:"); + output.WriteAlwaysLine($"kubectl create secret generic {secretInputBinding.Name} --namespace {config.Namespace} --from-literal=connectionstring="); + continue; } - V1Secret secret; - if (secretInputBinding is SecretConnectionStringInputBinding) + secret = new V1Secret(type: "Opaque", stringData: new Dictionary() { - // If we get here then we should create the secret. - var text = output.Prompt($"Enter the connection string to use for service '{secretInputBinding.Service.Name}'", allowEmpty: true); - if (string.IsNullOrWhiteSpace(text)) - { - output.WriteAlwaysLine($"Skipping creation of secret for '{secretInputBinding.Service.Name}'. This may prevent creation of pods until secrets are created."); - output.WriteAlwaysLine($"Manually create a secret with:"); - output.WriteAlwaysLine($"kubectl create secret generic {secretInputBinding.Name} --namespace {config.Namespace} --from-literal=connectionstring="); - continue; - } - - secret = new V1Secret(type: "Opaque", stringData: new Dictionary() - { - { "connectionstring", text }, - }); - } - else if (secretInputBinding is SecretUrlInputBinding) + { "connectionstring", text }, + }); + } + else if (secretInputBinding is SecretUrlInputBinding) + { + // If we get here then we should create the secret. + string text; + Uri? uri = null; + while (true) { - // If we get here then we should create the secret. - string text; - Uri? uri = null; - while (true) + text = output.Prompt($"Enter the URI to use for service '{secretInputBinding.Service.Name}'", allowEmpty: true); + if (string.IsNullOrEmpty(text)) { - text = output.Prompt($"Enter the URI to use for service '{secretInputBinding.Service.Name}'", allowEmpty: true); - if (string.IsNullOrEmpty(text)) - { - break; // skip - } - else if (Uri.TryCreate(text, UriKind.Absolute, out uri)) - { - break; // success - } - - output.WriteAlwaysLine($"Invalid URI: '{text}'"); + break; // skip } - - if (string.IsNullOrWhiteSpace(text)) + else if (Uri.TryCreate(text, UriKind.Absolute, out uri)) { - output.WriteAlwaysLine($"Skipping creation of secret for '{secretInputBinding.Service.Name}'. This may prevent creation of pods until secrets are created."); - output.WriteAlwaysLine($"Manually create a secret with:"); - output.WriteAlwaysLine($"kubectl create secret generic {secretInputBinding.Name} --namespace {config.Namespace} --from-literal=protocol= --from-literal=host= --from-literal=port="); - continue; + break; // success } - secret = new V1Secret(type: "Opaque", stringData: new Dictionary() - { - { "protocol", uri!.Scheme }, - { "host", uri!.Host }, - { "port", uri!.Port.ToString(CultureInfo.InvariantCulture) }, - }); + output.WriteAlwaysLine($"Invalid URI: '{text}'"); } - else + + if (string.IsNullOrWhiteSpace(text)) { - throw new InvalidOperationException("Unknown Secret type: " + secretInputBinding); + output.WriteAlwaysLine($"Skipping creation of secret for '{secretInputBinding.Service.Name}'. This may prevent creation of pods until secrets are created."); + output.WriteAlwaysLine($"Manually create a secret with:"); + output.WriteAlwaysLine($"kubectl create secret generic {secretInputBinding.Name} --namespace {config.Namespace} --from-literal=protocol= --from-literal=host= --from-literal=port="); + continue; } - secret.Metadata = new V1ObjectMeta(); - secret.Metadata.Name = secretInputBinding.Name; - secret.Metadata.Labels = new Dictionary() + secret = new V1Secret(type: "Opaque", stringData: new Dictionary() { - ["app.kubernetes.io/part-of"] = application.Name, - }; + { "protocol", uri!.Scheme }, + { "host", uri!.Host }, + { "port", uri!.Port.ToString(CultureInfo.InvariantCulture) }, + }); + } + else + { + throw new InvalidOperationException("Unknown Secret type: " + secretInputBinding); + } - output.WriteDebugLine($"Creating secret '{secret.Metadata.Name}'."); + secret.Metadata = new V1ObjectMeta(); + secret.Metadata.Name = secretInputBinding.Name; + secret.Metadata.Labels = new Dictionary() + { + ["app.kubernetes.io/part-of"] = application.Name, + }; - try - { - await kubernetes.CreateNamespacedSecretWithHttpMessagesAsync(secret, config.Namespace); - output.WriteInfoLine($"Created secret '{secret.Metadata.Name}'."); - } - catch (Exception ex) - { - output.WriteDebugLine("Failed to create secret."); - output.WriteDebugLine(ex.ToString()); - throw new CommandException("Failed to create secret.", ex); - } + output.WriteDebugLine($"Creating secret '{secret.Metadata.Name}'."); + + try + { + await kubernetes.CreateNamespacedSecretWithHttpMessagesAsync(secret, config.Namespace); + output.WriteInfoLine($"Created secret '{secret.Metadata.Name}'."); + } + catch (Exception ex) + { + output.WriteDebugLine("Failed to create secret."); + output.WriteDebugLine(ex.ToString()); + throw new CommandException("Failed to create secret.", ex); } } }