abstracted the file chomping
[feisty_meow.git] / scripts / system / common_sysadmin.sh
1 #!/bin/bash
2
3 # this is a library of functions shared by scripts in the system folder.
4 #
5 # Author: Chris Koeritz
6
7 # removes a full domain from the DNS.
8 function remove_domain_file()
9 {
10   local domain_name="$1"; shift
11
12   local domain_file="/etc/bind/${domain_name}.conf"
13   if [ -f "$domain_file" ]; then
14     # don't destroy, just shuffle.
15     \mv -f "$domain_file" "/tmp/${domain_file}-old-${RANDOM}"
16     test_or_die "removing domain file: $domain_file"
17   fi
18 }
19
20 # creates a totally new domain config file for DNS.
21 function write_new_domain_file()
22 {
23   local domain_name="$1"; shift
24
25   local domain_file="/etc/bind/${domain_name}.conf"
26
27   echo "adding a totally new domain called $domain_name"
28   echo "using the config file: $domain_file"
29
30   if [ -f $domain_file ]; then
31     echo
32     echo "The domain configuration file already exists at:"
33     echo "  $domain_file"
34     echo "Since we don't want to tear that down if it has specialized configuration"
35     echo "data in it, we will just leave it in place and consider our job done."
36     echo
37     exit 0
38   fi
39
40   echo "
41 \$TTL 1W
42 @       IN SOA  @       ${SERVER_ADMIN}. (
43                 2017100801 ; serial
44                 2H ; refresh
45                 8M ; retry
46                 14D ; expiry
47                 6H ) ; minimum
48
49         IN NS           ${MAIN_NAME_SERVER}.
50         IN MX   10      ${MAIL_SERVER}.
51
52 ${domain_name}. IN A    ${IP_ADDRESS}
53         IN HINFO        \"linux server\" \"${DISTRO}\"
54 " >"$domain_file"
55
56   # our personalized configuration approach wants the real owner to own the file.
57   chown "$(logname):$(logname)" $domain_file
58   test_or_die "setting ownership on: $domain_file"
59 }
60
61 #hmmm: move to core!
62
63 # given a filename and a string to seek and a number of lines, then this
64 # function will remove the first occurrence of a line in the file that
65 # matches the string, and it will also axe the next N lines as specified.
66 function create_chomped_copy_of_file()
67 {
68   local filename="$1"; shift
69   local seeker="$1"; shift
70   local numlines=$1; shift
71
72   # make a backup first, oy.
73   \cp -f "$filename" "$filename.bkup-${RANDOM}" 
74   test_or_die "backing up file: $filename"
75
76   # make a temp file to write to before we move file into place in bind.
77   local new_version="/tmp/${filename}.bkup-${RANDOM}" 
78   \rm -f "$new_version"
79   test_or_die "cleaning out new version of file from: $new_version"
80
81   local line
82   local skip_count=0
83   while read line; do
84     # don't bother looking at the lines if we're already in skip mode.
85     if [[ $skip_count == 0 ]]; then
86       # find the string they're seeking.
87       if [[ ! "$line" =~ *"$seeker"* ]]; then
88         # no match.
89         echo "$line" >> "$new_version"
90       else
91         # a match!  start skipping.  we will delete this line and the next N lines.
92         ((skip_count++))
93 echo first skip count is now $skip_count
94       fi
95     else
96       # we're already skipping.  let's keep going until we hit the limit.
97       ((skip_count++))
98 echo ongoing skip count is now $skip_count
99       if [[ $skip_count >= $numlines ]]; then
100         echo "Done skipping, and back to writing output file."
101         skip_count=0
102       fi
103     fi
104   done < "$filename"
105
106 #put the file back into place.
107 echo file we created looks like this:
108 filedump "$new_version"
109
110 echo bailing
111 exit 1
112
113   \mv "$new_version" "$filename"
114   test_or_die "moving the new version into place in: $filename"
115
116   
117 }
118
119 # takes a zone back out of the local conf file for bind
120 function remove_zone_for_domain()
121 {
122   local domain_name="$1"; shift
123
124   local domain_file="/etc/bind/${domain_name}.conf"
125
126   # eat the zone file definition.  this will botch up badly if more text was added
127   # or the zone info shrank.
128   create_chomped_copy_of_file "$domain_file" "zone \"${domain_name}\"" 6
129
130
131   \cp -f "$domain_file" "$domain_file.bkup-${RANDOM}" 
132   test_or_die "backing up domain file: $domain_file"
133
134   # temp file to write to before we move file into place in bind.
135   local new_version="/tmp/$domain_file.bkup-${RANDOM}" 
136   \rm -f "$new_version"
137   test_or_die "cleaning out new version of domain file from: $new_version"
138
139   local line
140   local skip_count=0
141   while read line; do
142     # don't bother looking at the lines if we're already in skip mode.
143     if [[ $skip_count == 0 ]]; then
144       # find the zone for the domain.
145       if [[ ! "$line" =~ *"zone \"${domain_name}\""* ]]; then
146         echo "$line" >> "$new_version"
147       else
148         # start skipping.  we will delete this line and the next 6 lines.
149         ((skip_count++))
150 echo first skip count is now $skip_count
151       fi
152     else
153       # we're already skipping.  let's keep going until we hit the limit.
154       ((skip_count++))
155       if [[ $skip_count >= 6 ]]; then
156         echo "Done skipping, and back to writing output file."
157         skip_count=0
158       fi
159     fi
160   done < "$domain_file"
161
162 #put the file back into place.
163 echo file we created looks like this:
164 filedump "$new_version"
165
166 echo bailing
167 exit 1
168
169   \mv "$new_version" "$domain_file"
170   test_or_die "moving the new version into place in: $domain_file"
171
172 }
173
174 # hooks up a new config file into bind's list of zones.
175 function add_zone_for_new_domain()
176 {
177   local domain_name="$1"; shift
178
179   local domain_file="/etc/bind/${domain_name}.conf"
180
181   echo "adding a new domain configured by ${domain_file} into"
182   echo "the named.conf.local configuration file."
183
184   # append the reference to the new conf file in the zone list.
185   echo "
186 zone \"${domain_name}\" in {
187         file \"${domain_file}\";
188         type master;
189         allow-query { any; };
190 };
191
192 ////////////////////////////////////////////////////////////////////////////
193
194 " >> /etc/bind/named.conf.local
195
196   # keep ownership for the real user.
197   chown "$(logname):$(logname)" /etc/bind/named.conf.local
198   test_or_die "setting ownership on: /etc/bind/named.conf.local"
199
200 }
201
202 # adds a new subdomain under a containing domain.
203 function add_new_subdomain()
204 {
205   local new_domain="$1"; shift
206
207   # split up the full domain name into subdomain portion and containing domain.
208   local subdomain="${new_domain%.*.*}"
209   local containing_domain="${new_domain#*.}"
210
211   echo "adding a subdomain $subdomain to containing domain $containing_domain"
212
213   local domain_file="/etc/bind/${containing_domain}.conf"
214   # see if config file already exists; if not, complain.
215   if [ ! -f "$domain_file" ]; then
216     echo "The domain configuration file for $new_domain is missing."
217     echo "It should already be present in: $domain_file"
218     echo "Please add the containing domain before trying to add a subdomain."
219     exit 1
220   fi
221
222   # see if subdomain already present in config.
223   if [ $(grep -q "$new_domain" "$domain_file") ]; then
224     echo "The subdomain $subdomain already seems to exist in the domain"
225     echo "configuration file: $domain_file"
226     echo "Please edit the config file to remove the subdomain before trying"
227     echo "to re-add the subdomain."
228     exit 1
229   fi
230
231   # append the new subdomain into the config file.
232   echo "
233 ${subdomain}.${containing_domain}.    IN A    ${IP_ADDRESS}
234         IN HINFO \"linux server\" \"${DISTRO}\"
235 " >> /etc/bind/${containing_domain}.conf
236
237   # keep ownership for real user.
238   chown "$(logname):$(logname)" "/etc/bind/${containing_domain}.conf"
239   test_or_die "setting ownership on: /etc/bind/${containing_domain}.conf"
240 }
241
242 function restart_bind()
243 {
244   echo restarting DNS server.
245   service bind9 restart
246   if [ $? -ne 0 ]; then
247     echo "The bind service did not restart properly.  Please check the error logs."
248     exit 1
249   fi
250   echo DNS server restarted.
251 }
252