port-authority 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NjQxZGVlNDk3YzA1OTNkY2ZiYzM1ZjY3MmJkZGU0OTVjZGM1Y2JlMA==
5
- data.tar.gz: !binary |-
6
- YWMwYTk0NjYzYjI2OTAyYTc0OWQwOGJhZWY5MjE5M2U4MWZhMDMzMg==
2
+ SHA1:
3
+ metadata.gz: e29bbb93c31d6ecff7d9931333bda2b6d5b70f04
4
+ data.tar.gz: e964daf7b9d98e1f93efe3737e96e09c1a9f33f6
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- NGRkYzljOGQ2ZmJkZjRlYTA1YjliNDZjNjhiYTcxYjNjNTNlY2E2MzFmYWQ4
10
- NjRjYzNmZDU5ZWFlZDNlMTczY2I1YmFjMWI5MDdiZDhmNDVkNTc1NGRjY2M5
11
- YzIyY2JjZmJiM2I5N2U5ODBjNDBkZmM1MmZjZDk0MjgwYjlhYWI=
12
- data.tar.gz: !binary |-
13
- NTY4MWVkODk1NzE5ZjU3ZTNlYTYwNzA0MjkxZDg3MDkxNjhjN2Y0YWQ4MGY3
14
- MzNiNDM2ZWM0MjFjN2FhMmNmYTJhODkxMGFmMmE5ZmZjMzVkOTk0MDFiNDNh
15
- ZGFlYzA3MGQ4MjMwOWUwNDYxNmZiOGQyZDEwMDk3NGQwMTI5OTg=
6
+ metadata.gz: 22a89d416d76f7797f51ee1425ca00cd11df6bbc0062940db3cf891d36b08b19019b31580fb01b6abee0bbfc9c26e3d86f3ad005708965904d351f49e634e69f
7
+ data.tar.gz: 450d1ca0945399efed8020a21f027c7334854689d986e5804fec9807efc4688aed154b5dfa7db59a2a232ea3f5ecdcfe7c94577375676d630579765eb5c875aa
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: port-authority
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Radek 'blufor' Slavicinsky
@@ -14,101 +14,88 @@ dependencies:
14
14
  name: etcd
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0.3'
20
- - - ! '>='
20
+ - - ">="
21
21
  - !ruby/object:Gem::Version
22
22
  version: 0.3.0
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
- - - ~>
27
+ - - "~>"
28
28
  - !ruby/object:Gem::Version
29
29
  version: '0.3'
30
- - - ! '>='
30
+ - - ">="
31
31
  - !ruby/object:Gem::Version
32
32
  version: 0.3.0
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: etcd-tools
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
- - - ~>
37
+ - - "~>"
38
38
  - !ruby/object:Gem::Version
39
39
  version: '0.4'
40
- - - ! '>='
40
+ - - ">="
41
41
  - !ruby/object:Gem::Version
42
42
  version: 0.4.0
43
43
  type: :runtime
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
46
46
  requirements:
47
- - - ~>
47
+ - - "~>"
48
48
  - !ruby/object:Gem::Version
49
49
  version: '0.4'
50
- - - ! '>='
50
+ - - ">="
51
51
  - !ruby/object:Gem::Version
52
52
  version: 0.4.0
53
53
  - !ruby/object:Gem::Dependency
54
54
  name: net-ping
55
55
  requirement: !ruby/object:Gem::Requirement
56
56
  requirements:
57
- - - ~>
57
+ - - "~>"
58
58
  - !ruby/object:Gem::Version
59
59
  version: '1.7'
60
- - - ! '>='
60
+ - - ">="
61
61
  - !ruby/object:Gem::Version
62
62
  version: 1.7.8
63
63
  type: :runtime
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
- - - ~>
67
+ - - "~>"
68
68
  - !ruby/object:Gem::Version
69
69
  version: '1.7'
70
- - - ! '>='
70
+ - - ">="
71
71
  - !ruby/object:Gem::Version
72
72
  version: 1.7.8
73
73
  - !ruby/object:Gem::Dependency
74
74
  name: docker-api
75
75
  requirement: !ruby/object:Gem::Requirement
76
76
  requirements:
77
- - - ~>
77
+ - - "~>"
78
78
  - !ruby/object:Gem::Version
79
79
  version: '1.0'
80
- - - ! '>='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: 1.25.0
83
83
  type: :runtime
84
84
  prerelease: false
85
85
  version_requirements: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ~>
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
89
  version: '1.0'
90
- - - ! '>='
90
+ - - ">="
91
91
  - !ruby/object:Gem::Version
92
92
  version: 1.25.0
93
93
  description: CLI Tools for PortAuthority
94
94
  email: radek.slavicinsky@gmail.com
95
- executables:
96
- - pa-manager
95
+ executables: []
97
96
  extensions: []
98
97
  extra_rdoc_files: []
99
- files:
100
- - bin/pa-manager
101
- - lib/port-authority.rb
102
- - lib/port-authority/manager/app.rb
103
- - lib/port-authority/manager/init.rb
104
- - lib/port-authority/manager/threads/icmp.rb
105
- - lib/port-authority/manager/threads/swarm.rb
106
- - lib/port-authority/util/config.rb
107
- - lib/port-authority/util/etcd.rb
108
- - lib/port-authority/util/helpers.rb
109
- - lib/port-authority/util/loadbalancer.rb
110
- - lib/port-authority/util/logger.rb
111
- - lib/port-authority/util/vip.rb
98
+ files: []
112
99
  homepage: https://github.com/prozeta/port-authority
113
100
  licenses:
114
101
  - GPLv2
@@ -119,17 +106,17 @@ require_paths:
119
106
  - lib
120
107
  required_ruby_version: !ruby/object:Gem::Requirement
121
108
  requirements:
122
- - - ! '>='
109
+ - - ">="
123
110
  - !ruby/object:Gem::Version
124
111
  version: 1.9.3
125
112
  required_rubygems_version: !ruby/object:Gem::Requirement
126
113
  requirements:
127
- - - ! '>='
114
+ - - ">="
128
115
  - !ruby/object:Gem::Version
129
116
  version: '0'
130
117
  requirements: []
131
118
  rubyforge_project:
132
- rubygems_version: 2.4.3
119
+ rubygems_version: 2.4.6
133
120
  signing_key:
134
121
  specification_version: 4
135
122
  summary: Port Authority
data/bin/pa-manager DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'port-authority/manager/app'
3
- PortAuthority::Manager::App.new('pa-manager').run
@@ -1,153 +0,0 @@
1
- # rubocop:disable MethodLength, CyclomaticComplexity, Metrics/BlockNesting, Metrics/LineLength, Metrics/AbcSize, Metrics/PerceivedComplexity
2
- require 'ipaddr'
3
- require 'port-authority'
4
- require 'port-authority/util/vip'
5
- require 'port-authority/util/etcd'
6
- require 'port-authority/util/loadbalancer'
7
- require 'port-authority/manager/init'
8
- require 'port-authority/manager/threads/icmp'
9
- require 'port-authority/manager/threads/swarm'
10
-
11
- module PortAuthority
12
- module Manager
13
- ##
14
- # Port Authority Manager - manages floating VIP and lb placement
15
- #
16
- class App < PortAuthority::Manager::Init
17
- include PortAuthority::Util::Etcd
18
- include PortAuthority::Util::Vip
19
- include PortAuthority::Util::LoadBalancer
20
- include PortAuthority::Manager::Threads
21
-
22
- def run
23
- # exit if not root
24
- if Process.euid != 0
25
- alert 'must run under root user!'
26
- exit! 1
27
- end
28
-
29
- Signal.trap('USR1') { @lb_update_hook = true }
30
-
31
- # prepare semaphores
32
- @semaphore.merge!(swarm: Mutex.new, icmp: Mutex.new)
33
-
34
- # prepare threads
35
- @thread = {icmp: thread_icmp,swarm: thread_swarm}
36
-
37
- # prepare status vars
38
- @status_swarm = false
39
- @status_icmp = false
40
-
41
- # start threads
42
- @thread.each_value(&:run)
43
-
44
- # setup docker client
45
- lb_docker_setup! || @exit = true
46
-
47
- # prepare container with load-balancer
48
- lb_create!
49
-
50
- # wait for threads to make sure they gather something
51
- debug 'waiting for threads to gather something...'
52
- sleep @config[:vip][:interval]
53
- first_cycle = true
54
- status_time = Time.now.to_i - 60
55
-
56
- # main loop
57
- until @exit
58
- # initialize local state vars on first iteration
59
- status_swarm = status_icmp = false if first_cycle
60
-
61
- if @lb_update_hook
62
- notice 'updating LB image'
63
- lb_update!
64
- end
65
-
66
- # iteration interval
67
- sleep @config[:vip][:interval]
68
-
69
- # sync state to local variables
70
- @semaphore[:icmp].synchronize { status_icmp = @status_icmp }
71
- @semaphore[:swarm].synchronize { status_swarm = @status_swarm }
72
-
73
- # the logic (should be self-explanatory ;))
74
- if status_swarm
75
- debug 'i am the leader'
76
- if got_vip?
77
- debug 'got VIP, that is OK'
78
- else
79
- info 'no VIP here, checking whether it is free'
80
- if status_icmp
81
- info 'VIP is still up! (ICMP)'
82
- # FIXME: notify by sensu client socket
83
- else
84
- # FIXME: proper arping handling
85
- # info 'VIP is unreachable by ICMP, checking for duplicates on L2'
86
- # if vip_dup?
87
- # info 'VIP is still assigned! (ARP)'
88
- # # FIXME: notify by sensu client socket
89
- # else
90
- # info 'VIP is free :) assigning'
91
- # vip_handle! status_swarm
92
- # info 'updating other hosts about change'
93
- # vip_update_arp!
94
- # end
95
- notice 'VIP is free :) assigning'
96
- vip_handle! status_swarm
97
- notice 'updating other hosts about change'
98
- vip_update_arp!
99
- end
100
- end
101
- if lb_up?
102
- debug 'load-balancer is up, that is OK'
103
- else
104
- notice 'load-balancer is down, starting'
105
- lb_start!
106
- end
107
- else
108
- debug 'i am not the leader'
109
- if got_vip?
110
- notice 'i got VIP and should not, removing'
111
- vip_handle! status_swarm
112
- notice 'updating other hosts about change'
113
- vip_update_arp!
114
- else
115
- debug 'no VIP here, that is OK'
116
- end
117
- if lb_up?
118
- notice 'load-balancer is up, stopping'
119
- lb_stop!
120
- else
121
- debug 'load-balancer is down, that is OK'
122
- end
123
- end
124
-
125
- if status_time + 60 <= Time.now.to_i
126
- info "STATUS_REPORT { leader: '#{status_swarm ? 'yes' : 'no'}', vip: '#{got_vip? ? 'yes' : 'no'}/#{status_icmp ? 'up' : 'down'}', lb: '#{lb_up? ? 'yes' : 'no'}' }"
127
- status_time = Time.now.to_i
128
- end
129
-
130
- end
131
-
132
- # this is triggerred on exit
133
- @thread.each_value(&:join)
134
-
135
- # remove VIP on shutdown
136
- if got_vip?
137
- notice 'removing VIP'
138
- vip_handle! false
139
- vip_update_arp!
140
- end
141
-
142
- # stop LB on shutdown
143
- if lb_up?
144
- notice 'stopping load-balancer'
145
- lb_stop!
146
- end
147
-
148
- info 'exiting...'
149
- exit 0
150
- end
151
- end
152
- end
153
- end
@@ -1,43 +0,0 @@
1
- require 'timeout'
2
- require 'json'
3
- require 'etcd-tools'
4
- require 'port-authority/util/config'
5
- require 'port-authority/util/logger'
6
- require 'port-authority/util/helpers'
7
-
8
- module PortAuthority
9
- module Manager
10
- class Init
11
- include PortAuthority::Util::Config
12
- include PortAuthority::Util::Logger
13
- include PortAuthority::Util::Helpers
14
-
15
- def initialize(proc_name='dummy')
16
- @config = config
17
- @exit = false
18
- @semaphore = { log: Mutex.new }
19
- Thread.current[:name] = 'main'
20
- syslog_init proc_name if @config[:syslog]
21
- setup proc_name
22
- info 'starting main thread'
23
- debug 'setting signal handling'
24
- @exit_sigs = %w(INT TERM)
25
- @exit_sigs.each { |sig| Signal.trap(sig) { @exit = true } }
26
- Signal.trap('USR2') { @config[:debug] = !@config[:debug] }
27
- Signal.trap('HUP') { @config = config }
28
- end
29
-
30
- def setup(proc_name, nice = -20)
31
- debug 'setting process name'
32
- if RUBY_VERSION >= '2.1'
33
- Process.setproctitle(proc_name)
34
- else
35
- $0 = proc_name
36
- end
37
- debug 'setting process title'
38
- Process.setpriority(Process::PRIO_PROCESS, 0, nice)
39
- # FIXME: Process.daemon ...
40
- end
41
- end
42
- end
43
- end
@@ -1,30 +0,0 @@
1
- # rubocop:disable Metrics/MethodLength
2
- require 'net/ping'
3
-
4
- module PortAuthority
5
- module Manager
6
- module Threads
7
- def thread_icmp
8
- Thread.new do
9
- Thread.current[:name] = 'icmp'
10
- begin
11
- info 'starting ICMP thread...'
12
- icmp = Net::Ping::ICMP.new(@config[:vip][:ip])
13
- until @exit
14
- debug 'checking state by ICMP echo'
15
- status = vip_alive? icmp
16
- @semaphore[:icmp].synchronize { @status_icmp = status }
17
- debug "VIP is #{status ? 'alive' : 'down'} according to ICMP"
18
- sleep @config[:icmp][:interval]
19
- end
20
- info 'ending ICMP thread...'
21
- rescue StandardError => e
22
- alert "#{e.class}: #{e.message}"
23
- alert e.backtrace
24
- @exit = true
25
- end
26
- end
27
- end
28
- end
29
- end
30
- end
@@ -1,42 +0,0 @@
1
- # rubocop:disable Metrics/MethodLength
2
- module PortAuthority
3
- module Manager
4
- module Threads
5
- def thread_swarm
6
- Thread.new do
7
- Thread.current[:name] = 'swarm'
8
- info 'starting swarm thread...'
9
- begin
10
- etcd = etcd_connect!
11
- until @exit
12
- debug 'checking ETCD state'
13
- etcd_healthy? etcd
14
- debug 'checking swarm state'
15
- status = am_i_leader? etcd
16
- @semaphore[:swarm].synchronize { @status_swarm = status }
17
- debug "i am #{status ? 'the leader' : 'not the leader' }"
18
- sleep @config[:etcd][:interval]
19
- end
20
- info 'ending swarm thread...'
21
- rescue PortAuthority::Errors::ETCDIsSick => e
22
- notice "#{e.class}: #{e.message}"
23
- notice "connection: " + e.etcd.to_s
24
- @semaphore[:swarm].synchronize { @status_swarm = false }
25
- sleep @config[:etcd][:interval]
26
- retry unless @exit
27
- rescue PortAuthority::Errors::ETCDConnectFailed => e
28
- err "#{e.class}: #{e.message}"
29
- err "connection: " + e.etcd.to_s
30
- @semaphore[:swarm].synchronize { @status_swarm = false }
31
- sleep @config[:etcd][:interval]
32
- retry unless @exit
33
- rescue StandardError => e
34
- alert e.message
35
- alert e.backtrace.to_s
36
- @exit = true
37
- end
38
- end
39
- end
40
- end
41
- end
42
- end
@@ -1,61 +0,0 @@
1
- require 'yaml'
2
- require 'etcd-tools'
3
-
4
- module PortAuthority
5
- module Util
6
- module Config
7
-
8
- def config
9
- cfg = default_config
10
- if File.exist? '/etc/port-authority.yaml'
11
- cfg = cfg.deep_merge YAML.load_file('/etc/port-authority.yaml')
12
- puts 'loaded config from /etc/port-authority.yaml'
13
- elsif File.exist? './port-authority.yaml'
14
- cfg = cfg.deep_merge YAML.load_file('./port-authority.yaml')
15
- puts 'loaded config from ./port-authority.yaml'
16
- else
17
- puts 'no config file loaded, using defaults'
18
- end
19
- cfg
20
- end
21
-
22
- private
23
-
24
- def default_config
25
- { debug: false,
26
- syslog: false,
27
- etcd: {
28
- endpoints: ['http://localhost:2379'],
29
- interval: 5,
30
- timeout: 5
31
- },
32
- icmp: {
33
- count: 5,
34
- interval: 2
35
- },
36
- arping: {
37
- count: 1,
38
- wait: 1
39
- },
40
- vip: {
41
- interval: 1,
42
- ip: '172.17.1.5',
43
- mask: '255.255.255.0',
44
- interface: 'eth0'
45
- },
46
- lb: {
47
- image: 'docker-registry.prz/stackdocks/haproxy:latest',
48
- name: 'lb',
49
- network: 'overlay',
50
- docker_endpoint: 'unix:///var/run/docker.sock'
51
- },
52
- commands: {
53
- arping: `which arping`.chomp,
54
- arp: `which arp`.chomp,
55
- iproute: `which ip`.chomp
56
- }
57
- }
58
- end
59
- end
60
- end
61
- end
@@ -1,33 +0,0 @@
1
- require 'etcd'
2
- require 'etcd-tools/mixins'
3
-
4
- module PortAuthority
5
- module Util
6
- module Etcd
7
- # connect to ETCD
8
- def etcd_connect!
9
- endpoints = @config[:etcd][:endpoints].map { |e| e = e.gsub!(/^https?:\/\//, '').gsub(/\/$/, '').split(':'); { host: e[0], port: e[1].to_i } }
10
- debug "parsed ETCD endpoints: #{endpoints.to_s}"
11
- etcd = ::Etcd::Client.new(cluster: endpoints, read_timeout: @config[:etcd][:timeout])
12
- etcd if etcd.version
13
- rescue
14
- raise PortAuthority::Errors::ETCDConnectFailed.new(@config[:etcd][:endpoints])
15
- end
16
-
17
- def etcd_healthy?(etcd)
18
- raise PortAuthority::Errors::ETCDIsSick.new(@config[:etcd][:endpoints]) unless etcd.healthy?
19
- end
20
-
21
- def swarm_leader(etcd)
22
- etcd.get('/_pa/docker/swarm/leader').value
23
- end
24
-
25
- def am_i_leader?(etcd)
26
- Socket.ip_address_list.map(&:ip_address).member?(swarm_leader(etcd).split(':').first)
27
- rescue StandardError => e
28
- false
29
- end
30
-
31
- end
32
- end
33
- end
@@ -1,27 +0,0 @@
1
- require 'socket'
2
-
3
- module PortAuthority
4
- module Util
5
- module Helpers
6
- def hostname
7
- @hostname ||= Socket.gethostname
8
- end
9
-
10
- def my_ip
11
- @my_ip ||= Socket.ip_address_list.detect(&:ipv4_private?).ip_address
12
- end
13
-
14
- def arping
15
- @config[:commands][:arping]
16
- end
17
-
18
- def iproute
19
- @config[:commands][:iproute]
20
- end
21
-
22
- def arp
23
- @config[:commands][:arp]
24
- end
25
- end
26
- end
27
- end
@@ -1,66 +0,0 @@
1
- require 'docker-api'
2
-
3
- module PortAuthority
4
- module Util
5
- module LoadBalancer
6
- # connect to Docker
7
- def lb_docker_setup!
8
- Docker.url = @config[:lb][:docker_endpoint]
9
- Docker.version
10
- true
11
- rescue
12
- false
13
- end
14
-
15
- def lb_update!
16
- lb_stop! if lb_up?
17
- lb_remove!
18
- lb_create!
19
- @lb_update_hook = false
20
- end
21
-
22
- def lb_remove!
23
- Docker::Container.get(@config[:lb][:name]).delete
24
- rescue Docker::Error::NotFoundError
25
- end
26
-
27
-
28
- def lb_create!
29
- lb_remove!
30
- img = Docker::Image.create('fromImage' => @config[:lb][:image])
31
-
32
- # setup port bindings hash
33
- port_bindings = Hash.new
34
- img.json['ContainerConfig']['ExposedPorts'].keys.each do |port|
35
- port_bindings[port] = [ { 'HostPort' => "#{port.split('/').first}" } ]
36
- end
37
-
38
- # create container with
39
- @lb_container = Docker::Container.create(
40
- 'Image' => img.json['Id'],
41
- 'name' => @config[:lb][:name],
42
- 'Hostname' => @config[:lb][:name],
43
- 'Env' => [ "ETCDCTL_ENDPOINT=#{@config[:etcd][:endpoints].join(',')}" ],
44
- 'RestartPolicy' => { 'Name' => 'never' },
45
- 'HostConfig' => {
46
- 'PortBindings' => port_bindings,
47
- 'NetworkMode' => @config[:lb][:network]
48
- }
49
- )
50
- end
51
-
52
- def lb_up?
53
- @lb_container.json['State']['Running']
54
- end
55
-
56
- def lb_start!
57
- @lb_container.start
58
- end
59
-
60
- def lb_stop!
61
- @lb_container.stop
62
- end
63
-
64
- end
65
- end
66
- end
@@ -1,57 +0,0 @@
1
- # rubocop:disable Metrics/LineLength, Metrics/AbcSize, Metrics/MethodLength
2
- require 'syslog'
3
-
4
- module PortAuthority
5
- module Util
6
- module Logger
7
- def debug(message)
8
- log :debug, message if @config[:debug]
9
- end
10
-
11
- def info(message)
12
- log :info, message
13
- end
14
-
15
- def notice(message)
16
- log :notice, message
17
- end
18
-
19
- def err(message)
20
- log :err, message
21
- end
22
-
23
- def alert(message)
24
- log :alert, message if @config[:debug]
25
- end
26
-
27
- def syslog_init(proc_name)
28
- Syslog.open(proc_name, Syslog::LOG_PID, Syslog::LOG_DAEMON)
29
- end
30
-
31
- def log(lvl, msg)
32
- if @config[:syslog]
33
- case lvl
34
- when :debug
35
- l = Syslog::LOG_DEBUG
36
- when :info
37
- l = Syslog::LOG_INFO
38
- when :notice
39
- l = Syslog::LOG_NOTICE
40
- when :err
41
- l = Syslog::LOG_ERR
42
- when :alert
43
- l = Syslog::LOG_ALERT
44
- end
45
- @semaphore[:log].synchronize do
46
- Syslog.log(l, "(%s) %s", Thread.current[:name], msg.to_s)
47
- end
48
- else
49
- @semaphore[:log].synchronize do
50
- $stdout.puts("#{Time.now.to_s} #{lvl.to_s[0].capitalize} (#{Thread.current[:name]} #{msg.to_s}")
51
- $stdout.flush
52
- end
53
- end
54
- end
55
- end
56
- end
57
- end
@@ -1,57 +0,0 @@
1
- # rubocop:disable Metrics/LineLength, Metrics/AbcSize
2
- module PortAuthority
3
- module Util
4
- module Vip
5
- # add or remove VIP on interface
6
- # <IMPLEMENTED>
7
- def vip_handle!(leader)
8
- ip = IPAddr.new(@config[:vip][:ip])
9
- mask = @config[:vip][:mask]
10
- cmd = [iproute, 'address', '', "#{ip}/#{mask}", 'dev', @config[:vip][:interface], 'label', @config[:vip][:interface] + '-vip', '>/dev/null 2>&1']
11
- leader ? cmd[2] = 'add' : cmd[2] = 'delete'
12
- debug "#{cmd.join(' ')}"
13
- if system(cmd.join(' '))
14
- return true
15
- else
16
- return false
17
- end
18
- end
19
-
20
- # send gratuitous ARP to the network
21
- def vip_update_arp!
22
- cmd = [arping, '-U', '-q', '-c', @config[:arping][:count], '-I', @config[:vip][:interface], @config[:vip][:ip]]
23
- debug "#{cmd.join(' ')}"
24
- if system(cmd.join(' '))
25
- return true
26
- else
27
- return false
28
- end
29
- end
30
-
31
- # check whether VIP is assigned to me
32
- def got_vip?
33
- Socket.ip_address_list.map(&:ip_address).member?(@config[:vip][:ip])
34
- end
35
-
36
- # check reachability of VIP by ICMP echo
37
- def vip_alive?(icmp)
38
- (1..@config[:icmp][:count]).each { return true if icmp.ping }
39
- false
40
- end
41
-
42
- # check whether the IP is registered anywhere
43
- def vip_dup?
44
- cmd_arp = [arp, '-d', @config[:vip][:ip], '>/dev/null 2>&1']
45
- cmd_arping = [arping, '-D', '-q', '-c', @config[:arping][:count], '-w', @config[:arping][:wait], '-I', @config[:vip][:interface], @config[:vip][:ip]]
46
- debug "#{cmd_arp.join(' ')}"
47
- system(cmd_arp.join(' '))
48
- debug "#{cmd_arping.join(' ')}"
49
- if system(cmd_arping.join(' '))
50
- return false
51
- else
52
- return true
53
- end
54
- end
55
- end
56
- end
57
- end
@@ -1,28 +0,0 @@
1
- module PortAuthority
2
- module Manager
3
- end
4
-
5
- module Util
6
- end
7
-
8
- module Errors
9
-
10
- class ETCDConnectFailed < StandardError
11
- attr_reader :etcd, :message
12
- def initialize(etcd, message = "Can't connect to ETCD")
13
- @message = message
14
- @etcd = etcd
15
- end
16
- end
17
-
18
- class ETCDIsSick < StandardError
19
- attr_reader :etcd, :message
20
- def initialize(etcd, message = 'ETCD is not healthy')
21
- @message = message
22
- @etcd = etcd
23
- end
24
- end
25
-
26
- end
27
-
28
- end