the-maestro 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +25 -0
- data/LICENSE +23 -0
- data/README.rdoc +378 -0
- data/Rakefile +116 -0
- data/VERSION +1 -0
- data/lib/maestro.rb +354 -0
- data/lib/maestro/cloud.rb +384 -0
- data/lib/maestro/cloud/aws.rb +1231 -0
- data/lib/maestro/dsl_property.rb +15 -0
- data/lib/maestro/log4r/console_formatter.rb +18 -0
- data/lib/maestro/log4r/file_formatter.rb +24 -0
- data/lib/maestro/node.rb +123 -0
- data/lib/maestro/operating_system.rb +53 -0
- data/lib/maestro/operating_system/cent_os.rb +23 -0
- data/lib/maestro/operating_system/debian.rb +40 -0
- data/lib/maestro/operating_system/fedora.rb +23 -0
- data/lib/maestro/operating_system/ubuntu.rb +100 -0
- data/lib/maestro/role.rb +36 -0
- data/lib/maestro/tasks.rb +52 -0
- data/lib/maestro/validator.rb +32 -0
- data/rails/init.rb +1 -0
- data/test/integration/base_aws.rb +156 -0
- data/test/integration/fixtures/config/maestro/cookbooks/emacs/metadata.json +41 -0
- data/test/integration/fixtures/config/maestro/cookbooks/emacs/metadata.rb +3 -0
- data/test/integration/fixtures/config/maestro/cookbooks/emacs/recipes/default.rb +21 -0
- data/test/integration/fixtures/config/maestro/roles/default.json +9 -0
- data/test/integration/fixtures/config/maestro/roles/web.json +9 -0
- data/test/integration/helper.rb +8 -0
- data/test/integration/test_aws_cloud.rb +805 -0
- data/test/integration/test_cent_os.rb +104 -0
- data/test/integration/test_debian.rb +119 -0
- data/test/integration/test_fedora.rb +104 -0
- data/test/integration/test_ubuntu.rb +149 -0
- data/test/unit/fixtures/invalid-clouds-not-a-directory/config/maestro/clouds +1 -0
- data/test/unit/fixtures/invalid-cookbooks-not-a-directory/config/maestro/cookbooks +0 -0
- data/test/unit/fixtures/invalid-maestro-not-a-directory/config/maestro +0 -0
- data/test/unit/fixtures/invalid-missing-cookbooks/config/maestro/clouds/valid.yml +21 -0
- data/test/unit/fixtures/invalid-missing-roles/config/maestro/clouds/valid.yml +21 -0
- data/test/unit/fixtures/invalid-roles-not-a-directory/config/maestro/roles +1 -0
- data/test/unit/fixtures/ssh/id_rsa-maestro-test-keypair +27 -0
- data/test/unit/helper.rb +6 -0
- data/test/unit/test_aws_cloud.rb +133 -0
- data/test/unit/test_aws_ec2_node.rb +76 -0
- data/test/unit/test_aws_elb_node.rb +221 -0
- data/test/unit/test_aws_rds_node.rb +380 -0
- data/test/unit/test_cent_os.rb +28 -0
- data/test/unit/test_cloud.rb +142 -0
- data/test/unit/test_debian.rb +62 -0
- data/test/unit/test_fedora.rb +28 -0
- data/test/unit/test_invalid_mode.rb +11 -0
- data/test/unit/test_maestro.rb +140 -0
- data/test/unit/test_node.rb +50 -0
- data/test/unit/test_operating_system.rb +19 -0
- data/test/unit/test_rails_mode.rb +77 -0
- data/test/unit/test_role.rb +59 -0
- data/test/unit/test_standalone_mode.rb +75 -0
- data/test/unit/test_ubuntu.rb +95 -0
- data/the-maestro.gemspec +150 -0
- metadata +228 -0
@@ -0,0 +1 @@
|
|
1
|
+
hi
|
File without changes
|
File without changes
|
@@ -0,0 +1,21 @@
|
|
1
|
+
provider: ec2
|
2
|
+
provider_config:
|
3
|
+
aws_account_id: XXXX-XXXX-XXXX
|
4
|
+
aws_access_key: XXXXXXXXXXXXXXXXXXXX
|
5
|
+
aws_secret_access_key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
6
|
+
keypair_name: maestro-test-keypair
|
7
|
+
keypair_file: /home/foo/id_rsa-maestro-test-keypair
|
8
|
+
|
9
|
+
roles:
|
10
|
+
web:
|
11
|
+
public_ports: [80, 443]
|
12
|
+
db-master: {}
|
13
|
+
|
14
|
+
nodes:
|
15
|
+
test-1.maestro-rails-test.node:
|
16
|
+
# Node -> Role mapping
|
17
|
+
roles: [web, db-master]
|
18
|
+
provider_config:
|
19
|
+
ami: ami-XXXXXXXX
|
20
|
+
instance_type: m1.small
|
21
|
+
availability_zone: us-east-1b
|
@@ -0,0 +1,21 @@
|
|
1
|
+
provider: ec2
|
2
|
+
provider_config:
|
3
|
+
aws_account_id: XXXX-XXXX-XXXX
|
4
|
+
aws_access_key: XXXXXXXXXXXXXXXXXXXX
|
5
|
+
aws_secret_access_key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
6
|
+
keypair_name: maestro-test-keypair
|
7
|
+
keypair_file: /home/foo/id_rsa-maestro-test-keypair
|
8
|
+
|
9
|
+
roles:
|
10
|
+
web:
|
11
|
+
public_ports: [80, 443]
|
12
|
+
db-master: {}
|
13
|
+
|
14
|
+
nodes:
|
15
|
+
test-1.maestro-rails-test.node:
|
16
|
+
# Node -> Role mapping
|
17
|
+
roles: [web, db-master]
|
18
|
+
provider_config:
|
19
|
+
ami: ami-XXXXXXXX
|
20
|
+
instance_type: m1.small
|
21
|
+
availability_zone: us-east-1b
|
@@ -0,0 +1 @@
|
|
1
|
+
hi
|
@@ -0,0 +1,27 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
MIIEowIBAAKCAQEApiOBafftYOaMlJkP+xrVf/0ULMCZ0VUk42EigDA6t8cloejW
|
3
|
+
HAR5NJ8k6wlOiszvoSpb2Pi+tLPfDOwHzJCl3DSvn1kVpmozC7CyZwz0+67JBRus
|
4
|
+
LgJMR2zzlBnFql55MV9a0XxYlOGNnvvYlSqrgwzSnMONU9X8br9AX7Ivjt5Dkk95
|
5
|
+
+bnShrSVop0vF0K1dWkWFFbmaKnYBkzKD2Rt6w1Wblm5geW74FLQYIxWzKiz0WZI
|
6
|
+
lX74A1BsYpvp6viVZXX3hw7LYuLTHYIyz/sKgupzItw+kaKJK8B1reP/RKuD1Alg
|
7
|
+
AWxuAEcH2zSDU+2FxDYfJKoMELN4BgVZF1gFBQIDAQABAoIBADcsK1oJn6dCaQUg
|
8
|
+
H5KAQs6SORTzkSFXaTypkU+ItLc7R2ARdqkvQyEaiKQVHyQxEpMvAfl4Abz4zuX3
|
9
|
+
rE9e6fXK+Vetuebd9b24HEbkoqbCULeFjRRqZvKBWBKizGXbodunkv1mkfQ/Q0y8
|
10
|
+
zhwbY4HNzFOLDW/97CrLEJG3FtwWorcugYr2acilVV6z4R5uxcuuDGSK1GM7dvwR
|
11
|
+
tMZ2tJCRwpNuw3fH7nW+zcjk/x8fhC69IvtjuCaQPdMhuUeuRAEi4lC/ryka9WQ+
|
12
|
+
kNuGlPrLPsDAQtfJHL40XEUH/MH4GvCg4v002OD8XaDpYxASWuHrHv3a1o5KFG8r
|
13
|
+
hHARtwECgYEA11+SKqE2PM2avHSS37sEee/FVWjW6wCn7vT3V63yqKrMLkhwkwHw
|
14
|
+
zDzBC+XYsbilRwKHQNIJ8vhXEWurqJie4c/ZmUa/rpT76PWOKubUFxc1oQf37mrj
|
15
|
+
jM+N6jmbK7f9+odmpJET1nyc8s3ROV4c4iom+ftHEkX8sS0vxeTxbrECgYEAxXph
|
16
|
+
7hNl1yJEvAIgtT5qIKyxcYBFHIFehrD3hlPydtOusx7KWG/rc+CUICL3reAJ+SHa
|
17
|
+
KfZ5iruMegZsXmHV0tUwTOTd9TnPaEKJfxByFYQTX5XAXxzdtA1UD/pr553vZVgq
|
18
|
+
Pb5DWQKXU1TqatTE44ot/9bi2nFzytTh9CwSGJUCgYAoTZIkuBZWOoOCUK5Lf8vO
|
19
|
+
pbffy8asI2tJpD3FAqAuQAgFgTjPycUt8xCNEW4Dk/IZ37c/wg5qkV55vBRbcHQK
|
20
|
+
/cJSlJK6MNcTOSBpltiJmaZHhB45V3dNmmmMM0t+WugEQeJLWXrE4HzeUvWcLqhp
|
21
|
+
CkpQ7VzXZpFq9nHCLp2fgQKBgBeh/MREGAT1+enSC14FWSgN4rJlml+977UIyqaN
|
22
|
+
t0+XJ6oR/j81LaVRdAighqmNTUQ+U+B/ua3rofUcfa2R4cf4cW5SWWm2gGbGx7Oo
|
23
|
+
IS8H/lWLE1mOl82rZqr+2hj+4p5rParj8SVe1QNI/0DHs8RTTgv3CHEB8MyOS3gw
|
24
|
+
Kf49AoGBALhv8PiSNyMtDj3BGtB6Mfs/8tg0Zbk+c4P0A52ppNA7414OqVx0A1ML
|
25
|
+
VIw2kOU19Yj6CmRyzBZLeTDaWArwEYyDEblWs9tklI7HNAR3KfW/ptp8XrYT+w98
|
26
|
+
N5BkWOgV7Zcr90vj9WbAMr4bQHi2SoXG2zSKagUuoQ6hblDdUZxT
|
27
|
+
-----END RSA PRIVATE KEY-----
|
data/test/unit/helper.rb
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
# Unit tests for Maestro::Cloud::Aws
|
4
|
+
class TestAwsCloud < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "Maestro::Cloud::Aws" do
|
7
|
+
setup do
|
8
|
+
@cloud = aws_cloud :test do
|
9
|
+
keypair_name "XXXXXXX-keypair"
|
10
|
+
keypair_file "/path/to/id_rsa-XXXXXXX-keypair"
|
11
|
+
aws_account_id "XXXX-XXXX-XXXX"
|
12
|
+
aws_access_key "XXXXXXXXXXXXXXXXXXXX"
|
13
|
+
aws_secret_access_key "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
14
|
+
chef_bucket "maestro.mydomain.com"
|
15
|
+
|
16
|
+
roles do
|
17
|
+
role "web" do
|
18
|
+
public_ports [80, 443]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
nodes do
|
23
|
+
ec2_node "web-1" do
|
24
|
+
roles ["web"]
|
25
|
+
ami "ami-bb709dd2"
|
26
|
+
ssh_user "ubuntu"
|
27
|
+
instance_type "m1.small"
|
28
|
+
availability_zone "us-east-1b"
|
29
|
+
elastic_ip "111.111.11.111"
|
30
|
+
ebs_volume_id "vol-XXXXXXXX"
|
31
|
+
ebs_device "/dev/sdh"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
should "be invalid due to duplicate ec2 nodes" do
|
38
|
+
cloud = aws_cloud :test do
|
39
|
+
keypair_name "XXXXXXX-keypair"
|
40
|
+
keypair_file "/path/to/id_rsa-XXXXXXX-keypair"
|
41
|
+
aws_account_id "XXXX-XXXX-XXXX"
|
42
|
+
aws_access_key "XXXXXXXXXXXXXXXXXXXX"
|
43
|
+
aws_secret_access_key "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
44
|
+
chef_bucket "maestro.mydomain.com"
|
45
|
+
|
46
|
+
roles {}
|
47
|
+
|
48
|
+
nodes do
|
49
|
+
ec2_node "web-1" do
|
50
|
+
roles ["web"]
|
51
|
+
ami "ami-bb709dd2"
|
52
|
+
ssh_user "ubuntu"
|
53
|
+
instance_type "m1.small"
|
54
|
+
availability_zone "us-east-1b"
|
55
|
+
elastic_ip "111.111.11.111"
|
56
|
+
ebs_volume_id "vol-XXXXXXXX"
|
57
|
+
ebs_device "/dev/sdh"
|
58
|
+
end
|
59
|
+
ec2_node "web-1" do
|
60
|
+
roles ["web"]
|
61
|
+
ami "ami-bb709dd2"
|
62
|
+
ssh_user "ubuntu"
|
63
|
+
instance_type "m1.small"
|
64
|
+
availability_zone "us-east-1b"
|
65
|
+
elastic_ip "111.111.11.111"
|
66
|
+
ebs_volume_id "vol-XXXXXXXX"
|
67
|
+
ebs_device "/dev/sdh"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
cloud.validate
|
72
|
+
assert !cloud.valid?
|
73
|
+
assert cloud.validation_errors.any? {|message| !message.index("Duplicate node definition: web-1").nil?}
|
74
|
+
end
|
75
|
+
|
76
|
+
should "be invalid due to duplicate elb nodes" do
|
77
|
+
cloud = aws_cloud :test do
|
78
|
+
keypair_name "XXXXXXX-keypair"
|
79
|
+
keypair_file "/path/to/id_rsa-XXXXXXX-keypair"
|
80
|
+
aws_account_id "XXXX-XXXX-XXXX"
|
81
|
+
aws_access_key "XXXXXXXXXXXXXXXXXXXX"
|
82
|
+
aws_secret_access_key "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
83
|
+
chef_bucket "maestro.mydomain.com"
|
84
|
+
|
85
|
+
roles {}
|
86
|
+
|
87
|
+
nodes do
|
88
|
+
elb_node "lb-1" do
|
89
|
+
end
|
90
|
+
elb_node "lb-1" do
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
cloud.validate
|
95
|
+
assert !cloud.valid?
|
96
|
+
assert cloud.validation_errors.any? {|message| !message.index("Duplicate node definition: lb-1").nil?}
|
97
|
+
end
|
98
|
+
|
99
|
+
should "be invalid due to missing aws access key" do
|
100
|
+
@cloud.aws_access_key nil
|
101
|
+
@cloud.validate
|
102
|
+
assert !@cloud.valid?
|
103
|
+
assert @cloud.validation_errors.any? {|message| !message.index("Missing aws_access_key").nil? }
|
104
|
+
end
|
105
|
+
|
106
|
+
should "be invalid due to missing aws account id" do
|
107
|
+
@cloud.aws_account_id nil
|
108
|
+
@cloud.validate
|
109
|
+
assert !@cloud.valid?
|
110
|
+
assert @cloud.validation_errors.any? {|message| !message.index("Missing aws_account_id").nil? }
|
111
|
+
end
|
112
|
+
|
113
|
+
should "be invalid due to missing aws secret access key" do
|
114
|
+
@cloud.aws_secret_access_key nil
|
115
|
+
@cloud.validate
|
116
|
+
assert !@cloud.valid?
|
117
|
+
assert @cloud.validation_errors.any? {|message| !message.index("Missing aws_secret_access_key").nil? }
|
118
|
+
end
|
119
|
+
|
120
|
+
should "be invalid due to missing chef bucket" do
|
121
|
+
@cloud.chef_bucket nil
|
122
|
+
@cloud.validate
|
123
|
+
assert !@cloud.valid?
|
124
|
+
assert @cloud.validation_errors.any? {|message| !message.index("Missing chef_bucket").nil? }
|
125
|
+
end
|
126
|
+
|
127
|
+
should "be valid" do
|
128
|
+
@cloud.validate
|
129
|
+
assert @cloud.valid?
|
130
|
+
assert @cloud.validation_errors.empty?
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
# Unit tests for Maestro::Node::Aws::Ec2
|
4
|
+
class TestAwsEc2Node < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "Maestro::Node::Aws::Ec2" do
|
7
|
+
setup do
|
8
|
+
@cloud = aws_cloud :test do
|
9
|
+
roles do
|
10
|
+
role "web" do
|
11
|
+
public_ports [80, 443]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
nodes do
|
16
|
+
ec2_node "web-1" do
|
17
|
+
roles ["web"]
|
18
|
+
ami "ami-bb709dd2"
|
19
|
+
ssh_user "ubuntu"
|
20
|
+
instance_type "m1.small"
|
21
|
+
availability_zone "us-east-1b"
|
22
|
+
elastic_ip "111.111.11.111"
|
23
|
+
ebs_volume_id "vol-XXXXXXXX"
|
24
|
+
ebs_device "/dev/sdh"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
@node = @cloud.nodes["web-1"]
|
29
|
+
end
|
30
|
+
|
31
|
+
should "be an Ec2 node" do
|
32
|
+
assert @node.is_a? Maestro::Node::Aws::Ec2
|
33
|
+
end
|
34
|
+
|
35
|
+
should "be invalid due to node missing ami" do
|
36
|
+
@node.ami nil
|
37
|
+
@node.validate
|
38
|
+
assert !@node.valid?
|
39
|
+
assert @node.validation_errors.any? {|message| !message.index("missing ami").nil? }
|
40
|
+
end
|
41
|
+
|
42
|
+
should "be invalid due to node missing instance type" do
|
43
|
+
@node.instance_type nil
|
44
|
+
@node.validate
|
45
|
+
assert !@node.valid?
|
46
|
+
assert @node.validation_errors.any? {|message| !message.index("missing instance_type").nil? }
|
47
|
+
end
|
48
|
+
|
49
|
+
should "be invalid due to node missing availability zone" do
|
50
|
+
@node.availability_zone nil
|
51
|
+
@node.validate
|
52
|
+
assert !@node.valid?
|
53
|
+
assert @node.validation_errors.any? {|message| !message.index("missing availability_zone").nil? }
|
54
|
+
end
|
55
|
+
|
56
|
+
should "be invalid due to node missing ebs_device" do
|
57
|
+
@node.ebs_device nil
|
58
|
+
@node.validate
|
59
|
+
assert !@node.valid?
|
60
|
+
assert @node.validation_errors.any? {|message| !message.index("missing ebs_device").nil? }
|
61
|
+
end
|
62
|
+
|
63
|
+
should "be invalid due to node missing ebs_volume_id" do
|
64
|
+
@node.ebs_volume_id nil
|
65
|
+
@node.validate
|
66
|
+
assert !@node.valid?
|
67
|
+
assert @node.validation_errors.any? {|message| !message.index("missing ebs_volume_id").nil? }
|
68
|
+
end
|
69
|
+
|
70
|
+
should "be valid" do
|
71
|
+
@node.validate
|
72
|
+
assert @node.valid?
|
73
|
+
assert @node.validation_errors.empty?
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,221 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
# Unit tests for Maestro::Node::Aws::Elb
|
4
|
+
class TestAwsElbNode < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "Maestro::Node::Aws::Elb" do
|
7
|
+
setup do
|
8
|
+
@cloud = aws_cloud :test do
|
9
|
+
roles {}
|
10
|
+
|
11
|
+
nodes do
|
12
|
+
ec2_node "web-1" do end
|
13
|
+
|
14
|
+
elb_node "lb-1" do
|
15
|
+
availability_zones ["us-east-1b"]
|
16
|
+
listeners [{:load_balancer_port => 80, :instance_port => 80, :protocol => "http"}]
|
17
|
+
ec2_nodes ["web-1"]
|
18
|
+
health_check(:target => "TCP:80", :timeout => 15, :interval => 60, :unhealthy_threshold => 5, :healthy_threshold => 3)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
@node = @cloud.nodes["lb-1"]
|
23
|
+
end
|
24
|
+
|
25
|
+
should "be an Elb node" do
|
26
|
+
assert @node.is_a? Maestro::Node::Aws::Elb
|
27
|
+
end
|
28
|
+
|
29
|
+
should "be invalid due to name too long" do
|
30
|
+
cloud = aws_cloud :test do
|
31
|
+
roles {}
|
32
|
+
nodes do
|
33
|
+
ec2_node "web-1" do end
|
34
|
+
elb_node "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX123" do end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
node = cloud.nodes["XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX123"]
|
38
|
+
node.validate
|
39
|
+
assert !node.valid?
|
40
|
+
assert node.validation_errors.any? {|message| !message.index("name must be less than 32 characters").nil?}
|
41
|
+
end
|
42
|
+
|
43
|
+
should "be invalid due to name containing invalid characters" do
|
44
|
+
"!@\#$%^&*()_=+~`\"{[}]\\|/?.>,<".each_char do |char|
|
45
|
+
cloud = aws_cloud :test do
|
46
|
+
roles {}
|
47
|
+
nodes do
|
48
|
+
ec2_node "web-1" do end
|
49
|
+
elb_node "#{char}" do end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
node = cloud.nodes["#{char}"]
|
53
|
+
node.validate
|
54
|
+
assert !node.valid?
|
55
|
+
assert node.validation_errors.any? {|message| !message.index("name may only contain alphanumerics and hyphens").nil?}
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
should "be invalid due to name not starting with a letter" do
|
60
|
+
"0123456789!@\#$%^&*()_=+~`\"{[}]\\|/?.>,<".each_char do |char|
|
61
|
+
cloud = aws_cloud :test do
|
62
|
+
roles {}
|
63
|
+
nodes do
|
64
|
+
ec2_node "web-1" do end
|
65
|
+
elb_node "#{char}" do end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
node = cloud.nodes["#{char}"]
|
69
|
+
node.validate
|
70
|
+
assert !node.valid?
|
71
|
+
assert node.validation_errors.any? {|message| !message.index("name must start with a letter").nil?}
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
should "be invalid due to name ending with hyphen" do
|
76
|
+
cloud = aws_cloud :test do
|
77
|
+
roles {}
|
78
|
+
nodes do
|
79
|
+
ec2_node "web-1" do end
|
80
|
+
elb_node "test-" do end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
node = cloud.nodes["test-"]
|
84
|
+
node.validate
|
85
|
+
assert !node.valid?
|
86
|
+
assert node.validation_errors.any? {|message| !message.index("name must not end with a hypen").nil?}
|
87
|
+
end
|
88
|
+
|
89
|
+
should "be invalid due to name containing two consecutive hyphens" do
|
90
|
+
cloud = aws_cloud :test do
|
91
|
+
roles {}
|
92
|
+
nodes do
|
93
|
+
ec2_node "web-1" do end
|
94
|
+
elb_node "te--st" do end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
node = cloud.nodes["te--st"]
|
98
|
+
node.validate
|
99
|
+
assert !node.valid?
|
100
|
+
assert node.validation_errors.any? {|message| !message.index("name must not contain two consecutive hyphens").nil?}
|
101
|
+
end
|
102
|
+
|
103
|
+
should "be invalid due to missing listeners" do
|
104
|
+
@node.listeners nil
|
105
|
+
@node.validate
|
106
|
+
assert !@node.valid?
|
107
|
+
assert @node.validation_errors.any? {|message| !message.index("node missing listeners").nil? }
|
108
|
+
end
|
109
|
+
|
110
|
+
should "be invalid due to listeners not an array" do
|
111
|
+
@node.listeners "foo"
|
112
|
+
@node.validate
|
113
|
+
assert !@node.valid?
|
114
|
+
assert @node.validation_errors.any? {|message| !message.index("node's listeners must be an Array of Hashes").nil? }
|
115
|
+
end
|
116
|
+
|
117
|
+
should "be invalid due to listeners element not a Hash" do
|
118
|
+
@node.listeners[0] = "foo"
|
119
|
+
@node.validate
|
120
|
+
assert !@node.valid?
|
121
|
+
assert @node.validation_errors.any? {|message| !message.index("node's listeners must be an Array of Hashes").nil? }
|
122
|
+
end
|
123
|
+
|
124
|
+
should "be invalid due to missing load_balancer_port" do
|
125
|
+
@node.listeners[0].delete(:load_balancer_port)
|
126
|
+
@node.validate
|
127
|
+
assert !@node.valid?
|
128
|
+
assert @node.validation_errors.any? {|message| !message.index("node's listeners Hash missing :load_balancer_port key").nil? }
|
129
|
+
end
|
130
|
+
|
131
|
+
should "be invalid due to missing instance_port" do
|
132
|
+
@node.listeners[0].delete(:instance_port)
|
133
|
+
@node.validate
|
134
|
+
assert !@node.valid?
|
135
|
+
assert @node.validation_errors.any? {|message| !message.index("node's listeners Hash missing :instance_port key").nil? }
|
136
|
+
end
|
137
|
+
|
138
|
+
should "be invalid due to missing protocol" do
|
139
|
+
@node.listeners[0].delete(:protocol)
|
140
|
+
@node.validate
|
141
|
+
assert !@node.valid?
|
142
|
+
assert @node.validation_errors.any? {|message| !message.index("node's listeners Hash missing :protocol key").nil? }
|
143
|
+
end
|
144
|
+
|
145
|
+
should "be invalid due to missing ec2_nodes" do
|
146
|
+
@node.ec2_nodes nil
|
147
|
+
@node.validate
|
148
|
+
assert !@node.valid?
|
149
|
+
assert @node.validation_errors.any? {|message| !message.index("node missing ec2_nodes collection").nil? }
|
150
|
+
end
|
151
|
+
|
152
|
+
should "be invalid due to ec2_nodes not an array" do
|
153
|
+
@node.ec2_nodes 1
|
154
|
+
@node.validate
|
155
|
+
assert !@node.valid?
|
156
|
+
assert @node.validation_errors.any? {|message| !message.index("node ec2_nodes collection is not an Array ").nil? }
|
157
|
+
end
|
158
|
+
|
159
|
+
should "be invalid due to missing availability_zones" do
|
160
|
+
@node.availability_zones nil
|
161
|
+
@node.validate
|
162
|
+
assert !@node.valid?
|
163
|
+
assert @node.validation_errors.any? {|message| !message.index("node missing availability_zones collection").nil? }
|
164
|
+
end
|
165
|
+
|
166
|
+
should "be invalid due to availability_zones not an array" do
|
167
|
+
@node.availability_zones 1
|
168
|
+
@node.validate
|
169
|
+
assert !@node.valid?
|
170
|
+
assert @node.validation_errors.any? {|message| !message.index("node availability_zones collection is not an Array ").nil? }
|
171
|
+
end
|
172
|
+
|
173
|
+
should "be invalid due to health_check element not a Hash" do
|
174
|
+
@node.health_check "foo"
|
175
|
+
@node.validate
|
176
|
+
assert !@node.valid?
|
177
|
+
assert @node.validation_errors.any? {|message| !message.index("node's health_check must be a Hash").nil? }
|
178
|
+
end
|
179
|
+
|
180
|
+
should "be invalid due to missing target" do
|
181
|
+
@node.health_check.delete(:target)
|
182
|
+
@node.validate
|
183
|
+
assert !@node.valid?
|
184
|
+
assert @node.validation_errors.any? {|message| !message.index("node's health_check Hash missing :target key").nil? }
|
185
|
+
end
|
186
|
+
|
187
|
+
should "be invalid due to missing timeout" do
|
188
|
+
@node.health_check.delete(:timeout)
|
189
|
+
@node.validate
|
190
|
+
assert !@node.valid?
|
191
|
+
assert @node.validation_errors.any? {|message| !message.index("node's health_check Hash missing :timeout key").nil? }
|
192
|
+
end
|
193
|
+
|
194
|
+
should "be invalid due to missing interval" do
|
195
|
+
@node.health_check.delete(:interval)
|
196
|
+
@node.validate
|
197
|
+
assert !@node.valid?
|
198
|
+
assert @node.validation_errors.any? {|message| !message.index("node's health_check Hash missing :interval key").nil? }
|
199
|
+
end
|
200
|
+
|
201
|
+
should "be invalid due to missing unhealthy_threshold" do
|
202
|
+
@node.health_check.delete(:unhealthy_threshold)
|
203
|
+
@node.validate
|
204
|
+
assert !@node.valid?
|
205
|
+
assert @node.validation_errors.any? {|message| !message.index("node's health_check Hash missing :unhealthy_threshold key").nil? }
|
206
|
+
end
|
207
|
+
|
208
|
+
should "be invalid due to missing healthy_threshold" do
|
209
|
+
@node.health_check.delete(:healthy_threshold)
|
210
|
+
@node.validate
|
211
|
+
assert !@node.valid?
|
212
|
+
assert @node.validation_errors.any? {|message| !message.index("node's health_check Hash missing :healthy_threshold key").nil? }
|
213
|
+
end
|
214
|
+
|
215
|
+
should "be valid" do
|
216
|
+
@node.validate
|
217
|
+
assert @node.valid?
|
218
|
+
assert @node.validation_errors.empty?
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|