ironfan 4.3.4 → 4.4.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.
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