class TestToggleRundeckLock(asynctest.TestCase): def setUp(self): patcher1 = patch('charlesbot_rundeck.rundeck_lock.RundeckLock.seed_job_list') # NOQA self.addCleanup(patcher1.stop) self.mock_seed_job_list = patcher1.start() from charlesbot_rundeck.rundeck_lock import RundeckLock self.rd_lock = RundeckLock("token", "url", "channel", []) self.rd_lock.rundeck_jobs = [RundeckJob(friendly_name="job1")] self.rd_lock.populate_slack_user_object = CoroutineMock() self.rd_lock.slack.send_channel_message = CoroutineMock() self.rd_lock.lock_or_unlock_rundeck_job = CoroutineMock() self.rd_lock.set_channel_topic = CoroutineMock() self.rd_lock.print_lock_status = CoroutineMock() self.sm = SlackMessage(user="******", channel="C001") self.su = SlackUser(name="suser", is_admin=True) def test_unauthorized_user(self): self.su.is_admin = False self.rd_lock.populate_slack_user_object.side_effect = [self.su] yield from self.rd_lock.toggle_rundeck_lock(self.sm, True) calls = [ call("C001", "Sorry <@suser>, you are not allowed to lock Rundeck executions.") # NOQA ] self.assertEqual(self.rd_lock.slack.send_channel_message.mock_calls, calls) def test_authorized_user_unlock(self): self.rd_lock.populate_slack_user_object.side_effect = [self.su] yield from self.rd_lock.toggle_rundeck_lock(self.sm, False) self.assertEqual(self.rd_lock.set_channel_topic.mock_calls, [call(False)]) send_channel_msg_calls = [ call("C001", ":white_check_mark: Rundeck executions unlocked! :white_check_mark:") # NOQA ] self.assertEqual(self.rd_lock.slack.send_channel_message.mock_calls, send_channel_msg_calls) self.assertEqual(self.rd_lock.print_lock_status.mock_calls, [call(self.sm)]) def test_authorized_user_lock(self): self.rd_lock.populate_slack_user_object.side_effect = [self.su] yield from self.rd_lock.toggle_rundeck_lock(self.sm, True) self.assertEqual(self.rd_lock.set_channel_topic.mock_calls, [call(True)]) send_channel_msg_calls = [ call("C001", ":lock: Rundeck executions locked by <@suser> :lock:") ] self.assertEqual(self.rd_lock.slack.send_channel_message.mock_calls, send_channel_msg_calls) self.assertEqual(self.rd_lock.print_lock_status.mock_calls, [call(self.sm)])
class Rundeck(BasePlugin): def __init__(self): super().__init__("Rundeck") self.load_config() def load_config(self): # pragma: no cover config_dict = configuration.get() self.rundeck_token = config_dict['rundeck']['token'] self.rundeck_url = config_dict['rundeck']['url'] try: # It's okay if this key isn't set self.topic_channel = config_dict['rundeck']['deployment_status_channel'] # NOQA except KeyError: self.topic_channel = None self.rd_jobs_raw_list = config_dict['rundeck']['lock_jobs'] self.rundeck_lock = RundeckLock(self.rundeck_token, self.rundeck_url, self.topic_channel, self.rd_jobs_raw_list) def get_help_message(self): help_msg = [] help_msg.append("!lock status - Prints the status of the Rundeck deployment lock") # NOQA help_msg.append("!lock acquire - Acquires the Rundeck deployment lock (only available to Slack admins)") # NOQA help_msg.append("!lock release - Releases the Rundeck deployment lock (only available to Slack admins)") # NOQA return "\n".join(help_msg) @asyncio.coroutine def process_message(self, message): """ Main method that handles all messages sent to this plugin """ if not type(message) is SlackMessage: return parsed_message = parse_msg_with_prefix("!lock", message.text) if not parsed_message: return if does_msg_contain_prefix("acquire", parsed_message): yield from self.rundeck_lock.toggle_rundeck_lock(message, lock_job=True) elif does_msg_contain_prefix("release", parsed_message): yield from self.rundeck_lock.toggle_rundeck_lock(message, lock_job=False) elif does_msg_contain_prefix("status", parsed_message): yield from self.rundeck_lock.print_lock_status(message)