class Brillo::Scrubber
Responsible for creating a fresh scrubbed SQL copy of the database, as specified via config, and uploading to S3
Responsible for asserting that the config file is valid
Constants
- JUMBLE_PRNG
- LATEST_LIMIT
- SCRUBBERS
Define some procs as scrubbing strategies for Polo
- TACTICS
Attributes
adapter[R]
config[R]
transferrer[R]
Public Class Methods
new(config)
click to toggle source
# File lib/brillo/scrubber.rb, line 30 def initialize(config) @config = config @adapter = config.adapter end
Public Instance Methods
dump_structure_and_migrations()
click to toggle source
# File lib/brillo/scrubber.rb, line 44 def dump_structure_and_migrations return unless config.recreate_db adapter.dump_structure_and_migrations(config) end
explore_all_classes()
click to toggle source
# File lib/brillo/scrubber.rb, line 49 def explore_all_classes File.open(config.dump_path, "a") do |sql_file| sql_file.puts(adapter.header) klass_association_map.each do |klass, options| begin klass = deserialize_class(klass) tactic = deserialize_tactic(klass, options) rescue ConfigParseError => e logger.error "Error in brillo.yml: #{e.message}" next end associations = options.fetch(:associations, []) explore_class(klass, tactic, associations) do |insert| sql_file.puts(insert) end end ActiveRecord::Base.descendants.each do |klass| sql_file.puts(adapter.table_footer(klass)) end sql_file.puts(adapter.footer) end end
scrub!()
click to toggle source
# File lib/brillo/scrubber.rb, line 35 def scrub! FileUtils.rm config.compressed_filename, force: true configure_polo dump_structure_and_migrations explore_all_classes compress config.transferrer.upload end
validate()
click to toggle source
# File lib/brillo/validator.rb, line 12 def validate errors = Hash.new({}.freeze) klass_association_map.each do |klass, options| begin real_klass = deserialize_class(klass) rescue errors[klass][:name] = "No such class #{klass.camelize}, did you use the singular?" end begin tactic = options.fetch("tactic").to_sym rescue KeyError errors[klass][:tactic] "Tactic not specified" end end end
Private Instance Methods
compress()
click to toggle source
# File lib/brillo/scrubber.rb, line 74 def compress return unless config.compress execute!("gzip -f #{config.dump_path}") end
configure_polo()
click to toggle source
# File lib/brillo/scrubber.rb, line 99 def configure_polo obfs = obfuscations adapter = config.db["adapter"] Polo.configure do obfuscate obfs if adapter == "mysql2" on_duplicate :ignore end end end
deserialize_class(klass)
click to toggle source
# File lib/brillo/scrubber.rb, line 110 def deserialize_class(klass) klass.to_s.camelize.constantize rescue raise ConfigParseError, "Could not process class '#{klass}'" end
deserialize_tactic(klass, options)
click to toggle source
# File lib/brillo/scrubber.rb, line 116 def deserialize_tactic(klass, options) options.fetch(:tactic).to_sym rescue KeyError raise ConfigParseError, "Tactic not specified for class #{klass}" end
explore_class(klass, tactic_or_ids, associations) { |"#{row};"| ... }
click to toggle source
# File lib/brillo/scrubber.rb, line 79 def explore_class(klass, tactic_or_ids, associations) ids = tactic_or_ids.is_a?(Symbol) ? TACTICS.fetch(tactic_or_ids).call(klass) : tactic_or_ids logger.info("Scrubbing #{ids.length} #{klass} rows with associations #{associations}") ActiveRecord::Base.connection.uncached do Polo.explore(klass, ids, associations).each do |row| yield "#{row};" end end end
klass_association_map()
click to toggle source
# File lib/brillo/scrubber.rb, line 89 def klass_association_map config.klass_association_map end
obfuscations()
click to toggle source
# File lib/brillo/scrubber.rb, line 93 def obfuscations config.obfuscations.map do |field, strategy| [field, SCRUBBERS.fetch(strategy)] end.to_h end