Table of Contents

11h00 - TP « Encapsulation du parseur DHCP »

Navigation rapide : Lundi / Mardi / Mercredi / Jeudi / Vendredi Mémos : Perl / Python / Ruby

Finalité

Lorsque vous développez des composants logiciels, il peut être intéressant de les diffuser, pour vous même ou plus largement.
Vous allez réécrire le parseur DHCP sous forme objet.
Puis, si vous avez le temps, vous allez créer un paquet contenant une bibliothéque et un exécutable.

Enoncé

Nous allons créer 2 classes :

Pour cela, nous souhaitons que :

dhcpd.conf

 1: #
 2: # DHCP Server Configuration file.
 3: #   see /usr/share/doc/dhcp*/dhcpd.conf.sample
 4: #
 5: ddns-update-style ad-hoc;
 6: not authoritative;
 7: min-lease-time 43200;
 8: max-lease-time 43200;
 9:
10: subnet 172.19.45.0 netmask 255.255.255.0 {
11:         deny unknown-clients ;
12:         range 172.19.45.245 172.19.45.254;
13:         option subnet-mask              255.255.0.0;
14:         option domain-name-servers      172.19.45.18,172.19.45.20;
15:         option routers  172.19.0.254;
16: }
17:
18: host coquil-gw1 { hardware ethernet 00:1d:09:0a:33:db; fixed-address coquil-gw1; }
19: host fpl { hardware ethernet 00:26:b9:5d:32:32; fixed-address fpl; }
20: host roundcube
21: {
22:   hardware ethernet 00:16:36:09:2d:b9; fixed-address roundcube;
23: }
24: host deux { hardware ethernet 00:14:38:63:6E:F3; fixed-address deux; }
25: host visiteur1 { hardware ethernet 00:00:aa:be:93:5d; }
26: host visiteur2 { hardware ethernet 00:60:B0:D5:3B:05; }

stdout

 1: [user@tp-anf2012 ruby]$ ruby main.rb
 2: [#<DHCP::Host:0xb789c9a4
 3:   @attributes={"mac"=>"00:1d:09:0a:33:db", "ip"=>"coquil-gw1"},
 4:   @hostname="coquil-gw1">,
 5:  #<DHCP::Host:0xb789c724
 6:   @attributes={"mac"=>"00:26:b9:5d:32:32", "ip"=>"fpl"},
 7:   @hostname="fpl">,
 8:  #<DHCP::Host:0xb789c4a4
 9:   @attributes={"mac"=>"00:14:38:63:6E:F3", "ip"=>"deux"},
10:   @hostname="deux">,
11:  #<DHCP::Host:0xb789c224
12:   @attributes={"mac"=>"00:00:aa:be:93:5d"},
13:   @hostname="visiteur1">,
14:  #<DHCP::Host:0xb789c06c
15:   @attributes={"mac"=>"00:60:B0:D5:3B:05"},
16:   @hostname="visiteur2">]

Corrigé

main.rb

1: Dir[File.dirname(__FILE__) + "/dhcp/**/*.rb"].each do |lib| require lib end
2:
3: db = DHCP::Database.new
4: db.addPattern( "mac", 'hardware\s+ethernet\s+(\S+)' )
5: db.addPattern( "ip",  'fixed-address\s+(\S+)'       )
6: db.load('dhcpd.conf')
7: db.dump

dhcp/host.rb

 1: module DHCP; class Host
 2:         def initialize(hostname,attributes)
 3:                 if hostname.kind_of?(String) then
 4:                         @hostname   = hostname
 5:                 else
 6:                         raise "hostname is of type '#{hostname.class}', must be a String"
 7:                 end
 8:                 if attributes.kind_of?(Hash) then
 9:                         @attributes = attributes
10:                 else
11:                         raise "attributes is of type '#{attributes.class}', must be an Hash"
12:                 end
13:         end
14: end; end
15:
16: if $0 == __FILE__ then
17:         require 'pp'
18:         pp DHCP::Host.new(
19:                 'toto',
20:                 {
21:                         'mac' => '00:11:22:33:44:55',
22:                         'ip'  => '192.168.0.1'
23:                 }
24:         )
25:         begin
26:                 DHCP::Host.new(
27:                         :toto,
28:                         {
29:                                 'mac' => '00:11:22:33:44:55',
30:                                 'ip'  => '192.168.0.1'
31:                         }
32:                 )
33:         rescue Exception => e
34:                 pp e
35:         end
36:         begin
37:                 DHCP::Host.new(
38:                         'toto',
39:                         [
40:                                 ['mac','00:11:22:33:44:55'],
41:                                 ['ip','192.168.0.1']
42:                         ]
43:                 )
44:         rescue Exception => e
45:                 pp e
46:         end
47:
48: end

dhcp/database.rb

 1: require 'pp'
 2:
 3: module DHCP; class Database
 4:         def initialize()            @pattern,@hosts = {},[] end
 5:         def addPattern(key,pattern) @pattern[key]=pattern   end
 6:         def dump()                  pp @hosts               end
 7:         def load(filename)
 8:                 host  = /host\s*(\S+)\s*\{\s*(.*?)\s*\}/
 9:                 lines = File.readlines(filename)
10:                 stream = lines.collect! do |line|
11:                         line.chomp!
12:                         (line.match(/#/).nil?) ? line : nil;
13:                 end.compact.join('')
14:                 @hosts=stream.scan(host)
15:                 @hosts.collect! do |hostname,context|
16:                         attributes = {}
17:                         fields = context.split(';')
18:                         fields.each do |field|
19:                                 @pattern.each do |key,pattern|
20:                                         attributes[key] = $1 unless field.chomp.match(pattern).nil?
21:                                 end
22:                         end
23:                         DHCP::Host.new(hostname,attributes)
24:                 end
25:         end
26: end; end

Version

$Id: mardi_objet_corrige_ruby.txt 567 2012-05-21 07:29:58Z aicardi $