classify_cluster 0.2.7 → 0.3.7
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.
- data/Gemfile.lock +21 -0
- data/bin/classify +13 -0
- data/classify_cluster.gemspec +2 -1
- data/examples/defaults.rb +27 -0
- data/examples/variables.rb +33 -0
- data/lib/classify_cluster.rb +1 -0
- data/lib/classify_cluster/configurator/cluster.rb +28 -17
- data/lib/classify_cluster/configurator/role.rb +22 -1
- data/lib/classify_cluster/readers.rb +1 -0
- data/lib/classify_cluster/readers/cli.rb +114 -0
- data/lib/classify_cluster/version.rb +1 -1
- data/lib/classify_cluster/writers.rb +2 -1
- data/lib/classify_cluster/writers/classify.rb +25 -0
- data/lib/classify_cluster/writers/puppet.rb +2 -1
- metadata +29 -7
data/Gemfile.lock
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
classify_cluster (0.2.7)
|
5
|
+
activesupport (>= 2.3.5)
|
6
|
+
commander (~> 4.0.3)
|
7
|
+
highline (~> 1.6.1)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: http://rubygems.org/
|
11
|
+
specs:
|
12
|
+
activesupport (3.0.3)
|
13
|
+
commander (4.0.3)
|
14
|
+
highline (>= 1.5.0)
|
15
|
+
highline (1.6.1)
|
16
|
+
|
17
|
+
PLATFORMS
|
18
|
+
ruby
|
19
|
+
|
20
|
+
DEPENDENCIES
|
21
|
+
classify_cluster!
|
data/bin/classify
CHANGED
@@ -20,4 +20,17 @@ command :puppet do |c|
|
|
20
20
|
ClassifyCluster::Writers::Puppet.export!(options.export, :cluster => args[0], :config_file => options.config)
|
21
21
|
say("Success!")
|
22
22
|
end
|
23
|
+
end
|
24
|
+
|
25
|
+
command :config do |c|
|
26
|
+
c.syntax = 'classify config <clustername> [options]'
|
27
|
+
c.description = 'Runs an interactive script to generate a cluster configuration'
|
28
|
+
c.option '--export STRING', String, 'Location to output cluster configuration'
|
29
|
+
c.option '--cluster STRING', String, 'Cluster being created'
|
30
|
+
c.option '--defaults STRING', String, 'Location to load cluster defaults'
|
31
|
+
c.option '--variables STRING', String, 'Location to load cluster variables'
|
32
|
+
c.action do |args, options|
|
33
|
+
options.default :export => ClassifyCluster::Base.default_config_file, :defaults => '', :variables => ''
|
34
|
+
ClassifyCluster::Writers::Classify.export!(ClassifyCluster::Readers::Cli.start!(options.cluster, options.defaults, options.variables))
|
35
|
+
end
|
23
36
|
end
|
data/classify_cluster.gemspec
CHANGED
@@ -11,7 +11,8 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.homepage = "http://rubygems.org/gems/classify_cluster"
|
12
12
|
s.summary = %q{Contains several binaries for generating capistrano and puppet configurations}
|
13
13
|
s.description = %q{Reading from a YAML file will allow for consistent configuration between capistrano and puppet}
|
14
|
-
s.add_dependency(%q<commander>, ["
|
14
|
+
s.add_dependency(%q<commander>, ["~> 4.0.3"])
|
15
|
+
s.add_dependency(%q<highline>, ["~> 1.6.1"])
|
15
16
|
s.add_dependency(%q<activesupport>, [">= 2.3.5"])
|
16
17
|
|
17
18
|
s.rubyforge_project = "classify_cluster"
|
@@ -0,0 +1,27 @@
|
|
1
|
+
{
|
2
|
+
:socialcast_background_processor => 'resque',
|
3
|
+
'socialcast_mode' => 'appliance',
|
4
|
+
'socialcast_filestore' => 'riak',
|
5
|
+
'cluster_name' => 'appliance-cluster',
|
6
|
+
'deployment_root' => '/var/www/socialcast',
|
7
|
+
'app_root' => '/var/www/socialcast',
|
8
|
+
'app_shared_root' => '/var/www/socialcast',
|
9
|
+
'app_user' => 'socialcast',
|
10
|
+
'ssl_pem_path' => '/etc/ssl/pem',
|
11
|
+
'app_pem_file' => 'scmc.pem',
|
12
|
+
'cdn_disabled' => 'true',
|
13
|
+
'solr_jvm_options' => '-server -Xmx500M -Xms64M', # Needs more granular configuration
|
14
|
+
'rails_env' => 'production',
|
15
|
+
'scheduler_env' => 'production',
|
16
|
+
:backup_s3_app_name => "appliance",
|
17
|
+
:newrelic_enabled => false,
|
18
|
+
:solr_newrelic_app_name => "appliance",
|
19
|
+
:newrelic_app_name => 'appliance',
|
20
|
+
:aws_access_key_id => '',
|
21
|
+
:aws_secret_access_key => '',
|
22
|
+
:s3_bucket => '',
|
23
|
+
:backup_s3_bucket => '',
|
24
|
+
:cloudkick_oauth_key => '',
|
25
|
+
:cloudkick_oauth_secret => '',
|
26
|
+
:database_encoding => 'utf8'
|
27
|
+
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
{
|
2
|
+
:socialcast_domain => "",
|
3
|
+
:database_username => '',
|
4
|
+
:database_password => '',
|
5
|
+
:database_database => '',
|
6
|
+
:database_root_password => '',
|
7
|
+
:flickr_key => '',
|
8
|
+
:flickr_secret => '',
|
9
|
+
:secret_access_key => '',
|
10
|
+
:ldap_connections => [{
|
11
|
+
'base' => '',
|
12
|
+
'filter_string' => '',
|
13
|
+
'host' => '',
|
14
|
+
'map' => {'email' => '', 'first_name' => '', 'last_name' => '', 'company_login' => ''},
|
15
|
+
'port' => '',
|
16
|
+
'searcher_password' => '',
|
17
|
+
'searcher_username' => '',
|
18
|
+
'ssl' => ''
|
19
|
+
}],
|
20
|
+
:email_dropbox_account => '',
|
21
|
+
:email_dropbox_password => '',
|
22
|
+
:email_dropbox_host => '',
|
23
|
+
:email_dropbox_port => '',
|
24
|
+
|
25
|
+
:jabber_account => '',
|
26
|
+
:jabber_password => '',
|
27
|
+
|
28
|
+
:smtp_host => "",
|
29
|
+
:smtp_port => '',
|
30
|
+
:smtp_username => '',
|
31
|
+
:smtp_password => '',
|
32
|
+
:alert_address => ''
|
33
|
+
}
|
data/lib/classify_cluster.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
module ClassifyCluster
|
2
2
|
module Configurator
|
3
3
|
class Cluster
|
4
|
+
SSLPEM_FILEPATH = '/etc/ssl/pem/scmc.pem'
|
5
|
+
SSLPEM_MODULE = 'loadbalancer'
|
4
6
|
attr_reader :nodes, :name, :classes, :variables, :resources, :hostnames, :ssl_pem
|
5
7
|
def initialize(*args, &block)
|
6
|
-
@ssl_pem = {
|
8
|
+
@ssl_pem = {}
|
7
9
|
@nodes = {}
|
8
10
|
@variables = {}
|
9
11
|
@resources = []
|
@@ -11,25 +13,15 @@ module ClassifyCluster
|
|
11
13
|
@name = args.first
|
12
14
|
@hostnames = {}
|
13
15
|
returned = block.call(self)
|
14
|
-
|
15
|
-
|
16
|
-
@variables['hostnames'] << "#{fqdn}/#{node.private_ip}"
|
17
|
-
end
|
18
|
-
@nodes.each_pair do |fqdn, node|
|
19
|
-
node.resource do |resource|
|
20
|
-
resource.type 'etchosts'
|
21
|
-
resource.name "hosts"
|
22
|
-
resource.options({
|
23
|
-
:short_name => fqdn.split('.').first,
|
24
|
-
:fqdn => fqdn,
|
25
|
-
:hosts => @variables['hostnames']
|
26
|
-
})
|
27
|
-
end
|
28
|
-
end
|
16
|
+
add_hostnames
|
17
|
+
add_node_roles
|
29
18
|
returned
|
30
19
|
end
|
31
20
|
def ssl_pem(file_path=nil, module_name=nil)
|
32
|
-
|
21
|
+
if file_path.nil? && module_name.nil?
|
22
|
+
@ssl_pem = {:file_path => SSLPEM_FILEPATH, :module => SSLPEM_MODULE}
|
23
|
+
return @ssl_pem
|
24
|
+
end
|
33
25
|
@ssl_pem = {:file_path => file_path, :module => module_name}
|
34
26
|
end
|
35
27
|
def name(value=nil)
|
@@ -49,6 +41,25 @@ module ClassifyCluster
|
|
49
41
|
def klass(name)
|
50
42
|
@classes << name
|
51
43
|
end
|
44
|
+
def add_hostnames
|
45
|
+
@nodes.each_pair do |fqdn, node|
|
46
|
+
@variables['hostnames'] = [] unless @variables['hostnames']
|
47
|
+
@variables['hostnames'] << "#{fqdn}/#{node.private_ip}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
def add_node_roles
|
51
|
+
@nodes.each_pair do |fqdn, node|
|
52
|
+
node.resource do |resource|
|
53
|
+
resource.type 'etchosts'
|
54
|
+
resource.name "hosts"
|
55
|
+
resource.options({
|
56
|
+
:short_name => fqdn.split('.').first,
|
57
|
+
:fqdn => fqdn,
|
58
|
+
:hosts => @variables['hostnames']
|
59
|
+
})
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
52
63
|
end
|
53
64
|
end
|
54
65
|
end
|
@@ -1,10 +1,31 @@
|
|
1
1
|
module ClassifyCluster
|
2
2
|
module Configurator
|
3
|
+
ROLES = [
|
4
|
+
'file',
|
5
|
+
'scheduler',
|
6
|
+
'app',
|
7
|
+
'web',
|
8
|
+
'push',
|
9
|
+
'puppet_master',
|
10
|
+
{'munin' => ['master', 'node']},
|
11
|
+
'cache',
|
12
|
+
{'db' => ['primary', 'backup']},
|
13
|
+
'queue',
|
14
|
+
{'cron' => ['primary', 'backup']},
|
15
|
+
'search',
|
16
|
+
'worker'
|
17
|
+
]
|
3
18
|
class Role
|
19
|
+
begin
|
20
|
+
require 'active_support/hash_with_indifferent_access'
|
21
|
+
include ActiveSupport
|
22
|
+
rescue LoadError
|
23
|
+
end
|
24
|
+
|
4
25
|
attr_reader :type, :options, :node, :variables
|
5
26
|
def initialize(node, type, options={}, &block)
|
6
27
|
@type = type
|
7
|
-
@options = options
|
28
|
+
@options = HashWithIndifferentAccess.new(options)
|
8
29
|
@node = node
|
9
30
|
@variables = {}
|
10
31
|
block.call(self) if block_given?
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'classify_cluster/readers/cli'
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'highline/import'
|
2
|
+
|
3
|
+
module ClassifyCluster
|
4
|
+
module Readers
|
5
|
+
class Cli
|
6
|
+
def self.start!(cluster_name, defaults_path='', variables_path='')
|
7
|
+
say("Welcome to classify cluster cli configurator!")
|
8
|
+
|
9
|
+
defaults={}
|
10
|
+
variables={}
|
11
|
+
File.open(defaults_path, 'r') do |file|
|
12
|
+
defaults = eval(file.read)
|
13
|
+
end if File.exists?(defaults_path)
|
14
|
+
|
15
|
+
File.open(variables_path, 'r') do |file|
|
16
|
+
variables = eval(file.read)
|
17
|
+
end if File.exists?(variables_path)
|
18
|
+
say "Configure cluster wide"
|
19
|
+
cluster_config = gather_cluster_info(cluster_name, defaults, variables)
|
20
|
+
say "Configure nodes"
|
21
|
+
nodes = []
|
22
|
+
ask("How many nodes: ", Integer).times do |i|
|
23
|
+
gather_node_info!(cluster_config)
|
24
|
+
end
|
25
|
+
puts cluster_config.inspect
|
26
|
+
cluster_config
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.gather_value(key, value, indent=0)
|
30
|
+
case value
|
31
|
+
when Array
|
32
|
+
answers = []
|
33
|
+
ask("#{"\t"*indent}How many #{key.to_s}: ", Integer).times do |i|
|
34
|
+
answers << gather_value(key, value.first, 1)
|
35
|
+
say "Configured #{i+1} #{key.to_s}"
|
36
|
+
end
|
37
|
+
answers
|
38
|
+
when Hash
|
39
|
+
ask("#{"\t"*indent}<%= @key %>: ", lambda {|ans| ans =~ /^\{\s*['|:].+$/ ? eval(ans) : ans}) do |q|
|
40
|
+
q.gather = value
|
41
|
+
end
|
42
|
+
when Integer
|
43
|
+
ask("#{"\t"*indent}#{key.to_s}: ", Integer)
|
44
|
+
else
|
45
|
+
ask("#{"\t"*indent}#{key.to_s}: ")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.gather_node_info!(cluster_config)
|
50
|
+
hostname = ask("Hostname: ")
|
51
|
+
ip = ask("Ip: ")
|
52
|
+
role_names = ClassifyCluster::Configurator::ROLES.map { |k| k.is_a?(Hash) ? k.keys.first : k }
|
53
|
+
|
54
|
+
cluster_config.node(hostname, ip) do |node|
|
55
|
+
more_roles = true
|
56
|
+
while more_roles
|
57
|
+
types = {}
|
58
|
+
role_name = ask("Role [#{role_names.join(', ')}]: ", role_names)
|
59
|
+
if ClassifyCluster::Configurator::ROLES.reject { |k| !k.is_a?(Hash) }.map(&:keys).flatten.include?(role_name)
|
60
|
+
possible_types = ClassifyCluster::Configurator::ROLES.reject { |k| !k.is_a?(Hash) || !k.has_key?(role_name)}[0][role_name]
|
61
|
+
more_types = true
|
62
|
+
while more_types
|
63
|
+
type = ask("Type [#{possible_types.join(', ')}]: ", possible_types)
|
64
|
+
possible_types -= [type]
|
65
|
+
types[type] = true
|
66
|
+
more_types = possible_types.size > 0 && agree("More types? ")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
node.role role_name.to_sym, types do |role|
|
70
|
+
while agree("Role variables?")
|
71
|
+
name = ask("name: ")
|
72
|
+
value = ask("value: ")
|
73
|
+
role.variable name, value
|
74
|
+
end
|
75
|
+
end
|
76
|
+
role_names -= [role_name]
|
77
|
+
more_roles = role_names.size > 0 && agree("More roles? ")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.gather_cluster_info(cluster_name, defaults={}, variables={})
|
83
|
+
cluster_name = ask("Cluster Name (no spaces): ") do |q|
|
84
|
+
q.validate = /^\w.*/
|
85
|
+
end unless cluster_name
|
86
|
+
|
87
|
+
ClassifyCluster::Configurator::Cluster.new(cluster_name) do |cluster_config|
|
88
|
+
file_path = ask("Ssl pem path: ") do |q|
|
89
|
+
q.validate{ |a| File.exists?(a) }
|
90
|
+
q.default = ClassifyCluster::Configurator::Cluster::SSLPEM_FILEPATH
|
91
|
+
end
|
92
|
+
module_name = ask("Puppet module to move it to: ") do |q|
|
93
|
+
q.default = ClassifyCluster::Configurator::Cluster::SSLPEM_MODULE
|
94
|
+
end
|
95
|
+
cluster_config.ssl_pem(file_path, module_name)
|
96
|
+
|
97
|
+
defaults.each_pair do |key, value|
|
98
|
+
cluster_config.variable key, value
|
99
|
+
end
|
100
|
+
variables.each_pair do |key, value|
|
101
|
+
cluster_config.variable key, gather_value(key, value)
|
102
|
+
end
|
103
|
+
|
104
|
+
klasses = ask("Classes: (q to stop)") do |q|
|
105
|
+
q.gather = 'q'
|
106
|
+
end
|
107
|
+
klasses.delete_if {|klass| klass.nil? || klass.empty?}.each do |klass|
|
108
|
+
cluster_config.klass klass
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module ClassifyCluster
|
2
|
+
module Writers
|
3
|
+
class Classify
|
4
|
+
def self.export!(classify_configurator)
|
5
|
+
File.open('/etc/cluster.rb', 'w') do |file|
|
6
|
+
output file, "# Autogenerated on #{Time.now.to_s}"
|
7
|
+
output file, "cluster :\"#{classify_configurator.name}\" do |cluster|"
|
8
|
+
|
9
|
+
classify_configurator.classes.each do |klass|
|
10
|
+
output file, "cluster.klass #{klass.inspect}", 1
|
11
|
+
end
|
12
|
+
classify_configurator.variables.each_pair do |key, variable|
|
13
|
+
output file, "cluster.variable #{key.inspect}, #{variable.inspect}", 1
|
14
|
+
end
|
15
|
+
|
16
|
+
output file, "end"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.output(file, str, indent=0)
|
21
|
+
file.write("#{"\s"*(indent*4)}#{str}\n")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'fileutils'
|
2
|
+
|
2
3
|
module ClassifyCluster
|
3
4
|
module Writers
|
4
5
|
class Puppet
|
5
6
|
def self.export!(export_to_folder, options={})
|
6
|
-
options
|
7
|
+
options = {:config_file => ClassifyCluster::Base.default_config_file}.merge(options)
|
7
8
|
config = ClassifyCluster::Configurator::Configuration.new(options[:config_file])
|
8
9
|
config.clusters.each_pair do |name, cluster|
|
9
10
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: classify_cluster
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 29
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 3
|
9
9
|
- 7
|
10
|
-
version: 0.
|
10
|
+
version: 0.3.7
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Sean Cashin
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-02-04 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -24,7 +24,7 @@ dependencies:
|
|
24
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
26
26
|
requirements:
|
27
|
-
- -
|
27
|
+
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
hash: 57
|
30
30
|
segments:
|
@@ -35,9 +35,25 @@ dependencies:
|
|
35
35
|
type: :runtime
|
36
36
|
version_requirements: *id001
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
|
-
name:
|
38
|
+
name: highline
|
39
39
|
prerelease: false
|
40
40
|
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 13
|
46
|
+
segments:
|
47
|
+
- 1
|
48
|
+
- 6
|
49
|
+
- 1
|
50
|
+
version: 1.6.1
|
51
|
+
type: :runtime
|
52
|
+
version_requirements: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: activesupport
|
55
|
+
prerelease: false
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
41
57
|
none: false
|
42
58
|
requirements:
|
43
59
|
- - ">="
|
@@ -49,7 +65,7 @@ dependencies:
|
|
49
65
|
- 5
|
50
66
|
version: 2.3.5
|
51
67
|
type: :runtime
|
52
|
-
version_requirements: *
|
68
|
+
version_requirements: *id003
|
53
69
|
description: Reading from a YAML file will allow for consistent configuration between capistrano and puppet
|
54
70
|
email:
|
55
71
|
- sean@socialcast.com
|
@@ -62,11 +78,14 @@ extra_rdoc_files: []
|
|
62
78
|
files:
|
63
79
|
- .gitignore
|
64
80
|
- Gemfile
|
81
|
+
- Gemfile.lock
|
65
82
|
- README
|
66
83
|
- Rakefile
|
67
84
|
- bin/classify
|
68
85
|
- classify_cluster.gemspec
|
69
86
|
- examples/cluster.rb
|
87
|
+
- examples/defaults.rb
|
88
|
+
- examples/variables.rb
|
70
89
|
- lib/classify_cluster.rb
|
71
90
|
- lib/classify_cluster/base.rb
|
72
91
|
- lib/classify_cluster/configurator.rb
|
@@ -75,9 +94,12 @@ files:
|
|
75
94
|
- lib/classify_cluster/configurator/node.rb
|
76
95
|
- lib/classify_cluster/configurator/resource.rb
|
77
96
|
- lib/classify_cluster/configurator/role.rb
|
97
|
+
- lib/classify_cluster/readers.rb
|
98
|
+
- lib/classify_cluster/readers/cli.rb
|
78
99
|
- lib/classify_cluster/version.rb
|
79
100
|
- lib/classify_cluster/writers.rb
|
80
101
|
- lib/classify_cluster/writers/capistrano.rb
|
102
|
+
- lib/classify_cluster/writers/classify.rb
|
81
103
|
- lib/classify_cluster/writers/puppet.rb
|
82
104
|
has_rdoc: true
|
83
105
|
homepage: http://rubygems.org/gems/classify_cluster
|