fhcap-cli 0.3.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 (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