ferry 1.3.3 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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