Commit ac624524 authored by Neil Williams's avatar Neil Williams Committed by Senthil Kumaran Shanmugasundaram
Browse files

LAVA-1333 fix visibility check for health checks

The lava-health user is treated a bit differently but hidden
devices still need protection so that the health check is
not public. Ensure that health checks check visibility
and fail if the test job would be public.
Remove some python2 conditionals.

Change-Id: Ica4bce291200dbdef20a140c9888416c3c25ef5f
parent a37a30f7
......@@ -11,7 +11,6 @@ import uuid
import simplejson
import smtplib
import socket
import sys
import yaml
from django.db.models import Q
......@@ -41,7 +40,6 @@ from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
from django.utils.safestring import mark_safe
from django_restricted_resource.models import (
RestrictedResource,
RestrictedResourceManager
......@@ -52,28 +50,17 @@ from lava_scheduler_app.schema import (
handle_include_option,
SubmissionException
)
from lava_common.exceptions import ConfigurationError
from lava_scheduler_app import utils
from linaro_django_xmlrpc.models import AuthToken
from lava_scheduler_app.schema import validate_device
if sys.version_info[0] == 2:
# Python 2.x
from urllib2 import urlopen, Request
from urllib import urlencode
elif sys.version_info[0] == 3:
# For Python 3.0 and later
from urllib.request import urlopen, Request
from urllib.parse import urlencode
from urllib.request import urlopen, Request
from urllib.parse import urlencode
# pylint: disable=invalid-name,no-self-use,too-many-public-methods,too-few-public-methods
# pylint: disable=too-many-branches,too-many-return-statements,too-many-instance-attributes
# Make the open function accept encodings in python < 3.x
if sys.version_info[0] < 3:
import codecs
open = codecs.open # pylint: disable=redefined-builtin
class JSONDataError(ValueError):
"""Error raised when JSON is syntactically valid but ill-formed."""
......@@ -1130,6 +1117,13 @@ def _create_pipeline_job(job_data, user, taglist, device=None,
visibility = TestJob.VISIBLE_PUBLIC
viewing_groups = []
param = job_data['visibility']
if health_check and not device.is_public:
# 'lava-health' user is normally allowed to "ignore" visibility
if isinstance(param, str):
if param == 'public':
raise ConfigurationError("Publicly visible health check for restricted device")
if isinstance(param, str):
if param == 'personal':
public_state = False
......@@ -1462,7 +1456,7 @@ class TestJob(RestrictedResource):
Jobs that are not multinode will directly use STATE_SCHEDULED
"""
if device.state != Device.STATE_IDLE:
raise Exception("device is not IDLE")
raise Exception("device is not IDLE: %s", Device.STATE_CHOICES[device.state])
if self.state >= TestJob.STATE_SCHEDULING:
return
self.state = TestJob.STATE_SCHEDULING
......@@ -1485,7 +1479,7 @@ class TestJob(RestrictedResource):
device = self.actual_device
else:
if device.state != Device.STATE_IDLE:
raise Exception("device is not IDLE")
raise Exception("device is not IDLE: %s", Device.STATE_CHOICES[device.state])
if self.state >= TestJob.STATE_SCHEDULED:
return
self.state = TestJob.STATE_SCHEDULED
......
......@@ -33,6 +33,7 @@ from lava_scheduler_app.models import (
DeviceType,
Device,
_create_pipeline_job,
_check_submit_to_device,
TestJob,
Worker
)
......@@ -143,9 +144,9 @@ def schedule_health_checks_for_device_type(logger, dt):
def schedule_health_check(device, definition):
user = User.objects.get(username="lava-health")
job = _create_pipeline_job(yaml.load(definition), user, [],
device_type=device.device_type,
orig=definition, health_check=True)
job = _create_pipeline_job(
yaml.load(definition), user, [], device=device, device_type=device.device_type,
orig=definition, health_check=True)
job.go_state_scheduled(device)
job.save()
return job.id
......
......@@ -11,11 +11,14 @@ from django_testscenarios.ubertest import TestCase
from lava_scheduler_app.models import (
Device,
DeviceType,
DevicesUnavailableException,
Notification,
Tag,
TestJob,
)
from lava_scheduler_app.schema import SubmissionException
from lava_scheduler_app.scheduler import schedule_health_check
from lava_common.exceptions import ConfigurationError
LOGGER = logging.getLogger()
LOGGER.level = logging.INFO # change to DEBUG to see *all* output
......@@ -105,7 +108,9 @@ class ModelFactory(object):
if not isinstance(tags, list):
tags = []
# a hidden device type will override is_public
device = Device(device_type=device_type, is_public=is_public, hostname=hostname, **kw)
device = Device(
device_type=device_type, is_public=is_public, state=Device.STATE_IDLE,
hostname=hostname, **kw)
device.tags = tags
logging.debug("making a device of type %s %s %s with tags '%s'",
device_type, device.is_public, device.hostname, ", ".join([x.name for x in device.tags.all()]))
......@@ -244,3 +249,59 @@ class TestHiddenTestJob(TestCaseWithFactory): # pylint: disable=too-many-ancest
device = self.factory.make_device(device_type=device_type, hostname="hidden1")
device.save()
self.assertEqual(device.is_public, False)
def test_visibility_and_hidden(self):
self.factory.cleanup()
device_type = self.factory.make_hidden_device_type('hidden')
device = self.factory.make_device(device_type=device_type, hostname="hidden1")
device.save()
self.assertEqual(device.is_public, False)
definition = self.factory.make_job_data()
definition['visibility'] = 'public'
user = self.factory.make_user()
user.user_permissions.add(
Permission.objects.get(codename='add_testjob'))
user.save()
self.assertRaises(
DevicesUnavailableException,
TestJob.from_yaml_and_user,
yaml.dump(definition),
user)
def test_hidden_healthcheck(self):
self.factory.cleanup()
device_type = self.factory.make_hidden_device_type('hidden')
device = self.factory.make_device(device_type=device_type, hostname="hidden1")
device.save()
device.refresh_from_db()
self.assertEqual(Device.STATE_IDLE, device.state)
self.assertEqual(device.is_public, False)
definition = self.factory.make_job_data()
definition['job_name'] = 'job_should_fail'
definition['visibility'] = 'public'
self.assertIsNotNone(device)
self.factory.ensure_user('lava-health', 'test@l.org', 'pass')
self.assertRaises(
ConfigurationError,
schedule_health_check,
device,
yaml.dump(definition))
# reset device state.
definition['job_name'] = 'job_should_schedule'
self.factory.make_group('hide')
device.state = Device.STATE_IDLE
device.save(update_fields=['state'])
definition['visibility'] = {'group': ['hide']}
job_id = schedule_health_check(device, yaml.dump(definition))
job = TestJob.objects.get(id=job_id)
self.assertEqual(job.is_public, False)
self.assertEqual(job.visibility, TestJob.VISIBLE_GROUP)
device.state = Device.STATE_IDLE
device.save(update_fields=['state'])
definition['visibility'] = 'personal'
job_id = schedule_health_check(device, yaml.dump(definition))
job = TestJob.objects.get(id=job_id)
self.assertEqual(job.is_public, False)
self.assertEqual(job.visibility, TestJob.VISIBLE_PERSONAL)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment