| 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 key = { a = 1; b= 2}
|
|---|
| 16 | rxp_openbrace = re.compile('^\\s*(\\w[\\w ]*\\w+)\\s*\\=?\\s*\\{\\s*') # match xxx {
|
|---|
| 17 | rxp_closebrace = re.compile('[^{]*}.*') # match }
|
|---|
| 18 | rxp_comment = re.compile('^\s*#.*')
|
|---|
| 19 |
|
|---|
| 20 |
|
|---|
| 21 |
|
|---|
| 22 | #'dird', 'console', 'filed' or 'stored'
|
|---|
| 23 | class Config(object):
|
|---|
| 24 | """Class for bacula configuration access"""
|
|---|
| 25 |
|
|---|
| 26 | def __init__(self, resource_type, filename=""):
|
|---|
| 27 | self.resource_type = resource_type
|
|---|
| 28 | self.filename = filename
|
|---|
| 29 | self.resources = resource.Root(level=0)
|
|---|
| 30 | self.resources.name="<root>"
|
|---|
| 31 |
|
|---|
| 32 | def read(self):
|
|---|
| 33 | self.parse(self.resources,open(self.filename,"r"),0)
|
|---|
| 34 | #print self.resources
|
|---|
| 35 |
|
|---|
| 36 | def write(self, filename=None):
|
|---|
| 37 | if(filename==None):
|
|---|
| 38 | filename=self.filename
|
|---|
| 39 | f=open(filename,"w")
|
|---|
| 40 | f.write(str(self.getRoot()))
|
|---|
| 41 | f.close()
|
|---|
| 42 |
|
|---|
| 43 | def getResourceById(self,theid):
|
|---|
| 44 | return self.resources.getById(theid)
|
|---|
| 45 |
|
|---|
| 46 | def getResourceByName(self,name):
|
|---|
| 47 | return self.resources.getByName(name)
|
|---|
| 48 |
|
|---|
| 49 | def getRoot(self):
|
|---|
| 50 | return self.resources
|
|---|
| 51 |
|
|---|
| 52 | def parse(self,curRes,f,level):
|
|---|
| 53 | #print "START",curRes.name
|
|---|
| 54 |
|
|---|
| 55 | while True:
|
|---|
| 56 | line=f.readline()
|
|---|
| 57 | if not line:
|
|---|
| 58 | break
|
|---|
| 59 |
|
|---|
| 60 | inlinecomment=None
|
|---|
| 61 |
|
|---|
| 62 | commentStart=line.find("#")
|
|---|
| 63 | if commentStart!=-1:
|
|---|
| 64 | inlinecomment=line[commentStart:]
|
|---|
| 65 | line=line[:commentStart].strip()
|
|---|
| 66 | #curRes.add_comment(inlinecomment)
|
|---|
| 67 |
|
|---|
| 68 | include=line.strip()
|
|---|
| 69 | if include.startswith("@"):
|
|---|
| 70 | includepath=include[1:].strip()
|
|---|
| 71 | print "include " +includepath
|
|---|
| 72 | self.parse(curRes,open(includepath,"r"),level)
|
|---|
| 73 |
|
|---|
| 74 | if rxp_closebrace.match(line):
|
|---|
| 75 | #print "closebraceline"
|
|---|
| 76 | break
|
|---|
| 77 |
|
|---|
| 78 | item2 = rxp_item2.match(line)
|
|---|
| 79 | if item2:
|
|---|
| 80 | #print "item2"
|
|---|
| 81 | name = item2.group(1)
|
|---|
| 82 | value = item2.group(2)
|
|---|
| 83 | #print "item:",name,value
|
|---|
| 84 | newRes=resource.Resource(level+1)
|
|---|
| 85 | newRes.name=name
|
|---|
| 86 | newRes.value="{"+value+"}"
|
|---|
| 87 | curRes.add_item(newRes)
|
|---|
| 88 | continue
|
|---|
| 89 |
|
|---|
| 90 | openbraceline = rxp_openbrace.match(line)
|
|---|
| 91 | if openbraceline:
|
|---|
| 92 | #print "openbraceline"
|
|---|
| 93 | resname = openbraceline.group(1)
|
|---|
| 94 | try:
|
|---|
| 95 | resClass = getattr(resource,resname);
|
|---|
| 96 | except:
|
|---|
| 97 | resClass = resource.Resource
|
|---|
| 98 |
|
|---|
| 99 | newRes=resClass(level+1)
|
|---|
| 100 | newRes.name=resname
|
|---|
| 101 | curRes.add_item(newRes);
|
|---|
| 102 | self.parse(newRes,f,level+1);
|
|---|
| 103 |
|
|---|
| 104 | continue
|
|---|
| 105 |
|
|---|
| 106 | item = rxp_item.match(line)
|
|---|
| 107 | if item:
|
|---|
| 108 | name = item.group(1)
|
|---|
| 109 | value = item.group(2).strip()
|
|---|
| 110 | #print "item:",name,value
|
|---|
| 111 | newRes=resource.Resource(level+1)
|
|---|
| 112 | newRes.name=name
|
|---|
| 113 | newRes.value=value
|
|---|
| 114 | curRes.add_item(newRes)
|
|---|
| 115 | continue
|
|---|
| 116 |
|
|---|
| 117 | #print "END",curRes.name
|
|---|
| 118 |
|
|---|
| 119 | class DirdConfig(Config):
|
|---|
| 120 |
|
|---|
| 121 | def __init__(self, filename=""):
|
|---|
| 122 | Config.__init__(self, 'dird', filename)
|
|---|
| 123 |
|
|---|
| 124 | class ConsoleConfig(Config):
|
|---|
| 125 | pass
|
|---|
| 126 |
|
|---|
| 127 | class FiledConfig(Config):
|
|---|
| 128 | def __init__(self, filename=""):
|
|---|
| 129 | Config.__init__(self, 'fd', filename)
|
|---|
| 130 |
|
|---|
| 131 | def setDefaults(self,directorName,directorPassword,myName):
|
|---|
| 132 | director=resource.Director(1,"Director")
|
|---|
| 133 | director.add("Name",directorName)
|
|---|
| 134 | director.add("Password",'"'+directorPassword+'"')
|
|---|
| 135 | self.getRoot().add_item(director)
|
|---|
| 136 |
|
|---|
| 137 | fileDaemon=resource.FileDaemon(1,"FileDaemon")
|
|---|
| 138 | fileDaemon.add("Name",myName)
|
|---|
| 139 | #fileDaemon.add("FDport","9102")
|
|---|
| 140 | fileDaemon.add("WorkingDirectory","/var/lib/bacula")
|
|---|
| 141 | fileDaemon.add("Pid Directory","/var/run")
|
|---|
| 142 | fileDaemon.add("Maximum Concurrent Jobs","20")
|
|---|
| 143 | self.getRoot().add_item(fileDaemon)
|
|---|
| 144 |
|
|---|
| 145 | messages=resource.Messages(1,"Messages")
|
|---|
| 146 | messages.add("Name","Standard")
|
|---|
| 147 | messages.add("director",directorName+" = all, !skipped, !restored")
|
|---|
| 148 | self.getRoot().add_item(messages)
|
|---|
| 149 |
|
|---|
| 150 | class StoredConfig(Config):
|
|---|
| 151 | pass
|
|---|
| 152 |
|
|---|
| 153 | def createClient(clientname,clientaddr,catalog,password):
|
|---|
| 154 | newclient=resource.Client(1,"Client")
|
|---|
| 155 | newclient.add("Name",clientname)
|
|---|
| 156 | newclient.add("Address",clientaddr)
|
|---|
| 157 | #newclient.add("FDPort",fdport)
|
|---|
| 158 | newclient.add("Catalog",catalog)
|
|---|
| 159 | newclient.add("Password",'"'+password+'"')
|
|---|
| 160 | return newclient
|
|---|
| 161 |
|
|---|
| 162 | def genpasswd(len=32):
|
|---|
| 163 | charset="01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!/%()=?@"
|
|---|
| 164 | password=""
|
|---|
| 165 | for a in xrange(0,len):
|
|---|
| 166 | password += random.choice(charset)
|
|---|
| 167 | return password
|
|---|
| 168 |
|
|---|
| 169 | if __name__ == "__main__":
|
|---|
| 170 |
|
|---|
| 171 | if len(sys.argv) < 2:
|
|---|
| 172 | filename="test.conf"
|
|---|
| 173 | else:
|
|---|
| 174 | filename=sys.argv[1]
|
|---|
| 175 |
|
|---|
| 176 | dirdcfg = DirdConfig(filename)
|
|---|
| 177 | dirdcfg.read()
|
|---|
| 178 |
|
|---|
| 179 | job=resource.Job(1,"Job")
|
|---|
| 180 | job.add("Name",'"test2"')
|
|---|
| 181 | job.add("Client",'"test2"')
|
|---|
| 182 | job.add("JobDefs",'"testdefs"')
|
|---|
| 183 | job.add("FileSet",'"Full Set"')
|
|---|
| 184 |
|
|---|
| 185 | root=dirdcfg.getRoot()
|
|---|
| 186 | root.add_item(job)
|
|---|
| 187 |
|
|---|
| 188 | pwd=genpasswd()
|
|---|
| 189 | newclient=createClient("test-fd","testclient","MyCatalog",pwd)
|
|---|
| 190 | root.add_item(newclient)
|
|---|
| 191 |
|
|---|
| 192 | dirdcfg.write("test.conf.out")
|
|---|
| 193 |
|
|---|
| 194 | fdcfg=FiledConfig("test-fd.conf")
|
|---|
| 195 | fdcfg.setDefaults("bacula-dird",pwd,"test-fd")
|
|---|
| 196 | fdcfg.write()
|
|---|
| 197 |
|
|---|
| 198 | sys.exit(0)
|
|---|