add a script to examine the gerrit acls for issues
This is based on mnaser's work in https://review.openstack.org/533780/ Change-Id: Ie6f94db0dce2f5331c3d21a1192533ffc648329b Signed-off-by: Doug Hellmann <doug@doughellmann.com>
This commit is contained in:
parent
39d9cc021c
commit
a12d59edd1
1
.gitignore
vendored
1
.gitignore
vendored
@ -11,3 +11,4 @@
|
||||
/.testrepository/
|
||||
/cover/
|
||||
/unreleased-*.txt
|
||||
gerrit.ini
|
||||
|
186
openstack_releases/cmds/find_gerrit_acl_issues.py
Normal file
186
openstack_releases/cmds/find_gerrit_acl_issues.py
Normal file
@ -0,0 +1,186 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""Look for governed projects that have their tagging ACLs misconfigured.
|
||||
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import configparser
|
||||
import json
|
||||
import os.path
|
||||
import urllib
|
||||
|
||||
import appdirs
|
||||
import requests
|
||||
from requests.packages import urllib3
|
||||
|
||||
import openstack_releases
|
||||
from openstack_releases import defaults
|
||||
from openstack_releases import deliverable
|
||||
from openstack_releases import governance
|
||||
|
||||
# Disable warnings about insecure connections.
|
||||
urllib3.disable_warnings()
|
||||
|
||||
|
||||
IGNORED_TEAMS = [
|
||||
'Infrastructure',
|
||||
'OpenStack Charms',
|
||||
]
|
||||
|
||||
ALLOWED = [
|
||||
'library-release',
|
||||
'Release Managers',
|
||||
'openstack-chef-release',
|
||||
'xstatic-release',
|
||||
'release-tools-core',
|
||||
'releases-core',
|
||||
]
|
||||
|
||||
|
||||
class GerritClient(object):
|
||||
|
||||
BASE = 'https://review.openstack.org:443/a/'
|
||||
|
||||
def __init__(self, user, password):
|
||||
self._user = user
|
||||
self._password = password
|
||||
self._auth = requests.auth.HTTPDigestAuth(
|
||||
self._user,
|
||||
self._password,
|
||||
)
|
||||
self._groups = {}
|
||||
|
||||
def _mk_url(self, api, *args):
|
||||
encoded = [
|
||||
urllib.parse.quote_plus(a)
|
||||
for a in args
|
||||
]
|
||||
return self.BASE + api.format(*encoded)
|
||||
|
||||
def _get(self, url):
|
||||
response = requests.get(url, auth=self._auth)
|
||||
if response.status_code == 404:
|
||||
raise ValueError(404)
|
||||
|
||||
# strip off first few chars because 'the JSON response body starts with
|
||||
# a magic prefix line that must be stripped before feeding the rest of
|
||||
# the response body to a JSON parser'
|
||||
# https://review.openstack.org/Documentation/rest-api.html
|
||||
# print(response.text)
|
||||
return json.loads(response.text[5:])
|
||||
|
||||
def get_access(self, repo):
|
||||
url = self._mk_url('projects/{}/access', repo)
|
||||
return self._get(url)
|
||||
|
||||
def get_group(self, group_id):
|
||||
if group_id in self._groups:
|
||||
return self._groups[group_id]
|
||||
url = self._mk_url('groups/{}', group_id)
|
||||
data = self._get(url)
|
||||
self._groups[group_id] = data
|
||||
return data
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
'--verbose', '-v',
|
||||
action='store_true',
|
||||
default=False,
|
||||
)
|
||||
parser.add_argument(
|
||||
'--deliverables-dir',
|
||||
default=openstack_releases.deliverable_dir,
|
||||
help='location of deliverable files',
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
config_filename = os.path.join(
|
||||
appdirs.user_config_dir('openstack-release', 'openstack'),
|
||||
'gerrit.ini',
|
||||
)
|
||||
config = configparser.ConfigParser()
|
||||
config.read(config_filename, encoding='utf-8')
|
||||
|
||||
if not config.has_option('DEFAULT', 'username'):
|
||||
parser.error('No username set in {}'.format(config_filename))
|
||||
if not config.has_option('DEFAULT', 'password'):
|
||||
parser.error('No password set in {}'.format(config_filename))
|
||||
|
||||
team_data = governance.get_team_data()
|
||||
|
||||
# Some deliverables were independent at one time but might not be
|
||||
# any more, so compare the independent list with the current
|
||||
# release series.
|
||||
all_independent_deliverables = set(
|
||||
name
|
||||
for team, series, name, deliv in deliverable.Deliverables(
|
||||
root_dir=args.deliverables_dir,
|
||||
collapse_history=True,
|
||||
).get_deliverables(None, None)
|
||||
)
|
||||
current_deliverables = set(
|
||||
name
|
||||
for team, series, name, deliv in deliverable.Deliverables(
|
||||
root_dir=args.deliverables_dir,
|
||||
collapse_history=True,
|
||||
).get_deliverables(None, defaults.RELEASE)
|
||||
)
|
||||
independent_deliverables = all_independent_deliverables.difference(
|
||||
current_deliverables)
|
||||
|
||||
gerrit = GerritClient(
|
||||
config['DEFAULT']['username'],
|
||||
config['DEFAULT']['password'],
|
||||
)
|
||||
|
||||
for repo in governance.get_repositories(team_data, code_only=True):
|
||||
|
||||
if repo.deliverable.team.name in IGNORED_TEAMS:
|
||||
if args.verbose:
|
||||
print('{}: ignoring {} team'.format(
|
||||
repo.name, repo.deliverable.team.name))
|
||||
continue
|
||||
|
||||
if repo.deliverable.name in independent_deliverables:
|
||||
if args.verbose:
|
||||
print('{}: ignoring independent deliverable'.format(
|
||||
repo.name))
|
||||
continue
|
||||
|
||||
acls = gerrit.get_access(repo.name)
|
||||
local_tag_acls = acls.get('local', {}).get('refs/tags/*', {})
|
||||
if local_tag_acls:
|
||||
rules = local_tag_acls.get('permissions', {}).get(
|
||||
'pushSignedTag', {}).get('rules', {})
|
||||
if not rules and args.verbose:
|
||||
print('{}: OK'.format(repo.name))
|
||||
|
||||
for group_id, permissions in rules.items():
|
||||
group_details = gerrit.get_group(group_id)
|
||||
group_name = group_details['name']
|
||||
if group_name in ALLOWED:
|
||||
if args.verbose:
|
||||
print('{}: {} pushSignedTag OK'.format(
|
||||
repo.name, group_name))
|
||||
continue
|
||||
if args.verbose:
|
||||
print('{}: {} pushSignedTag WARNING'.format(
|
||||
repo.name, group_name))
|
||||
else:
|
||||
print('{}: {} pushSignedTag'.format(
|
||||
repo.name, group_name))
|
@ -30,3 +30,5 @@ reno>=2.0.0
|
||||
sphinx>=1.6.2 # BSD
|
||||
|
||||
pyfiglet>=0.7.5
|
||||
|
||||
appdirs
|
||||
|
@ -41,6 +41,7 @@ console_scripts =
|
||||
send-mail = openstack_releases.cmds.mail:main
|
||||
release-notes = openstack_releases.cmds.release_notes:main
|
||||
check-schema = openstack_releases.cmds.check_schema:main
|
||||
find-gerrit-acl-issues = openstack_releases.cmds.find_gerrit_acl_issues:main
|
||||
|
||||
[extras]
|
||||
sphinxext =
|
||||
|
Loading…
Reference in New Issue
Block a user