summaryrefslogtreecommitdiff
path: root/lib/tapicero/replication.rb
blob: 2d9b842a13cc131984f998ec88d20c8dc82a32a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
require 'couchrest'
require 'json'

module Tapicero
  class Replication

    attr_reader :source, :target

    LocalEndpoint = Struct.new(:name) do
      def key; name; end
      def url; name; end
      def save_url; name; end
    end

    RemoteEndpoint = Struct.new(:remote, :credentials) do
      def key;        domain; end
      def url;       "http://#{creds}@#{domain}:#{port}/#{name}"; end
      def save_url;  "http://#{username}@#{domain}:#{port}/#{name}"; end
      def domain;    remote["domain_internal"]; end
      def port;      remote["couch_port"]; end
      def name;      remote["name"]; end
      def creds;     username + ':' + credentials["password"]; end
      def username;  credentials["username"]; end
    end

    def initialize(source, target)
      @source = endpoint_for(source)
      @target = endpoint_for(target)
    end

    def run(options)
      Tapicero.logger.info "Replicating from #{source.save_url} to #{target.save_url}."
      replication_db.save_doc replication_doc.merge(options)
    end

    def replication_doc
      {
        "_id"      => source.domain.gsub('.', '_'),
        "source"   => source.url,
        "target"   => target.url,
        "user_ctx" => {
          name: replication_credentials["username"],
          roles: [replication_credentials["role"]]
        }
      }
    end

    protected

    def endpoint_for(hash_or_string)
      hash_or_string.respond_to?(:keys) ?
        RemoteEndpoint.new(hash_or_string, replication_credentials) :
        LocalEndpoint.new(hash_or_string)
    end

    def replication_credentials
      config.options[:replication].select do |k,v|
        %w/username password role/.include? k
      end
    end

    def replication_db
      @replication_db ||= couch.database('_replicator')
    end

    def couch
      @couch ||= CouchRest.new(config.couch_host)
    end

    def config
      Tapicero.config
    end

  end
end