1 | #!/usr/bin/python
|
---|
2 | # -*- coding: utf-8 -*-
|
---|
3 | """Classes and functions for configuration file handling
|
---|
4 | """
|
---|
5 |
|
---|
6 | import sys
|
---|
7 | import re
|
---|
8 | import resource
|
---|
9 | import directive
|
---|
10 | import random
|
---|
11 |
|
---|
12 | RESOURCE_TYPES = ('dird', 'console', 'filed', 'stored')
|
---|
13 |
|
---|
14 | rxp_item = re.compile('^\\s*(\\w[\\w ]*\\w+)\\s*\\=(.*)') # xxx = xxx matchen
|
---|
15 | rxp_item2 = re.compile('^\\s*(\\w[\\w ]*\\w+)\\s*\\=\\s*{(.*)}\\s*') # match type = { a = 1; b= 2}
|
---|
16 | rxp_openbrace = re.compile('^\\s*(\\w[\\w ]*\\w+)\\s*\\=?\\s*\\{\\s*') # match xxx {
|
---|
17 | rxp_open = re.compile('^\\s*(\\w[\\w ]*\\w+)\\s*$') # match xxx
|
---|
18 | rxp_closebrace = re.compile('[^{]*}.*') # match }
|
---|
19 | rxp_comment = re.compile('^\s*#.*')
|
---|
20 |
|
---|
21 |
|
---|
22 |
|
---|
23 | #'dird', 'console', 'filed' or 'stored'
|
---|
24 | class Config(object):
|
---|
25 | """Class for bacula configuration access"""
|
---|
26 |
|
---|
27 | def __init__(self, resource_type, filename=""):
|
---|
28 | self.resource_type = resource_type
|
---|
29 | self.filename = filename
|
---|
30 | self.resources = resource.Root(level=0)
|
---|
31 | self.resources.type="<root>"
|
---|
32 |
|
---|
33 | def read(self):
|
---|
34 | self.parse(self.resources,open(self.filename,"r"),0)
|
---|
35 | #print self.resources
|
---|
36 |
|
---|
37 | def write(self, filename=None):
|
---|
38 | if(filename==None):
|
---|
39 | filename=self.filename
|
---|
40 | f=open(filename,"w")
|
---|
41 | f.write(str(self.getRoot()))
|
---|
42 | f.close()
|
---|
43 |
|
---|
44 | def getRoot(self):
|
---|
45 | return self.resources
|
---|
46 |
|
---|
47 | def addResource(self,resname,level,curRes):
|
---|
48 | try:
|
---|
49 | resClass = getattr(resource,resname);
|
---|
50 | except:
|
---|
51 | resClass = resource.Resource
|
---|
52 |
|
---|
53 | newRes=resClass(level+1)
|
---|
54 | newRes.type=resname
|
---|
55 | curRes.add_item(newRes);
|
---|
56 | return newRes
|
---|
57 |
|
---|
58 | def parse(self,curRes,f,level):
|
---|
59 | #print "START",curRes.type
|
---|
60 |
|
---|
61 | while True:
|
---|
62 | line=f.readline()
|
---|
63 | if not line:
|
---|
64 | break
|
---|
65 |
|
---|
66 | inlinecomment=None
|
---|
67 |
|
---|
68 | commentStart=line.find("#")
|
---|
69 | if commentStart!=-1:
|
---|
70 | inlinecomment=line[commentStart:]
|
---|
71 | line=line[:commentStart].strip()
|
---|
72 | #curRes.add_comment(inlinecomment)
|
---|
73 |
|
---|
74 | include=line.strip()
|
---|
75 | if include.startswith("@"):
|
---|
76 | includepath=include[1:].strip()
|
---|
77 | print "include " +includepath
|
---|
78 | self.parse(curRes,open(includepath,"r"),level)
|
---|
79 |
|
---|
80 | if rxp_closebrace.match(line):
|
---|
81 | #print "closebraceline"
|
---|
82 | break
|
---|
83 |
|
---|
84 | item2 = rxp_item2.match(line)
|
---|
85 | if item2:
|
---|
86 | #print "item2"
|
---|
87 | name = item2.group(1)
|
---|
88 | value = item2.group(2)
|
---|
89 | #print "item:",name,value
|
---|
90 | newRes=resource.Resource(level+1)
|
---|
91 | newRes.type=name
|
---|
92 | newRes.value="{"+value+"}"
|
---|
93 | curRes.add_item(newRes)
|
---|
94 | continue
|
---|
95 |
|
---|
96 | openbraceline = rxp_openbrace.match(line)
|
---|
97 | if openbraceline:
|
---|
98 | #print "openbraceline"
|
---|
99 | resname = openbraceline.group(1)
|
---|
100 | newRes=self.addResource(resname,level,curRes)
|
---|
101 | self.parse(newRes,f,level+1);
|
---|
102 | continue
|
---|
103 |
|
---|
104 | open = rxp_open.match(line)
|
---|
105 | if open:
|
---|
106 | resname = open.group(1)
|
---|
107 | newRes=self.addResource(resname,level,curRes)
|
---|
108 | self.parse(newRes,f,level+1);
|
---|
109 | continue
|
---|
110 |
|
---|
111 | item = rxp_item.match(line)
|
---|
112 | if item:
|
---|
113 | name = item.group(1)
|
---|
114 | value = item.group(2).strip()
|
---|
115 | #print "item:",name,value
|
---|
116 | newRes=resource.Resource(level+1)
|
---|
117 | newRes.type=name
|
---|
118 | newRes.value=value
|
---|
119 | curRes.add_item(newRes)
|
---|
120 | continue
|
---|
121 |
|
---|
122 | #print "END",curRes.name
|
---|
123 |
|
---|
124 | class DirdConfig(Config):
|
---|
125 |
|
---|
126 | def __init__(self, filename=""):
|
---|
127 | Config.__init__(self, 'dird', filename)
|
---|
128 |
|
---|
129 | class ConsoleConfig(Config):
|
---|
130 | pass
|
---|
131 |
|
---|
132 | class FiledConfig(Config):
|
---|
133 | def __init__(self, filename=""):
|
---|
134 | Config.__init__(self, 'fd', filename)
|
---|
135 |
|
---|
136 | def setDefaults(self,directorName,directorPassword,myName):
|
---|
137 | director=resource.Director(1,"Director")
|
---|
138 | director.add("Name",directorName)
|
---|
139 | director.add("Password",'"'+directorPassword+'"')
|
---|
140 | self.getRoot().add_item(director)
|
---|
141 |
|
---|
142 | fileDaemon=resource.FileDaemon(1,"FileDaemon")
|
---|
143 | fileDaemon.add("Name",myName)
|
---|
144 | #fileDaemon.add("FDport","9102")
|
---|
145 | fileDaemon.add("WorkingDirectory","/var/lib/bacula")
|
---|
146 | fileDaemon.add("Pid Directory","/var/run")
|
---|
147 | fileDaemon.add("Maximum Concurrent Jobs","20")
|
---|
148 | self.getRoot().add_item(fileDaemon)
|
---|
149 |
|
---|
150 | messages=resource.Messages(1,"Messages")
|
---|
151 | messages.add("Name","Standard")
|
---|
152 | messages.add("director",directorName+" = all, !skipped, !restored")
|
---|
153 | self.getRoot().add_item(messages)
|
---|
154 |
|
---|
155 | class StoredConfig(Config):
|
---|
156 | pass
|
---|
157 |
|
---|
158 | def genpasswd(len=32):
|
---|
159 | charset="01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!/%()=?@"
|
---|
160 | password=""
|
---|
161 | for a in xrange(0,len):
|
---|
162 | password += random.choice(charset)
|
---|
163 | return password
|
---|
164 |
|
---|
165 |
|
---|
166 | def createClientConfig(dirdcfg,clientName,clientPassword=genpasswd()):
|
---|
167 | director=dirdcfg.getRoot().getByType("Director")[0]
|
---|
168 | dirdName=director.getName()
|
---|
169 | r=dirdcfg.getRoot().getByName(clientName)
|
---|
170 | if len(r)==1:
|
---|
171 | client=r[0]
|
---|
172 | else:
|
---|
173 | return
|
---|
174 |
|
---|
175 | filename=clientName+".conf"
|
---|
176 | fdcfg=FiledConfig(filename)
|
---|
177 | fdcfg.setDefaults(dirdName,clientPassword,clientName)
|
---|
178 | fdcfg.write()
|
---|
179 |
|
---|
180 | def createAllClientConfigs(dirdcfg):
|
---|
181 | clients=dirdcfg.getRoot().getByType("Client",1)
|
---|
182 | director=dirdcfg.getRoot().getByType("Director")[0]
|
---|
183 | dirdName=director.getName()
|
---|
184 |
|
---|
185 | for c in clients:
|
---|
186 | print c
|
---|
187 | clientName=c.getName()
|
---|
188 | if clientName!=None:
|
---|
189 | r=c.getByType("Password")
|
---|
190 | if len(r)>0:
|
---|
191 | clientPassword=r[0].value
|
---|
192 | clientPassword=clientPassword.replace('"','')
|
---|
193 | else:
|
---|
194 | clientPassword=""
|
---|
195 | filename=clientName+".conf"
|
---|
196 | fdcfg=FiledConfig(filename)
|
---|
197 | fdcfg.setDefaults(dirdName,clientPassword,clientName)
|
---|
198 | fdcfg.write()
|
---|
199 |
|
---|
200 |
|
---|
201 | if __name__ == "__main__":
|
---|
202 | if len(sys.argv) < 2:
|
---|
203 | filename="test.conf"
|
---|
204 | else:
|
---|
205 | filename=sys.argv[1]
|
---|
206 |
|
---|
207 | dirdcfg = DirdConfig(filename)
|
---|
208 | dirdcfg.read()
|
---|
209 |
|
---|
210 | root=dirdcfg.getRoot()
|
---|
211 |
|
---|
212 | job=resource.Job(1,"Job")
|
---|
213 | job.setDefaults("test2-job","test2","testdefs","Full Set")
|
---|
214 |
|
---|
215 | root.add_item(job)
|
---|
216 |
|
---|
217 | pwd=genpasswd()
|
---|
218 | newclient=resource.Client(1,"Client")
|
---|
219 | newclient.setDefaults("test-fd","testclient","MyCatalog",pwd)
|
---|
220 | root.add_item(newclient)
|
---|
221 |
|
---|
222 | dirdcfg.write("test.conf.out")
|
---|
223 |
|
---|
224 | fdcfg=FiledConfig("test-fd.conf")
|
---|
225 | fdcfg.setDefaults("bacula-dird",pwd,"test-fd")
|
---|
226 | fdcfg.write()
|
---|
227 |
|
---|
228 |
|
---|
229 | createClientConfig(dirdcfg,"gaffel-fd")
|
---|
230 | createClientConfig(dirdcfg,"test-fd")
|
---|
231 |
|
---|
232 | createAllClientConfigs(dirdcfg)
|
---|
233 | sys.exit(0)
|
---|