fhcap-cli 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.rakeTasks +7 -0
  4. data/.rspec +1 -0
  5. data/CHANGELOG.md +15 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +150 -0
  9. data/Rakefile +2 -0
  10. data/bin/fhcap +6 -0
  11. data/fhcap-cli.gemspec +44 -0
  12. data/lib/cookbooks/provision/libraries/provision.rb +140 -0
  13. data/lib/cookbooks/provision/metadata.rb +7 -0
  14. data/lib/cookbooks/provision/recipes/aws.rb +15 -0
  15. data/lib/cookbooks/provision/recipes/aws_cluster_create.rb +59 -0
  16. data/lib/cookbooks/provision/recipes/aws_cluster_create_elb.rb +61 -0
  17. data/lib/cookbooks/provision/recipes/aws_cluster_destroy.rb +52 -0
  18. data/lib/cookbooks/provision/recipes/cluster_create.rb +2 -0
  19. data/lib/cookbooks/provision/recipes/cluster_destroy.rb +2 -0
  20. data/lib/cookbooks/provision/recipes/cluster_destroy_instances.rb +11 -0
  21. data/lib/cookbooks/provision/recipes/cluster_provision.rb +4 -0
  22. data/lib/cookbooks/provision/recipes/cluster_provision_instances.rb +55 -0
  23. data/lib/cookbooks/provision/recipes/cluster_status.rb +24 -0
  24. data/lib/cookbooks/provision/recipes/common.rb +9 -0
  25. data/lib/cookbooks/provision/recipes/default.rb +5 -0
  26. data/lib/cookbooks/provision/recipes/openstack.rb +11 -0
  27. data/lib/cookbooks/provision/recipes/openstack_cluster_create.rb +11 -0
  28. data/lib/cookbooks/provision/recipes/openstack_cluster_destroy.rb +4 -0
  29. data/lib/cookbooks/provision/recipes/reset_rabbitmq.rb +49 -0
  30. data/lib/cookbooks/provision/recipes/restart_services.rb +24 -0
  31. data/lib/extensions/chef/provisioning.rb +21 -0
  32. data/lib/extensions/chef/provisioning/aws_driver/driver.rb +46 -0
  33. data/lib/extensions/chef/provisioning/chef_run_data.rb +18 -0
  34. data/lib/extensions/cheffish/merged_config.rb +9 -0
  35. data/lib/fhcap.rb +14 -0
  36. data/lib/fhcap/chef-dk/chef_runner.rb +94 -0
  37. data/lib/fhcap/cli.rb +75 -0
  38. data/lib/fhcap/cluster.rb +112 -0
  39. data/lib/fhcap/config.rb +104 -0
  40. data/lib/fhcap/cookbook.rb +75 -0
  41. data/lib/fhcap/dummy_node.rb +80 -0
  42. data/lib/fhcap/fhcap_helper.rb +9 -0
  43. data/lib/fhcap/kitchen.rb +235 -0
  44. data/lib/fhcap/knife.rb +74 -0
  45. data/lib/fhcap/knife_helper.rb +38 -0
  46. data/lib/fhcap/misc.rb +103 -0
  47. data/lib/fhcap/provider.rb +41 -0
  48. data/lib/fhcap/providers_helper.rb +60 -0
  49. data/lib/fhcap/repo.rb +52 -0
  50. data/lib/fhcap/repos_helper.rb +217 -0
  51. data/lib/fhcap/tasks/chef/chef_task_base.rb +82 -0
  52. data/lib/fhcap/tasks/chef/cookbook/list.rb +37 -0
  53. data/lib/fhcap/tasks/chef/cookbook/update_changelog.rb +63 -0
  54. data/lib/fhcap/tasks/chef/cookbook/update_metadata.rb +57 -0
  55. data/lib/fhcap/tasks/chef/cookbook/update_readme.rb +30 -0
  56. data/lib/fhcap/tasks/chef/cookbook/update_version.rb +90 -0
  57. data/lib/fhcap/tasks/chef/environments/create.rb +115 -0
  58. data/lib/fhcap/tasks/chef/environments/destroy.rb +37 -0
  59. data/lib/fhcap/tasks/chef/environments/promote_cookbooks.rb +47 -0
  60. data/lib/fhcap/tasks/chef/provisioning/chef_provisioning_task.rb +27 -0
  61. data/lib/fhcap/tasks/chef/provisioning/chef_provisioning_task_base.rb +38 -0
  62. data/lib/fhcap/tasks/chef/provisioning/create.rb +22 -0
  63. data/lib/fhcap/tasks/chef/provisioning/destroy.rb +21 -0
  64. data/lib/fhcap/tasks/chef/provisioning/provision.rb +19 -0
  65. data/lib/fhcap/tasks/chef/server/bootstrap.rb +165 -0
  66. data/lib/fhcap/tasks/chef/server/create_user.rb +97 -0
  67. data/lib/fhcap/tasks/chef/server/info.rb +82 -0
  68. data/lib/fhcap/tasks/chef/server/provision.rb +45 -0
  69. data/lib/fhcap/tasks/clean.rb +34 -0
  70. data/lib/fhcap/tasks/cluster/cluster_task_base.rb +57 -0
  71. data/lib/fhcap/tasks/cluster/create.rb +243 -0
  72. data/lib/fhcap/tasks/cluster/create_environment.rb +171 -0
  73. data/lib/fhcap/tasks/cluster/destroy.rb +30 -0
  74. data/lib/fhcap/tasks/cluster/destroy_environment.rb +28 -0
  75. data/lib/fhcap/tasks/cluster/info.rb +67 -0
  76. data/lib/fhcap/tasks/cluster/list.rb +40 -0
  77. data/lib/fhcap/tasks/cluster/provision.rb +46 -0
  78. data/lib/fhcap/tasks/cluster/status.rb +17 -0
  79. data/lib/fhcap/tasks/cluster/test.rb +15 -0
  80. data/lib/fhcap/tasks/knife/add.rb +111 -0
  81. data/lib/fhcap/tasks/knife/list.rb +22 -0
  82. data/lib/fhcap/tasks/knife/remove.rb +39 -0
  83. data/lib/fhcap/tasks/misc/create_dns_record.rb +100 -0
  84. data/lib/fhcap/tasks/misc/create_ssl_cert.rb +82 -0
  85. data/lib/fhcap/tasks/provider/add.rb +136 -0
  86. data/lib/fhcap/tasks/provider/list.rb +31 -0
  87. data/lib/fhcap/tasks/provider/remove.rb +28 -0
  88. data/lib/fhcap/tasks/repo/add.rb +57 -0
  89. data/lib/fhcap/tasks/repo/checkout.rb +144 -0
  90. data/lib/fhcap/tasks/repo/list.rb +22 -0
  91. data/lib/fhcap/tasks/repo/remove.rb +34 -0
  92. data/lib/fhcap/tasks/setup.rb +59 -0
  93. data/lib/fhcap/tasks/task_base.rb +89 -0
  94. data/lib/fhcap/thor_base.rb +121 -0
  95. data/lib/fhcap/version.rb +3 -0
  96. data/spec/fhcap/cli_spec.rb +6 -0
  97. data/spec/fhcap/tasks/cluster/create_spec.rb +46 -0
  98. data/spec/fhcap/tasks/knife/add_spec.rb +35 -0
  99. data/spec/fhcap/tasks/knife/remove_spec.rb +25 -0
  100. data/spec/fhcap/tasks/provider/add_spec.rb +61 -0
  101. data/spec/fhcap/tasks/provider/remove_spec.rb +25 -0
  102. data/spec/fhcap/tasks/repo/add_spec.rb +32 -0
  103. data/spec/fhcap/tasks/repo/remove_spec.rb +25 -0
  104. data/spec/fhcap/tasks/task_base_spec.rb +51 -0
  105. data/spec/fhcap/thor_base_spec.rb +9 -0
  106. data/spec/spec_helper.rb +23 -0
  107. data/spec/support/dummy_config.rb +7 -0
  108. data/spec/support/dummy_thor.rb +3 -0
  109. data/templates/chef/cookbook/changelog.md.erb +12 -0
  110. data/templates/chef/cookbook/metadata.erb +45 -0
  111. data/templates/chef/environment_core.json.erb +278 -0
  112. data/templates/chef/environment_empty.json.erb +10 -0
  113. data/templates/chef/environment_mbaas.json.erb +120 -0
  114. data/templates/chef/environment_single.json.erb +300 -0
  115. data/templates/cluster/aws/common.json.erb +43 -0
  116. data/templates/cluster/aws/core-3node.json.erb +106 -0
  117. data/templates/cluster/aws/core-small-9node.json.erb +333 -0
  118. data/templates/cluster/aws/mbaas-3node.json.erb +116 -0
  119. data/templates/cluster/aws/nginx-test.json.erb +93 -0
  120. data/templates/cluster/aws/single-blank.json.erb +41 -0
  121. data/templates/cluster/aws/single.json.erb +88 -0
  122. data/templates/cluster/core-3node.json.erb +8 -0
  123. data/templates/cluster/core-mbaas-6node.json.erb +13 -0
  124. data/templates/cluster/core-small-9node.json.erb +8 -0
  125. data/templates/cluster/mbaas-3node.json.erb +9 -0
  126. data/templates/cluster/nginx-test.json.erb +8 -0
  127. data/templates/cluster/openstack/common.json.erb +7 -0
  128. data/templates/cluster/openstack/core-3node.json.erb +14 -0
  129. data/templates/cluster/openstack/core-small-9node.json.erb +32 -0
  130. data/templates/cluster/openstack/mbaas-3node.json.erb +14 -0
  131. data/templates/cluster/openstack/nginx-test.json.erb +11 -0
  132. data/templates/cluster/openstack/single-blank.json.erb +10 -0
  133. data/templates/cluster/openstack/single.json.erb +10 -0
  134. data/templates/cluster/single-blank.json.erb +8 -0
  135. data/templates/cluster/single.json.erb +8 -0
  136. data/templates/init/knife.rb.erb +13 -0
  137. data/templates/kitchen/Cheffile.erb +11 -0
  138. data/templates/kitchen/kitchen.aws.yml.erb +35 -0
  139. data/templates/kitchen/kitchen.docker.yml.erb +24 -0
  140. data/templates/kitchen/kitchen.generate.yml.erb +2 -0
  141. data/templates/kitchen/kitchen.openstack.yml.erb +31 -0
  142. metadata +506 -0
@@ -0,0 +1,27 @@
1
+ require 'fhcap/tasks/chef/provisioning/chef_provisioning_task_base'
2
+
3
+ module Fhcap
4
+ module Tasks
5
+ module Chef
6
+ module Provisioning
7
+ class ChefProvisioningTask < ChefProvisioningTaskBase
8
+
9
+ attr_reader :run_list
10
+
11
+ def initialize(options)
12
+ super
13
+ @run_list = options[:'run-list']
14
+ end
15
+
16
+ def run
17
+ thor.say "Chef::Provisioning::Task name = #{@name}, run_list = #{@run_list}", :yellow
18
+ do_chef_run(run_list)
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+
@@ -0,0 +1,38 @@
1
+ require 'fhcap/tasks/chef/chef_task_base'
2
+ require 'fhcap/chef-dk/chef_runner'
3
+
4
+ module Fhcap
5
+ module Tasks
6
+ module Chef
7
+ module Provisioning
8
+ class ChefProvisioningTaskBase < ChefTaskBase
9
+
10
+ attr_reader :name, :cluster_config, :cluster_filepath, :chef_server
11
+
12
+ def initialize(options)
13
+ super
14
+ @name = options[:name]
15
+ @cluster_filepath = find_cluster(name)
16
+ if @cluster_filepath
17
+ @cluster_config = JSON.parse(IO.read(@cluster_filepath), {:symbolize_names => true})
18
+ @cluster_config.merge!({
19
+ local_repo_path: repo_dir(@cluster_config[:repo]),
20
+ chef_server_config: chef_server_config_hash_for(@cluster_config[:chef_server]),
21
+ provider_credentials: provider_credentials(@cluster_config[:provider_id])
22
+ })
23
+ @chef_server = @cluster_config[:chef_server]
24
+ else
25
+ exit_with_error("Unknown cluster #{@name}")
26
+ end
27
+ end
28
+
29
+ def do_chef_run(run_list)
30
+ cookbook_path = File.join(Fhcap.source_root, 'lib', 'cookbooks')
31
+ Fhcap::ChefRunner.new(cookbook_path, run_list, @cluster_config).converge
32
+ end
33
+
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,22 @@
1
+ require 'fhcap/tasks/chef/provisioning/chef_provisioning_task_base'
2
+
3
+ module Fhcap
4
+ module Tasks
5
+ module Chef
6
+ module Provisioning
7
+ class Create < ChefProvisioningTaskBase
8
+
9
+ def run
10
+ thor.say "Chef::Provisioning::Create #{@name}", :yellow
11
+ do_chef_run("provision::cluster_create")
12
+ do_chef_run("provision::reset_rabbitmq")
13
+ do_chef_run("provision::restart_services")
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+
@@ -0,0 +1,21 @@
1
+ require 'fhcap/tasks/chef/provisioning/chef_provisioning_task_base'
2
+
3
+ module Fhcap
4
+ module Tasks
5
+ module Chef
6
+ module Provisioning
7
+ class Destroy < ChefProvisioningTaskBase
8
+
9
+ def run
10
+ thor.say "Chef::Provisioning::Destroy #{@name}", :yellow
11
+ if thor.yes? "Destroy cluster #{@name}? (y/n)"
12
+ run_list = "provision::cluster_destroy"
13
+ do_chef_run(run_list)
14
+ end
15
+ end
16
+
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ require 'fhcap/tasks/chef/provisioning/chef_provisioning_task_base'
2
+
3
+ module Fhcap
4
+ module Tasks
5
+ module Chef
6
+ module Provisioning
7
+ class Provision < ChefProvisioningTaskBase
8
+
9
+ def run
10
+ thor.say "Chef::Provisioning::Provision #{@name}", :yellow
11
+ run_list = "provision::cluster_provision"
12
+ do_chef_run(run_list)
13
+ end
14
+
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,165 @@
1
+ require 'fhcap/tasks/chef/chef_task_base'
2
+ require 'chef/knife/diff'
3
+
4
+ module Fhcap
5
+ module Tasks
6
+ module Chef
7
+ module Server
8
+ class Bootstrap < ChefTaskBase
9
+
10
+ attr_reader :environments
11
+
12
+ def initialize(options)
13
+ super
14
+ @environments = options[:environments]
15
+ @chef_server = options[:chef_server]
16
+ @diff_strategy = options[:'diff-strategy'] || 'knife'
17
+ @skip_roles = options[:'skip-roles']
18
+ @skip_data_bags = options[:'skip-data-bags']
19
+ @skip_environments = options[:'skip-environments']
20
+ @skip_cookbooks = options[:'skip-cookbooks']
21
+ end
22
+
23
+ def run
24
+ thor.say "Chef::Server::Bootstrap: environments = #{environments}", :yellow
25
+
26
+ chef_server_environments = {}
27
+ environments.each do |environment|
28
+ chef_server = select_chef_server(environment, @chef_server)
29
+ chef_server_environments[chef_server] = chef_server_environments[chef_server] || []
30
+ chef_server_environments[chef_server] << environment
31
+ end
32
+
33
+ chef_server_environments.each do |server, environments|
34
+ sync_roles({:environments => environments, :server => server}) unless @skip_roles
35
+ sync_data_bags({:environments => environments, :server => server}) unless @skip_data_bags
36
+ sync_environments({:environments => environments, :server => server}) unless @skip_environments
37
+ sync_cookbooks({:environments => environments, :server => server}) unless @skip_cookbooks
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ def sync_roles(options)
44
+ sync_items('roles', options) do |local_repo, sync_items|
45
+ sync_items.each do |item|
46
+ unless item =~ /roles\/dev*/
47
+ run_knife_cmd("role from file #{File.join(local_repo, item)}", options[:server])
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ def sync_data_bags(options, bag_created_cache=[])
54
+ requires_resync = false
55
+ sync_items('data_bags', options) do |local_repo, sync_items|
56
+ sync_items.each do |item|
57
+ if include_data_bag_item?(item, options)
58
+ tmp, bag, bag_item = item.split('/')
59
+ if bag
60
+ unless bag_created_cache.include? bag
61
+ output = run_knife_cmd("data bag create #{bag}", options[:server])
62
+ requires_resync = requires_resync || output =~ /Created/
63
+ bag_created_cache << bag
64
+ end
65
+ if bag_item
66
+ run_knife_cmd("data bag from file #{bag} #{File.join(local_repo, item)}", options[:server])
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ sync_data_bags(options, bag_created_cache) if requires_resync
73
+ end
74
+
75
+ def include_data_bag_item?(item, options)
76
+ include = true
77
+ environments = options[:environments]
78
+ if environments
79
+ if item =~ /nagios_/
80
+ #As usual nagios requires the most work Argghh
81
+ nagios_data_bag_name = item.split('/')[1]
82
+ #Default nagios data bags will only be 2 in length, check everything else
83
+ if nagios_data_bag_name.split('_').length > 2
84
+ allowed = ['fheng', 'production']
85
+ allowed |= environments
86
+ allowed |= environments.collect { |env| env.gsub('-', '_') } # Prod data bags are named incorrectly for some reason
87
+ include = allowed.any? { |val| nagios_data_bag_name =~ /#{val}/ }
88
+ end
89
+ elsif item =~ /environments\//
90
+ include = environments.any? { |val| item =~ /#{val}/ }
91
+ end
92
+ end
93
+ include
94
+ end
95
+
96
+ def sync_environments(options)
97
+ environments = options[:environments]
98
+ if environments
99
+ sync_items('environments', options) do |local_repo, sync_items|
100
+ sync_items.each do |item|
101
+ if environments.any? { |val| item =~ /#{val}/ }
102
+ run_knife_cmd("environment from file #{File.join(local_repo, item)}", options[:server])
103
+ end
104
+ end
105
+ end
106
+ else
107
+ #thor.say "No environments specified!!"
108
+ end
109
+ end
110
+
111
+ def sync_cookbooks(options)
112
+ #sync_items('cookbooks', options) do |local_repo, sync_items|
113
+ # modified_cookbooks = sync_items.collect do |cookbook|
114
+ # cookbook.split('/')[1]
115
+ # end.uniq
116
+ # run_knife_cmd("cookbook upload #{modified_cookbooks.join(' ')} --force", options[:server]) unless modified_cookbooks.empty?
117
+ #end
118
+ run_knife_cmd("cookbook upload -a --force", options[:server], !verbose)
119
+ end
120
+
121
+ def sync_items(item, options)
122
+ repo_paths.each do |local_repo|
123
+ #thor.say "Syncing #{item} in #{local_repo} based on #{@diff_strategy} diff", :yellow
124
+ if @diff_strategy == 'git'
125
+ item = %w{cookbooks site-cookbooks wrapper-cookbooks} if item == 'cookbooks'
126
+ yield local_repo, git_diff(item, local_repo)
127
+ else
128
+ yield local_repo, knife_diff(item, local_repo, options[:server])
129
+ end
130
+ end
131
+ #thor.say "All #{item} synced successfully!"
132
+ end
133
+
134
+ def git_diff(item, local_repo)
135
+ result = ''
136
+ Dir.chdir local_repo do
137
+ paths = item.is_a?(Array) ? item : [item]
138
+ paths.each do |path|
139
+ if Dir.exists? File.join(local_repo, path)
140
+ result += `git diff --name-only origin/master -- #{path}`
141
+ end
142
+ end
143
+ end
144
+ result.split
145
+ end
146
+
147
+ def knife_diff(item, local_repo, server)
148
+ result = ''
149
+ if Dir.exists? File.join(local_repo, item)
150
+ thor.inside local_repo do
151
+ cmd = "knife diff #{item} --chef-repo-path #{local_repo} --repo-mode static --name-only --diff-filter=[AM] --config #{knife_config_file_for(server)}"
152
+ result = thor.run(cmd, :capture => true)
153
+ thor.say result if verbose
154
+ end
155
+ else
156
+ #thor.say "No #{item} in #{local_repo}"
157
+ end
158
+ result.split
159
+ end
160
+
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,97 @@
1
+ require 'fhcap/tasks/chef/chef_task_base'
2
+ require 'chef/config'
3
+ require 'securerandom'
4
+
5
+ module Fhcap
6
+ module Tasks
7
+ module Chef
8
+ module Server
9
+ class CreateUser < ChefTaskBase
10
+
11
+ attr_reader :user_config, :chef_server_version
12
+
13
+ def initialize(options)
14
+ super
15
+ @chef_server_version = options[:'chef-server-version'] || 'osc'
16
+ @user_config = {
17
+ chef_server: options[:'chef-server'],
18
+ username: options[:username],
19
+ display_name: options[:'display-name'] || @username,
20
+ first_name: options[:'first-name'] || @username,
21
+ last_name: options[:'last-name'] || @username,
22
+ email: options[:email],
23
+ password: options[:password] || SecureRandom.urlsafe_base64(6),
24
+ validation_client_name: @validation_client_name,
25
+ }
26
+ end
27
+
28
+ def run
29
+ thor.say "Knife::CreateUser", :yellow
30
+
31
+ ask_config(required_config, user_config)
32
+
33
+ if @chef_server_version == 'osc'
34
+ cmd = "osc_user create #{user_config[:username]} -p #{user_config[:password]} -y -d -a"
35
+ else
36
+ cmd = "user create #{user_config[:username]} #{user_config[:display_name]} #{user_config[:first_name]} #{user_config[:last_name]} #{user_config[:email]} #{user_config[:password]} -y"
37
+ end
38
+
39
+ import_cfg = {}
40
+
41
+ private_key = run_knife_cmd(cmd, user_config[:chef_server])
42
+
43
+ if $?.exitstatus == 0
44
+ knife_config_dir = config[:knife_dir] || File.join(config.default_dir, '.chef')
45
+ knife_config_file = File.join(knife_config_dir, "knife-#{user_config[:chef_server]}.rb")
46
+ ::Chef::Config.from_file(knife_config_file)
47
+ file = File.open(::Chef::Config[:validation_key], "rb")
48
+ validation_key = file.read
49
+
50
+ import_cfg[:chef_server_url] = ::Chef::Config[:chef_server_url]
51
+ import_cfg[:validation_client_name] = ::Chef::Config[:validation_client_name]
52
+ import_cfg[:node_name] = user_config[:username]
53
+ import_cfg[:private_key] = private_key
54
+ import_cfg[:validation_key] = validation_key
55
+
56
+ import_file = File.join(config.tmp_dir,"#{user_config[:username]}-#{user_config[:chef_server]}_import.json")
57
+ thor.create_file(import_file, JSON.pretty_generate(import_cfg), :force => true)
58
+
59
+ table_contents = [table_header('Username', 'Password', 'Chef Server URL')]
60
+ table_contents << table_row(user_config[:username], user_config[:password], ::Chef::Config[:chef_server_url])
61
+ thor.print_table table_contents
62
+
63
+ table_contents = [table_header('Private Key')]
64
+ table_contents << table_row(private_key)
65
+ thor.print_table table_contents
66
+
67
+ table_contents = [table_header('Validation Key')]
68
+ table_contents << table_row(validation_key)
69
+ thor.print_table table_contents
70
+
71
+ thor.say_status 'warning', "The validation key shown above is the validation key used by you for '#{user_config[:chef_server]}'. If you don't normally share this key between users, you should create a new one manually for '#{user_config[:username]}'", :yellow
72
+
73
+ thor.say_status 'Import Command:', "fhcap knife add --name #{user_config[:chef_server]} --import-file #{import_file}", :cyan
74
+ end
75
+ end
76
+
77
+ private
78
+
79
+ def required_config
80
+ {
81
+ username: {
82
+ },
83
+ chef_server: {
84
+ options: {:limited_to => chef_server_names}
85
+ },
86
+ email: {
87
+ },
88
+ password: {
89
+ }
90
+ }
91
+ end
92
+
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,82 @@
1
+ require 'fhcap/tasks/chef/chef_task_base'
2
+
3
+ module Fhcap
4
+ module Tasks
5
+ module Chef
6
+ module Server
7
+ class Info < ChefTaskBase
8
+
9
+ attr_reader :environments, :node_names, :roles, :chef_server, :urls
10
+
11
+ def initialize(options)
12
+ super
13
+ @environments = options[:environments]
14
+ @node_names = options[:nodes]
15
+ @roles = options[:roles]
16
+ @chef_server = options[:chef_server]
17
+ @urls = {}
18
+ end
19
+
20
+ def run
21
+ thor.say "Chef::Server::Info: environments = #{environments}", :yellow
22
+ environments.each do |env|
23
+ ip_addresses(env) unless options[:only] && options[:only] != 'ips'
24
+ management_dashboards(env) unless options[:only] && options[:only] != 'urls'
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def ip_addresses(env)
31
+ thor.say "[#{env}] IP Addresses", :green
32
+ search_cmd = "search 'chef_environment:#{env}'"
33
+ search_options = '-a cloud.public_ips'
34
+ nodes_for(search_cmd, search_options) do |node|
35
+ thor.say_status "[#{env}] #{node['name']}:", node['cloud.public_ips'].join(','), :cyan
36
+ end
37
+ end
38
+
39
+ def management_dashboards(env)
40
+ thor.say "[#{env}] Monitoring Dashboards", :green
41
+ urls[env] = {} unless urls[env]
42
+ search_cmd = "search 'chef_environment:#{env} AND roles:management_server'"
43
+ search_options = '-a cloud.public_ips -a munin.web_server_port -a nagios.http_port'
44
+ nodes_for(search_cmd, search_options) do |node|
45
+ urls[env][:nagios] = "http://#{node['cloud.public_ips'].first}:#{node['nagios.http_port']}"
46
+ urls[env][:munin] = "http://#{node['cloud.public_ips'].first}:#{node['munin.web_server_port']}/munin"
47
+ thor.say_status "[#{env}] Nagios Dashboard:", "#{urls[env][:nagios]}", :cyan
48
+ thor.say_status "[#{env}] Munin Dashboard:", "#{urls[env][:munin]}", :cyan
49
+ end
50
+
51
+ search_cmd = "search 'chef_environment:#{env} AND roles:rabbitmq_server'"
52
+ search_options = '-a cloud.public_ips -a rabbitmq.web_console_ssl_port'
53
+ node = nodes_for(search_cmd, search_options).first
54
+ if node
55
+ urls[env][:rabbitmq] = "http://#{node['cloud.public_ips'].first}:#{node['rabbitmq.web_console_ssl_port']}"
56
+ thor.say_status "[#{env}] RabbitMQ Dashboard:", "#{urls[env][:rabbitmq]}", :cyan
57
+ end
58
+
59
+ end
60
+
61
+ def nodes_for(search_cmd, search_options)
62
+ cmd = "cd #{File.expand_path("..", knife_config_dir)} && knife #{search_cmd} #{search_options} -c #{knife_config_file_for(chef_server)} -F json"
63
+ raw_nodes = JSON.parse(`#{cmd}`)
64
+ nodes = []
65
+ if raw_nodes['rows'].empty?
66
+ thor.say("No node found for '#{search_cmd}'")
67
+ else
68
+ raw_nodes['rows'].each do |node|
69
+ name, attrs = node.first
70
+ attrs.merge!({'name' => name})
71
+ nodes << attrs
72
+ yield attrs if block_given?
73
+ end
74
+ end
75
+ nodes
76
+ end
77
+
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end