def test_system_transform(self): rule = self.models['rules']['rule_action_default_value_render_fail.yaml'] runner_type_db = mock.Mock() runner_type_db.runner_parameters = {} action_db = mock.Mock() action_db.parameters = {} k5 = KeyValuePair.add_or_update(KeyValuePairDB(name='k5', value='v5')) k6 = KeyValuePair.add_or_update(KeyValuePairDB(name='k6', value='v6')) k7 = KeyValuePair.add_or_update(KeyValuePairDB(name='k7', value='v7')) k8 = KeyValuePair.add_or_update(KeyValuePairDB(name='k8', value='v8', scope=FULL_SYSTEM_SCOPE)) params = {'ip5': '{{trigger.k2}}-static', 'ip6': '{{st2kv.system.k6}}-static', 'ip7': '{{st2kv.system.k7}}-static'} expected_params = {'ip5': 'v2-static', 'ip6': 'v6-static', 'ip7': 'v7-static'} try: self.assertResolvedParamsMatchExpected(rule=rule, trigger_instance=MOCK_TRIGGER_INSTANCE_4, params=params, expected_params=expected_params) finally: KeyValuePair.delete(k5) KeyValuePair.delete(k6) KeyValuePair.delete(k7) KeyValuePair.delete(k8)
def test_user_scope_lookups_user_sep_in_name(self): KeyValuePair.add_or_update(KeyValuePairDB(name='stanley:r:i:p', value='v4', scope=FULL_USER_SCOPE)) lookup = UserKeyValueLookup(scope=FULL_USER_SCOPE, user='******') # This is the only way to lookup because USER_SEPARATOR (':') cannot be a part of # variable name in Python. self.assertEquals(str(lookup['r:i:p']), 'v4')
def test_system_transform(self): k5 = KeyValuePair.add_or_update(KeyValuePairDB(name='k5', value='v5')) k6 = KeyValuePair.add_or_update(KeyValuePairDB(name='k6', value='v6')) k7 = KeyValuePair.add_or_update(KeyValuePairDB(name='k7', value='v7')) k8 = KeyValuePair.add_or_update( KeyValuePairDB(name='k8', value='v8', scope=FULL_SYSTEM_SCOPE)) try: transformer = datatransform.get_transformer(PAYLOAD) mapping = { 'ip5': '{{trigger.k2}}-static', 'ip6': '{{st2kv.system.k6}}-static', 'ip7': '{{st2kv.system.k7}}-static' } result = transformer(mapping) expected = { 'ip5': 'v2-static', 'ip6': 'v6-static', 'ip7': 'v7-static' } self.assertEqual(result, expected) finally: KeyValuePair.delete(k5) KeyValuePair.delete(k6) KeyValuePair.delete(k7) KeyValuePair.delete(k8)
def test_get_config_dynamic_config_item_list(self): pack_name = "dummy_pack_schema_with_nested_object_7" loader = ContentPackConfigLoader(pack_name=pack_name) KeyValuePair.add_or_update(KeyValuePairDB(name="k0", value="v0")) KeyValuePair.add_or_update(KeyValuePairDB(name="k1", value="v1")) #################### # values in list values = { "level0_key": [ "a", "{{st2kv.system.k0}}", "b", "{{st2kv.system.k1}}", ] } config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) config_rendered = loader.get_config() self.assertEqual(config_rendered, {"level0_key": ["a", "v0", "b", "v1"]}) config_db.delete()
def test_get_config_dynamic_config_item_list(self): pack_name = 'dummy_pack_schema_with_nested_object_7' loader = ContentPackConfigLoader(pack_name=pack_name) KeyValuePair.add_or_update(KeyValuePairDB(name='k0', value='v0')) KeyValuePair.add_or_update(KeyValuePairDB(name='k1', value='v1')) #################### # values in list values = { 'level0_key': [ 'a', '{{st2kv.system.k0}}', 'b', '{{st2kv.system.k1}}', ] } config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) config_rendered = loader.get_config() self.assertEqual(config_rendered, {'level0_key': ['a', 'v0', 'b', 'v1']}) config_db.delete()
def test_lookup_cast(self): KeyValuePair.add_or_update(KeyValuePairDB(name='count', value='5.5')) lookup = KeyValueLookup(scope=FULL_SYSTEM_SCOPE) self.assertEqual(str(lookup.count), '5.5') self.assertEqual(float(lookup.count), 5.5) self.assertEqual(int(lookup.count), 5)
def test_get_finalized_params_system_values(self): KeyValuePair.add_or_update(KeyValuePairDB(name='actionstr', value='foo')) KeyValuePair.add_or_update(KeyValuePairDB(name='actionnumber', value='1.0')) params = { 'runnerint': 555 } liveaction_db = self._get_liveaction_model(params) runner_params, action_params = param_utils.get_finalized_params( ParamsUtilsTest.runnertype_db.runner_parameters, ParamsUtilsTest.action_system_default_db.parameters, liveaction_db.parameters, liveaction_db.context) # Asserts for runner params. # Assert that default values for runner params are resolved. self.assertEqual(runner_params.get('runnerstr'), 'defaultfoo') # Assert that a runner param from action exec is picked up. self.assertEqual(runner_params.get('runnerint'), 555) # Assert that an immutable param cannot be overridden by action param or execution param. self.assertEqual(runner_params.get('runnerimmutable'), 'runnerimmutable') # Asserts for action params. self.assertEqual(action_params.get('actionstr'), 'foo') self.assertEqual(action_params.get('actionnumber'), 1.0)
def migrate_datastore(): key_value_items = KeyValuePair.get_all() try: for kvp in key_value_items: kvp_id = getattr(kvp, 'id', None) secret = getattr(kvp, 'secret', False) scope = getattr(kvp, 'scope', SYSTEM_SCOPE) if scope == USER_SCOPE: scope = FULL_USER_SCOPE if scope == SYSTEM_SCOPE: scope = FULL_SYSTEM_SCOPE new_kvp_db = KeyValuePairDB(id=kvp_id, name=kvp.name, expire_timestamp=kvp.expire_timestamp, value=kvp.value, secret=secret, scope=scope) KeyValuePair.add_or_update(new_kvp_db) except: print('ERROR: Failed migrating datastore item with name: %s' % kvp.name) tb.print_exc() raise
def test_get_config_dynamic_config_item_list(self): pack_name = 'dummy_pack_schema_with_nested_object_7' loader = ContentPackConfigLoader(pack_name=pack_name) KeyValuePair.add_or_update(KeyValuePairDB(name='k0', value='v0')) KeyValuePair.add_or_update(KeyValuePairDB(name='k1', value='v1')) #################### # values in list values = { 'level0_key': [ 'a', '{{st2kv.system.k0}}', 'b', '{{st2kv.system.k1}}', ] } config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) config_rendered = loader.get_config() self.assertEquals(config_rendered, { 'level0_key': [ 'a', 'v0', 'b', 'v1' ] }) config_db.delete()
def test_get_value_from_datastore_through_render_live_params(self): # Register datastore value to be refered by this test-case register_kwargs = [ { 'name': 'test_key', 'value': 'foo' }, { 'name': 'user1:test_key', 'value': 'bar', 'scope': FULL_USER_SCOPE }, { 'name': '%s:test_key' % cfg.CONF.system_user.user, 'value': 'baz', 'scope': FULL_USER_SCOPE }, ] for kwargs in register_kwargs: KeyValuePair.add_or_update(KeyValuePairDB(**kwargs)) # Assert that datastore value can be got via the Jinja expression from individual scopes. context = {'user': '******'} param = { 'system_value': { 'default': '{{ st2kv.system.test_key }}' }, 'user_value': { 'default': '{{ st2kv.user.test_key }}' }, } live_params = param_utils.render_live_params(runner_parameters={}, action_parameters=param, params={}, action_context=context) self.assertEqual(live_params['system_value'], 'foo') self.assertEqual(live_params['user_value'], 'bar') # Assert that datastore value in the user-scope that is registered by user1 # cannot be got by the operation of user2. context = {'user': '******'} param = {'user_value': {'default': '{{ st2kv.user.test_key }}'}} live_params = param_utils.render_live_params(runner_parameters={}, action_parameters=param, params={}, action_context=context) self.assertEqual(live_params['user_value'], '') # Assert that system-user's scope is selected when user and api_user parameter specified context = {} param = {'user_value': {'default': '{{ st2kv.user.test_key }}'}} live_params = param_utils.render_live_params(runner_parameters={}, action_parameters=param, params={}, action_context=context) self.assertEqual(live_params['user_value'], 'baz')
def test_user_scope_lookups_dot_in_user(self): KeyValuePair.add_or_update( KeyValuePairDB(name='first.last:r.i.p', value='v4', scope=FULL_USER_SCOPE)) lookup = UserKeyValueLookup(scope=FULL_USER_SCOPE, user='******') self.assertEqual(str(lookup.r.i.p), 'v4') self.assertEqual(str(lookup['r']['i']['p']), 'v4')
def test_user_scope_lookups_dot_in_user(self): KeyValuePair.add_or_update( KeyValuePairDB(name="first.last:r.i.p", value="v4", scope=FULL_USER_SCOPE)) lookup = UserKeyValueLookup(scope=FULL_USER_SCOPE, user="******") self.assertEqual(str(lookup.r.i.p), "v4") self.assertEqual(str(lookup["r"]["i"]["p"]), "v4")
def test_non_hierarchical_lookup(self): k1 = KeyValuePair.add_or_update(KeyValuePairDB(name='k1', value='v1')) k2 = KeyValuePair.add_or_update(KeyValuePairDB(name='k2', value='v2')) k3 = KeyValuePair.add_or_update(KeyValuePairDB(name='k3', value='v3')) lookup = KeyValueLookup() self.assertEquals(str(lookup.k1), k1.value) self.assertEquals(str(lookup.k2), k2.value) self.assertEquals(str(lookup.k3), k3.value)
def test_lookups_older_scope_names_backward_compatibility(self): k1 = KeyValuePair.add_or_update(KeyValuePairDB(name='a.b', value='v1', scope=FULL_SYSTEM_SCOPE)) lookup = KeyValueLookup(scope=SYSTEM_SCOPE) self.assertEquals(str(lookup['a']['b']), k1.value) k2 = KeyValuePair.add_or_update(KeyValuePairDB(name='stanley:r.i.p', value='v4', scope=FULL_USER_SCOPE)) user_lookup = UserKeyValueLookup(scope=USER_SCOPE, user='******') self.assertEquals(str(user_lookup['r']['i']['p']), k2.value)
def test_hierarchical_lookup_dict(self): k1 = KeyValuePair.add_or_update(KeyValuePairDB(name='a.b', value='v1')) k2 = KeyValuePair.add_or_update(KeyValuePairDB(name='a.b.c', value='v2')) k3 = KeyValuePair.add_or_update(KeyValuePairDB(name='b.c', value='v3')) lookup = KeyValueLookup() self.assertEquals(str(lookup['a']['b']), k1.value) self.assertEquals(str(lookup['a']['b']['c']), k2.value) self.assertEquals(str(lookup['b']['c']), k3.value) self.assertEquals(str(lookup['a']), '')
def setUp(self): super(KeyValuesControllerRBACTestCase, self).setUp() self.kvps = {} # Insert mock users user_1_db = UserDB(name='user1') user_1_db = User.add_or_update(user_1_db) self.users['user_1'] = user_1_db user_2_db = UserDB(name='user2') user_2_db = User.add_or_update(user_2_db) self.users['user_2'] = user_2_db # Insert mock kvp objects kvp_api = KeyValuePairSetAPI(name='test_system_scope', value='value1', scope=FULL_SYSTEM_SCOPE) kvp_db = KeyValuePairSetAPI.to_model(kvp_api) kvp_db = KeyValuePair.add_or_update(kvp_db) kvp_db = KeyValuePairAPI.from_model(kvp_db) self.kvps['kvp_1'] = kvp_db kvp_api = KeyValuePairSetAPI(name='test_system_scope_secret', value='value_secret', scope=FULL_SYSTEM_SCOPE, secret=True) kvp_db = KeyValuePairSetAPI.to_model(kvp_api) kvp_db = KeyValuePair.add_or_update(kvp_db) kvp_db = KeyValuePairAPI.from_model(kvp_db) self.kvps['kvp_2'] = kvp_db name = get_key_reference(scope=FULL_USER_SCOPE, name='test_user_scope_1', user='******') kvp_db = KeyValuePairDB(name=name, value='valueu12', scope=FULL_USER_SCOPE) kvp_db = KeyValuePair.add_or_update(kvp_db) kvp_db = KeyValuePairAPI.from_model(kvp_db) self.kvps['kvp_3'] = kvp_db name = get_key_reference(scope=FULL_USER_SCOPE, name='test_user_scope_2', user='******') kvp_api = KeyValuePairSetAPI(name=name, value='user_secret', scope=FULL_USER_SCOPE, secret=True) kvp_db = KeyValuePairSetAPI.to_model(kvp_api) kvp_db = KeyValuePair.add_or_update(kvp_db) kvp_db = KeyValuePairAPI.from_model(kvp_db) self.kvps['kvp_4'] = kvp_db name = get_key_reference(scope=FULL_USER_SCOPE, name='test_user_scope_3', user='******') kvp_db = KeyValuePairDB(name=name, value='valueu21', scope=FULL_USER_SCOPE) kvp_db = KeyValuePair.add_or_update(kvp_db) kvp_db = KeyValuePairAPI.from_model(kvp_db) self.kvps['kvp_5'] = kvp_db self.system_scoped_items_count = 2 self.user_scoped_items_count = 3 self.user_scoped_items_per_user_count = { 'user1': 2, 'user2': 1 }
def test_get_config_dynamic_config_item_under_additional_properties(self): pack_name = "dummy_pack_schema_with_additional_properties_1" loader = ContentPackConfigLoader(pack_name=pack_name) encrypted_value = crypto.symmetric_encrypt(KeyValuePairAPI.crypto_key, "v1_encrypted") KeyValuePair.add_or_update( KeyValuePairDB(name="k1_encrypted", value=encrypted_value, secret=True)) #################### # values in objects under an object with additionalProperties values = { "profiles": { "dev": { # no host or port to test default value "token": "hard-coded-secret", }, "prod": { "host": "127.1.2.7", "port": 8282, # encrypted in datastore "token": "{{st2kv.system.k1_encrypted}}", # schema declares `secret: true` which triggers auto-decryption. # If this were not encrypted, it would try to decrypt it and fail. }, } } config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) config_rendered = loader.get_config() self.assertEqual( config_rendered, { "region": "us-east-1", "profiles": { "dev": { "host": "127.0.0.3", "port": 8080, "token": "hard-coded-secret", }, "prod": { "host": "127.1.2.7", "port": 8282, "token": "v1_encrypted", }, }, }, ) config_db.delete()
def test_lookup_with_key_prefix(self): KeyValuePair.add_or_update(KeyValuePairDB(name='some:prefix:stanley:k5', value='v5', scope=FULL_USER_SCOPE)) # No prefix provided, should return None lookup = UserKeyValueLookup(user='******', scope=FULL_USER_SCOPE) self.assertEqual(str(lookup.k5), '') # Prefix provided lookup = UserKeyValueLookup(prefix='some:prefix', user='******', scope=FULL_USER_SCOPE) self.assertEqual(str(lookup.k5), 'v5')
def test_get_value_from_datastore_through_render_live_params(self): # Register datastore value to be refered by this test-case register_kwargs = [ {"name": "test_key", "value": "foo"}, {"name": "user1:test_key", "value": "bar", "scope": FULL_USER_SCOPE}, { "name": "%s:test_key" % cfg.CONF.system_user.user, "value": "baz", "scope": FULL_USER_SCOPE, }, ] for kwargs in register_kwargs: KeyValuePair.add_or_update(KeyValuePairDB(**kwargs)) # Assert that datastore value can be got via the Jinja expression from individual scopes. context = {"user": "******"} param = { "system_value": {"default": "{{ st2kv.system.test_key }}"}, "user_value": {"default": "{{ st2kv.user.test_key }}"}, } live_params = param_utils.render_live_params( runner_parameters={}, action_parameters=param, params={}, action_context=context, ) self.assertEqual(live_params["system_value"], "foo") self.assertEqual(live_params["user_value"], "bar") # Assert that datastore value in the user-scope that is registered by user1 # cannot be got by the operation of user2. context = {"user": "******"} param = {"user_value": {"default": "{{ st2kv.user.test_key }}"}} live_params = param_utils.render_live_params( runner_parameters={}, action_parameters=param, params={}, action_context=context, ) self.assertEqual(live_params["user_value"], "") # Assert that system-user's scope is selected when user and api_user parameter specified context = {} param = {"user_value": {"default": "{{ st2kv.user.test_key }}"}} live_params = param_utils.render_live_params( runner_parameters={}, action_parameters=param, params={}, action_context=context, ) self.assertEqual(live_params["user_value"], "baz")
def test_lookups_older_scope_names_backward_compatibility(self): k1 = KeyValuePair.add_or_update( KeyValuePairDB(name="a.b", value="v1", scope=FULL_SYSTEM_SCOPE)) lookup = KeyValueLookup(scope=SYSTEM_SCOPE) self.assertEqual(str(lookup["a"]["b"]), k1.value) k2 = KeyValuePair.add_or_update( KeyValuePairDB(name="stanley:r.i.p", value="v4", scope=FULL_USER_SCOPE)) user_lookup = UserKeyValueLookup(scope=USER_SCOPE, user="******") self.assertEqual(str(user_lookup["r"]["i"]["p"]), k2.value)
def test_secret_lookup(self): secret_value = '0055A2D9A09E1071931925933744965EEA7E23DCF59A8D1D7A3' + \ '64338294916D37E83C4796283C584751750E39844E2FD97A3727DB5D553F638' k1 = KeyValuePair.add_or_update(KeyValuePairDB( name='k1', value=secret_value, secret=True, encrypted=True) ) k2 = KeyValuePair.add_or_update(KeyValuePairDB(name='k2', value='v2')) lookup = KeyValueLookup() self.assertEquals(str(lookup.k1), k1.value) self.assertEquals(str(lookup.k2), k2.value)
def setUp(self): super(KeyValuesControllerRBACTestCase, self).setUp() self.kvps = {} # Insert mock users user_1_db = UserDB(name="user1") user_1_db = User.add_or_update(user_1_db) self.users["user_1"] = user_1_db user_2_db = UserDB(name="user2") user_2_db = User.add_or_update(user_2_db) self.users["user_2"] = user_2_db # Insert mock kvp objects kvp_api = KeyValuePairSetAPI(name="test_system_scope", value="value1", scope=FULL_SYSTEM_SCOPE) kvp_db = KeyValuePairSetAPI.to_model(kvp_api) kvp_db = KeyValuePair.add_or_update(kvp_db) kvp_db = KeyValuePairAPI.from_model(kvp_db) self.kvps["kvp_1"] = kvp_db kvp_api = KeyValuePairSetAPI( name="test_system_scope_secret", value="value_secret", scope=FULL_SYSTEM_SCOPE, secret=True ) kvp_db = KeyValuePairSetAPI.to_model(kvp_api) kvp_db = KeyValuePair.add_or_update(kvp_db) kvp_db = KeyValuePairAPI.from_model(kvp_db) self.kvps["kvp_2"] = kvp_db name = get_key_reference(scope=FULL_USER_SCOPE, name="test_user_scope_1", user="******") kvp_db = KeyValuePairDB(name=name, value="valueu12", scope=FULL_USER_SCOPE) kvp_db = KeyValuePair.add_or_update(kvp_db) kvp_db = KeyValuePairAPI.from_model(kvp_db) self.kvps["kvp_3"] = kvp_db name = get_key_reference(scope=FULL_USER_SCOPE, name="test_user_scope_2", user="******") kvp_api = KeyValuePairSetAPI(name=name, value="user_secret", scope=FULL_USER_SCOPE, secret=True) kvp_db = KeyValuePairSetAPI.to_model(kvp_api) kvp_db = KeyValuePair.add_or_update(kvp_db) kvp_db = KeyValuePairAPI.from_model(kvp_db) self.kvps["kvp_4"] = kvp_db name = get_key_reference(scope=FULL_USER_SCOPE, name="test_user_scope_3", user="******") kvp_db = KeyValuePairDB(name=name, value="valueu21", scope=FULL_USER_SCOPE) kvp_db = KeyValuePair.add_or_update(kvp_db) kvp_db = KeyValuePairAPI.from_model(kvp_db) self.kvps["kvp_5"] = kvp_db self.system_scoped_items_count = 2 self.user_scoped_items_count = 3 self.user_scoped_items_per_user_count = {"user1": 2, "user2": 1}
def test_system_transform(self): k5 = KeyValuePair.add_or_update(KeyValuePairDB(name="k5", value="v5")) k6 = KeyValuePair.add_or_update(KeyValuePairDB(name="k6", value="v6")) k7 = KeyValuePair.add_or_update(KeyValuePairDB(name="k7", value="v7")) try: transformer = datatransform.get_transformer(PAYLOAD) mapping = {"ip5": "{{trigger.k2}}-static", "ip6": "{{system.k6}}-static", "ip7": "{{system.k7}}-static"} result = transformer(mapping) expected = {"ip5": "v2-static", "ip6": "v6-static", "ip7": "v7-static"} self.assertEqual(result, expected) finally: KeyValuePair.delete(k5) KeyValuePair.delete(k6) KeyValuePair.delete(k7)
def setUp(self): super(TemplatingUtilsTestCase, self).setUp() # Insert mock DB objects kvp_1_db = KeyValuePairDB(name='key1', value='valuea') kvp_1_db = KeyValuePair.add_or_update(kvp_1_db) kvp_2_db = KeyValuePairDB(name='key2', value='valueb') kvp_2_db = KeyValuePair.add_or_update(kvp_2_db) kvp_3_db = KeyValuePairDB(name='stanley:key1', value='valuestanley1', scope=USER_SCOPE) kvp_3_db = KeyValuePair.add_or_update(kvp_3_db) kvp_4_db = KeyValuePairDB(name='joe:key1', value='valuejoe1', scope=USER_SCOPE) kvp_4_db = KeyValuePair.add_or_update(kvp_4_db)
def setUp(self): super(TemplatingUtilsTestCase, self).setUp() # Insert mock DB objects kvp_1_db = KeyValuePairDB(name='key1', value='valuea') kvp_1_db = KeyValuePair.add_or_update(kvp_1_db) kvp_2_db = KeyValuePairDB(name='key2', value='valueb') kvp_2_db = KeyValuePair.add_or_update(kvp_2_db) kvp_3_db = KeyValuePairDB(name='stanley:key1', value='valuestanley1', scope=FULL_USER_SCOPE) kvp_3_db = KeyValuePair.add_or_update(kvp_3_db) kvp_4_db = KeyValuePairDB(name='joe:key1', value='valuejoe1', scope=FULL_USER_SCOPE) kvp_4_db = KeyValuePair.add_or_update(kvp_4_db)
def test_filter_decrypt_kv(self): KeyValuePair.add_or_update(KeyValuePairDB(name='k8', value=self.secret_value, scope=FULL_SYSTEM_SCOPE, secret=True)) context = {} context.update({SYSTEM_SCOPE: KeyValueLookup(scope=SYSTEM_SCOPE)}) context.update({ DATASTORE_PARENT_SCOPE: { SYSTEM_SCOPE: KeyValueLookup(scope=FULL_SYSTEM_SCOPE) } }) template = '{{st2kv.system.k8 | decrypt_kv}}' actual = self.env.from_string(template).render(context) self.assertEqual(actual, self.secret)
def test_filter_decrypt_kv_with_user_scope_value(self): KeyValuePair.add_or_update(KeyValuePairDB(name='stanley:k8', value=self.secret_value, scope=FULL_USER_SCOPE, secret=True)) context = {} context.update({USER_SCOPE: UserKeyValueLookup(user='******', scope=USER_SCOPE)}) context.update({ DATASTORE_PARENT_SCOPE: { USER_SCOPE: UserKeyValueLookup(user='******', scope=FULL_USER_SCOPE) } }) template = '{{st2kv.user.k8 | decrypt_kv}}' actual = self.env.from_string(template).render(context) self.assertEqual(actual, self.secret)
def put(self, name, kvp): """ Create a new entry or update an existing one. """ # TODO: There is a race, add custom add_or_update which updates by non # id field existing_kvp = self.__get_by_name(name=name) kvp.name = name try: kvp_db = KeyValuePairAPI.to_model(kvp) if existing_kvp: kvp_db.id = existing_kvp.id kvp_db = KeyValuePair.add_or_update(kvp_db) except (ValidationError, ValueError) as e: LOG.exception('Validation failed for key value data=%s', kvp) abort(http_client.BAD_REQUEST, str(e)) return extra = {'kvp_db': kvp_db} LOG.audit('KeyValuePair updated. KeyValuePair.id=%s' % (kvp_db.id), extra=extra) kvp_api = KeyValuePairAPI.from_model(kvp_db) return kvp_api
def put(self, name, kvp): """ Create a new entry or update an existing one. """ lock_name = self._get_lock_name_for_key(name=name) # TODO: Custom permission check since the key doesn't need to exist here # Note: We use lock to avoid a race with self._coordinator.get_lock(lock_name): existing_kvp = self._get_by_name(resource_name=name) kvp.name = name try: kvp_db = KeyValuePairAPI.to_model(kvp) if existing_kvp: kvp_db.id = existing_kvp.id kvp_db = KeyValuePair.add_or_update(kvp_db) except (ValidationError, ValueError) as e: LOG.exception('Validation failed for key value data=%s', kvp) abort(http_client.BAD_REQUEST, str(e)) return except CryptoKeyNotSetupException as e: LOG.exception(str(e)) abort(http_client.BAD_REQUEST, str(e)) return extra = {'kvp_db': kvp_db} LOG.audit('KeyValuePair updated. KeyValuePair.id=%s' % (kvp_db.id), extra=extra) kvp_api = KeyValuePairAPI.from_model(kvp_db) return kvp_api
def test_get_config_dynamic_config_item(self): pack_name = "dummy_pack_schema_with_nested_object_6" loader = ContentPackConfigLoader(pack_name=pack_name) #################### # value in top level item KeyValuePair.add_or_update(KeyValuePairDB(name="k1", value="v1")) values = {"level0_key": "{{st2kv.system.k1}}"} config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) config_rendered = loader.get_config() self.assertEqual(config_rendered, {"level0_key": "v1"}) config_db.delete()
def put(self, name, kvp): """ Create a new entry or update an existing one. """ lock_name = self._get_lock_name_for_key(name=name) # TODO: Custom permission check since the key doesn't need to exist here # Note: We use lock to avoid a race with self._coordinator.get_lock(lock_name): existing_kvp = self.__get_by_name(name=name) kvp.name = name try: kvp_db = KeyValuePairAPI.to_model(kvp) if existing_kvp: kvp_db.id = existing_kvp.id kvp_db = KeyValuePair.add_or_update(kvp_db) except (ValidationError, ValueError) as e: LOG.exception('Validation failed for key value data=%s', kvp) abort(http_client.BAD_REQUEST, str(e)) return extra = {'kvp_db': kvp_db} LOG.audit('KeyValuePair updated. KeyValuePair.id=%s' % (kvp_db.id), extra=extra) kvp_api = KeyValuePairAPI.from_model(kvp_db) return kvp_api
def put(self, kvp, name, scope=FULL_SYSTEM_SCOPE): """ Create a new entry or update an existing one. """ if not scope: scope = FULL_SYSTEM_SCOPE requester_user = get_requester() scope = getattr(kvp, 'scope', scope) scope = get_datastore_full_scope(scope) self._validate_scope(scope=scope) user = getattr(kvp, 'user', requester_user) or requester_user # Validate that the authenticated user is admin if user query param is provided assert_request_user_is_admin_if_user_query_param_is_provider(request=pecan.request, user=user) key_ref = get_key_reference(scope=scope, name=name, user=user) lock_name = self._get_lock_name_for_key(name=key_ref, scope=scope) LOG.debug('PUT scope: %s, name: %s', scope, name) # TODO: Custom permission check since the key doesn't need to exist here # Note: We use lock to avoid a race with self._coordinator.get_lock(lock_name): try: existing_kvp_api = self._get_one_by_scope_and_name( scope=scope, name=key_ref ) except StackStormDBObjectNotFoundError: existing_kvp_api = None kvp.name = key_ref kvp.scope = scope try: kvp_db = KeyValuePairAPI.to_model(kvp) if existing_kvp_api: kvp_db.id = existing_kvp_api.id kvp_db = KeyValuePair.add_or_update(kvp_db) except (ValidationError, ValueError) as e: LOG.exception('Validation failed for key value data=%s', kvp) abort(http_client.BAD_REQUEST, str(e)) return except CryptoKeyNotSetupException as e: LOG.exception(str(e)) abort(http_client.BAD_REQUEST, str(e)) return except InvalidScopeException as e: LOG.exception(str(e)) abort(http_client.BAD_REQUEST, str(e)) return extra = {'kvp_db': kvp_db} LOG.audit('KeyValuePair updated. KeyValuePair.id=%s' % (kvp_db.id), extra=extra) kvp_api = KeyValuePairAPI.from_model(kvp_db) return kvp_api
def test_get_config_dynamic_config_item(self): pack_name = 'dummy_pack_schema_with_nested_object_6' loader = ContentPackConfigLoader(pack_name=pack_name) #################### # value in top level item KeyValuePair.add_or_update(KeyValuePairDB(name='k1', value='v1')) values = {'level0_key': '{{st2kv.system.k1}}'} config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) config_rendered = loader.get_config() self.assertEqual(config_rendered, {'level0_key': 'v1'}) config_db.delete()
def put(self, kvp, name, scope=FULL_SYSTEM_SCOPE): """ Create a new entry or update an existing one. """ if not scope: scope = FULL_SYSTEM_SCOPE requester_user = get_requester() scope = getattr(kvp, 'scope', scope) scope = get_datastore_full_scope(scope) self._validate_scope(scope=scope) user = getattr(kvp, 'user', requester_user) or requester_user # Validate that the authenticated user is admin if user query param is provided assert_request_user_is_admin_if_user_query_param_is_provided( request=pecan.request, user=user) key_ref = get_key_reference(scope=scope, name=name, user=user) lock_name = self._get_lock_name_for_key(name=key_ref, scope=scope) LOG.debug('PUT scope: %s, name: %s', scope, name) # TODO: Custom permission check since the key doesn't need to exist here # Note: We use lock to avoid a race with self._coordinator.get_lock(lock_name): try: existing_kvp_api = self._get_one_by_scope_and_name( scope=scope, name=key_ref) except StackStormDBObjectNotFoundError: existing_kvp_api = None kvp.name = key_ref kvp.scope = scope try: kvp_db = KeyValuePairAPI.to_model(kvp) if existing_kvp_api: kvp_db.id = existing_kvp_api.id kvp_db = KeyValuePair.add_or_update(kvp_db) except (ValidationError, ValueError) as e: LOG.exception('Validation failed for key value data=%s', kvp) abort(http_client.BAD_REQUEST, str(e)) return except CryptoKeyNotSetupException as e: LOG.exception(str(e)) abort(http_client.BAD_REQUEST, str(e)) return except InvalidScopeException as e: LOG.exception(str(e)) abort(http_client.BAD_REQUEST, str(e)) return extra = {'kvp_db': kvp_db} LOG.audit('KeyValuePair updated. KeyValuePair.id=%s' % (kvp_db.id), extra=extra) kvp_api = KeyValuePairAPI.from_model(kvp_db) return kvp_api
def migrate_datastore(): key_value_items = KeyValuePair.get_all() try: for kvp in key_value_items: kvp_id = getattr(kvp, 'id', None) secret = getattr(kvp, 'secret', False) scope = getattr(kvp, 'scope', SYSTEM_SCOPE) new_kvp_db = KeyValuePairDB(id=kvp_id, name=kvp.name, expire_timestamp=kvp.expire_timestamp, value=kvp.value, secret=secret, scope=scope) KeyValuePair.add_or_update(new_kvp_db) except: print('ERROR: Failed migrating datastore item with name: %s' % kvp.name) tb.print_exc() raise
def test_non_hierarchical_lookup(self): k1 = KeyValuePair.add_or_update(KeyValuePairDB(name='k1', value='v1')) k2 = KeyValuePair.add_or_update(KeyValuePairDB(name='k2', value='v2')) k3 = KeyValuePair.add_or_update(KeyValuePairDB(name='k3', value='v3')) k4 = KeyValuePair.add_or_update(KeyValuePairDB(name='stanley:k4', value='v4', scope=FULL_USER_SCOPE)) lookup = KeyValueLookup() self.assertEquals(str(lookup.k1), k1.value) self.assertEquals(str(lookup.k2), k2.value) self.assertEquals(str(lookup.k3), k3.value) # Scoped lookup lookup = KeyValueLookup(scope=FULL_SYSTEM_SCOPE) self.assertEquals(str(lookup.k4), '') user_lookup = UserKeyValueLookup(scope=FULL_USER_SCOPE, user='******') self.assertEquals(str(user_lookup.k4), k4.value)
def test_get_value_from_datastore_through_render_live_params(self): # Register datastore value to be refered by this test-case register_kwargs = [ {'name': 'test_key', 'value': 'foo'}, {'name': 'user1:test_key', 'value': 'bar', 'scope': FULL_USER_SCOPE}, {'name': '%s:test_key' % cfg.CONF.system_user.user, 'value': 'baz', 'scope': FULL_USER_SCOPE}, ] for kwargs in register_kwargs: KeyValuePair.add_or_update(KeyValuePairDB(**kwargs)) # Assert that datastore value can be got via the Jinja expression from individual scopes. context = {'user': '******'} param = { 'system_value': {'default': '{{ st2kv.system.test_key }}'}, 'user_value': {'default': '{{ st2kv.user.test_key }}'}, } live_params = param_utils.render_live_params(runner_parameters={}, action_parameters=param, params={}, action_context=context) self.assertEqual(live_params['system_value'], 'foo') self.assertEqual(live_params['user_value'], 'bar') # Assert that datastore value in the user-scope that is registered by user1 # cannot be got by the operation of user2. context = {'user': '******'} param = {'user_value': {'default': '{{ st2kv.user.test_key }}'}} live_params = param_utils.render_live_params(runner_parameters={}, action_parameters=param, params={}, action_context=context) self.assertEqual(live_params['user_value'], '') # Assert that system-user's scope is selected when user and api_user parameter specified context = {} param = {'user_value': {'default': '{{ st2kv.user.test_key }}'}} live_params = param_utils.render_live_params(runner_parameters={}, action_parameters=param, params={}, action_context=context) self.assertEqual(live_params['user_value'], 'baz')
def test_get_finalized_params_older_kv_scopes_backwards_compatibility(self): KeyValuePair.add_or_update(KeyValuePairDB(name="cmd_to_run", value="echo MELANIA", scope=FULL_SYSTEM_SCOPE)) # k2 = KeyValuePair.add_or_update(KeyValuePairDB(name='ivanka:cmd_to_run', # value='echo MA DAD IS GREAT', # scope=USER_SCOPE)) params = { "sys_cmd": "{{system.cmd_to_run}}", # 'user_cmd': '{{user.ivanka:cmd_to_run}}' Not supported yet. } runner_param_info = {"r1": {}} action_param_info = {"sys_cmd": {}} action_context = {} r_runner_params, r_action_params = param_utils.get_finalized_params( runner_param_info, action_param_info, params, action_context ) self.assertEqual(r_action_params["sys_cmd"], "echo MELANIA")
def test_kvstore_partitioner(self): cfg.CONF.set_override(name='partition_provider', override={'name': KVSTORE_PARTITION_LOADER}, group='sensorcontainer') kvp = KeyValuePairDB(**{'name': 'sensornode1.sensor_partition', 'value': 'generic.Sensor1, generic.Sensor2'}) KeyValuePair.add_or_update(kvp, publish=False, dispatch_trigger=False) provider = get_sensors_partitioner() sensors = provider.get_sensors() self.assertEqual(len(sensors), len(kvp.value.split(','))) sensor1 = self.models['sensors']['sensor1.yaml'] self.assertTrue(provider.is_sensor_owner(sensor1)) sensor3 = self.models['sensors']['sensor3.yaml'] self.assertFalse(provider.is_sensor_owner(sensor3))
def test_hierarchical_lookup_dotted(self): k1 = KeyValuePair.add_or_update(KeyValuePairDB(name='a.b', value='v1')) k2 = KeyValuePair.add_or_update(KeyValuePairDB(name='a.b.c', value='v2')) k3 = KeyValuePair.add_or_update(KeyValuePairDB(name='b.c', value='v3')) k4 = KeyValuePair.add_or_update(KeyValuePairDB(name='stanley:r.i.p', value='v4', scope=USER_SCOPE)) lookup = KeyValueLookup() self.assertEquals(str(lookup.a.b), k1.value) self.assertEquals(str(lookup.a.b.c), k2.value) self.assertEquals(str(lookup.b.c), k3.value) self.assertEquals(str(lookup.a), '') # Scoped lookup lookup = KeyValueLookup(scope=SYSTEM_SCOPE) self.assertEquals(str(lookup.r.i.p), '') user_lookup = UserKeyValueLookup(scope=USER_SCOPE, user='******') self.assertEquals(str(user_lookup.r.i.p), k4.value)
def test_get_config_dynamic_config_item(self): pack_name = 'dummy_pack_schema_with_nested_object_6' loader = ContentPackConfigLoader(pack_name=pack_name) #################### # value in top level item KeyValuePair.add_or_update(KeyValuePairDB(name='k1', value='v1')) values = { 'level0_key': '{{st2kv.system.k1}}' } config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) config_rendered = loader.get_config() self.assertEquals(config_rendered, {'level0_key': 'v1'}) config_db.delete()
def test_hierarchical_lookup_dict(self): k1 = KeyValuePair.add_or_update(KeyValuePairDB(name='a.b', value='v1')) k2 = KeyValuePair.add_or_update(KeyValuePairDB(name='a.b.c', value='v2')) k3 = KeyValuePair.add_or_update(KeyValuePairDB(name='b.c', value='v3')) k4 = KeyValuePair.add_or_update(KeyValuePairDB(name='stanley:r.i.p', value='v4', scope=FULL_USER_SCOPE)) lookup = KeyValueLookup() self.assertEquals(str(lookup['a']['b']), k1.value) self.assertEquals(str(lookup['a']['b']['c']), k2.value) self.assertEquals(str(lookup['b']['c']), k3.value) self.assertEquals(str(lookup['a']), '') # Scoped lookup lookup = KeyValueLookup(scope=FULL_SYSTEM_SCOPE) self.assertEquals(str(lookup['r']['i']['p']), '') user_lookup = UserKeyValueLookup(scope=FULL_USER_SCOPE, user='******') self.assertEquals(str(user_lookup['r']['i']['p']), k4.value)
def test_chain_runner_typed_system_params(self, request): kvps = [] try: kvps.append(KeyValuePair.add_or_update(KeyValuePairDB(name='a', value='1'))) kvps.append(KeyValuePair.add_or_update(KeyValuePairDB(name='a.b.c', value='two'))) chain_runner = acr.get_runner() chain_runner.entry_point = CHAIN_SYSTEM_PARAMS chain_runner.action = ACTION_2 chain_runner.container_service = RunnerContainerService() chain_runner.pre_run() chain_runner.run({}) self.assertNotEqual(chain_runner.chain_holder.actionchain, None) expected_value = {'inttype': 1, 'strtype': 'two'} mock_args, _ = request.call_args self.assertEqual(mock_args[0].parameters, expected_value) finally: for kvp in kvps: KeyValuePair.delete(kvp)
def test_secret_lookup(self): secret_value = '0055A2D9A09E1071931925933744965EEA7E23DCF59A8D1D7A3' + \ '64338294916D37E83C4796283C584751750E39844E2FD97A3727DB5D553F638' k1 = KeyValuePair.add_or_update( KeyValuePairDB(name='k1', value=secret_value, secret=True)) k2 = KeyValuePair.add_or_update(KeyValuePairDB(name='k2', value='v2')) k3 = KeyValuePair.add_or_update( KeyValuePairDB(name='stanley:k3', value=secret_value, scope=FULL_USER_SCOPE, secret=True)) lookup = KeyValueLookup() self.assertEqual(str(lookup.k1), k1.value) self.assertEqual(str(lookup.k2), k2.value) self.assertEqual(str(lookup.k3), '') user_lookup = UserKeyValueLookup(scope=FULL_USER_SCOPE, user='******') self.assertEqual(str(user_lookup.k3), k3.value)
def test_chain_runner_typed_system_params(self, request): action_ref = ResourceReference.to_string_reference(name=ACTION_2.name, pack=ACTION_2.pack) kvps = [] try: kvps.append(KeyValuePair.add_or_update(KeyValuePairDB(name='a', value='1'))) kvps.append(KeyValuePair.add_or_update(KeyValuePairDB(name='a.b.c', value='two'))) chain_runner = acr.get_runner() chain_runner.entry_point = CHAIN_SYSTEM_PARAMS chain_runner.action = ACTION_2 chain_runner.liveaction = LiveActionDB(action=action_ref) chain_runner.pre_run() chain_runner.run({}) self.assertNotEqual(chain_runner.chain_holder.actionchain, None) expected_value = {'inttype': 1, 'strtype': 'two'} mock_args, _ = request.call_args self.assertEqual(mock_args[0].parameters, expected_value) finally: for kvp in kvps: KeyValuePair.delete(kvp)
def test_secret_lookup(self): secret_value = '0055A2D9A09E1071931925933744965EEA7E23DCF59A8D1D7A3' + \ '64338294916D37E83C4796283C584751750E39844E2FD97A3727DB5D553F638' k1 = KeyValuePair.add_or_update(KeyValuePairDB( name='k1', value=secret_value, secret=True) ) k2 = KeyValuePair.add_or_update(KeyValuePairDB(name='k2', value='v2')) k3 = KeyValuePair.add_or_update(KeyValuePairDB( name='stanley:k3', value=secret_value, scope=FULL_USER_SCOPE, secret=True) ) lookup = KeyValueLookup() self.assertEquals(str(lookup.k1), k1.value) self.assertEquals(str(lookup.k2), k2.value) self.assertEquals(str(lookup.k3), '') user_lookup = UserKeyValueLookup(scope=FULL_USER_SCOPE, user='******') self.assertEquals(str(user_lookup.k3), k3.value)