예제 #1
0
 def __init__(self, s3, manifestPath, localWorkingDir):
     self.manifestPath = manifestPath
     self.manifest = Manifest(manifestPath)
     self.s3interface = S3Interface(s3, self.manifest.GetBucketName(), localWorkingDir)
     metafac = InstanceMetadataFactory(self.manifest)
     self.instanceManager = InstanceManager(self.s3interface, self.manifest, metafac)
     self.manifestKey = "/".join([self.manifest.GetS3KeyPrefix(), "manifest.json"])
예제 #2
0
    def test_publishInstance(self):

        mockManifest = Mock(spec=Manifest)
        mockS3Interface = Mock(spec=S3Interface)
        mockInstanceMetadataFactory = Mock(spec=InstanceMetadataFactory)

        mockInstanceMetadataFactory.InitializeMetadata.side_effect = \
            lambda i, a : "metadata"

        mockManifest.GetS3KeyPrefix.side_effect = lambda: "the prefix"
        mockS3Interface.localTempDir = "tests"
        inst = InstanceManager(mockS3Interface, mockManifest,
                               mockInstanceMetadataFactory)
        instId = 100
        tmpfile = inst.GetMetaFileTempPath(instId)
        with open(tmpfile, 'w') as tmp:
            tmp.write("nothing")

        inst.publishInstance(instId, 1000)

        mockManifest.GetS3KeyPrefix.assert_any_call()
        mockS3Interface.uploadFile.assert_called_with(
            tmpfile, "the prefix/instances/100/metadata.json", True)
        mockInstanceMetadataFactory.InitializeMetadata.assert_any_call(
            instId, 1000)
        mockInstanceMetadataFactory.ToJson.assert_any_call("metadata", tmpfile)
        self.assertFalse(os.path.exists(tmpfile))
예제 #3
0
class Application(object):
    
    def __init__(self, s3, manifestPath, localWorkingDir):
        self.manifestPath = manifestPath
        self.manifest = Manifest(manifestPath)
        self.s3interface = S3Interface(s3, self.manifest.GetBucketName(), localWorkingDir)
        metafac = InstanceMetadataFactory(self.manifest)
        self.instanceManager = InstanceManager(self.s3interface, self.manifest, metafac)
        self.manifestKey = "/".join([self.manifest.GetS3KeyPrefix(), "manifest.json"])

    def downloadS3Document(self, documentName):
        logging.info("downloading specified document '{0}'  from s3 bucket {1}"
                     .format(documentName, self.s3interface.bucketName))

        filteredDocs = list(
            self.manifest.GetS3Documents(
                filter = {"Name": documentName}))
        if len(filteredDocs) == 0:
            raise ValueError("specified document {0} not found".format(documentName))
        elif filteredDocs[0]["Direction"] != "AWSToLocal":
            raise ValueError("specified document not marked AWSToLocal")
        elif len(filteredDocs)> 1:
            raise ValueError("manifest error")

        doc = filteredDocs[0]
        self.s3interface.downloadCompressed(self.manifest.GetS3KeyPrefix(), documentName,
                                            os.path.abspath(doc["LocalPath"]))

    def downloadS3Documents(self):
        logging.info("downloading files from s3 bucket {0}".format(self.s3interface.bucketName))

        for doc in self.manifest.GetS3Documents(filter = {"Direction": "AWSToLocal"}):
            self.s3interface.downloadCompressed(self.manifest.GetS3KeyPrefix(), doc["Name"],
                                                os.path.abspath(doc["LocalPath"]))
        logging.info("downloading finished")

    def downloadLogs(self, outputdir):
        logging.info("downloading instance logs s3 bucket {0}".format(self.s3interface.bucketName))
        for j in self.manifest.GetJobs():
            self.instanceManager.downloadInstanceLog(j["Id"], outputdir)

    def uploadS3Documents(self):
        logging.info("uploading files to s3 bucket {0}".format(self.s3interface.bucketName))
        logging.info("uploading manifest {0} to {1}".format(self.manifestPath, self.manifestKey))
        self.s3interface.uploadFile(self.manifestPath, self.manifestKey)

        for doc in self.manifest.GetS3Documents(filter = {"Direction": "LocalToAWS"}):
            self.s3interface.uploadCompressed(self.manifest.GetS3KeyPrefix(), doc["Name"],
                                              os.path.abspath(doc["LocalPath"]))
        logging.info("uploading finished")

    def runInstances(self, ec2, instanceConfig):
        ec2interface = EC2Interface(ec2, instanceConfig["BootStrapperConfig"]["WorkingDirectory"], 
                                     self.manifest, self.manifestKey, self.instanceManager,
                                     instanceConfig["BootStrapperConfig"]["PythonPath"],
                                     instanceConfig["BootStrapperConfig"]["BootStrapScriptPath"],
                                     instanceConfig["BootStrapperConfig"]["LineBreak"],
                                     instanceConfig["BootStrapperConfig"]["BootstrapCommands"])
        ec2interface.launchInstances(instanceConfig["EC2Config"]["InstanceConfig"])
        logging.info("ec2 launch finished")
    def __init__(self, *args):
        logging.debug('MainWindow creation')

        QMainWindow.__init__(self, *args)
        self.ui = Ui_MainWindow()
        logging.debug('MainWindow ui setup')
        self.ui.setupUi(self)

        self.instanceManager = InstanceManager(InstanceManager.getStoredKey())
        self.readConfig()
        self.setupModels()

        self.ui.treeView.activated.connect(self.updatePasswordsModel)
        self.ui.tableView.activated.connect(self.udpateDetailTabs)
        self.ui.actionQuit.triggered.connect(self.closeReally)
        self.ui.actionPreferences.triggered.connect(self.openPreferences)
        self.ui.actionRefresh.triggered.connect(self.refreshInstances)

        # Init QSystemTrayIcon
        icon = QIcon.fromTheme('dialog-passwords',
                               QIcon(':/icons/dialog-password.svg'))
        self.trayIcon = QSystemTrayIcon(icon, self)
        systrayMenu = QMenu(self)
        systrayMenu.addAction(self.ui.actionRefresh)
        systrayMenu.addAction(self.ui.actionQuit)
        self.trayIcon.setContextMenu(systrayMenu)
        self.trayIcon.show()
        self.trayIcon.activated.connect(self.handleSystray)
예제 #5
0
 def test_GetKeyPrefix(self):
     mockManifest = Mock(spec=Manifest)
     mockS3Interface = Mock(spec=S3Interface)
     mockInstanceMetadataFactory = Mock(spec=InstanceMetadataFactory)
     inst = InstanceManager(mockS3Interface, mockManifest,
                            mockInstanceMetadataFactory)
     mockManifest.GetS3KeyPrefix.side_effect = lambda: "the prefix"
     self.assertTrue(inst.GetKeyPrefix(1000) == "the prefix/instances/1000")
     mockManifest.GetS3KeyPrefix.assert_any_call()
예제 #6
0
 def test_GetMetaFileTempPath(self):
     mockManifest = Mock(spec=Manifest)
     mockS3Interface = Mock(spec=S3Interface)
     mockS3Interface.localTempDir = "temp123"
     mockInstanceMetadataFactory = Mock(spec=InstanceMetadataFactory)
     inst = InstanceManager(mockS3Interface, mockManifest,
                            mockInstanceMetadataFactory)
     result = inst.GetMetaFileTempPath(10)
     self.assertEqual(result,
                      os.path.join("temp123", "instance_metadata10.json"))
예제 #7
0
 def test_downloadInstanceData(self):
     mockManifest = Mock(spec=Manifest)
     mockManifest.GetS3KeyPrefix.side_effect = lambda: "the prefix"
     mockS3Interface = Mock(spec=S3Interface)
     mockInstanceMetadataFactory = Mock(spec=InstanceMetadataFactory)
     inst = InstanceManager(mockS3Interface, mockManifest,
                            mockInstanceMetadataFactory)
     inst.uploadInstanceData(10000, "docname", "localPath")
     mockS3Interface.uploadFile.assert_has_calls(
         [call("localPath", "the prefix/instances/10000/docname", True)])
예제 #8
0
파일: pyqaws.py 프로젝트: lsiudut/pyqaws
    def addInstance(self, data):
        tab = data[0]
        instance = data[1]
        tabCount = tab.rowCount()

        tab.setRowCount(tabCount+1)
        for i in xrange(0, len(self.configAccountTabFields)):
            instance_manager = InstanceManager(instance, ro = True)
            item = AMITableWidgetItem(instance_manager)
            item.setText(instance_manager.get(self.configAccountTabFields[i][0]))
            tab.setItem(tabCount, i, item)

        tab.resizeColumnsToContents()
예제 #9
0
 def test_constructor(self):
     mockManifest = Mock(spec=Manifest)
     mockS3Interface = Mock(spec=S3Interface)
     mockInstanceMetaFac = Mock(spec=InstanceMetadataFactory)
     inst = InstanceManager(mockS3Interface, mockManifest,
                            mockInstanceMetaFac)
     self.assertTrue(inst.manifest == mockManifest)
     self.assertTrue(inst.s3Interface == mockS3Interface)
     self.assertTrue(inst.instanceMetadataFactory == mockInstanceMetaFac)
예제 #10
0
    def test_uploadMetaData(self):
        mockManifest = Mock(spec=Manifest)
        mockManifest.GetS3KeyPrefix.side_effect = lambda: ""
        mockS3Interface = Mock(spec=S3Interface)
        mockS3Interface.localTempDir = "tests"
        mockInstanceMetadataFactory = Mock(spec=InstanceMetadataFactory)
        mockMetadata = Mock(spec=InstanceMetadata)
        instId = 17
        mockMetadata.Get.side_effect = lambda key: {"Id": instId}[key]

        inst = InstanceManager(mockS3Interface, mockManifest,
                               mockInstanceMetadataFactory)

        tmpfile = inst.GetMetaFileTempPath(instId)
        with open(tmpfile, 'w') as tmp:
            tmp.write("nothing")

        inst.uploadMetaData(mockMetadata)

        self.assertFalse(os.path.exists(tmpfile))
        mockS3Interface.uploadFile.has_call()
        mockInstanceMetadataFactory.ToJson.assert_any_call(
            mockMetadata, tmpfile)
예제 #11
0
    def test_downloadMetaData(self):
        mockManifest = Mock(spec=Manifest)
        mockManifest.GetS3KeyPrefix.side_effect = lambda: ""
        mockS3Interface = Mock(spec=S3Interface)
        mockS3Interface.localTempDir = "tests"
        mockInstanceMetadataFactory = Mock(spec=InstanceMetadataFactory)
        inst = InstanceManager(mockS3Interface, mockManifest,
                               mockInstanceMetadataFactory)

        mockInstanceMetadataFactory.FromJson.side_effect = \
            lambda tmpfile : -9999

        instId = 10
        tmpfile = inst.GetMetaFileTempPath(instId)
        with open(tmpfile, 'w') as tmp:
            tmp.write("nothing")
        res = inst.downloadMetaData(instId)

        mockInstanceMetadataFactory.FromJson.assert_called_once_with(tmpfile)
        self.assertTrue(res == -9999)
        self.assertFalse(os.path.exists(tmpfile))
        mockManifest.GetS3KeyPrefix.has_call()
        mockS3Interface.downloadFile.has_call()
        self.assertFalse(os.path.exists(tmpfile))
예제 #12
0
def main():
    """to be run on by each instance as a startup command"""
    import argparse, sys
    import boto3
    #from powershell_s3 import powershell_s3
    from s3interface import S3Interface
    from manifest import Manifest
    from instancemanager import InstanceManager
    from instancemetadatafactory import InstanceMetadataFactory
    from loghelper import LogHelper
    parser = argparse.ArgumentParser(
        description="AWS Instance bootstrapper" +
        "Loads manifest which contains data and commands to run on this instance,"
        + "downloads data from S3, runs commands, and uploads results to S3")

    parser.add_argument("--bucketName",
                        help="the name of the S3 bucket to work with",
                        required=True)
    parser.add_argument(
        "--manifestKey",
        help="the key pointing to the manifest file in the s3 bucket",
        required=True)
    parser.add_argument(
        "--instanceId",
        help="the id of this instance as defined in the manifest file",
        required=True)
    parser.add_argument(
        "--localWorkingDir",
        help=
        "a directory to store working files, it will be created if it does not exist on the instance",
        required=True)

    try:
        #boto3.set_stream_logger(name='botocore')
        args = vars(parser.parse_args())
        bootstrapper = None

        bucketName = args["bucketName"]
        manifestKey = args["manifestKey"]
        instanceId = int(args["instanceId"])
        localWorkingDir = args["localWorkingDir"]

        if not os.path.exists(localWorkingDir):
            os.makedirs(localWorkingDir)
        logPath = LogHelper.instanceLogPath(localWorkingDir, instanceId)
        LogHelper.start_logging(logPath)
        logging.info("startup")
        logging.info("creating boto3 s3 resource")
        s3 = boto3.resource('s3')

        logging.info("creating S3Interface")
        s3interface = S3Interface(s3, bucketName, localWorkingDir)

        localManifestPath = os.path.join(localWorkingDir, "manifest.json")
        logging.info("downloading manifest from S3")
        s3interface.downloadFile(manifestKey, localManifestPath)
        manifest = Manifest(localManifestPath)
        metafac = InstanceMetadataFactory(manifest)
        instancemanager = InstanceManager(s3interface, manifest, metafac)
        metadata = instancemanager.downloadMetaData(instanceId)
        bootstrapper = AWSInstanceBootStrapper(instanceId, manifest,
                                               s3interface, instancemanager,
                                               metadata)
        bootstrapper.DownloadS3Documents()
        bootstrapper.RunCommands()
        bootstrapper.UploadS3Documents()
    except Exception as ex:
        logging.exception("error in bootstrapper")
        if bootstrapper is not None:
            bootstrapper.UploadStatus()
        sys.exit(1)
예제 #13
0
class MainWindow(QMainWindow):
    def __init__(self, *args):
        logging.debug('MainWindow creation')

        QMainWindow.__init__(self, *args)
        self.ui = Ui_MainWindow()
        logging.debug('MainWindow ui setup')
        self.ui.setupUi(self)

        self.instanceManager = InstanceManager(InstanceManager.getStoredKey())
        self.readConfig()
        self.setupModels()

        self.ui.treeView.activated.connect(self.updatePasswordsModel)
        self.ui.tableView.activated.connect(self.udpateDetailTabs)
        self.ui.actionQuit.triggered.connect(self.closeReally)
        self.ui.actionPreferences.triggered.connect(self.openPreferences)
        self.ui.actionRefresh.triggered.connect(self.refreshInstances)

        # Init QSystemTrayIcon
        icon = QIcon.fromTheme('dialog-passwords',
                               QIcon(':/icons/dialog-password.svg'))
        self.trayIcon = QSystemTrayIcon(icon, self)
        systrayMenu = QMenu(self)
        systrayMenu.addAction(self.ui.actionRefresh)
        systrayMenu.addAction(self.ui.actionQuit)
        self.trayIcon.setContextMenu(systrayMenu)
        self.trayIcon.show()
        self.trayIcon.activated.connect(self.handleSystray)

    def closeEvent(self, event):
        """ Close to systray
        """
        event.ignore()
        self.hide()

    def closeReally(self):
        """ Close by Quit action
        """
        exit(0)

    def handleSystray(self):
        if self.isVisible():
            self.hide()
        else:
            self.show()

    @Slot(QModelIndex)
    def updatePasswordsModel(self, index):
        logging.debug('MainWindow.updatePasswordsModel called')
        passwords = self.treeModel.getPasswords(index)
        self.listModel.setPasswords(passwords)

    def udpateDetailTabs(self, index):
        logging.debug('MainWindow.udpateDetailTabs called')
        password = self.listModel.getPassword(index.row())

        self.ui.detailTabWidget.setVisible(True)
        self.ui.detailTabWidget.setCurrentIndex(0)

        if 'notes' in password:
            self.ui.notesBrowser.setText(password['notes'])
            self.ui.tabNotes.setEnabled(True)
        else:
            self.ui.tabNotes.setEnabled(False)

        if 'revisions' in password:
            for i in password['revisions']:
                for key, val in i.items():
                    self.ui.revisionsBrowser.append(key + ': ' + str(val))
                self.ui.revisionsBrowser.append('\n')
            self.ui.tabRevisions.setEnabled(True)
        else:
            self.ui.tabRevisions.setEnabled(False)

        self.ui.detailsBrowser.clear()
        for key, val in password.items():
            if key not in ['notes', 'revisions']:
                self.ui.detailsBrowser.append(key + ': ' + str(val))

    def readConfig(self):
        self.ncInstances = []
        self.instanceManager.readConfig()
        for i, val in self.instanceManager.getInstances().items():
            logging.debug('reading: ' + i)
            instance = NextcloudInstance(description=val['name'],
                                         url=val['url'],
                                         username=val['username'],
                                         password=val['password'],
                                         verifySSL=val['verifySSL'])
            self.ncInstances.append(instance)

    def setupModels(self):
        self.ui.treeView.blockSignals(True)

        self.ui.detailTabWidget.setVisible(False)

        self.treeModel = NCTreeModel(self.ncInstances, self)
        self.listModel = PasswordsModel(self)
        self.ui.treeView.setModel(self.treeModel)

        self.ui.treeView.blockSignals(False)

        self.ui.tableView.setModel(self.listModel)

    def openPreferences(self):
        dia = PreferencesDialog(self.instanceManager.getInstances())
        if (dia.exec_()):
            self.instanceManager.replaceInstances(dia.getInstances())
            self.instanceManager.writeConfig()
            self.refreshInstances()

    def refreshInstances(self):
        self.readConfig()
        self.setupModels()