remove $Log$
[freeside.git] / FS / FS / domain_record.pm
1 package FS::domain_record;
2
3 use strict;
4 use vars qw( @ISA );
5 #use FS::Record qw( qsearch qsearchs );
6 use FS::Record qw( qsearchs );
7 use FS::svc_domain;
8
9 @ISA = qw(FS::Record);
10
11 =head1 NAME
12
13 FS::domain_record - Object methods for domain_record records
14
15 =head1 SYNOPSIS
16
17   use FS::domain_record;
18
19   $record = new FS::domain_record \%hash;
20   $record = new FS::domain_record { 'column' => 'value' };
21
22   $error = $record->insert;
23
24   $error = $new_record->replace($old_record);
25
26   $error = $record->delete;
27
28   $error = $record->check;
29
30 =head1 DESCRIPTION
31
32 An FS::domain_record object represents an entry in a DNS zone.
33 FS::domain_record inherits from FS::Record.  The following fields are currently
34 supported:
35
36 =over 4
37
38 =item recnum - primary key
39
40 =item svcnum - Domain (see L<FS::svc_domain>) of this entry
41
42 =item reczone - partial (or full) zone for this entry
43
44 =item recaf - address family for this entry, currently only `IN' is recognized.
45
46 =item rectype - record type for this entry (A, MX, etc.)
47
48 =item recdata - data for this entry
49
50 =back
51
52 =head1 METHODS
53
54 =over 4
55
56 =item new HASHREF
57
58 Creates a new entry.  To add the example to the database, see L<"insert">.
59
60 Note that this stores the hash reference, not a distinct copy of the hash it
61 points to.  You can ask the object for a copy with the I<hash> method.
62
63 =cut
64
65 sub table { 'domain_record'; }
66
67 =item insert
68
69 Adds this record to the database.  If there is an error, returns the error,
70 otherwise returns false.
71
72 =cut
73
74 =item delete
75
76 Delete this record from the database.
77
78 =cut
79
80 =item replace OLD_RECORD
81
82 Replaces the OLD_RECORD with this one in the database.  If there is an error,
83 returns the error, otherwise returns false.
84
85 =cut
86
87 =item check
88
89 Checks all fields to make sure this is a valid example.  If there is
90 an error, returns the error, otherwise returns false.  Called by the insert
91 and replace methods.
92
93 =cut
94
95 # the check method should currently be supplied - FS::Record contains some
96 # data checking routines
97
98 sub check {
99   my $self = shift;
100
101   my $error = 
102     $self->ut_numbern('recnum')
103     || $self->ut_number('svcnum')
104   ;
105   return $error if $error;
106
107   return "Unknown svcnum (in svc_domain)"
108     unless qsearchs('svc_domain', { 'svcnum' => $self->svcnum } );
109
110   $self->reczone =~ /^(@|[a-z0-9\.\-]+)$/
111     or return "Illegal reczone: ". $self->reczone;
112   $self->reczone($1);
113
114   $self->recaf =~ /^(IN)$/ or return "Illegal recaf: ". $self->recaf;
115   $self->recaf($1);
116
117   $self->rectype =~ /^(SOA|NS|MX|A|PTR|CNAME)$/
118     or return "Illegal rectype (only SOA NS MX A PTR CNAME recognized): ".
119               $self->rectype;
120   $self->rectype($1);
121
122   if ( $self->rectype eq 'SOA' ) {
123     my $recdata = $self->recdata;
124     $recdata =~ s/\s+/ /g;
125     $recdata =~ /^([a-z0-9\.\-]+ [\w\-\+]+\.[a-z0-9\.\-]+ \( (\d+ ){5}\))$/
126       or return "Illegal data for SOA record: $recdata";
127     $self->recdata($1);
128   } elsif ( $self->rectype eq 'NS' ) {
129     $self->recdata =~ /^([a-z0-9\.\-]+)$/
130       or return "Illegal data for NS record: ". $self->recdata;
131     $self->recdata($1);
132   } elsif ( $self->rectype eq 'MX' ) {
133     $self->recdata =~ /^(\d+)\s+([a-z0-9\.\-]+)$/
134       or return "Illegal data for MX record: ". $self->recdata;
135     $self->recdata("$1 $2");
136   } elsif ( $self->rectype eq 'A' ) {
137     $self->recdata =~ /^((\d{1,3}\.){3}\d{1,3})$/
138       or return "Illegal data for A record: ". $self->recdata;
139     $self->recdata($1);
140   } elsif ( $self->rectype eq 'PTR' ) {
141     $self->recdata =~ /^([a-z0-9\.\-]+)$/
142       or return "Illegal data for PTR record: ". $self->recdata;
143     $self->recdata($1);
144   } elsif ( $self->rectype eq 'CNAME' ) {
145     $self->recdata =~ /^([a-z0-9\.\-]+)$/
146       or return "Illegal data for CNAME record: ". $self->recdata;
147     $self->recdata($1);
148   } else {
149     die "ack!";
150   }
151
152   ''; #no error
153 }
154
155 =back
156
157 =head1 VERSION
158
159 $Id: domain_record.pm,v 1.3 2001-08-21 02:44:47 ivan Exp $
160
161 =head1 BUGS
162
163 The data validation doesn't check everything it could.  In particular,
164 there is no protection against bad data that passes the regex, duplicate
165 SOA records, forgetting the trailing `.', impossible IP addersses, etc.  Of
166 course, it's still better than editing the zone files directly.  :)
167
168 =head1 SEE ALSO
169
170 L<FS::Record>, schema.html from the base documentation.
171
172 =cut
173
174 1;
175