dendrite 0.0.1 → 0.2.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: 3df2a8393c2d49b666bf727b18dcca034788431c
4
- data.tar.gz: 9955f2b4e9120c9a66cde66af40a8c0fe8fb5d9a
3
+ metadata.gz: e10396502c8af59086c5bf3f6d3b414679830200
4
+ data.tar.gz: f11e24cc3410edc382a309d4d66c5a2e4a902865
5
5
  SHA512:
6
- metadata.gz: ee2ff24e85fac16745d0aa09f0f077f5630acbd7b83c1e6953335ee87832c66db771638dcacfb37e884840eb389ba84912048e648127117486205a7744f971a9
7
- data.tar.gz: d159e46d349ed175838d05e3083bbfc008e4e5a3fdbb6f6b9551a519bdc27667963b0e13c53e9e0323054a666a6bbbf1371d135cfb86c13f18d10908cfa93969
6
+ metadata.gz: c20ba4b8a03ebf55457f9b650ea360687a8c679458b3a5aa1b27bec0e3574d5c67523c199966abe28eb8a2e2c79bcddc0bb8ebb6e4a6f288c3a30ce56ba69461
7
+ data.tar.gz: f30b865221e2e1f79c97362675df5c7fc1cc67e06f745a78651955415b94638670b64bcfced495eb78a6b429bf42fa5615fbfa1687241c20b3192837868c33a4
data/conf/config.yaml CHANGED
@@ -1,11 +1,12 @@
1
1
  dendrite:
2
+ organization: sd
2
3
  dc: ggn1
3
4
  env: dev
4
5
  zk_hosts:
5
6
  - localhost:2181
6
7
  nerve_config_path: /opt/smartstack/conf/nerve.yml
7
8
  synapse_config_path: /opt/smartstack/conf/synapse.yml
8
- services_source: ./conf/services
9
+ services_source: /vagrant/services/services/
9
10
 
10
11
  synapse:
11
12
  haproxy:
@@ -1,34 +1,48 @@
1
+ dendrite_version: 1
2
+ organization: sd
1
3
  namespace: cams
2
4
  lead_email: vp@foobar.com
3
5
  team_email: team@foobar.com
4
6
  services:
5
7
  - name: foobar
6
8
  type: tomcat
7
- repo: git@github.com:yagnik/dendrite
8
- package_name: dendrite
9
+ deploy:
10
+ repository: git@github.com:yagnik/dendrite
11
+ package: dendrite
12
+ scale:
13
+ min_instance_count: 1
14
+ max_instance_count: 5
9
15
  ports:
10
16
  advertised_port: 8081
11
- running_port: 8080
17
+ listening_port: 8080
12
18
  dependancies:
13
- - name: cat
19
+ - namespace: cams
20
+ name: cat
14
21
  latency: foo
15
22
  - name: cat
16
23
  type: tomcat
17
- repo: git@github.com:yagnik/dendrite
18
- package_name: dendrite
19
- error_budget: None
24
+ deploy:
25
+ repository: git@github.com:yagnik/dendrite
26
+ package: dendrite
27
+ scale:
28
+ min_instance_count: 1
29
+ max_instance_count: 5
20
30
  ports:
21
31
  advertised_port: 8081
22
- lb_port: 8080
32
+ listening_port: 8080
23
33
  dependancies:
24
- - name: foobar
34
+ - namespace: cams
35
+ name: foobar
25
36
  latency: foo
26
37
  - name: baz
27
38
  type: tomcat
28
- repo: git@github.com:yagnik/dendrite
29
- package_name: dendrite
30
- error_budget: None
39
+ deploy:
40
+ repository: git@github.com:yagnik/dendrite
41
+ package: dendrite
42
+ scale:
43
+ min_instance_count: 1
44
+ max_instance_count: 5
31
45
  ports:
32
46
  advertised_port: 8081
33
- running_port: 8080
47
+ listening_port: 8080
34
48
  dependancies: []
@@ -7,6 +7,7 @@ module Dendrite
7
7
  @graph = graph
8
8
  @services = graph.services
9
9
  .select { |service_name, service| service_names.include?(service_name) }
10
+ .collect { |_, service| service }
10
11
  end
11
12
 
12
13
  def to_h
@@ -4,7 +4,7 @@ module Dendrite
4
4
 
5
5
  def initialize(graph:, service_names:)
6
6
  super
7
- @services = @services.collect { |service_name, service| ServiceConfig.new(service)}
7
+ @services = @services.collect { |service| ServiceConfig.new(service)}
8
8
  end
9
9
 
10
10
  def to_h
@@ -22,6 +22,7 @@ module Dendrite
22
22
  extend Forwardable
23
23
  def_delegator :service, :name, :name
24
24
  def_delegator :service, :namespace, :namespace
25
+ def_delegator :service, :organization, :organization
25
26
 
26
27
  def to_h
27
28
  {
@@ -38,7 +39,7 @@ module Dendrite
38
39
  {
39
40
  reporter_type: 'zookeeper',
40
41
  zk_hosts: Dendrite::Config.zk_hosts,
41
- zk_path: "/smartstack/services/#{service.namespace}/#{service.name}/instances"
42
+ zk_path: "/smartstack/services/#{organization}/#{namespace}/#{service.real_name}/instances"
42
43
  }
43
44
  end
44
45
  end
@@ -3,14 +3,14 @@ module Dendrite
3
3
  class Synapse < Base
4
4
  def initialize(graph:, service_names:)
5
5
  super
6
- dep = {}
7
- @services.each do |service_name, service|
8
- service.dependancies.each do |dependancy_name, dependancy|
9
- dep[dependancy_name] = dependancy.service
6
+ dep = []
7
+ @services.each do |service|
8
+ service.dependancies.each do |_, dependancy|
9
+ dep << dependancy.service
10
10
  end
11
11
  end
12
- @services = dep
13
- @services = @services.collect { |service_name, service| ServiceConfig.new(service)}
12
+ @services = dep.uniq
13
+ @services = @services.collect { |service| ServiceConfig.new(service)}
14
14
  end
15
15
 
16
16
  def to_h
@@ -33,6 +33,7 @@ module Dendrite
33
33
  extend Forwardable
34
34
  def_delegator :service, :name, :name
35
35
  def_delegator :service, :namespace, :namespace
36
+ def_delegator :service, :organization, :organization
36
37
 
37
38
  def to_h
38
39
  discovery_config.merge(haproxy_config)
@@ -43,7 +44,7 @@ module Dendrite
43
44
  discovery: {
44
45
  method: 'zookeeper',
45
46
  hosts: Dendrite::Config.zk_hosts,
46
- path: "/smartstack/services/#{namespace}/#{name}/instances"
47
+ path: "/smartstack/services/#{organization}/#{namespace}/#{service.real_name}/instances"
47
48
  }
48
49
  }
49
50
  end
data/lib/dendrite/io.rb CHANGED
@@ -12,8 +12,10 @@ module Dendrite
12
12
  end
13
13
 
14
14
  services.each do |service|
15
+ node = ServiceNode.new(service)
15
16
  service[:dependancies].each do |deps|
16
- graph[service[:name]].add_dependancy(service: graph.fetch(deps[:name]), latency: deps[:latency])
17
+ dependancy_name = "#{service[:organization]}_#{deps[:namespace]}_#{deps[:name]}"
18
+ graph[node.name].add_dependancy(service: graph[dependancy_name], latency: deps[:latency])
17
19
  end
18
20
  end
19
21
 
@@ -34,9 +36,10 @@ module Dendrite
34
36
  def services_from_file(source:)
35
37
  data = read(source: source)
36
38
  data[:services].collect do |service|
37
- service[:namespace] = data[:namespace]
38
- service[:lead_email] = data[:lead_email]
39
- service[:team_email] = data[:team_email]
39
+ service[:organization] = data[:organization]
40
+ service[:namespace] = data[:namespace]
41
+ service[:lead_email] = data[:lead_email]
42
+ service[:team_email] = data[:team_email]
40
43
  service
41
44
  end
42
45
  end
@@ -11,24 +11,21 @@ module Dendrite
11
11
 
12
12
  def <<(service)
13
13
  raise KeyError unless service.name
14
- @services[service.name] = service
14
+ raise DuplicateService if services.keys.include?(service.name)
15
+ services[service.name] = service
15
16
  end
16
17
 
17
18
  def [](name)
18
- @services[name]
19
- end
20
-
21
- def fetch(name)
22
- @services.fetch(name)
19
+ services.fetch(name)
23
20
  end
24
21
 
25
22
  def valid?
26
- @services.values.collect(&:valid?).all?
23
+ services.values.collect(&:valid?).all?
27
24
  end
28
25
 
29
26
  def errors
30
- @services.inject({}) do |hash, (name, service)|
31
- hash[name] = service.errors.messages
27
+ services.inject({}) do |hash, (name, service)|
28
+ hash[name] = service.errors.messages if service.errors.messages.length > 0
32
29
  hash
33
30
  end
34
31
  end
@@ -3,7 +3,7 @@ module Dendrite
3
3
  def valid?
4
4
  super
5
5
 
6
- @dependancies.each do |depname, dep|
6
+ dependancies.each do |depname, dep|
7
7
  if dep.invalid?
8
8
  dep.errors.each do |key, value|
9
9
  errors.add "dependancy_#{key}", value
@@ -11,7 +11,7 @@ module Dendrite
11
11
  end
12
12
  end
13
13
 
14
- @ports.each do |depname, dep|
14
+ ports.each do |depname, dep|
15
15
  if dep.invalid?
16
16
  dep.errors.each do |key, value|
17
17
  errors.add "port_#{key}", value
@@ -19,6 +19,18 @@ module Dendrite
19
19
  end
20
20
  end
21
21
 
22
+ if deploy && deploy.invalid?
23
+ deploy.errors.each do |key, value|
24
+ errors.add "deploy_#{key}", value
25
+ end
26
+ end
27
+
28
+ if scale && scale.invalid?
29
+ scale.errors.each do |key, value|
30
+ errors.add "scale_#{key}", value
31
+ end
32
+ end
33
+
22
34
  return errors.count == 0
23
35
  end
24
36
  end
@@ -38,6 +50,27 @@ module Dendrite
38
50
  include ActiveModel::Validations
39
51
  validates_presence_of :service
40
52
  validates_presence_of :latency
53
+ validate :service_type
54
+
55
+ def service_type
56
+ unless service.is_a?(ServiceNode)
57
+ errors.add(:service, "service has to be a Service Node")
58
+ end
59
+ end
60
+ end
61
+
62
+ Scale = Struct.new(:max_instance_count, :min_instance_count) do
63
+ include ActiveModel::Validations
64
+ validates_presence_of :max_instance_count
65
+ validates_presence_of :min_instance_count
66
+ validates :max_instance_count, numericality: { only_integer: true }
67
+ validates :min_instance_count, numericality: { only_integer: true }
68
+ end
69
+
70
+ Deploy = Struct.new(:repository, :package) do
71
+ include ActiveModel::Validations
72
+ validates_presence_of :repository
73
+ validates_presence_of :package
41
74
  end
42
75
 
43
76
  VALID_TYPE = %w(
@@ -48,24 +81,34 @@ module Dendrite
48
81
  cassandra
49
82
  )
50
83
 
51
- attr_reader :namespace, :lead_email, :team_email,
52
- :name, :type, :repo, :package_name,
53
- :ports, :dependancies
84
+ VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i
54
85
 
55
- validates_presence_of :namespace, :lead_email, :team_email,
56
- :name, :type, :repo, :package_name
86
+ attr_reader :organization, :namespace, :lead_email, :team_email,
87
+ :type, :deploy, :scale, :ports, :dependancies
88
+ # :name is set but magically
57
89
 
58
- validates :namespace, format: { with: /\A[a-z_]+\z/, message: "only allows lowercase letters" }
90
+ validates_presence_of :organization, :namespace, :lead_email, :team_email,
91
+ :name, :type, :deploy, :scale
92
+
93
+ validates :organization, format: { with: /\A[a-z]+\z/, message: "only allows lowercase letters" }
94
+ validates :namespace, format: { with: /\A[a-z]+\z/, message: "only allows lowercase letters" }
95
+ validates :lead_email, format: { with: VALID_EMAIL_REGEX, message: "invalid email format" }
96
+ validates :team_email, format: { with: VALID_EMAIL_REGEX, message: "invalid email format" }
59
97
  validates :name, format: { with: /\A[a-z_]+\z/, message: "only allows lowercase letters" }
60
98
  validates :type, inclusion: { in: VALID_TYPE, message: "%{value} is not a valid type" }
61
99
 
62
100
  def initialize(**args)
63
101
  @ports = {}
64
102
  args.each do |k,v|
65
- if k == :ports
103
+ case k
104
+ when :ports
66
105
  v.each do |name, port|
67
106
  @ports[name] = Port.new(name, port)
68
107
  end
108
+ when :deploy
109
+ @deploy = Deploy.new(v[:repository], v[:package]) if v != nil
110
+ when :scale
111
+ @scale = Scale.new(v[:max_instance_count], v[:min_instance_count]) if v != nil
69
112
  else
70
113
  instance_variable_set("@#{k}", v)
71
114
  end
@@ -73,12 +116,20 @@ module Dendrite
73
116
  @dependancies = {}
74
117
  end
75
118
 
119
+ def real_name
120
+ @name
121
+ end
122
+
123
+ def name
124
+ "#{organization}_#{namespace}_#{@name}" if @name
125
+ end
126
+
76
127
  def listening_port
77
- ports[:advertised_port].port
128
+ ports[:listening_port].port if ports[:listening_port]
78
129
  end
79
130
 
80
131
  def advertised_port
81
- ports[:advertised_port].port
132
+ ports[:advertised_port].port if ports[:advertised_port]
82
133
  end
83
134
 
84
135
  def add_dependancy(service:, latency:)
@@ -1,3 +1,3 @@
1
1
  module Dendrite
2
- VERSION = "0.0.1"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/dendrite.rb CHANGED
@@ -14,6 +14,7 @@ module Dendrite
14
14
  Error = Class.new(StandardError)
15
15
  InvalidData = Class.new(Error)
16
16
  UnknownService = Class.new(Error)
17
+ DuplicateService = Class.new(Error)
17
18
 
18
19
  class Config
19
20
  class << self
@@ -50,7 +51,8 @@ module Dendrite
50
51
  end
51
52
 
52
53
  def public_ip
53
- ip = Socket.ip_address_list.detect{|intf| intf.ipv4_private?}
54
+ ip = Socket.ip_address_list.detect{|intf| intf.ipv4_private?} ||
55
+ Socket.ip_address_list.detect{|intf| intf.ipv4? && !intf.ipv4_loopback? && !intf.ipv4_multicast? && !intf.ipv4_private?}
54
56
  ip.ip_address if ip
55
57
  end
56
58
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dendrite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yagnik
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-01 00:00:00.000000000 Z
11
+ date: 2016-05-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler