knife-joyent 0.0.10 → 0.1.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.
- data/README.md +3 -3
- data/knife-joyent.gemspec +3 -3
- data/lib/chef/knife/joyent_base.rb +60 -0
- data/lib/chef/knife/joyent_flavor_list.rb +20 -19
- data/lib/chef/knife/joyent_image_list.rb +23 -21
- data/lib/chef/knife/joyent_key_add.rb +39 -38
- data/lib/chef/knife/joyent_key_delete.rb +23 -22
- data/lib/chef/knife/joyent_key_list.rb +17 -16
- data/lib/chef/knife/joyent_server_create.rb +238 -151
- data/lib/chef/knife/joyent_server_delete.rb +58 -56
- data/lib/chef/knife/joyent_server_list.rb +47 -44
- data/lib/chef/knife/joyent_server_reboot.rb +24 -23
- data/lib/chef/knife/joyent_server_resize.rb +41 -40
- data/lib/chef/knife/joyent_server_start.rb +29 -27
- data/lib/chef/knife/joyent_server_stop.rb +28 -27
- data/lib/chef/knife/joyent_snapshot_create.rb +16 -15
- data/lib/chef/knife/joyent_snapshot_delete.rb +30 -29
- data/lib/chef/knife/joyent_snapshot_list.rb +34 -33
- data/lib/chef/knife/joyent_tag_create.rb +29 -27
- data/lib/chef/knife/joyent_tag_delete.rb +45 -43
- data/lib/chef/knife/joyent_tag_list.rb +26 -24
- data/lib/knife-joyent/version.rb +1 -1
- metadata +9 -9
- data/lib/chef/knife/base.rb +0 -58
@@ -1,168 +1,255 @@
|
|
1
|
-
require
|
1
|
+
require 'chef/knife/joyent_base'
|
2
2
|
|
3
|
-
|
4
|
-
class
|
3
|
+
class Chef
|
4
|
+
class Knife
|
5
|
+
class JoyentServerCreate < Knife
|
5
6
|
|
6
|
-
|
7
|
+
include Knife::JoyentBase
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
:
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
:
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
:
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
:
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
9
|
+
deps do
|
10
|
+
require 'fog'
|
11
|
+
require 'readline'
|
12
|
+
require 'chef/json_compat'
|
13
|
+
require 'chef/knife/bootstrap'
|
14
|
+
require 'ipaddr'
|
15
|
+
Chef::Knife::Bootstrap.load_deps
|
16
|
+
end
|
17
|
+
|
18
|
+
banner 'knife joyent server create (options)'
|
19
|
+
|
20
|
+
|
21
|
+
def is_linklocal(ip)
|
22
|
+
linklocal = IPAddr.new "169.254.0.0/16"
|
23
|
+
return linklocal.include?(ip)
|
24
|
+
end
|
25
|
+
|
26
|
+
def is_loopback(ip)
|
27
|
+
loopback = IPAddr.new "127.0.0.0/8"
|
28
|
+
return loopback.include?(ip)
|
29
|
+
end
|
30
|
+
|
31
|
+
def is_private(ip)
|
32
|
+
block_a = IPAddr.new "10.0.0.0/8"
|
33
|
+
block_b = IPAddr.new "172.16.0.0/12"
|
34
|
+
block_c = IPAddr.new "192.168.0.0/16"
|
35
|
+
return (block_a.include?(ip) or block_b.include?(ip) or block_c.include?(ip))
|
36
|
+
end
|
37
|
+
|
38
|
+
option :package,
|
39
|
+
:short => '-f FLAVOR_NAME',
|
40
|
+
:long => '--flavor FLAVOR_NAME',
|
41
|
+
:description => 'specify flavor/package for the server'
|
42
|
+
|
43
|
+
option :dataset,
|
44
|
+
:short => '-I IMAGE_ID',
|
45
|
+
:long => '--image IMAGE_ID',
|
46
|
+
:description => 'specify image for the server'
|
47
|
+
|
48
|
+
option :run_list,
|
49
|
+
:short => "-r RUN_LIST",
|
50
|
+
:long => "--run-list RUN_LIST",
|
51
|
+
:description => "Comma separated list of roles/recipes to apply",
|
52
|
+
:proc => lambda { |o| o.split(/[\s,]+/) },
|
53
|
+
:default => []
|
54
|
+
|
55
|
+
option :private_network,
|
56
|
+
:long => "--private-network",
|
57
|
+
:description => "Use the private IP for bootstrapping rather than the public IP",
|
58
|
+
:boolean => true,
|
59
|
+
:default => false
|
60
|
+
|
61
|
+
option :ssh_user,
|
62
|
+
:short => "-x USERNAME",
|
63
|
+
:long => "--ssh-user USERNAME",
|
64
|
+
:description => "The ssh username",
|
65
|
+
:default => "root"
|
66
|
+
|
67
|
+
option :identity_file,
|
68
|
+
:short => "-i IDENTITY_FILE",
|
69
|
+
:long => "--identity-file IDENTITY_FILE",
|
70
|
+
:description => "The SSH identity file used for authentication"
|
71
|
+
|
72
|
+
option :chef_node_name,
|
73
|
+
:short => "-N NAME",
|
74
|
+
:long => "--node-name NAME",
|
75
|
+
:description => "The Chef node name for your new node"
|
76
|
+
|
77
|
+
option :prerelease,
|
78
|
+
:long => "--prerelease",
|
79
|
+
:description => "Install the pre-release chef gems"
|
80
|
+
|
81
|
+
option :distro,
|
82
|
+
:short => "-d DISTRO",
|
83
|
+
:long => "--distro DISTRO",
|
84
|
+
:description => "Bootstrap a distro using a template",
|
85
|
+
:proc => Proc.new { |d| Chef::Config[:knife][:distro] = d },
|
86
|
+
:default => "chef-full"
|
87
|
+
|
88
|
+
option :no_host_key_verify,
|
89
|
+
:long => "--no-host-key-verify",
|
90
|
+
:description => "Disable host key verification",
|
91
|
+
:boolean => true,
|
92
|
+
:default => false
|
93
|
+
|
94
|
+
def is_linklocal(ip)
|
95
|
+
linklocal = IPAddr.new "169.254.0.0/16"
|
96
|
+
return linklocal.include?(ip)
|
97
|
+
end
|
98
|
+
|
99
|
+
def is_loopback(ip)
|
100
|
+
loopback = IPAddr.new "127.0.0.0/8"
|
101
|
+
return loopback.include?(ip)
|
102
|
+
end
|
66
103
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
104
|
+
def is_private(ip)
|
105
|
+
block_a = IPAddr.new "10.0.0.0/8"
|
106
|
+
block_b = IPAddr.new "172.16.0.0/12"
|
107
|
+
block_c = IPAddr.new "192.168.0.0/16"
|
108
|
+
return (block_a.include?(ip) or block_b.include?(ip) or block_c.include?(ip))
|
109
|
+
end
|
110
|
+
|
111
|
+
# wait for ssh to come up
|
112
|
+
def tcp_test_ssh(hostname)
|
113
|
+
tcp_socket = TCPSocket.new(hostname, 22)
|
114
|
+
readable = IO.select([tcp_socket], nil, nil, 5)
|
115
|
+
if readable
|
116
|
+
Chef::Log.debug("sshd accepting connections on #{hostname}, banner is #{tcp_socket.gets}")
|
117
|
+
yield
|
118
|
+
true
|
119
|
+
else
|
120
|
+
false
|
121
|
+
end
|
122
|
+
rescue Errno::ETIMEDOUT
|
123
|
+
false
|
124
|
+
rescue Errno::EPERM
|
125
|
+
false
|
126
|
+
rescue Errno::ECONNREFUSED
|
127
|
+
sleep 2
|
82
128
|
false
|
129
|
+
rescue Errno::EHOSTUNREACH
|
130
|
+
sleep 2
|
131
|
+
false
|
132
|
+
ensure
|
133
|
+
tcp_socket && tcp_socket.close
|
83
134
|
end
|
84
|
-
rescue Errno::ETIMEDOUT
|
85
|
-
false
|
86
|
-
rescue Errno::EPERM
|
87
|
-
false
|
88
|
-
rescue Errno::ECONNREFUSED
|
89
|
-
sleep 2
|
90
|
-
false
|
91
|
-
rescue Errno::EHOSTUNREACH
|
92
|
-
sleep 2
|
93
|
-
false
|
94
|
-
ensure
|
95
|
-
tcp_socket && tcp_socket.close
|
96
|
-
end
|
97
135
|
|
136
|
+
# Run Chef bootstrap script
|
137
|
+
def bootstrap_for_node(server, bootstrap_ip_address)
|
138
|
+
bootstrap = Chef::Knife::Bootstrap.new
|
139
|
+
Chef::Log.debug("Bootstrap name_args = [ #{bootstrap_ip_address} ]")
|
140
|
+
bootstrap.name_args = [ bootstrap_ip_address ]
|
141
|
+
Chef::Log.debug("Bootstrap run_list = #{config[:run_list]}")
|
142
|
+
bootstrap.config[:run_list] = config[:run_list]
|
143
|
+
Chef::Log.debug("Bootstrap ssh_user = #{config[:ssh_user]}")
|
144
|
+
bootstrap.config[:ssh_user] = config[:ssh_user]
|
145
|
+
Chef::Log.debug("Bootstrap identity_file = #{config[:identity_file]}")
|
146
|
+
bootstrap.config[:identity_file] = config[:identity_file]
|
147
|
+
Chef::Log.debug("Bootstrap chef_node_name = #{config[:chef_node_name]}")
|
148
|
+
bootstrap.config[:chef_node_name] = config[:chef_node_name] || server.id
|
149
|
+
Chef::Log.debug("Bootstrap prerelease = #{config[:prerelease]}")
|
150
|
+
bootstrap.config[:prerelease] = config[:prerelease]
|
151
|
+
Chef::Log.debug("Bootstrap distro = #{config[:distro]}")
|
152
|
+
bootstrap.config[:distro] = config[:distro]
|
153
|
+
#Chef::Log.debug("Bootstrap use_sudo = #{config[:use_sudo]}")
|
154
|
+
#bootstrap.config[:use_sudo] = true
|
155
|
+
Chef::Log.debug("Bootstrap environment = #{config[:environment]}")
|
156
|
+
bootstrap.config[:environment] = config[:environment]
|
157
|
+
Chef::Log.debug("Bootstrap no_host_key_verify = #{config[:no_host_key_verify]}")
|
158
|
+
bootstrap.config[:no_host_key_verify] = config[:no_host_key_verify]
|
159
|
+
|
160
|
+
bootstrap
|
161
|
+
end
|
98
162
|
|
99
|
-
|
100
|
-
|
101
|
-
bootstrap = Chef::Knife::Bootstrap.new
|
102
|
-
Chef::Log.debug("Bootstrap name_args = [ #{server.ips.first} ]")
|
103
|
-
bootstrap.name_args = [ server.ips.first ]
|
104
|
-
Chef::Log.debug("Bootstrap run_list = #{config[:run_list]}")
|
105
|
-
bootstrap.config[:run_list] = config[:run_list]
|
106
|
-
Chef::Log.debug("Bootstrap ssh_user = #{config[:ssh_user]}")
|
107
|
-
bootstrap.config[:ssh_user] = config[:ssh_user]
|
108
|
-
Chef::Log.debug("Bootstrap identity_file = #{config[:identity_file]}")
|
109
|
-
bootstrap.config[:identity_file] = config[:identity_file]
|
110
|
-
Chef::Log.debug("Bootstrap chef_node_name = #{config[:chef_node_name]}")
|
111
|
-
bootstrap.config[:chef_node_name] = config[:chef_node_name] || server.id
|
112
|
-
Chef::Log.debug("Bootstrap prerelease = #{config[:prerelease]}")
|
113
|
-
bootstrap.config[:prerelease] = config[:prerelease]
|
114
|
-
Chef::Log.debug("Bootstrap distro = #{config[:distro]}")
|
115
|
-
bootstrap.config[:distro] = config[:distro]
|
116
|
-
#Chef::Log.debug("Bootstrap use_sudo = #{config[:use_sudo]}")
|
117
|
-
#bootstrap.config[:use_sudo] = true
|
118
|
-
Chef::Log.debug("Bootstrap environment = #{config[:environment]}")
|
119
|
-
bootstrap.config[:environment] = config[:environment]
|
120
|
-
Chef::Log.debug("Bootstrap no_host_key_verify = #{config[:no_host_key_verify]}")
|
121
|
-
bootstrap.config[:no_host_key_verify] = config[:no_host_key_verify]
|
122
|
-
|
123
|
-
bootstrap
|
124
|
-
end
|
163
|
+
def run
|
164
|
+
$stdout.sync = true
|
125
165
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
166
|
+
# add some validation here ala knife-ec2
|
167
|
+
|
168
|
+
node_name = config[:chef_node_name] || config[:server_name]
|
169
|
+
|
170
|
+
puts ui.color("Creating machine #{node_name}", :cyan)
|
171
|
+
|
172
|
+
server = connection.servers.create(
|
173
|
+
:name => node_name,
|
174
|
+
:dataset => config[:dataset],
|
175
|
+
:package => config[:package]
|
176
|
+
)
|
177
|
+
|
178
|
+
print "\n#{ui.color("Waiting for server", :magenta)}"
|
179
|
+
server.wait_for { print "."; ready? }
|
180
|
+
|
181
|
+
#which IP address to bootstrap
|
182
|
+
bootstrap_ip_addresses = server.ips.select{|ip|
|
183
|
+
ip and not(is_loopback(ip) or is_linklocal(ip))
|
184
|
+
}
|
185
|
+
|
186
|
+
if bootstrap_ip_addresses.count == 1
|
187
|
+
bootstrap_ip_address = bootstrap_ip_addresses.first
|
140
188
|
else
|
141
|
-
|
189
|
+
if config[:private_network]
|
190
|
+
bootstrap_ip_address = bootstrap_ip_addresses.find{|ip| is_private(ip)}
|
191
|
+
else
|
192
|
+
bootstrap_ip_address = bootstrap_ip_addresses.find{|ip| not is_private(ip)}
|
193
|
+
end
|
142
194
|
end
|
195
|
+
|
196
|
+
Chef::Log.debug("Bootstrap IP Address #{bootstrap_ip_address}")
|
197
|
+
if bootstrap_ip_address.nil?
|
198
|
+
ui.error("No IP address available for bootstrapping.")
|
199
|
+
exit 1
|
200
|
+
end
|
201
|
+
|
202
|
+
puts ui.color("attempting to bootstrap on #{bootstrap_ip_address}", :cyan)
|
203
|
+
|
204
|
+
print(".") until tcp_test_ssh(bootstrap_ip_address) {
|
205
|
+
sleep @initial_sleep_delay ||= 10
|
206
|
+
puts("done")
|
207
|
+
}
|
208
|
+
|
209
|
+
bootstrap_for_node(server, bootstrap_ip_address).run
|
210
|
+
|
211
|
+
puts ui.color("Created machine:", :cyan)
|
212
|
+
msg_pair("ID", server.id.to_s)
|
213
|
+
msg_pair("Name", server.name)
|
214
|
+
msg_pair("State", server.state)
|
215
|
+
msg_pair("Type", server.type)
|
216
|
+
msg_pair("Dataset", server.dataset)
|
217
|
+
msg_pair("IP's", server.ips)
|
218
|
+
end
|
219
|
+
|
220
|
+
# Run Chef bootstrap script
|
221
|
+
def bootstrap_for_node(server, bootstrap_ip_address)
|
222
|
+
bootstrap = Chef::Knife::Bootstrap.new
|
223
|
+
Chef::Log.debug("Bootstrap name_args = [ #{bootstrap_ip_address} ]")
|
224
|
+
bootstrap.name_args = [ bootstrap_ip_address ]
|
225
|
+
Chef::Log.debug("Bootstrap run_list = #{config[:run_list]}")
|
226
|
+
bootstrap.config[:run_list] = config[:run_list]
|
227
|
+
Chef::Log.debug("Bootstrap ssh_user = #{config[:ssh_user]}")
|
228
|
+
bootstrap.config[:ssh_user] = config[:ssh_user]
|
229
|
+
Chef::Log.debug("Bootstrap identity_file = #{config[:identity_file]}")
|
230
|
+
bootstrap.config[:identity_file] = config[:identity_file]
|
231
|
+
Chef::Log.debug("Bootstrap chef_node_name = #{config[:chef_node_name]}")
|
232
|
+
bootstrap.config[:chef_node_name] = config[:chef_node_name] || server.id
|
233
|
+
Chef::Log.debug("Bootstrap prerelease = #{config[:prerelease]}")
|
234
|
+
bootstrap.config[:prerelease] = config[:prerelease]
|
235
|
+
Chef::Log.debug("Bootstrap distro = #{config[:distro]}")
|
236
|
+
bootstrap.config[:distro] = config[:distro]
|
237
|
+
#Chef::Log.debug("Bootstrap use_sudo = #{config[:use_sudo]}")
|
238
|
+
#bootstrap.config[:use_sudo] = true
|
239
|
+
Chef::Log.debug("Bootstrap environment = #{config[:environment]}")
|
240
|
+
bootstrap.config[:environment] = config[:environment]
|
241
|
+
Chef::Log.debug("Bootstrap no_host_key_verify = #{config[:no_host_key_verify]}")
|
242
|
+
bootstrap.config[:no_host_key_verify] = config[:no_host_key_verify]
|
243
|
+
|
244
|
+
bootstrap
|
143
245
|
end
|
144
246
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
msg("Type", server.type)
|
150
|
-
msg("Dataset", server.dataset)
|
151
|
-
msg("IP's", server.ips)
|
152
|
-
puts ui.color("attempting to bootstrap on #{server.ips.first}", :cyan)
|
153
|
-
|
154
|
-
print(".") until tcp_test_ssh(server.ips.first) {
|
155
|
-
sleep 1
|
156
|
-
puts("done")
|
157
|
-
}
|
158
|
-
bootstrap_for_node(server).run
|
159
|
-
exit 0
|
160
|
-
end
|
161
|
-
|
162
|
-
def msg(label, value = nil)
|
163
|
-
if value && !value.empty?
|
164
|
-
puts "#{ui.color(label, :cyan)}: #{value}"
|
247
|
+
def msg_pair(label, value = nil)
|
248
|
+
if value && !value.empty?
|
249
|
+
puts "#{ui.color(label, :cyan)}: #{value}"
|
250
|
+
end
|
165
251
|
end
|
166
252
|
end
|
167
253
|
end
|
168
254
|
end
|
255
|
+
|
@@ -1,72 +1,74 @@
|
|
1
|
-
require
|
1
|
+
require 'chef/knife/joyent_base'
|
2
2
|
|
3
3
|
require 'chef/api_client'
|
4
4
|
|
5
|
-
|
6
|
-
class
|
5
|
+
class Chef
|
6
|
+
class Knife
|
7
|
+
class JoyentServerDelete < Knife
|
7
8
|
|
8
|
-
|
9
|
+
include Knife::JoyentBase
|
9
10
|
|
10
|
-
|
11
|
+
banner 'knife joyent server delete <server_id>'
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
def run
|
14
|
+
unless name_args.size === 1
|
15
|
+
show_usage
|
16
|
+
exit 1
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
+
id = name_args.first
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
21
|
+
server = self.connection.servers.get(id)
|
22
|
+
|
23
|
+
msg("ID", server.id.to_s)
|
24
|
+
msg("Name", server.name)
|
25
|
+
msg("State", server.state)
|
26
|
+
msg("Type", server.type)
|
27
|
+
msg("Dataset", server.dataset)
|
28
|
+
msg("IP's", server.ips)
|
29
|
+
|
30
|
+
unless server
|
31
|
+
puts ui.error("Unable to locate server: #{id}")
|
32
|
+
exit 1
|
33
|
+
end
|
34
|
+
|
35
|
+
puts "\n"
|
36
|
+
confirm("Do you really want to delete this server")
|
37
|
+
|
38
|
+
puts ui.color("Stopping server...", :cyan)
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
else
|
42
|
-
if server.stop
|
43
|
-
puts ui.color("Server stopped", :cyan)
|
40
|
+
if server.stopped?
|
41
|
+
puts ui.color("Server #{id} is already stopped", :cyan)
|
44
42
|
else
|
45
|
-
|
46
|
-
|
43
|
+
if server.stop
|
44
|
+
puts ui.color("Server stopped", :cyan)
|
45
|
+
else
|
46
|
+
puts ui.error("Failed to stop server")
|
47
|
+
exit 1
|
48
|
+
end
|
47
49
|
end
|
48
|
-
end
|
49
|
-
|
50
|
-
server.destroy
|
51
|
-
puts ui.color("Deleted server: #{id}", :cyan)
|
52
|
-
|
53
|
-
puts "\n"
|
54
|
-
confirm("Delete client and node for #{server.name}?")
|
55
50
|
|
56
|
-
|
57
|
-
|
58
|
-
node.destroy
|
59
|
-
ui.warn("Deleted node named #{node.name}")
|
51
|
+
server.destroy
|
52
|
+
puts ui.color("Deleted server: #{id}", :cyan)
|
60
53
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
54
|
+
puts "\n"
|
55
|
+
confirm("Delete client and node for #{server.name}?")
|
56
|
+
|
57
|
+
node = Chef::Node.load(server.name)
|
58
|
+
puts "deleting node #{node.name}"
|
59
|
+
node.destroy
|
60
|
+
ui.warn("Deleted node named #{node.name}")
|
61
|
+
|
62
|
+
client = Chef::ApiClient.load(server.name)
|
63
|
+
puts "deleting client #{client.name}"
|
64
|
+
client.destroy
|
65
|
+
ui.warn("Deleted client named #{client.name}")
|
66
|
+
end
|
67
|
+
|
68
|
+
def msg(label, value)
|
69
|
+
if value && !value.empty?
|
70
|
+
puts "#{ui.color(label, :cyan)}: #{value}"
|
71
|
+
end
|
70
72
|
end
|
71
73
|
end
|
72
74
|
end
|
@@ -1,50 +1,53 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
1
|
+
require 'chef/knife/joyent_base'
|
2
|
+
|
3
|
+
class Chef
|
4
|
+
class Knife
|
5
|
+
class JoyentServerList < Knife
|
6
|
+
|
7
|
+
include Knife::JoyentBase
|
8
|
+
|
9
|
+
banner "knife joyent server list <options>"
|
10
|
+
|
11
|
+
def run
|
12
|
+
servers = [
|
13
|
+
ui.color('ID', :bold),
|
14
|
+
ui.color('Name', :bold),
|
15
|
+
ui.color('State', :bold),
|
16
|
+
ui.color('Type', :bold),
|
17
|
+
ui.color('Image', :bold),
|
18
|
+
ui.color('IPs', :bold),
|
19
|
+
ui.color('RAM', :bold),
|
20
|
+
ui.color('Disk', :bold),
|
21
|
+
ui.color('Tags', :bold)
|
22
|
+
]
|
23
|
+
|
24
|
+
self.connection.servers.sort do |a, b|
|
25
|
+
(a.name || '') <=> (b.name || '')
|
26
|
+
end.each do |s|
|
27
|
+
servers << s.id.to_s
|
28
|
+
servers << s.name
|
29
|
+
|
30
|
+
servers << case s.state
|
31
|
+
when 'running'
|
32
|
+
ui.color(s.state, :green)
|
33
|
+
when 'stopping', 'provisioning'
|
34
|
+
ui.color(s.state, :yellow)
|
35
|
+
when 'stopped'
|
36
|
+
ui.color(s.state, :red)
|
37
|
+
else
|
38
|
+
ui.color('unknown', :red)
|
39
|
+
end
|
40
|
+
|
41
|
+
servers << s.type
|
42
|
+
servers << s.dataset
|
43
|
+
servers << s.ips.join(" ")
|
44
|
+
servers << "#{s.memory/1024} GB".to_s
|
45
|
+
servers << "#{s.disk/1024} GB".to_s
|
46
|
+
servers << s.tags.map { |k, v| "#{k}:#{v}" }.join(' ')
|
38
47
|
end
|
39
48
|
|
40
|
-
servers
|
41
|
-
servers << s.dataset
|
42
|
-
servers << s.ips.join(" ")
|
43
|
-
servers << "#{s.memory/1024} GB".to_s
|
44
|
-
servers << "#{s.disk/1024} GB".to_s
|
49
|
+
puts ui.list(servers, :uneven_columns_across, 9)
|
45
50
|
end
|
46
|
-
|
47
|
-
puts ui.list(servers, :uneven_columns_across, 8)
|
48
51
|
end
|
49
52
|
end
|
50
53
|
end
|