Example #1
0
    def get_server_config(self, needs_response_elem=False):

        with NamedTemporaryFile() as f:
            contents = simple_io_conf_contents.format(bytes_to_str_encoding=get_bytes_to_str_encoding())
            if isinstance(contents, unicode):
                contents = contents.encode('utf8')
            f.write(contents)
            f.flush()

            sio_fs_config = ConfigObj(f.name)
            sio_fs_config = bunchify(sio_fs_config)

        sio_server_config = get_sio_server_config(sio_fs_config)

        if not needs_response_elem:
            sio_server_config.response_elem = None

        return sio_server_config
Example #2
0
    def test_default_config_object(self):

        test_encoding = 'abcdef'

        config = get_config_from_string(
            simple_io_conf_contents.format(
                bytes_to_str_encoding=test_encoding))
        config = get_sio_server_config(config)

        bool_ = config.bool_config
        int_ = config.int_config
        secret = config.secret_config
        bytes_to_str = config.bytes_to_str_encoding

        self.assertIsInstance(bool_.exact, set)
        self.assertIsInstance(bool_.prefixes, set)
        self.assertIsInstance(bool_.suffixes, set)

        self.assertListEqual(sorted(bool_.exact), [])
        self.assertListEqual(
            sorted(bool_.prefixes),
            ['by_', 'has_', 'is_', 'may_', 'needs_', 'should_'])
        self.assertListEqual(sorted(bool_.suffixes), [])

        self.assertIsInstance(int_.exact, set)
        self.assertIsInstance(int_.prefixes, set)
        self.assertIsInstance(int_.suffixes, set)

        self.assertListEqual(sorted(int_.exact), ['id'])
        self.assertListEqual(sorted(int_.prefixes), [])
        self.assertListEqual(
            sorted(int_.suffixes),
            ['_count', '_id', '_size', '_size_max', '_size_min', '_timeout'])

        self.assertIsInstance(secret.exact, set)
        self.assertIsInstance(secret.prefixes, set)
        self.assertIsInstance(secret.suffixes, set)

        self.assertListEqual(sorted(secret.exact), [
            'auth_data', 'auth_token', 'password', 'password1', 'password2',
            'secret_key', 'tls_pem_passphrase', 'token'
        ])
        self.assertListEqual(sorted(secret.prefixes), [])
        self.assertListEqual(sorted(secret.suffixes), [])

        self.assertEquals(bytes_to_str, test_encoding)

        self.assertEquals(config.default_value, '')
        self.assertEquals(config.default_input_value, '')
        self.assertEquals(config.default_output_value, '')
        self.assertEquals(config.response_elem, 'response')

        self.assertFalse(config.skip_empty_keys)
        self.assertFalse(config.skip_empty_request_keys)
        self.assertFalse(config.skip_empty_response_keys)

        self.assertEquals(config.input_required_name, 'input_required')
        self.assertEquals(config.input_optional_name, 'input_optional')
        self.assertEquals(config.output_required_name, 'output_required')
        self.assertEquals(config.output_optional_name, 'output_optional')

        self.assertEquals(config.prefix_as_is, 'a')
        self.assertEquals(config.prefix_bool, 'b')
        self.assertEquals(config.prefix_csv, 'c')
        self.assertEquals(config.prefix_date, 'date')
        self.assertEquals(config.prefix_date_time, 'dt')
        self.assertEquals(config.prefix_dict, 'd')
        self.assertEquals(config.prefix_dict_list, 'dl')
        self.assertEquals(config.prefix_float, 'f')
        self.assertEquals(config.prefix_int, 'i')
        self.assertEquals(config.prefix_list, 'l')
        self.assertEquals(config.prefix_text, 't')
        self.assertEquals(config.prefix_uuid, 'u')
Example #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()

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

            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