ssp 0.1 → 0.2
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/bin/ssp +1 -1
- data/lib/ssp/app.rb +11 -0
- data/lib/ssp/application/node.rb +15 -2
- data/lib/ssp/application/office_node.rb +180 -0
- data/lib/ssp/version.rb +1 -1
- metadata +5 -4
data/bin/ssp
CHANGED
data/lib/ssp/app.rb
CHANGED
@@ -2,7 +2,15 @@ require 'thor'
|
|
2
2
|
require 'thor/group'
|
3
3
|
|
4
4
|
module SSP
|
5
|
+
module ThorExtensions
|
6
|
+
def banner(task, namespace = nil, subcommand = false)
|
7
|
+
"#{File.basename($0)} #{task.formatted_usage(self, $thor_runner, subcommand)}"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
5
11
|
class App < Thor
|
12
|
+
extend ThorExtensions
|
13
|
+
|
6
14
|
namespace :app
|
7
15
|
map "-T" => :list
|
8
16
|
|
@@ -61,6 +69,9 @@ module SSP
|
|
61
69
|
unless @_commands_initialized
|
62
70
|
Dir[File.join(File.dirname(__FILE__), "application", "*.rb")].each do |command|
|
63
71
|
require(command)
|
72
|
+
klass_name = Thor::Util.camel_case(File.basename(command).sub(/\.rb$/, ''))
|
73
|
+
klass = SSP::App.const_get(klass_name)
|
74
|
+
klass.extend(ThorExtensions)
|
64
75
|
end
|
65
76
|
@_commands_initialized = true
|
66
77
|
end
|
data/lib/ssp/application/node.rb
CHANGED
@@ -24,8 +24,8 @@ class SSP::App::Node < Thor
|
|
24
24
|
:desc => "Sets the flavor of the server (1: 256MB, 2: 512MB, 3: 1024MB, ...)",
|
25
25
|
:default => 2
|
26
26
|
method_option :image, :aliases => "-i", :type => :numeric,
|
27
|
-
:desc => "Sets the image to be used (49: Ubuntu 10.04,
|
28
|
-
:default =>
|
27
|
+
:desc => "Sets the image to be used (49: Ubuntu 10.04, 4256704: chef-node)",
|
28
|
+
:default => 4256704
|
29
29
|
def create(fqdn, *roles)
|
30
30
|
server = connection.servers.new
|
31
31
|
|
@@ -110,6 +110,19 @@ validation_client_name "#{chef_config[:validation_client_name]}"
|
|
110
110
|
ssh.run
|
111
111
|
end
|
112
112
|
|
113
|
+
desc "list", "Lists available servers on Rackspace"
|
114
|
+
def list
|
115
|
+
server_list = [ ["ID", "Name", "Public IP", "Private IP", "Flavor ID"].map {|t| shell.set_color(t, :bold)} ]
|
116
|
+
server_list += connection.servers.all.map do |server|
|
117
|
+
[
|
118
|
+
server.id.to_s, server.name,
|
119
|
+
server.addresses["public"][0], server.addresses["private"][0],
|
120
|
+
server.flavor_id.to_s
|
121
|
+
]
|
122
|
+
end
|
123
|
+
print_table(server_list)
|
124
|
+
end
|
125
|
+
|
113
126
|
protected
|
114
127
|
def connection
|
115
128
|
@connection ||= Fog::Rackspace::Servers.new(
|
@@ -0,0 +1,180 @@
|
|
1
|
+
require 'chef/config'
|
2
|
+
require 'chef/knife/ssh'
|
3
|
+
require 'ssp/config'
|
4
|
+
|
5
|
+
class SSP::App::OfficeNode < Thor
|
6
|
+
namespace :officenode
|
7
|
+
|
8
|
+
class_option :ssh_user,
|
9
|
+
:desc => "The ssh username",
|
10
|
+
:default => "root"
|
11
|
+
|
12
|
+
class_option :ssh_password,
|
13
|
+
:desc => "The ssh password",
|
14
|
+
:default => SSP::Config[:vanilla][:root_password]
|
15
|
+
|
16
|
+
class_option :chef_config, :aliases => "-c",
|
17
|
+
:desc => "Location of the chef configuration file",
|
18
|
+
:default => File.join(ENV['HOME'], '.chef', 'knife.rb')
|
19
|
+
|
20
|
+
|
21
|
+
desc "create FQDN [ROLES...]", "Creates a new chef client on Vanilla"
|
22
|
+
method_option :memory, :aliases => "-m", :type => :numeric,
|
23
|
+
:desc => "Sets the memory size for the node in MB",
|
24
|
+
:default => 512
|
25
|
+
method_option :iplastpart, :aliases => "-i", :type => :numeric,
|
26
|
+
:desc => "Sets the last part of the node's IP",
|
27
|
+
:required => true
|
28
|
+
def create(fqdn, *roles)
|
29
|
+
ip = "192.168.1.#{options[:iplastpart]}"
|
30
|
+
disk_size = options[:memory] * 20 / 1024
|
31
|
+
hostname = fqdn.split(".").first
|
32
|
+
|
33
|
+
# Convert roles array to proper run list
|
34
|
+
run_list = roles.map { |r| r =~ /recipe\[(.*)\]/ ? $1 : "role[#{r}]" }
|
35
|
+
|
36
|
+
# Always include the chef-client role in the run list
|
37
|
+
unless run_list.include? "role[chef-client]"
|
38
|
+
run_list.unshift "role[chef-client]"
|
39
|
+
end
|
40
|
+
|
41
|
+
vncpass = pwgen
|
42
|
+
rootpass = pwgen
|
43
|
+
|
44
|
+
say_status "Name: ", fqdn, :cyan
|
45
|
+
say_status "Memory: ", "#{options[:memory]}MB", :cyan
|
46
|
+
say_status "Disk: ", "#{disk_size}GB", :cyan
|
47
|
+
say_status "IP: ", ip, :cyan
|
48
|
+
say_status "VNC password: ", vncpass, :cyan
|
49
|
+
say_status "root password: ", rootpass, :cyan
|
50
|
+
|
51
|
+
say "\nRequesting server", :magenta
|
52
|
+
|
53
|
+
command = <<EOH
|
54
|
+
bash -c '
|
55
|
+
/root/bin/mkdomu.sh -m #{options[:memory]} -d #{disk_size} -v #{vncpass} -p #{rootpass} #{hostname} #{options[:iplastpart]}
|
56
|
+
xm create /etc/xen/#{hostname}.cfg
|
57
|
+
'
|
58
|
+
EOH
|
59
|
+
|
60
|
+
ssh_run "vanilla", command
|
61
|
+
|
62
|
+
say "\nServer ready, waiting 15 seconds to bootstrap."
|
63
|
+
sleep 15
|
64
|
+
|
65
|
+
say "\nBootstrapping #{shell.set_color(fqdn, :bold)}..."
|
66
|
+
|
67
|
+
command = <<EOH
|
68
|
+
bash -c '
|
69
|
+
mkdir -p /etc/chef
|
70
|
+
|
71
|
+
(
|
72
|
+
cat <<'EOP'
|
73
|
+
127.0.0.1 localhost localhost.localdomain
|
74
|
+
#{ip} #{fqdn} #{fqdn.split(".").first}
|
75
|
+
|
76
|
+
192.168.1.82 basil basil.secretsaucepartners.com chef.secretsaucepartners.com
|
77
|
+
EOP
|
78
|
+
) > /etc/hosts
|
79
|
+
|
80
|
+
(
|
81
|
+
cat <<'EOP'
|
82
|
+
#{IO.read(chef_config[:validation_key])}
|
83
|
+
EOP
|
84
|
+
) > /tmp/validation.pem
|
85
|
+
awk NF /tmp/validation.pem > /etc/chef/validation.pem
|
86
|
+
rm /tmp/validation.pem
|
87
|
+
|
88
|
+
(
|
89
|
+
cat <<'EOP'
|
90
|
+
log_level :info
|
91
|
+
log_location STDOUT
|
92
|
+
chef_server_url "#{chef_config[:chef_server_url]}"
|
93
|
+
validation_client_name "#{chef_config[:validation_client_name]}"
|
94
|
+
EOP
|
95
|
+
) > /etc/chef/client.rb
|
96
|
+
|
97
|
+
(
|
98
|
+
cat <<'EOP'
|
99
|
+
#{{ "run_list" => run_list }.to_json}
|
100
|
+
EOP
|
101
|
+
) > /etc/chef/first-boot.json
|
102
|
+
|
103
|
+
apt-get -y update
|
104
|
+
apt-get -y upgrade
|
105
|
+
|
106
|
+
/usr/local/bin/chef-client -j /etc/chef/first-boot.json'
|
107
|
+
EOH
|
108
|
+
|
109
|
+
begin
|
110
|
+
ssh_run ip, command, "root", rootpass
|
111
|
+
rescue Net::SSH::HostKeyMismatch => key_ex
|
112
|
+
key_ex.remember_host!
|
113
|
+
retry
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
desc "list", "Lists available servers on Vanilla"
|
118
|
+
def list
|
119
|
+
ssh_run "vanilla", "xm list"
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
desc "destroy FQDN", "Removes a chef client and also destorys the Xen guest on Vanilla"
|
124
|
+
def destroy(fqdn)
|
125
|
+
hostname = fqdn.split(".").first
|
126
|
+
|
127
|
+
if ask("Are you sure you want to destroy the `#{fqdn}' node? [yes/no]").downcase != "yes"
|
128
|
+
raise Thor::Error, "Aborting."
|
129
|
+
end
|
130
|
+
|
131
|
+
command = <<EOH
|
132
|
+
bash -c '
|
133
|
+
xm shutdown #{hostname}
|
134
|
+
sleep 3
|
135
|
+
rm /etc/xen/#{hostname}.cfg
|
136
|
+
lvremove -f vg/#{hostname}-{root,swap}'
|
137
|
+
EOH
|
138
|
+
|
139
|
+
ssh_run "vanilla", command
|
140
|
+
|
141
|
+
say %x{knife node delete #{fqdn} -y -c #{options[:chef_config]} 2>/dev/null}
|
142
|
+
say %x{knife client delete #{fqdn} -y -c #{options[:chef_config]} 2>/dev/null}
|
143
|
+
end
|
144
|
+
|
145
|
+
protected
|
146
|
+
def chef_config
|
147
|
+
unless defined?(@_chef_config_loaded)
|
148
|
+
Chef::Config.from_file(options[:chef_config])
|
149
|
+
@_chef_config_loaded = true
|
150
|
+
end
|
151
|
+
Chef::Config
|
152
|
+
end
|
153
|
+
|
154
|
+
def ssh_run(host, command, user = options[:ssh_user], pass = options[:ssh_password])
|
155
|
+
ssh = Chef::Knife::Ssh.new
|
156
|
+
ssh.name_args = [ host, command ]
|
157
|
+
ssh.config[:ssh_user] = user
|
158
|
+
ssh.config[:password] = pass
|
159
|
+
ssh.config[:manual] = true
|
160
|
+
|
161
|
+
begin
|
162
|
+
ssh.run
|
163
|
+
rescue Net::SSH::AuthenticationFailed
|
164
|
+
unless config[:ssh_password]
|
165
|
+
puts "Failed to authenticate #{config[:ssh_user]} - trying password auth"
|
166
|
+
ssh = Chef::Knife::Ssh.new
|
167
|
+
ssh.name_args = [ host, command ]
|
168
|
+
ssh.config[:ssh_user] = user
|
169
|
+
ssh.config[:manual] = true
|
170
|
+
ssh.config[:password] = ssh.get_password
|
171
|
+
ssh.run
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def pwgen(length = 16)
|
177
|
+
chars = (('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a) - %w(i o 0 1 l I O)
|
178
|
+
(1..length).collect {|a| chars[rand(chars.size)]}.join
|
179
|
+
end
|
180
|
+
end
|
data/lib/ssp/version.rb
CHANGED
metadata
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ssp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: "0.
|
8
|
+
- 2
|
9
|
+
version: "0.2"
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- !binary |
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2010-
|
19
|
+
date: 2010-07-05 00:00:00 +02:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
@@ -64,6 +64,7 @@ files:
|
|
64
64
|
- lib/ssp/app.rb
|
65
65
|
- lib/ssp/application/bags.rb
|
66
66
|
- lib/ssp/application/node.rb
|
67
|
+
- lib/ssp/application/office_node.rb
|
67
68
|
- lib/ssp/application/pair.rb
|
68
69
|
- lib/ssp/config.rb
|
69
70
|
- lib/ssp/version.rb
|