kojid: extend SCM.assert_allowed with hub policy
This is a simple extention of `SCM.assert_allowed` - `assert_allowed_by_policy` will set the default "use_common" to False which is different to the old behavior - `channel`, `user_id`, `scratch` are passed in the `policy_data` with scminfo right now. This is a prototype for this change, and there are some other solutions could be implemented too - Use a scmpolicy plugin as `postSCMCheckout` callback, the pro is that we can do more checks after the source is initialized on builder, meanwhile, the con is that the source will be downloaded even it is denied by policy. It might be a potential risk? - Do the scm check in hub's `make_task`, this looks straightforward, but may lack some builder's information fixes: #2757
This commit is contained in:
parent
ec70d21c41
commit
47c4b5d70b
8 changed files with 431 additions and 25 deletions
|
|
@ -8,9 +8,40 @@ import unittest
|
|||
|
||||
import koji
|
||||
import koji.daemon
|
||||
import koji.policy
|
||||
|
||||
from koji.daemon import SCM
|
||||
|
||||
policy = {
|
||||
'one': '''
|
||||
match scmhost goodserver :: allow none
|
||||
match scmhost badserver :: deny
|
||||
match scmhost maybeserver && match scmrepository /badpath/* :: deny
|
||||
all :: allow
|
||||
''',
|
||||
'two': '''
|
||||
match scmhost default :: allow
|
||||
match scmhost nocommon :: allow
|
||||
match scmhost common :: allow use_common
|
||||
match scmhost srccmd :: allow fedpkg sources
|
||||
match scmhost nosrc :: allow none
|
||||
match scmhost mixed && match scmrepository /foo/* :: allow
|
||||
match scmhost mixed && match scmrepository /bar/* :: allow use_common
|
||||
match scmhost mixed && match scmrepository /baz/* :: allow fedpkg sources
|
||||
match scmhost mixed && match scmrepository /foobar/* :: allow use_common fedpkg sources
|
||||
match scmhost mixed && match scmrepository /foobaz/* :: allow use_common none
|
||||
'''
|
||||
}
|
||||
|
||||
class FakePolicy(object):
|
||||
|
||||
def __init__(self, rule):
|
||||
base_tests = koji.policy.findSimpleTests(vars(koji.policy))
|
||||
self.ruleset = koji.policy.SimpleRuleSet(rule.splitlines(), base_tests)
|
||||
|
||||
def evalPolicy(self, name, data):
|
||||
return self.ruleset.apply(data)
|
||||
|
||||
|
||||
class TestSCM(unittest.TestCase):
|
||||
|
||||
|
|
@ -67,8 +98,22 @@ class TestSCM(unittest.TestCase):
|
|||
self.assertEqual(scm.source_cmd, ['make', 'sources'])
|
||||
self.assertEqual(scm.scmtype, 'GIT')
|
||||
|
||||
def test_assert_allowed_basic(self):
|
||||
scm = SCM("git://scm.example.com/path1#1234")
|
||||
|
||||
# session must be passed
|
||||
with self.assertRaises(koji.GenericError) as cm:
|
||||
scm.assert_allowed(session=None, by_config=False, by_policy=True)
|
||||
self.assertEqual(str(cm.exception),
|
||||
'When allowed SCM assertion is by policy, session must be passed in.')
|
||||
|
||||
# allowed could not be None
|
||||
scm.assert_allowed_by_config = mock.MagicMock()
|
||||
scm.assert_allowed(allowed=None, by_config=True, by_policy=False)
|
||||
scm.assert_allowed_by_config.assert_called_once_with('')
|
||||
|
||||
@mock.patch('logging.getLogger')
|
||||
def test_allowed(self, getLogger):
|
||||
def test_allowed_by_config(self, getLogger):
|
||||
config = '''
|
||||
goodserver:*:no
|
||||
!badserver:*
|
||||
|
|
@ -104,7 +149,7 @@ class TestSCM(unittest.TestCase):
|
|||
raise AssertionError("allowed bad url: %s" % url)
|
||||
|
||||
@mock.patch('logging.getLogger')
|
||||
def test_badrule(self, getLogger):
|
||||
def test_badrule_by_config(self, getLogger):
|
||||
config = '''
|
||||
bogus-entry-should-be-ignored
|
||||
goodserver:*:no
|
||||
|
|
@ -115,7 +160,7 @@ class TestSCM(unittest.TestCase):
|
|||
scm.assert_allowed(config)
|
||||
|
||||
@mock.patch('logging.getLogger')
|
||||
def test_opts(self, getLogger):
|
||||
def test_opts_by_config(self, getLogger):
|
||||
config = '''
|
||||
default:*
|
||||
nocommon:*:no
|
||||
|
|
@ -196,6 +241,181 @@ class TestSCM(unittest.TestCase):
|
|||
with self.assertRaises(koji.BuildError):
|
||||
scm.assert_allowed(config)
|
||||
|
||||
def test_allowed_by_policy(self):
|
||||
good = [
|
||||
"git://goodserver/path1#1234",
|
||||
"git+ssh://maybeserver/path1#1234",
|
||||
]
|
||||
bad = [
|
||||
"cvs://badserver/projects/42#ref",
|
||||
"svn://badserver/projects/42#ref",
|
||||
"git://maybeserver/badpath/project#1234",
|
||||
"git://maybeserver//badpath/project#1234",
|
||||
"git://maybeserver////badpath/project#1234",
|
||||
"git://maybeserver/./badpath/project#1234",
|
||||
"git://maybeserver//.//badpath/project#1234",
|
||||
"git://maybeserver/goodpath/../badpath/project#1234",
|
||||
"git://maybeserver/goodpath/..//badpath/project#1234",
|
||||
"git://maybeserver/..//badpath/project#1234",
|
||||
]
|
||||
session = mock.MagicMock()
|
||||
session.host.evalPolicy.side_effect = FakePolicy(policy['one']).evalPolicy
|
||||
for url in good:
|
||||
scm = SCM(url)
|
||||
scm.assert_allowed(session=session, by_config=False, by_policy=True)
|
||||
for url in bad:
|
||||
scm = SCM(url)
|
||||
with self.assertRaises(koji.BuildError) as cm:
|
||||
scm.assert_allowed(session=session, by_config=False, by_policy=True)
|
||||
self.assertRegexpMatches(str(cm.exception), '^SCM: .* is not allowed, reason: None$')
|
||||
|
||||
def test_opts_by_policy(self):
|
||||
session = mock.MagicMock()
|
||||
session.host.evalPolicy.side_effect = FakePolicy(policy['two']).evalPolicy
|
||||
|
||||
url = "git://default/koji.git#1234"
|
||||
scm = SCM(url)
|
||||
scm.assert_allowed_by_policy(session=session)
|
||||
self.assertEqual(scm.use_common, False)
|
||||
self.assertEqual(scm.source_cmd, ['make', 'sources'])
|
||||
|
||||
url = "git://nocommon/koji.git#1234"
|
||||
scm = SCM(url)
|
||||
scm.assert_allowed_by_policy(session=session)
|
||||
self.assertEqual(scm.use_common, False)
|
||||
self.assertEqual(scm.source_cmd, ['make', 'sources'])
|
||||
|
||||
url = "git://common/koji.git#1234"
|
||||
scm = SCM(url)
|
||||
scm.assert_allowed_by_policy(session=session)
|
||||
self.assertEqual(scm.use_common, True)
|
||||
self.assertEqual(scm.source_cmd, ['make', 'sources'])
|
||||
|
||||
url = "git://srccmd/koji.git#1234"
|
||||
scm = SCM(url)
|
||||
scm.assert_allowed_by_policy(session=session)
|
||||
self.assertEqual(scm.use_common, False)
|
||||
self.assertEqual(scm.source_cmd, ['fedpkg', 'sources'])
|
||||
|
||||
url = "git://nosrc/koji.git#1234"
|
||||
scm = SCM(url)
|
||||
scm.assert_allowed_by_policy(session=session)
|
||||
self.assertEqual(scm.use_common, False)
|
||||
self.assertEqual(scm.source_cmd, None)
|
||||
|
||||
url = "git://mixed/foo/koji.git#1234"
|
||||
scm = SCM(url)
|
||||
scm.assert_allowed_by_policy(session=session)
|
||||
self.assertEqual(scm.use_common, False)
|
||||
self.assertEqual(scm.source_cmd, ['make', 'sources'])
|
||||
|
||||
url = "git://mixed/bar/koji.git#1234"
|
||||
scm = SCM(url)
|
||||
scm.assert_allowed_by_policy(session=session)
|
||||
self.assertEqual(scm.use_common, True)
|
||||
self.assertEqual(scm.source_cmd, ['make', 'sources'])
|
||||
|
||||
url = "git://mixed/baz/koji.git#1234"
|
||||
scm = SCM(url)
|
||||
scm.assert_allowed_by_policy(session=session)
|
||||
self.assertEqual(scm.use_common, False)
|
||||
self.assertEqual(scm.source_cmd, ['fedpkg', 'sources'])
|
||||
|
||||
url = "git://mixed/koji.git#1234"
|
||||
scm = SCM(url)
|
||||
with self.assertRaises(koji.BuildError):
|
||||
scm.assert_allowed_by_policy(session=session)
|
||||
|
||||
url = "git://mixed/foo/koji.git#1234"
|
||||
scm = SCM(url)
|
||||
scm.assert_allowed_by_policy(session=session)
|
||||
self.assertEqual(scm.use_common, False)
|
||||
self.assertEqual(scm.source_cmd, ['make', 'sources'])
|
||||
|
||||
url = "git://mixed/bar/koji.git#1234"
|
||||
scm = SCM(url)
|
||||
scm.assert_allowed_by_policy(session=session)
|
||||
self.assertEqual(scm.use_common, True)
|
||||
self.assertEqual(scm.source_cmd, ['make', 'sources'])
|
||||
|
||||
url = "git://mixed/baz/koji.git#1234"
|
||||
scm = SCM(url)
|
||||
scm.assert_allowed_by_policy(session=session)
|
||||
self.assertEqual(scm.use_common, False)
|
||||
self.assertEqual(scm.source_cmd, ['fedpkg', 'sources'])
|
||||
|
||||
url = "git://mixed/foobar/koji.git#1234"
|
||||
scm = SCM(url)
|
||||
scm.assert_allowed_by_policy(session=session)
|
||||
self.assertEqual(scm.use_common, True)
|
||||
self.assertEqual(scm.source_cmd, ['fedpkg', 'sources'])
|
||||
|
||||
url = "git://mixed/foobaz/koji.git#1234"
|
||||
scm = SCM(url)
|
||||
scm.assert_allowed_by_policy(session=session)
|
||||
self.assertEqual(scm.use_common, True)
|
||||
self.assertIsNone(scm.source_cmd)
|
||||
|
||||
url = "git://nomatch/koji.git#1234"
|
||||
scm = SCM(url)
|
||||
with self.assertRaises(koji.BuildError):
|
||||
scm.assert_allowed_by_policy(session=session)
|
||||
|
||||
def test_assert_allowed_by_both(self):
|
||||
config = '''
|
||||
default:*:no:
|
||||
mixed:/foo/*:yes
|
||||
mixed:/bar/*:no
|
||||
mixed:/baz/*:no:centpkg,sources
|
||||
mixed:/foobar/*:no:
|
||||
mixed:/foobaz/*:no:centpkg,sources
|
||||
'''
|
||||
|
||||
session = mock.MagicMock()
|
||||
session.host.evalPolicy.side_effect = FakePolicy(policy['two']).evalPolicy
|
||||
|
||||
url = "git://default/koji.git#1234"
|
||||
scm = SCM(url)
|
||||
# match scmhost default :: allow
|
||||
scm.assert_allowed(allowed=config, session=session, by_config=True, by_policy=True)
|
||||
self.assertEqual(scm.use_common, False)
|
||||
self.assertIsNone(scm.source_cmd)
|
||||
|
||||
url = "git://mixed/foo/koji.git#1234"
|
||||
scm = SCM(url)
|
||||
# match scmhost mixed && match scmrepository /foo/* :: allow
|
||||
scm.assert_allowed(allowed=config, session=session, by_config=True, by_policy=True)
|
||||
self.assertEqual(scm.use_common, False)
|
||||
self.assertEqual(scm.source_cmd, ['make', 'sources'])
|
||||
|
||||
url = "git://mixed/bar/koji.git#1234"
|
||||
scm = SCM(url)
|
||||
# match scmhost mixed && match scmrepository /bar/* :: allow use_common
|
||||
scm.assert_allowed(allowed=config, session=session, by_config=True, by_policy=True)
|
||||
self.assertEqual(scm.use_common, True)
|
||||
self.assertEqual(scm.source_cmd, ['make', 'sources'])
|
||||
|
||||
url = "git://mixed/baz/koji.git#1234"
|
||||
scm = SCM(url)
|
||||
# match scmhost mixed && match scmrepository /baz/* :: allow fedpkg sources
|
||||
scm.assert_allowed(allowed=config, session=session, by_config=True, by_policy=True)
|
||||
self.assertEqual(scm.use_common, False)
|
||||
self.assertEqual(scm.source_cmd, ['fedpkg', 'sources'])
|
||||
|
||||
url = "git://mixed/foobar/koji.git#1234"
|
||||
scm = SCM(url)
|
||||
# match scmhost mixed && match scmrepository /foobar/* :: allow use_common fedpkg sources
|
||||
scm.assert_allowed(allowed=config, session=session, by_config=True, by_policy=True)
|
||||
self.assertEqual(scm.use_common, True)
|
||||
self.assertEqual(scm.source_cmd, ['fedpkg', 'sources'])
|
||||
|
||||
url = "git://mixed/foobaz/koji.git#1234"
|
||||
scm = SCM(url)
|
||||
# match scmhost mixed && match scmrepository /foobaz/* :: allow use_common none
|
||||
scm.assert_allowed(allowed=config, session=session, by_config=True, by_policy=True)
|
||||
self.assertEqual(scm.use_common, True)
|
||||
self.assertIsNone(scm.source_cmd)
|
||||
|
||||
|
||||
class TestSCMCheckouts(unittest.TestCase):
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue