Esempio n. 1
0
    def execute(self, args, port=http_plain_server_port, show_output=True):
        
        engine = self._get_engine(args)
        session = self._get_session(engine)
        
        cluster = session.query(Cluster).\
            filter(Cluster.name == args.cluster_name).\
            first()
        
        if not cluster:
            msg = "Cluster [{}] doesn't exist in the ODB".format(args.cluster_name)
            self.logger.error(msg)
            return self.SYS_ERROR.NO_SUCH_CLUSTER
        
        server = Server()
        server.cluster_id = cluster.id
        server.name = args.server_name
        server.token = self.token
        server.last_join_status = SERVER_JOIN_STATUS.ACCEPTED
        server.last_join_mod_by = self._get_user_host()
        server.last_join_mod_date = datetime.utcnow()
        
        session.add(server)

        try:
            if not self.dirs_prepared:
                self.prepare_directories(show_output)
    
            repo_dir = os.path.join(self.target_dir, 'config', 'repo')
            self.copy_server_crypto(repo_dir, args)
            priv_key = open(os.path.join(repo_dir, 'zato-server-priv-key.pem')).read()
            
            if show_output:
                self.logger.debug('Created a Bazaar repo in {}'.format(repo_dir))
                self.logger.debug('Creating files..')
                
            for file_name, contents in sorted(files.items()):
                file_name = os.path.join(self.target_dir, file_name)
                if show_output:
                    self.logger.debug('Creating {}'.format(file_name))
                f = file(file_name, 'w')
                f.write(contents)
                f.close()
    
            logging_conf_loc = os.path.join(self.target_dir, 'config/repo/logging.conf')
    
            logging_conf = open(logging_conf_loc).read()
            open(logging_conf_loc, 'w').write(logging_conf.format(
                log_path=os.path.join(self.target_dir, 'logs', 'zato.log')))
    
            if show_output:
                self.logger.debug('Logging configuration stored in {}'.format(logging_conf_loc))
    
            server_conf_loc = os.path.join(self.target_dir, 'config/repo/server.conf')
            server_conf = open(server_conf_loc, 'w')
            server_conf.write(
                server_conf_template.format(
                    port=port,
                    gunicorn_workers=cpu_count(),
                    odb_db_name=args.odb_db_name,
                    odb_engine=args.odb_type,
                    odb_host=args.odb_host,
                    odb_port=args.odb_port,
                    odb_password=encrypt(args.odb_password, priv_key), 
                    odb_pool_size=default_odb_pool_size, 
                    odb_user=args.odb_user, 
                    token=self.token, 
                    kvdb_host=args.kvdb_host,
                    kvdb_port=args.kvdb_port,
                    kvdb_password=encrypt(args.kvdb_password, priv_key) if args.kvdb_password else '',
                    initial_cluster_name=args.cluster_name,
                    initial_server_name=args.server_name,
                ))
            server_conf.close()
            
            if show_output:
                self.logger.debug('Core configuration stored in {}'.format(server_conf_loc))
            
            # Initial info
            self.store_initial_info(self.target_dir, self.COMPONENTS.SERVER.code)
            
            session.commit()

        except IntegrityError, e:
            msg = 'Server name [{}] already exists'.format(args.server_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.SERVER_NAME_ALREADY_EXISTS
Esempio n. 2
0
    def execute(self, args, port=http_plain_server_port, show_output=True):

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

        cluster = session.query(Cluster).\
            filter(Cluster.name == args.cluster_name).\
            first()

        if not cluster:
            msg = "Cluster [{}] doesn't exist in the ODB".format(
                args.cluster_name)
            self.logger.error(msg)
            return self.SYS_ERROR.NO_SUCH_CLUSTER

        server = Server()
        server.cluster_id = cluster.id
        server.name = args.server_name
        server.token = self.token
        server.last_join_status = SERVER_JOIN_STATUS.ACCEPTED
        server.last_join_mod_by = self._get_user_host()
        server.last_join_mod_date = datetime.utcnow()

        session.add(server)

        try:
            if not self.dirs_prepared:
                self.prepare_directories(show_output)

            repo_dir = os.path.join(self.target_dir, 'config', 'repo')
            self.copy_server_crypto(repo_dir, args)
            priv_key = open(os.path.join(repo_dir,
                                         'zato-server-priv-key.pem')).read()

            if show_output:
                self.logger.debug(
                    'Created a Bazaar repo in {}'.format(repo_dir))
                self.logger.debug('Creating files..')

            for file_name, contents in sorted(files.items()):
                file_name = os.path.join(self.target_dir, file_name)
                if show_output:
                    self.logger.debug('Creating {}'.format(file_name))
                f = file(file_name, 'w')
                f.write(contents)
                f.close()

            logging_conf_loc = os.path.join(self.target_dir,
                                            'config/repo/logging.conf')

            logging_conf = open(logging_conf_loc).read()
            open(logging_conf_loc, 'w').write(
                logging_conf.format(log_path=os.path.join(
                    self.target_dir, 'logs', 'zato.log')))

            if show_output:
                self.logger.debug('Logging configuration stored in {}'.format(
                    logging_conf_loc))

            odb_engine = args.odb_type
            if odb_engine.startswith('postgresql'):
                odb_engine = 'postgresql+pg8000'

            server_conf_loc = os.path.join(self.target_dir,
                                           'config/repo/server.conf')
            server_conf = open(server_conf_loc, 'w')
            server_conf.write(
                server_conf_template.format(
                    port=port,
                    gunicorn_workers=1,
                    odb_db_name=args.odb_db_name or args.sqlite_path,
                    odb_engine=odb_engine,
                    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_pool_size=default_odb_pool_size,
                    odb_user=args.odb_user or '',
                    token=self.token,
                    kvdb_host=args.kvdb_host,
                    kvdb_port=args.kvdb_port,
                    kvdb_password=encrypt(args.kvdb_password, priv_key)
                    if args.kvdb_password else '',
                    initial_cluster_name=args.cluster_name,
                    initial_server_name=args.server_name,
                    jwt_secret=getattr(args, 'jwt_secret',
                                       Fernet.generate_key()),
                ))
            server_conf.close()

            pickup_conf_loc = os.path.join(self.target_dir,
                                           'config/repo/pickup.conf')
            pickup_conf_file = open(pickup_conf_loc, 'w')
            pickup_conf_file.write(pickup_conf)
            pickup_conf_file.close()

            user_conf_loc = os.path.join(self.target_dir,
                                         'config/repo/user.conf')
            user_conf = open(user_conf_loc, 'w')
            user_conf.write(user_conf_contents)
            user_conf.close()

            if show_output:
                self.logger.debug(
                    'Core configuration stored in {}'.format(server_conf_loc))

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

            session.commit()

        except IntegrityError, e:
            msg = 'Server name [{}] already exists'.format(args.server_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.SERVER_NAME_ALREADY_EXISTS
Esempio n. 3
0
    def execute(self,
                args,
                default_http_port=http_plain_server_port,
                show_output=True,
                return_server_id=False):

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

        cluster = session.query(Cluster).\
            filter(Cluster.name == args.cluster_name).\
            first()

        if not cluster:
            self.logger.error("Cluster `%s` doesn't exist in ODB",
                              args.cluster_name)
            return self.SYS_ERROR.NO_SUCH_CLUSTER

        server = Server(cluster=cluster)
        server.name = args.server_name
        if isinstance(self.token, (bytes, bytearray)):
            server.token = self.token.decode('utf8')
        else:
            server.token = self.token
        server.last_join_status = SERVER_JOIN_STATUS.ACCEPTED
        server.last_join_mod_by = self._get_user_host()
        server.last_join_mod_date = datetime.utcnow()
        session.add(server)

        try:
            if not self.dirs_prepared:
                self.prepare_directories(show_output)

            repo_dir = os.path.join(self.target_dir, 'config', 'repo')

            # Note that server crypto material is optional so if none was given on input
            # this command will be a no-op.
            self.copy_server_crypto(repo_dir, args)

            if show_output:
                self.logger.debug('Created a repo in {}'.format(repo_dir))
                self.logger.debug('Creating files..')

            for file_name, contents in sorted(files.items()):
                file_name = os.path.join(self.target_dir, file_name)
                if show_output:
                    self.logger.debug('Creating {}'.format(file_name))
                f = open(file_name, 'w')
                f.write(contents)
                f.close()

            logging_conf_loc = os.path.join(self.target_dir,
                                            'config/repo/logging.conf')

            logging_conf = open(logging_conf_loc).read()
            open(logging_conf_loc, 'w').write(
                logging_conf.format(log_path=os.path.join(
                    self.target_dir, 'logs', 'zato.log')))

            if show_output:
                self.logger.debug('Logging configuration stored in {}'.format(
                    logging_conf_loc))

            odb_engine = args.odb_type
            if odb_engine.startswith('postgresql'):
                odb_engine = 'postgresql+pg8000'

            server_conf_loc = os.path.join(self.target_dir,
                                           'config/repo/server.conf')
            server_conf = open(server_conf_loc, 'w')
            server_conf.write(
                server_conf_template.format(
                    port=getattr(args, 'http_port', None) or default_http_port,
                    gunicorn_workers=1,
                    odb_db_name=args.odb_db_name or args.sqlite_path,
                    odb_engine=odb_engine,
                    odb_host=args.odb_host or '',
                    odb_port=args.odb_port or '',
                    odb_pool_size=default_odb_pool_size,
                    odb_user=args.odb_user or '',
                    kvdb_host=args.kvdb_host,
                    kvdb_port=args.kvdb_port,
                    initial_cluster_name=args.cluster_name,
                    initial_server_name=args.server_name,
                ))
            server_conf.close()

            pickup_conf_loc = os.path.join(self.target_dir,
                                           'config/repo/pickup.conf')
            pickup_conf_file = open(pickup_conf_loc, 'w')
            pickup_conf_file.write(pickup_conf)
            pickup_conf_file.close()

            user_conf_loc = os.path.join(self.target_dir,
                                         'config/repo/user.conf')
            user_conf = open(user_conf_loc, 'w')
            user_conf.write(user_conf_contents)
            user_conf.close()

            sso_conf_loc = os.path.join(self.target_dir,
                                        'config/repo/sso.conf')
            sso_conf = open(sso_conf_loc, 'w')
            sso_conf.write(sso_conf_contents)
            sso_conf.close()

            # There will be multiple keys in future releases to allow for key rotation
            key1 = args.secret_key or Fernet.generate_key()
            fernet1 = Fernet(key1)

            secrets_conf_loc = os.path.join(self.target_dir,
                                            'config/repo/secrets.conf')
            secrets_conf = open(secrets_conf_loc, 'w')

            kvdb_password = args.kvdb_password or ''
            kvdb_password = kvdb_password.encode('utf8')
            kvdb_password = fernet1.encrypt(kvdb_password)
            kvdb_password = kvdb_password.decode('utf8')

            odb_password = args.odb_password or ''
            odb_password = odb_password.encode('utf8')
            odb_password = fernet1.encrypt(odb_password)
            odb_password = odb_password.decode('utf8')

            zato_well_known_data = fernet1.encrypt(
                well_known_data.encode('utf8'))
            zato_well_known_data = zato_well_known_data.decode('utf8')

            if isinstance(key1, (bytes, bytearray)):
                key1 = key1.decode('utf8')

            zato_main_token = fernet1.encrypt(self.token)
            zato_main_token = zato_main_token.decode('utf8')

            zato_misc_jwt_secret = getattr(args, 'jwt_secret', None)
            if not zato_misc_jwt_secret:
                zato_misc_jwt_secret = Fernet.generate_key()

            zato_misc_jwt_secret = fernet1.encrypt(zato_misc_jwt_secret)

            if isinstance(zato_misc_jwt_secret, bytes):
                zato_misc_jwt_secret = zato_misc_jwt_secret.decode('utf8')

            secrets_conf.write(
                secrets_conf_template.format(
                    keys_key1=key1,
                    zato_well_known_data=zato_well_known_data,
                    zato_kvdb_password=kvdb_password,
                    zato_main_token=zato_main_token,
                    zato_misc_jwt_secret=zato_misc_jwt_secret,
                    zato_odb_password=odb_password,
                ))
            secrets_conf.close()

            bytes_to_str_encoding = 'utf8' if PY3 else ''

            simple_io_conf_loc = os.path.join(self.target_dir,
                                              'config/repo/simple-io.conf')
            simple_io_conf = open(simple_io_conf_loc, 'w')
            simple_io_conf.write(
                simple_io_conf_contents.format(
                    bytes_to_str_encoding=bytes_to_str_encoding))
            simple_io_conf.close()

            if show_output:
                self.logger.debug(
                    'Core configuration stored in {}'.format(server_conf_loc))

            # Sphinx APISpec files
            for file_path, contents in apispec_files.items():
                full_path = os.path.join(
                    self.target_dir, 'config/repo/static/sphinxdoc/apispec',
                    file_path)
                dir_name = os.path.dirname(full_path)
                try:
                    os.makedirs(dir_name, 0o770)
                except OSError:
                    # That is fine, the directory must have already created in one of previous iterations
                    pass
                finally:
                    api_file = open(full_path, 'w')
                    api_file.write(contents)
                    api_file.close()

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

            session.commit()

        except IntegrityError:
            msg = 'Server name `{}` already exists'.format(args.server_name)
            if self.verbose:
                msg += '. Caught an exception:`{}`'.format(format_exc())
            self.logger.error(msg)
            session.rollback()

            return self.SYS_ERROR.SERVER_NAME_ALREADY_EXISTS

        except Exception:
            self.logger.error('Could not create the server, e:`%s`',
                              format_exc())
            session.rollback()
        else:
            if show_output:
                self.logger.debug('Server added to the ODB')

        if show_output:
            if self.verbose:
                msg = """Successfully created a new server.
You can now start it with the 'zato start {}' command.""".format(
                    self.target_dir)
                self.logger.debug(msg)
            else:
                self.logger.info('OK')

        # This is optional - need only by quickstart.py and needs to be requested explicitly,
        # otherwise it would be construed as a non-0 return code from this process.
        if return_server_id:
            return server.id