hosties 1.1.0.alpha → 1.1.0.alpha2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b67e9ef6e1d2d98eaf6c3e5dc570e2b478e12708
4
- data.tar.gz: d3fa2796ecfee0d21f0091c6ca6d1518961d281f
3
+ metadata.gz: c5aad13eda9a31ed69dda41c369424d5311e4d60
4
+ data.tar.gz: 3a37f4fed44c321a37ec488580e164e7c521fd55
5
5
  SHA512:
6
- metadata.gz: c3b2df43b6b47519ad39ef1c339c60b94e0ad27f2d1b7941c4686e7cbaed8166735aa03ac4fa1c8b9a3fae126a41935e041030a669f6ab1c1410eb3d0d5ee326
7
- data.tar.gz: 86b140c14683a0b37cf754158920181856cd4fb0bc85f560806e37166b13246a0da667a2db1c965a0c1bb44574a601163ab7d8c2ae3cec5aea9bce4e11879e51
6
+ metadata.gz: 2c27fff8d37d95deb87f6387c360e5eb7a259aced2e88fd1ea730928100b1b9990bad978261b6ed0ce20d8806a8dc1b575dd1b75d12f24142965d9e8db120c8e
7
+ data.tar.gz: 0e18fd57a070555657954bb4433a147e6c4a9dd10a51e9a5e59b28976cf9f892de63459219147cacb71d58a9e710008fd5123e98f6e708335415e7b8af0e8470
@@ -4,138 +4,145 @@
4
4
  # have in order to be valid. #
5
5
  #######################################################################
6
6
 
7
- # Constrains a named attribute to a provided set of values. This is good
8
- # for things like describing environments that a set of hosts can be in,
9
- # for instance Dev, QA, etc
10
- class AttributeConstraint
11
- attr_reader :name, :possible_vals
12
-
13
- def initialize(name)
14
- @name = name
15
- @possible_vals = []
16
- end
7
+ module Hosties
8
+ # Constrains a named attribute to a provided set of values. This is good
9
+ # for things like describing environments that a set of hosts can be in,
10
+ # for instance Dev, QA, etc
11
+ class AttributeConstraint
12
+ attr_reader :name, :possible_vals
13
+
14
+ def initialize(name)
15
+ @name = name
16
+ @possible_vals = []
17
+ end
17
18
 
18
- def can_be(val, *more)
19
- @possible_vals += (more << val)
19
+ def can_be(val, *more)
20
+ @possible_vals += (more << val)
21
+ end
20
22
  end
21
- end
22
23
 
23
- # Superclass for the host and environment requirement types. This
24
- # class handles the plumbing of tracking, constraining, and eventually
25
- # reifying attributes.
26
- class HasAttributes
27
- attr_accessor :constraints
28
- attr_accessor :attributes
29
- def initialize
30
- @constraints = {}
31
- @attributes = []
32
- end
24
+ # Superclass for the host and environment requirement types. This
25
+ # class handles the plumbing of tracking, constraining, and eventually
26
+ # reifying attributes.
27
+ class HasAttributes
28
+ attr_accessor :constraints
29
+ attr_accessor :attributes
30
+
31
+ def initialize(verbotten = [])
32
+ @constraints = {}
33
+ @attributes = []
34
+ @verbotten = verbotten
35
+ end
33
36
 
34
- # Specify symbols that will later be reified into attributes
35
- def have_attributes(attr, *more)
36
- @attributes += (more << attr)
37
- end
37
+ # Specify symbols that will later be reified into attributes
38
+ def have_attributes(attr, *more)
39
+ sum = (more << attr)
40
+ sum.each do |name|
41
+ raise ArgumentError, "Reserved attribute name #{name}" if @verbotten.include?(name)
42
+ end
43
+ @attributes += sum
44
+ end
38
45
 
39
- alias_method :have_attribute, :have_attributes
40
- alias_method :has_attribute, :have_attribute
41
- alias_method :has_attributes, :have_attributes
46
+ alias_method :have_attribute, :have_attributes
47
+ alias_method :has_attribute, :have_attribute
48
+ alias_method :has_attributes, :have_attributes
42
49
 
43
- # Helpful method to define constraints
44
- def where(name)
45
- # Must define the attributes before constraining them
46
- raise ArgumentError, "Unknown attribute: #{name}" unless @attributes.include? name
47
- @constraints[name] = AttributeConstraint.new(name)
48
- end
50
+ # Helpful method to define constraints
51
+ def where(name)
52
+ # Must define the attributes before constraining them
53
+ raise ArgumentError, "Unknown attribute: #{name}" unless @attributes.include? name
54
+ @constraints[name] = AttributeConstraint.new(name)
55
+ end
49
56
 
50
- # Check if a given name-value pair is valid given the constraints
51
- def valid?(name, value)
52
- if @constraints.include? name then
53
- constraints[name].possible_vals.include? value
54
- else true end
57
+ # Check if a given name-value pair is valid given the constraints
58
+ def valid?(name, value)
59
+ if @constraints.include? name then
60
+ constraints[name].possible_vals.include? value
61
+ else true end
62
+ end
55
63
  end
56
- end
57
64
 
58
- # Defines what a host of a certain type looks like
59
- class HostRequirement < HasAttributes
60
- attr_reader :type, :services
61
- def initialize(type)
62
- super()
63
- @type = type
64
- @services = []
65
- end
65
+ # Defines what a host of a certain type looks like
66
+ class HostRequirement < HasAttributes
67
+ attr_reader :type, :services
68
+ def initialize(type)
69
+ super([:hostname, :type])
70
+ @type = type
71
+ @services = []
72
+ end
66
73
 
67
- # Services will be provided with a host definition. In order for
68
- # a host definition to be valid, it must provide service details
69
- # for all of the services specified by its matching
70
- # HostRequirement
71
- def have_services(service, *more)
72
- @services += (more << service)
73
- end
74
+ # Services will be provided with a host definition. In order for
75
+ # a host definition to be valid, it must provide service details
76
+ # for all of the services specified by its matching
77
+ # HostRequirement
78
+ def have_services(service, *more)
79
+ @services += (more << service)
80
+ end
74
81
 
75
- alias_method :have_service, :have_services
76
- alias_method :has_service, :have_service
77
- alias_method :has_services, :have_services
82
+ alias_method :have_service, :have_services
83
+ alias_method :has_service, :have_service
84
+ alias_method :has_services, :have_services
78
85
 
79
- def finished
80
- Hosties::HostDefinitions[@type] = self
86
+ def finished
87
+ Hosties::HostDefinitions[@type] = self
88
+ end
81
89
  end
82
- end
83
90
 
84
- # Builder method
85
- def host_type(symbol, &block)
86
- builder = HostRequirement.new(symbol)
87
- begin
88
- builder.instance_eval(&block)
89
- builder.finished
90
- rescue ArgumentError => ex
91
- # TODO: There must be a better way!
92
- # I'd like to provide some feedback in this case, but I don't
93
- # like having this show up in test output.
94
- #puts "Problem defining host \"#{symbol}\": #{ex}"
95
- end
96
- end
97
91
 
98
- # Used to describe an environment.
99
- class EnvironmentRequirement < HasAttributes
100
- attr_reader :type, :hosts, :grouping
101
- def initialize(type)
102
- super()
103
- @type = type
104
- @hosts = []
105
- end
92
+ # Used to describe an environment.
93
+ class EnvironmentRequirement < HasAttributes
94
+ attr_reader :type, :hosts, :grouping, :host_attributes
95
+ def initialize(type)
96
+ super([:type, :hosts])
97
+ @type = type
98
+ @host_attributes = []
99
+ @hosts = []
100
+ end
106
101
 
107
- # Define the hosts that an environment needs to be valid,
108
- # for instance, maybe you need a :logger host and a
109
- # :service host at a minimum.
110
- def need(host1, *more)
111
- sum = more << host1
112
- # Array doesn't have an 'exists' method, so behold - map reduce wankery!
113
- unless sum.map { |x| Hosties::HostDefinitions.include? x }.reduce(true) { |xs, x| x & xs }
114
- raise ArgumentError, "Unrecognized host type"
102
+ # Define the hosts that an environment needs to be valid,
103
+ # for instance, maybe you need a :logger host and a
104
+ # :service host at a minimum.
105
+ def need(host1, *more)
106
+ sum = more << host1
107
+ # Array doesn't have an 'exists' method, so behold - map reduce wankery!
108
+ unless sum.map { |x| Hosties::HostDefinitions.include? x }.reduce(true) { |xs, x| x & xs }
109
+ raise ArgumentError, "Unrecognized host type"
110
+ end
111
+ @hosts += sum
115
112
  end
116
- @hosts += sum
117
- end
118
113
 
119
- # Optionally specify an attribute to group by when registering
120
- # environments of this type.
121
- def grouped_by(attr)
122
- raise ArgumentError, "Unknown attribute #{attr}" unless @attributes.include?(attr)
123
- @grouping = attr
124
- end
114
+ alias_method :needs, :need
115
+
116
+ def hosts_inherit(attr)
117
+ unless self.attributes.include? attr then
118
+ raise ArgumentError, "Unrecognized attribute #{attr}"
119
+ end
120
+ @host_attributes << attr
121
+ end
125
122
 
126
- def finished
127
- Hosties::EnvironmentDefinitions[@type] = self
123
+ # Optionally specify an attribute to group by when registering
124
+ # environments of this type.
125
+ def grouped_by(attr)
126
+ raise ArgumentError, "Unknown attribute #{attr}" unless @attributes.include?(attr)
127
+ @grouping = attr
128
+ end
129
+
130
+ def finished
131
+ Hosties::EnvironmentDefinitions[@type] = self
132
+ end
128
133
  end
129
134
  end
130
135
 
131
- # Builder method
136
+ ## Globally accessible builder methods
137
+
132
138
  def environment_type(symbol, &block)
133
- builder = EnvironmentRequirement.new(symbol)
134
- begin
135
- builder.instance_eval(&block)
136
- builder.finished
137
- rescue ArgumentError => ex
138
- # TODO: Same as above, find a better way to get this information out
139
- #puts "Problem describing environment \"#{builder.type}\": #{ex}"
140
- end
139
+ builder = Hosties::EnvironmentRequirement.new(symbol)
140
+ builder.instance_eval(&block)
141
+ builder.finished
142
+ end
143
+
144
+ def host_type(symbol, &block)
145
+ builder = Hosties::HostRequirement.new(symbol)
146
+ builder.instance_eval(&block)
147
+ builder.finished
141
148
  end
@@ -2,23 +2,33 @@
2
2
  # Provide a more convenient data structure to work with once #
3
3
  # environment declarations have been read. #
4
4
  ###############################################################
5
- class DataWrapper
6
- def metaclass
7
- class << self
8
- self
9
- end
10
- end
11
- end
12
-
13
5
  module Hosties
14
6
  module EasyData
7
+ class DataWrapper
8
+ def metaclass
9
+ class << self
10
+ self
11
+ end
12
+ end
13
+ end
14
+
15
15
  def self.fromHost(hash)
16
16
  result = DataWrapper.new
17
17
  hash.each do |k, v|
18
18
  result.metaclass.send(:define_method, k) do v end
19
19
  end
20
+ # Define a human-friendly to_s
21
+ # NOTE: Application behavior should not rely on the stability of this
22
+ # string representation! It is subject to change whenever I'm feeling
23
+ # squirrely.
24
+ filtered_hash = hash.reject { |k,v| k == :type or k == :hostname }
25
+ attr_string = filtered_hash.map{|k,v| "#{k}: #{v}"}.join(", ")
26
+ result.metaclass.send(:define_method, :to_s) do
27
+ "<#{hash[:type]} host @ #{hash[:hostname]} attrs: #{attr_string}>"
28
+ end
20
29
  result
21
30
  end
31
+
22
32
  def self.fromEnv(hash)
23
33
  result = DataWrapper.new
24
34
  hash.each do |k, v|
@@ -34,6 +44,23 @@ module Hosties
34
44
  result.metaclass.send(:define_method, :each_host) do |&block|
35
45
  yield self.hosts
36
46
  end
47
+ # Apply all of the host_attributes to our little host children
48
+ definition = Hosties::EnvironmentDefinitions[hash[:type]]
49
+ inheritance = definition.host_attributes
50
+ hash[:hosts].each do |host|
51
+ inheritance.each do |attr|
52
+ val = hash[attr]
53
+ host.metaclass.send(:define_method, attr) do val end
54
+ end
55
+ end
56
+ # Human friendly to_s
57
+ # NOTE: As above, this representation is subject to change whenever,
58
+ # don't rely on it for application behavior!
59
+ filtered_hash = hash.reject { |k,v| k == :type or k == :hosts }
60
+ attr_string = filtered_hash.map{|k,v| "#{k}: #{v}"}.join(", ")
61
+ result.metaclass.send(:define_method, :to_s) do
62
+ "<#{hash[:type]} environment, attrs: #{attr_string}, hosts: #{hash[:hosts].join(", ")}>"
63
+ end
37
64
  result
38
65
  end
39
66
  end
@@ -2,113 +2,117 @@
2
2
  # Provide some classes to turn a declarative host definition into something
3
3
  # more useful in code, applying rules from the definition files to ensure we
4
4
  # only get valid stuff.
5
- class UsesAttributes
6
- # Oh this old thing...
7
- def metaclass
8
- class << self
9
- self
5
+
6
+ module Hosties
7
+ class UsesAttributes
8
+ # Oh this old thing...
9
+ def metaclass
10
+ class << self
11
+ self
12
+ end
10
13
  end
11
- end
12
- def initialize(has_attributes)
13
- @attributes = has_attributes.attributes
14
- # Magic.
15
- has_attributes.attributes.each do |attr|
16
- # Add in the attribute
17
- self.metaclass.send(:attr_accessor, attr)
18
- # Define a constrained setter
19
- self.metaclass.send(:define_method, attr) do |val|
20
- raise ArgumentError, "Invalid value" unless has_attributes.valid?(attr, val)
21
- instance_variable_set "@#{attr}", val
14
+ def initialize(has_attributes)
15
+ @attributes = has_attributes.attributes
16
+ # Magic.
17
+ has_attributes.attributes.each do |attr|
18
+ # Add in the attribute
19
+ self.metaclass.send(:attr_accessor, attr)
20
+ # Define a constrained setter
21
+ self.metaclass.send(:define_method, attr) do |val|
22
+ raise ArgumentError, "Invalid value" unless has_attributes.valid?(attr, val)
23
+ instance_variable_set "@#{attr}", val
24
+ end
22
25
  end
23
26
  end
24
- end
25
27
 
26
- # Return a hash after verifying everything was set correctly
27
- def finish
28
- retval = {}
29
- # Ensure all required attributes have been set
30
- @attributes.each do |attr|
31
- val = instance_variable_get "@#{attr}"
32
- raise ArgumentError, "Missing attribute #{attr}" if val.nil?
33
- retval[attr] = val
28
+ # Return a hash after verifying everything was set correctly
29
+ def finish
30
+ retval = {}
31
+ # Ensure all required attributes have been set
32
+ @attributes.each do |attr|
33
+ val = instance_variable_get "@#{attr}"
34
+ raise ArgumentError, "Missing attribute #{attr}" if val.nil?
35
+ retval[attr] = val
36
+ end
37
+ retval
34
38
  end
35
- retval
36
39
  end
37
- end
38
40
 
39
- class HostBuilder < UsesAttributes
40
- def initialize(type, hostname)
41
- if Hosties::HostDefinitions[type].nil? then
42
- raise ArgumentError, "Unrecognized host type"
43
- end
44
- @type = type
45
- @definition = Hosties::HostDefinitions[@type]
46
- @hostname = hostname
47
- @service_ports = {} # Map of service type to port
48
- super(@definition) # Creates attribute code
49
- # Services are really just a special kind of attribute, but for now I'll
50
- # keep them separate. I'm thinking maybe I could add a new type of attribute
51
- # constraint that let's a user specify that an attribute must be numeric, or
52
- # a string for instance.
53
- @definition.services.each do |service_type|
54
- self.metaclass.send(:attr_accessor, service_type)
55
- self.metaclass.send(:define_method, service_type) do |port|
56
- raise ArgumentError, "Port number required" unless port.is_a? Integer
57
- @service_ports[service_type] = port
41
+ class HostBuilder < UsesAttributes
42
+ def initialize(type, hostname)
43
+ if Hosties::HostDefinitions[type].nil? then
44
+ raise ArgumentError, "Unrecognized host type"
45
+ end
46
+ @type = type
47
+ @definition = Hosties::HostDefinitions[@type]
48
+ @hostname = hostname
49
+ @service_ports = {} # Map of service type to port
50
+ super(@definition) # Creates attribute code
51
+ # Services are really just a special kind of attribute, but for now I'll
52
+ # keep them separate. I'm thinking maybe I could add a new type of attribute
53
+ # constraint that let's a user specify that an attribute must be numeric, or
54
+ # a string for instance.
55
+ @definition.services.each do |service_type|
56
+ self.metaclass.send(:attr_accessor, service_type)
57
+ self.metaclass.send(:define_method, service_type) do |port|
58
+ raise ArgumentError, "Port number required" unless port.is_a? Integer
59
+ @service_ports[service_type] = port
60
+ end
58
61
  end
59
62
  end
60
- end
61
63
 
62
- def finish
63
- # Ensure all services have been set
64
- @definition.services.each do |svc|
65
- raise ArgumentError, "Missing service #{svc}" if @service_ports[svc].nil?
64
+ def finish
65
+ # Ensure all services have been set
66
+ @definition.services.each do |svc|
67
+ raise ArgumentError, "Missing service #{svc}" if @service_ports[svc].nil?
68
+ end
69
+ # TODO: Declare these reserved names
70
+ super.merge({ :hostname => @hostname, :type => @type }).merge(@service_ports)
66
71
  end
67
- # TODO: Declare these reserved names
68
- super.merge({ :hostname => @hostname, :type => @type }).merge(@service_ports)
69
72
  end
70
- end
71
73
 
72
- # Turn a description into a useful data structure - and it's validated!
73
- class EnvironmentBuilder < UsesAttributes
74
- def initialize(type)
75
- if Hosties::EnvironmentDefinitions[type].nil? then
76
- raise ArgumentError, "Unrecognized environment type"
77
- end
78
- @hosts = []
79
- @type = type
80
- @definition = Hosties::EnvironmentDefinitions[@type]
81
- super(@definition) # Creates attribute code
82
- # More magic, this time create a parameterized host builder based
83
- # on the type of hosts this environment wants. Poor man's currying
84
- @definition.hosts.each do |host_type|
85
- self.metaclass.send(:define_method, host_type) do |hostname, &block|
86
- begin
87
- builder = HostBuilder.new(host_type, hostname)
88
- builder.instance_eval(&block)
89
- @hosts << Hosties::EasyData.fromHost(builder.finish)
90
- rescue ArgumentError => ex
91
- #puts "Problem declaring host: #{ex}"
92
- raise ex
74
+ # Turn a description into a useful data structure - and it's validated!
75
+ class EnvironmentBuilder < UsesAttributes
76
+ def initialize(type)
77
+ if Hosties::EnvironmentDefinitions[type].nil? then
78
+ raise ArgumentError, "Unrecognized environment type"
79
+ end
80
+ @hosts = []
81
+ @type = type
82
+ @definition = Hosties::EnvironmentDefinitions[@type]
83
+ super(@definition) # Creates attribute code
84
+ # More magic, this time create a parameterized host builder based
85
+ # on the type of hosts this environment wants. Poor man's currying
86
+ @definition.hosts.each do |host_type|
87
+ self.metaclass.send(:define_method, host_type) do |hostname, &block|
88
+ begin
89
+ builder = HostBuilder.new(host_type, hostname)
90
+ builder.instance_eval(&block)
91
+ @hosts << Hosties::EasyData.fromHost(builder.finish)
92
+ rescue ArgumentError => ex
93
+ #puts "Problem declaring host: #{ex}"
94
+ raise ex
95
+ end
93
96
  end
94
97
  end
95
98
  end
96
- end
97
99
 
98
- def finish
99
- # Verify all of the required hosts were set
100
- @definition.hosts.each do |host_type|
101
- unless @hosts.detect { |host| host.type == host_type } then
102
- raise ArgumentError, "Missing #{host_type} host"
100
+ def finish
101
+ # Verify all of the required hosts were set
102
+ @definition.hosts.each do |host_type|
103
+ unless @hosts.detect { |host| host.type == host_type } then
104
+ raise ArgumentError, "Missing #{host_type} host"
105
+ end
103
106
  end
107
+ super.merge({ :type => @type, :hosts => @hosts })
104
108
  end
105
- super.merge({ :hosts => @hosts })
106
109
  end
107
110
  end
108
111
 
112
+ ## Globally accessible builder methods
109
113
  def environment_for(type, &block)
110
114
  begin
111
- builder = EnvironmentBuilder.new(type)
115
+ builder = Hosties::EnvironmentBuilder.new(type)
112
116
  builder.instance_eval(&block)
113
117
  data = builder.finish
114
118
  nice_version = Hosties::EasyData.fromEnv(data)
@@ -1,14 +1,14 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe HasAttributes do
3
+ describe Hosties::HasAttributes do
4
4
  it 'rejects definitions with constraints on nonexistent attributes' do
5
- instance = HasAttributes.new
5
+ instance = Hosties::HasAttributes.new
6
6
  instance.have_attributes :foo, :bar
7
7
  expect { instance.where(:baz).can_be("anything") }.to raise_error(ArgumentError)
8
8
  end
9
9
  end
10
10
 
11
- describe HostRequirement do
11
+ describe Hosties::HostRequirement do
12
12
  it 'defines host types' do
13
13
  # Declare a host type
14
14
  host_type :logger do
@@ -16,9 +16,17 @@ describe HostRequirement do
16
16
  have_attributes :control_mbean, :default_user
17
17
  end
18
18
  end
19
+
20
+ it 'rejects definitions with reserved attribute names' do
21
+ builder = Hosties::HostRequirement.new(:failsauce)
22
+ # hostname
23
+ expect { builder.have_attributes(:hostname) }.to raise_error(ArgumentError)
24
+ # type
25
+ expect { builder.have_attributes(:type) }.to raise_error(ArgumentError)
26
+ end
19
27
  end
20
28
 
21
- describe EnvironmentRequirement do
29
+ describe Hosties::EnvironmentRequirement do
22
30
  it 'defines environments with host and attribute requirements' do
23
31
  host_type :mutant_maker do end
24
32
  host_type :turkey_blaster do end
@@ -28,13 +36,32 @@ describe EnvironmentRequirement do
28
36
  end
29
37
  end
30
38
 
39
+ it 'rejects definitions with reserved attribute names' do
40
+ builder = Hosties::EnvironmentRequirement.new(:failsauce)
41
+ # hosts
42
+ expect { builder.have_attributes(:hosts) }.to raise_error(ArgumentError)
43
+ # type
44
+ expect { builder.have_attributes(:type) }.to raise_error(ArgumentError)
45
+ end
46
+
31
47
  it 'rejects environment definitions that need undefined host types' do
32
- builder = EnvironmentRequirement.new(:failure)
48
+ builder = Hosties::EnvironmentRequirement.new(:failure)
33
49
  expect { builder.need(:nonexistent) }.to raise_error(ArgumentError)
34
50
  end
35
51
 
36
52
  it 'rejects groupings for unknown attributes' do
37
- builder = EnvironmentRequirement.new(:failure)
53
+ builder = Hosties::EnvironmentRequirement.new(:failure)
38
54
  expect { builder.grouped_by(:nonexistent) }.to raise_error(ArgumentError)
39
55
  end
56
+
57
+ it 'can define host-inherited attributes ' do
58
+ builder = Hosties::EnvironmentRequirement.new(:inherit_provider)
59
+ builder.has_attribute :to_inherit
60
+ builder.hosts_inherit :to_inherit
61
+ end
62
+
63
+ it 'catches faulty hosts_inherit clauses' do
64
+ builder = Hosties::EnvironmentRequirement.new(:inherit_failure)
65
+ expect { builder.hosts_inherit :to_inherit }.to raise_error(ArgumentError)
66
+ end
40
67
  end
@@ -6,7 +6,7 @@ describe Hosties::EasyData do
6
6
  have_service :http
7
7
  have_attribute :attr_one
8
8
  end
9
- builder = HostBuilder.new(:easydata_one, "localhost")
9
+ builder = Hosties::HostBuilder.new(:easydata_one, "localhost")
10
10
  builder.http 80
11
11
  builder.attr_one "One!"
12
12
  result = Hosties::EasyData.fromHost(builder.finish)
@@ -24,7 +24,7 @@ describe Hosties::EasyData do
24
24
  have_attribute :environment
25
25
  where(:environment).can_be :dev, :testing
26
26
  end
27
- builder = EnvironmentBuilder.new :easydata_one
27
+ builder = Hosties::EnvironmentBuilder.new :easydata_one
28
28
  builder.easydata_two "0.0.0.0" do end
29
29
  builder.easydata_three "1.1.1.1" do end
30
30
  builder.environment :dev
data/spec/hosties_spec.rb CHANGED
@@ -4,7 +4,7 @@ describe Hosties do
4
4
  it 'can declare a host' do
5
5
  host_type :special_host do
6
6
  end
7
- instance = HostBuilder.new(:special_host, "0.0.0.0")
7
+ instance = Hosties::HostBuilder.new(:special_host, "0.0.0.0")
8
8
  expect(instance.finish).to eq({ :hostname => "0.0.0.0", :type => :special_host})
9
9
  end
10
10
 
@@ -12,7 +12,7 @@ describe Hosties do
12
12
  host_type :web_host do
13
13
  have_service :http
14
14
  end
15
- instance = HostBuilder.new(:web_host, "0.0.0.0")
15
+ instance = Hosties::HostBuilder.new(:web_host, "0.0.0.0")
16
16
  expect { instance.finish }.to raise_error(ArgumentError)
17
17
  end
18
18
 
@@ -20,7 +20,7 @@ describe Hosties do
20
20
  host_type :mud_server do
21
21
  have_attribute :version
22
22
  end
23
- instance = HostBuilder.new(:mud_server, "0.0.0.0")
23
+ instance = Hosties::HostBuilder.new(:mud_server, "0.0.0.0")
24
24
  expect { instance.finish }.to raise_error(ArgumentError)
25
25
  end
26
26
 
@@ -28,7 +28,7 @@ describe Hosties do
28
28
  host_type :web_host do
29
29
  have_service :http
30
30
  end
31
- instance = HostBuilder.new(:web_host, "0.0.0.0")
31
+ instance = Hosties::HostBuilder.new(:web_host, "0.0.0.0")
32
32
  expect { instance.http 10.4 }.to raise_error(ArgumentError)
33
33
  end
34
34
 
@@ -40,7 +40,7 @@ describe Hosties do
40
40
  environment_type :needy_environment do
41
41
  need :type_a, :type_b
42
42
  end
43
- builder = EnvironmentBuilder.new(:needy_environment)
43
+ builder = Hosties::EnvironmentBuilder.new(:needy_environment)
44
44
  builder.type_a "0.0.0.0" do end
45
45
  # No type_b specified
46
46
  expect { builder.finish }.to raise_error(ArgumentError)
@@ -85,6 +85,7 @@ describe Hosties do
85
85
  expect(data.hosts_by_type(:monitoring).size).to eq(2) # Two monitoring hosts
86
86
  expect(data.hosts_by_type(:service_host).size).to eq(1)
87
87
  service_host = data.hosts_by_type(:service_host).first
88
+ expect(service_host.hostname).to eq("192.168.0.3")
88
89
  expect(service_host.service_port).to eq(1234)
89
90
  expect(service_host.uuid).to eq("81E3C1D4-C040-4D59-A56F-4273384D576B")
90
91
  end
@@ -111,4 +112,21 @@ describe Hosties do
111
112
  expect(Hosties::GroupedEnvironments[:foobar][:dev].size).to eq(1)
112
113
  expect(Hosties::GroupedEnvironments[:foobar][:qa].size).to eq(1)
113
114
  end
115
+
116
+ it 'lets hosts inherit attributes' do
117
+ host_type :beneficiary do end# ha.
118
+ environment_type :benefactor do
119
+ need :beneficiary
120
+ has_attribute :monies
121
+ hosts_inherit :monies # Lucky!
122
+ end
123
+ amount = 1000000
124
+ environment_for :benefactor do
125
+ beneficiary "0.0.0.0" do end
126
+ # Prove that ordering doesn't matter here
127
+ monies amount
128
+ end
129
+ beneficiary = Hosties::Environments[:benefactor].first.hosts.first
130
+ expect(beneficiary.monies).to eq(amount)
131
+ end
114
132
  end
@@ -1,18 +1,18 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe UsesAttributes do
3
+ describe Hosties::UsesAttributes do
4
4
  it 'can enforce attribute constraints' do
5
- definition = HasAttributes.new
5
+ definition = Hosties::HasAttributes.new
6
6
  definition.have_attributes(:x)
7
7
  definition.where(:x).can_be("hello")
8
- instance = UsesAttributes.new(definition)
8
+ instance = Hosties::UsesAttributes.new(definition)
9
9
  instance.x "hello"
10
10
  expect { instance.x 31 }.to raise_error(ArgumentError)
11
11
  end
12
12
  it 'catches missing attributes' do
13
- definition = HasAttributes.new
13
+ definition = Hosties::HasAttributes.new
14
14
  definition.have_attributes(:x)
15
- instance = UsesAttributes.new(definition)
15
+ instance = Hosties::UsesAttributes.new(definition)
16
16
  expect { instance.finish }.to raise_error(ArgumentError)
17
17
  end
18
18
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hosties
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0.alpha
4
+ version: 1.1.0.alpha2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ron Dahlgren