diff --git a/.zuul.yaml b/.zuul.yaml index aa9e053bb7..1a9042e11e 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -230,6 +230,37 @@ vars: *haproxy-statsd_vars files: *haproxy-statsd_files +# accessbot jobs +- job: + name: system-config-build-image-accessbot + description: Build a accessbot image. + parent: system-config-build-image + requires: python-base-3.7-container-image + provides: accessbot-container-image + vars: &accessbot_vars + docker_images: + - context: docker/accessbot + repository: opendevorg/accessbot + files: &accessbot_files + - docker/accessbot/ + - docker/python-base/ + +- job: + name: system-config-upload-image-accessbot + description: Build and upload a accessbot image. + parent: system-config-upload-image + requires: python-base-3.7-container-image + provides: accessbot-container-image + vars: *accessbot_vars + files: *accessbot_files + +- job: + name: system-config-promote-image-accessbot + description: Promote a previously published accessbot image to latest. + parent: system-config-promote-image + vars: *accessbot_vars + files: *accessbot_files + # Gerrit 2.13 jobs - job: name: system-config-build-image-gerrit-2.13 @@ -1078,22 +1109,36 @@ - job: name: system-config-run-eavesdrop - parent: system-config-run + parent: system-config-run-containers description: | Run the playbook for an eavesdrop server. + required-projects: + - opendev/system-config + - openstack/project-config + requires: accessbot-container-image nodeset: nodes: - name: bridge.openstack.org label: ubuntu-bionic - name: eavesdrop01.openstack.org label: ubuntu-xenial - files: - - playbooks/install-ansible.yaml - - playbooks/group_vars/eavesdrop.yaml - - testinfra/test_eavesdrop.py vars: run_playbooks: - - playbooks/remote_puppet_else.yaml + - playbooks/service-eavesdrop.yaml + files: + - playbooks/service-eavesdrop.yaml + - playbooks/run-accessbot.yaml + - playbooks/group_vars/eavesdrop.yaml + - playbooks/roles/zuul-user + - playbooks/roles/install-docker + - playbooks/roles/puppet-install/ + - playbooks/roles/disable-puppet-agent/ + - playbooks/roles/accessbot + - playbooks/roles/logrotate + - modules/openstack_project/manifests/eavesdrop.pp + - manifests/eavesdrop.pp + - docker/accessbot/ + - testinfra/test_eavesdrop.py - job: name: system-config-run-codesearch @@ -1620,7 +1665,6 @@ required-projects: - opendev/system-config - opendev/ansible-role-puppet - - opendev/puppet-accessbot - opendev/puppet-ansible - opendev/puppet-apparmor - opendev/puppet-askbot @@ -1799,7 +1843,6 @@ - opendev/puppet-snmpd - opendev/puppet-user - opendev/puppet-jeepyb - - opendev/puppet-accessbot - opendev/puppet-ptgbot - opendev/puppet-jenkins - opendev/puppet-vcsrepo @@ -1853,7 +1896,6 @@ required-projects: - opendev/ansible-role-puppet - openstack/logstash-filters - - opendev/puppet-accessbot - opendev/puppet-ansible - opendev/puppet-askbot - opendev/puppet-asterisk @@ -2376,6 +2418,52 @@ - modules/openstack_project/files/resync-hound-config.sh - manifests/codesearch.pp +- job: + name: infra-prod-service-eavesdrop + parent: infra-prod-service-base + description: Run service-eavesdrop.yaml playbook + required-projects: + - opendev/system-config + - openstack/project-config + dependencies: + - name: infra-prod-install-ansible + soft: true + - name: infra-prod-base + soft: true + - name: infra-prod-service-letsencrypt + soft: true + - name: system-config-promote-image-accessbot + soft: true + vars: + playbook_name: service-eavesdrop.yaml + files: &infra_prod_eavesdrop_files + - inventory/ + - playbooks/service-eavesdrop.yaml + - playbooks/run-accessbot.yaml + - playbooks/group_vars/eavesdrop.yaml + - playbooks/roles/zuul-user + - playbooks/roles/install-docker + - playbooks/roles/puppet-install/ + - playbooks/roles/disable-puppet-agent/ + - playbooks/roles/accessbot + - playbooks/roles/logrotate + - modules/openstack_project/manifests/eavesdrop.pp + - manifests/eavesdrop.pp + - docker/accessbot/ + +- job: + name: infra-prod-run-accessbot + parent: infra-prod-service-base + description: Run run-accessbot.yaml playbook + required-projects: + - opendev/system-config + - openstack/project-config + dependencies: + - infra-prod-service-eavesdrop + vars: + playbook_name: run-accessbot.yaml + files: *infra_prod_eavesdrop_files + # Run AFS changes separately so we can make sure to only do one at a time # (turns out quorum is nice to have) - job: @@ -2626,7 +2714,11 @@ voting: false - system-config-run-backup - system-config-run-dns - - system-config-run-eavesdrop + - system-config-run-eavesdrop: + dependencies: + - name: opendev-buildset-registry + - name: system-config-build-image-accessbot + soft: true - system-config-run-codesearch - system-config-run-lists - system-config-run-nodepool @@ -2677,6 +2769,11 @@ - name: opendev-buildset-registry - name: system-config-build-image-python-base-3.7 soft: true + - system-config-build-image-accessbot: + dependencies: + - name: opendev-buildset-registry + - name: system-config-build-image-python-base-3.7 + soft: true - system-config-build-image-python-base-3.7 - system-config-build-image-python-base-3.8 - system-config-build-image-python-builder-3.7 @@ -2693,7 +2790,11 @@ - tox-linters - system-config-run-base - system-config-run-dns - - system-config-run-eavesdrop + - system-config-run-eavesdrop: + dependencies: + - name: opendev-buildset-registry + - name: system-config-upload-image-accessbot + soft: true - system-config-run-codesearch - system-config-run-lists - system-config-run-nodepool @@ -2744,6 +2845,11 @@ - name: opendev-buildset-registry - name: system-config-upload-image-python-base-3.7 soft: true + - system-config-upload-image-accessbot: + dependencies: + - name: opendev-buildset-registry + - name: system-config-build-image-python-base-3.7 + soft: true - system-config-upload-image-python-base-3.7 - system-config-upload-image-python-base-3.8 - system-config-upload-image-python-builder-3.7 @@ -2761,6 +2867,7 @@ - system-config-promote-image-etherpad - system-config-promote-image-jitsi-meet - system-config-promote-image-haproxy-statsd + - system-config-promote-image-accessbot - system-config-promote-image-python-base-3.7 - system-config-promote-image-python-base-3.8 - system-config-promote-image-python-builder-3.7 @@ -2812,6 +2919,7 @@ - infra-prod-service-review-dev - infra-prod-service-gitea - infra-prod-service-codesearch + - infra-prod-service-eavesdrop - infra-prod-remote-puppet-afs - infra-prod-remote-puppet-else periodic: @@ -2843,6 +2951,8 @@ - infra-prod-service-review-dev - infra-prod-service-gitea - infra-prod-service-codesearch + - infra-prod-service-eavesdrop + - infra-prod-run-accessbot - infra-prod-remote-puppet-afs opendev-prod-hourly: jobs: @@ -2863,3 +2973,7 @@ dependencies: - name: infra-prod-install-ansible soft: true + - infra-prod-run-accessbot: + dependencies: + - name: infra-prod-install-ansible + soft: true diff --git a/docker/accessbot/Dockerfile b/docker/accessbot/Dockerfile new file mode 100644 index 0000000000..c8c6c94a31 --- /dev/null +++ b/docker/accessbot/Dockerfile @@ -0,0 +1,21 @@ +# Copyright (c) 2020 Red Hat, Inc. +# +# 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. + +FROM docker.io/opendevorg/python-base:3.7 + +RUN pip install pyyaml irc +COPY accessbot.py /usr/local/bin/accessbot.py +COPY accessbot.sh /usr/local/bin/accessbot +CMD ["/usr/local/bin/accessbot", "-c", "/etc/accessbot/accessbot.config", "-l", "/etc/accessbot/channels.yaml", ">>", "]] diff --git a/docker/accessbot/accessbot.py b/docker/accessbot/accessbot.py new file mode 100755 index 0000000000..1eefdd2a55 --- /dev/null +++ b/docker/accessbot/accessbot.py @@ -0,0 +1,248 @@ +#! /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( + format='%(asctime)s [%(levelname)s] %(name)s - %(message)s', + 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 + # Prejoin and set ourselves as op in these channels, + # to facilitate +f forwarding. + for channel in self.config.get('op_channels', []): + c.join("#%s" % channel) + c.privmsg("chanserv", "op #%s" % channel) + 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 = {} + alumni = [] + mode = '' + 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 + if access == 'alumni': + alumni += nicks + continue + if access == 'mode': + mode = nicks + continue + flags = self.config['access'].get(access) + if flags is None: + continue + for nick in nicks: + ret[nick] = flags + return mask, ret, alumni, mode + + 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, alumni, mode = 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() + global_alumni = self.config.get('alumni', {}) + global_mode = self.config.get('mode', '') + current = {} + changes = [] + for nick, flags, msg in self.current_list: + if nick in global_alumni or nick in alumni : + self.log.debug("%s is an alumni; removing access", nick) + changes.append('access #%s del %s' % (self.current_channel, nick)) + continue + 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)) + + # Set the mode. Note we always just hard-set the mode for + # simplicity (per the man page mlock always clears and sets + # anyway). Channel mode overrides global mode. + # + # Note for +f you need to be op in the target channel; see + # op_channel option. + if not mode and global_mode: + mode = global_mode + self.log.debug("Setting mode to : %s" % mode) + if mode: + changes.append('set #%s mlock %s' % (self.current_channel, mode)) + + 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/docker/accessbot/accessbot.sh b/docker/accessbot/accessbot.sh new file mode 100755 index 0000000000..a3c0dee424 --- /dev/null +++ b/docker/accessbot/accessbot.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# Copyright (c) 2020 Red Hat, Inc. +# +# 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. + +exec python /usr/local/bin/accessbot.py -c /etc/accessbot/accessbot.config -l /etc/accessbot/channels.yaml >> /var/log/accessbot/accessbot.log 2>&1 diff --git a/manifests/eavesdrop.pp b/manifests/eavesdrop.pp new file mode 100644 index 0000000000..7e8b33bfea --- /dev/null +++ b/manifests/eavesdrop.pp @@ -0,0 +1,30 @@ +# Node-OS: xenial +node /^eavesdrop\d*\.open.*\.org$/ { + $group = "eavesdrop" + class { 'openstack_project::eavesdrop': + nickpass => hiera('openstack_meetbot_password'), + statusbot_nick => hiera('statusbot_nick', 'username'), + statusbot_password => hiera('statusbot_nick_password'), + statusbot_server => 'chat.freenode.net', + statusbot_channels => hiera_array('statusbot_channels', ['openstack_infra']), + statusbot_auth_nicks => hiera_array('statusbot_auth_nicks'), + statusbot_wiki_user => hiera('statusbot_wiki_username', 'username'), + statusbot_wiki_password => hiera('statusbot_wiki_password'), + statusbot_wiki_url => 'https://wiki.openstack.org/w/api.php', + # https://wiki.openstack.org/wiki/Infrastructure_Status + statusbot_wiki_pageid => '1781', + statusbot_wiki_successpageid => '7717', + statusbot_wiki_successpageurl => 'https://wiki.openstack.org/wiki/Successes', + statusbot_wiki_thankspageid => '37700', + statusbot_wiki_thankspageurl => 'https://wiki.openstack.org/wiki/Thanks', + statusbot_irclogs_url => 'http://eavesdrop.openstack.org/irclogs/%(chan)s/%(chan)s.%(date)s.log.html', + statusbot_twitter => true, + statusbot_twitter_key => hiera('statusbot_twitter_key'), + statusbot_twitter_secret => hiera('statusbot_twitter_secret'), + statusbot_twitter_token_key => hiera('statusbot_twitter_token_key'), + statusbot_twitter_token_secret => hiera('statusbot_twitter_token_secret'), + meetbot_channels => hiera('meetbot_channels', ['openstack-infra']), + ptgbot_nick => hiera('ptgbot_nick', 'username'), + ptgbot_password => hiera('ptgbot_password'), + } +} diff --git a/manifests/site.pp b/manifests/site.pp index dd547d62c7..1f7025e4ac 100644 --- a/manifests/site.pp +++ b/manifests/site.pp @@ -86,42 +86,6 @@ node /planet\d*\.open.*\.org$/ { } } -# Node-OS: xenial -node /^eavesdrop\d*\.open.*\.org$/ { - $group = "eavesdrop" - class { 'openstack_project::server': } - - class { 'openstack_project::eavesdrop': - project_config_repo => 'https://opendev.org/openstack/project-config', - nickpass => hiera('openstack_meetbot_password'), - statusbot_nick => hiera('statusbot_nick', 'username'), - statusbot_password => hiera('statusbot_nick_password'), - statusbot_server => 'chat.freenode.net', - statusbot_channels => hiera_array('statusbot_channels', ['openstack_infra']), - statusbot_auth_nicks => hiera_array('statusbot_auth_nicks'), - statusbot_wiki_user => hiera('statusbot_wiki_username', 'username'), - statusbot_wiki_password => hiera('statusbot_wiki_password'), - statusbot_wiki_url => 'https://wiki.openstack.org/w/api.php', - # https://wiki.openstack.org/wiki/Infrastructure_Status - statusbot_wiki_pageid => '1781', - statusbot_wiki_successpageid => '7717', - statusbot_wiki_successpageurl => 'https://wiki.openstack.org/wiki/Successes', - statusbot_wiki_thankspageid => '37700', - statusbot_wiki_thankspageurl => 'https://wiki.openstack.org/wiki/Thanks', - statusbot_irclogs_url => 'http://eavesdrop.openstack.org/irclogs/%(chan)s/%(chan)s.%(date)s.log.html', - statusbot_twitter => true, - statusbot_twitter_key => hiera('statusbot_twitter_key'), - statusbot_twitter_secret => hiera('statusbot_twitter_secret'), - statusbot_twitter_token_key => hiera('statusbot_twitter_token_key'), - statusbot_twitter_token_secret => hiera('statusbot_twitter_token_secret'), - accessbot_nick => hiera('accessbot_nick', 'username'), - accessbot_password => hiera('accessbot_nick_password'), - meetbot_channels => hiera('meetbot_channels', ['openstack-infra']), - ptgbot_nick => hiera('ptgbot_nick', 'username'), - ptgbot_password => hiera('ptgbot_password'), - } -} - # Node-OS: xenial node /^ethercalc\d+\.open.*\.org$/ { $group = "ethercalc" diff --git a/modules.env b/modules.env index 339921b133..a18515d3ed 100644 --- a/modules.env +++ b/modules.env @@ -63,7 +63,6 @@ SOURCE_MODULES["https://github.com/voxpupuli/puppet-nodejs"]="v2.3.0" # Add modules that should be part of the openstack-infra integration test here # Please keep sorted -INTEGRATION_MODULES["$OPENSTACK_GIT_ROOT/opendev/puppet-accessbot"]="origin/master" INTEGRATION_MODULES["$OPENSTACK_GIT_ROOT/opendev/puppet-ansible"]="origin/master" INTEGRATION_MODULES["$OPENSTACK_GIT_ROOT/opendev/puppet-askbot"]="origin/master" INTEGRATION_MODULES["$OPENSTACK_GIT_ROOT/opendev/puppet-asterisk"]="origin/master" diff --git a/modules/openstack_project/manifests/eavesdrop.pp b/modules/openstack_project/manifests/eavesdrop.pp index 94d46b7ded..590bf6f032 100644 --- a/modules/openstack_project/manifests/eavesdrop.pp +++ b/modules/openstack_project/manifests/eavesdrop.pp @@ -21,9 +21,6 @@ class openstack_project::eavesdrop ( $statusbot_twitter_secret = '', $statusbot_twitter_token_key = '', $statusbot_twitter_token_secret = '', - $accessbot_nick = '', - $accessbot_password = '', - $project_config_repo = '', $meetbot_channels = [], $ptgbot_nick = '', $ptgbot_password = '', @@ -83,36 +80,16 @@ class openstack_project::eavesdrop ( } } - class { 'project_config': - url => $project_config_repo, - } - - class { 'accessbot': - nick => $accessbot_nick, - password => $accessbot_password, - server => $statusbot_server, - channel_file => $::project_config::accessbot_channels_yaml, - require => $::project_config::config_dir, - } - - # Needed to allow Jenkins jobs to publish meeting info to - # the eavesdrop server. - include openstack_project - class { 'jenkins::jenkinsuser': - ssh_key => $openstack_project::jenkins_ssh_key, - } - file { '/srv/yaml2ical': ensure => directory, - owner => 'jenkins', - group => 'jenkins', - require => User['jenkins'], + owner => 'zuul', + group => 'zuul', } file { '/srv/yaml2ical/calendars': ensure => directory, - owner => 'jenkins', - group => 'jenkins', + owner => 'zuul', + group => 'zuul', require => File['/srv/yaml2ical'], } diff --git a/playbooks/group_vars/eavesdrop.yaml b/playbooks/group_vars/eavesdrop.yaml index 2ff4864007..32466de1d6 100644 --- a/playbooks/group_vars/eavesdrop.yaml +++ b/playbooks/group_vars/eavesdrop.yaml @@ -1,2 +1,5 @@ iptables_extra_public_tcp_ports: - 80 +zuul_user_authorized_key: | + ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDcXd/QJDEprSLh6N6bULnhchf9M+uzYBEJ2b51Au67FON+5M6VEj5Ut+DlkEPhabOP+tSv9Cn1HpmpBjdEOXdmBj6JS7G/gBb4w28oZDyNjrPT2ebpRw/XnVEkGfikR2J+j3o7CV+ybhLDalXm2TUDReVXnONUq3YzZbjRzoYs0xxrxyss47vZP0xFpsAt9jCMAJW2k6H589VUY38k9LFyhZUZ72FB6eJ68B9GN0TimBYm2DqvupBGQrRhkP8OZ0WoBV8PulKXaHVFdmfBNHB7E7FLlZKuiM6nkV4bOWMGOB/TF++wXBK86t9po3pWCM7+kr72xGRTE+6LuZ2z1K+h zuul-system-config-20180924 + ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDQbidZ1wW8moNtPGBhZ3oDm1kcDtiAemI51euL6KZslwpG8CKMT0KBSYw1vpCYc5dYCerq63dQtg2Bm1rhc2gC/U2bbMlvnNPwlkS7eykVfrPDfJHVbff+qHv7l1e1ZoCVAEvVxXG/FgFUiqIKwEhMqG/Etegw07H7vERNETGE5RyRA8cMnK9Cj4oL0OUpZAv7o1a+A+gXRv1EMdWL7g9M6OImikO48w+ZSLOA8uD+0MmN23nh335k2VG609u+ZxTkZAB4GtW0HSCTFu5MCmJFaY1+5cCNedsC9O4ekaXNQxYelFxasN5Qe7miRWcR+Ax8g3HjHpG3Hc1LSc/6XVcj zuul-project-config-20180924 diff --git a/playbooks/remote_puppet_else.yaml b/playbooks/remote_puppet_else.yaml index e014c7abc1..2cd6f64354 100644 --- a/playbooks/remote_puppet_else.yaml +++ b/playbooks/remote_puppet_else.yaml @@ -1,4 +1,4 @@ -- hosts: 'puppet:!review:!afs:!afsdb:!puppetmaster*:!nb*:!codesearch:!disabled' +- hosts: 'puppet:!review:!afs:!afsdb:!puppetmaster*:!nb*:!codesearch:!eavesdrop:!disabled' name: "Puppet-else: run puppet on all other servers" strategy: free roles: diff --git a/playbooks/roles/accessbot/README.rst b/playbooks/roles/accessbot/README.rst new file mode 100644 index 0000000000..51890381ba --- /dev/null +++ b/playbooks/roles/accessbot/README.rst @@ -0,0 +1 @@ +Set up accessbot diff --git a/playbooks/roles/accessbot/files/accessbot b/playbooks/roles/accessbot/files/accessbot new file mode 100644 index 0000000000..f21506ee4c --- /dev/null +++ b/playbooks/roles/accessbot/files/accessbot @@ -0,0 +1,20 @@ +#!/bin/bash +# Copyright 2020 Red Hat, Inc. +# +# 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. + +exec docker run --rm --net=host \ + -v/etc/accessbot:/etc/accessbot \ + -v/var/log/accessbot:/var/log/accessbot \ + docker.io/opendevorg/accessbot diff --git a/playbooks/roles/accessbot/tasks/main.yaml b/playbooks/roles/accessbot/tasks/main.yaml new file mode 100644 index 0000000000..08beff9dad --- /dev/null +++ b/playbooks/roles/accessbot/tasks/main.yaml @@ -0,0 +1,36 @@ +- name: Install accessbot script + copy: + src: accessbot + dest: /usr/local/bin/accessbot + mode: 0755 + +- name: Ensure accessbot log dir + file: + path: /var/log/accessbot + state: directory + +- name: Ensure config dir + file: + path: /etc/accessbot + state: directory + +- name: Install accessbot config + template: + src: accessbot.config.j2 + dest: /etc/accessbot/accessbot.config + mode: 0440 + +- name: Copy accessbot channel config + copy: + remote_src: true + src: /opt/project-config/accessbot/channels.yaml + dest: /etc/accessbot/channels.yaml + +- name: Setup log rotation + include_role: + name: logrotate + vars: + logrotate_file_name: /var/log/accessbot/accessbot.log + +- name: Pull latest image + command: docker pull docker.io/opendevorg/accessbot diff --git a/playbooks/roles/accessbot/templates/accessbot.config.j2 b/playbooks/roles/accessbot/templates/accessbot.config.j2 new file mode 100644 index 0000000000..365124d4e6 --- /dev/null +++ b/playbooks/roles/accessbot/templates/accessbot.config.j2 @@ -0,0 +1,5 @@ +[ircbot] +nick={{ accessbot_nick }} +pass={{ accessbot_nick_password }} +server=chat.freenode.net +port=6697 diff --git a/playbooks/roles/set-hostname b/playbooks/roles/set-hostname new file mode 120000 index 0000000000..93e5683c7d --- /dev/null +++ b/playbooks/roles/set-hostname @@ -0,0 +1 @@ +../../roles/set-hostname/ \ No newline at end of file diff --git a/playbooks/roles/zuul-user/README.rst b/playbooks/roles/zuul-user/README.rst index 7d50612520..aa7e15d56a 100644 --- a/playbooks/roles/zuul-user/README.rst +++ b/playbooks/roles/zuul-user/README.rst @@ -9,3 +9,8 @@ Install a user ``zuul`` that has the per-project key from :default: False Enable passwordless ``sudo`` access for the zuul user. + +.. zuul:rolevar:: zuul_user_authorized_key + :default: per-project key from system-config + + Authorized key content for the zuul user. diff --git a/playbooks/roles/zuul-user/defaults/main.yaml b/playbooks/roles/zuul-user/defaults/main.yaml index 993dcd6c72..aa878a7b52 100644 --- a/playbooks/roles/zuul-user/defaults/main.yaml +++ b/playbooks/roles/zuul-user/defaults/main.yaml @@ -1 +1,4 @@ -zuul_user_enable_sudo: False \ No newline at end of file +zuul_user_enable_sudo: False +# Zuul key from https://zuul.opendev.org/api/tenant/openstack/project-ssh-key/opendev/system-config.pub at 2020-02-26 +zuul_user_authorized_key: | + ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDcXd/QJDEprSLh6N6bULnhchf9M+uzYBEJ2b51Au67FON+5M6VEj5Ut+DlkEPhabOP+tSv9Cn1HpmpBjdEOXdmBj6JS7G/gBb4w28oZDyNjrPT2ebpRw/XnVEkGfikR2J+j3o7CV+ybhLDalXm2TUDReVXnONUq3YzZbjRzoYs0xxrxyss47vZP0xFpsAt9jCMAJW2k6H589VUY38k9LFyhZUZ72FB6eJ68B9GN0TimBYm2DqvupBGQrRhkP8OZ0WoBV8PulKXaHVFdmfBNHB7E7FLlZKuiM6nkV4bOWMGOB/TF++wXBK86t9po3pWCM7+kr72xGRTE+6LuZ2z1K+h diff --git a/playbooks/roles/zuul-user/tasks/main.yaml b/playbooks/roles/zuul-user/tasks/main.yaml index 2334d133b2..dc7079f215 100644 --- a/playbooks/roles/zuul-user/tasks/main.yaml +++ b/playbooks/roles/zuul-user/tasks/main.yaml @@ -17,6 +17,4 @@ authorized_key: user: zuul state: present - key: | - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDcXd/QJDEprSLh6N6bULnhchf9M+uzYBEJ2b51Au67FON+5M6VEj5Ut+DlkEPhabOP+tSv9Cn1HpmpBjdEOXdmBj6JS7G/gBb4w28oZDyNjrPT2ebpRw/XnVEkGfikR2J+j3o7CV+ybhLDalXm2TUDReVXnONUq3YzZbjRzoYs0xxrxyss47vZP0xFpsAt9jCMAJW2k6H589VUY38k9LFyhZUZ72FB6eJ68B9GN0TimBYm2DqvupBGQrRhkP8OZ0WoBV8PulKXaHVFdmfBNHB7E7FLlZKuiM6nkV4bOWMGOB/TF++wXBK86t9po3pWCM7+kr72xGRTE+6LuZ2z1K+h - comment: Zuul key from https://zuul.opendev.org/api/tenant/openstack/project-ssh-key/opendev/system-config.pub at 2020-02-26 + key: '{{ zuul_user_authorized_key }}' diff --git a/playbooks/run-accessbot.yaml b/playbooks/run-accessbot.yaml new file mode 100644 index 0000000000..7f73aa84a8 --- /dev/null +++ b/playbooks/run-accessbot.yaml @@ -0,0 +1,5 @@ +- hosts: 'eavesdrop:!disabled' + name: "eavesdrop: run accessbot" + tasks: + - name: Run accessbot + command: /usr/local/bin/accessbot diff --git a/playbooks/service-eavesdrop.yaml b/playbooks/service-eavesdrop.yaml new file mode 100644 index 0000000000..9f6af287b4 --- /dev/null +++ b/playbooks/service-eavesdrop.yaml @@ -0,0 +1,12 @@ +- hosts: 'eavesdrop:!disabled' + name: "eavesdrop: run puppet on eavesdrop" + strategy: free + roles: + - zuul-user + - sync-project-config + - install-docker + - accessbot + - puppet-install + - disable-puppet-agent + - name: puppet + manifest: /opt/system-config/production/manifests/eavesdrop.pp diff --git a/playbooks/set-hostnames.yaml b/playbooks/set-hostnames.yaml index 4134d2b718..7ea9c9106a 100644 --- a/playbooks/set-hostnames.yaml +++ b/playbooks/set-hostnames.yaml @@ -1,5 +1,4 @@ - hosts: "!disabled" gather_facts: false - user: root roles: - set-hostname diff --git a/playbooks/zuul/run-base-pre.yaml b/playbooks/zuul/run-base-pre.yaml index 70b11424de..af0c3980b6 100644 --- a/playbooks/zuul/run-base-pre.yaml +++ b/playbooks/zuul/run-base-pre.yaml @@ -4,6 +4,7 @@ - multi-node-known-hosts - copy-build-sshkey - use-docker-mirror + - set-hostname tasks: - include_role: name: use-buildset-registry diff --git a/playbooks/zuul/run-base.yaml b/playbooks/zuul/run-base.yaml index 0c708932f2..2a09de3667 100644 --- a/playbooks/zuul/run-base.yaml +++ b/playbooks/zuul/run-base.yaml @@ -45,6 +45,7 @@ loop: - group_vars/all.yaml - group_vars/adns.yaml + - group_vars/eavesdrop.yaml - group_vars/nodepool.yaml - group_vars/ns.yaml - group_vars/registry.yaml @@ -91,8 +92,6 @@ dest: /home/zuul/src/opendev.org/opendev/system-config/playbooks/host_vars/bridge.openstack.org.yaml become: true - - name: Set hostname on host - command: ansible-playbook -v /home/zuul/src/opendev.org/opendev/system-config/playbooks/set-hostnames.yaml - name: Run base.yaml command: ansible-playbook -v /home/zuul/src/opendev.org/opendev/system-config/playbooks/base.yaml - name: Run bridge service playbook diff --git a/playbooks/zuul/templates/group_vars/eavesdrop.yaml.j2 b/playbooks/zuul/templates/group_vars/eavesdrop.yaml.j2 new file mode 100644 index 0000000000..8ca4039908 --- /dev/null +++ b/playbooks/zuul/templates/group_vars/eavesdrop.yaml.j2 @@ -0,0 +1,11 @@ +openstack_meetbot_password: password +statusbot_nick_password: password +statusbot_wiki_password: password +statusbot_twitter_key: twitter_key +statusbot_twitter_secret: twitter_secret +statusbot_twitter_token_key: token_key +statusbot_twitter_token_secret: token_secret +accessbot_nick: username +accessbot_nick_password: password +ptgbot_password: password +access_bot_install_only: true diff --git a/playbooks/roles/set-hostname/README.rst b/roles/set-hostname/README.rst similarity index 100% rename from playbooks/roles/set-hostname/README.rst rename to roles/set-hostname/README.rst diff --git a/playbooks/roles/set-hostname/tasks/main.yml b/roles/set-hostname/tasks/main.yml similarity index 91% rename from playbooks/roles/set-hostname/tasks/main.yml rename to roles/set-hostname/tasks/main.yml index bf27c1f3fb..8246cec03d 100644 --- a/playbooks/roles/set-hostname/tasks/main.yml +++ b/roles/set-hostname/tasks/main.yml @@ -3,6 +3,7 @@ # nodes, but not on the minimal ones we get from # nodepool. - name: ensure dbus for working hostnamectl + become: true apt: name: dbus state: present @@ -12,10 +13,13 @@ # https://github.com/ansible/ansible/pull/8482) # https://gist.github.com/rothgar/8793800 - name: Set /etc/hostname + become: true hostname: name="{{ inventory_hostname.split('.', 1)[0] }}" - name: Set /etc/hosts + become: true template: src=hosts.j2 dest=/etc/hosts mode=0644 - name: Set /etc/mailname + become: true template: src=mailname.j2 dest=/etc/mailname mode=0644 diff --git a/playbooks/roles/set-hostname/templates/hosts.j2 b/roles/set-hostname/templates/hosts.j2 similarity index 100% rename from playbooks/roles/set-hostname/templates/hosts.j2 rename to roles/set-hostname/templates/hosts.j2 diff --git a/playbooks/roles/set-hostname/templates/mailname.j2 b/roles/set-hostname/templates/mailname.j2 similarity index 100% rename from playbooks/roles/set-hostname/templates/mailname.j2 rename to roles/set-hostname/templates/mailname.j2