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 :

  • une classe DHCP::Host, modélisant une entrée host du fichier dhcpd.conf
  • une classe DHCP::Database, modélisant l'ensemble des informations parsées du fichier dhcpd.conf (c'est-à-dire l'ensemble des entrées host).

Pour cela, nous souhaitons que :

  • DHCP::Host dispose d'un constructeur avec 2 paramètres : le nom du host, et un hash pour les attributs
  • DHCP::Database dispose d'une méthode addPattern qui ajoute un nouvel attribut à extraire,
  • DHCP::Database dispose d'une méthode load qui parse le fichier dont le nom est fourni en argument,
  • DHCP::Database dispose d'une méthode dump qui visualise le contenu de la database.

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 $

mardi_objet_corrige_ruby.txt · Last modified: 2012/05/21 09:30 (external edit)
 
Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki