def __init__(self, start=False):
        output('Welcome to MiniCloud!\n')

        super(MiniCloudMgnt, self).__init__(self.setup_minicloud())
        self.cloud_mgnt = CloudMgnt(self)
        self.cluster_mgnt = ClusterMgnt(self)
        self.instance_mgnt = InstanceMgnt(self)
        self.network_mgnt = NetworkMgnt(self)
        self.router_mgnt = RouterMgnt(self)
        self.first_topology = True
        if start:
            self.manage_entities()
class MiniCloudMgnt(EntityMgnt):

    def __init__(self, start=False):
        output('Welcome to MiniCloud!\n')

        super(MiniCloudMgnt, self).__init__(self.setup_minicloud())
        self.cloud_mgnt = CloudMgnt(self)
        self.cluster_mgnt = ClusterMgnt(self)
        self.instance_mgnt = InstanceMgnt(self)
        self.network_mgnt = NetworkMgnt(self)
        self.router_mgnt = RouterMgnt(self)
        self.first_topology = True
        if start:
            self.manage_entities()

    def obtain_choices(self):
        class Choices:
            def __init__(self):
                pass

            CLOUD_DEPLOYMENT_OVERVIEW = 1
            CLOUD_MGNT = 2
            CLUSTER_MGNT = 3
            ROUTER_MGNT = 4
            NETWORK_MGNT = 5
            INSTANCE_MGNT = 6
            RESET = 7
            DESTROY_ALL = 8

            options_list = ['Cloud deployment topology',
                            'Cloud management',
                            'Cluster management',
                            'Router management',
                            'Network management',
                            'Instance management',
                            'Reset to startup',
                            'Destroy all data and exit',
                            'Exit (keep data)']
        return Choices()

    def manage_entities(self):
        while True:
            choices = self.obtain_choices()
            choice = choice_input_list('MiniCloud', choices.options_list)

            if choice == choices.CLOUD_DEPLOYMENT_OVERVIEW:
                self.topologize()
            elif choice == choices.CLOUD_MGNT:
                self.cloud_mgnt.manage_entities()
            elif choice == choices.CLUSTER_MGNT:
                self.cluster_mgnt.manage_entities()
            elif choice == choices.ROUTER_MGNT:
                self.router_mgnt.manage_entities()
            elif choice == choices.NETWORK_MGNT:
                self.network_mgnt.manage_entities()
            elif choice == choices.INSTANCE_MGNT:
                self.instance_mgnt.manage_entities()
            elif choice == choices.RESET:
                self.reset()
            elif choice == choices.DESTROY_ALL:
                self.drop_all()
                self.end_program()
                break
            else:
                self.end_program()
                break

    @staticmethod
    def obtain_db_credentials(db_host, db_username, db_password, db_name):
        return DatabaseCredentials(shell_input('Database host', db_host, default='localhost'),
                                   shell_input('Database username', db_username, default='minicloud'),
                                   shell_input('Database password', db_password, default='password'),
                                   shell_input('Database name', db_name, default='minicloud'))

    @staticmethod
    def setup_minicloud():
        database = None
        try:
            output('Setting up MiniCloud ...')
            database = MiniCloudMgnt.obtain_db_credentials('MINICLOUD_DB_HOST', 'MINICLOUD_DB_USERNAME',
                                                           'MINICLOUD_DB_PASSWORD', 'MINICLOUD_DB_NAME')
            mc = MiniCloud(database)
            print
            if mc.system.get_setting('first_use') is None:
                mc.system.set_setting('first_use', datetime.datetime.now().strftime('%d-%m-%Y'))
                output('This is the first use of MiniCloud!')
            else:
                output('The first use of MiniCloud was %s!', mc.system.get_setting('first_use'))
            return mc

        except DatabaseException as e:
            output(e)
            output('Please make sure you have a MySql server running,\n'
                   'the MiniCloud database is present and users are provisioned.\n\n'
                   'Install mysql-server\n\n'
                   'give: mysql -u root -p\n'
                   '<password>\n\n'
                   'mysql> CREATE DATABASE %s;', database.database)
            if database.username != 'root':
                output('mysql> CREATE USER \'%s\'@\'%s\' IDENTIFIED BY \'%s\';',
                       database.username, database.host, database.password)
                output('mysql> GRANT ALL PRIVILEGES ON %s.* to %s@%s;',
                       database.database, database.username, database.host)
                output('mysql> FLUSH PRIVILEGES;')
            output('mysql> exit;')
            fatal_error()

    def get_topology(self, indent=''):
        deep_topology = self.first_topology
        show_empty_compute_entities = False
        show_empty_network_entities = True

        if not boolean_input('Default topology parameters' + (' (DEEP fetch)' if deep_topology else '')):
            deep_topology = self.force_deep_topology()
            show_empty_compute_entities = boolean_input(
                'Show empty compute entities', show_empty_compute_entities)
            show_empty_network_entities = boolean_input(
                'Show empty network entities', show_empty_network_entities)

        self.first_topology = False
        return self.build_topology(deep_topology, 'MiniCloud', indent, indent,
                                   show_empty_compute_entities=show_empty_compute_entities,
                                   show_empty_network_entities=show_empty_network_entities)

    def topology(self, entity, deep_topology, root_prefix="", prefix="", show_empty_entities=False):
        pass

    def build_topology(self, deep_topology=False,
                       root=None, root_prefix='', prefix='', entity=None,
                       skip_head=False, skip_prebuild=False,
                       list_entities=None, entity_mgnt=None,
                       show_empty_compute_entities=True, show_empty_network_entities=True):
        s = ''
        head = root_prefix + root + '\n' + root_prefix + '|\n'
        sn, nc = self.router_mgnt.build_topology(
            deep_topology, 'Networking', prefix + '+---', prefix + '    ',
            show_empty_entities=show_empty_network_entities)

        cline = '|' if nc else ' '
        sc, cc = self.cloud_mgnt.build_topology(
            deep_topology, 'Compute', prefix + '+---', prefix + cline + '   ',
            show_empty_entities=show_empty_compute_entities)
        if cc:
            s = head + sc
            if nc:
                s = s + prefix + '|\n' + sn
        elif nc:
            s = head + sn

        return s, cc+nc

    def reset(self):
        output('Reset\'ing.')
        self.manager.reset()
        self.first_topology = True
        output('Done.')

    def drop_all(self):
        if boolean_input('Are you ABSOLUTELY sure you want to do this', default=False):
            if boolean_input('Once again, ABSOLUTELY sure', default=False):
                self.manager.drop(boolean_input('Do you want to clean up the deployed data also (Y)'
                                                ' or is pure db clear sufficient (n)'))
                output('All data is cleared.')
                return

        # else
        output('Aborted.')

    def obtain_entity_to_add(self):
        pass

    @staticmethod
    def print_header():
        output('\n== MINICLOUD v1.0 ==\n\n')

    @staticmethod
    def end_program():
        output('Thanks for using MiniCloud.\n'
               'Enjoy your day.')