redirus 0.1.2 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,173 @@
1
+ require 'optparse'
2
+ require 'singleton'
3
+ require 'erb'
4
+
5
+ module Redirus
6
+ module Cli
7
+ class Init
8
+ include Singleton
9
+
10
+ attr_reader :options
11
+
12
+ def parse(args = ARGV)
13
+ init_options(args)
14
+ validate!
15
+ end
16
+
17
+ def run
18
+ generate_templates
19
+ mkdir(@options[:configs_dir])
20
+ mkdir(@options[:log_dir])
21
+ end
22
+
23
+ private
24
+
25
+ def generate_templates
26
+ Dir[File.join(tmpl_dir, '*')].each { |tmpl| generate(tmpl) }
27
+ end
28
+
29
+ def mkdir(dir)
30
+ Dir.mkdir(dir) unless Dir.exist?(dir)
31
+ end
32
+
33
+ def tmpl_dir
34
+ @templates ||= File.join(Redirus.root, 'templates')
35
+ end
36
+
37
+ def init_options(args)
38
+ opts = parse_options(args)
39
+ @options = defaults.merge(opts)
40
+ @options[:http_template] = target('http.conf.erb')
41
+ @options[:https_template] = target('https.conf.erb')
42
+ end
43
+
44
+ def parse_options(args)
45
+ opts = {}
46
+
47
+ parser = OptionParser.new do |o|
48
+ o.on('-t', '--target PATH',
49
+ 'Target path (default current dir)') do |arg|
50
+ opts[:target] = arg
51
+ opts[:pid] = File.join(arg, 'nginx.pid')
52
+ opts[:configs_dir] = File.join(arg, 'configurations')
53
+ opts[:log_dir] = File.join(arg, 'log')
54
+ end
55
+
56
+ o.on('--ip IP', 'Server IP address (default *)') do |arg|
57
+ opts[:ip] = arg
58
+ end
59
+
60
+ o.on('--server-name NAME', 'Server name') do |arg|
61
+ opts[:server_name] = arg
62
+ end
63
+
64
+ o.on('--ssl-cert PATH', 'Server certificate path') do |arg|
65
+ opts[:ssl_cert] = arg
66
+ end
67
+
68
+ o.on('--ssl-cert-key PATH', 'Server certificate key path') do |arg|
69
+ opts[:ssl_cert_key] = arg
70
+ end
71
+
72
+ o.on('--nginx-pid PATH',
73
+ 'Nginx pid location (default nginx.pid in '\
74
+ 'current dir)') do |arg|
75
+ opts[:pid] = arg
76
+ end
77
+
78
+ o.on('--configurations DIR',
79
+ 'Directory where nginx configs will be generated '\
80
+ '(default "configurations" in current directory)') do |arg|
81
+ opts[:configs_dir] = arg
82
+ end
83
+
84
+ o.on('--logs DIR', 'Directory where nginx logs will be placed'\
85
+ '(default "log" dir in current dirrectory)') do |arg|
86
+ opts[:log_dir] = arg
87
+ end
88
+
89
+ o.on('--redis URL',
90
+ 'Redis location (default "redis://localhost:6379")') do |arg|
91
+ opts[:redis] = arg
92
+ end
93
+
94
+ o.on('--queues', Array,
95
+ 'List of redirs queues (default ["redirus"]') do |arg|
96
+ opts[:queues] = arg
97
+ end
98
+
99
+ o.on_tail('-h', '--help', 'Show this message') do
100
+ puts o
101
+ exit
102
+ end
103
+
104
+ o.on_tail('-v', '--version', 'Show version') do
105
+ puts "Redirus #{Redirus::VERSION}"
106
+ exit
107
+ end
108
+ end
109
+
110
+ parser.banner = 'redirus-init [options]'
111
+ parser.parse!(args)
112
+
113
+ opts
114
+ end
115
+
116
+ def defaults
117
+ {
118
+ target: Dir.pwd,
119
+ ip: '*',
120
+ server_name: 'CHANGE_ME',
121
+ pid: File.join(Dir.pwd, 'nginx.pid'),
122
+ configs_dir: File.join(Dir.pwd, 'configurations'),
123
+ log_dir: File.join(Dir.pwd, 'log'),
124
+ redis: 'redis://localhost:6379',
125
+ queues: ['redirus']
126
+ }
127
+ end
128
+
129
+ def validate!
130
+ check_target_dir!
131
+ check_ip!
132
+ check_pid_dir!
133
+ end
134
+
135
+ def check_target_dir!
136
+ return if Dir.exist?(options[:target])
137
+
138
+ puts "ERROR: Directory #{options[:target]} does not exist"
139
+ exit(1)
140
+ end
141
+
142
+ def check_ip!
143
+ return if valid_id?
144
+
145
+ puts 'ERROR: Server IP is not valid'
146
+ exit(1)
147
+ end
148
+
149
+ def valid_id?
150
+ options[:ip] == '*' ||
151
+ options[:ip].match(/\A\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}:\d+\z/)
152
+ end
153
+
154
+ def check_pid_dir!
155
+ return if Dir.exist?(File.dirname(options[:pid]))
156
+
157
+ puts 'ERROR: Pid directory does not exist'
158
+ exit(1)
159
+ end
160
+
161
+ def generate(tmpl)
162
+ File.open(target(tmpl), 'w') do |file|
163
+ erb = ERB.new(File.read(tmpl), nil, '-')
164
+ file.write(erb.result(binding))
165
+ end
166
+ end
167
+
168
+ def target(tmpl)
169
+ File.join(@options[:target], File.basename(tmpl))
170
+ end
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,101 @@
1
+ require 'optparse'
2
+ require 'singleton'
3
+ require 'sidekiq/cli'
4
+
5
+ module Redirus
6
+ module Cli
7
+ class Server
8
+ include Singleton
9
+
10
+ attr_reader :options
11
+
12
+ def parse(args = ARGV)
13
+ init_options(args)
14
+ validate!
15
+ end
16
+
17
+ def run
18
+ Redirus.config_path = options[:config_path]
19
+ init_sidekiq
20
+
21
+ sidekiq_cli = Sidekiq::CLI.instance
22
+ args = queues + [
23
+ '-c', '1',
24
+ '-r', runner_path,
25
+ options[:config_path]
26
+ ]
27
+
28
+ sidekiq_cli.parse(args)
29
+ sidekiq_cli.run
30
+ end
31
+
32
+ private
33
+
34
+ def init_sidekiq
35
+ Sidekiq.configure_server do |config|
36
+ config.redis = {
37
+ namespace: Redirus.config.namespace,
38
+ url: Redirus.config.redis_url
39
+ }
40
+ end
41
+ end
42
+
43
+ def queues
44
+ Redirus.config.queues.inject([]) do |arr, q|
45
+ arr << '-q'
46
+ arr << q
47
+ end
48
+ end
49
+
50
+ def runner_path
51
+ module_path = File.expand_path(File.join(
52
+ File.dirname(__FILE__), '..', '..'))
53
+
54
+ File.join(module_path, 'redirus.rb')
55
+ end
56
+
57
+ def init_options(args)
58
+ opts = parse_options(args)
59
+ opts[:config_path] ||= 'config.yml'
60
+
61
+ Redirus.config_path = opts[:config_path]
62
+
63
+ @options = opts
64
+ end
65
+
66
+ def parse_options(args)
67
+ opts = {}
68
+
69
+ OptionParser.new do |o|
70
+ o.banner = 'Usage: redirus [options]'
71
+
72
+ o.on('-c',
73
+ '--configuration PATH',
74
+ 'Yaml redirus configuration path') do |arg|
75
+ opts[:config_path] = arg
76
+ end
77
+
78
+ o.on_tail('-h', '--help', 'Show this message') do
79
+ puts o
80
+ exit
81
+ end
82
+
83
+ o.on_tail('-v', '--version', 'Show version') do
84
+ puts "Redirus #{Redirus::VERSION}"
85
+ exit
86
+ end
87
+ end.parse!(args)
88
+
89
+ opts
90
+ end
91
+
92
+ def validate!
93
+ unless File.exist?(options[:config_path])
94
+ puts "ERROR: Configuration file #{options[:config_path]} "\
95
+ 'does not exist'
96
+ exit(1)
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
data/lib/redirus/cli.rb CHANGED
@@ -1,144 +1,7 @@
1
- require 'optparse'
2
- require 'singleton'
3
-
4
- Sidekiq.configure_client do |c|
5
- c.redis = {
6
- namespace: Redirus.config.namespace,
7
- url: Redirus.config.redis_url
8
- }
9
- end
10
-
11
1
  module Redirus
12
- class CLI
13
- include Singleton
14
-
15
- attr_reader :options
16
-
17
- def parse(args = ARGV)
18
- init_options(args)
19
- validate!
20
- end
21
-
22
- def run
23
- add? ? add : rm
24
- end
25
-
26
- private
27
-
28
- def init_options(args)
29
- opts = parse_options(args)
30
- opts[:config_path] ||= 'config.yml'
31
-
32
- Redirus.config_path = opts[:config_path]
33
-
34
- @options = defaults.merge(opts)
35
- end
36
-
37
- def parse_options(args)
38
- opts = {}
39
-
40
- parser = OptionParser.new do |o|
41
- o.on('-c', '--configuration PATH', 'Configuration path') do |arg|
42
- opts[:config_path] = arg
43
- end
44
-
45
- o.on('-a',
46
- '--action TYPE', [:add, :rm],
47
- 'Action type (add, rm)') do |arg|
48
- opts[:action] = arg
49
- end
50
-
51
- o.on('-q', '--queue NAME', 'Queue name') do |arg|
52
- opts[:queue] = arg
53
- end
54
-
55
- o.on(
56
- '-t',
57
- '--type TYPE',
58
- [:http, :https],
59
- 'Rediraction type') do |arg|
60
- opts[:type] = arg
61
- end
62
-
63
- o.on_tail("-h", "--help", "Show this message") do
64
- puts o
65
- exit
66
- end
67
-
68
- o.on_tail('-v', '--version', 'Show version') do
69
- puts "Redirus #{Redirus.VERSION}"
70
- exit
71
- end
72
- end
73
-
74
- parser.banner = 'redirus-client [options] name [upstream1,upstream2,...]'
75
- parser.parse!(args)
76
-
77
- opts[:name] = args.shift
78
-
79
- upstreams_str = args.shift
80
- opts[:upstreams] = upstreams_str.split(',') if upstreams_str
81
-
82
- opts
83
- end
84
-
85
- def defaults
86
- {
87
- config_path: 'config.yml',
88
- type: :http,
89
- action: :add,
90
- queue: Redirus.config.queues.first
91
- }
92
- end
93
-
94
- def validate!
95
- unless File.exist?(options[:config_path])
96
- puts "ERROR: Configuration file #{options[:config_path]} does not exist"
97
- exit(1)
98
- end
99
-
100
- unless options[:name]
101
- puts "ERROR: Redirection name is not set"
102
- exit(1)
103
- end
104
-
105
- if add?
106
- unless options[:upstreams]
107
- puts "ERROR: Upstream locations are not set"
108
- exit(1)
109
- else
110
- options[:upstreams].each do |u|
111
- unless u.match(/\A\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}:\d+\z/)
112
- puts "ERROR: #{u} is not valid upstream definition, use IP:PORT schema"
113
- exit(1)
114
- end
115
- end
116
- end
117
- end
118
-
119
- Redirus.config_path = options[:config_path]
120
- end
121
-
122
- def add?
123
- options[:action] == :add
124
- end
125
-
126
- def add
127
- puts "Adding new redirection #{options[:name]} with following upstreams #{options[:upstreams]}"
128
-
129
- Sidekiq::Client.push(
130
- 'queue' => options[:queue],
131
- 'class' => Redirus::Worker::AddProxy,
132
- 'args' => [options[:name], options[:upstreams], options[:type]])
133
- end
134
-
135
- def rm
136
- puts "Removing redirection #{options[:name]}"
137
-
138
- Sidekiq::Client.push(
139
- 'queue' => options[:queue],
140
- 'class' => Redirus::Worker::RmProxy,
141
- 'args' => [options[:name], options[:type]])
142
- end
2
+ module Cli
3
+ autoload :Client, 'redirus/cli/client'
4
+ autoload :Init, 'redirus/cli/init'
5
+ autoload :Server, 'redirus/cli/server'
143
6
  end
144
7
  end
@@ -33,30 +33,11 @@ module Redirus
33
33
  end
34
34
 
35
35
  def http_template
36
- nginx_prop :http_template, 'listen *:80;'
36
+ nginx_prop :http_template, 'http.conf.erb'
37
37
  end
38
38
 
39
39
  def https_template
40
- nginx_prop :https_template, %q[listen *:443 ssl;
41
- ssl_certificate /usr/share/ssl/certs/localhost/host.cert;
42
- ssl_certificate_key /usr/share/ssl/certs/localhost/host.key;
43
- ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
44
- ]
45
- end
46
-
47
- def config_template
48
- nginx_prop :config_template, %q[#{upstream}
49
-
50
- server {
51
- #{listen}
52
-
53
- server_name #{name}.localhost;
54
- server_tokens off;
55
-
56
- location / {
57
- proxy_pass http://#{upstream_name};
58
- }
59
- }]
40
+ nginx_prop :https_template, 'https.conf.erb'
60
41
  end
61
42
 
62
43
  def allowed_properties
data/lib/redirus/proxy.rb CHANGED
@@ -5,19 +5,12 @@ module Redirus
5
5
  include Sidekiq::Worker
6
6
 
7
7
  def perform(*params)
8
- begin
9
- perform_action(*params)
10
- restart_nginx
11
- rescue Errno::EACCES => e
12
- $stderr << "Error: Cannot write to config files - continuing\n"
13
- $stderr << "#{e}\n"
14
- rescue Errno::ENOENT => e
15
- $stderr << "Error: Trying to remove non existing config files - continuing\n"
16
- $stderr << "#{e}\n"
17
- rescue Errno::ESRCH => e
18
- $stderr << "Warning: Nginx is dead - continuing\n"
19
- $stderr << "#{e}\n"
20
- end
8
+ perform_action(*params)
9
+ restart_nginx
10
+ rescue Errno::EACCES => e
11
+ error('Error: Cannot write to config files - continuing', e)
12
+ rescue Errno::ENOENT => e
13
+ error('Error: Remove non existing config files - continuing', e)
21
14
  end
22
15
 
23
16
  protected
@@ -26,23 +19,21 @@ module Redirus
26
19
  #by default do nothing
27
20
  end
28
21
 
29
- def full_name(name, type)
30
- "#{name}_#{type}"
31
- end
32
-
33
- def config_file_path(name, type)
34
- File.join(config.configs_path, full_name(name, type))
35
- end
36
-
37
- def config
38
- @config ||= Redirus.config
39
- end
22
+ private
40
23
 
41
24
  def restart_nginx
42
- File.open(config.nginx_pid_file) do |file|
25
+ File.open(Redirus.config.nginx_pid_file) do |file|
43
26
  pid = file.read.to_i
44
27
  Process.kill :SIGHUP, pid
45
28
  end
29
+ rescue Errno::ENOENT => e
30
+ error('Error: Nginx pid file does not exist - continuing', e)
31
+ rescue Errno::ESRCH => e
32
+ error('Warning: Nginx is dead - continuing', e)
33
+ end
34
+
35
+ def error(msg, e)
36
+ $stderr << "#{msg}\n - #{e}\n"
46
37
  end
47
38
  end
48
39
  end
@@ -0,0 +1,15 @@
1
+ module Redirus
2
+ module Utils
3
+ def full_name(name, type)
4
+ "#{name}_#{type}"
5
+ end
6
+
7
+ def config_file_path(name, type)
8
+ File.join(config.configs_path, full_name(name, type))
9
+ end
10
+
11
+ def config
12
+ @config ||= Redirus.config
13
+ end
14
+ end
15
+ end
@@ -1,3 +1,3 @@
1
1
  module Redirus
2
- VERSION = '0.1.2'
2
+ VERSION = '0.2.1'
3
3
  end
@@ -1,51 +1,62 @@
1
+ require 'erb'
2
+
1
3
  module Redirus
2
4
  module Worker
3
5
  class AddProxy < Proxy
4
6
 
5
- def perform_action(name, workers, type, props = nil)
6
- params = config_propertie(name, workers, type, props)
7
- File.open(config_file_path(name, type), 'w') do |file|
8
- param_regexp = '#{\w*}'
9
- file.write config.config_template
10
- .gsub(/#{param_regexp}/) { |p| params[p[2..-2]] }
11
- end
7
+ def perform_action(name, workers, type, location_props = nil, opt = {})
8
+ Action.new(name, workers, type, location_props, opt).execute
12
9
  end
13
10
 
14
11
  private
15
12
 
16
- def config_propertie(name, workers, type, props)
17
- {
18
- 'name' => name,
19
- 'listen' => https?(type) ? config.https_template : config.http_template,
20
- 'upstream' => upstream_conf(name, workers, type),
21
- 'upstream_name' => full_name(name, type),
22
- 'properties' => location_properties(props)
23
- }
24
- end
13
+ class Action
14
+ include Redirus::Utils
25
15
 
26
- def https?(type)
27
- type.to_s == 'https'
28
- end
16
+ def initialize(name, workers, type, location_props, options = {})
17
+ @name = name
18
+ @workers = workers
19
+ @type = type
20
+ @location_properties = location_properties(location_props) || []
21
+ @options = options
22
+ end
29
23
 
30
- def upstream_conf(name, workers, type)
31
- "upstream #{name}_#{type} {\n#{workers_conf(workers)}\}\n"
32
- end
24
+ attr_reader :name, :workers, :type
33
25
 
34
- def workers_conf(workers)
35
- workers.collect { |worker| " server #{worker};\n" }.join
36
- end
26
+ def execute
27
+ File.open(config_file_path(name, type), 'w') do |file|
28
+ erb = ERB.new(template, nil, '-')
29
+ file.write erb.result(binding)
30
+ end
31
+ end
37
32
 
38
- def location_properties(props)
39
- props.inject([]) do |tab, prop|
40
- tab << "#{prop};\n" if allowed? prop
41
- tab
42
- end.join('') if props
43
- end
33
+ private
44
34
 
45
- def allowed?(prop)
46
- config.allowed_properties
47
- .any? { |prop_regexp| /#{prop_regexp}/.match(prop) }
35
+ def location_properties(props)
36
+ props.inject([]) do |tab, prop|
37
+ tab << prop if allowed? prop
38
+ tab
39
+ end if props
40
+ end
41
+
42
+ def allowed?(prop)
43
+ config.
44
+ allowed_properties.
45
+ any? { |prop_regexp| /#{prop_regexp}/.match(prop) }
46
+ end
47
+
48
+ def template
49
+ File.read(template_path)
50
+ end
51
+
52
+ def template_path
53
+ https? ? config.https_template : config.http_template
54
+ end
55
+
56
+ def https?
57
+ type.to_s == 'https'
58
+ end
48
59
  end
49
60
  end
50
61
  end
51
- end
62
+ end
@@ -1,6 +1,7 @@
1
1
  module Redirus
2
2
  module Worker
3
3
  class RmProxy < Proxy
4
+ include Redirus::Utils
4
5
 
5
6
  def perform_action(name, type)
6
7
  File.delete(config_file_path(name, type))
data/lib/redirus.rb CHANGED
@@ -1,11 +1,12 @@
1
1
  require 'sidekiq'
2
+ require 'redirus/version'
2
3
 
3
4
  module Redirus
4
- autoload :Version, 'redirus/version'
5
- autoload :Config, 'redirus/config'
6
- autoload :Proxy, 'redirus/proxy'
7
- autoload :CLI, 'redirus/cli'
8
- autoload :ServerCLI, 'redirus/server_cli'
5
+ autoload :Config, 'redirus/config'
6
+ autoload :Proxy, 'redirus/proxy'
7
+ autoload :Utils, 'redirus/utils'
8
+ autoload :Cli, 'redirus/cli'
9
+ autoload :ServerCLI, 'redirus/server_cli'
9
10
 
10
11
  def self.config
11
12
  @@config ||= Redirus::Config.new(config_path)
@@ -19,6 +20,10 @@ module Redirus
19
20
  @@config_path = path
20
21
  @@config = nil
21
22
  end
23
+
24
+ def self.root
25
+ File.dirname __dir__
26
+ end
22
27
  end
23
28
 
24
29
  require 'redirus/worker'
data/redirus.gemspec CHANGED
@@ -18,12 +18,12 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
- spec.add_dependency 'sidekiq'
21
+ spec.add_dependency 'sidekiq', '~>3.2'
22
22
 
23
- spec.add_development_dependency 'bundler'
24
- spec.add_development_dependency 'rake'
25
- spec.add_development_dependency 'guard-rspec'
26
- spec.add_development_dependency 'shoulda-matchers'
27
- spec.add_development_dependency 'rspec-sidekiq'
28
- spec.add_development_dependency 'coveralls'
23
+ spec.add_development_dependency 'bundler', '~>1.7'
24
+ spec.add_development_dependency 'rake', '~>10'
25
+ spec.add_development_dependency 'guard-rspec', '~>4.3'
26
+ spec.add_development_dependency 'shoulda-matchers', '~>2.7'
27
+ spec.add_development_dependency 'rspec-sidekiq', '~>2.0'
28
+ spec.add_development_dependency 'coveralls', '~>0'
29
29
  end