diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..529ec7d8c9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +.DS_Store +*.swp +*~ +*.pyc +.tox/ +.test/ +/.project +/.pydevproject +*.egg diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 0000000000..cf17050ab9 --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1,2 @@ +hacking>=0.5.6,<0.8 +bashate>=0.2 diff --git a/tools/check_irc_access.py b/tools/check_irc_access.py new file mode 100644 index 0000000000..40384043fa --- /dev/null +++ b/tools/check_irc_access.py @@ -0,0 +1,154 @@ +#! /usr/bin/env python + +# Copyright 2011, 2013-2014 OpenStack Foundation +# Copyright 2012 Hewlett-Packard Development Company, L.P. +# +# 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. + +import argparse +import irc.client +import logging +import random +import string +import ssl +import sys +import time +import yaml + + +logging.basicConfig(level=logging.INFO) + + +class CheckAccess(irc.client.SimpleIRCClient): + log = logging.getLogger("checkaccess") + + def __init__(self, channels, nick, flags): + irc.client.SimpleIRCClient.__init__(self) + self.identify_msg_cap = False + self.channels = channels + self.nick = nick + self.flags = flags + self.current_channel = None + self.current_list = [] + self.failed = True + + def on_disconnect(self, connection, event): + if self.failed: + sys.exit(1) + else: + sys.exit(0) + + def on_welcome(self, c, e): + self.identify_msg_cap = False + self.log.debug("Requesting identify-msg capability") + c.cap('REQ', 'identify-msg') + c.cap('END') + + def on_cap(self, c, e): + self.log.debug("Received cap response %s" % repr(e.arguments)) + if e.arguments[0] == 'ACK' and 'identify-msg' in e.arguments[1]: + self.log.debug("identify-msg cap acked") + self.identify_msg_cap = True + self.advance() + + def on_privnotice(self, c, e): + if not self.identify_msg_cap: + self.log.debug("Ignoring message because identify-msg " + "cap not enabled") + return + nick = e.source.split('!')[0] + auth = e.arguments[0][0] + msg = e.arguments[0][1:] + if auth != '+' or nick != 'ChanServ': + self.log.debug("Ignoring message from unauthenticated " + "user %s" % nick) + return + self.failed = False + self.advance(msg) + + def advance(self, msg=None): + if not self.current_channel: + if not self.channels: + self.connection.quit() + return + self.current_channel = self.channels.pop() + self.current_list = [] + self.connection.privmsg('chanserv', 'access list %s' % + self.current_channel) + time.sleep(1) + return + if msg.startswith('End of'): + found = False + for nick, flags, msg in self.current_list: + if nick == self.nick and flags == self.flags: + self.log.info('%s access ok on %s' % + (self.nick, self.current_channel)) + found = True + break + if not found: + self.failed = True + print ("%s does not have permissions on %s:" % + (self.nick, self.current_channel)) + for nick, flags, msg in self.current_list: + print msg + print + self.current_channel = None + self.advance() + return + parts = msg.split() + self.current_list.append((parts[1], parts[2], msg)) + + +def main(): + parser = argparse.ArgumentParser(description='IRC channel access check') + parser.add_argument('-l', dest='config', + default='/etc/accessbot/channels.yaml', + help='path to the config file') + parser.add_argument('-s', dest='server', + default='chat.freenode.net', + help='IRC server') + parser.add_argument('-p', dest='port', + default=6697, + help='IRC port') + parser.add_argument('nick', + help='the nick for which access should be validated') + args = parser.parse_args() + + config = yaml.load(open(args.config)) + channels = [] + for channel in config['channels']: + channels.append('#' + channel['name']) + + access_level = None + for level, names in config['global'].items(): + if args.nick in names: + access_level = level + if access_level is None: + raise Exception("Unable to determine global access level for %s" % + args.nick) + flags = config['access'][access_level] + + a = CheckAccess(channels, args.nick, flags) + mynick = ''.join(random.choice(string.ascii_uppercase) + for x in range(16)) + port = int(args.port) + if port == 6697: + factory = irc.connection.Factory(wrapper=ssl.wrap_socket) + a.connect(args.server, int(args.port), mynick, + connect_factory=factory) + else: + a.connect(args.server, int(args.port), mynick) + a.start() + +if __name__ == "__main__": + main() diff --git a/tools/check_projects_yaml_alphabetized.sh b/tools/check_projects_yaml_alphabetized.sh index 87beb69598..040a8342cd 100755 --- a/tools/check_projects_yaml_alphabetized.sh +++ b/tools/check_projects_yaml_alphabetized.sh @@ -7,7 +7,7 @@ export TMPDIR=`/bin/mktemp -d` trap "rm -rf $TMPDIR" EXIT pushd $TMPDIR -PROJECTS_LIST=$OLDPWD/modules/openstack_project/files/review.projects.yaml +PROJECTS_LIST=$OLDPWD/$1 sed -e '/^- project: /!d' -e 's/^- project: //' $PROJECTS_LIST > projects_list diff --git a/tools/run-compare-xml.sh b/tools/run-compare-xml.sh index 8663f161ad..40b3cae2b9 100755 --- a/tools/run-compare-xml.sh +++ b/tools/run-compare-xml.sh @@ -32,11 +32,11 @@ GITHEAD=`git rev-parse HEAD` # First generate output from HEAD~1 git checkout HEAD~1 -cp modules/openstack_project/files/jenkins_job_builder/config/* .test/jenkins-job-builder/.test/old/config +cp jenkins/jobs/* .test/jenkins-job-builder/.test/old/config # Then use that as a reference to compare against HEAD git checkout $GITHEAD -cp modules/openstack_project/files/jenkins_job_builder/config/* .test/jenkins-job-builder/.test/new/config +cp jenkins/jobs/* .test/jenkins-job-builder/.test/new/config cd .test/jenkins-job-builder diff --git a/tools/run-layout.sh b/tools/run-layout.sh index 0d3cb1343e..2bc626a518 100755 --- a/tools/run-layout.sh +++ b/tools/run-layout.sh @@ -24,7 +24,7 @@ mkdir -p .test/new/config mkdir -p .test/new/out cd ../.. -cp modules/openstack_project/files/jenkins_job_builder/config/* .test/jenkins-job-builder/.test/new/config +cp jenkins/jobs/* .test/jenkins-job-builder/.test/new/config cd .test/jenkins-job-builder tox -e compare-xml-new @@ -32,4 +32,4 @@ cd .. find jenkins-job-builder/.test/new/out/ -printf "%f\n" > job-list.txt cd zuul -tox -e venv -- zuul-server -c etc/zuul.conf-sample -l ../../modules/openstack_project/files/zuul/layout.yaml -t ../job-list.txt +tox -e venv -- zuul-server -c etc/zuul.conf-sample -l ../../zuul/layout.yaml -t ../job-list.txt diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000000..ce1f798e38 --- /dev/null +++ b/tox.ini @@ -0,0 +1,51 @@ +[tox] +minversion = 1.6 +envlist = pep8,upstream,projects_alphabetized +skipsdist = True + +[testenv] +deps = -r{toxinidir}/test-requirements.txt + +[testenv:pep8] +commands = flake8 + +[testenv:projects] +deps = PyYAML +commands = + {toxinidir}/tools/check_upstream_url_scheme.py gerrit/projects.yaml + {toxinidir}/tools/check_projects_yaml_alphabetized.sh gerrit/projects.yaml + +[testenv:venv] +commands = {posargs} + +[testenv:docs] +commands = python setup.py build_sphinx + +[testenv:irc] +deps = PyYAML + irc +commands = python tools/check_irc_access.py -l accessbot/channels.yaml openstackinfra + +[flake8] +show-source = True +exclude = .tox +ignore = E125,H +select = H231 + +[testenv:jjb] +basepython = python2.7 +deps = jenkins-job-builder +commands = + rm -rf {envdir}/tmp + mkdir -p {envdir}/tmp + jenkins-jobs -l debug test -o {envdir}/tmp jenkins/jobs + +[testenv:zuul] +basepython = python2.7 +deps = +commands = + {toxinidir}/tools/check_projects_yaml_alphabetized.sh + {toxinidir}/tools/run-layout.sh openstack-infra config + +[testenv:bashate] +commands = bashate -v diff --git a/zuul/layout.yaml b/zuul/layout.yaml index 4bc49dfa33..99513d4707 100644 --- a/zuul/layout.yaml +++ b/zuul/layout.yaml @@ -595,9 +595,8 @@ jobs: - name: gate-jenkins-job-builder-python33 voting: false - name: gate-config-irc-access - voting: false files: - - 'modules/openstack_project/files/accessbot/channels.yaml' + - 'accessbot/channels.yaml' - name: check-tripleo-ironic-overcloud-precise-ha voting: false # Continous publishing from master of the following documentation targets: