ironfan 4.3.4 → 4.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/CHANGELOG.md +7 -0
  2. data/ELB.md +121 -0
  3. data/Gemfile +1 -0
  4. data/Rakefile +4 -0
  5. data/VERSION +1 -1
  6. data/ironfan.gemspec +48 -3
  7. data/lib/chef/knife/cluster_launch.rb +5 -0
  8. data/lib/chef/knife/cluster_proxy.rb +3 -3
  9. data/lib/chef/knife/cluster_sync.rb +4 -0
  10. data/lib/chef/knife/ironfan_knife_common.rb +17 -6
  11. data/lib/chef/knife/ironfan_script.rb +29 -11
  12. data/lib/ironfan.rb +2 -2
  13. data/lib/ironfan/broker/computer.rb +8 -3
  14. data/lib/ironfan/dsl/ec2.rb +133 -2
  15. data/lib/ironfan/headers.rb +4 -0
  16. data/lib/ironfan/provider.rb +48 -3
  17. data/lib/ironfan/provider/ec2.rb +23 -8
  18. data/lib/ironfan/provider/ec2/elastic_load_balancer.rb +239 -0
  19. data/lib/ironfan/provider/ec2/iam_server_certificate.rb +101 -0
  20. data/lib/ironfan/provider/ec2/machine.rb +8 -0
  21. data/lib/ironfan/provider/ec2/security_group.rb +3 -5
  22. data/lib/ironfan/requirements.rb +2 -0
  23. data/notes/Home.md +45 -0
  24. data/notes/INSTALL-cloud_setup.md +103 -0
  25. data/notes/INSTALL.md +134 -0
  26. data/notes/Ironfan-Roadmap.md +70 -0
  27. data/notes/advanced-superpowers.md +16 -0
  28. data/notes/aws_servers.jpg +0 -0
  29. data/notes/aws_user_key.png +0 -0
  30. data/notes/cookbook-versioning.md +11 -0
  31. data/notes/core_concepts.md +200 -0
  32. data/notes/declaring_volumes.md +3 -0
  33. data/notes/design_notes-aspect_oriented_devops.md +36 -0
  34. data/notes/design_notes-ci_testing.md +169 -0
  35. data/notes/design_notes-cookbook_event_ordering.md +249 -0
  36. data/notes/design_notes-meta_discovery.md +59 -0
  37. data/notes/ec2-pricing_and_capacity.md +69 -0
  38. data/notes/ec2-pricing_and_capacity.numbers +0 -0
  39. data/notes/homebase-layout.txt +102 -0
  40. data/notes/knife-cluster-commands.md +18 -0
  41. data/notes/named-cloud-objects.md +11 -0
  42. data/notes/opscode_org_key.png +0 -0
  43. data/notes/opscode_user_key.png +0 -0
  44. data/notes/philosophy.md +13 -0
  45. data/notes/rake_tasks.md +24 -0
  46. data/notes/renamed-recipes.txt +142 -0
  47. data/notes/silverware.md +85 -0
  48. data/notes/style_guide.md +300 -0
  49. data/notes/tips_and_troubleshooting.md +92 -0
  50. data/notes/version-3_2.md +273 -0
  51. data/notes/walkthrough-hadoop.md +168 -0
  52. data/notes/walkthrough-web.md +166 -0
  53. data/spec/fixtures/ec2/elb/snakeoil.crt +35 -0
  54. data/spec/fixtures/ec2/elb/snakeoil.key +51 -0
  55. data/spec/integration/minimal-chef-repo/chefignore +41 -0
  56. data/spec/integration/minimal-chef-repo/environments/_default.json +12 -0
  57. data/spec/integration/minimal-chef-repo/knife/credentials/knife-org.rb +19 -0
  58. data/spec/integration/minimal-chef-repo/knife/credentials/knife-user-ironfantester.rb +9 -0
  59. data/spec/integration/minimal-chef-repo/knife/knife.rb +66 -0
  60. data/spec/integration/minimal-chef-repo/roles/systemwide.rb +10 -0
  61. data/spec/integration/spec/elb_build_spec.rb +95 -0
  62. data/spec/integration/spec_helper.rb +16 -0
  63. data/spec/integration/spec_helper/launch_cluster.rb +55 -0
  64. data/spec/ironfan/ec2/elb_spec.rb +95 -0
  65. data/spec/ironfan/ec2/security_group_spec.rb +0 -6
  66. metadata +60 -3
@@ -0,0 +1,35 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIGKDCCBBACAgKaMA0GCSqGSIb3DQEBBQUAMIH4MQswCQYDVQQGEwJVUzETMBEG
3
+ A1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEYMBYGA1UE
4
+ ChMPR2V0U2F0aXNmYWN0aW9uMTYwNAYDVQQLEy1EZXBhcnRtZW50IG9mIE5lcmRz
5
+ LCBGcmlzYmVlcywgYW5kIEtlZ2VyYXRvcnMxKzApBgNVBAMTIkdldFNhdCBOZXJk
6
+ cyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxPTA7BgkqhkiG9w0BCQEWLm5lcmRzK2Nl
7
+ cnRpZmljYXRlYXV0aG9yaXR5QGdldHNhdGlzZmFjdGlvbi5jb20wHhcNMTIxMDEy
8
+ MDMyMDE3WhcNMjIxMDEwMDMyMDE3WjCBuTELMAkGA1UEBhMCVVMxEzARBgNVBAgT
9
+ CkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xGDAWBgNVBAoTD1Nu
10
+ YWtlIE9pbCwgSW5jLjEmMCQGA1UECxMdRGVwYXJ0bWVudCBvZiBTaGlmdHkgUHJv
11
+ ZHVjdHMxFzAVBgNVBAMUDiouc25ha2VvaWwuY29tMSIwIAYJKoZIhvcNAQkBFhNz
12
+ aGlmdHlAc25ha2VvaWwuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC
13
+ AgEApW4tKF5XhrsnbKEAeVqNxedNj3jWFU/ZRwl0MnyUH3y1LgrASXO25x8OrmLV
14
+ FO4un2ufhHlxg+e1DNkurQnvIYIaDA97SPtyMg/SCerBo3F1pB6gKtgfGF8z3UTs
15
+ z28ioXJz+5NkI864sHF7An2H1HJfU9q8xnSf4ClxdpcNVPXtz3Um4ZO33j4D393D
16
+ KeUeZbXXprr4UN0QdCfM8/wB4KxZCRiGGvjDT4qHMr/pLxl0jWxrZwJqi+mwsVTR
17
+ U+AQGT0K3l0pYRUO1IknOxmgbOVHGuv+iFd+mq3LSerq5eYIvi69BraE1dUC95cK
18
+ dpOrCGxkyIRIgpBEzL3UJuMR8bMPKLojbTFQ+b86+El5S+dGugMGFH3S0wGAc8zo
19
+ wrAZM0nmaPg+4lp3m7+tb9SdzvCWX+fPz9qEUOXTUYza2LjKpu4fj7FBY1RCxF+c
20
+ C9Fff1mjXkq0abI1/KSbr9D8hfd2dWKF0LMX6UyySjSCjeLUBLNtB/uWwrFRzWes
21
+ hThVz04U3pqvbMYOtzYlv3BpJLr8CTe19jt6F75TNXr8FxWadoUhtrRNioyjJuFN
22
+ 5pICWf40YswitMbw/QvC7ez6+NqyNMSTzfZGPVVFGwT97nGOrrfQO0Bj93W2STYM
23
+ q7Ta/NYCf0LcS89EW5UU7F89YF+eKyGCwA5aBWPjm8t11qcCAwEAATANBgkqhkiG
24
+ 9w0BAQUFAAOCAgEAXLO2YmQDfNdog2AWB3u8Bbu6oM5dim/My+nacklkAPh/PeWj
25
+ byoWdWAX8nQ+MUxG42E8BfHcHOq6iLHlYKGXV5koichsBQ52G3/9JR93aP0DeN9z
26
+ 5Xlv0bnGtwqrS/pk3uVcwE1Scf7t8Zsk6u1oGsGzBaV+5s9fnXzr0eKhqMThZRoE
27
+ XkBnANb56FwvJTWQu1kbyMgCn0dVjY7LzXjqItLd4m3GGFnJEAzBPq9ayvFeO9QW
28
+ hPL9p8IksFlurZD2GuvEUQJo6yUtYFDwgJOQzx3EzbCfgShInuRmhsx3yprLQNyA
29
+ +rUYiLp7TM7wbedAkBh3Qyombi6XEhs8A4Qqo9/pjqhlkgVU88XWyTCTfhjfoK+A
30
+ zFysPZ+uiZWwXcGFMl1qlWXHmEgckKvD28YQEzibeiHapwYnjzBnmhGPN/ygzLTp
31
+ txTSg0TBx4aRKKsRtEd5l2XtkOTYCN4ieYnLQaheq8LeP6866+HbU04E6WHpAzeY
32
+ KLCLMOVQ1BHX8buOnhEIqXH03oIfNmmG3DFB2RCT2YWP8eJhfvOW8YlVZelD5MKX
33
+ kBhY8KdPfW2AXdvKZ+5MzGIyGEsNKD/z4VLNnylIQD1gUdlILBkiPv3y53f7nRHg
34
+ aKaEX1x2BZWXPeMXPCLDaer+zs2GfAMIS9OVtOZcL4BIFivUNmDzPr6h0Vg=
35
+ -----END CERTIFICATE-----
@@ -0,0 +1,51 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ 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
51
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1,41 @@
1
+ # Put files/directories that should be ignored in this file.
2
+ # Lines that start with '# ' are comments.
3
+
4
+ ## OS
5
+ .DS_Store
6
+ Icon?
7
+ nohup.out
8
+
9
+ ## EDITORS
10
+ \#*
11
+ .#*
12
+ *~
13
+ *.sw[a-z]
14
+ *.bak
15
+ REVISION
16
+ TAGS*
17
+ tmtags
18
+ *_flymake.*
19
+ *_flymake
20
+ *.tmproj
21
+ .project
22
+ .settings
23
+ mkmf.log
24
+
25
+ ## COMPILED
26
+ a.out
27
+ *.o
28
+ *.pyc
29
+ *.so
30
+
31
+ ## OTHER SCM
32
+ */.bzr/*
33
+ */.hg/*
34
+ */.svn/*
35
+
36
+ ## Don't send rspecs up in cookbook
37
+ .watchr
38
+ .rspec
39
+ spec/*
40
+ spec/fixtures/*
41
+ features/*
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "_default",
3
+ "description": "Default environment for Ironfan testing",
4
+ "cookbook_versions": {
5
+ },
6
+ "json_class": "Chef::Environment",
7
+ "chef_type": "environment",
8
+ "default_attributes": {
9
+ },
10
+ "override_attributes": {
11
+ }
12
+ }
@@ -0,0 +1,19 @@
1
+ #
2
+ # Put your own AWS credentials in knife-user-ironfantester.rb, not here.
3
+ #
4
+ Chef::Config.instance_eval do
5
+ organization "ironfantest"
6
+ chef_server_url "https://api.opscode.com/organizations/#{organization}"
7
+ validation_client_name "#{organization}-validator"
8
+ validation_key "#{credentials_path}/#{organization}-validator.pem"
9
+
10
+ Chef::Config[:ec2_image_info] ||= {}
11
+ ec2_image_info.merge!({
12
+ %w[us-east-1 64-bit ebs alestic-precise] => { :image_id => 'ami-b0d309d9', :ssh_user => 'ubuntu', :bootstrap_distro => "ubuntu12.04-gems", },
13
+ })
14
+ Chef::Log.debug("Loaded #{__FILE__}, now have #{ec2_image_info.size} ec2 images")
15
+
16
+ # Don't complain about ssh known_hosts
17
+ knife[:host_key_verify] = false # yeah... so 0.10.7+ uses one, 0.10.4 the other.
18
+ knife[:no_host_key_verify] = true
19
+ end
@@ -0,0 +1,9 @@
1
+ Chef::Config.instance_eval do
2
+ organization "infochimps_test"
3
+ chef_server_url "https://api.opscode.com/organizations/#{organization}"
4
+ knife[:aws_account_id] = "346633265723"
5
+
6
+ knife[:aws_access_key_id] = "AKIAIFPVHWHGTQDXOF6Q"
7
+ knife[:aws_secret_access_key] = "f8e/XwVSIx9ApupaZaoW/xGme64YuQhKWZM/nn5Y"
8
+ end
9
+
@@ -0,0 +1,66 @@
1
+ #
2
+ # organization - selects your cloud environment.
3
+ # username - selects your client key and user-specific overrides
4
+ # homebase - default location for clusters, cookbooks and so forth
5
+ #
6
+ username ENV['CHEF_USER'] || ENV['USER']
7
+ homebase ENV['CHEF_HOMEBASE'] ? File.expand_path(ENV['CHEF_HOMEBASE']) : File.expand_path("..", File.realdirpath(File.dirname(__FILE__)))
8
+
9
+ #
10
+ # Additional settings and overrides
11
+ #
12
+
13
+ #
14
+ # Clusters, cookbooks and roles
15
+ #
16
+ cluster_path [ "#{homebase}/clusters" ]
17
+ cookbook_path [ "#{homebase}/cookbooks" ]
18
+ role_path [ "#{homebase}/roles" ]
19
+
20
+ #
21
+ # Keys and cloud-specific settings.
22
+ # Be sure all your .pem files are non-readable (mode 0600)
23
+ #
24
+ credentials_path File.expand_path("credentials", File.realdirpath(File.dirname(__FILE__)))
25
+ client_key_dir "#{credentials_path}/client_keys"
26
+ ec2_key_dir "#{credentials_path}/ec2_keys"
27
+
28
+ #
29
+ # Load the vendored ironfan lib if present
30
+ #
31
+ if File.exists?("#{homebase}/vendor/ironfan-knife/lib")
32
+ $LOAD_PATH.unshift("#{homebase}/vendor/ironfan-knife/lib")
33
+ end
34
+
35
+ verbosity 1
36
+ log_level :info
37
+ log_location STDOUT
38
+ node_name username
39
+ client_key "#{credentials_path}/#{username}.pem"
40
+ cache_type 'BasicFile'
41
+ cache_options :path => "/tmp/chef-checksums-#{username}"
42
+
43
+ #
44
+ # Configure client bootstrapping
45
+ #
46
+ bootstrap_runs_chef_client true
47
+ bootstrap_chef_version "~> 0.10.4"
48
+
49
+ def load_if_exists(file) ; load(file) if File.exists?(file) ; end
50
+
51
+ # Organization-sepecific settings -- Chef::Config[:ec2_image_info] and so forth
52
+ #
53
+ # This must do at least these things:
54
+ #
55
+ # * define Chef::Config.chef_server
56
+ # * define Chef::Config.organization
57
+ #
58
+ #
59
+ load_if_exists "#{credentials_path}/knife-org.rb"
60
+
61
+ # User-specific knife info or credentials
62
+ load_if_exists "#{credentials_path}/knife-user-#{username}.rb"
63
+
64
+ [:aws_access_key_id, :aws_secret_access_key, :aws_account_id].each do |k|
65
+ raise "Chef::Config.knife[:#{k}] not defined, please define it in #{credentials_path}/knife-user-#{username}.rb" unless Chef::Config.knife.has_key?(k)
66
+ end
@@ -0,0 +1,10 @@
1
+ name 'systemwide'
2
+ description 'top level attributes, applies to all nodes'
3
+
4
+ run_list *%w[
5
+ build-essential
6
+ motd
7
+ zsh
8
+ emacs
9
+ ntp
10
+ ]
@@ -0,0 +1,95 @@
1
+ require_relative '../spec_helper'
2
+
3
+ Ironfan.cluster "elb" do
4
+
5
+ cloud(:ec2) do
6
+ availability_zones ('b'..'d').map { |z| "us-east-1#{z}" }
7
+ flavor 't1.micro'
8
+ backing 'ebs'
9
+ image_name 'alestic-precise'
10
+ chef_client_script 'client.rb'
11
+ iam_server_certificate "snake-oil" do
12
+ certificate IO.read(File.expand_path('../../../fixtures/ec2/elb/snakeoil.crt', __FILE__))
13
+ private_key IO.read(File.expand_path('../../../fixtures/ec2/elb/snakeoil.key', __FILE__))
14
+ end
15
+ security_group :systemwide
16
+ security_group :ssh do
17
+ authorize_port_range(22..22)
18
+ end
19
+ mount_ephemerals
20
+ end
21
+
22
+ facet :web do
23
+ instances 2
24
+ cloud(:ec2) do
25
+
26
+ elastic_load_balancer "simple-elb" do
27
+ map_port('HTTP', 80, 'HTTP', 81)
28
+ map_port('HTTPS', 443, 'HTTP', 81, 'snake-oil')
29
+ disallowed_ciphers %w[ RC4-SHA ]
30
+
31
+ health_check do
32
+ ping_protocol 'HTTP'
33
+ ping_port 82
34
+ ping_path '/healthcheck'
35
+ timeout 4
36
+ interval 10
37
+ unhealthy_threshold 3
38
+ healthy_threshold 2
39
+ end
40
+ end
41
+
42
+ end
43
+ end
44
+ end
45
+
46
+
47
+ launch_cluster 'elb' do |cluster, computers|
48
+ describe "the elb cluster" do
49
+
50
+ it "should have the correct number of running computers"
51
+ # it "should have the correct number of running computers" do
52
+ # computers.size.should == cluster.facets[:web].instances
53
+ # computers.values.reject { |c| c.running? }.should be_empty
54
+ # end
55
+
56
+ describe "the snake-oil certificate" do
57
+ before :each do
58
+ @iss = Ironfan::Provider::Ec2::IamServerCertificate.recall('ironfan-elb-snake-oil')
59
+ end
60
+
61
+ it "should exist"
62
+ # it "should exist" do
63
+ # @iss.should_not be_nil
64
+ # end
65
+
66
+ it "should be retrievable by ARN"
67
+ # it "should be retrievable by ARN" do
68
+ # @iss.should == Ironfan::Provider::Ec2::IamServerCertificate.recall("#{Ironfan::Provider::Ec2::IamServerCertificate::ARN_PREFIX}:#{@iss['Arn']}")
69
+ # end
70
+
71
+ end
72
+
73
+ describe "the ELB" do
74
+ before :each do
75
+ @elb = Ironfan::Provider::Ec2::ElasticLoadBalancer.recall('ironfan-elb-simple-elb')
76
+ end
77
+
78
+ it "should exist"
79
+ # it "should exist" do
80
+ # @elb.should_not be_nil
81
+ # end
82
+
83
+ it "should have two instances"
84
+ # @elb.instances.size.should == cluster.facets[:web].instances
85
+ # end
86
+
87
+ it "should use the snake-oil certificate"
88
+ # it "should use the snake-oil certificate" do
89
+ # iss = Ironfan::Provider::Ec2::IamServerCertificate.recall('ironfan-elb-snake-oil')
90
+ # @elb.listeners.map(&:ssl_id).include?(iss['Arn']).should be_true
91
+ # end
92
+ end
93
+
94
+ end
95
+ end
@@ -0,0 +1,16 @@
1
+ this_dir = File.realpath(File.dirname(__FILE__))
2
+
3
+ $:.unshift File.expand_path('../../lib', this_dir)
4
+ require 'chef'
5
+ require 'chef/knife'
6
+ require 'fog'
7
+
8
+ ENV['KNIFE_HOME'] = File.expand_path('minimal-chef-repo/knife', this_dir)
9
+ ENV['CHEF_USER'] = 'ironfantester'
10
+ Chef::Knife.new.configure_chef
11
+
12
+ require 'ironfan'
13
+ Ironfan.ui = Chef::Knife::UI.new(STDOUT, STDERR, STDIN, {})
14
+ Ironfan.chef_config = { :verbosity => 0 }
15
+
16
+ Dir.glob(File.expand_path('spec_helper/*.rb', this_dir)).each { |file| load(file) }
@@ -0,0 +1,55 @@
1
+ require 'chef/knife/cluster_launch'
2
+ require 'chef/knife/cluster_kill'
3
+
4
+ def launch_cluster(name, options = {}, &block)
5
+ raise "No block given!" unless block_given?
6
+
7
+ cluster = Ironfan.cluster(name)
8
+
9
+ # Make sure that the cluster is clobbered before trying to launch it
10
+ begin
11
+ Chef::Knife::ClusterKill.new(['--yes', name]).run
12
+ rescue Exception => e
13
+ Chef::Log.fatal("Unable to terminate existing instance of cluster #{name}: #{e.inspect}")
14
+ end
15
+
16
+ # Launch the cluster and then yield to the testing block
17
+ begin
18
+
19
+ # In the case of a normal shutdown, destroy the cluster to save moolah
20
+ RSpec.configure do |config|
21
+ config.after(:all) do
22
+ Chef::Log.info("Shutting down #{name} cluster")
23
+ begin
24
+ Chef::Knife::ClusterKill.new(['--yes', name]).run
25
+ rescue Exception => failed_termination
26
+ Chef::Log.fatal("Unable to kill cluster #{name} after test run: #{failed_termination.inspect}")
27
+ end
28
+ end
29
+ end
30
+
31
+ Chef::Log.info("Launching #{name} cluster")
32
+ launcher = Chef::Knife::ClusterLaunch.new([name])
33
+ launcher.run
34
+
35
+ Chef::Log.info("Running tests against #{name} cluster")
36
+ yield cluster, Ironfan.broker.discover!(cluster)
37
+
38
+ rescue Exception => launchfail
39
+
40
+ Chef::Log.warn("Exception occurred while launching cluster #{name}: #{launchfail.inspect}")
41
+
42
+ # Failed tests should not result in wasted Chef/IAAS resources
43
+ if ENV['IRONFAN_PRESERVE_TESTING_CORPSES']
44
+ Chef::Log.warn("Failed to launch #{name} cluster, but NOT terminating cluster so that you have a chance to inspect it")
45
+ Chef::Log.warn(launchfail.inspect)
46
+ else
47
+ begin
48
+ Chef::Knife::ClusterKill.new([name, '--yes'])
49
+ rescue Exception => death
50
+ Chef::Log.fatal("Unable to kill cluster #{name} after failed test run: #{death.inspect}")
51
+ end
52
+ end
53
+ end
54
+
55
+ end
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+
3
+ require 'ironfan'
4
+
5
+ cert = IO.read(File.realpath(File.join(File.dirname(__FILE__), '../../fixtures/ec2/elb/snakeoil.crt')))
6
+ key = IO.read(File.realpath(File.join(File.dirname(__FILE__), '../../fixtures/ec2/elb/snakeoil.key')))
7
+
8
+ describe Ironfan::Dsl::Cluster do
9
+ let (:cluster) do
10
+
11
+ Ironfan.cluster "sparky" do
12
+
13
+ cloud(:ec2) do
14
+ iam_server_certificate "snake-oil" do
15
+ certificate cert
16
+ private_key key
17
+ end
18
+ end
19
+
20
+ facet :web do
21
+ instances 2
22
+ cloud(:ec2) do
23
+
24
+ elastic_load_balancer "sparky-elb" do
25
+ map_port('HTTP', 80, 'HTTP', 81)
26
+ map_port('HTTPS', 443, 'HTTP', 81, 'snake-oil')
27
+ disallowed_ciphers %w[ RC4-SHA ]
28
+
29
+ health_check do
30
+ ping_protocol 'HTTP'
31
+ ping_port 82
32
+ ping_path '/healthcheck'
33
+ timeout 4
34
+ interval 10
35
+ unhealthy_threshold 3
36
+ healthy_threshold 2
37
+ end
38
+ end
39
+
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ describe 'cluster definition' do
46
+ subject { cluster }
47
+
48
+ its(:name) { should eql "sparky" }
49
+ its(:environment) { should eql :_default }
50
+ its(:run_list) { should eql [] }
51
+
52
+ it "should have one IAM server certificate" do
53
+ cluster.clouds.values.first.iam_server_certificates.values.length.should == 1
54
+ end
55
+
56
+ describe 'facets' do
57
+ before { @facets = cluster.facets }
58
+ subject { @facets.values }
59
+ its(:length) { should eql 1 }
60
+
61
+ describe 'web facet' do
62
+ before { @facet = @facets.values.first }
63
+ subject { @facet }
64
+ its(:name) { should eql "web" }
65
+ describe "elastic load balancers" do
66
+
67
+ before { @elb = @facet.clouds.values.first.elastic_load_balancers.values.first }
68
+ subject { @elb }
69
+ its(:name) { should eql "sparky-elb" }
70
+
71
+ it "should have two port mappings" do
72
+ @elb.port_mappings.length.should == 2
73
+ end
74
+
75
+ it "should have just one disallowed SSL cipher" do
76
+ @elb.disallowed_ciphers.length.should == 1
77
+ end
78
+
79
+ describe "health check" do
80
+ before { @hc = @elb.health_check }
81
+ subject { @hc }
82
+ its(:ping_protocol) { should eql 'HTTP' }
83
+ its(:ping_port) { should eql 82 }
84
+ its(:ping_path) { should eql '/healthcheck' }
85
+ its(:timeout) { should eql 4 }
86
+ its(:interval) { should eql 10 }
87
+ its(:unhealthy_threshold) { should eql 3 }
88
+ its(:healthy_threshold) { should eql 2 }
89
+ end
90
+
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end