Created
January 12, 2018 13:52
-
-
Save lawrencejones/79f707a507a87ff5395d78ef2dde9978 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
#!/usr/bin/env ruby | |
require "tempfile" | |
require "open3" | |
require "shellwords" | |
require "yaml" | |
require "base64" | |
require "active_support/core_ext/hash" | |
def print_usage | |
puts <<-USAGE | |
Desc: Edit a kube secret resource, automatically handling base64 | |
Usage: edit-secret <ctx> <namespace> <release-name> | |
Examples... | |
edit-secret prd production sentry | |
USAGE | |
end | |
class Kubectl | |
def initialize(context, namespace) | |
@context = context | |
@namespace = namespace | |
end | |
def connect! | |
output, status = exec("get", "pods") | |
return true if status.success? | |
STDERR.puts(output) | |
raise "failed to connect to kube!" | |
end | |
def get(resource:, name:) | |
output, status = exec("get", "-o", "yaml", resource, name) | |
return YAML.load(output) if status.success? | |
raise "failed to access #{resource} named #{name}!" | |
end | |
def apply(content) | |
output, status = exec("apply", "-f", "-", stdin_data: content) | |
return output if status.success? | |
STDERR.puts(output) | |
raise "failed to apply resource!" | |
end | |
# returns output, status | |
def exec(*args, stdin_data: nil) | |
Open3.capture2e( | |
Shellwords.join([ | |
"kubectl", | |
"--context", @context, | |
"--namespace", @namespace, | |
*args, | |
]), | |
stdin_data: stdin_data, | |
) | |
end | |
end | |
def edit_yaml(value) | |
tmp = Tempfile.new | |
tmp.write(value.to_yaml) | |
tmp.close | |
# Open the secret values for editing | |
Kernel.system("#{ENV.fetch("EDITOR", "vim")} #{tmp.path}") | |
updated_content = File.read(tmp.path) | |
if updated_content == value.to_yaml | |
puts("No changes made, exiting") | |
exit 0 | |
end | |
tmp.unlink | |
YAML.load(updated_content) | |
end | |
def deep_transform(hash, &block) | |
hash.transform_values do |value| | |
value.is_a?(Hash) ? deep_transform(value, &block) : block.call("#{value}") | |
end | |
end | |
context, namespace, release = ARGV | |
unless context && namespace && release | |
print_usage | |
exit | |
end | |
kubectl = Kubectl.new(context, namespace).tap(&:connect!) | |
secret = kubectl.get(resource: "secret", name: "values-#{release}") | |
secret.fetch('metadata').delete('creationTimestamp') | |
secret_data = secret.fetch('data', {}) | |
decoded = deep_transform(secret_data, &Base64.method(:strict_decode64)) | |
encoded = deep_transform(edit_yaml(decoded), &Base64.method(:strict_encode64)) | |
kubectl.apply(secret.merge('data' => encoded).to_yaml) | |
puts("Saved new secret values") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment