config: add playbooks to job.toDict()

This change adds the job's playbook configuration to the job.toDict() method
so that the playbooks usage can be inspected from the REST APIs.
This change also improves the test_web to enable skipping build provisioning
for test that only query static rest end point.

Change-Id: I93b602fb3ddd8a418b7d750bd443477a83be2f75
This commit is contained in:
Tristan Cacqueray 2018-12-01 08:54:20 +00:00 committed by Joshua Hesketh
parent 275cbc92e0
commit 775c45c316
9 changed files with 112 additions and 4 deletions

View File

@ -18,7 +18,8 @@
name: project1-secret
run: playbooks/secret.yaml
secrets:
- project1_secret
- secret: project1_secret
name: secret_name
- project:
check:

View File

@ -0,0 +1 @@
---

View File

@ -0,0 +1 @@
---

View File

@ -195,3 +195,13 @@
run: playbooks/project-merge.yaml
required-projects:
- org/project
- job:
name: complete-job
description: A fake job to test attribute
abstract: true
run: playbooks/run.yaml
pre-run: playbooks/pre-run.yaml
post-run:
- playbooks/post-run-01.yaml
- playbooks/post-run-02.yaml

View File

@ -3662,8 +3662,8 @@ class TestSecrets(ZuulTestCase):
dict(name='project1-secret', result='SUCCESS', changes='1,1'),
])
self.assertEqual(
self._getSecrets('project1-secret', 'playbooks'),
[{'project1_secret': self.secret}])
[{'secret_name': self.secret}],
self._getSecrets('project1-secret', 'playbooks'))
def test_secret_branch_error_same_branch(self):
# Test that we are unable to define a secret twice on the same

View File

@ -280,6 +280,18 @@ class TestWeb(BaseTestWeb):
'path': 'zuul.yaml',
'project': 'common-config',
}
run = [{
'path': 'playbooks/project-test1.yaml',
'roles': [{
'implicit': True,
'project_canonical_name': 'review.example.com/common-config',
'target_name': 'common-config',
'type': 'zuul'
}],
'secrets': [],
'source_context': source_ctx,
}]
self.assertEqual([
{
'name': 'project-test1',
@ -309,6 +321,9 @@ class TestWeb(BaseTestWeb):
'required_projects': [],
'requires': [],
'roles': [common_config_role],
'run': run,
'pre_run': [],
'post_run': [],
'semaphore': None,
'source_context': source_ctx,
'tags': [],
@ -344,6 +359,9 @@ class TestWeb(BaseTestWeb):
'required_projects': [],
'requires': [],
'roles': [common_config_role],
'run': run,
'pre_run': [],
'post_run': [],
'semaphore': None,
'source_context': source_ctx,
'tags': [],
@ -354,6 +372,7 @@ class TestWeb(BaseTestWeb):
}], data)
data = self.get_url('api/tenant/tenant-one/job/test-job').json()
run[0]['path'] = 'playbooks/project-merge.yaml'
self.assertEqual([
{
'abstract': False,
@ -376,6 +395,9 @@ class TestWeb(BaseTestWeb):
'project_name': 'review.example.com/org/project'}],
'requires': [],
'roles': [common_config_role],
'run': run,
'pre_run': [],
'post_run': [],
'semaphore': None,
'source_context': source_ctx,
'tags': [],
@ -385,6 +407,38 @@ class TestWeb(BaseTestWeb):
'voting': True
}], data)
def test_find_job_complete_playbooks(self):
# can we fetch the variants for a single job
data = self.get_url('api/tenant/tenant-one/job/complete-job').json()
def expected_pb(path):
return {
'path': path,
'roles': [{
'implicit': True,
'project_canonical_name':
'review.example.com/common-config',
'target_name': 'common-config',
'type': 'zuul'
}],
'secrets': [],
'source_context': {
'branch': 'master',
'path': 'zuul.yaml',
'project': 'common-config',
}
}
self.assertEqual([
expected_pb("playbooks/run.yaml")
], data[0]['run'])
self.assertEqual([
expected_pb("playbooks/pre-run.yaml")
], data[0]['pre_run'])
self.assertEqual([
expected_pb("playbooks/post-run-01.yaml"),
expected_pb("playbooks/post-run-02.yaml")
], data[0]['post_run'])
def test_web_nodes_list(self):
# can we fetch the nodes list
self.add_base_changes()
@ -447,6 +501,9 @@ class TestWeb(BaseTestWeb):
'required_projects': [],
'requires': [],
'roles': [],
'run': [],
'pre_run': [],
'post_run': [],
'semaphore': None,
'source_context': {
'branch': 'master',
@ -474,6 +531,9 @@ class TestWeb(BaseTestWeb):
'required_projects': [],
'requires': [],
'roles': [],
'run': [],
'pre_run': [],
'post_run': [],
'semaphore': None,
'source_context': {
'branch': 'master',
@ -501,6 +561,9 @@ class TestWeb(BaseTestWeb):
'required_projects': [],
'requires': [],
'roles': [],
'run': [],
'pre_run': [],
'post_run': [],
'semaphore': None,
'source_context': {
'branch': 'master',
@ -528,6 +591,9 @@ class TestWeb(BaseTestWeb):
'required_projects': [],
'requires': [],
'roles': [],
'run': [],
'pre_run': [],
'post_run': [],
'semaphore': None,
'source_context': {
'branch': 'master',
@ -588,7 +654,7 @@ class TestWeb(BaseTestWeb):
def test_jobs_list(self):
jobs = self.get_url("api/tenant/tenant-one/jobs").json()
self.assertEqual(len(jobs), 9)
self.assertEqual(len(jobs), 10)
resp = self.get_url("api/tenant/non-tenant/jobs")
self.assertEqual(404, resp.status_code)
@ -598,6 +664,16 @@ class TestWeb(BaseTestWeb):
self.assertEqual("noop", job[0]["name"])
class TestWebSecrets(BaseTestWeb):
tenant_config_file = 'config/secrets/main.yaml'
def test_web_find_job_secret(self):
data = self.get_url('api/tenant/tenant-one/job/project1-secret').json()
run = data[0]['run']
secret = {'name': 'project1_secret', 'alias': 'secret_name'}
self.assertEqual([secret], run[0]['secrets'])
class TestInfo(BaseTestWeb):
def setUp(self):

View File

@ -987,6 +987,20 @@ class PlaybookContext(ConfigObject):
secrets=secrets,
path=self.path)
def toSchemaDict(self):
# Render to a dict to use in REST api
d = {
'path': self.path,
'roles': list(map(lambda x: x.toDict(), self.roles)),
'secrets': [{'name': secret.name, 'alias': secret.alias}
for secret in self.secrets],
}
if self.source_context:
d['source_context'] = self.source_context.toDict()
else:
d['source_context'] = None
return d
class Role(ConfigObject, metaclass=abc.ABCMeta):
"""A reference to an ansible role."""
@ -1177,6 +1191,9 @@ class Job(ConfigObject):
d['dependencies'] = list(self.dependencies)
d['attempts'] = self.attempts
d['roles'] = list(map(lambda x: x.toDict(), self.roles))
d['run'] = list(map(lambda x: x.toSchemaDict(), self.run))
d['pre_run'] = list(map(lambda x: x.toSchemaDict(), self.pre_run))
d['post_run'] = list(map(lambda x: x.toSchemaDict(), self.post_run))
d['post_review'] = self.post_review
if self.isBase():
d['parent'] = None