adjutant/adjutant/actions/v1/misc.py

207 lines
6.6 KiB
Python

# Copyright (C) 2016 Catalyst IT Ltd
#
# 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 six
from confspirator import groups
from confspirator import fields
from confspirator import types
from adjutant.actions.v1.base import BaseAction
from adjutant.actions.v1 import serializers
from adjutant.actions.utils import send_email
from adjutant.common import user_store
from adjutant.common import constants
from adjutant.config import CONF
def _build_default_email_group(group_name):
email_group = groups.ConfigGroup(group_name)
email_group.register_child_config(
fields.StrConfig(
"subject",
help_text="Email subject for this stage.",
default="Openstack Email Notification",
)
)
email_group.register_child_config(
fields.StrConfig(
"from",
help_text="From email for this stage.",
regex=constants.EMAIL_WITH_TEMPLATE_REGEX,
default="bounce+%(task_uuid)s@example.com",
)
)
email_group.register_child_config(
fields.StrConfig(
"reply",
help_text="Reply-to email for this stage.",
regex=constants.EMAIL_WITH_TEMPLATE_REGEX,
default="no-reply@example.com",
)
)
email_group.register_child_config(
fields.StrConfig(
"template",
help_text="Email template for this stage. "
"No template will cause the email not to send.",
default=None,
)
)
email_group.register_child_config(
fields.StrConfig(
"html_template",
help_text="Email html template for this stage. "
"No template will cause the email not to send.",
default=None,
)
)
email_group.register_child_config(
fields.BoolConfig(
"email_current_user",
help_text="Email the user who started the task.",
default=False,
)
)
email_group.register_child_config(
fields.BoolConfig(
"email_task_cache",
help_text="Send to an email set in the task cache.",
default=False,
)
)
email_group.register_child_config(
fields.ListConfig(
"email_roles",
help_text="Send emails to the given roles on the project.",
default=[],
)
)
email_group.register_child_config(
fields.ListConfig(
"email_additional_addresses",
help_text="Send emails to an arbitrary admin emails",
item_type=types.String(regex=constants.EMAIL_WITH_TEMPLATE_REGEX),
default=[],
)
)
return email_group
class SendAdditionalEmailAction(BaseAction):
serializer = serializers.SendAdditionalEmailSerializer
config_group = groups.DynamicNameConfigGroup(
children=[
_build_default_email_group("prepare"),
_build_default_email_group("approve"),
_build_default_email_group("submit"),
],
)
def set_email(self, conf):
self.emails = set()
if conf.get("email_current_user"):
self.add_note("Adding the current user's email address")
if CONF.identity.username_is_email:
self.emails.add(self.action.task.keystone_user["username"])
else:
try:
id_manager = user_store.IdentityManager()
email = id_manager.get_user(
self.action.task.keystone_user["user_id"]
).email
self.emails.add(email)
except AttributeError:
self.add_note("Could not add current user email address")
if conf.get("email_roles"):
roles = set(conf.get("email_roles"))
project_id = self.action.task.keystone_user["project_id"]
self.add_note(
"Adding email addresses for roles %s in project %s"
% (roles, project_id)
)
id_manager = user_store.IdentityManager()
users = id_manager.list_users(project_id)
for user in users:
user_roles = [role.name for role in user.roles]
if roles.intersection(user_roles):
if CONF.identity.username_is_email:
self.emails.add(user.name)
else:
self.emails.add(user.email)
if conf.get("email_task_cache"):
task_emails = self.action.task.cache.get("additional_emails", [])
if isinstance(task_emails, six.string_types):
task_emails = [task_emails]
for email in task_emails:
self.emails.add(email)
for email in conf.get("email_additional_addresses"):
self.emails.add(email)
def _validate(self):
self.action.valid = True
self.action.save()
def _prepare(self):
self.perform_action("prepare")
def _approve(self):
self.perform_action("approve")
def _submit(self, token_data, keystone_user=None):
self.perform_action("submit")
def perform_action(self, stage):
self._validate()
task = self.action.task
for action in task.actions:
if not action.valid:
return
email_conf = self.config.get(stage)
# If either of these are false we won't be sending anything.
if not email_conf or not email_conf.get("template"):
return
self.set_email(email_conf)
if not self.emails:
self.add_note(self.emails)
self.add_note("Email address not set. Stage: %s" % stage)
return
self.add_note("Sending emails to: %s" % self.emails)
actions = {}
for action in task.actions:
act = action.get_action()
actions[str(act)] = act
context = {"task": task, "actions": actions}
result = send_email(self.emails, context, email_conf, task)
if not result:
self.add_note("Unable to send additional email. Stage: %s" % stage)
else:
self.add_note("Additional email sent. Stage: %s" % stage)