From bfee17bb52d762d0cbce16bdb468048c97850b42 Mon Sep 17 00:00:00 2001 From: "Elizabeth K. Joseph" Date: Wed, 28 Jan 2015 10:46:29 -0800 Subject: [PATCH] Split out accessbot module Change-Id: Ic1c894d3567e9590bd450e9fe942f7dc0c6701d6 --- modules.env | 1 + modules/accessbot/files/accessbot.py | 214 ------------------ modules/accessbot/files/checkaccess.py | 154 ------------- modules/accessbot/manifests/init.pp | 82 ------- .../accessbot/templates/accessbot.config.erb | 5 - 5 files changed, 1 insertion(+), 455 deletions(-) delete mode 100755 modules/accessbot/files/accessbot.py delete mode 100755 modules/accessbot/files/checkaccess.py delete mode 100644 modules/accessbot/manifests/init.pp delete mode 100644 modules/accessbot/templates/accessbot.config.erb diff --git a/modules.env b/modules.env index 77c00b1e33..ebf541c012 100644 --- a/modules.env +++ b/modules.env @@ -56,6 +56,7 @@ SOURCE_MODULES["https://github.com/puppet-community/puppet-module-puppetboard"]= # Add modules that should be part of the openstack-infra integration test here +INTEGRATION_MODULES["https://git.openstack.org/openstack-infra/puppet-accessbot"]="origin/master" INTEGRATION_MODULES["https://git.openstack.org/openstack-infra/puppet-ansible"]="origin/master" INTEGRATION_MODULES["https://git.openstack.org/openstack-infra/puppet-asterisk"]="origin/master" INTEGRATION_MODULES["https://git.openstack.org/openstack-infra/puppet-bup"]="origin/master" diff --git a/modules/accessbot/files/accessbot.py b/modules/accessbot/files/accessbot.py deleted file mode 100755 index 6f657a59fb..0000000000 --- a/modules/accessbot/files/accessbot.py +++ /dev/null @@ -1,214 +0,0 @@ -#! /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 ConfigParser -import argparse -import irc.client -import logging -import ssl -import sys -import time -import yaml - -logging.basicConfig(level=logging.DEBUG) - - -class SetAccess(irc.client.SimpleIRCClient): - log = logging.getLogger("setaccess") - - def __init__(self, config, noop, nick, password, server, port): - irc.client.SimpleIRCClient.__init__(self) - self.identify_msg_cap = False - self.config = config - self.nick = nick - self.password = password - self.server = server - self.port = int(port) - self.noop = noop - self.channels = [x['name'] for x in self.config['channels']] - self.current_channel = None - self.current_list = [] - self.changes = [] - self.identified = False - if self.port == 6697: - factory = irc.connection.Factory(wrapper=ssl.wrap_socket) - self.connect(self.server, self.port, self.nick, - connect_factory=factory) - else: - self.connect(self.server, self.port, self.nick) - - def on_disconnect(self, connection, event): - 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.log.debug("Identifying to nickserv") - c.privmsg("nickserv", "identify %s " % self.password) - - 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 == '+' and nick == 'NickServ' and not self.identified: - if msg.startswith('You are now identified'): - self.identified = True - self.advance() - return - if auth != '+' or nick != 'ChanServ': - self.log.debug("Ignoring message from unauthenticated " - "user %s" % nick) - return - self.failed = False - self.advance(msg) - - def _get_access_list(self, channel_name): - ret = {} - channel = None - for c in self.config['channels']: - if c['name'] == channel_name: - channel = c - if channel is None: - raise Exception("Unknown channel %s" % (channel_name,)) - mask = '' - for access, nicks in (self.config['global'].items() + - channel.items()): - if access == 'mask': - mask = self.config['access'].get(nicks) - continue - flags = self.config['access'].get(access) - if flags is None: - continue - for nick in nicks: - ret[nick] = flags - return mask, ret - - def _get_access_change(self, current, target, mask): - remove = '' - add = '' - change = '' - for x in current: - if x in '+-': - continue - if target: - if x not in target: - remove += x - else: - if x not in mask: - remove += x - for x in target: - if x in '+-': - continue - if x not in current: - add += x - if remove: - change += '-' + remove - if add: - change += '+' + add - return change - - def _get_access_changes(self): - mask, target = self._get_access_list(self.current_channel) - self.log.debug("Mask for %s: %s" % (self.current_channel, mask)) - self.log.debug("Target for %s: %s" % (self.current_channel, target)) - all_nicks = set() - current = {} - changes = [] - for nick, flags, msg in self.current_list: - all_nicks.add(nick) - current[nick] = flags - for nick in target.keys(): - all_nicks.add(nick) - for nick in all_nicks: - change = self._get_access_change(current.get(nick, ''), - target.get(nick, ''), mask) - if change: - changes.append('access #%s add %s %s' % (self.current_channel, - nick, change)) - return changes - - def advance(self, msg=None): - if self.changes: - if self.noop: - for change in self.changes: - self.log.info('NOOP: ' + change) - self.changes = [] - else: - change = self.changes.pop() - self.log.info(change) - self.connection.privmsg('chanserv', change) - time.sleep(1) - return - 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'): - self.changes = self._get_access_changes() - self.current_channel = None - self.advance() - return - parts = msg.split() - if parts[2].startswith('+'): - self.current_list.append((parts[1], parts[2], msg)) - - -def main(): - parser = argparse.ArgumentParser(description='IRC channel access check') - parser.add_argument('-c', dest='config', nargs=1, - help='specify the config file') - parser.add_argument('-l', dest='channels', - default='/etc/irc/channels.yaml', - help='path to the channel config') - parser.add_argument('--noop', dest='noop', - action='store_true', - help="Don't make any changes") - args = parser.parse_args() - - config = ConfigParser.ConfigParser() - config.read(args.config) - - channels = yaml.load(open(args.channels)) - - a = SetAccess(channels, args.noop, - config.get('ircbot', 'nick'), - config.get('ircbot', 'pass'), - config.get('ircbot', 'server'), - config.get('ircbot', 'port')) - a.start() - - -if __name__ == "__main__": - main() diff --git a/modules/accessbot/files/checkaccess.py b/modules/accessbot/files/checkaccess.py deleted file mode 100755 index 40384043fa..0000000000 --- a/modules/accessbot/files/checkaccess.py +++ /dev/null @@ -1,154 +0,0 @@ -#! /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/modules/accessbot/manifests/init.pp b/modules/accessbot/manifests/init.pp deleted file mode 100644 index 800b8f4d7e..0000000000 --- a/modules/accessbot/manifests/init.pp +++ /dev/null @@ -1,82 +0,0 @@ -# == Class: accessbot -# -class accessbot( - $nick = '', - $password = '', - $server = '', - $channel_file = '', -) { - - user { 'accessbot': - ensure => present, - home => '/home/accessbot', - shell => '/bin/bash', - gid => 'accessbot', - managehome => true, - require => Group['accessbot'], - } - - group { 'accessbot': - ensure => present, - } - - # A lot of things need yaml, be conservative requiring this package to avoid - # conflicts with other modules. - if ! defined(Package['python-yaml']) { - package { 'python-yaml': - ensure => present, - } - } - - exec { 'run_accessbot' : - command => '/usr/local/bin/accessbot -c /etc/accessbot/accessbot.config -l /etc/accessbot/channels.yaml >> /var/log/accessbot/accessbot.log 2>&1', - path => '/usr/local/bin:/usr/bin:/bin/', - user => 'accessbot', - refreshonly => true, - subscribe => File['/etc/accessbot/channels.yaml'], - require => [File['/etc/accessbot/channels.yaml'], - File['/etc/accessbot/accessbot.config'], - File['/usr/local/bin/accessbot']], - } - - file { '/etc/accessbot': - ensure => directory, - } - - file { '/var/log/accessbot': - ensure => directory, - owner => 'accessbot', - group => 'accessbot', - mode => '0775', - require => User['accessbot'], - } - - file { '/etc/accessbot/accessbot.config': - ensure => present, - content => template('accessbot/accessbot.config.erb'), - group => 'accessbot', - mode => '0440', - owner => 'root', - replace => true, - require => User['accessbot'], - } - - file { '/etc/accessbot/channels.yaml': - ensure => present, - source => $channel_file, - group => 'accessbot', - mode => '0440', - owner => 'root', - replace => true, - require => User['accessbot'], - } - - file { '/usr/local/bin/accessbot': - ensure => present, - source => 'puppet:///modules/accessbot/accessbot.py', - mode => '0555', - owner => 'root', - group => 'root', - replace => true, - } -} diff --git a/modules/accessbot/templates/accessbot.config.erb b/modules/accessbot/templates/accessbot.config.erb deleted file mode 100644 index a11ea48a5d..0000000000 --- a/modules/accessbot/templates/accessbot.config.erb +++ /dev/null @@ -1,5 +0,0 @@ -[ircbot] -nick=<%= nick %> -pass=<%= password %> -server=<%= server %> -port=6697