root/linen/trunk/examples/host.rb

Revision 564, 3.3 kB (checked in by bbleything, 2 months ago)
  • refix the copyright. doh.
  • Property svn:keywords set to Date Rev Author URL Id
Line 
1 #!/usr/bin/env ruby
2 #
3 # Demonstrates more complex arguments and commands than
4 # math.rb, including a two-phase command (edit).
5 #
6 # == Authors
7 #
8 # * Ben Bleything <bbleything@laika.com>
9 #
10 # == Copyright
11 #
12 # Copyright (c) 2008 LAIKA, Inc.
13 #
14 # This code released under the terms of the BSD license.
15 #
16 # == Version
17 #
18 #  $Id$
19 #
20
21 require 'rubygems'
22 require 'linen'
23 require 'ostruct'
24 require 'ping'
25 require 'socket'
26
27 class HostPlugin < Linen::Plugin
28     description "Inspect and check machines on your network."
29
30     argument :ip,
31              :prompt  => 'Please enter the IP address: ',
32              :regex   => /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/,
33              :process => lambda { |ip|
34                 ip.split('.').each do |octet|
35                     octet = octet.to_f
36
37                     fail "#{ip} is not valid: #{octet.to_i} must be between 0 and 255." if octet < 0 or octet > 255
38                 end
39
40                 return ip
41              }
42            
43     argument :hostname,
44              :prompt => 'Please enter the hostname: ',
45              :regex  => /^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$/
46              # pattern yoinked from http://regexlib.com/REDetails.aspx?regexp_id=391
47    
48     argument :mac,
49              :prompt => 'Please enter the MAC address: ',
50              :process => proc {|mac|
51                 stripped_mac = mac.gsub( /:/, '' )
52                 fail "MAC Address is too short." unless stripped_mac.length == 12
53                 fail "MAC Address contains invalid characters." unless stripped_mac =~ /^[0-9a-f]*/i
54
55                 return stripped_mac.scan( /../ ).join( ':' )
56             }
57
58     command :lookup do
59         help_message "Attempts to do a DNS lookup on the IP or hostname provided."
60
61         one_of :ip, :hostname
62
63         action do
64             ip_addr_info = Socket.getaddrinfo( ip, nil ) rescue nil
65             hn_addr_info = Socket.getaddrinfo( hostname, nil ) rescue nil
66
67             if ip_addr_info
68                 say "IP address #{ip} has hostname #{ip_addr_info[0][2]}."
69             elsif hn_addr_info
70                 say "Hostname '#{hostname}' has IP address #{hn_addr_info[0][3]}."
71             else
72                 say "You said something I do not understand.  I am sorry."
73             end
74         end
75     end
76
77     command :check do
78         help_message "Attempts to ping the IP or hostname provided."
79
80         one_of :ip, :hostname
81
82         require_confirmation
83
84         action do
85             to_check = ip || hostname
86
87             if Ping.pingecho( to_check, 5 )
88                 say "Host #{to_check} is alive!"
89             else
90                 say "Host #{to_check} appears to be dead :("
91             end
92         end
93     end
94    
95     command :edit, :lookup_first => true do
96         help_message "Lets you pretend to change the host's IP and MAC addresses.  Lookup by hostname."
97
98         lookup_by :hostname do |hostname|
99             out          = OpenStruct.new
100             out.hostname = hostname
101             out.ip       = Socket.getaddrinfo( hostname, nil )[0][3]
102            
103             # yoinked this from a thread on ruby-talk about UUID generation
104             # http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/242664
105             out.mac = ("%012x" % rand(1 << 12*4)).scan( /../ ).join( ':')
106            
107             # return
108             out
109         end
110        
111         inspect do
112             say "Hostname:    #{hostname.hostname}"
113             say "IP Address:  #{hostname.ip}"
114             say "MAC Address: #{hostname.mac}"
115         end
116        
117         editable_attributes :ip, :mac
118        
119         action do
120             say "If this was real, you would have just changed #{hostname.hostname}'s IP address to " +
121                 "#{ip.empty? ? 'nothing' : ip} and its MAC address to #{mac.empty? ? 'nothing' : mac}.  " +
122                 "It's not real, though, so rest easy."
123         end
124     end
125 end
126
127 Linen::CLI.prompt = "host > "
128 Linen.start
Note: See TracBrowser for help on using the browser.