[956] | 1 | #!/usr/bin/env python
|
---|
| 2 | # -*- coding: utf-8 -*-
|
---|
| 3 | #
|
---|
| 4 |
|
---|
| 5 | from PyQt4 import QtGui, QtCore
|
---|
| 6 | from PyQt4.QtCore import *
|
---|
| 7 | from PyQt4.QtGui import *
|
---|
| 8 |
|
---|
| 9 | import socket
|
---|
| 10 | import string
|
---|
| 11 | import random
|
---|
| 12 | import Ui_baseconfigwizard
|
---|
| 13 | import os
|
---|
| 14 | import sys
|
---|
| 15 |
|
---|
| 16 | from nosferatu import bacresources, prettynames, auto_types
|
---|
| 17 |
|
---|
| 18 |
|
---|
| 19 |
|
---|
| 20 | # TODO: move this into base_classes
|
---|
| 21 |
|
---|
| 22 |
|
---|
| 23 |
|
---|
| 24 |
|
---|
| 25 | class newdatacenterwizard(QtGui.QWizard, Ui_baseconfigwizard.Ui_Wizard,):
|
---|
| 26 | '''
|
---|
| 27 | '''
|
---|
| 28 |
|
---|
[960] | 29 | def __init__(self, TEMPLATES_PATH ):
|
---|
[956] | 30 | super(newdatacenterwizard, self).__init__()
|
---|
| 31 | self.setupUi(self)
|
---|
| 32 | self.setWindowTitle("New Datacenter Wizard")
|
---|
| 33 | self.groupBox.setTitle('Welcome to the new Datacenter Wizard.')
|
---|
[960] | 34 | self.TEMPLATES_PATH = TEMPLATES_PATH
|
---|
[956] | 35 | # configuration info that has to be provided:
|
---|
| 36 | self.newDCinfo = {
|
---|
| 37 | 'dcname' : ['Datacenter Name','Name of the Datacenter, e.g. Company Name or OU <br>e.g. <i>MyCompany</i>',''],
|
---|
| 38 | 'hostname' : ['Hostname','Hostname of the Bacula Server (short name) <br>e.g. <i> bacula </i>',''],
|
---|
| 39 | 'hostaddress' : ['Hostaddress','DNS Name of the Bacula Server (FQDN) <br>e.g. <i>bacula.dass-it.de</i>',''],
|
---|
| 40 | }
|
---|
| 41 |
|
---|
| 42 |
|
---|
| 43 |
|
---|
| 44 | introtext = 'Please provide the following information:<br><ul>'
|
---|
| 45 | #self.groupBox_2.setTitle('please provide the following information for the %s:' % (prettynames.PrettyNames[resource.resourcetype]))
|
---|
| 46 |
|
---|
| 47 | for name,info in self.newDCinfo.iteritems():
|
---|
| 48 | introtext += '<li><b>' + info[0] + '</b><br>' + info[1] + '</li>'
|
---|
| 49 | introtext +='</ul>'
|
---|
| 50 |
|
---|
| 51 | self.introtextEdit.setHtml(introtext)
|
---|
| 52 |
|
---|
| 53 | row = 0
|
---|
| 54 | # for name,info in self.newDCinfo.iteritems():
|
---|
| 55 | for name in sorted(self.newDCinfo.keys()):
|
---|
| 56 | info = self.newDCinfo[name]
|
---|
| 57 | newlabel = QtGui.QLabel(self.scrollAreaWidgetContents)
|
---|
| 58 | newlabel.setText(info[0])
|
---|
| 59 |
|
---|
| 60 | self.gridLayout_4.addWidget(newlabel, row, 0, 1, 1)
|
---|
| 61 | newwidget = QtGui.QLineEdit(self.scrollAreaWidgetContents)
|
---|
| 62 | newwidget.setToolTip(info[1])
|
---|
| 63 | self.wizardPage2.registerField(name + '*', newwidget)
|
---|
| 64 | self.gridLayout_4.addWidget(newwidget, row, 1, 1, 1)
|
---|
| 65 |
|
---|
| 66 |
|
---|
| 67 | if name == 'hostaddress':
|
---|
| 68 | newButton = QtGui.QPushButton(self.scrollAreaWidgetContents)
|
---|
| 69 | newButton.setText('check')
|
---|
| 70 | self.gridLayout_4.addWidget(newButton, row, 2, 1, 1)
|
---|
| 71 | self.addressLineEdit = newwidget
|
---|
| 72 | self.connect(newButton,
|
---|
| 73 | SIGNAL("clicked()"),
|
---|
| 74 | self.onaddrCheckButtonClicked
|
---|
| 75 | )
|
---|
| 76 |
|
---|
| 77 |
|
---|
| 78 | # find validator to ensure ony valid hostnames can be enteredTODO:
|
---|
| 79 | #if name == 'hostname':
|
---|
| 80 | # validator = QtGui.QValidator()
|
---|
| 81 | # QtGui.QValidator.
|
---|
| 82 | # newwidget.setValidator(validator)
|
---|
| 83 | row += 1
|
---|
| 84 |
|
---|
| 85 |
|
---|
| 86 | def initializePage(self,pagenumber):
|
---|
| 87 |
|
---|
| 88 |
|
---|
| 89 | if pagenumber == 2: # overview page
|
---|
| 90 |
|
---|
| 91 | for name,info in self.newDCinfo.iteritems(): # safe registerd fields to DCinfo
|
---|
| 92 | self.newDCinfo[name][2] = unicode(self.field(name).toString())
|
---|
| 93 |
|
---|
[975] | 94 | dc = bacresources.DataCenter(os.path.normpath( self.TEMPLATES_PATH + '/503_psql.dmdz')) # use this template
|
---|
[956] | 95 |
|
---|
| 96 | dcname = self.newDCinfo['dcname'][2]
|
---|
| 97 | hostname = self.newDCinfo['hostname'][2]
|
---|
| 98 | hostaddress = self.newDCinfo['hostaddress'][2]
|
---|
| 99 |
|
---|
| 100 | DIRNAME = hostname + '-dir'
|
---|
| 101 | FDNAME = hostname + '-fd'
|
---|
| 102 | SDNAME = hostname + '-sd'
|
---|
| 103 | MONNAME = hostname + '-mon'
|
---|
| 104 |
|
---|
| 105 | # Passwords
|
---|
| 106 | pw_DIR_SD = bacresources.genPw(None,32) # director - storage daemon
|
---|
| 107 | pw_DIR_FD = bacresources.genPw(None,32) # director - filedaemon
|
---|
| 108 | pw_DIR_CON = bacresources.genPw(None,32) # director - console
|
---|
| 109 | pw_DIR_MON = bacresources.genPw(None,32 ) # director - monitoring console
|
---|
| 110 |
|
---|
| 111 | dc.setName(dcname)
|
---|
| 112 |
|
---|
| 113 | # Director Config
|
---|
| 114 | # set the Name of the Director resource in the Director Config
|
---|
| 115 | directorlist = list(dc.directors)
|
---|
| 116 | directorconfig = directorlist[0]
|
---|
| 117 | directorconfigDir = directorconfig.getResourceByName('bacula-dir')
|
---|
| 118 | directorconfigDir.setName(DIRNAME)
|
---|
| 119 | directorconfigDir.setItemValue('password', pw_DIR_CON)
|
---|
| 120 |
|
---|
| 121 | # set the Client name in 'DefaultJob' JobDefs
|
---|
| 122 | directorconfigJobDefs = directorconfig.getResourceByName('DefaultJob')
|
---|
| 123 | directorconfigJobDefs.setItemValue('client', FDNAME)
|
---|
| 124 |
|
---|
| 125 | # set the Client name in 'RestoreFiles' Job
|
---|
| 126 | directorrestorefiles = directorconfig.getResourceByName('RestoreFiles')
|
---|
| 127 | directorrestorefiles.setItemValue('client', FDNAME)
|
---|
| 128 |
|
---|
| 129 | # set the Name of the Client Resource and the address 'bacula-fd'
|
---|
| 130 | directorclientresource = directorconfig.getResourceByName('bacula-fd')
|
---|
| 131 | directorclientresource.setName(FDNAME)
|
---|
| 132 | # set the password
|
---|
| 133 | directorclientresource.setItemValue('password', pw_DIR_FD)
|
---|
| 134 | # set the address
|
---|
| 135 | directorclientresource.setItemValue('address',hostaddress)
|
---|
| 136 |
|
---|
| 137 | # set the Address of the storage Resource 'File'
|
---|
| 138 | directorstorageresource = directorconfig.getResourceByName('File')
|
---|
| 139 | directorstorageresource.setItemValue('address',hostaddress)
|
---|
| 140 | directorstorageresource.setItemValue('password', pw_DIR_SD)
|
---|
| 141 |
|
---|
| 142 | # set the Name of the Monitor Console Entry
|
---|
| 143 | directormonitorconsole = directorconfig.getResourceByName('bacula-mon')
|
---|
| 144 | directormonitorconsole.setName(MONNAME)
|
---|
| 145 | directormonitorconsole.setItemValue('password', pw_DIR_MON)
|
---|
| 146 |
|
---|
| 147 | # Filedaemon Config
|
---|
| 148 | fdlist = list(dc.filedaemons)
|
---|
| 149 | fdconfig = fdlist[0]
|
---|
| 150 | # set the Name of the Director resource in the Filedaemon Config
|
---|
| 151 | filedaemonconfigdir = fdconfig.getResourceByName('bacula-dir')
|
---|
| 152 | filedaemonconfigdir.setName(DIRNAME)
|
---|
| 153 | filedaemonconfigdir.setItemValue('password', pw_DIR_FD)
|
---|
| 154 |
|
---|
| 155 | # set the Name of the Filedaemon resource in the Filedaemon Config
|
---|
| 156 | filedaemonconfigfd = fdconfig.getResourceByName('bacula-fd')
|
---|
| 157 | filedaemonconfigfd.setName(FDNAME)
|
---|
| 158 |
|
---|
| 159 | # set the Name of the Director in the messages Resource in the Filedaemon Config
|
---|
| 160 | filedaemonconfigmsg = fdconfig.getResourceByName('Standard')
|
---|
| 161 | filedaemonconfigmsg.setItemValue('director', DIRNAME +' = all,!skipped,!restored')
|
---|
| 162 |
|
---|
| 163 |
|
---|
| 164 | # Storage Daemon Config
|
---|
| 165 | sdlist = list(dc.storagedaemons)
|
---|
| 166 | sdconfig = sdlist[0]
|
---|
| 167 | # set the Name for the Storage Daemon
|
---|
| 168 | storagedaemonconfigsd = sdconfig.getResourceByName('bacula-sd')
|
---|
| 169 | storagedaemonconfigsd.setName(SDNAME)
|
---|
| 170 |
|
---|
| 171 | # set the Director Entry
|
---|
| 172 | storagedaemonconfigdir = sdconfig.getResourceByName('bacula-dir')
|
---|
| 173 | storagedaemonconfigdir.setName(DIRNAME)
|
---|
| 174 | storagedaemonconfigdir.setItemValue('password', pw_DIR_SD)
|
---|
| 175 |
|
---|
| 176 | # set the Messages Resource
|
---|
| 177 | storagedaemonconfigmsg = sdconfig.getResourceByName('Standard')
|
---|
| 178 | storagedaemonconfigmsg.setItemValue('director', DIRNAME +' = all,!skipped,!restored')
|
---|
| 179 |
|
---|
| 180 |
|
---|
| 181 |
|
---|
| 182 | # Console Config
|
---|
| 183 | consoleslist = list(dc.consoles)
|
---|
| 184 | consoleconfig = consoleslist[0]
|
---|
| 185 | # set the name for the Director
|
---|
| 186 | consoleconfigdir = consoleconfig.getResourceByName('bacula-dir')
|
---|
| 187 | consoleconfigdir.setName(DIRNAME)
|
---|
| 188 | # set the address of the Director
|
---|
| 189 | consoleconfigdir.setItemValue('address', hostaddress)
|
---|
| 190 | consoleconfigdir.setItemValue('password', pw_DIR_CON)
|
---|
| 191 |
|
---|
| 192 | filename = u''
|
---|
| 193 | while not filename:
|
---|
| 194 | filename = unicode(QFileDialog.getSaveFileName(self
|
---|
| 195 | ,self.tr('Save Datacenter file')
|
---|
| 196 | ,dc.getName()
|
---|
| 197 | ,self.tr('dassModus datacenter .dmdz files (*.dmdz)'))
|
---|
| 198 | )
|
---|
| 199 | self.filename = filename
|
---|
| 200 | dc.setFileName(filename)
|
---|
| 201 | dc.safeDatacenter()
|
---|
| 202 |
|
---|
| 203 | previewtext = 'A new datacenter with the following configuration: <p><ul>'
|
---|
| 204 | for name,info in self.newDCinfo.iteritems():
|
---|
| 205 | #self.newDCinfo[name][2] = str(self.field(name).toString())
|
---|
| 206 | previewtext += '<li><i>' + info[0] + '</i>:<b>' + self.field(name).toString()+'</b></li>'
|
---|
| 207 | previewtext += '</ul></p>'
|
---|
| 208 | previewtext += 'has been saved to <p><i>' + filename + '<i></p>' + ' and will be loaded automatically'
|
---|
| 209 | self.previewtextEdit.setHtml(previewtext)
|
---|
| 210 |
|
---|
| 211 |
|
---|
| 212 |
|
---|
| 213 |
|
---|
| 214 | def onpwgenPasswdClicked(self):
|
---|
| 215 | self.passwordLineEdit.setText(bacresources.genPw(None,32))
|
---|
| 216 |
|
---|
| 217 | def onaddrCheckButtonClicked(self):
|
---|
| 218 | hostname = unicode(self.addressLineEdit.text())
|
---|
| 219 | ip = self.check_hostname(hostname)
|
---|
| 220 | if ip != None:
|
---|
| 221 | reply = QMessageBox.information(self,
|
---|
| 222 | "hostname OK",
|
---|
| 223 | "check successful: \n\n \"%s\" \n is at\n %s" % (hostname, ip) ,
|
---|
| 224 | QMessageBox.Ok)
|
---|
| 225 | else:
|
---|
| 226 | reply = QMessageBox.warning(self,
|
---|
| 227 | "hostname ERROR",
|
---|
| 228 | "\"%s\" can NOT be resolved!" % (hostname) ,
|
---|
| 229 | QMessageBox.Ok)
|
---|
| 230 |
|
---|
| 231 |
|
---|
| 232 |
|
---|
| 233 | def check_hostname(self,hostname):
|
---|
| 234 | '''
|
---|
| 235 | try to resolve the given hostname
|
---|
| 236 | returns the IP or NONE if not resolvable
|
---|
| 237 | '''
|
---|
| 238 | if len(hostname) == 0:
|
---|
| 239 | return None
|
---|
| 240 | try:
|
---|
| 241 | ip = socket.gethostbyname(hostname)
|
---|
| 242 | return ip
|
---|
| 243 | except:
|
---|
| 244 | return None
|
---|
| 245 |
|
---|
| 246 |
|
---|
| 247 |
|
---|
| 248 | if __name__ == "__main__":
|
---|
| 249 | import sys
|
---|
| 250 | #def main():
|
---|
| 251 | print "started"
|
---|
| 252 | app = QtGui.QApplication(sys.argv)
|
---|
| 253 | app.setOrganizationDomain("dass-it.de")
|
---|
| 254 | app.setOrganizationName("dassIT GmbH")
|
---|
| 255 | app.setApplicationName("dassModus")
|
---|
| 256 | app.setWindowIcon(QIcon(":/icons/dassit_logo.png"))
|
---|
| 257 |
|
---|
| 258 | wizard = newdatacenterwizard()
|
---|
| 259 | if wizard.exec_():
|
---|
[975] | 260 | dc = bacresources.DataCenter('templates/503_psql.dmdz') # use this template
|
---|
[956] | 261 |
|
---|
| 262 | dcname = wizard.newDCinfo['dcname'][2]
|
---|
| 263 | hostname = wizard.newDCinfo['hostname'][2]
|
---|
| 264 | hostaddress = wizard.newDCinfo['hostaddress'][2]
|
---|
| 265 |
|
---|
| 266 | DIRNAME = hostname + '-dir'
|
---|
| 267 | FDNAME = hostname + '-fd'
|
---|
| 268 | SDNAME = hostname + '-sd'
|
---|
| 269 |
|
---|
| 270 |
|
---|
| 271 | dc.setName(dcname)
|
---|
| 272 |
|
---|
| 273 | # Director Config
|
---|
| 274 | # set the Name of the Director resource in the Director Config
|
---|
| 275 | directorlist = list(dc.directors)
|
---|
| 276 | directorconfig = directorlist[0]
|
---|
| 277 | directorconfigDir = directorconfig.getResourceByName('bacula-dir')
|
---|
| 278 | directorconfigDir.setName(DIRNAME)
|
---|
| 279 |
|
---|
| 280 | # set the Client name in 'DefaultJob' JobDefs
|
---|
| 281 | directorconfigJobDefs = directorconfig.getResourceByName('DefaultJob')
|
---|
| 282 | directorconfigJobDefs.setItemValue('client', FDNAME)
|
---|
| 283 |
|
---|
| 284 | # set the Client name in 'RestoreFiles' Job
|
---|
| 285 | directorrestorefiles = directorconfig.getResourceByName('RestoreFiles')
|
---|
| 286 | directorrestorefiles.setItemValue('client', FDNAME)
|
---|
| 287 |
|
---|
| 288 | # set the Name of the Client Resource and the address 'bacula-fd'
|
---|
| 289 | directorclientresource = directorconfig.getResourceByName('bacula-fd')
|
---|
| 290 | directorclientresource.setName(FDNAME)
|
---|
| 291 | # set the Address
|
---|
| 292 | directorclientresource.setItemValue('address', hostaddress)
|
---|
| 293 |
|
---|
| 294 | # set the Address of the storage Resource 'File'
|
---|
| 295 | directorstorageresource = directorconfig.getResourceByName('File')
|
---|
| 296 | directorstorageresource.setItemValue('address', hostaddress)
|
---|
| 297 |
|
---|
| 298 |
|
---|
| 299 | # Filedaemon Config
|
---|
| 300 | fdlist = list(dc.filedaemons)
|
---|
| 301 | fdconfig = fdlist[0]
|
---|
| 302 | # set the Name of the Director resource in the Filedaemon Config
|
---|
| 303 | filedaemonconfigdir = fdconfig.getResourceByName('bacula-dir')
|
---|
| 304 | filedaemonconfigdir.setName(DIRNAME)
|
---|
| 305 |
|
---|
| 306 | # set the Name of the Filedaemon resource in the Filedaemon Config
|
---|
| 307 | filedaemonconfigfd = fdconfig.getResourceByName('bacula-fd')
|
---|
| 308 | filedaemonconfigfd.setName(FDNAME)
|
---|
| 309 |
|
---|
| 310 | # set the Name of the Director in the messages Resource in the Filedaemon Config
|
---|
| 311 | filedaemonconfigmsg = fdconfig.getResourceByName('Standard')
|
---|
| 312 | filedaemonconfigmsg.setItemValue('director', DIRNAME +' = all,!skipped,!restored')
|
---|
| 313 |
|
---|
| 314 |
|
---|
| 315 | # Storage Daemon Config
|
---|
| 316 | sdlist = list(dc.storagedaemons)
|
---|
| 317 | sdconfig = sdlist[0]
|
---|
| 318 | # set the Name for the Storage Daemon
|
---|
| 319 | storagedaemonconfigsd = sdconfig.getResourceByName('bacula-sd')
|
---|
| 320 | storagedaemonconfigsd.setName(SDNAME)
|
---|
| 321 |
|
---|
| 322 | # set the Director Entry
|
---|
| 323 | storagedaemonconfigdir = sdconfig.getResourceByName('bacula-dir')
|
---|
| 324 | storagedaemonconfigdir.setName(DIRNAME)
|
---|
| 325 |
|
---|
| 326 | # set the Messages Resource
|
---|
| 327 | storagedaemonconfigmsg = sdconfig.getResourceByName('Standard')
|
---|
| 328 | storagedaemonconfigmsg.setItemValue('director', DIRNAME +' = all,!skipped,!restored')
|
---|
| 329 |
|
---|
| 330 |
|
---|
| 331 |
|
---|
| 332 | # Console Config
|
---|
| 333 | consoleslist = list(dc.consoles)
|
---|
| 334 | consoleconfig = consoleslist[0]
|
---|
| 335 | # set the name for the Director
|
---|
| 336 | consoleconfigdir = consoleconfig.getResourceByName('bacula-dir')
|
---|
| 337 | consoleconfigdir.setName(DIRNAME)
|
---|
| 338 | # set the address of the Director
|
---|
| 339 | consoleconfigdir.setItemValue('address', hostaddress)
|
---|
| 340 |
|
---|
| 341 |
|
---|
| 342 |
|
---|
| 343 |
|
---|
| 344 | filename = unicode(QFileDialog.getSaveFileName(wizard
|
---|
| 345 | ,wizard.tr('Save Datacenter file')
|
---|
| 346 | ,dc.getName()
|
---|
| 347 | ,wizard.tr('dassModus datacenter .dmdz files (*.dmdz)'))
|
---|
| 348 | )
|
---|
| 349 | dc.setFileName(filename)
|
---|
| 350 | dc.safeDatacenter()
|
---|
| 351 | #filename = QtGui.QFileDialog()
|
---|
| 352 |
|
---|
| 353 | #dc.setFileName(filename)
|
---|
| 354 | else:
|
---|
| 355 | print "no"
|
---|
| 356 | #wizard.show()
|
---|
| 357 |
|
---|
| 358 |
|
---|
| 359 | sys.exit(app.exec_())
|
---|
| 360 |
|
---|
| 361 |
|
---|