Beispiel #1
0
class Create(ZatoCommand):
    """ Creates a new Zato cluster in the ODB
    """
    opts = deepcopy(common_odb_opts)
    
    opts.append({'name':'lb_host', 'help':"Load-balancer host"})
    opts.append({'name':'lb_port', 'help':'Load-balancer port'})
    opts.append({'name':'lb_agent_port', 'help':'Load-balancer agent host'})
    opts.append({'name':'broker_host', 'help':"Redis host"})
    opts.append({'name':'broker_port', 'help':'Redis port'})
    opts.append({'name':'cluster_name', 'help':'Name of the cluster to create'})
    
    opts += get_tech_account_opts('for web admin instances to use')
    
    def execute(self, args, show_output=True):
        
        engine = self._get_engine(args)
        session = self._get_session(engine)
        
        cluster = Cluster()
        cluster.name = args.cluster_name
        cluster.description = 'Created by {} on {} (UTC)'.format(self._get_user_host(), datetime.utcnow().isoformat())
        
        for name in('odb_type', 'odb_host', 'odb_port', 'odb_user', 'odb_db_name', 
            'broker_host', 'broker_port', 'lb_host', 'lb_port', 'lb_agent_port'):
            setattr(cluster, name, getattr(args, name))
        session.add(cluster)
        
        admin_invoke_sec = HTTPBasicAuth(None, 'admin.invoke', True, 'admin.invoke', 'Zato admin invoke', args.admin_invoke_password, cluster)
        session.add(admin_invoke_sec)
        
        pubapi_sec = HTTPBasicAuth(None, 'pubapi', True, 'pubapi', 'Zato public API', uuid4().hex, cluster)
        session.add(pubapi_sec)
        
        self.add_soap_services(session, cluster, admin_invoke_sec, pubapi_sec)
        self.add_ping_services(session, cluster)
        
        try:
            session.commit()
        except IntegrityError, e:
            msg = 'Cluster name [{}] already exists'.format(cluster.name)
            if self.verbose:
                msg += '. Caught an exception:[{}]'.format(format_exc(e))
                self.logger.error(msg)
            self.logger.error(msg)
            session.rollback()
            
            return self.SYS_ERROR.CLUSTER_NAME_ALREADY_EXISTS

        if show_output:
            if self.verbose:
                msg = 'Successfully created a new cluster [{}]'.format(args.cluster_name)
                self.logger.debug(msg)
            else:
                self.logger.info('OK')
Beispiel #2
0
class Create(ZatoCommand):
    """ Creates a new Zato cluster in the ODB
    """
    opts = deepcopy(common_odb_opts)

    opts.append({'name': 'lb_host', 'help': "Load-balancer host"})
    opts.append({'name': 'lb_port', 'help': 'Load-balancer port'})
    opts.append({'name': 'lb_agent_port', 'help': 'Load-balancer agent host'})
    opts.append({'name': 'broker_host', 'help': "Redis host"})
    opts.append({'name': 'broker_port', 'help': 'Redis port'})
    opts.append({
        'name': 'cluster_name',
        'help': 'Name of the cluster to create'
    })

    opts += get_tech_account_opts('for web admin instances to use')

    def execute(self, args, show_output=True):

        engine = self._get_engine(args)
        session = self._get_session(engine)

        cluster = Cluster()
        cluster.name = args.cluster_name
        cluster.description = 'Created by {} on {} (UTC)'.format(
            self._get_user_host(),
            datetime.utcnow().isoformat())

        for name in ('odb_type', 'odb_host', 'odb_port', 'odb_user',
                     'odb_db_name', 'broker_host', 'broker_port', 'lb_host',
                     'lb_port', 'lb_agent_port'):
            setattr(cluster, name, getattr(args, name))
        session.add(cluster)

        # TODO: getattrs below should be squared away - one of the attrs should win
        #       and the other one should be get ridden of.
        admin_invoke_sec = HTTPBasicAuth(
            None, 'admin.invoke', True, 'admin.invoke', 'Zato admin invoke',
            getattr(args, 'admin_invoke_password', None)
            or getattr(args, 'tech_account_password'), cluster)
        session.add(admin_invoke_sec)

        pubapi_sec = HTTPBasicAuth(None, 'pubapi', True, 'pubapi',
                                   'Zato public API',
                                   uuid4().hex, cluster)
        session.add(pubapi_sec)

        internal_invoke_sec = HTTPBasicAuth(None, 'zato.internal.invoke', True,
                                            'zato.internal.invoke.user',
                                            'Zato internal invoker',
                                            uuid4().hex, cluster)
        session.add(internal_invoke_sec)

        live_browser_sec = JWT(None, msg_browser_defaults.CHANNEL, True,
                               msg_browser_defaults.USER,
                               uuid4().hex, msg_browser_defaults.TOKEN_TTL,
                               cluster)
        session.add(live_browser_sec)

        self.add_internal_services(session, cluster, admin_invoke_sec,
                                   pubapi_sec, internal_invoke_sec,
                                   live_browser_sec)
        self.add_ping_services(session, cluster)
        self.add_default_pubsub_accounts(session, cluster)
        self.add_default_rbac_permissions(session, cluster)
        self.add_default_rbac_roles(session, cluster)

        try:
            session.commit()
        except IntegrityError, e:
            msg = 'Cluster name [{}] already exists'.format(cluster.name)
            if self.verbose:
                msg += '. Caught an exception:[{}]'.format(
                    format_exc(e).decode('utf-8'))
                self.logger.error(msg)
            self.logger.error(msg)
            session.rollback()

            return self.SYS_ERROR.CLUSTER_NAME_ALREADY_EXISTS

        if show_output:
            if self.verbose:
                msg = 'Successfully created a new cluster [{}]'.format(
                    args.cluster_name)
                self.logger.debug(msg)
            else:
                self.logger.info('OK')
Beispiel #3
0
class Create(ZatoCommand):
    """ Creates a new web admin web console
    """
    needs_empty_dir = True
    allow_empty_secrets = True

    opts = deepcopy(common_odb_opts)

    opts.append({
        'name': 'pub_key_path',
        'help': "Path to the web admin's public key in PEM"
    })
    opts.append({
        'name': 'priv_key_path',
        'help': "Path to the web admin's private key in PEM"
    })
    opts.append({
        'name': 'cert_path',
        'help': "Path to the web admin's certificate in PEM"
    })
    opts.append({
        'name': 'ca_certs_path',
        'help': "Path to a bundle of CA certificates to be trusted"
    })

    opts += get_tech_account_opts()

    def __init__(self, args):
        self.target_dir = os.path.abspath(args.path)
        super(Create, self).__init__(args)

    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'))

        # 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 #4
0
class Create(ZatoCommand):
    """ Creates a new web admin web console
    """
    needs_empty_dir = True
    allow_empty_secrets = True

    opts = deepcopy(common_odb_opts)

    opts.append({'name':'--pub_key_path', 'help':"Path to the web admin's public key in PEM"})
    opts.append({'name':'--priv_key_path', 'help':"Path to the web admin's private key in PEM"})
    opts.append({'name':'--cert_path', 'help':"Path to the web admin's certificate in PEM"})
    opts.append({'name':'--ca_certs_path', 'help':"Path to a bundle of CA certificates to be trusted"})

    opts += get_tech_account_opts()

    def __init__(self, args):
        self.target_dir = os.path.abspath(args.path)
        super(Create, self).__init__(args)

    def execute(self, args, show_output=True, admin_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'
        admin_password = admin_password if admin_password else WebAdminCryptoManager.generate_password()

        self.copy_web_admin_crypto(repo_dir, args)

        zato_secret_key = WebAdminCryptoManager.generate_key()
        cm = WebAdminCryptoManager.from_secret_key(zato_secret_key)

        django_secret_key = uuid4().hex.encode('utf8')
        django_site_id = getrandbits(20)

        admin_invoke_password = getattr(args, 'admin_invoke_password', None) or getattr(args, 'tech_account_password')
        admin_invoke_password = admin_invoke_password.encode('utf8')

        odb_password = args.odb_password or ''
        odb_password = odb_password.encode('utf8')

        # If we have a CA's certificate then it implicitly means that there is some CA
        # which tells us that we are to trust both the CA and the certificates that it issues,
        # and the only certificate we are interested in is the one to the load-balancer.
        # This is why, if we get ca_certs_path, it must be because we are to use TLS
        # in communication with the load-balancer's agent.
        lb_agent_use_tls = bool(args.get('ca_certs_path'))

        config = {
            'host': web_admin_host,
            'port': web_admin_port,
            'db_type': args.odb_type,
            'log_config': 'logging.conf',
            'lb_agent_use_tls': 'true' if lb_agent_use_tls else 'false',
            'zato_secret_key':zato_secret_key,
            'well_known_data': cm.encrypt(well_known_data.encode('utf8')),
            'DATABASE_NAME': args.odb_db_name or args.sqlite_path,
            'DATABASE_USER': args.odb_user or '',
            'DATABASE_PASSWORD': cm.encrypt(odb_password),
            'DATABASE_HOST': args.odb_host or '',
            'DATABASE_PORT': args.odb_port or '',
            'SITE_ID': django_site_id,
            'SECRET_KEY': cm.encrypt(django_secret_key),
            'ADMIN_INVOKE_NAME':'admin.invoke',
            'ADMIN_INVOKE_PASSWORD':cm.encrypt(admin_invoke_password),
        }

        for name in 'zato_secret_key', 'well_known_data', 'DATABASE_PASSWORD', 'SECRET_KEY', 'ADMIN_INVOKE_PASSWORD':
            config[name] = config[name].decode('utf8')

        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(admin_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