def test_validate_settings(self): self.validator_test(config.validate_settings_config, config_pb2.SettingsCfg(), []) self.validator_test( config.validate_settings_config, config_pb2.SettingsCfg(mp_server='http://url'), ['mp_server must start with "https://" or "http://localhost"']) self.validator_test( config.validate_settings_config, config_pb2.SettingsCfg(mp_server='url'), ['mp_server must start with "https://" or "http://localhost"'])
def settings(): return config_pb2.SettingsCfg(auth=config_pb2.AuthSettings( admins_group='admins', bot_bootstrap_group='bot_bootstrap', privileged_users_group='privileged_users', users_group='users', view_all_bots_group='view_all_bots', view_all_tasks_group='view_all_tasks'))
def test_settings_valid_mp_config(self): """Ensures base MP settings are correctly received if configured.""" settings_config = config_pb2.SettingsCfg(mp_server='server') self.install_mock(settings_config=settings_config) self.assertEqual(config._get_settings()[1].mp_server, 'server') self.assertEqual(machine_provider.MachineProviderConfiguration.instance_url, 'server')
def get_settings(): """Returns auth service own settings (from settings.cfg) as SettingsCfg proto. Returns default settings if the ones in the datastore are no longer valid. """ text = _get_service_config('settings.cfg') if not text: return config_pb2.SettingsCfg() # The config MUST be valid, since we do validation before storing it. If it # doesn't, better to revert to default setting rather than fail all requests. try: msg = config_pb2.SettingsCfg() protobuf.text_format.Merge(text, msg) return msg except protobuf.text_format.ParseError as ex: logging.error('Invalid settings.cfg: %s', ex) return config_pb2.SettingsCfg()
def test_settings_empty_mp_config(self): """Ensures base MP settings are correctly received if not configured.""" settings_config = config_pb2.SettingsCfg() self.install_mock(settings_config=settings_config) mpdefault = machine_provider.MachineProviderConfiguration.get_instance_url() self.failIf(config._get_settings()[1].mp_server) self.assertEqual(machine_provider.MachineProviderConfiguration.instance_url, mpdefault)
def get_self_config(path, _, **kwargs): self.assertIn(path, ('templates.cfg', 'managers.cfg', 'settings.cfg')) if path == 'templates.cfg': proto = template_config or config_pb2.InstanceTemplateConfig() elif path == 'managers.cfg': proto = manager_config or config_pb2.InstanceGroupManagerConfig() elif path == 'settings.cfg': proto = settings_config or config_pb2.SettingsCfg() return revision or 'mock-revision', proto
def test_validate_settings(self): self.validator_test( config._validate_settings, config_pb2.SettingsCfg( bot_death_timeout_secs=-1, reusable_task_age_secs=-1), [ 'bot_death_timeout_secs cannot be negative', 'reusable_task_age_secs cannot be negative', ]) self.validator_test( config._validate_settings, config_pb2.SettingsCfg( bot_death_timeout_secs=config._SECONDS_IN_YEAR + 1, reusable_task_age_secs=config._SECONDS_IN_YEAR + 1), [ 'bot_death_timeout_secs cannot be more than a year', 'reusable_task_age_secs cannot be more than a year', ]) self.validator_test( config._validate_settings, config_pb2.SettingsCfg( display_server_url_template='http://foo/bar', extra_child_src_csp_url=['http://alpha/beta', 'https://']), [ 'display_server_url_template URL http://foo/bar must be https', 'extra_child_src_csp_url URL http://alpha/beta must be https', 'extra_child_src_csp_url URL https:// must be https', ]) self.validator_test( config._validate_settings, config_pb2.SettingsCfg( display_server_url_template='https://foo/', extra_child_src_csp_url=['https://alpha/beta/']), []) self.validator_test(config._validate_settings, config_pb2.SettingsCfg(), []) self.validator_test( config._validate_settings, config_pb2.SettingsCfg( mp=config_pb2.MachineProviderSettings(server='http://url')), [ 'mp.server must start with "https://" or "http://localhost"', ]) self.validator_test( config._validate_settings, config_pb2.SettingsCfg( mp=config_pb2.MachineProviderSettings(server='url')), [ 'mp.server must start with "https://" or "http://localhost"', ])
def test_settings_updates(self): # Fetch only settings.cfg in this test case. self.mock(config, 'is_remote_configured', lambda: True) self.mock(config, '_CONFIG_SCHEMAS', { 'settings.cfg': config._CONFIG_SCHEMAS['settings.cfg'], }) # Default settings. self.assertEqual(config_pb2.SettingsCfg(), config.get_settings()) # Mock new settings value in luci-config. settings_cfg_text = 'enable_ts_monitoring: true' self.mock( config, '_fetch_configs', lambda _: { 'settings.cfg': (config.Revision('rev', 'url'), settings_cfg_text), }) # Fetch them. config.refetch_config() # Verify they are used now. utils.clear_cache(config.get_settings) self.assertEqual(config_pb2.SettingsCfg(enable_ts_monitoring=True), config.get_settings()) # "Delete" them from luci-config. self.mock( config, '_fetch_configs', lambda _: { 'settings.cfg': (config.Revision('0' * 40, 'url'), ''), }) # Fetch them. config.refetch_config() # Verify defaults are restored. utils.clear_cache(config.get_settings) self.assertEqual(config_pb2.SettingsCfg(), config.get_settings())
def _get_settings(): """Returns (rev, cfg) where cfg is a parsed SettingsCfg message. If config does not exists, returns (None, <cfg with defaults>). The config is cached in the datastore. """ # store_last_good=True tells config component to update the config file # in a cron job. Here we just read from the datastore. rev, cfg = config.get_self_config(SETTINGS_CFG_FILENAME, config_pb2.SettingsCfg, store_last_good=True) cfg = cfg or config_pb2.SettingsCfg() return rev, cfg
def test_validate_settings(self): self.validator_test( config.validate_settings, config_pb2.SettingsCfg(bot_death_timeout_secs=-1, reusable_task_age_secs=-1), [ 'bot_death_timeout_secs cannot be negative', 'reusable_task_age_secs cannot be negative', ]) self.validator_test( config.validate_settings, config_pb2.SettingsCfg( bot_death_timeout_secs=config.SECONDS_IN_YEAR + 1, reusable_task_age_secs=config.SECONDS_IN_YEAR + 1), [ 'bot_death_timeout_secs cannot be more than a year', 'reusable_task_age_secs cannot be more than a year', ]) self.validator_test(config.validate_settings, config_pb2.SettingsCfg(), []) self.validator_test( config.validate_settings, config_pb2.SettingsCfg(mp=config_pb2.MachineProviderSettings( server='http://url')), [ 'mp.server must start with "https://" or "http://localhost"', ]) self.validator_test( config.validate_settings, config_pb2.SettingsCfg(mp=config_pb2.MachineProviderSettings( server='url')), [ 'mp.server must start with "https://" or "http://localhost"', ])
def _get_settings_with_defaults(): """Returns (rev, cfg) where cfg is a parsed SettingsCfg message. If config does not exists, returns (None, <cfg with defaults>). The config is cached in the datastore. """ rev, cfg = _get_settings() cfg = cfg or config_pb2.SettingsCfg() cfg.default_expiration = cfg.default_expiration or 30 * 24 * 60 * 60 cfg.sharding_letters = cfg.sharding_letters or 4 cfg.gs_bucket = cfg.gs_bucket or app_identity.get_application_id() cfg.auth.full_access_group = cfg.auth.full_access_group or 'administrators' cfg.auth.readonly_access_group = \ cfg.auth.readonly_access_group or 'administrators' return rev, cfg
def _get_settings(): """Returns (rev, cfg) where cfg is a parsed SettingsCfg message. The config is cached in the datastore. """ rev, cfg = config.get_self_config(SETTINGS_CFG_FILENAME, config_pb2.SettingsCfg, store_last_good=True) cfg = cfg or config_pb2.SettingsCfg() if cfg.mp_server: current_config = machine_provider.MachineProviderConfiguration.cached() if cfg.mp_server != current_config.instance_url: logging.info('Updating Machine Provider server to %s', cfg.mp_server) current_config.modify(instance_url=cfg.mp_server) return rev, cfg
def setUp(self): super(AppTestBase, self).setUp() self.bot_version = None self.source_ip = '192.168.2.2' self.testbed.init_user_stub() gae_ts_mon.reset_for_unittest(disable=True) event_mon_metrics.initialize() # By default requests in tests are coming from bot with fake IP. # WSGI app that implements auth REST API. self.auth_app = webtest.TestApp( auth.create_wsgi_application(debug=True), extra_environ={ 'REMOTE_ADDR': self.source_ip, 'SERVER_SOFTWARE': os.environ['SERVER_SOFTWARE'], }) admins_group = 'test_admins_group' priv_users_group = 'test_priv_users_group' users_group = 'test_users_group' cfg = config_pb2.SettingsCfg(auth=config_pb2.AuthSettings( admins_group=admins_group, privileged_users_group=priv_users_group, users_group=users_group, )) self.mock(config, '_get_settings', lambda: ('test_rev', cfg)) utils.clear_cache(config.settings) # Note that auth.ADMIN_GROUP != admins_group. auth.bootstrap_group( auth.ADMIN_GROUP, [auth.Identity(auth.IDENTITY_USER, '*****@*****.**')]) auth.bootstrap_group( admins_group, [auth.Identity(auth.IDENTITY_USER, '*****@*****.**')]) auth.bootstrap_group( priv_users_group, [auth.Identity(auth.IDENTITY_USER, '*****@*****.**')]) auth.bootstrap_group( users_group, [auth.Identity(auth.IDENTITY_USER, '*****@*****.**')])
def _get_settings_with_defaults(): """Returns (rev, cfg) where cfg is a parsed SettingsCfg message. If config does not exists, returns (None, <cfg with defaults>). The config is cached in the datastore. """ rev, cfg = _get_settings() cfg = cfg or config_pb2.SettingsCfg() cfg.reusable_task_age_secs = cfg.reusable_task_age_secs or 7 * 24 * 60 * 60 cfg.bot_death_timeout_secs = cfg.bot_death_timeout_secs or 10 * 60 cfg.auth.admins_group = cfg.auth.admins_group or 'administrators' cfg.auth.bot_bootstrap_group = cfg.auth.bot_bootstrap_group or \ 'administrators' cfg.auth.privileged_users_group = cfg.auth.privileged_users_group or \ 'administrators' cfg.auth.users_group = cfg.auth.users_group or 'administrators' return rev, cfg
def _get_settings(): """Returns (rev, cfg) where cfg is a parsed SettingsCfg message. If config does not exists, returns (None, <cfg with defaults>). The config is cached in the datastore. """ rev = None cfg = None try: # store_last_good=True tells config component to update the config file # in a cron job. Here we just read from datastore. rev, cfg = config.get_self_config(SETTINGS_CFG_FILENAME, config_pb2.SettingsCfg, store_last_good=True) except config.CannotLoadConfigError as ex: logging.info('Could not load settings.cfg: %s; using defaults', ex) if not cfg: cfg = config_pb2.SettingsCfg(reusable_task_age_secs=7 * 24 * 60 * 60, bot_death_timeout_secs=10 * 60) return rev, cfg
def mock_config(self, **kwargs): self.mock(config, 'get_settings', lambda: config_pb2.SettingsCfg(**kwargs))
def test_make(self): settings = config_pb2.SettingsCfg() config = json.loads( bot_archive._make_config_json('host', 'host_version', settings)) self.assertEqual(_EXPECTED_CONFIG_KEYS, set(config))
def is_valid(**fields): ctx = validation.Context() config.validate_settings_cfg(config_pb2.SettingsCfg(**fields), ctx) return not ctx.messages