From 14c01e09b68b367d708c6ddd6f3d4e440687727c Mon Sep 17 00:00:00 2001 From: Don Dugger Date: Tue, 8 May 2012 18:30:57 -0600 Subject: Add scheduler filter for trustedness of a host Implements blueprint trusted-computing-pools Add a scheduling filter that filters based upon the trustedness of a node. A request is sent to the attestation service to disover the trustedness of the target node and, only if it matches the `trust_host' key/value pair in the `extra_specs' for the instance type, then the instance can be started on that node. More details can be found in the docspec for the filter in: nova/scheduler/filters/trusted_filter.py To setup an attestation server go to the Open Attestation Project at: https://github.com/OpenAttestation/OpenAttestation Also add 5 tests for the new filter that verifies: 1) Schedule works with no trust in the extra specs 2) Schedule works with trusted instance and trusted host 3) Schedule works with untrusted instance and untrusted host 4) Schedule fails with trusted instance and untrusted host 5) Scheduel fails with untrusted instance and trusted host Signed-off-by: Don Dugger Signed-off-by: Fred Yang Change-Id: Iafa6aed8061f6cd4630367553aee14bd4b0263e2 --- nova/tests/scheduler/test_host_filters.py | 81 +++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/scheduler/test_host_filters.py b/nova/tests/scheduler/test_host_filters.py index 22a162aa2..b7a5402c8 100644 --- a/nova/tests/scheduler/test_host_filters.py +++ b/nova/tests/scheduler/test_host_filters.py @@ -15,17 +15,45 @@ Tests For Scheduler Host Filters. """ +import httplib import json +import stubout from nova import context from nova import exception from nova import flags from nova.scheduler import filters +from nova.scheduler.filters.trusted_filter import AttestationService from nova import test from nova.tests.scheduler import fakes from nova import utils +DATA = '' + + +def stub_out_https_backend(stubs): + """ + Stubs out the httplib.HTTPRequest.getresponse to return + faked-out data instead of grabbing actual contents of a resource + + The stubbed getresponse() returns an iterator over + the data "I am a teapot, short and stout\n" + + :param stubs: Set of stubout stubs + """ + + class FakeHTTPResponse(object): + + def read(self): + return DATA + + def fake_do_request(self, *args, **kwargs): + return httplib.OK, FakeHTTPResponse() + + stubs.Set(AttestationService, '_do_request', fake_do_request) + + class TestFilter(filters.BaseHostFilter): pass @@ -40,6 +68,8 @@ class HostFiltersTestCase(test.TestCase): def setUp(self): super(HostFiltersTestCase, self).setUp() + self.stubs = stubout.StubOutForTesting() + stub_out_https_backend(self.stubs) self.context = context.RequestContext('fake', 'fake') self.json_query = json.dumps( ['and', ['>=', '$free_ram_mb', 1024], @@ -586,6 +616,57 @@ class HostFiltersTestCase(test.TestCase): filter_properties = {'scheduler_hints': {'query': json.dumps(raw)}} self.assertTrue(filt_cls.host_passes(host, filter_properties)) + def test_trusted_filter_default_passes(self): + self._stub_service_is_up(True) + filt_cls = self.class_map['TrustedFilter']() + filter_properties = {'instance_type': {'memory_mb': 1024}} + host = fakes.FakeHostState('host1', 'compute', {}) + self.assertTrue(filt_cls.host_passes(host, filter_properties)) + + def test_trusted_filter_trusted_and_trusted_passes(self): + global DATA + DATA = '{"hosts":[{"host_name":"host1","trust_lvl":"trusted"}]}' + self._stub_service_is_up(True) + filt_cls = self.class_map['TrustedFilter']() + extra_specs = {'trusted_host': 'trusted'} + filter_properties = {'instance_type': {'memory_mb': 1024, + 'extra_specs': extra_specs}} + host = fakes.FakeHostState('host1', 'compute', {}) + self.assertTrue(filt_cls.host_passes(host, filter_properties)) + + def test_trusted_filter_trusted_and_untrusted_fails(self): + global DATA + DATA = '{"hosts":[{"host_name":"host1","trust_lvl":"untrusted"}]}' + self._stub_service_is_up(True) + filt_cls = self.class_map['TrustedFilter']() + extra_specs = {'trusted_host': 'trusted'} + filter_properties = {'instance_type': {'memory_mb': 1024, + 'extra_specs': extra_specs}} + host = fakes.FakeHostState('host1', 'compute', {}) + self.assertFalse(filt_cls.host_passes(host, filter_properties)) + + def test_trusted_filter_untrusted_and_trusted_fails(self): + global DATA + DATA = '{"hosts":[{"host_name":"host1","trust_lvl":"trusted"}]}' + self._stub_service_is_up(True) + filt_cls = self.class_map['TrustedFilter']() + extra_specs = {'trusted_host': 'untrusted'} + filter_properties = {'instance_type': {'memory_mb': 1024, + 'extra_specs': extra_specs}} + host = fakes.FakeHostState('host1', 'compute', {}) + self.assertFalse(filt_cls.host_passes(host, filter_properties)) + + def test_trusted_filter_untrusted_and_untrusted_passes(self): + global DATA + DATA = '{"hosts":[{"host_name":"host1","trust_lvl":"untrusted"}]}' + self._stub_service_is_up(True) + filt_cls = self.class_map['TrustedFilter']() + extra_specs = {'trusted_host': 'untrusted'} + filter_properties = {'instance_type': {'memory_mb': 1024, + 'extra_specs': extra_specs}} + host = fakes.FakeHostState('host1', 'compute', {}) + self.assertTrue(filt_cls.host_passes(host, filter_properties)) + def test_core_filter_passes(self): filt_cls = self.class_map['CoreFilter']() filter_properties = {'instance_type': {'vcpus': 1}} -- cgit