ferry 1.3.3 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d2ea374461adb3e147321f225cb172802431a78a
4
- data.tar.gz: fae16da54831f76bbc8722d47c5bb8ddedad3313
3
+ metadata.gz: f492db93e09993eb5609bb9550f8bf3fc3076cd5
4
+ data.tar.gz: afca6fdd10a193d69ccf45f141c814b914f74972
5
5
  SHA512:
6
- metadata.gz: 3fc0b7f1a21ab1a7cf7a6d12fcb131615f2e1ae59829464ab3d9a68a1ebd9ff24a28768023ccf1d9938b110531f3967690a5f6412471ed865529cd8356b0e26d
7
- data.tar.gz: a29778e674b94c6c89296753e94c98b0bc1ade3993083e595ea4b94b613f060a938a36b104febad177318687a7bf29fd3e68c566440876a922691f33f2251713
6
+ metadata.gz: 9b17c36ac8df1dff74d595e7f0d1112364562f462b069207fa341986184b9df60a07d2682d672a1445067f4fba97561786d3fc322102806e662ccbf65318ac76
7
+ data.tar.gz: 366782e71c8fa8a83fd784cc13e965a01a3ef6fcd2b58578ff832f1c59dbaedc8b4e80bc09a5897ae1caf7a5712bf1a3ac5b6e5b004a10d6928ab3a5e0ec637d
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- ![ferry](doc/ferry_readme_icon_2.png)
1
+ ![ferry](img/ferry_readme_icon_2.png)
2
2
 
3
3
  [![Build Status](https://travis-ci.org/cmu-is-projects/ferry.svg?branch=master)](https://travis-ci.org/cmu-is-projects/ferry)
4
4
  [![Gem Version](https://badge.fury.io/rb/ferry.svg)](http://badge.fury.io/rb/ferry)
data/bin/ferry CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/ruby
2
2
  require 'ferry'
3
+ # require 'all'
3
4
 
4
5
  OptionParser.new do |opts|
5
6
  options = {}
@@ -36,10 +37,9 @@ OptionParser.new do |opts|
36
37
  importer.import_json(opt, ARGV[0], ARGV[1])
37
38
  end
38
39
 
39
- opts.on('-i', '--init', 'Initializes ferry.rb file in config directory') do |opt|
40
- filemaker = Ferry::Utilities.new
41
- filemaker.make_starter_file
42
- end
40
+ # opts.on('--init', 'Installs and configures ferry') do |opt|
41
+ # Ferry::DSL
42
+ # end
43
43
 
44
44
  opts.on("--to_csv ENVIRONMENT TABLE", 'Exports table to csv file in db/csv/[your db environment]/[your table]') do |opt|
45
45
  check_appro_args(1)
File without changes
File without changes
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/ruby ferry
2
+ include Ferry::DSL
3
+ require 'ferry/install'
@@ -0,0 +1,14 @@
1
+ require 'rake'
2
+ require 'sshkit'
3
+
4
+ require 'io/console'
5
+
6
+ Rake.application.options.trace = true
7
+
8
+ require 'ferry/i18n'
9
+ require 'ferry/dsl'
10
+ require 'ferry/configuration'
11
+
12
+ module Ferry
13
+
14
+ end
@@ -0,0 +1,142 @@
1
+ require_relative 'configuration/filter'
2
+ require_relative 'configuration/question'
3
+ require_relative 'configuration/server'
4
+ require_relative 'configuration/servers'
5
+
6
+ module Ferry
7
+ class Configuration
8
+
9
+ def initialize(config = nil)
10
+ @config ||= config
11
+ end
12
+
13
+ def self.env
14
+ @env ||= new
15
+ end
16
+
17
+ def self.reset!
18
+ @env = new
19
+ end
20
+
21
+ def ask(key, default=nil, options={})
22
+ question = Question.new(key, default, options)
23
+ set(key, question)
24
+ end
25
+
26
+ def set(key, value)
27
+ config[key] = value
28
+ end
29
+
30
+ def set_if_empty(key, value)
31
+ config[key] = value unless config.has_key? key
32
+ end
33
+
34
+ def delete(key)
35
+ config.delete(key)
36
+ end
37
+
38
+ def fetch(key, default=nil, &block)
39
+ value = fetch_for(key, default, &block)
40
+ while callable_without_parameters?(value)
41
+ value = set(key, value.call)
42
+ end
43
+ return value
44
+ end
45
+
46
+ def keys
47
+ config.keys
48
+ end
49
+
50
+ def role(name, hosts, options={})
51
+ if name == :all
52
+ raise ArgumentError.new("#{name} reserved name for role. Please choose another name")
53
+ end
54
+
55
+ servers.add_role(name, hosts, options)
56
+ end
57
+
58
+ def server(name, properties={})
59
+ servers.add_host(name, properties)
60
+ end
61
+
62
+ def roles_for(names)
63
+ servers.roles_for(names)
64
+ end
65
+
66
+ def role_properties_for(names, &block)
67
+ servers.role_properties_for(names, &block)
68
+ end
69
+
70
+ def primary(role)
71
+ servers.fetch_primary(role)
72
+ end
73
+
74
+ def backend
75
+ @backend ||= SSHKit
76
+ end
77
+
78
+ attr_writer :backend
79
+
80
+ def configure_backend
81
+ backend.configure do |sshkit|
82
+ sshkit.format = fetch(:format)
83
+ sshkit.output_verbosity = fetch(:log_level)
84
+ sshkit.default_env = fetch(:default_env)
85
+ sshkit.backend = fetch(:sshkit_backend, SSHKit::Backend::Netssh)
86
+ sshkit.backend.configure do |backend|
87
+ backend.pty = fetch(:pty)
88
+ backend.connection_timeout = fetch(:connection_timeout)
89
+ backend.ssh_options = (backend.ssh_options || {}).merge(fetch(:ssh_options,{}))
90
+ end
91
+ end
92
+ end
93
+
94
+ def timestamp
95
+ @timestamp ||= Time.now.utc
96
+ end
97
+
98
+ def setup_filters
99
+ @filters = cmdline_filters.clone
100
+ @filters << Filter.new(:role, ENV['ROLES']) if ENV['ROLES']
101
+ @filters << Filter.new(:host, ENV['HOSTS']) if ENV['HOSTS']
102
+ fh = fetch_for(:filter,{}) || {}
103
+ @filters << Filter.new(:host, fh[:host]) if fh[:host]
104
+ @filters << Filter.new(:role, fh[:role]) if fh[:role]
105
+ end
106
+
107
+ def add_cmdline_filter(type, values)
108
+ cmdline_filters << Filter.new(type, values)
109
+ end
110
+
111
+ def filter list
112
+ setup_filters if @filters.nil?
113
+ @filters.reduce(list) { |l,f| f.filter l }
114
+ end
115
+
116
+ private
117
+
118
+ def cmdline_filters
119
+ @cmdline_filters ||= []
120
+ end
121
+
122
+ def servers
123
+ @servers ||= Servers.new
124
+ end
125
+
126
+ def config
127
+ @config ||= Hash.new
128
+ end
129
+
130
+ def fetch_for(key, default, &block)
131
+ if block_given?
132
+ config.fetch(key, &block)
133
+ else
134
+ config.fetch(key, default)
135
+ end
136
+ end
137
+
138
+ def callable_without_parameters?(x)
139
+ x.respond_to?(:call) && ( !x.respond_to?(:arity) || x.arity == 0)
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,56 @@
1
+ require 'ferry/configuration'
2
+
3
+ module Ferry
4
+ class Configuration
5
+ class Filter
6
+ def initialize type, values = nil
7
+ raise "Invalid filter type #{type}" unless [:host,:role].include? type
8
+ av = Array(values).dup
9
+ @mode = case
10
+ when av.size == 0 then :none
11
+ when av.include?(:all) then :all
12
+ else type
13
+ end
14
+ @rex = case @mode
15
+ when :host
16
+ av.map!{|v| (v.is_a?(String) && v =~ /^(?<name>[-A-Za-z0-9.]+)(,\g<name>)*$/) ? v.split(',') : v }
17
+ av.flatten!
18
+ av.map! do |v|
19
+ case v
20
+ when Regexp then v
21
+ else
22
+ vs = v.to_s
23
+ vs =~ /^[-A-Za-z0-9.]+$/ ? vs : Regexp.new(vs)
24
+ end
25
+ end
26
+ Regexp.union av
27
+ when :role
28
+ av.map!{|v| v.is_a?(String) ? v.split(',') : v }
29
+ av.flatten!
30
+ av.map! do |v|
31
+ case v
32
+ when Regexp then v
33
+ else
34
+ vs = v.to_s
35
+ vs =~ %r{^/(.+)/$} ? Regexp.new($1) : %r{^#{vs}$}
36
+ end
37
+ end
38
+ Regexp.union av
39
+ else
40
+ nil
41
+ end
42
+ end
43
+ def filter servers
44
+ as = Array(servers)
45
+ case @mode
46
+ when :none then return []
47
+ when :all then return servers
48
+ when :host
49
+ as.select {|s| @rex.match s.to_s}
50
+ when :role
51
+ as.select { |s| s.is_a?(String) ? false : s.roles.any? {|r| @rex.match r} }
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,53 @@
1
+ module Ferry
2
+ module Configuration
3
+ module Question
4
+ def initialize(key, default, options = {})
5
+ @key, @default, @options = key, default, options
6
+ end
7
+
8
+ def call
9
+ ask_question
10
+ value_or_default
11
+ end
12
+
13
+ private
14
+ attr_reader :key, :default, :options
15
+
16
+ def ask_question
17
+ $stdout.print question
18
+ end
19
+
20
+ def value_or_default
21
+ if response.empty?
22
+ default
23
+ else
24
+ response
25
+ end
26
+ end
27
+
28
+ def response
29
+ return @response if defined? @response
30
+
31
+ @response = (gets || "").chomp
32
+ end
33
+
34
+ def gets
35
+ if echo?
36
+ $stdin.gets
37
+ else
38
+ $stdin.noecho(&:gets).tap{ $stdout.print "\n" }
39
+ end
40
+ rescue Errno::EIO
41
+ # when stdio gets closed
42
+ end
43
+
44
+ def question
45
+ I18n.t(:question, key: key, default_value: default, scope: :capistrano)
46
+ end
47
+
48
+ def echo?
49
+ (options || {}).fetch(:echo, true)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,131 @@
1
+ require 'set'
2
+ module Ferry
3
+ class Configuration
4
+ class Server < SSHKit::Host
5
+ extend Forwardable
6
+ def_delegators :properties, :roles, :fetch, :set
7
+
8
+ def self.[](host)
9
+ host.is_a?(Server) ? host : new(host)
10
+ end
11
+
12
+ def add_roles(roles)
13
+ Array(roles).each { |role| add_role(role) }
14
+ self
15
+ end
16
+ alias roles= add_roles
17
+
18
+ def add_role(role)
19
+ roles.add role.to_sym
20
+ self
21
+ end
22
+
23
+ def has_role?(role)
24
+ roles.include? role.to_sym
25
+ end
26
+
27
+ def select?(options)
28
+ options.each do |k,v|
29
+ callable = v.respond_to?(:call) ? v: ->(server){server.fetch(v)}
30
+ result = case k
31
+ when :filter, :select
32
+ callable.call(self)
33
+ when :exclude
34
+ !callable.call(self)
35
+ else
36
+ self.fetch(k) == v
37
+ end
38
+ return false unless result
39
+ end
40
+ return true
41
+ end
42
+
43
+ def primary
44
+ self if fetch(:primary)
45
+ end
46
+
47
+ def with(properties)
48
+ properties.each { |key, value| add_property(key, value) }
49
+ self
50
+ end
51
+
52
+ def properties
53
+ @properties ||= Properties.new
54
+ end
55
+
56
+ def netssh_options
57
+ @netssh_options ||= super.merge( fetch(:ssh_options) || {} )
58
+ end
59
+
60
+ def roles_array
61
+ roles.to_a
62
+ end
63
+
64
+ def matches?(other)
65
+ hostname == other.hostname
66
+ end
67
+
68
+ private
69
+
70
+ def add_property(key, value)
71
+ if respond_to?("#{key}=")
72
+ send("#{key}=", value)
73
+ else
74
+ set(key, value)
75
+ end
76
+ end
77
+
78
+ class Properties
79
+
80
+ def initialize
81
+ @properties = {}
82
+ end
83
+
84
+ def set(key, value)
85
+ pval = @properties[key]
86
+ if pval.is_a? Hash and value.is_a? Hash
87
+ pval.merge!(value)
88
+ elsif pval.is_a? Set and value.is_a? Set
89
+ pval.merge(value)
90
+ elsif pval.is_a? Array and value.is_a? Array
91
+ pval.concat value
92
+ else
93
+ @properties[key] = value
94
+ end
95
+ end
96
+
97
+ def fetch(key)
98
+ @properties[key]
99
+ end
100
+
101
+ def respond_to?(method, include_all=false)
102
+ @properties.has_key?(method)
103
+ end
104
+
105
+ def roles
106
+ @roles ||= Set.new
107
+ end
108
+
109
+ def keys
110
+ @properties.keys
111
+ end
112
+
113
+ def method_missing(key, value=nil)
114
+ if value
115
+ set(lvalue(key), value)
116
+ else
117
+ fetch(key)
118
+ end
119
+ end
120
+
121
+ private
122
+
123
+ def lvalue(key)
124
+ key.to_s.chomp('=').to_sym
125
+ end
126
+
127
+ end
128
+
129
+ end
130
+ end
131
+ end