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,22 @@
1
+ require 'fhcap/tasks/task_base'
2
+
3
+ module Fhcap
4
+ module Tasks
5
+ module Repo
6
+ class List < TaskBase
7
+
8
+ def run
9
+ thor.say "Repo::List", :yellow
10
+
11
+ table_contents = [table_header('Name', 'Directory', 'URL')]
12
+
13
+ repos_config.each do |name, cfg|
14
+ table_contents << table_row(name, repo_dir(name), cfg[:url])
15
+ end
16
+ thor.print_table table_contents
17
+ end
18
+
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,34 @@
1
+ require 'fhcap/tasks/task_base'
2
+ require 'fhcap/tasks/setup'
3
+
4
+ module Fhcap
5
+ module Tasks
6
+ module Repo
7
+ class Remove < TaskBase
8
+
9
+ attr_reader :name
10
+
11
+ def initialize(options)
12
+ super
13
+ @name = options[:name]
14
+ @skip_setup = options[:'skip-setup']
15
+ end
16
+
17
+ def run
18
+ thor.say "Repo::Remove: name = #{name}", :yellow
19
+ if thor.yes? "Remove repo #{name}? (y/n)"
20
+ repo_dir = repo_dir(name)
21
+ if repo_dir && thor.yes?("Remove local repo dir #{repo_dir}? (y/n)")
22
+ thor.remove_file repo_dir
23
+ end
24
+ config[:repos].delete(name.to_sym)
25
+ thor.create_file(config.default_config_file, JSON.pretty_generate(config.data), :force => true)
26
+ config.reload
27
+ Tasks::Setup.new(@options).run unless @skip_setup
28
+ end
29
+ end
30
+
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,59 @@
1
+ require 'fhcap/tasks/task_base'
2
+ require 'fhcap/tasks/repo/add'
3
+ require 'fhcap/tasks/knife/add'
4
+
5
+ module Fhcap
6
+ module Tasks
7
+ class Setup < TaskBase
8
+
9
+ def initialize(options)
10
+ super
11
+ @fhcap_config = @config.exists? ? @config.data : @config.fhcap_config
12
+
13
+ opts = {
14
+ repos_dir: options[:'repos-dir'],
15
+ }.delete_if { |k, v| v.nil? || v.empty? }
16
+
17
+ @fhcap_config.merge!(opts)
18
+ end
19
+
20
+ def run
21
+ ask_config(required_config, @fhcap_config)
22
+ create_fhcap_config
23
+ create_fhcap_repos
24
+ create_knife_config
25
+ end
26
+
27
+ private
28
+
29
+ def required_config
30
+ {
31
+ repos_dir: {
32
+ msg: "Local directory where repos will be checked out",
33
+ options: {:path => true}
34
+ }
35
+ }
36
+ end
37
+
38
+ def create_fhcap_config
39
+ thor.create_file(config.default_config_file, JSON.pretty_generate(@fhcap_config))
40
+ config.reload
41
+ end
42
+
43
+ def create_fhcap_repos
44
+ repos = config[:repos]
45
+ repos.each do |name, cfg|
46
+ Repo::Checkout.new(@options.dup.merge({:repo => name.to_s})).run
47
+ end if repos
48
+ end
49
+
50
+ def create_knife_config
51
+ knife_config = config[:knife]
52
+ knife_config.each do |name, cfg|
53
+ Knife::Add.new(@options.dup.merge({:name => name.to_s, :url => cfg[:chef_server_url], :node_name => cfg[:node_name]})).run
54
+ end if knife_config
55
+ end
56
+
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,89 @@
1
+ require 'fhcap/fhcap_helper'
2
+ require 'fhcap/repos_helper'
3
+ require 'fhcap/providers_helper'
4
+ require 'fhcap/knife_helper'
5
+ require 'ruby-progressbar'
6
+
7
+ module Fhcap
8
+ module Tasks
9
+ class TaskBase
10
+
11
+ include Fhcap::FhcapHelper
12
+ include Fhcap::ReposHelper
13
+ include Fhcap::ProvidersHelper
14
+ include Fhcap::KnifeHelper
15
+
16
+ attr_reader :options, :config, :thor, :verbose
17
+
18
+ def initialize(options)
19
+ @options = options
20
+ @config = options[:config]
21
+ @thor = options[:thor]
22
+ @verbose = options[:verbose]
23
+ end
24
+
25
+ def ask_config(required, config)
26
+ required.each do |key, cfg|
27
+ if !config[key] || options[:interactive]
28
+ msg = cfg[:msg] || "#{key}:"
29
+ options = cfg[:options] || {}
30
+ options[:default] = config[key]
31
+ if cfg[:boolean]
32
+ config[key] = thor.yes? "#{msg} y/n?"
33
+ else
34
+ config[key] = thor.ask msg, options
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ def exit_with_error(msg)
41
+ thor.say_status 'error', msg, :red
42
+ exit(-1)
43
+ end
44
+
45
+ def with_progress(title, &block)
46
+ long_running_task = fork(&block)
47
+
48
+ progress = fork do
49
+ progressbar = ProgressBar.create(title: title, total: nil)
50
+
51
+ trap "INT" do
52
+ progressbar.total = progressbar.progress + 1
53
+ progressbar.clear
54
+ exit
55
+ end
56
+
57
+ loop do
58
+ progressbar.increment
59
+ sleep 0.5
60
+ end
61
+ end
62
+
63
+ Process.wait(long_running_task)
64
+ Process.kill(2, progress)
65
+ end
66
+
67
+ def table_header(*args)
68
+ args.collect do |name|
69
+ set_color(name.to_s, :green)
70
+ end
71
+ end
72
+
73
+ def table_row(*args)
74
+ args.collect do |name|
75
+ color_pad(name.to_s)
76
+ end
77
+ end
78
+
79
+ def color_pad(string)
80
+ string + set_color("", :white)
81
+ end
82
+
83
+ def set_color(*args)
84
+ thor.shell.set_color(*args)
85
+ end
86
+
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,121 @@
1
+ require 'thor'
2
+ require 'fhcap'
3
+ require 'fhcap/config'
4
+ require 'fhcap/providers_helper'
5
+ require 'fhcap/repos_helper'
6
+
7
+ module Fhcap
8
+
9
+ class ThorBase < Thor
10
+
11
+ attr_reader :config, :thor
12
+
13
+ class << self
14
+ @@shared_options = {}
15
+ @@fhcap_config = Fhcap::Config.new(
16
+ :config_file => ENV['FHCAP_CFG_FILE']
17
+ )
18
+
19
+ def add_shared_option(name, options = {})
20
+ @@shared_options[name] = options
21
+ end
22
+
23
+ def shared_options(*option_names)
24
+ option_names.each do |option_name|
25
+ opt = @@shared_options[option_name]
26
+ raise "Tried to access shared option '#{option_name}' but it was not previously defined" if opt.nil?
27
+ option option_name, opt
28
+ end
29
+ end
30
+
31
+ def config_key_collection(name)
32
+ if @@fhcap_config.exists? && @@fhcap_config[name.to_sym]
33
+ @@fhcap_config[name.to_sym].collect do |key, val|
34
+ if block_given?
35
+ yield key.to_s, val
36
+ else
37
+ key.to_s
38
+ end
39
+ end
40
+ else
41
+ []
42
+ end
43
+ end
44
+
45
+ def provider_names
46
+ config_key_collection(:providers) do |provider, cfg|
47
+ cfg.collect do |id, pcfg|
48
+ "#{provider}:#{id}"
49
+ end
50
+ end.flatten
51
+ end
52
+
53
+ def provider_names_for(service)
54
+ config_key_collection(:providers) do |provider, cfg|
55
+ cfg.reject do |id, pcfg|
56
+ !pcfg[:provides] || !pcfg[:provides].include?(service)
57
+ end.collect do |id, pcfg|
58
+ "#{provider}:#{id}"
59
+ end
60
+ end.flatten
61
+ end
62
+
63
+ def chef_server_names
64
+ config_key_collection(:knife)
65
+ end
66
+
67
+ def repo_names
68
+ config_key_collection(:repos)
69
+ end
70
+
71
+ def cluster_template_names
72
+ Fhcap::TEMPLATE_NAMES
73
+ end
74
+
75
+ def run_knife_cmd(cmd, options)
76
+ cmd = (['knife', cmd]).join(' ')
77
+ run_cmd(cmd, options)
78
+ end
79
+
80
+ def run_cmd(cmd, options)
81
+ run(cmd)
82
+ end
83
+
84
+ end
85
+
86
+ include Thor::Actions
87
+ include Fhcap::ProvidersHelper
88
+ include Fhcap::ReposHelper
89
+
90
+ def initialize(*args)
91
+ super
92
+ self.class.source_root(Fhcap.source_root)
93
+ #$stdout.sync = true
94
+ @config = Fhcap::Config.new(
95
+ :config_file => ENV['FHCAP_CFG_FILE']
96
+ )
97
+ @thor = self
98
+ end
99
+
100
+ private
101
+
102
+ def task_options(options)
103
+ opts = {
104
+ :thor => self,
105
+ :config => @config
106
+ }.merge(options)
107
+ symbolize_keys_deep! opts
108
+ opts
109
+ end
110
+
111
+ def symbolize_keys_deep!(h)
112
+ h.keys.each do |k|
113
+ ks = k.to_sym
114
+ h[ks] = h.delete k
115
+ symbolize_keys_deep! h[ks] if h[ks].kind_of? Hash
116
+ end
117
+ end
118
+
119
+ end
120
+
121
+ end
@@ -0,0 +1,3 @@
1
+ module Fhcap
2
+ VERSION = "0.3.0"
3
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+ describe Fhcap::CLI::Cli do
3
+ describe "#initialize" do
4
+
5
+ end
6
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+ require "fhcap/tasks/cluster/create"
3
+
4
+ describe Fhcap::Tasks::Cluster::Create do
5
+
6
+ subject {
7
+ Fhcap::Tasks::Cluster::Create.new(options)
8
+ }
9
+
10
+ let(:thor) do
11
+ DummyThor.new
12
+ end
13
+
14
+ let(:config) do
15
+ DummyConfig.new
16
+ end
17
+
18
+ let(:options) do
19
+ {
20
+ :config => config,
21
+ :thor => thor,
22
+ :name => 'testcluster',
23
+ :repo => 'testrepo',
24
+ :template => 'template',
25
+ :'git-ref' => 'master',
26
+ :domain => 'testdomain',
27
+ :'ssl-cert' => 'testcert',
28
+ :'dns-provider-id' => 'test',
29
+ :'chef-server' => 'test',
30
+ :'provider-id' => 'test',
31
+ }
32
+ end
33
+
34
+ describe "#initialize" do
35
+ specify { expect(subject.name).to eq(options[:name]) }
36
+ specify { expect(subject.instance_variable_get(:@gitref)).to eq(options[:'git-ref']) }
37
+ specify { expect(subject.instance_variable_get(:@ssl_cert)).to eq(options[:'ssl-cert']) }
38
+ specify { expect(subject.instance_variable_get(:@dns_provider_id)).to eq(options[:'dns-provider-id']) }
39
+ specify { expect(subject.cluster_config[:id]).to eq(options[:name]) }
40
+ specify { expect(subject.cluster_config[:template]).to eq(options[:template]) }
41
+ specify { expect(subject.cluster_config[:domain]).to eq(options[:domain]) }
42
+ specify { expect(subject.cluster_config[:chef_server]).to eq(options[:'chef-server']) }
43
+ specify { expect(subject.cluster_config[:provider_id]).to eq(options[:'provider-id']) }
44
+ end
45
+
46
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+ require "fhcap/tasks/knife/add"
3
+
4
+ describe Fhcap::Tasks::Knife::Add do
5
+
6
+ subject {
7
+ Fhcap::Tasks::Knife::Add.new(options)
8
+ }
9
+
10
+ let(:thor) do
11
+ DummyThor.new
12
+ end
13
+
14
+ let(:config) do
15
+ {:knife => {}}
16
+ end
17
+
18
+ let(:options) do
19
+ {
20
+ :config => config,
21
+ :thor => thor,
22
+ :name => 'testknife',
23
+ :url => 'https://example.com',
24
+ :'node-name' => 'testnode'
25
+ }
26
+ end
27
+
28
+ describe "#initialize" do
29
+ specify { expect(subject.name).to eq(options[:name]) }
30
+ specify { expect(subject.knife_config[:chef_server_url]).to eq(options[:url]) }
31
+ specify { expect(subject.knife_config[:node_name]).to eq(options[:'node-name']) }
32
+ specify { expect(subject.knife_config[:validation_client_name]).to eq('chef-validator') }
33
+ end
34
+
35
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+ require "fhcap/tasks/knife/remove"
3
+
4
+ describe Fhcap::Tasks::Knife::Remove do
5
+
6
+ subject {
7
+ Fhcap::Tasks::Knife::Remove.new(options)
8
+ }
9
+
10
+ let(:thor) do
11
+ DummyThor.new
12
+ end
13
+
14
+ let(:options) do
15
+ {
16
+ :thor => thor,
17
+ :name => 'testrepo'
18
+ }
19
+ end
20
+
21
+ describe "#initialize" do
22
+ specify { expect(subject.name).to eq(options[:name]) }
23
+ end
24
+
25
+ end