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