Beispiel #1
0
    def execute(self, args):
        """ Quickly creates Zato components
        1) CA and crypto material
        2) ODB
        3) ODB initial data
        4) server1
        5) server2
        6) load-balancer
        7) Web admin
        8) Scripts
        """
        next_step = count(1)
        next_port = count(http_plain_server_port)
        total_steps = 8
        cluster_name = 'quickstart-{}'.format(random.getrandbits(20)).zfill(7)
        server_names = {'1': 'server1', '2': 'server2'}
        admin_invoke_password = uuid4().hex
        broker_host = 'localhost'
        broker_port = 6379
        lb_host = 'localhost'
        lb_port = 11223
        lb_agent_port = 20151

        args_path = os.path.abspath(args.path)

        # This could've been set to True by user in the command-line so we'd want
        # to unset it so that individual commands quickstart invokes don't attempt
        # to store their own configs.
        args.store_config = False

        #
        # 1) CA
        #
        ca_path = os.path.join(args_path, 'ca')
        os.mkdir(ca_path)

        ca_args = self._bunch_from_args(args, cluster_name)
        ca_args.path = ca_path

        ca_args_server1 = deepcopy(ca_args)
        ca_args_server1.server_name = server_names['1']

        ca_args_server2 = deepcopy(ca_args)
        ca_args_server2.server_name = server_names['2']

        ca_create_ca.Create(ca_args).execute(ca_args, False)
        ca_create_lb_agent.Create(ca_args).execute(ca_args, False)

        ca_create_server.Create(ca_args_server1).execute(
            ca_args_server1, False)
        ca_create_server.Create(ca_args_server2).execute(
            ca_args_server2, False)

        ca_create_web_admin.Create(ca_args).execute(ca_args, False)

        server_crypto_loc = {}
        for key in server_names:
            server_crypto_loc[key] = CryptoMaterialLocation(
                ca_path, '{}-{}'.format(cluster_name, server_names[key]))

        lb_agent_crypto_loc = CryptoMaterialLocation(ca_path, 'lb-agent')
        web_admin_crypto_loc = CryptoMaterialLocation(ca_path, 'web-admin')

        self.logger.info('[{}/{}] Certificate authority created'.format(
            next_step.next(), total_steps))

        #
        # 2) ODB
        #
        if create_odb.Create(args).execute(args,
                                           False) == self.SYS_ERROR.ODB_EXISTS:
            self.logger.info('[{}/{}] ODB schema already exists'.format(
                next_step.next(), total_steps))
        else:
            self.logger.info('[{}/{}] ODB schema created'.format(
                next_step.next(), total_steps))

        #
        # 3) ODB initial data
        #
        create_cluster_args = self._bunch_from_args(args, cluster_name)
        create_cluster_args.broker_host = broker_host
        create_cluster_args.broker_port = broker_port
        create_cluster_args.lb_host = lb_host
        create_cluster_args.lb_port = lb_port
        create_cluster_args.lb_agent_port = lb_agent_port
        create_cluster_args.admin_invoke_password = admin_invoke_password
        create_cluster.Create(create_cluster_args).execute(
            create_cluster_args, False)

        self.logger.info('[{}/{}] ODB initial data created'.format(
            next_step.next(), total_steps))

        #
        # 4) server1
        # 5) server2
        #
        for key in server_names:
            server_path = os.path.join(args_path, server_names[key])
            os.mkdir(server_path)

            create_server_args = self._bunch_from_args(args, cluster_name)
            create_server_args.server_name = server_names[key]
            create_server_args.path = server_path
            create_server_args.cert_path = server_crypto_loc[key].cert_path
            create_server_args.pub_key_path = server_crypto_loc[key].pub_path
            create_server_args.priv_key_path = server_crypto_loc[key].priv_path
            create_server_args.ca_certs_path = server_crypto_loc[
                key].ca_certs_path

            create_server.Create(create_server_args).execute(
                create_server_args, next_port.next(), False)

            self.logger.info('[{}/{}] server{} created'.format(
                next_step.next(), total_steps, key))

        #
        # 6) load-balancer
        #
        lb_path = os.path.join(args_path, 'load-balancer')
        os.mkdir(lb_path)

        create_lb_args = self._bunch_from_args(args, cluster_name)
        create_lb_args.path = lb_path
        create_lb_args.cert_path = lb_agent_crypto_loc.cert_path
        create_lb_args.pub_key_path = lb_agent_crypto_loc.pub_path
        create_lb_args.priv_key_path = lb_agent_crypto_loc.priv_path
        create_lb_args.ca_certs_path = lb_agent_crypto_loc.ca_certs_path

        # Need to substract 1 because we've already called .next() twice
        # when creating servers above.
        server2_port = next_port.next() - 1

        create_lb.Create(create_lb_args).execute(create_lb_args, True,
                                                 server2_port, False)
        self.logger.info('[{}/{}] Load-balancer created'.format(
            next_step.next(), total_steps))

        #
        # 7) Web admin
        #
        web_admin_path = os.path.join(args_path, 'web-admin')
        os.mkdir(web_admin_path)

        create_web_admin_args = self._bunch_from_args(args, cluster_name)
        create_web_admin_args.path = web_admin_path
        create_web_admin_args.cert_path = web_admin_crypto_loc.cert_path
        create_web_admin_args.pub_key_path = web_admin_crypto_loc.pub_path
        create_web_admin_args.priv_key_path = web_admin_crypto_loc.priv_path
        create_web_admin_args.ca_certs_path = web_admin_crypto_loc.ca_certs_path
        create_web_admin_args.admin_invoke_password = admin_invoke_password

        password = generate_password()
        admin_created = create_web_admin.Create(create_web_admin_args).execute(
            create_web_admin_args, False, password, True)

        # Need to reset the logger here because executing the create_web_admin command
        # loads the web admin's logger which doesn't like that of ours.
        self.reset_logger(args, True)
        self.logger.info('[{}/{}] Web admin created'.format(
            next_step.next(), total_steps))

        #
        # 8) Scripts
        #
        zato_bin = 'zato'
        zato_qs_start_path = os.path.join(args_path, 'zato-qs-start.sh')
        zato_qs_stop_path = os.path.join(args_path, 'zato-qs-stop.sh')
        zato_qs_restart_path = os.path.join(args_path, 'zato-qs-restart.sh')

        open(zato_qs_start_path, 'w').write(
            zato_qs_start_template.format(zato_bin=zato_bin,
                                          script_dir=script_dir))
        open(zato_qs_stop_path, 'w').write(
            zato_qs_stop_template.format(zato_bin=zato_bin,
                                         script_dir=script_dir))
        open(zato_qs_restart_path,
             'w').write(zato_qs_restart.format(script_dir=script_dir))

        file_mod = stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | stat.S_IRGRP

        os.chmod(zato_qs_start_path, file_mod)
        os.chmod(zato_qs_stop_path, file_mod)
        os.chmod(zato_qs_restart_path, file_mod)

        self.logger.info('[{}/{}] Management scripts created'.format(
            next_step.next(), total_steps))
        self.logger.info('Quickstart cluster {} created'.format(cluster_name))

        if admin_created:
            self.logger.info(
                'Web admin user:[admin], password:[{}]'.format(password))
        else:
            self.logger.info('User [admin] already exists in the ODB')

        start_command = os.path.join(args_path, 'zato-qs-start.sh')
        self.logger.info('Start the cluster by issuing the {} command'.format(
            start_command))
        self.logger.info(
            'Visit https://zato.io/support for more information and support options'
        )
Beispiel #2
0
    def execute(self,
                args,
                show_output=True,
                password=None,
                needs_admin_created_flag=False):
        os.chdir(self.target_dir)

        repo_dir = os.path.join(self.target_dir, 'config', 'repo')
        web_admin_conf_path = os.path.join(repo_dir, 'web-admin.conf')
        initial_data_json_path = os.path.join(repo_dir, 'initial-data.json')

        os.mkdir(os.path.join(self.target_dir, 'logs'))
        os.mkdir(os.path.join(self.target_dir, 'config'))
        os.mkdir(repo_dir)

        user_name = 'admin'
        password = password if password else generate_password()

        self.copy_web_admin_crypto(repo_dir, args)
        priv_key = open(os.path.join(repo_dir,
                                     'web-admin-priv-key.pem')).read()

        config = {
            'host':
            web_admin_host,
            'port':
            web_admin_port,
            'db_type':
            args.odb_type,
            'log_config':
            'logging.conf',
            'DATABASE_NAME':
            args.odb_db_name or args.sqlite_path,
            'DATABASE_USER':
            args.odb_user or '',
            'DATABASE_PASSWORD':
            encrypt(args.odb_password, priv_key) if args.odb_password else '',
            'DATABASE_HOST':
            args.odb_host or '',
            'DATABASE_PORT':
            args.odb_port or '',
            'SITE_ID':
            getrandbits(20),
            'SECRET_KEY':
            encrypt(uuid.uuid4().hex, priv_key),
            'ADMIN_INVOKE_NAME':
            'admin.invoke',
            'ADMIN_INVOKE_PASSWORD':
            encrypt(
                getattr(args, 'admin_invoke_password', None)
                or getattr(args, 'tech_account_password'), priv_key),
        }

        open(os.path.join(repo_dir, 'logging.conf'), 'w').write(
            common_logging_conf_contents.format(
                log_path='./logs/web-admin.log'))
        open(web_admin_conf_path, 'w').write(config_template.format(**config))
        open(initial_data_json_path,
             'w').write(initial_data_json.format(**config))

        # Initial info
        self.store_initial_info(self.target_dir,
                                self.COMPONENTS.WEB_ADMIN.code)

        config = json.loads(
            open(os.path.join(repo_dir, 'web-admin.conf')).read())
        config['config_dir'] = self.target_dir
        update_globals(config, self.target_dir)

        os.environ['DJANGO_SETTINGS_MODULE'] = 'zato.admin.settings'

        import django
        django.setup()
        self.reset_logger(args, True)

        # Can't import these without DJANGO_SETTINGS_MODULE being set
        from django.contrib.auth.models import User
        from django.db import connection
        from django.db.utils import IntegrityError

        call_command('migrate',
                     run_syncdb=True,
                     interactive=False,
                     verbosity=0)
        call_command('loaddata', initial_data_json_path, verbosity=0)

        try:
            call_command('createsuperuser',
                         interactive=False,
                         username=user_name,
                         first_name='admin-first-name',
                         last_name='admin-last-name',
                         email='*****@*****.**')
            admin_created = True

            user = User.objects.get(username=user_name)
            user.set_password(password)
            user.save()

        except IntegrityError, e:
            admin_created = False
            connection._rollback()
            self.logger.info('Ignoring IntegrityError e:[%s]',
                             format_exc(e).decode('utf-8'))
Beispiel #3
0
    def execute(self, args):
        """ Quickly creates Zato components
        1) CA and crypto material
        2) ODB
        3) ODB initial data
        4) servers
        5) load-balancer
        6) Web admin
        7) Scheduler
        8) Scripts
        """

        if args.odb_type == 'sqlite':
            args.sqlite_path = os.path.abspath(
                os.path.join(args.path, 'zato.db'))
        '''
        cluster_id_args = Bunch()
        cluster_id_args.odb_db_name = args.odb_db_name
        cluster_id_args.odb_host = args.odb_host
        cluster_id_args.odb_password = args.odb_password
        cluster_id_args.odb_port = args.odb_port
        cluster_id_args.odb_type = args.odb_type
        cluster_id_args.odb_user = args.odb_user
        cluster_id_args.postgresql_schema = args.postgresql_schema
        cluster_id_args.sqlite_path = args.sqlite_path
        '''

        next_step = count(1)
        next_port = count(http_plain_server_port)
        cluster_name = getattr(args, 'cluster_name',
                               None) or 'quickstart-{}'.format(
                                   random.getrandbits(20)).zfill(7)
        servers = int(getattr(args, 'servers', 0) or DEFAULT_NO_SERVERS)

        server_names = OrderedDict()
        for idx in range(1, servers + 1):
            server_names['{}'.format(idx)] = 'server{}'.format(idx)

        total_steps = 7 + servers
        admin_invoke_password = uuid4().hex
        broker_host = 'localhost'
        broker_port = 6379
        lb_host = 'localhost'
        lb_port = 11223
        lb_agent_port = 20151

        args_path = os.path.abspath(args.path)

        # This could've been set to True by user in the command-line so we'd want
        # to unset it so that individual commands quickstart invokes don't attempt
        # to store their own configs.
        args.store_config = False

        # ################################################################################################################################

        #
        # 1) CA
        #
        ca_path = os.path.join(args_path, 'ca')
        os.mkdir(ca_path)

        ca_args = self._bunch_from_args(args, cluster_name)
        ca_args.path = ca_path

        ca_create_ca.Create(ca_args).execute(ca_args, False)
        ca_create_lb_agent.Create(ca_args).execute(ca_args, False)
        ca_create_web_admin.Create(ca_args).execute(ca_args, False)
        ca_create_scheduler.Create(ca_args).execute(ca_args, False)

        server_crypto_loc = {}

        for name in server_names:
            ca_args_server = deepcopy(ca_args)
            ca_args_server.server_name = server_names[name]
            ca_create_server.Create(ca_args_server).execute(
                ca_args_server, False)
            server_crypto_loc[name] = CryptoMaterialLocation(
                ca_path, '{}-{}'.format(cluster_name, server_names[name]))

        lb_agent_crypto_loc = CryptoMaterialLocation(ca_path, 'lb-agent')
        web_admin_crypto_loc = CryptoMaterialLocation(ca_path, 'web-admin')
        scheduler_crypto_loc = CryptoMaterialLocation(ca_path, 'scheduler1')

        self.logger.info('[{}/{}] Certificate authority created'.format(
            next_step.next(), total_steps))

        # ################################################################################################################################

        #
        # 2) ODB
        #
        if create_odb.Create(args).execute(args,
                                           False) == self.SYS_ERROR.ODB_EXISTS:
            self.logger.info('[{}/{}] ODB schema already exists'.format(
                next_step.next(), total_steps))
        else:
            self.logger.info('[{}/{}] ODB schema created'.format(
                next_step.next(), total_steps))

# ################################################################################################################################

#
# 3) ODB initial data
#
        create_cluster_args = self._bunch_from_args(args, cluster_name)
        create_cluster_args.broker_host = broker_host
        create_cluster_args.broker_port = broker_port
        create_cluster_args.lb_host = lb_host
        create_cluster_args.lb_port = lb_port
        create_cluster_args.lb_agent_port = lb_agent_port
        create_cluster_args.admin_invoke_password = admin_invoke_password
        create_cluster.Create(create_cluster_args).execute(
            create_cluster_args, False)

        self.logger.info('[{}/{}] ODB initial data created'.format(
            next_step.next(), total_steps))

        # ################################################################################################################################

        #
        # 4) servers
        #

        # Must be shared by all servers
        jwt_secret = Fernet.generate_key()

        for name in server_names:
            server_path = os.path.join(args_path, server_names[name])
            os.mkdir(server_path)

            create_server_args = self._bunch_from_args(args, cluster_name)
            create_server_args.server_name = server_names[name]
            create_server_args.path = server_path
            create_server_args.cert_path = server_crypto_loc[name].cert_path
            create_server_args.pub_key_path = server_crypto_loc[name].pub_path
            create_server_args.priv_key_path = server_crypto_loc[
                name].priv_path
            create_server_args.ca_certs_path = server_crypto_loc[
                name].ca_certs_path
            create_server_args.jwt_secret = jwt_secret

            create_server.Create(create_server_args).execute(
                create_server_args, next_port.next(), False)

            self.logger.info('[{}/{}] server{} created'.format(
                next_step.next(), total_steps, name))

# ################################################################################################################################

#
# 5) load-balancer
#
        lb_path = os.path.join(args_path, 'load-balancer')
        os.mkdir(lb_path)

        create_lb_args = self._bunch_from_args(args, cluster_name)
        create_lb_args.path = lb_path
        create_lb_args.cert_path = lb_agent_crypto_loc.cert_path
        create_lb_args.pub_key_path = lb_agent_crypto_loc.pub_path
        create_lb_args.priv_key_path = lb_agent_crypto_loc.priv_path
        create_lb_args.ca_certs_path = lb_agent_crypto_loc.ca_certs_path

        # Need to substract 1 because we've already called .next() twice
        # when creating servers above.
        servers_port = next_port.next() - 1

        create_lb.Create(create_lb_args).execute(create_lb_args, True,
                                                 servers_port, False)
        self.logger.info('[{}/{}] Load-balancer created'.format(
            next_step.next(), total_steps))

        # ################################################################################################################################

        #
        # 6) Web admin
        #
        web_admin_path = os.path.join(args_path, 'web-admin')
        os.mkdir(web_admin_path)

        create_web_admin_args = self._bunch_from_args(args, cluster_name)
        create_web_admin_args.path = web_admin_path
        create_web_admin_args.cert_path = web_admin_crypto_loc.cert_path
        create_web_admin_args.pub_key_path = web_admin_crypto_loc.pub_path
        create_web_admin_args.priv_key_path = web_admin_crypto_loc.priv_path
        create_web_admin_args.ca_certs_path = web_admin_crypto_loc.ca_certs_path
        create_web_admin_args.admin_invoke_password = admin_invoke_password

        password = generate_password()
        admin_created = create_web_admin.Create(create_web_admin_args).execute(
            create_web_admin_args, False, password, True)

        # Need to reset the logger here because executing the create_web_admin command
        # loads the web admin's logger which doesn't like that of ours.
        self.reset_logger(args, True)
        self.logger.info('[{}/{}] Web admin created'.format(
            next_step.next(), total_steps))

        # ################################################################################################################################

        #
        # 7) Scheduler
        #
        scheduler_path = os.path.join(args_path, 'scheduler')
        os.mkdir(scheduler_path)

        session = get_session(get_engine(args))

        with closing(session):
            cluster_id = session.query(Cluster.id).\
                filter(Cluster.name==cluster_name).\
                one()[0]

        create_scheduler_args = self._bunch_from_args(args, cluster_name)
        create_scheduler_args.path = scheduler_path
        create_scheduler_args.cert_path = scheduler_crypto_loc.cert_path
        create_scheduler_args.pub_key_path = scheduler_crypto_loc.pub_path
        create_scheduler_args.priv_key_path = scheduler_crypto_loc.priv_path
        create_scheduler_args.ca_certs_path = scheduler_crypto_loc.ca_certs_path
        create_scheduler_args.cluster_id = cluster_id

        password = generate_password()
        admin_created = create_scheduler.Create(create_scheduler_args).execute(
            create_scheduler_args, False, password, True)

        self.logger.info('[{}/{}] Scheduler created'.format(
            next_step.next(), total_steps))

        # ################################################################################################################################

        #
        # 8) Scripts
        #
        zato_bin = 'zato'
        zato_qs_start_path = os.path.join(args_path, 'zato-qs-start.sh')
        zato_qs_stop_path = os.path.join(args_path, 'zato-qs-stop.sh')
        zato_qs_restart_path = os.path.join(args_path, 'zato-qs-restart.sh')

        sanity_checks = []
        start_servers = []
        stop_servers = []

        for name in server_names:
            sanity_checks.append(
                sanity_checks_template.format(server_name=server_names[name]))
            start_servers.append(
                start_servers_template.format(server_name=server_names[name],
                                              step_number=int(name) + 3))
            stop_servers.append(
                stop_servers_template.format(server_name=server_names[name],
                                             step_number=int(name) + 1))

        sanity_checks = '\n'.join(sanity_checks)
        start_servers = '\n'.join(start_servers)
        stop_servers = '\n'.join(stop_servers)
        start_steps = 4 + servers
        stop_steps = 2 + servers

        zato_qs_start_head = zato_qs_start_head_template.format(
            zato_bin=zato_bin,
            script_dir=script_dir,
            cluster_name=cluster_name,
            start_steps=start_steps)
        zato_qs_start_body = zato_qs_start_body_template.format(
            sanity_checks=sanity_checks, start_servers=start_servers)
        zato_qs_start = zato_qs_start_head + zato_qs_start_body + zato_qs_start_tail

        zato_qs_stop = zato_qs_stop_template.format(zato_bin=zato_bin,
                                                    script_dir=script_dir,
                                                    cluster_name=cluster_name,
                                                    stop_steps=stop_steps,
                                                    stop_servers=stop_servers)

        open(zato_qs_start_path, 'w').write(zato_qs_start)
        open(zato_qs_stop_path, 'w').write(zato_qs_stop)
        open(zato_qs_restart_path, 'w').write(
            zato_qs_restart.format(script_dir=script_dir,
                                   cluster_name=cluster_name))

        file_mod = stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | stat.S_IRGRP

        os.chmod(zato_qs_start_path, file_mod)
        os.chmod(zato_qs_stop_path, file_mod)
        os.chmod(zato_qs_restart_path, file_mod)

        self.logger.info('[{}/{}] Management scripts created'.format(
            next_step.next(), total_steps))
        self.logger.info('Quickstart cluster {} created'.format(cluster_name))

        if admin_created:
            self.logger.info(
                'Web admin user:[admin], password:[{}]'.format(password))
        else:
            self.logger.info('User [admin] already exists in the ODB')

        start_command = os.path.join(args_path, 'zato-qs-start.sh')
        self.logger.info('Start the cluster by issuing the {} command'.format(
            start_command))
        self.logger.info(
            'Visit https://zato.io/support for more information and support options'
        )
Beispiel #4
0
    def execute(self, args, show_output=True, password=None):
        os.chdir(self.target_dir)

        repo_dir = os.path.join(self.target_dir, 'config', 'repo')
        zato_admin_conf_path = os.path.join(repo_dir, 'zato-admin.conf')
        initial_data_json_path = os.path.join(repo_dir, 'initial-data.json')

        os.mkdir(os.path.join(self.target_dir, 'logs'))
        os.mkdir(os.path.join(self.target_dir, 'config'))
        os.mkdir(os.path.join(self.target_dir, 'config', 'zdaemon'))
        os.mkdir(repo_dir)
        
        user_name = 'admin'
        password = password if password else generate_password()
        
        self.copy_zato_admin_crypto(repo_dir, args)
        pub_key = open(os.path.join(repo_dir, 'zato-admin-pub-key.pem')).read()
        
        config = {
            'host': zato_admin_host,
            'port': zato_admin_port,
            'db_type': args.odb_type,
            'log_config': 'logging.conf',
            'DATABASE_NAME': args.odb_db_name,
            'DATABASE_USER': args.odb_user,
            'DATABASE_PASSWORD': encrypt(args.odb_password, pub_key),
            'DATABASE_HOST': args.odb_host,
            'DATABASE_PORT': args.odb_port,
            'SITE_ID': getrandbits(20),
            'SECRET_KEY': encrypt(uuid.uuid4().hex, pub_key),
            'TECH_ACCOUNT_NAME':args.tech_account_name,
            'TECH_ACCOUNT_PASSWORD':encrypt(args.tech_account_password, pub_key),
        }
        
        open(os.path.join(repo_dir, 'logging.conf'), 'w').write(common_logging_conf_contents.format(log_path='./logs/zato-admin.log'))
        open(zato_admin_conf_path, 'w').write(config_template.format(**config))
        open(initial_data_json_path, 'w').write(initial_data_json.format(**config))
        
        # Initial info
        self.store_initial_info(self.target_dir, self.COMPONENTS.ZATO_ADMIN.code)
        
        config = json.loads(open(os.path.join(repo_dir, 'zato-admin.conf')).read())
        config['config_dir'] = self.target_dir
        update_globals(config, self.target_dir)
        
        os.environ['DJANGO_SETTINGS_MODULE'] = 'zato.admin.settings'
        
        # Can't import these without DJANGO_SETTINGS_MODULE being set
        from django.contrib.auth.models import User
        from django.db import connection
        from django.db.utils import IntegrityError
        
        call_command('syncdb', interactive=False, verbosity=0)
        call_command('loaddata', initial_data_json_path, verbosity=0)
        
        try:
            call_command('createsuperuser', interactive=False, username=user_name, first_name='admin-first-name',
                                     last_name='admin-last-name', email='*****@*****.**')
            admin_created = True
        except IntegrityError, e:
            admin_created = False
            connection._rollback()
            msg = 'Ignoring IntegrityError e:[{}]'.format(format_exc(e))
            self.logger.info(msg)
Beispiel #5
0
    def execute(self, args):
        """ Quickly creates Zato components
        1) CA and crypto material
        2) ODB
        3) ODB initial data
        4) server1
        5) server2
        6) load-balancer
        7) Web admin
        8) Scripts
        """
        next_step = count(1)
        next_port = count(http_plain_server_port)
        total_steps = 8
        cluster_name = "quickstart-{}".format(random.getrandbits(20)).zfill(7)
        server_names = {"1": "server1", "2": "server2"}
        admin_invoke_password = uuid4().hex
        broker_host = "localhost"
        broker_port = 6379
        lb_host = "localhost"
        lb_port = 11223
        lb_agent_port = 20151

        args_path = os.path.abspath(args.path)

        # This could've been set to True by user in the command-line so we'd want
        # to unset it so that individual commands quickstart invokes don't attempt
        # to store their own configs.
        args.store_config = False

        #
        # 1) CA
        #
        ca_path = os.path.join(args_path, "ca")
        os.mkdir(ca_path)

        ca_args = self._bunch_from_args(args, cluster_name)
        ca_args.path = ca_path

        ca_args_server1 = deepcopy(ca_args)
        ca_args_server1.server_name = server_names["1"]

        ca_args_server2 = deepcopy(ca_args)
        ca_args_server2.server_name = server_names["2"]

        ca_create_ca.Create(ca_args).execute(ca_args, False)
        ca_create_lb_agent.Create(ca_args).execute(ca_args, False)

        ca_create_server.Create(ca_args_server1).execute(ca_args_server1, False)
        ca_create_server.Create(ca_args_server2).execute(ca_args_server2, False)

        ca_create_web_admin.Create(ca_args).execute(ca_args, False)

        server_crypto_loc = {}
        for key in server_names:
            server_crypto_loc[key] = CryptoMaterialLocation(ca_path, "{}-{}".format(cluster_name, server_names[key]))

        lb_agent_crypto_loc = CryptoMaterialLocation(ca_path, "lb-agent")
        web_admin_crypto_loc = CryptoMaterialLocation(ca_path, "web-admin")

        self.logger.info("[{}/{}] Certificate authority created".format(next_step.next(), total_steps))

        #
        # 2) ODB
        #
        if create_odb.Create(args).execute(args, False) == self.SYS_ERROR.ODB_EXISTS:
            self.logger.info("[{}/{}] ODB schema already exists".format(next_step.next(), total_steps))
        else:
            self.logger.info("[{}/{}] ODB schema created".format(next_step.next(), total_steps))

        #
        # 3) ODB initial data
        #
        create_cluster_args = self._bunch_from_args(args, cluster_name)
        create_cluster_args.broker_host = broker_host
        create_cluster_args.broker_port = broker_port
        create_cluster_args.lb_host = lb_host
        create_cluster_args.lb_port = lb_port
        create_cluster_args.lb_agent_port = lb_agent_port
        create_cluster_args.admin_invoke_password = admin_invoke_password
        create_cluster.Create(create_cluster_args).execute(create_cluster_args, False)

        self.logger.info("[{}/{}] ODB initial data created".format(next_step.next(), total_steps))

        #
        # 4) server1
        # 5) server2
        #
        for key in server_names:
            server_path = os.path.join(args_path, server_names[key])
            os.mkdir(server_path)

            create_server_args = self._bunch_from_args(args, cluster_name)
            create_server_args.server_name = server_names[key]
            create_server_args.path = server_path
            create_server_args.cert_path = server_crypto_loc[key].cert_path
            create_server_args.pub_key_path = server_crypto_loc[key].pub_path
            create_server_args.priv_key_path = server_crypto_loc[key].priv_path
            create_server_args.ca_certs_path = server_crypto_loc[key].ca_certs_path

            create_server.Create(create_server_args).execute(create_server_args, next_port.next(), False)

            self.logger.info("[{}/{}] server{} created".format(next_step.next(), total_steps, key))

        #
        # 6) load-balancer
        #
        lb_path = os.path.join(args_path, "load-balancer")
        os.mkdir(lb_path)

        create_lb_args = self._bunch_from_args(args, cluster_name)
        create_lb_args.path = lb_path
        create_lb_args.cert_path = lb_agent_crypto_loc.cert_path
        create_lb_args.pub_key_path = lb_agent_crypto_loc.pub_path
        create_lb_args.priv_key_path = lb_agent_crypto_loc.priv_path
        create_lb_args.ca_certs_path = lb_agent_crypto_loc.ca_certs_path

        # Need to substract 1 because we've already called .next() twice
        # when creating servers above.
        server2_port = next_port.next() - 1

        create_lb.Create(create_lb_args).execute(create_lb_args, True, server2_port, False)
        self.logger.info("[{}/{}] Load-balancer created".format(next_step.next(), total_steps))

        #
        # 7) Web admin
        #
        web_admin_path = os.path.join(args_path, "web-admin")
        os.mkdir(web_admin_path)

        create_web_admin_args = self._bunch_from_args(args, cluster_name)
        create_web_admin_args.path = web_admin_path
        create_web_admin_args.cert_path = web_admin_crypto_loc.cert_path
        create_web_admin_args.pub_key_path = web_admin_crypto_loc.pub_path
        create_web_admin_args.priv_key_path = web_admin_crypto_loc.priv_path
        create_web_admin_args.ca_certs_path = web_admin_crypto_loc.ca_certs_path
        create_web_admin_args.admin_invoke_password = admin_invoke_password

        password = generate_password()
        admin_created = create_web_admin.Create(create_web_admin_args).execute(create_web_admin_args, False, password)

        # Need to reset the logger here because executing the create_web_admin command
        # loads the web admin's logger which doesn't like that of ours.
        self.reset_logger(args, True)
        self.logger.info("[{}/{}] Web admin created".format(next_step.next(), total_steps))

        #
        # 8) Scripts
        #
        zato_bin = "zato"
        zato_qs_start_path = os.path.join(args_path, "zato-qs-start.sh")
        zato_qs_stop_path = os.path.join(args_path, "zato-qs-stop.sh")
        zato_qs_restart_path = os.path.join(args_path, "zato-qs-restart.sh")

        open(zato_qs_start_path, "w").write(zato_qs_start_template.format(zato_bin=zato_bin, script_dir=script_dir))
        open(zato_qs_stop_path, "w").write(zato_qs_stop_template.format(zato_bin=zato_bin, script_dir=script_dir))
        open(zato_qs_restart_path, "w").write(zato_qs_restart.format(script_dir=script_dir))

        file_mod = stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | stat.S_IRGRP

        os.chmod(zato_qs_start_path, file_mod)
        os.chmod(zato_qs_stop_path, file_mod)
        os.chmod(zato_qs_restart_path, file_mod)

        self.logger.info("[{}/{}] Management scripts created".format(next_step.next(), total_steps))
        self.logger.info("Quickstart cluster {} created".format(cluster_name))

        if admin_created:
            self.logger.info("Web admin user:[admin], password:[{}]".format(password))
        else:
            self.logger.info("User [admin] already exists in the ODB")

        start_command = os.path.join(args_path, "zato-qs-start.sh")
        self.logger.info("Start the cluster by issuing the {} command".format(start_command))
        self.logger.info("Visit https://zato.io/support for more information and support options")
    def execute(self, args):
        """ Quickly creates Zato components
        1) CA and crypto material
        2) ODB
        3) ODB initial data
        4) servers
        5) load-balancer
        6) Web admin
        7) Scripts
        """

        if args.odb_type == 'sqlite':
            args.sqlite_path = os.path.abspath(os.path.join(args.path, 'zato.db'))

        next_step = count(1)
        next_port = count(http_plain_server_port)
        cluster_name = getattr(args, 'cluster_name', None) or 'quickstart-{}'.format(random.getrandbits(20)).zfill(7)
        servers = int(getattr(args, 'servers', 0) or DEFAULT_NO_SERVERS)

        server_names = OrderedDict()
        for idx in range(1, servers+1):
            server_names['{}'.format(idx)] = 'server{}'.format(idx)

        total_steps = 6 + servers
        admin_invoke_password = uuid4().hex
        broker_host = 'localhost'
        broker_port = 6379
        lb_host = 'localhost'
        lb_port = 11223
        lb_agent_port = 20151

        args_path = os.path.abspath(args.path)

        # This could've been set to True by user in the command-line so we'd want
        # to unset it so that individual commands quickstart invokes don't attempt
        # to store their own configs.
        args.store_config = False

        #
        # 1) CA
        #
        ca_path = os.path.join(args_path, 'ca')
        os.mkdir(ca_path)

        ca_args = self._bunch_from_args(args, cluster_name)
        ca_args.path = ca_path

        ca_create_ca.Create(ca_args).execute(ca_args, False)
        ca_create_lb_agent.Create(ca_args).execute(ca_args, False)

        ca_create_web_admin.Create(ca_args).execute(ca_args, False)

        server_crypto_loc = {}

        for name in server_names:
            ca_args_server = deepcopy(ca_args)
            ca_args_server.server_name = server_names[name]
            ca_create_server.Create(ca_args_server).execute(ca_args_server, False)
            server_crypto_loc[name] = CryptoMaterialLocation(ca_path, '{}-{}'.format(cluster_name, server_names[name]))

        lb_agent_crypto_loc = CryptoMaterialLocation(ca_path, 'lb-agent')
        web_admin_crypto_loc = CryptoMaterialLocation(ca_path, 'web-admin')

        self.logger.info('[{}/{}] Certificate authority created'.format(next_step.next(), total_steps))

        #
        # 2) ODB
        #
        if create_odb.Create(args).execute(args, False) == self.SYS_ERROR.ODB_EXISTS:
            self.logger.info('[{}/{}] ODB schema already exists'.format(next_step.next(), total_steps))
        else:
            self.logger.info('[{}/{}] ODB schema created'.format(next_step.next(), total_steps))

        #
        # 3) ODB initial data
        #
        create_cluster_args = self._bunch_from_args(args, cluster_name)
        create_cluster_args.broker_host = broker_host
        create_cluster_args.broker_port = broker_port
        create_cluster_args.lb_host = lb_host
        create_cluster_args.lb_port = lb_port
        create_cluster_args.lb_agent_port = lb_agent_port
        create_cluster_args.admin_invoke_password = admin_invoke_password
        create_cluster.Create(create_cluster_args).execute(create_cluster_args, False)

        self.logger.info('[{}/{}] ODB initial data created'.format(next_step.next(), total_steps))

        #
        # 4) servers
        #
        for name in server_names:
            server_path = os.path.join(args_path, server_names[name])
            os.mkdir(server_path)

            create_server_args = self._bunch_from_args(args, cluster_name)
            create_server_args.server_name = server_names[name]
            create_server_args.path = server_path
            create_server_args.cert_path = server_crypto_loc[name].cert_path
            create_server_args.pub_key_path = server_crypto_loc[name].pub_path
            create_server_args.priv_key_path = server_crypto_loc[name].priv_path
            create_server_args.ca_certs_path = server_crypto_loc[name].ca_certs_path

            create_server.Create(create_server_args).execute(create_server_args, next_port.next(), False)

            self.logger.info('[{}/{}] server{} created'.format(next_step.next(), total_steps, name))

        #
        # 5) load-balancer
        #
        lb_path = os.path.join(args_path, 'load-balancer')
        os.mkdir(lb_path)

        create_lb_args = self._bunch_from_args(args, cluster_name)
        create_lb_args.path = lb_path
        create_lb_args.cert_path = lb_agent_crypto_loc.cert_path
        create_lb_args.pub_key_path = lb_agent_crypto_loc.pub_path
        create_lb_args.priv_key_path = lb_agent_crypto_loc.priv_path
        create_lb_args.ca_certs_path = lb_agent_crypto_loc.ca_certs_path

        # Need to substract 1 because we've already called .next() twice
        # when creating servers above.
        servers_port = next_port.next() - 1

        create_lb.Create(create_lb_args).execute(create_lb_args, True, servers_port, False)
        self.logger.info('[{}/{}] Load-balancer created'.format(next_step.next(), total_steps))

        #
        # 6) Web admin
        #
        web_admin_path = os.path.join(args_path, 'web-admin')
        os.mkdir(web_admin_path)

        create_web_admin_args = self._bunch_from_args(args, cluster_name)
        create_web_admin_args.path = web_admin_path
        create_web_admin_args.cert_path = web_admin_crypto_loc.cert_path
        create_web_admin_args.pub_key_path = web_admin_crypto_loc.pub_path
        create_web_admin_args.priv_key_path = web_admin_crypto_loc.priv_path
        create_web_admin_args.ca_certs_path = web_admin_crypto_loc.ca_certs_path
        create_web_admin_args.admin_invoke_password = admin_invoke_password

        password = generate_password()
        admin_created = create_web_admin.Create(create_web_admin_args).execute(
            create_web_admin_args, False, password, True)

        # Need to reset the logger here because executing the create_web_admin command
        # loads the web admin's logger which doesn't like that of ours.
        self.reset_logger(args, True)
        self.logger.info('[{}/{}] Web admin created'.format(next_step.next(), total_steps))

        #
        # 7) Scripts
        #
        zato_bin = 'zato'
        zato_qs_start_path = os.path.join(args_path, 'zato-qs-start.sh')
        zato_qs_stop_path = os.path.join(args_path, 'zato-qs-stop.sh')
        zato_qs_restart_path = os.path.join(args_path, 'zato-qs-restart.sh')

        sanity_checks = []
        start_servers = []
        stop_servers = []

        for name in server_names:
            sanity_checks.append(sanity_checks_template.format(server_name=server_names[name]))
            start_servers.append(start_servers_template.format(server_name=server_names[name], step_number=int(name)+3))
            stop_servers.append(stop_servers_template.format(server_name=server_names[name], step_number=int(name)+1))

        sanity_checks = '\n'.join(sanity_checks)
        start_servers = '\n'.join(start_servers)
        stop_servers = '\n'.join(stop_servers)
        start_steps = 4 + servers
        stop_steps = 2 + servers

        zato_qs_start_head = zato_qs_start_head_template.format(
            zato_bin=zato_bin, script_dir=script_dir, cluster_name=cluster_name, start_steps=start_steps)
        zato_qs_start_body = zato_qs_start_body_template.format(sanity_checks=sanity_checks, start_servers=start_servers)
        zato_qs_start = zato_qs_start_head + zato_qs_start_body + zato_qs_start_tail

        zato_qs_stop = zato_qs_stop_template.format(
            zato_bin=zato_bin, script_dir=script_dir, cluster_name=cluster_name, stop_steps=stop_steps, stop_servers=stop_servers)

        open(zato_qs_start_path, 'w').write(zato_qs_start)
        open(zato_qs_stop_path, 'w').write(zato_qs_stop)
        open(zato_qs_restart_path, 'w').write(zato_qs_restart.format(script_dir=script_dir, cluster_name=cluster_name))

        file_mod = stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | stat.S_IRGRP

        os.chmod(zato_qs_start_path, file_mod)
        os.chmod(zato_qs_stop_path, file_mod)
        os.chmod(zato_qs_restart_path, file_mod)

        self.logger.info('[{}/{}] Management scripts created'.format(next_step.next(), total_steps))
        self.logger.info('Quickstart cluster {} created'.format(cluster_name))

        if admin_created:
            self.logger.info('Web admin user:[admin], password:[{}]'.format(password))
        else:
            self.logger.info('User [admin] already exists in the ODB')

        start_command = os.path.join(args_path, 'zato-qs-start.sh')
        self.logger.info('Start the cluster by issuing the {} command'.format(start_command))
        self.logger.info('Visit https://zato.io/support for more information and support options')
Beispiel #7
0
    def execute(self, args, show_output=True, password=None, needs_admin_created_flag=False):
        os.chdir(self.target_dir)

        repo_dir = os.path.join(self.target_dir, 'config', 'repo')
        web_admin_conf_path = os.path.join(repo_dir, 'web-admin.conf')
        initial_data_json_path = os.path.join(repo_dir, 'initial-data.json')

        os.mkdir(os.path.join(self.target_dir, 'logs'))
        os.mkdir(os.path.join(self.target_dir, 'config'))
        os.mkdir(repo_dir)

        user_name = 'admin'
        password = password if password else generate_password()

        self.copy_web_admin_crypto(repo_dir, args)
        priv_key = open(os.path.join(repo_dir, 'web-admin-priv-key.pem')).read()

        config = {
            'host': web_admin_host,
            'port': web_admin_port,
            'db_type': args.odb_type,
            'log_config': 'logging.conf',
            'DATABASE_NAME': args.odb_db_name or args.sqlite_path,
            'DATABASE_USER': args.odb_user or '',
            'DATABASE_PASSWORD': encrypt(args.odb_password, priv_key) if args.odb_password else '',
            'DATABASE_HOST': args.odb_host or '',
            'DATABASE_PORT': args.odb_port or '',
            'SITE_ID': getrandbits(20),
            'SECRET_KEY': encrypt(uuid.uuid4().hex, priv_key),
            'ADMIN_INVOKE_NAME':'admin.invoke',
            'ADMIN_INVOKE_PASSWORD':encrypt(getattr(args, 'admin_invoke_password', None) or getattr(args, 'tech_account_password'), priv_key),
        }

        open(os.path.join(repo_dir, 'logging.conf'), 'w').write(common_logging_conf_contents.format(log_path='./logs/web-admin.log'))
        open(web_admin_conf_path, 'w').write(config_template.format(**config))
        open(initial_data_json_path, 'w').write(initial_data_json.format(**config))

        # Initial info
        self.store_initial_info(self.target_dir, self.COMPONENTS.WEB_ADMIN.code)

        config = json.loads(open(os.path.join(repo_dir, 'web-admin.conf')).read())
        config['config_dir'] = self.target_dir
        update_globals(config, self.target_dir)

        os.environ['DJANGO_SETTINGS_MODULE'] = 'zato.admin.settings'

        # Can't import these without DJANGO_SETTINGS_MODULE being set
        from django.contrib.auth.models import User
        from django.db import connection
        from django.db.utils import IntegrityError

        call_command('syncdb', interactive=False, verbosity=0)
        call_command('loaddata', initial_data_json_path, verbosity=0)

        try:
            call_command(
                'createsuperuser', interactive=False, username=user_name, first_name='admin-first-name',
                last_name='admin-last-name', email='*****@*****.**')
            admin_created = True

            user = User.objects.get(username=user_name)
            user.set_password(password)
            user.save()

        except IntegrityError, e:
            admin_created = False
            connection._rollback()
            self.logger.info('Ignoring IntegrityError e:[%s]', format_exc(e).decode('utf-8'))
Beispiel #8
0
    def execute(self,
                args,
                show_output=True,
                password=None,
                needs_admin_created_flag=False):
        os.chdir(self.target_dir)

        repo_dir = os.path.join(self.target_dir, 'config', 'repo')
        web_admin_conf_path = os.path.join(repo_dir, 'web-admin.conf')
        initial_data_json_path = os.path.join(repo_dir, 'initial-data.json')

        os.mkdir(os.path.join(self.target_dir, 'logs'))
        os.mkdir(os.path.join(self.target_dir, 'config'))
        os.mkdir(repo_dir)

        user_name = 'admin'
        password = password if password else generate_password()

        self.copy_web_admin_crypto(repo_dir, args)
        priv_key = open(os.path.join(repo_dir,
                                     'web-admin-priv-key.pem')).read()

        config = {
            'host':
            web_admin_host,
            'port':
            web_admin_port,
            'db_type':
            args.odb_type,
            'log_config':
            'logging.conf',
            'DATABASE_NAME':
            args.odb_db_name or args.sqlite_path,
            'DATABASE_USER':
            args.odb_user or '',
            'DATABASE_PASSWORD':
            encrypt(args.odb_password, priv_key) if args.odb_password else '',
            'DATABASE_HOST':
            args.odb_host or '',
            'DATABASE_PORT':
            args.odb_port or '',
            'SITE_ID':
            getrandbits(20),
            'SECRET_KEY':
            encrypt(uuid.uuid4().hex, priv_key),
            'ADMIN_INVOKE_NAME':
            'admin.invoke',
            'ADMIN_INVOKE_PASSWORD':
            encrypt(
                getattr(args, 'admin_invoke_password', None)
                or getattr(args, 'tech_account_password'), priv_key),
        }

        open(os.path.join(repo_dir, 'logging.conf'), 'w').write(
            common_logging_conf_contents.format(
                log_path='./logs/web-admin.log'))
        open(web_admin_conf_path, 'w').write(config_template.format(**config))
        open(initial_data_json_path,
             'w').write(initial_data_json.format(**config))

        # Initial info
        self.store_initial_info(self.target_dir,
                                self.COMPONENTS.WEB_ADMIN.code)

        config = json.loads(
            open(os.path.join(repo_dir, 'web-admin.conf')).read())
        config['config_dir'] = self.target_dir
        update_globals(config, self.target_dir)

        os.environ['DJANGO_SETTINGS_MODULE'] = 'zato.admin.settings'

        import django
        django.setup()
        self.reset_logger(args, True)

        # Can't import these without DJANGO_SETTINGS_MODULE being set
        from django.contrib.auth.models import User
        from django.db import connection
        from django.db.utils import IntegrityError

        call_command('migrate',
                     run_syncdb=True,
                     interactive=False,
                     verbosity=0)
        call_command('loaddata', initial_data_json_path, verbosity=0)

        try:
            call_command('createsuperuser',
                         interactive=False,
                         username=user_name,
                         first_name='admin-first-name',
                         last_name='admin-last-name',
                         email='*****@*****.**')
            admin_created = True

            user = User.objects.get(username=user_name)
            user.set_password(password)
            user.save()

        except IntegrityError:
            # This will happen if user 'admin' already exists, e.g. if this is not the first cluster in this database
            admin_created = False
            connection._rollback()

        # Needed because Django took over our logging config
        self.reset_logger(args, True)

        if show_output:
            if self.verbose:
                msg = """Successfully created a web admin instance.
    You can start it with the 'zato start {path}' command.""".format(
                    path=os.path.abspath(
                        os.path.join(os.getcwd(), self.target_dir)))
                self.logger.debug(msg)
            else:
                self.logger.info('OK')

        # We return it only when told to explicitly so when the command runs from CLI
        # it doesn't return a non-zero exit code.
        if needs_admin_created_flag:
            return admin_created
Beispiel #9
0
    def execute(self,
                args,
                show_output=True,
                password=None,
                needs_created_flag=False):
        os.chdir(self.target_dir)

        repo_dir = os.path.join(self.target_dir, 'config', 'repo')
        conf_path = os.path.join(repo_dir, 'scheduler.conf')
        startup_jobs_conf_path = os.path.join(repo_dir, 'startup_jobs.conf')
        sql_conf_path = os.path.join(repo_dir, 'sql.conf')

        os.mkdir(os.path.join(self.target_dir, 'logs'))
        os.mkdir(os.path.join(self.target_dir, 'config'))
        os.mkdir(repo_dir)

        self.copy_scheduler_crypto(repo_dir, args)
        priv_key = open(os.path.join(repo_dir,
                                     'zato-scheduler-priv-key.pem')).read()

        config = {
            'odb_db_name':
            args.odb_db_name or args.sqlite_path,
            'odb_engine':
            args.odb_type,
            'odb_host':
            args.odb_host or '',
            'odb_port':
            args.odb_port or '',
            'odb_password':
            encrypt(args.odb_password, priv_key) if args.odb_password else '',
            'odb_username':
            args.odb_user or '',
            'broker_host':
            args.kvdb_host,
            'broker_port':
            args.kvdb_port,
            'broker_password':
            encrypt(args.kvdb_password, priv_key)
            if args.kvdb_password else '',
            'user1_password':
            generate_password(),
            'cluster_id':
            args.cluster_id,
        }

        open(os.path.join(repo_dir, 'logging.conf'), 'w').write(
            common_logging_conf_contents.format(
                log_path='./logs/scheduler.log'))
        open(conf_path, 'w').write(config_template.format(**config))
        open(startup_jobs_conf_path, 'w').write(startup_jobs)
        open(sql_conf_path, 'w').write(sql_conf_contents)

        # Initial info
        self.store_initial_info(self.target_dir,
                                self.COMPONENTS.SCHEDULER.code)

        if show_output:
            if self.verbose:
                msg = """Successfully created a scheduler instance.
    You can start it with the 'zato start {path}' command.""".format(
                    path=os.path.abspath(
                        os.path.join(os.getcwd(), self.target_dir)))
                self.logger.debug(msg)
            else:
                self.logger.info('OK')

        # We return it only when told to explicitly so when the command runs from CLI
        # it doesn't return a non-zero exit code.
        if needs_created_flag:
            return True
Beispiel #10
0
    def execute(self, args):
        """ Quickly creates Zato components
        1) CA and crypto material
        2) ODB
        3) ODB initial data 
        4) server1 
        5) server2 
        6) load-balancer
        7) Zato admin
        8) Scripts
        """
        next_step = count(1)
        next_port = count(http_plain_server_port)
        total_steps = 8
        cluster_name = 'quickstart-{}'.format(random.getrandbits(20)).zfill(7)
        server_names = {'1':'server1', '2':'server2'}
        tech_account_name = 'techacct-{}'.format(random.getrandbits(20)).zfill(7)
        tech_account_password = uuid4().hex
        broker_host = 'localhost'
        broker_port = 6379
        lb_host = 'localhost'
        lb_port = 11223
        lb_agent_port = 20151
        
        # This could've been set to True by user in the command-line so we'd want
        # to unset it so that individual commands quickstart invokes don't attempt
        # to store their own configs.
        args.store_config = False
        
        #
        # 1) CA
        #
        ca_path = os.path.join(args.path, 'ca')
        os.mkdir(ca_path)
        
        ca_args = self._bunch_from_args(args, cluster_name)
        ca_args.path = ca_path
        
        ca_args_server1 = deepcopy(ca_args)
        ca_args_server1.server_name = server_names['1']
        
        ca_args_server2 = deepcopy(ca_args)
        ca_args_server2.server_name = server_names['2']
        
        ca_create_ca.Create(ca_args).execute(ca_args, False)
        ca_create_lb_agent.Create(ca_args).execute(ca_args, False)
        
        ca_create_server.Create(ca_args_server1).execute(ca_args_server1, False)
        ca_create_server.Create(ca_args_server2).execute(ca_args_server2, False)
        
        ca_create_zato_admin.Create(ca_args).execute(ca_args, False)

        server_crypto_loc = {}
        for key in server_names:
            server_crypto_loc[key] = CryptoMaterialLocation(ca_path, '{}-{}'.format(cluster_name, server_names[key]))
        
        lb_agent_crypto_loc = CryptoMaterialLocation(ca_path, 'lb-agent')
        zato_admin_crypto_loc = CryptoMaterialLocation(ca_path, 'zato-admin')
        
        self.logger.info('[{}/{}] Certificate authority created'.format(next_step.next(), total_steps))
        
        #
        # 2) ODB
        #
        if create_odb.Create(args).execute(args, False) == self.SYS_ERROR.ODB_EXISTS:
            self.logger.info('[{}/{}] ODB schema already exists, not creating it'.format(next_step.next(), total_steps))
        else:
            self.logger.info('[{}/{}] ODB schema created'.format(next_step.next(), total_steps))
            
        #
        # 3) ODB initial data
        #
        create_cluster_args = self._bunch_from_args(args, cluster_name)
        create_cluster_args.broker_host = broker_host
        create_cluster_args.broker_port = broker_port
        create_cluster_args.lb_host = lb_host
        create_cluster_args.lb_port = lb_port
        create_cluster_args.lb_agent_port = lb_agent_port
        create_cluster_args.tech_account_name = tech_account_name
        create_cluster_args.tech_account_password = tech_account_password
        create_cluster.Create(create_cluster_args).execute(create_cluster_args, False)
        
        self.logger.info('[{}/{}] ODB initial data created'.format(next_step.next(), total_steps))
        
        #
        # 4) server1 
        # 5) server2
        #
        for key in server_names:
            server_path = os.path.join(args.path, server_names[key])
            os.mkdir(server_path)
            
            create_server_args = self._bunch_from_args(args, cluster_name)
            create_server_args.server_name = server_names[key]
            create_server_args.path = server_path
            create_server_args.cert_path = server_crypto_loc[key].cert_path
            create_server_args.pub_key_path = server_crypto_loc[key].pub_path
            create_server_args.priv_key_path = server_crypto_loc[key].priv_path
            create_server_args.ca_certs_path = server_crypto_loc[key].ca_certs_path
            
            create_server.Create(create_server_args).execute(create_server_args, next_port.next(), False)
            
            self.logger.info('[{}/{}] server{} created'.format(next_step.next(), total_steps, key))
            
        #
        # 6) load-balancer
        #
        lb_path = os.path.join(args.path, 'load-balancer')
        os.mkdir(lb_path)
        
        create_lb_args = self._bunch_from_args(args, cluster_name)
        create_lb_args.path = lb_path
        create_lb_args.cert_path = lb_agent_crypto_loc.cert_path
        create_lb_args.pub_key_path = lb_agent_crypto_loc.pub_path
        create_lb_args.priv_key_path = lb_agent_crypto_loc.priv_path
        create_lb_args.ca_certs_path = lb_agent_crypto_loc.ca_certs_path
        
        # Need to substract 1 because we've already called .next() twice
        # when creating servers above.
        server2_port = next_port.next()-1 
        
        create_lb.Create(create_lb_args).execute(create_lb_args, True, server2_port, False)
        self.logger.info('[{}/{}] Load-balancer created'.format(next_step.next(), total_steps))
        
        #
        # 7) Zato admin
        #
        zato_admin_path = os.path.join(args.path, 'zato-admin')
        os.mkdir(zato_admin_path)
        
        create_zato_admin_args = self._bunch_from_args(args, cluster_name)
        create_zato_admin_args.path = zato_admin_path
        create_zato_admin_args.cert_path = zato_admin_crypto_loc.cert_path
        create_zato_admin_args.pub_key_path = zato_admin_crypto_loc.pub_path
        create_zato_admin_args.priv_key_path = zato_admin_crypto_loc.priv_path
        create_zato_admin_args.ca_certs_path = zato_admin_crypto_loc.ca_certs_path
        create_zato_admin_args.tech_account_name = tech_account_name
        create_zato_admin_args.tech_account_password = tech_account_password
        
        password = generate_password()
        admin_created = create_zato_admin.Create(create_zato_admin_args).execute(create_zato_admin_args, False, password)
        
        # Need to reset the logger here because executing the create_zato_admin command
        # loads the Zato admin's logger which doesn't like that of ours.
        self.reset_logger(args, True)
        self.logger.info('[{}/{}] Zato admin created'.format(next_step.next(), total_steps))
        
        #
        # 8) Scripts
        #
        zato_bin = os.path.join(os.path.dirname(sys.executable), 'zato')
        zato_qs_start_path = os.path.join(args.path, 'zato-qs-start.sh')
        zato_qs_stop_path = os.path.join(args.path, 'zato-qs-stop.sh')
        zato_qs_restart_path = os.path.join(args.path, 'zato-qs-restart.sh')

        open(zato_qs_start_path, 'w').write(zato_qs_start_template.format(zato_bin=zato_bin, script_dir=script_dir))
        open(zato_qs_stop_path, 'w').write(zato_qs_stop_template.format(zato_bin=zato_bin, script_dir=script_dir))
        open(zato_qs_restart_path, 'w').write(zato_qs_restart.format(script_dir=script_dir))

        file_mod = stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | stat.S_IRGRP
        
        os.chmod(zato_qs_start_path, file_mod)
        os.chmod(zato_qs_stop_path, file_mod)
        os.chmod(zato_qs_restart_path, file_mod)
        
        self.logger.info('[{}/{}] Management scripts created'.format(next_step.next(), total_steps))
        self.logger.info('Quickstart cluster {} created'.format(cluster_name))
        
        if admin_created:
            self.logger.info('Zato admin user:[admin], password:[{}]'.format(password))
        else:
            self.logger.info('User [admin] already exists in the ODB')
            
        self.logger.info('Start the cluster by issuing the {}/zato-qs-start.sh command'.format(args.path))
        self.logger.info('Visit https://TODO for more information and support options')