Browse Source

Refactor core validate secret step (#787)

* ValidateSecretStep remove nested if

* applied format

* added both missing nit nit: prefer braces around ifs
pull/804/head
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)
{
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=<value>");
}
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=<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(
$"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>");
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=<value>");
continue;
}
V1Secret secret;
if (secretInputBinding is SecretConnectionStringInputBinding)
secret = new V1Secret(type: "Opaque", stringData: new Dictionary<string, string>()
{
// 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=<value>");
continue;
}
secret = new V1Secret(type: "Opaque", stringData: new Dictionary<string, string>()
{
{ "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=<value> --from-literal=host=<value> --from-literal=port=<value>");
continue;
break; // success
}
secret = new V1Secret(type: "Opaque", stringData: new Dictionary<string, string>()
{
{ "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=<value> --from-literal=host=<value> --from-literal=port=<value>");
continue;
}
secret.Metadata = new V1ObjectMeta();
secret.Metadata.Name = secretInputBinding.Name;
secret.Metadata.Labels = new Dictionary<string, string>()
secret = new V1Secret(type: "Opaque", stringData: 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
{
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);
}
}
}

Loading…
Cancel
Save