class Renuo::Cli::Commands::FetchSecrets
Constants
- CONFIG_FILE
Public Instance Methods
Source
# File lib/renuo/cli/commands/fetch_secrets.rb, line 18 def init(private_vault_link) abort("Config file #{CONFIG_FILE} already exists.") if File.exist?(CONFIG_FILE) File.write(CONFIG_FILE, generate_config_file(private_vault_link)) end
Source
# File lib/renuo/cli/commands/fetch_secrets.rb, line 23 def run unless ENV["CI"] system("which op > /dev/null") || abort("op is not installed. Please install it (e.g. brew install " \ "1password-cli).") end abort("Config file #{CONFIG_FILE} not found.") unless File.exist?(CONFIG_FILE) config = Psych.load_file(CONFIG_FILE).deep_symbolize_keys config[:items].each do |item| elaborate_item(item) end end
Private Instance Methods
Source
# File lib/renuo/cli/commands/fetch_secrets.rb, line 126 def download_file_from_item(files, vault_id, item_id, filename, output_path) item_file = files&.find { |tmp_file_config| tmp_file_config["name"].eql?(filename) } if item_file.nil? warn "File `#{filename}` not found in item #{item_id}. Check the file name in your #{CONFIG_FILE} file." return end execute_command(command: "op read \"op://#{vault_id}/#{item_id}/#{item_file["id"]}\" --out-file #{output_path}", success_message: "Successfully fetched #{filename} and saved to #{output_path}", error_message: "Error fetching #{filename}.") end
Source
# File lib/renuo/cli/commands/fetch_secrets.rb, line 43 def elaborate_item(item) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity private_link = item[:private_link] if private_link.nil? warn "Private link not found in your config file." return elsif private_link.include?("share.1password.com") warn "Please use a private link, not a share link." return end item_id = extract_item_id(private_link) item_json = get_item(item_id) return if item_json.nil? item[:env_variables]&.each do |env_variable| process_env_variable(env_variable[:name], item_id, item_json) end item[:files]&.each do |file| process_file(file[:folder] || item[:default_folder], file[:name], item_json, item_id) end end
Source
# File lib/renuo/cli/commands/fetch_secrets.rb, line 78 def execute_command(command:, success_message:, error_message:) output = `#{command}` if $CHILD_STATUS.success? puts success_message unless success_message.empty? output else warn error_message end end
Source
# File lib/renuo/cli/commands/fetch_secrets.rb, line 66 def extract_item_id(private_link) /&i=([^&]+)/.match(private_link)[1] end
Source
# File lib/renuo/cli/commands/fetch_secrets.rb, line 39 def generate_config_file(private_vault_link) { "items" => [{ "private_link" => private_vault_link, "files" => [], "env_variables" => [] }] }.to_yaml end
Source
# File lib/renuo/cli/commands/fetch_secrets.rb, line 70 def get_item(item_id) output = execute_command(command: "op item get #{item_id} --format json", success_message: "", error_message: "Error fetching item #{item_id}." \ "Check `private_link` in your #{CONFIG_FILE} file.") JSON.parse(output) if output end
Source
# File lib/renuo/cli/commands/fetch_secrets.rb, line 88 def process_env_variable(name, item_id, item_json) env_json = item_json["fields"].find { |field| field["label"] == name } if env_json.nil? warn "Field `#{name}` not found in item #{item_id}. Check the field name in your #{CONFIG_FILE} file." else value = env_json["value"] update_or_add_variable(".env", name, /^#{name}=/, "#{name}=#{value}") update_or_add_variable("config/application.yml", name, /^#{name}:.*$/, "#{name}: \"#{value}\"") end end
Source
# File lib/renuo/cli/commands/fetch_secrets.rb, line 117 def process_file(output_folder, filename, item, item_id) FileUtils.mkdir_p(output_folder) output_path = File.join(output_folder, filename) vault_id = item.dig("vault", "id") download_file_from_item(item["files"], vault_id, item_id, filename, output_path) puts "\n\n" end
Source
# File lib/renuo/cli/commands/fetch_secrets.rb, line 99 def update_or_add_variable(file_path, name, pattern, replacement) # rubocop:disable Metrics/MethodLength return unless File.exist?(file_path) file_contents = File.read(file_path) updated_contents = file_contents if file_contents.match(pattern) if ask("Do you want to update the value of #{name} in #{file_path}? (y/n)", "y") == "y" updated_contents = file_contents.gsub(pattern, replacement) end else puts "Added environment variable #{name} to #{file_path}" updated_contents = "#{file_contents}#{replacement}\n" end File.write(file_path, updated_contents) end