Browse Source

Refactor core validate secret step (#787)

* ValidateSecretStep remove nested if

* applied format

* added both missing nit nit: prefer braces around ifs
finitereality/replica-status-colors
sirh3e 6 years ago
committed by GitHub
parent
commit
f5218f8f96
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 222
      src/Microsoft.Tye.Core/ValidateSecretStep.cs

222
src/Microsoft.Tye.Core/ValidateSecretStep.cs

@ -41,142 +41,144 @@ namespace Microsoft.Tye
foreach (var binding in bindings.Bindings) foreach (var binding in bindings.Bindings)
{ {
if (binding is SecretInputBinding secretInputBinding) if (!(binding is SecretInputBinding secretInputBinding))
{ {
if (!Secrets.Add(secretInputBinding.Name)) continue;
{ }
output.WriteDebugLine($"Already validated secret '{secretInputBinding.Name}'.");
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 var config = KubernetesClientConfiguration.BuildDefaultConfig();
config.Namespace ??= "default";
var kubernetes = new Kubernetes(config); // If namespace is null, set it to default
config.Namespace ??= "default";
try var kubernetes = new Kubernetes(config);
{
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 (Force) try
{ {
output.WriteDebugLine("Skipping because force was specified."); var result = await kubernetes.ReadNamespacedSecretWithHttpMessagesAsync(secretInputBinding.Name, config.Namespace);
continue; 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) if (Force)
{ {
throw new CommandException( output.WriteDebugLine("Skipping because force was specified.");
$"The secret '{secretInputBinding.Name}' used for service '{secretInputBinding.Service.Name}' is missing from the deployment environment. " + continue;
$"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=<value>"); 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=<value>");
}
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=<value> --from-literal=host=<value> --from-literal=port=<value>");
}
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( output.WriteAlwaysLine($"Skipping creation of secret for '{secretInputBinding.Service.Name}'. This may prevent creation of pods until secrets are created.");
$"The secret '{secretInputBinding.Name}' used for service '{secretInputBinding.Service.Name}' is missing from the deployment environment. " + output.WriteAlwaysLine($"Manually create a secret with:");
$"Rerun the command with --interactive to specify the value interactively, or with --force to skip validation. Alternatively " + output.WriteAlwaysLine($"kubectl create secret generic {secretInputBinding.Name} --namespace {config.Namespace} --from-literal=connectionstring=<value>");
$"use the following command to manually create the secret." + System.Environment.NewLine + continue;
$"kubectl create secret generic {secretInputBinding.Name} --namespace {config.Namespace} --from-literal=protocol=<value> --from-literal=host=<value> --from-literal=port=<value>");
} }
V1Secret secret; secret = new V1Secret(type: "Opaque", stringData: new Dictionary<string, string>()
if (secretInputBinding is SecretConnectionStringInputBinding)
{ {
// If we get here then we should create the secret. { "connectionstring", text },
var text = output.Prompt($"Enter the connection string to use for service '{secretInputBinding.Service.Name}'", allowEmpty: true); });
if (string.IsNullOrWhiteSpace(text)) }
{ else if (secretInputBinding is SecretUrlInputBinding)
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:"); // If we get here then we should create the secret.
output.WriteAlwaysLine($"kubectl create secret generic {secretInputBinding.Name} --namespace {config.Namespace} --from-literal=connectionstring=<value>"); string text;
continue; Uri? uri = null;
} while (true)
secret = new V1Secret(type: "Opaque", stringData: new Dictionary<string, string>()
{
{ "connectionstring", text },
});
}
else if (secretInputBinding is SecretUrlInputBinding)
{ {
// If we get here then we should create the secret. text = output.Prompt($"Enter the URI to use for service '{secretInputBinding.Service.Name}'", allowEmpty: true);
string text; if (string.IsNullOrEmpty(text))
Uri? uri = null;
while (true)
{ {
text = output.Prompt($"Enter the URI to use for service '{secretInputBinding.Service.Name}'", allowEmpty: true); break; // skip
if (string.IsNullOrEmpty(text))
{
break; // skip
}
else if (Uri.TryCreate(text, UriKind.Absolute, out uri))
{
break; // success
}
output.WriteAlwaysLine($"Invalid URI: '{text}'");
} }
else if (Uri.TryCreate(text, UriKind.Absolute, out uri))
if (string.IsNullOrWhiteSpace(text))
{ {
output.WriteAlwaysLine($"Skipping creation of secret for '{secretInputBinding.Service.Name}'. This may prevent creation of pods until secrets are created."); break; // success
output.WriteAlwaysLine($"Manually create a secret with:");
output.WriteAlwaysLine($"kubectl create secret generic {secretInputBinding.Name} --namespace {config.Namespace} --from-literal=protocol=<value> --from-literal=host=<value> --from-literal=port=<value>");
continue;
} }
secret = new V1Secret(type: "Opaque", stringData: new Dictionary<string, string>() output.WriteAlwaysLine($"Invalid URI: '{text}'");
{
{ "protocol", uri!.Scheme },
{ "host", uri!.Host },
{ "port", uri!.Port.ToString(CultureInfo.InvariantCulture) },
});
} }
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=<value> --from-literal=host=<value> --from-literal=port=<value>");
continue;
} }
secret.Metadata = new V1ObjectMeta(); secret = new V1Secret(type: "Opaque", stringData: new Dictionary<string, string>()
secret.Metadata.Name = secretInputBinding.Name;
secret.Metadata.Labels = new Dictionary<string, string>()
{ {
["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<string, string>()
{
["app.kubernetes.io/part-of"] = application.Name,
};
try output.WriteDebugLine($"Creating secret '{secret.Metadata.Name}'.");
{
await kubernetes.CreateNamespacedSecretWithHttpMessagesAsync(secret, config.Namespace); try
output.WriteInfoLine($"Created secret '{secret.Metadata.Name}'."); {
} await kubernetes.CreateNamespacedSecretWithHttpMessagesAsync(secret, config.Namespace);
catch (Exception ex) output.WriteInfoLine($"Created secret '{secret.Metadata.Name}'.");
{ }
output.WriteDebugLine("Failed to create secret."); catch (Exception ex)
output.WriteDebugLine(ex.ToString()); {
throw new CommandException("Failed to create secret.", ex); output.WriteDebugLine("Failed to create secret.");
} output.WriteDebugLine(ex.ToString());
throw new CommandException("Failed to create secret.", ex);
} }
} }
} }

Loading…
Cancel
Save