entrance-agent 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 034670028c5ffe7ad93f6b461d311e7e274be90e
4
+ data.tar.gz: 101e71764d9aedc96e243d6dd32fbe5c75d552f7
5
+ SHA512:
6
+ metadata.gz: 65bc755ac61898aca62779cd349f2c4ada100b768596bc7579109eb382d3aa7ec11ecb6767e945c4a24d709569a8cc0e6fb9730ada3717ee32f7382d82cb41f2
7
+ data.tar.gz: 6007f3d88a74e7db6c55c770655926f37cd1d6b3d11d373012f5194116eed2a1e2a993a7a33cafcef3635f28e9a5fa654e2b28b5df6fcd50de10dadb681f1a9e
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.1
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in entrance.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # Entrance::Agent
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/entrance/agent`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'entrance-agent'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install entrance-agent
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ 1. Fork it ( https://github.com/[my-github-username]/entrance/fork )
36
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
37
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
38
+ 4. Push to the branch (`git push origin my-new-feature`)
39
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/console ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "entrance/agent"
5
+ require "pry"
6
+ Pry.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,36 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'entrance/agent/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "entrance-agent"
8
+ spec.version = Entrance::Agent::VERSION
9
+ spec.authors = ["Mathias Kaufmann"]
10
+ spec.email = ["me@stei.gr"]
11
+
12
+ spec.summary = %q{Reverse Proxy/Load-Balancer based on Nerve and Synapse.}
13
+ spec.description = %q{Reverse Proxy/Load-Balancer based on Nerve and Synapse.}
14
+ spec.homepage = "https://doorkeepr.stei.gr/entrance"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "entrance-watcher"
22
+ spec.add_dependency "resolv-consul"
23
+ spec.add_dependency "thor"
24
+ spec.add_dependency "unirest"
25
+ spec.add_dependency "awesome_print"
26
+ spec.add_dependency "activesupport"
27
+ spec.add_dependency "boutons"
28
+ spec.add_dependency "synapse-easy"
29
+ spec.add_dependency "synapse-config"
30
+ spec.add_dependency "pry"
31
+ spec.add_dependency "uuidtools"
32
+ spec.add_dependency "fake-hash"
33
+
34
+ spec.add_development_dependency "bundler", "~> 1.8"
35
+ spec.add_development_dependency "rake", "~> 10.0"
36
+ end
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "entrance/agent/cli"
5
+
6
+ Entrance::Agent::Cli.start
@@ -0,0 +1,3 @@
1
+ require "entrance/agent/version"
2
+ require "entrance/agent/agent"
3
+ require "entrance/agent/cli"
@@ -0,0 +1,2 @@
1
+ require "entrance/agent/acl/base"
2
+ require "entrance/agent/acl/url_backend_router"
@@ -0,0 +1,32 @@
1
+ require "digest"
2
+
3
+ module Entrance
4
+ module Agent
5
+ module Acl
6
+ class Base
7
+ attr_accessor :name, :comparator, :value, :as_digest
8
+ def initialize params={}
9
+ @as_digest = params[:as_digest]
10
+ @as_digest ||= true if @as_digest.nil?
11
+ @comparator = params[:comparator]
12
+ @value = params[:value]
13
+ @name = params[:name]
14
+ end
15
+ def acl
16
+ @acl = []
17
+ @acl << "acl"
18
+ @acl << label
19
+ @acl << comparator
20
+ @acl << value
21
+ @acl.join(" ")
22
+ end
23
+ def label
24
+ as_digest ? Digest::MD5.hexdigest(name) : name
25
+ end
26
+ def condition
27
+ "if #{label}"
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,23 @@
1
+ require "entrance/agent/acl/base"
2
+
3
+ module Entrance
4
+ module Agent
5
+ module Acl
6
+ class UrlBackendRouter < Base
7
+ attr_accessor :url, :backend
8
+ def initialize params={}
9
+ @url = params[:url]
10
+ @backend = params[:backend]
11
+ super params.merge(comparator:"hdr(host) -i",value:url,name:url)
12
+ end
13
+ def apply
14
+ @apply = []
15
+ @apply << "use_backend"
16
+ @apply << backend.application
17
+ @apply << condition
18
+ @apply.join(" ")
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,74 @@
1
+ require "entrance/agent/doorkeepr"
2
+ require "entrance/agent/zookeeper"
3
+ require "entrance/watcher/agent"
4
+ require "entrance/agent/haproxy"
5
+ require "entrance/agent/entrance"
6
+ require "uuidtools"
7
+
8
+ module Entrance
9
+ module Agent
10
+ class Agent
11
+
12
+ def initialize
13
+ puts "Connecting to Doorkeepr Webservice"
14
+ doorkeepr
15
+ puts "Connecting to Zookeeper Database"
16
+ zookeeper
17
+ puts "Create Entrance Instance"
18
+ entrance
19
+ puts "Watch for Updates"
20
+ watcher
21
+ puts "Start Load Balancer"
22
+ frontend
23
+ end
24
+
25
+ def start
26
+ frontend.start
27
+ watcher.callback = callback
28
+ watcher.start
29
+ loop do
30
+ sleep 1
31
+ end
32
+ end
33
+
34
+ def process
35
+ update
36
+ end
37
+
38
+ private
39
+
40
+ def update
41
+ puts "Update Load Balancer"
42
+ frontend.update
43
+ frontend.start
44
+ end
45
+
46
+ def callback
47
+ Proc.new do
48
+ self.send :update
49
+ end
50
+ end
51
+
52
+ def entrance
53
+ @entrance ||= Entrance.new
54
+ Entrance.current = @entrance
55
+ end
56
+
57
+ def doorkeepr
58
+ @doorkeepr ||= Doorkeepr.new
59
+ end
60
+
61
+ def zookeeper
62
+ @zookeeper ||= Zookeeper.new
63
+ end
64
+
65
+ def watcher
66
+ @watcher ||= Watcher::Agent.new Config.current.path, name: "entrance-agent"
67
+ end
68
+
69
+ def frontend
70
+ @frontend ||= Haproxy.new
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,22 @@
1
+ require "boutons"
2
+ require "synapse/easy"
3
+ require "entrance/agent/config"
4
+
5
+ module Entrance
6
+ module Agent
7
+ module Bouton
8
+ attr_accessor :customer, :application, :function
9
+ def config
10
+ @mode ||= :tcp
11
+ @function ||= "common"
12
+ @application ||= self.class.name.split("::").last
13
+ @customer ||= "global"
14
+ Synapse::Easy::Service.new customer: @customer,
15
+ application: @application,
16
+ function: @function,
17
+ mode: @mode,
18
+ uri: @uri
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,30 @@
1
+ require "entrance/agent/globalizer"
2
+ require "entrance/agent/restful"
3
+ require "digest"
4
+
5
+ module Entrance
6
+ module Agent
7
+ class Certificate < Restful
8
+ extend Globalizer
9
+ attr_accessor :name, :key, :certificate
10
+ def initialize params={}
11
+ super params.merge(load:true)
12
+ update_certificate_file
13
+ end
14
+ def path
15
+ @path ||= Config.current.workdir.join("#{@name}.pem").to_s
16
+ end
17
+ def path=path
18
+ @path = path
19
+ end
20
+ def to_s
21
+ update_certificate_file
22
+ @path
23
+ end
24
+ private
25
+ def update_certificate_file
26
+ File.write path, [key,certificate].compact.join("\n")
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,14 @@
1
+ require "entrance/agent/agent"
2
+ require "thor"
3
+
4
+ module Entrance
5
+ module Agent
6
+ class Cli < Thor
7
+ desc "start","Start Reverse Proxy Marshal"
8
+ def start
9
+ agent = Agent.new
10
+ agent.start
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,72 @@
1
+ require "ostruct"
2
+ require "boutons"
3
+ require "pathname"
4
+ require "unirest"
5
+ require "entrance/agent/globalizer"
6
+ require "entrance/agent/frontend/http"
7
+ require "entrance/agent/frontend/https"
8
+
9
+ module Entrance
10
+ module Agent
11
+ class Config < OpenStruct
12
+ extend Globalizer
13
+
14
+ def initialize params={}
15
+ params[:path] ||= "/doorkeepr/entrance"
16
+ params[:api_headers] ||= {
17
+ "X-Doorkeepr-API" => 1,
18
+ "Accept" => 'application/json',
19
+ }
20
+ params[:api_path] ||= "api"
21
+ params[:api_timeout] ||= 5
22
+ params[:user_agent] ||= "Doorkeepr Watcher 1"
23
+ params[:doorkeepr_server] ||= "http://localhost:3000"
24
+ params[:doorkeepr_customer] ||= ENV["USER"]
25
+ params[:doorkeepr_service] ||= "rails"
26
+ params[:workdir] ||= Pathname.new("/tmp")
27
+ params[:id_file] ||= params[:workdir].join("entrance.id").to_s
28
+ params[:entrance] = nil
29
+ params[:id] = nil
30
+ params[:customer] ||= "steigr"
31
+ params[:http_port] = 80
32
+ params[:https_port] = 443
33
+ super params
34
+ end
35
+ def id
36
+ entrance.id
37
+ end
38
+ def id_files_prefix
39
+ workdir.join("entrance-#{id}").to_s + "."
40
+ end
41
+ def config_file_path
42
+ id_files_prefix + "cfg"
43
+ end
44
+ def socket_file_path
45
+ id_files_prefix + "sock"
46
+ end
47
+ def pid_file_path
48
+ id_files_prefix + "pid"
49
+ end
50
+ def doorkeepr_server
51
+ Pathname.new begin
52
+ Boutons.doorkeepr.to_s
53
+ rescue Boutons::SynapseNotFound
54
+ @table[:doorkeepr_server]
55
+ end
56
+ end
57
+ def api_url
58
+ doorkeepr_server.join(api_path)
59
+ end
60
+ def get_binding
61
+ binding
62
+ end
63
+ end
64
+ Config.current ||= Config.new
65
+ Config.current.http_params = Frontend::Http.new
66
+ Config.current.https_params = Frontend::Https.new
67
+ Unirest.timeout Config.current.api_timeout
68
+ Config.current.api_headers.each do |k,v|
69
+ Unirest.default_header k,v
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,22 @@
1
+ require "entrance/agent/bouton"
2
+ require "entrance/agent/config"
3
+
4
+ module Entrance
5
+ module Agent
6
+ class Doorkeepr
7
+ include Bouton
8
+ def initialize
9
+ connect
10
+ end
11
+ private
12
+ def connect
13
+ @customer = Config.current.customer
14
+ @application = "doorkeepr"
15
+ @function = Config.current.doorkeepr_service
16
+ @mode = "http"
17
+ @uri = "/doorkeepr"
18
+ Boutons.add config
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,123 @@
1
+ require "ostruct"
2
+ require "fake/hash"
3
+ require "entrance/agent/config"
4
+ require "active_support/core_ext/string/inflections"
5
+ require "active_support/lazy_load_hooks"
6
+ require "awesome_print"
7
+ require "socket"
8
+ require "erb"
9
+ require "entrance/agent/globalizer"
10
+ require "entrance/agent/restful"
11
+ require "synapse/easy"
12
+
13
+ module Entrance
14
+ module Agent
15
+ class Entrance < Restful
16
+ extend Globalizer
17
+
18
+ attr_writer :name, :config_file_path, :socket_file_path,
19
+ :pid_file_path
20
+
21
+ attr_reader :id, :services
22
+
23
+ attr_writer :service_ids
24
+
25
+ attr_accessor :do_reloads, :do_writes, :do_socket,
26
+ :global, :defaults, :certificate_id, :certificate
27
+
28
+ def initialize params={}
29
+ Config.current.entrance = self
30
+ @id ||= File.read Config.current.id_file rescue nil
31
+ @id ? read : create
32
+ @frontend_ids = []
33
+ @certificate ||= Certificate.new id: certificate_id
34
+ end
35
+ def name
36
+ @name ||= "#{Socket.gethostname}-#{id}"
37
+ end
38
+ def id=id
39
+ @id = persist_id id
40
+ end
41
+ def to_h
42
+ { entrance: { name: name, id: id } }
43
+ end
44
+ def config_file_path
45
+ ERB.new(@config_file_path).result(Config.current.get_binding)
46
+ end
47
+ def socket_file_path
48
+ ERB.new(@socket_file_path).result(Config.current.get_binding)
49
+ end
50
+ def pid_file_path
51
+ ERB.new(@pid_file_path).result(Config.current.get_binding)
52
+ end
53
+ def update
54
+ _update
55
+ end
56
+ def reload_command
57
+ "haproxy -f '#{config_file_path}' -p '#{pid_file_path}' -st $(cat '#{pid_file_path}' 2>/dev/null|| true)"
58
+ end
59
+ def extra_sections
60
+ @extra_sections ||= Synapse::Config::Services.new
61
+ @extra_sections[stats_section.label] ||= stats_section
62
+ @extra_sections
63
+ end
64
+ def stats_section
65
+ @stats_section ||= Synapse::Easy::Section::Stats.new(username: :foo, password: :bar,show_node: true)
66
+ end
67
+ def service_ids
68
+ @service_ids || []
69
+ end
70
+ private
71
+ def read
72
+ begin
73
+ process Unirest.get url
74
+ rescue Unavailable
75
+ create
76
+ end
77
+ end
78
+ def create
79
+ begin
80
+ process Unirest.post init_url.to_s,
81
+ parameters: self.to_h
82
+ rescue Unavailable => code
83
+ puts code
84
+ end
85
+ end
86
+ def delete
87
+ Unirest.delete url
88
+ end
89
+ def _update
90
+ Unirest.put url,
91
+ parameters: self.to_h,
92
+ &process_cb
93
+ end
94
+ def process_cb
95
+ Proc.new do |response|
96
+ process response
97
+ end
98
+ end
99
+ def process response
100
+ raise Unavailable.new(response.code) if (400..599).include? response.code
101
+ raise Invalid.new("malformed response") unless response.body.has_key? resource_name
102
+ response.body[resource_name].each do |attr,value|
103
+ self.send :"#{attr}=", value
104
+ end
105
+ end
106
+ def resource_name
107
+ self.class.name.split("::").last.underscore.singularize
108
+ end
109
+ def collection_name
110
+ resource_name.pluralize
111
+ end
112
+ def url
113
+ init_url.join(id).to_s
114
+ end
115
+ def init_url
116
+ Config.current.api_url.join('entrances')
117
+ end
118
+ def persist_id id
119
+ File.write Config.current.id_file, id and id
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,22 @@
1
+ require "entrance/agent/globalizer"
2
+ require "fake/hash"
3
+
4
+ module Entrance
5
+ module Agent
6
+ module Frontend
7
+ class Http
8
+ extend Globalizer
9
+ include Fake::Hash
10
+
11
+ attr_accessor :name, :port, :mode
12
+
13
+ def initialize params={}
14
+ @name = params[:name]
15
+ @name ||= "http"
16
+ @port = Config.current.http_port
17
+ @mode = :http
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,29 @@
1
+ require "entrance/agent/globalizer"
2
+ require "fake/hash"
3
+ require "entrance/agent/config"
4
+ require "entrance/agent/certificate"
5
+ require "entrance/agent/entrance"
6
+
7
+ module Entrance
8
+ module Agent
9
+ module Frontend
10
+ class Https
11
+ extend Globalizer
12
+ include Fake::Hash
13
+
14
+ attr_accessor :name, :default_certificate, :port, :protocol, :mode
15
+
16
+ def initialize params={}
17
+ @name = params[:name]
18
+ @name ||= "https"
19
+ @port = Config.current.https_port
20
+ @protocol = :https
21
+ @default_certificate = params[:default_certificate]
22
+ @default_certificate = Entrance.current.certificate rescue nil
23
+ @default_certificate ||= nil
24
+ @mode = :http
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,8 @@
1
+ module Entrance
2
+ module Globalizer
3
+ attr_accessor :current
4
+ # def current
5
+ # @current ||= self.new
6
+ # end
7
+ end
8
+ end
@@ -0,0 +1,88 @@
1
+ require "synapse/easy"
2
+ require "synapse/config"
3
+ require "synapse"
4
+ require "active_support/core_ext/hash/indifferent_access"
5
+ require "entrance/agent/service"
6
+ require "entrance/agent/globalizer"
7
+ require "active_support/lazy_load_hooks"
8
+ require "awesome_print"
9
+
10
+ module Entrance
11
+ module Agent
12
+ class Haproxy
13
+ extend Globalizer
14
+
15
+ attr_accessor :synapse, :thread, :haproxy, :backends, :services, :http,
16
+ :https
17
+
18
+ def initialize
19
+ Haproxy.current ||= self
20
+ @haproxy = Synapse::Config::Haproxy.new Entrance.current
21
+ @backends = Synapse::Config::Services.new
22
+ @services = {}
23
+ @synapse_config = {
24
+ haproxy: haproxy,
25
+ services: backends
26
+ }.with_indifferent_access
27
+ @synapse = Synapse::Synapse.new @synapse_config
28
+ @synapse.services = backends
29
+ Config.current.https_params.default_certificate = Entrance.current.certificate
30
+ @http = Synapse::Easy::Section::Http.new Config.current.http_params
31
+ @https = Synapse::Easy::Section::Http.new Config.current.https_params
32
+ haproxy.extra_sections[http.label] = http
33
+ haproxy.extra_sections[https.label] = https
34
+ link_notifiers
35
+ end
36
+ def update
37
+ Entrance.current.update
38
+ update_frontends
39
+ update_haproxy
40
+ link_notifiers
41
+ end
42
+ def start
43
+ return if backends.empty?
44
+ self.thread = Thread.new do
45
+ synapse.run
46
+ end
47
+ @started = true
48
+ end
49
+ private
50
+ def link_notifiers
51
+ unless @haproxy_linked
52
+ haproxy.inform synapse
53
+ haproxy.extra_sections.inform synapse
54
+ @haproxy_linked = true
55
+ end
56
+ unless @backends_linked
57
+ unless backends.empty?
58
+ backends.inform synapse
59
+ @backends_linked = true
60
+ end
61
+ end
62
+ end
63
+ def update_haproxy
64
+ rules = []
65
+ routing = []
66
+ services.each do |name,service|
67
+ rules << service.acl.acl
68
+ routing << service.acl.apply
69
+ end
70
+ http.options = rules + routing
71
+ https.options = rules + routing
72
+ end
73
+ def update_frontends
74
+ Entrance.current.service_ids.each do |service_id|
75
+ puts "Loading Service #{service_id}"
76
+ service = Service.new id: service_id
77
+ next if services[service.application_id]
78
+ services[service.application_id] = service
79
+ unless backends[service.backend.name]
80
+ backends[service.backend.name] = service.backend
81
+ synapse.add_service service.backend
82
+ service.backend.active = true
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,92 @@
1
+ require "ostruct"
2
+ require "fake/hash"
3
+ require "entrance/agent/config"
4
+ require "active_support/core_ext/string/inflections"
5
+ require "entrance/agent/globalizer"
6
+ require "active_support/lazy_load_hooks"
7
+ require "awesome_print"
8
+
9
+ module Entrance
10
+ module Agent
11
+ class Restful
12
+ include Fake::Hash
13
+ class GatewayTimeout < Exception; end
14
+ class Unavailable < Exception; end
15
+ class Invalid < Exception; end
16
+
17
+ attr_reader :id
18
+
19
+ def initialize params={}
20
+ if self.class.included_modules.include? ::Entrance::Globalizer
21
+ self.class.current = self
22
+ end
23
+ @id = params[:id]
24
+ read if params[:load] and id
25
+ end
26
+ def id= id
27
+ @id = id
28
+ end
29
+ def to_rest
30
+ raise NotImplementedError
31
+ end
32
+ private
33
+ def read_or_create
34
+ begin
35
+ local_update Unirest.get _url
36
+ rescue Unavailable
37
+ create
38
+ end
39
+ end
40
+ def read
41
+ wait = 1
42
+ begin
43
+ local_update Unirest.get _url
44
+ rescue GatewayTimeout
45
+ wait = wait * 2
46
+ wait = wait / 2 if wait > 150
47
+ retry
48
+ end
49
+ end
50
+ def create
51
+ begin
52
+ local_update Unirest.post _init_url.to_s,
53
+ parameters: { self.resource_name => self.to_rest }
54
+ rescue Unavailable => code
55
+ puts code
56
+ end
57
+ end
58
+ def delete
59
+ Unirest.delete _url
60
+ end
61
+ def update
62
+ local_update Unirest.put _url,
63
+ parameters: { self.resource_name => self.to_rest }
64
+ end
65
+ def local_update_callback
66
+ Proc.new do |response|
67
+ local_update response
68
+ end
69
+ end
70
+ def local_update response
71
+ raise GatewayTimeout.new if response.code == 504
72
+ raise Unavailable.new(response.code) if (400..599).include? response.code
73
+ raise Invalid.new("malformed response") unless response.body.has_key? resource_name
74
+ response.body[resource_name].each do |attribute,value|
75
+ self.send :"#{attribute}=", value
76
+ end
77
+ end
78
+ def _url
79
+ _init_url.join(id).to_s
80
+ end
81
+ def _init_url
82
+ Config.current.api_url.join(collection_name)
83
+ end
84
+ def resource_name
85
+ self.class.name.split("::").last.underscore.singularize
86
+ end
87
+ def collection_name
88
+ resource_name.pluralize
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,33 @@
1
+ require "entrance/agent/globalizer"
2
+ require "entrance/agent/restful"
3
+ require "entrance/agent/acl"
4
+ require "digest"
5
+
6
+ module Entrance
7
+ module Agent
8
+ class Service < Restful
9
+ extend Globalizer
10
+ attr_accessor :name, :application_id, :zk_path, :acl, :backend, :url
11
+ def initialize params={}
12
+ super params.merge(load:true)
13
+ backend_params = {
14
+ mode: :http,
15
+ enable_frontend: false,
16
+ port: 0,
17
+ path: zk_path,
18
+ application: name,
19
+ uri: "/health"
20
+ }
21
+ @backend = Synapse::Easy::Service.new backend_params
22
+ acl_params = {
23
+ as_digest: true,
24
+ url: url,
25
+ backend: backend
26
+ }
27
+ @acl = Acl::UrlBackendRouter.new acl_params
28
+ backend.application = acl.label
29
+ backend.name = acl.label
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,5 @@
1
+ module Entrance
2
+ module Agent
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,19 @@
1
+ require "entrance/agent/bouton"
2
+ require "entrance/agent/config"
3
+
4
+ module Entrance
5
+ module Agent
6
+ class Zookeeper
7
+ include Bouton
8
+ def initialize
9
+ connect
10
+ end
11
+ private
12
+ def connect
13
+ @customer = Config.current.customer
14
+ @application = "zookeeper"
15
+ Boutons.add config
16
+ end
17
+ end
18
+ end
19
+ end
metadata ADDED
@@ -0,0 +1,268 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: entrance-agent
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Mathias Kaufmann
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-04-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: entrance-watcher
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: resolv-consul
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: thor
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: unirest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: awesome_print
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: activesupport
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: boutons
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: synapse-easy
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: synapse-config
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: pry
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: uuidtools
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: fake-hash
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: bundler
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: '1.8'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: '1.8'
195
+ - !ruby/object:Gem::Dependency
196
+ name: rake
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: '10.0'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: '10.0'
209
+ description: Reverse Proxy/Load-Balancer based on Nerve and Synapse.
210
+ email:
211
+ - me@stei.gr
212
+ executables:
213
+ - entrance-agent
214
+ extensions: []
215
+ extra_rdoc_files: []
216
+ files:
217
+ - ".gitignore"
218
+ - ".travis.yml"
219
+ - Gemfile
220
+ - README.md
221
+ - Rakefile
222
+ - bin/console
223
+ - bin/setup
224
+ - entrance-agent.gemspec
225
+ - exe/entrance-agent
226
+ - lib/entrance/agent.rb
227
+ - lib/entrance/agent/acl.rb
228
+ - lib/entrance/agent/acl/base.rb
229
+ - lib/entrance/agent/acl/url_backend_router.rb
230
+ - lib/entrance/agent/agent.rb
231
+ - lib/entrance/agent/bouton.rb
232
+ - lib/entrance/agent/certificate.rb
233
+ - lib/entrance/agent/cli.rb
234
+ - lib/entrance/agent/config.rb
235
+ - lib/entrance/agent/doorkeepr.rb
236
+ - lib/entrance/agent/entrance.rb
237
+ - lib/entrance/agent/frontend/http.rb
238
+ - lib/entrance/agent/frontend/https.rb
239
+ - lib/entrance/agent/globalizer.rb
240
+ - lib/entrance/agent/haproxy.rb
241
+ - lib/entrance/agent/restful.rb
242
+ - lib/entrance/agent/service.rb
243
+ - lib/entrance/agent/version.rb
244
+ - lib/entrance/agent/zookeeper.rb
245
+ homepage: https://doorkeepr.stei.gr/entrance
246
+ licenses: []
247
+ metadata: {}
248
+ post_install_message:
249
+ rdoc_options: []
250
+ require_paths:
251
+ - lib
252
+ required_ruby_version: !ruby/object:Gem::Requirement
253
+ requirements:
254
+ - - ">="
255
+ - !ruby/object:Gem::Version
256
+ version: '0'
257
+ required_rubygems_version: !ruby/object:Gem::Requirement
258
+ requirements:
259
+ - - ">="
260
+ - !ruby/object:Gem::Version
261
+ version: '0'
262
+ requirements: []
263
+ rubyforge_project:
264
+ rubygems_version: 2.4.6
265
+ signing_key:
266
+ specification_version: 4
267
+ summary: Reverse Proxy/Load-Balancer based on Nerve and Synapse.
268
+ test_files: []