module MachineConfigure # The Exporter is responsible for finding all # necessary certificates for a given docker-machine, # and bundle them all into a single zip archive. class Exporter include Helpers::Message include Helpers::Shared # Initialize with a docker-machine name. def initialize name @machine_name = name VALIDATOR.validate_machine_name name @dir = { machine: DM_MACHINES_PATH.join(@machine_name), certs: DM_CERTS_PATH.join(@machine_name) } VALIDATOR.validate_directories @dir[:machine] @contents = nil end # Export certificates for the machine. def export_to zip_file zip_file = Pathname.new "#{zip_file.to_s}#{zip_file.to_s.match(/\.zip\z/i) ? '' : '.zip'}" VALIDATOR.validate_zip_file_export zip_file files = get_files @contents = get_contents_from_files(*files) config_json_path = get_config_json_path @contents[config_json_path] = remove_home_in @contents[config_json_path] @contents[MACHINE_NAME_FILENAME] = @machine_name write_zip_file_to zip_file message( "Successfully created zip archive", " `#{zip_file.to_s}'", "with the keys and certificates from docker-machine", " `#{@machine_name}'" ) end private # Returns all necessary filepaths. def get_files return @dir.values.map do |dir| next get_files_recursively_from dir end .reject { |x| !x } .flatten end # Returns all filepaths from directory, recursively. def get_files_recursively_from directory dir = Pathname.new directory return nil unless (dir.directory?) return dir.each_child.map do |file| next file.realpath.to_path if (file.file?) next get_files_recursively_from file if (file.directory?) end .flatten end # Reads contents from files, and returns # a Hash with the file's filepath as the key and # the file's content as the value. # The filepath key is the absolute path to the file, # but _without_ the DM_STORAGE_PATH. def get_contents_from_files *files return files.flatten.map do |filename| file = Pathname.new filename content = file.read path = remove_storage_path_from file.to_path next [path, content] end .to_h end # Write the processed @contents to # a zip archive using Zip. def write_zip_file_to zip_file Zip::File.open(zip_file, Zip::File::CREATE) do |zip| @contents.each do |filepath, content| zip.get_output_stream(filepath) do |zipfile| zipfile.write content end end end end end end