def test_service_policy_search(self): servers_plugin = self.initialized_plugins['OS::Nova::Server'] images_plugin = self.initialized_plugins['OS::Glance::Image'] volumes_plugin = self.initialized_plugins['OS::Cinder::Volume'] server_doc = { u'addresses': {}, u'id': 'abcdef', u'name': 'instance1', u'status': u'ACTIVE', u'tenant_id': TENANT1, u'user_id': USER1, u'image': { u'id': u'a' }, u'flavor': { u'id': u'1' }, u'created_at': u'2016-04-07T15:49:35Z', u'updated_at': u'2016-04-07T15:51:35Z' } image_doc = { "owner": TENANT1, "id": "1234567890", "visibility": "public", "name": "image", "created_at": "2016-04-06T12:48:18Z" } volume_doc = { "os-vol-tenant-attr:tenant_id": TENANT1, "user_id": USER1, "id": "deadbeef", "created_at": "2016-04-06T12:48:18Z", "updated_at": "2016-04-06T12:48:18Z", "volume_type": "lvmdriver-1" } with mock.patch(nova_version_getter, return_value=fake_version_list): self._index(servers_plugin, [test_utils.DictObj(**server_doc)]) self._index(images_plugin, [image_doc]) self._index(volumes_plugin, [test_utils.DictObj(**volume_doc)]) response, json_content = self._search_request(MATCH_ALL, TENANT1, role="user") self.assertEqual(200, response.status) self.assertEqual(2, json_content['hits']['total']) self.assertEqual( set([server_doc['id'], volume_doc['id']]), set(h['id'] for h in self._get_hit_source(json_content))) response, json_content = self._search_request(MATCH_ALL, TENANT1, role="admin") self.assertEqual(200, response.status) self.assertEqual(3, json_content['hits']['total']) self.assertEqual( set([server_doc['id'], image_doc['id'], volume_doc['id']]), set(s['id'] for s in self._get_hit_source(json_content)))
def test_search_rbac(self): servers_plugin = self.initialized_plugins['OS::Nova::Server'] server1 = { u'addresses': {}, u'flavor': {u'id': u'1'}, u'id': u'6c41b4d1-f0fa-42d6-9d8d-e3b99695aa69', u'image': {u'id': u'a'}, u'name': u'instance1', u'status': u'ACTIVE', u'tenant_id': TENANT1, u'created_at': u'2016-04-06T12:48:18Z', u'updated_at': u'2016-04-07T15:51:35Z', u'user_id': u'27f4d76b-be62-4e4e-aa33bb11cc55' } server2 = { u'addresses': {}, u'flavor': {u'id': u'1'}, u'id': u'08ca6c43-eea8-48d0-bbb2-30c50109d5d8', u'image': {u'id': u'a'}, u'name': u'instance2', u'status': u'RESUMING', u'tenant_id': TENANT2, u'created_at': u'2016-04-06T12:48:18Z', u'updated_at': u'2016-04-07T15:51:35Z', u'user_id': u'27f4d76b-be62-4e4e-aa33bb11cc55' } with mock.patch(nova_version_getter, return_value=fake_version_list): self._index( servers_plugin, [test_utils.DictObj(**server1), test_utils.DictObj(**server2)]) response, json_content = self._search_request( {"query": {"match_all": {}}, "type": "OS::Nova::Server"}, TENANT1, role="member") self.assertEqual(1, json_content['hits']['total']) self.assertEqual(["6c41b4d1-f0fa-42d6-9d8d-e3b99695aa69"], [h["_source"]["id"] for h in json_content["hits"]["hits"]]) response, json_content = self._search_request( {"query": {"match_all": {}}, "type": "OS::Nova::Server", "all_projects": True}, TENANT1, role="admin") self.assertEqual(2, json_content['hits']['total'])
def test_error_state_transition(self, mock_nova, mock_version_list): inst_id = "4b86f534-16db-4de8-8ce0-f1ee68894835" mock_nova.return_value = utils.DictObj( **{ 'id': inst_id, 'name': 'test-error', 'tenant_id': EV_TENANT, 'addresses': {}, 'image': { 'id': '1' }, 'flavor': { 'id': 'a' }, 'status': 'ERROR', 'created': '2016-08-31T23:32:11Z', 'updated': '2016-08-31T23:32:11Z', }) error_update = self.server_events['instance-update-error-final'] self._send_event_to_listener(error_update, self.listener_alias) result = self._verify_event_processing(error_update, owner=EV_TENANT) self._verify_result(error_update, ['tenant_id'], result) mock_nova.assert_called_with(inst_id)
def test_server_groups_rbac(self): self._index(self.server_groups_plugin, [ utils.DictObj(**server_group) for server_group in self.server_groups_objects["server_groups"] ]) query = {"type": ["OS::Nova::ServerGroup"], "query": {"match_all": {}}} response, json_content = self._search_request( query, self.server_groups_objects["server_groups"][0]["project_id"]) expected_sources = [{ u"user_id": u"944ff1aa607744ab9400acbf6be7f38a", u"policies": [u"affinity"], u"name": u"server_group_1", u"members": [u"8bf01fe7-1369-4059-92de-95ba11ff21dd"], u"project_id": u"d782f6257f0b484c97e9474b74db34a1", u"id": u"d0d017d6-0d41-4b32-b9f8-c43f039defc5", u"metadata": {} }] hits = json_content['hits']['hits'] for hit in hits: source = hit["_source"] source.pop("updated_at") actual_sources = [hit["_source"] for hit in hits] self.assertEqual(expected_sources, actual_sources) self.assertEqual(200, response.status) self.assertEqual(1, json_content['hits']['total'])
def _index_data(self): """Moving this here because failures in setUp result in the API server not getting torn down properly. """ def fake_volume_get(volume_id): vol = list(filter(lambda v: v["id"] == volume_id, self.volume_objects))[0] return utils.DictObj(**vol) def fake_snapshot_get(snapshot_id): snap = list(filter(lambda v: v["id"] == snapshot_id, self.snapshot_objects))[0] return utils.DictObj(**snap) self._index(self.snapshot_plugin, [utils.DictObj(**snap) for snap in self.snapshot_objects]) self._index(self.volume_plugin, [utils.DictObj(**vol) for vol in self.volume_objects])
def test_server_role_field_rbac(self): """Check that admins and users get different versions of documents""" doc_id = u'abc' s1 = { u'addresses': {}, u'OS-DCF:diskConfig': u'MANUAL', u'OS-EXT-AZ:availability_zone': u'nova', u'OS-EXT-SRV-ATTR:host': u'devstack', u'OS-EXT-SRV-ATTR:hypervisor_hostname': u'devstack', u'OS-EXT-SRV-ATTR:instance_name': u'instance-00000001', u'id': doc_id, u'image': { u'id': u'a' }, u'flavor': { u'id': u'1' }, u'name': 'instance1', u'status': u'ACTIVE', u'tenant_id': TENANT1, u'user_id': USER1, u'created_at': u'2016-04-07T15:49:35Z', u'updated_at': u'2016-04-07T15:51:35Z', } servers_plugin = self.initialized_plugins['OS::Nova::Server'] with mock.patch(nova_version_getter, return_value=fake_version_list): self._index(servers_plugin, [test_utils.DictObj(**s1)]) response, json_content = self._search_request(MATCH_ALL, TENANT1, role="admin") self.assertEqual(200, response.status) self.assertEqual(1, len(json_content['hits']['hits'])) hit = json_content['hits']['hits'][0] self.assertEqual(doc_id + "_ADMIN", hit['_id']) for k in ('OS-EXT-SRV-ATTR:host', 'OS-EXT-SRV-ATTR:hypervisor_hostname', 'OS-EXT-SRV-ATTR:instance_name'): self.assertIn(k, hit['_source']) # Now as a non admin response, json_content = self._search_request(MATCH_ALL, TENANT1, role="member") self.assertEqual(200, response.status) self.assertEqual(1, len(json_content['hits']['hits'])) hit = json_content['hits']['hits'][0] self.assertEqual(doc_id + "_USER", hit['_id']) for k, v in hit.items(): self.assertFalse(k.startswith('OS-EXT-SRV-ATTR:'), 'No protected attributes should be present') for field in (u'status', u'OS-DCF:diskConfig'): self.assertIn(field, hit['_source'])
def _volume_fixture(volume_id, tenant_id, **kwargs): volume = { '_info': { u'attachments': [], u'availability_zone': u'nova', # We don't care about any of this; _info should get deleted u'volume_type': u'lvmdriver-1' }, '_loaded': True, 'attachments': [], 'availability_zone': u'nova', 'bootable': u'false', 'consistencygroup_id': None, 'created_at': created_now, 'description': None, 'encrypted': False, 'id': volume_id, 'links': [{ u'href': u'dont care' }], 'manager': "A thing that doesn't serialize", 'metadata': {}, 'migration_status': None, 'multiattach': False, 'name': None, 'os-vol-host-attr:host': u'devstack@lvmdriver-1#lvmdriver-1', 'os-vol-mig-status-attr:migstat': None, 'os-vol-mig-status-attr:name_id': None, 'os-vol-tenant-attr:tenant_id': tenant_id, 'os-volume-replication:driver_data': None, 'os-volume-replication:extended_status': None, 'replication_status': u'disabled', 'size': 1, 'snapshot_id': None, 'source_volid': None, 'status': u'available', 'updated_at': updated_now, 'user_id': USER1, 'volume_type': u'lvmdriver-1' } volume.update(*kwargs) return test_utils.DictObj(**volume)
def setUp(self): super(TestCinderNotifications, self).setUp() self.volume_plugin = self.initialized_plugins['OS::Cinder::Volume'] self.snapshot_plugin = self.initialized_plugins['OS::Cinder::Snapshot'] self.volume_events = self._load_fixture_data('events/volumes.json') self.snapshot_events = self._load_fixture_data('events/snapshots.json') notification_plugins = { plugin.document_type: utils.StevedoreMock(plugin) for plugin in (self.volume_plugin, self.snapshot_plugin) } self.notification_endpoint = NotificationEndpoint(notification_plugins) self.index_alias = self.volume_plugin.alias_name_listener volume = { 'id': VOLUME_ID1, 'user_id': USER_ID, 'created_at': '2016-03-07T16:51:09.000000', 'updated_at': '2016-03-07T16:51:09.000000' } self.volume_fixture = utils.DictObj(**volume)
def _snapshot_fixture(snapshot_id, volume_id, project_id, **kwargs): fixture = { '_info': { u'created_at': created_now, u'description': None, # blah blah, don't want any of this u'volume_id': u'faaad6fe-9351-4313-bce9-881b476d5751' }, '_loaded': True, 'created_at': created_now, 'description': None, 'id': snapshot_id, 'manager': "we don't want this", 'metadata': {}, 'name': None, 'os-extended-snapshot-attributes:progress': u'100%', 'os-extended-snapshot-attributes:project_id': project_id, 'size': 1, 'status': u'available', 'updated_at': updated_now, 'volume_id': volume_id } return test_utils.DictObj(**fixture)
def fake_snapshot_get(snapshot_id): snap = list( filter(lambda v: v["id"] == snapshot_id, self.snapshot_objects))[0] return utils.DictObj(**snap)
def fake_volume_get(volume_id): vol = list( filter(lambda v: v["id"] == volume_id, self.volume_objects))[0] return utils.DictObj(**vol)
def test_aggregation_rbac(self): servers_plugin = self.initialized_plugins['OS::Nova::Server'] images_plugin = self.initialized_plugins['OS::Glance::Image'] server_doc = { u'addresses': {}, u'id': 'abcdef', u'name': 'instance1', u'status': u'ACTIVE', u'tenant_id': TENANT1, u'user_id': USER1, u'image': { u'id': u'a' }, u'flavor': { u'id': u'1' }, u'created_at': u'2016-04-07T15:49:35Z', u'updated_at': u'2016-04-07T15:51:35Z' } image_doc = { "owner": TENANT1, "id": "1234567890", "visibility": "public", "name": "for_instance1", "created_at": "2016-04-06T12:48:18Z" } with mock.patch(nova_version_getter, return_value=fake_version_list): self._index(servers_plugin, [test_utils.DictObj(**server_doc)]) self._index(images_plugin, [image_doc]) # Set type to ignore the image for all queries query = { "limit": 0, "type": "OS::Nova::Server", "query": { "match_all": {} }, "aggregations": { "names": { "terms": { "field": "name" } } } } expected_aggregation = { "names": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [{ "key": "instance1", "doc_count": 1 }] } } expected_aggregation_no_results = { "names": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [] } } # Expected aggregation results response, json_content = self._search_request(query, TENANT1, role="member") self.assertEqual(1, json_content['hits']['total']) self.assertEqual(expected_aggregation, json_content['aggregations']) # Now with a different tenant response, json_content = self._search_request(query, TENANT2, role="member") self.assertEqual(0, json_content['hits']['total']) self.assertEqual(expected_aggregation_no_results, json_content['aggregations']) # Now with all_projects query['all_projects'] = True response, json_content = self._search_request(query, TENANT2, role="member") self.assertEqual(0, json_content['hits']['total']) self.assertEqual(expected_aggregation_no_results, json_content['aggregations']) # Now admin all projects response, json_content = self._search_request(query, TENANT2, role="admin") self.assertEqual(1, json_content['hits']['total']) self.assertEqual(expected_aggregation, json_content['aggregations'])
def test_aggregations(self): servers_plugin = self.initialized_plugins['OS::Nova::Server'] images_plugin = self.initialized_plugins['OS::Glance::Image'] volumes_plugin = self.initialized_plugins['OS::Cinder::Volume'] server_doc = { u'addresses': {}, u'id': 'abcdef', u'name': 'instance1', u'status': u'ACTIVE', u'tenant_id': TENANT1, u'user_id': USER1, u'image': { u'id': u'a' }, u'flavor': { u'id': u'1' }, u'created_at': u'2016-04-07T15:49:35Z', u'updated_at': u'2016-04-07T15:51:35Z' } image_doc = { "owner": TENANT1, "id": "1234567890", "visibility": "public", "name": "for_instance1", "created_at": "2016-04-06T12:48:18Z" } volume_doc = { "os-vol-tenant-attr:tenant_id": TENANT1, "user_id": USER1, "id": "deadbeef", "name": "for_instance1", "created_at": "2016-04-06T12:48:18Z", "updated_at": "2016-04-06T12:48:18Z", "volume_type": "lvmdriver-1" } with mock.patch(nova_version_getter, return_value=fake_version_list): self._index(servers_plugin, [test_utils.DictObj(**server_doc)]) self._index(images_plugin, [image_doc]) self._index(volumes_plugin, [test_utils.DictObj(**volume_doc)]) query = { "limit": 0, "query": { "match_all": {} }, "aggregations": { "names": { "terms": { "field": "name" } }, "earliest": { "min": { "field": "created_at" } } } } response, json_content = self._search_request(query, TENANT1, role="admin") expected_aggregations = { "names": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [{ "key": "for_instance1", "doc_count": 2 }, { "key": "instance1", "doc_count": 1 }] }, "earliest": { "value": 1459946898000.0, "value_as_string": "2016-04-06T12:48:18.000Z" } } # Expect a total count but no hit documents self.assertEqual({ "total": 3, "max_score": 0.0, "hits": [] }, json_content["hits"]) # Should see "aggregations" at the top level self.assertIn("aggregations", json_content) self.assertEqual(expected_aggregations, json_content["aggregations"])
def test_resource_policy(self): servers_plugin = self.initialized_plugins['OS::Nova::Server'] images_plugin = self.initialized_plugins['OS::Glance::Image'] server_doc = { u'addresses': {}, u'id': 'abcdef', u'name': 'instance1', u'status': u'ACTIVE', u'tenant_id': TENANT1, u'user_id': USER1, u'image': { u'id': u'a' }, u'flavor': { u'id': u'1' }, u'created_at': u'2016-04-07T15:49:35Z', u'updated_at': u'2016-04-07T15:51:35Z' } image_doc = { "owner": TENANT1, "id": "1234567890", "visibility": "public", "name": "image", "created_at": "2016-04-06T12:48:18Z" } with mock.patch(nova_version_getter, return_value=fake_version_list): self._index(servers_plugin, [test_utils.DictObj(**server_doc)]) self._index(images_plugin, [image_doc]) # Modify the policy file to restrict Nova servers self._modify_policy_file({"resource:OS::Nova::Server": "role:admin"}) response, json_content = self._search_request(MATCH_ALL, TENANT1, role="user") self.assertEqual(1, json_content['hits']['total']) self.assertEqual('OS::Glance::Image', json_content['hits']['hits'][0]['_type']) response, json_content = self._search_request(MATCH_ALL, TENANT1, role="admin") self.assertEqual(2, json_content['hits']['total']) self.assertEqual( set(['OS::Glance::Image', 'OS::Nova::Server']), set([hit['_type'] for hit in json_content['hits']['hits']])) response, json_content = self._facet_request(TENANT1, role="user") self.assertNotIn('OS::Nova::Server', json_content) response, json_content = self._facet_request(TENANT1, role="admin") self.assertIn('OS::Nova::Server', json_content) self.assertIn('OS::Glance::Image', json_content) response, json_content = self._request('GET', '/search/plugins', TENANT1, role='user') self.assertEqual( 0, len( list( filter(lambda p: p['type'] == 'OS::Nova::Server', json_content['plugins'])))) response, json_content = self._request('GET', '/search/plugins', TENANT1, role='admin') self.assertEqual( 1, len( list( filter(lambda p: p['type'] == 'OS::Nova::Server', json_content['plugins']))))
def test_role_fishing(self): """Run some searches to ward against 'fishing' type attacks such that 'admin only' fields can't be searched by ordinary users """ admin_field, admin_value = (u'OS-EXT-SRV-ATTR:host', u'devstack') doc_id = u'abc' s1 = { u'addresses': {}, u'id': doc_id, u'image': { u'id': u'a' }, u'flavor': { u'id': u'1' }, u'name': 'instance1', u'status': u'ACTIVE', u'tenant_id': TENANT1, u'user_id': USER1, admin_field: admin_value, u'created_at': u'2016-04-07T15:49:35Z', u'updated_at': u'2016-04-07T15:51:35Z', } servers_plugin = self.initialized_plugins['OS::Nova::Server'] with mock.patch(nova_version_getter, return_value=fake_version_list): self._index(servers_plugin, [test_utils.DictObj(**s1)]) # For each of these queries (which are really looking for the same # thing) we expect a result for an admin, and no result for a user term_query = {'term': {admin_field: admin_value}} query_string = {'query_string': {'query': admin_value}} # search 'all' query_string_field = { 'query_string': { 'default_field': admin_field, 'query': admin_value } } for query in (term_query, query_string, query_string_field): full_query = {'query': query} response, json_content = self._search_request(full_query, TENANT1, role="admin") self.assertEqual(200, response.status) self.assertEqual(1, json_content['hits']['total'], "No results for: %s" % query) self.assertEqual(doc_id + '_ADMIN', json_content['hits']['hits'][0]['_id']) # The same search should not work for users response, json_content = self._search_request(full_query, TENANT1, role="user") self.assertEqual(200, response.status) self.assertEqual(0, json_content['hits']['total']) # Run the same queries against 'name'; should get results term_query['term'] = {'name': 'instance1'} query_string['query_string']['query'] = 'instance1' query_string_field['query_string'] = { 'default_field': 'name', 'query': 'instance1' } for query in (term_query, query_string, query_string_field): full_query = {'query': query} response, json_content = self._search_request(full_query, TENANT1, role="user") self.assertEqual(200, response.status) self.assertEqual(1, json_content['hits']['total'], "No results for: %s %s" % (query, json_content)) self.assertEqual(doc_id + '_USER', json_content['hits']['hits'][0]['_id'])
def test_nested_facets(self): """Check facets for a nested field (networks.OS-EXT-IPS:type). We expect a single count per server matched, not per object in the 'networks' field. Also check that for fields that are typed as 'object' (not 'nested') they're marked appropriately """ servers_plugin = self.initialized_plugins['OS::Nova::Server'] server1 = { u'addresses': { u'net4': [{ u'addr': u'127.0.0.1', u'OS-EXT-IPS:type': u'fixed', u'version': 4 }, { u'addr': u'127.0.0.1', u'OS-EXT-IPS:type': u'fixed', u'version': 4 }] }, u'flavor': { u'id': u'1' }, u'id': u'6c41b4d1-f0fa-42d6-9d8d-e3b99695aa69', u'image': { u'id': u'a' }, u'name': u'instance1', u'created_at': u'2016-04-07T15:49:35Z', u'updated_at': u'2016-04-07T15:51:35Z', u'status': u'ACTIVE', u'tenant_id': TENANT1, u'user_id': u'27f4d76b-be62-4e4e-aa33bb11cc55' } server2 = { u'addresses': { u'net4': [{ u'addr': u'127.0.0.1', u'OS-EXT-IPS:type': u'fixed', u'version': 4 }, { u'addr': u'127.0.0.1', u'OS-EXT-IPS:type': u'floating', u'version': 4 }] }, u'flavor': { u'id': u'1' }, u'id': u'08ca6c43-eea8-48d0-bbb2-30c50109d5d8', u'created_at': u'2016-04-07T15:49:35Z', u'updated_at': u'2016-04-07T15:51:35Z', u'image': { u'id': u'a' }, u'name': u'instance2', u'status': u'ACTIVE', u'tenant_id': TENANT1, u'user_id': u'27f4d76b-be62-4e4e-aa33bb11cc55' } with mock.patch(nova_version_getter, return_value=fake_version_list): self._index( servers_plugin, [test_utils.DictObj(**server1), test_utils.DictObj(**server2)]) response, json_content = self._facet_request( TENANT1, doc_type="OS::Nova::Server") self.assertEqual(2, json_content['OS::Nova::Server']['doc_count']) self.assertEqual(['OS::Nova::Server'], list(six.iterkeys(json_content))) # server1 has two fixed addresses (which should be rolled up into one # match). server2 has fixed and floating addresses. expected = { u'name': u'networks.OS-EXT-IPS:type', u'options': [ { u'doc_count': 2, u'key': u'fixed' }, { u'doc_count': 1, u'key': u'floating' }, ], u'type': u'string', u'nested': True } fixed_network_facet = list( six.moves.filter(lambda f: f['name'] == 'networks.OS-EXT-IPS:type', json_content['OS::Nova::Server']['facets']))[0] self.assertEqual( expected, fixed_network_facet, ) # Check that 'image.id' (not nested but 'object') has nested=False expected = { u'name': u'image.id', u'type': u'string', u'nested': False, u'resource_type': u'OS::Glance::Image', u'options': [{ u'doc_count': 2, u'key': u'a' }] } image_facet = list( six.moves.filter(lambda f: f['name'] == 'image.id', json_content['OS::Nova::Server']['facets']))[0] self.assertEqual( expected, image_facet, )
def test_facets(self): """Check facets for a non-nested field (status)""" servers_plugin = self.initialized_plugins['OS::Nova::Server'] server1 = { u'addresses': {}, u'flavor': { u'id': u'1' }, u'id': u'6c41b4d1-f0fa-42d6-9d8d-e3b99695aa69', u'image': { u'id': u'a' }, u'name': u'instance1', u'status': u'ACTIVE', u'tenant_id': TENANT1, u'created_at': u'2016-04-06T12:48:18Z', u'updated_at': u'2016-04-07T15:51:35Z', u'user_id': u'27f4d76b-be62-4e4e-aa33bb11cc55' } server2 = { u'addresses': {}, u'flavor': { u'id': u'1' }, u'id': u'08ca6c43-eea8-48d0-bbb2-30c50109d5d8', u'image': { u'id': u'a' }, u'name': u'instance2', u'status': u'RESUMING', u'tenant_id': TENANT1, u'created_at': u'2016-04-06T12:48:18Z', u'updated_at': u'2016-04-07T15:51:35Z', u'user_id': u'27f4d76b-be62-4e4e-aa33bb11cc55' } server3 = { u'addresses': {}, u'flavor': { u'id': u'1' }, u'id': u'08ca6c43-f0fa-48d0-48d0-53453522cda4', u'image': { u'id': u'a' }, u'name': u'instance1', u'status': u'ACTIVE', u'tenant_id': TENANT1, u'created_at': u'2016-04-06T12:48:18Z', u'updated_at': u'2016-04-07T15:51:35Z', u'user_id': u'27f4d76b-be62-4e4e-aa33bb11cc55' } with mock.patch(nova_version_getter, return_value=fake_version_list): self._index(servers_plugin, [ test_utils.DictObj(**server1), test_utils.DictObj(**server2), test_utils.DictObj(**server3) ]) # Query facets with options. response, json_content = self._facet_request( TENANT1, doc_type="OS::Nova::Server") self.assertEqual(3, json_content['OS::Nova::Server']['doc_count']) expected = { u'name': u'status', u'options': [ { u'doc_count': 2, u'key': u'ACTIVE' }, { u'doc_count': 1, u'key': u'RESUMING' }, ], u'type': u'string' } status_facet = list( six.moves.filter(lambda f: f['name'] == 'status', json_content['OS::Nova::Server']['facets']))[0] self.assertEqual( expected, status_facet, ) # Query facets without options. response, json_content = self._facet_request( TENANT1, doc_type="OS::Nova::Server", exclude_options=True) self.assertEqual(3, json_content['OS::Nova::Server']['doc_count']) expected = {u'name': u'status', u'type': u'string'} status_facet = list( six.moves.filter(lambda f: f['name'] == 'status', json_content['OS::Nova::Server']['facets']))[0] self.assertEqual( expected, status_facet, )
def test_is_admin_project(self): """The X-IS-ADMIN-PROJECT header is the current solution to the problems caused by the overloaded 'admin' role. It's only set if configured in keystone, and defaults to True for back compatibility. """ one_tenant_doc = { u'addresses': {}, u'id': 'abcdef', u'tenant_id': TENANT1, u'user_id': USER1, u'image': { u'id': u'a' }, u'flavor': { u'id': u'1' }, u'created_at': u'2016-04-07T15:49:35Z', u'updated_at': u'2016-04-07T15:51:35Z' } two_tenant_doc = { u'addresses': {}, u'id': '12341234', u'tenant_id': TENANT2, u'user_id': USER1, u'image': { u'id': u'a' }, u'flavor': { u'id': u'1' }, u'created_at': u'2016-04-07T15:49:35Z', u'updated_at': u'2016-04-07T15:51:35Z' } # A request with HTTP_X_IS_ADMIN_PROJECT=false should not allow a # TENANT1-scoped request to retrieve both servers if set to True it # should (assuming they also have the admin role) servers_plugin = self.initialized_plugins['OS::Nova::Server'] with mock.patch(nova_version_getter, return_value=fake_version_list): self._index(servers_plugin, [ test_utils.DictObj(**one_tenant_doc), test_utils.DictObj(**two_tenant_doc) ]) query = { "type": "OS::Nova::Server", "all_projects": True, "query": { "match_all": {} }, "sort": "id" } # First try admin request, is-admin-project false response, json_content = self._search_request(query, TENANT1, role="admin", is_admin_project=False) self.assertEqual(['abcdef_USER'], [h['_id'] for h in json_content['hits']['hits']]) # Now try with is_admin_project True response, json_content = self._search_request(query, TENANT1, role="admin", is_admin_project=True) self.assertEqual(['12341234_ADMIN', 'abcdef_ADMIN'], [h['_id'] for h in json_content['hits']['hits']]) # Now try with is_admin_project True but member role response, json_content = self._search_request(query, TENANT1, role="member", is_admin_project=True) self.assertEqual(['abcdef_USER'], [h['_id'] for h in json_content['hits']['hits']])
def test_hypervisor_rbac(self): self._index(self.hyper_plugin, [utils.DictObj(**hyper) for hyper in self.hyper_objects]) response, json_content = self._search_request( { "query": { "match_all": {} }, "all_projects": True }, TENANT1, role="admin") self.assertEqual(200, response.status) self.assertEqual(2, json_content['hits']['total']) hits = json_content['hits']['hits'] expected_sources = [{ u'cpu_info': { u'arch': u'x86_64', u'features': [u'pge', u'clflush'], u'model': u'Nehalem', u'topology': { u'cores': 20, u'sockets': 4, u'threads': 1 }, u'vendor': u'Intel' }, u'disk_available_least': 0, u'host_ip': u'192.168.1.11', u'hypervisor_hostname': u'host1', u'hypervisor_type': u'fake', u'hypervisor_version': 1000, u'id': u'1', u'local_gb': 600000, u'memory_mb': 800000, u'service': { u'disabled_reason': None, u'host': u'host1', u'id': 7 }, u'state': u'up', u'status': u'enabled', u'vcpus': 1000 }, { u'cpu_info': { u'arch': u'x86_64', u'features': [u'pge', u'clflush'], u'model': u'Nehalem', u'topology': { u'cores': 10, u'sockets': 4, u'threads': 1 }, u'vendor': u'Intel' }, u'disk_available_least': 0, u'host_ip': u'192.168.1.12', u'hypervisor_hostname': u'host2', u'hypervisor_type': u'kvm', u'hypervisor_version': 1000, u'id': u'2', u'local_gb': 300000, u'memory_mb': 400000, u'service': { u'disabled_reason': None, u'host': u'host2', u'id': 8 }, u'state': u'up', u'status': u'enabled', u'vcpus': 500 }] def process(hit): hit.pop('updated_at') return hit actual_sources = [process(hit['_source']) for hit in hits] self.assertEqual(expected_sources, actual_sources)
def _index_data(self): self._index( self.server_plugin, [utils.DictObj(**server) for server in self.server_objects])
def test_resource_policy(self): servers_plugin = self.initialized_plugins['OS::Nova::Server'] images_plugin = self.initialized_plugins['OS::Glance::Image'] server_doc = { u'addresses': {}, u'id': 'abcdef', u'name': 'instance1', u'status': u'ACTIVE', u'tenant_id': TENANT1, u'user_id': USER1, u'image': { u'id': u'a' }, u'flavor': { u'id': u'1' }, u'created_at': u'2016-04-07T15:49:35Z', u'updated_at': u'2016-04-07T15:51:35Z' } image_doc = { "owner": TENANT1, "id": "1234567890", "visibility": "public", "name": "image", "created_at": "2016-04-06T12:48:18Z" } self._index(servers_plugin, [test_utils.DictObj(**server_doc)]) self._index(images_plugin, [image_doc]) # Modify the policy file to disallow some things with open(self.policy_file, 'r') as policy_file: existing_policy = json.load(policy_file) existing_policy["resource:OS::Nova::Server:allow"] = "role:admin" existing_policy["resource:OS::Nova::Server:facets"] = "!" existing_policy["resource:OS::Glance::Image:facets"] = "!" existing_policy["resource:OS::Glance::Metadef:facets"] = "role:admin" with open(self.policy_file, 'w') as policy_file: json.dump(existing_policy, policy_file) # Policy file reloads; sleep until then time.sleep(2) response, json_content = self._search_request(MATCH_ALL, TENANT1, role="user") self.assertEqual(1, json_content['hits']['total']) self.assertEqual('OS::Glance::Image', json_content['hits']['hits'][0]['_type']) response, json_content = self._search_request(MATCH_ALL, TENANT1, role="admin") self.assertEqual(2, json_content['hits']['total']) self.assertEqual( set(['OS::Glance::Image', 'OS::Nova::Server']), set([hit['_type'] for hit in json_content['hits']['hits']])) response, json_content = self._facet_request(TENANT1, role="user") self.assertNotIn('OS::Nova::Server', json_content) self.assertNotIn('OS::Glance::Image', json_content) self.assertNotIn('OS::Glance::Metadef', json_content) response, json_content = self._facet_request(TENANT1, role="admin") # We DO expect some facets for metadefs for admins self.assertIn('OS::Glance::Metadef', json_content) # .. but not Server or Image self.assertNotIn('OS::Nova::Server', json_content) self.assertNotIn('OS::Glance::Image', json_content) response, json_content = self._request('GET', '/search/plugins', TENANT1, role='user') self.assertEqual( 0, len( list( filter(lambda p: p['name'] == 'OS::Nova::Server', json_content['plugins'])))) response, json_content = self._request('GET', '/search/plugins', TENANT1, role='admin') self.assertEqual( 1, len( list( filter(lambda p: p['name'] == 'OS::Nova::Server', json_content['plugins']))))