knife-oraclevm 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,275 @@
1
+ #
2
+ # Author:: Geoff O'Callaghan (<geoffocallaghan@gmail.com>)
3
+ # Contributor::
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+
7
+ require 'chef/knife'
8
+
9
+ # Base class for OracleVM knife commands
10
+ class Chef
11
+ class Knife
12
+ class BaseOraclevmCommand < Knife
13
+
14
+ deps do
15
+ require 'chef/knife/bootstrap'
16
+ Chef::Knife::Bootstrap.load_deps
17
+ require 'fog'
18
+ require 'socket'
19
+ require 'net/ssh'
20
+ require 'readline'
21
+ require 'chef/json_compat'
22
+ end
23
+
24
+ def self.get_common_options
25
+ unless defined? $default
26
+ $default = Hash.new
27
+ end
28
+
29
+ option :ovmmgr_user,
30
+ :short => "-u USERNAME",
31
+ :long => "--ovmmgruser USERNAME",
32
+ :description => "The username for OracleVM Manager"
33
+ $default[:ovmmgr_user] = "admin"
34
+
35
+ option :ovmmgr_pass,
36
+ :short => "-p PASSWORD",
37
+ :long => "--ovmmgrpass PASSWORD",
38
+ :description => "The password for OracleVM Manager"
39
+
40
+ option :ovmmgr_host,
41
+ :long => "--ovmmgrhost HOST",
42
+ :description => "The OracleVM Manager host"
43
+
44
+ option :ovmmgr_port,
45
+ :long => "--ovmmgrport PORT",
46
+ :description => "The OracleVM Manager CLI port number to use"
47
+ $default[:ovmmgr_port] = 10000
48
+ end
49
+
50
+ def get_config(key)
51
+ key = key.to_sym
52
+ rval = config[key] || Chef::Config[:knife][key] || $default[key]
53
+ Chef::Log.debug("value for config item #{key}: #{rval}")
54
+ rval
55
+ end
56
+
57
+ def get_cli_connection
58
+
59
+ conn_opts = {
60
+ :host => get_config(:ovmmgr_host),
61
+ :path => get_config(:ovmmgr_path),
62
+ :port => get_config(:ovmmgr_port),
63
+ :user => get_config(:ovmmgr_user),
64
+ :password => get_config(:ovmmgr_pass),
65
+ }
66
+
67
+ # Grab the ovmmgr host from the command line
68
+ # if tt is not in the config file
69
+ if not conn_opts[:host]
70
+ conn_opts[:host] = get_host
71
+ end
72
+ # Grab the password from the command line
73
+ # if tt is not in the config file
74
+ if not conn_opts[:password]
75
+ conn_opts[:password] = get_password
76
+ end
77
+ if conn_opts[:port]
78
+ Chef::Log.debug("Waiting for port #{conn_opts[:port]} on #{conn_opts[:host]}...")
79
+ tcp_test_port(conn_opts[:host],conn_opts[:port])
80
+ end
81
+ return conn_opts
82
+ end
83
+
84
+ def get_host
85
+ @host ||= ui.ask("Enter your OVM Mgr Host: ") { |q| q.echo = true }
86
+ end
87
+
88
+ def get_password
89
+ @password ||= ui.ask("Enter your password: ") { |q| q.echo = false }
90
+ end
91
+
92
+ def get_vm(vmname)
93
+ return retval
94
+ end
95
+
96
+
97
+ def fatal_exit(msg)
98
+ ui.fatal(msg)
99
+ exit 1
100
+ end
101
+
102
+ def tcp_test_port(hostname,port)
103
+ tcp_socket = TCPSocket.new(hostname, port)
104
+ readable = IO.select([tcp_socket], nil, nil, 5)
105
+ if readable
106
+ Chef::Log.debug("accepting connections on #{hostname}, banner is #{tcp_socket.gets}")
107
+ true
108
+ else
109
+ false
110
+ end
111
+ rescue Errno::ETIMEDOUT
112
+ false
113
+ rescue Errno::EPERM
114
+ false
115
+ rescue Errno::ECONNREFUSED
116
+ sleep 2
117
+ false
118
+ rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH
119
+ sleep 2
120
+ false
121
+ ensure
122
+ tcp_socket && tcp_socket.close
123
+ end
124
+
125
+ #
126
+ # show_vm_status, given a vmname return the operational status of the vm
127
+ #
128
+ def show_vm_status(vmname)
129
+ current = {:errormsg => "", :status => "", :time => "", :vmstatus => ""}
130
+
131
+ conn_opts=get_cli_connection
132
+ Chef::Log.debug("#{conn_opts[:host]}...show vm name=#{vmname}")
133
+ Net::SSH.start( conn_opts[:host], conn_opts[:user], :password => conn_opts[:password], :port => conn_opts[:port] ) do|ssh|
134
+ output = ssh.exec!("show vm name=#{vmname}")
135
+ output.each_line do |line|
136
+ if line.match(/Status:/)
137
+ current[:status]=line.split[1].strip
138
+ elsif line.match(/Time:/)
139
+ line["Time: "]=""
140
+ current[:time]=line.strip
141
+ elsif line.match(/ Status = /)
142
+ current[:vmstatus]=line.split('=')[1].strip
143
+ elsif line.match(/Error Msg:/)
144
+ line["Error Msg: "]=""
145
+ current[:errormsg]=line.strip
146
+ end
147
+ end
148
+ end
149
+ return current
150
+ end
151
+
152
+ #
153
+ # start_vm, given a vmname issue a start request
154
+ #
155
+ def start_vm(vmname)
156
+ current = {:errormsg => "", :status => "", :time => "", :vmstatus => ""}
157
+
158
+ conn_opts=get_cli_connection
159
+ Chef::Log.debug("#{conn_opts[:host]}...show vm name=#{vmname}")
160
+ Net::SSH.start( conn_opts[:host], conn_opts[:user], :password => conn_opts[:password], :port => conn_opts[:port] ) do|ssh|
161
+ output = ssh.exec!("start vm name=#{vmname}")
162
+ output.each_line do |line|
163
+ if line.match(/Status:/)
164
+ current[:status]=line.split[1].strip
165
+ elsif line.match(/Time:/)
166
+ line["Time: "]=""
167
+ current[:time]=line.strip
168
+ elsif line.match(/Error Msg:/)
169
+ line["Error Msg: "]=""
170
+ current[:errormsg]=line.strip
171
+ end
172
+ end
173
+ end
174
+ return current
175
+ end
176
+ #
177
+ # stop_vm, given a vmname issue a stop request
178
+ #
179
+ def stop_vm(vmname)
180
+ current = {:errormsg => "", :status => "", :time => "", :vmstatus => ""}
181
+
182
+ conn_opts=get_cli_connection
183
+ Chef::Log.debug("#{conn_opts[:host]}...show vm name=#{vmname}")
184
+ Net::SSH.start( conn_opts[:host], conn_opts[:user], :password => conn_opts[:password], :port => conn_opts[:port] ) do|ssh|
185
+ output = ssh.exec!("stop vm name=#{vmname}")
186
+ output.each_line do |line|
187
+ if line.match(/Status:/)
188
+ current[:status]=line.split[1].strip
189
+ elsif line.match(/Time:/)
190
+ line["Time: "]=""
191
+ current[:time]=line.strip
192
+ elsif line.match(/Error Msg:/)
193
+ line["Error Msg: "]=""
194
+ current[:errormsg]=line.strip
195
+ end
196
+ end
197
+ end
198
+ return current
199
+ end
200
+ #
201
+ # suspend_vm, given a vmname issue a suspend request
202
+ #
203
+ def suspend_vm(vmname)
204
+ current = {:errormsg => "", :status => "", :time => "", :vmstatus => ""}
205
+
206
+ conn_opts=get_cli_connection
207
+ Chef::Log.debug("#{conn_opts[:host]}...show vm name=#{vmname}")
208
+ Net::SSH.start( conn_opts[:host], conn_opts[:user], :password => conn_opts[:password], :port => conn_opts[:port] ) do|ssh|
209
+ output = ssh.exec!("suspend vm name=#{vmname}")
210
+ output.each_line do |line|
211
+ if line.match(/Status:/)
212
+ current[:status]=line.split[1].strip
213
+ elsif line.match(/Time:/)
214
+ line["Time: "]=""
215
+ current[:time]=line.strip
216
+ elsif line.match(/Error Msg:/)
217
+ line["Error Msg: "]=""
218
+ current[:errormsg]=line.strip
219
+ end
220
+ end
221
+ end
222
+ return current
223
+ end
224
+ #
225
+ # resume_vm, given a vmname issue a resume request
226
+ #
227
+ def resume_vm(vmname)
228
+ current = {:errormsg => "", :status => "", :time => "", :vmstatus => ""}
229
+
230
+ conn_opts=get_cli_connection
231
+ Chef::Log.debug("#{conn_opts[:host]}...show vm name=#{vmname}")
232
+ Net::SSH.start( conn_opts[:host], conn_opts[:user], :password => conn_opts[:password], :port => conn_opts[:port] ) do|ssh|
233
+ output = ssh.exec!("resume vm name=#{vmname}")
234
+ output.each_line do |line|
235
+ if line.match(/Status:/)
236
+ current[:status]=line.split[1].strip
237
+ elsif line.match(/Time:/)
238
+ line["Time: "]=""
239
+ current[:time]=line.strip
240
+ elsif line.match(/Error Msg:/)
241
+ line["Error Msg: "]=""
242
+ current[:errormsg]=line.strip
243
+ end
244
+ end
245
+ end
246
+ return current
247
+ end
248
+ #
249
+ # restart_vm, given a vmname issue a restart request
250
+ #
251
+ def restart_vm(vmname)
252
+ current = {:errormsg => "", :status => "", :time => "", :vmstatus => ""}
253
+
254
+ conn_opts=get_cli_connection
255
+ Chef::Log.debug("#{conn_opts[:host]}...show vm name=#{vmname}")
256
+ Net::SSH.start( conn_opts[:host], conn_opts[:user], :password => conn_opts[:password], :port => conn_opts[:port] ) do|ssh|
257
+ output = ssh.exec!("restart vm name=#{vmname}")
258
+ output.each_line do |line|
259
+ if line.match(/Status:/)
260
+ current[:status]=line.split[1].strip
261
+ elsif line.match(/Time:/)
262
+ line["Time: "]=""
263
+ current[:time]=line.strip
264
+ elsif line.match(/Error Msg:/)
265
+ line["Error Msg: "]=""
266
+ current[:errormsg]=line.strip
267
+ end
268
+ end
269
+ end
270
+ return current
271
+ end
272
+
273
+ end
274
+ end
275
+ end
@@ -0,0 +1,102 @@
1
+ #
2
+ # Author:: Geoff O'Callaghan (<geoffocallaghan@gmail.com>)
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+
6
+ require 'chef/knife'
7
+ require 'chef/knife/BaseOraclevmCommand'
8
+ require 'netaddr'
9
+ require 'net/ssh'
10
+
11
+ # Manage power state of a virtual machine
12
+ class Chef::Knife::OraclevmVmState < Chef::Knife::BaseOraclevmCommand
13
+
14
+ banner "knife oraclevm vm state VMNAME (options)"
15
+
16
+ get_common_options
17
+
18
+ option :state,
19
+ :short => "-s STATE",
20
+ :long => "--state STATE",
21
+ :description => "The power state to transition the VM into; one of on|off|suspend|resume|restart"
22
+
23
+
24
+ def run
25
+
26
+ $stdout.sync = true
27
+
28
+ vmname = @name_args[0]
29
+ if vmname.nil?
30
+ show_usage
31
+ ui.fatal("You must specify a virtual machine name")
32
+ exit 1
33
+ end
34
+ current=show_vm_status(vmname)
35
+ Chef::Log.debug("Status = #{current[:status]}. Time = #{current[:time]}. VM Status = #{current[:vmstatus]}.")
36
+
37
+ state=get_config(:state)
38
+
39
+ if current[:status]=="Success"
40
+ if not state
41
+ puts "Virtual machine #{vmname} is in state #{current[:vmstatus]}"
42
+ else
43
+ case current[:vmstatus]
44
+ when 'Running'
45
+ case state
46
+ when 'on'
47
+ puts "Virtual machine #{vmname} was already powered on"
48
+ when 'off'
49
+ result=stop_vm(vmname)
50
+ puts "Power off virtual machine #{vmname} : #{result[:status]}"
51
+ when 'suspend'
52
+ result=suspend_vm(vmname)
53
+ puts "Suspend virtual machine #{vmname} : #{result[:status]}"
54
+ when 'restart'
55
+ result=restart_vm(vmname)
56
+ puts "Restart virtual machine #{vmname} : #{result[:status]}"
57
+ when 'resume'
58
+ puts "Cannot Resume virtual machine #{vmname} as it is on"
59
+ else
60
+ show_usage
61
+ end
62
+ when 'Stopped'
63
+ case state
64
+ when 'on'
65
+ result=start_vm(vmname)
66
+ puts "Power on virtual machine #{vmname} : #{result[:status]}"
67
+ when 'off'
68
+ puts "virtual machine #{vmname} was already off"
69
+ when 'suspend'
70
+ puts "Cannot Suspend virtual machine #{vmname} as it is off"
71
+ when 'restart'
72
+ puts "Cannot Restrt virtual machine #{vmname} as it is off"
73
+ when 'resume'
74
+ puts "Cannot Resume virtual machine #{vmname} as it is off"
75
+ else
76
+ show_usage
77
+ end
78
+ when 'Suspended'
79
+ case state
80
+ when 'on'
81
+ puts "Cannot Power on virtual machine #{vmname} as it is suspended"
82
+ when 'off'
83
+ puts "Cannot Power off virtual machine #{vmname} as it is suspended"
84
+ when 'suspend'
85
+ puts "Cannot Suspend virtual machine #{vmname} as it is already suspended"
86
+ when 'restart'
87
+ puts "Cannot Restart virtual machine #{vmname} as it is suspended"
88
+ when 'resume'
89
+ result=resume_vm(vmname)
90
+ puts "Resume virtual machine #{vmname} : #{result[:status]}"
91
+ else
92
+ show_usage
93
+ end
94
+ else
95
+ puts "I don't know what a state of #{state} is on #{vmname}"
96
+ end
97
+ end
98
+ else
99
+ puts "Call to OVM CLI Failed with #{current[:errormsg]}"
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,4 @@
1
+ module KnifeOracleVM
2
+ VERSION = "0.0.1"
3
+ end
4
+
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: knife-oraclevm
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Geoff O'Callaghan
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2013-08-07 00:00:00 +10:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: netaddr
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 1
32
+ - 5
33
+ - 0
34
+ version: 1.5.0
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: chef
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 55
46
+ segments:
47
+ - 0
48
+ - 10
49
+ - 0
50
+ version: 0.10.0
51
+ type: :runtime
52
+ version_requirements: *id002
53
+ description: OracleVM Support for Chef's Knife Command
54
+ email: geoffocallaghan@gmail.com
55
+ executables: []
56
+
57
+ extensions: []
58
+
59
+ extra_rdoc_files: []
60
+
61
+ files:
62
+ - lib/knife-oraclevm/version.rb
63
+ - lib/chef/knife/BaseOraclevmCommand.rb
64
+ - lib/chef/knife/oraclevm_vm_state.rb
65
+ has_rdoc: true
66
+ homepage: http://github.com/gocallag/knife-oraclevm
67
+ licenses: []
68
+
69
+ post_install_message:
70
+ rdoc_options: []
71
+
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ hash: 3
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ hash: 3
89
+ segments:
90
+ - 0
91
+ version: "0"
92
+ requirements: []
93
+
94
+ rubyforge_project:
95
+ rubygems_version: 1.3.7
96
+ signing_key:
97
+ specification_version: 3
98
+ summary: OracleVM Support for Knife
99
+ test_files: []
100
+