Esempio n. 1
0
class NewDefaultNetworkAction(BaseAction, ProjectMixin):
    """
    This action will setup all required basic networking
    resources so that a new user can launch instances
    right away.
    """

    required = [
        "setup_network",
        "project_id",
        "region",
    ]

    serializer = serializers.NewDefaultNetworkSerializer

    config_group = groups.DynamicNameConfigGroup(
        children=[
            groups.ConfigGroup(
                "region_defaults",
                children=[
                    fields.StrConfig(
                        "network_name",
                        help_text="Name to be given to the default network.",
                        default="default_network",
                    ),
                    fields.StrConfig(
                        "subnet_name",
                        help_text="Name to be given to the default subnet.",
                        default="default_subnet",
                    ),
                    fields.StrConfig(
                        "router_name",
                        help_text="Name to be given to the default router.",
                        default="default_router",
                    ),
                    fields.StrConfig(
                        "public_network",
                        help_text="ID of the public network.",
                    ),
                    fields.StrConfig(
                        "subnet_cidr",
                        help_text="CIDR for the default subnet.",
                    ),
                    fields.ListConfig(
                        "dns_nameservers",
                        help_text="DNS nameservers for the subnet.",
                    ),
                ],
            ),
            fields.DictConfig(
                "regions",
                help_text="Specific per region config for default network. "
                "See 'region_defaults'.",
                default={},
            ),
        ]
    )

    def __init__(self, *args, **kwargs):
        super(NewDefaultNetworkAction, self).__init__(*args, **kwargs)

    def _validate_region(self):
        if not self.region:
            self.add_note("ERROR: No region given.")
            return False

        id_manager = user_store.IdentityManager()
        region = id_manager.get_region(self.region)
        if not region:
            self.add_note("ERROR: Region does not exist.")
            return False

        self.add_note("Region: %s exists." % self.region)
        return True

    def _validate(self):
        self.action.valid = validate_steps(
            [
                self._validate_region,
                self._validate_project_id,
                self._validate_keystone_user_project_id,
            ]
        )
        self.action.save()

    def _create_network(self):
        neutron = openstack_clients.get_neutronclient(region=self.region)
        try:
            region_config = self.config.regions[self.region]
            network_config = self.config.region_defaults.overlay(region_config)
        except KeyError:
            network_config = self.config.region_defaults

        if not self.get_cache("network_id"):
            try:
                network_body = {
                    "network": {
                        "name": network_config.network_name,
                        "tenant_id": self.project_id,
                        "admin_state_up": True,
                    }
                }
                network = neutron.create_network(body=network_body)
            except Exception as e:
                self.add_note(
                    "Error: '%s' while creating network: %s"
                    % (e, network_config.network_name)
                )
                raise
            self.set_cache("network_id", network["network"]["id"])
            self.add_note(
                "Network %s created for project %s"
                % (network_config.network_name, self.project_id)
            )
        else:
            self.add_note(
                "Network %s already created for project %s"
                % (network_config.network_name, self.project_id)
            )

        if not self.get_cache("subnet_id"):
            try:
                subnet_body = {
                    "subnet": {
                        "network_id": self.get_cache("network_id"),
                        "ip_version": 4,
                        "tenant_id": self.project_id,
                        "dns_nameservers": network_config.dns_nameservers,
                        "cidr": network_config.subnet_cidr,
                    }
                }
                subnet = neutron.create_subnet(body=subnet_body)
            except Exception as e:
                self.add_note("Error: '%s' while creating subnet" % e)
                raise
            self.set_cache("subnet_id", subnet["subnet"]["id"])
            self.add_note("Subnet created for network %s" % network_config.network_name)
        else:
            self.add_note(
                "Subnet already created for network %s" % network_config.network_name
            )

        if not self.get_cache("router_id"):
            try:
                router_body = {
                    "router": {
                        "name": network_config.router_name,
                        "external_gateway_info": {
                            "network_id": network_config.public_network
                        },
                        "tenant_id": self.project_id,
                        "admin_state_up": True,
                    }
                }
                router = neutron.create_router(body=router_body)
            except Exception as e:
                self.add_note(
                    "Error: '%s' while creating router: %s"
                    % (e, network_config.router_name)
                )
                raise
            self.set_cache("router_id", router["router"]["id"])
            self.add_note("Router created for project %s" % self.project_id)
        else:
            self.add_note("Router already created for project %s" % self.project_id)

        if not self.get_cache("port_id"):
            try:
                interface_body = {"subnet_id": self.get_cache("subnet_id")}
                interface = neutron.add_interface_router(
                    self.get_cache("router_id"), body=interface_body
                )
            except Exception as e:
                self.add_note("Error: '%s' while attaching interface" % e)
                raise
            self.set_cache("port_id", interface["port_id"])
            self.add_note("Interface added to router for subnet")
        else:
            self.add_note("Interface added to router for project %s" % self.project_id)

    def _prepare(self):
        # Note: Do we need to get this from cache? it is a required setting
        # self.project_id = self.action.task.cache.get('project_id', None)
        self._validate()

    def _approve(self):
        self._validate()

        if self.setup_network and self.valid:
            self._create_network()

    def _submit(self, token_data, keystone_user=None):
        pass
Esempio n. 2
0
config_group.register_child_config(
    fields.ListConfig(
        "active_delegate_apis",
        help_text="List of Active Delegate APIs.",
        required=True,
        default=[
            "UserRoles",
            "UserDetail",
            "UserResetPassword",
            "UserList",
            "RoleList",
        ],
        # NOTE(adriant): for testing purposes we include ALL default APIs
        test_default=[
            "UserRoles",
            "UserDetail",
            "UserResetPassword",
            "UserList",
            "RoleList",
            "SignUp",
            "UpdateProjectQuotas",
            "CreateProjectAndUser",
            "InviteUser",
            "ResetPassword",
            "EditUser",
            "UpdateEmail",
        ],
    ))

delegate_apis_group = groups.ConfigGroup("delegate_apis", lazy_load=True)
Esempio n. 3
0
        group_name="completed",
        email_subject="Task Completed",
        email_reply="*****@*****.**",
        email_from="bounce+%(task_uuid)[email protected]",
        email_template="completed.txt",
        email_html_template=None,
    ))

_notifications_defaults_group = groups.ConfigGroup("notifications")
_task_defaults_group.register_child_config(_notifications_defaults_group)

_notifications_defaults_group.register_child_config(
    fields.ListConfig(
        "standard_handlers",
        help_text="Handlers to use for standard notifications.",
        required=True,
        default=[
            "EmailNotification",
        ],
    ))
_notifications_defaults_group.register_child_config(
    fields.ListConfig(
        "error_handlers",
        help_text="Handlers to use for error notifications.",
        required=True,
        default=[
            "EmailNotification",
        ],
    ))
_notifications_defaults_group.register_child_config(
    fields.DictConfig(
        "standard_handler_config",
Esempio n. 4
0
def make_task_config(task_class):

    config_group = groups.DynamicNameConfigGroup()
    config_group.register_child_config(
        fields.BoolConfig(
            "allow_auto_approve",
            help_text="Override if this task allows auto_approval. "
            "Otherwise uses task default.",
            default=task_class.allow_auto_approve,
        ))
    config_group.register_child_config(
        fields.ListConfig(
            "additional_actions",
            help_text="Additional actions to be run as part of the task "
            "after default actions.",
            default=task_class.additional_actions or [],
        ))
    config_group.register_child_config(
        fields.IntConfig(
            "token_expiry",
            help_text="Override for the task token expiry. "
            "Otherwise uses task default.",
            default=task_class.token_expiry,
        ))
    config_group.register_child_config(
        fields.DictConfig(
            "actions",
            help_text="Action config overrides over the action defaults. "
            "See 'adjutant.workflow.action_defaults'.",
            is_json=True,
            default=task_class.action_config or {},
            sample_default={
                "SomeCustomAction": {
                    "some_action_setting": "<a-uuid-probably>"
                }
            },
        ))
    config_group.register_child_config(
        fields.DictConfig(
            "emails",
            help_text="Email config overrides for this task over task defaults."
            "See 'adjutant.workflow.emails'.",
            is_json=True,
            default=task_class.email_config or {},
            sample_default={
                "initial": None,
                "token": {
                    "subject": "Some custom subject",
                },
            },
        ))
    config_group.register_child_config(
        fields.DictConfig(
            "notifications",
            help_text=
            "Notification config overrides for this task over task defaults."
            "See 'adjutant.workflow.notifications'.",
            is_json=True,
            default=task_class.notification_config or {},
            sample_default={
                "standard_handlers": ["EmailNotification"],
                "error_handlers": ["EmailNotification"],
                "standard_handler_config": {
                    "EmailNotification": {
                        "emails": ["*****@*****.**"],
                        "reply": "*****@*****.**",
                    }
                },
                "error_handler_config": {
                    "EmailNotification": {
                        "emails": ["*****@*****.**"],
                        "reply": "*****@*****.**",
                    }
                },
            },
        ))
    return config_group
Esempio n. 5
0
}

config_group = groups.ConfigGroup("quota")

config_group.register_child_config(
    fields.DictConfig(
        "sizes",
        help_text=
        "A definition of the quota size groups that Adjutant should use.",
        value_type=types.Dict(value_type=types.Dict()),
        check_value_type=True,
        is_json=True,
        default=DEFAULT_QUOTA_SIZES,
    ))
config_group.register_child_config(
    fields.ListConfig(
        "sizes_ascending",
        help_text="An ascending list of all the quota size names, "
        "so that Adjutant knows their relative sizes/order.",
        default=["small", "medium", "large"],
    ))
config_group.register_child_config(
    fields.DictConfig(
        "services",
        help_text=
        "A per region definition of what services Adjutant should manage "
        "quotas for. '*' means all or default region.",
        value_type=types.List(),
        default={"*": ["cinder", "neutron", "nova"]},
    ))
Esempio n. 6
0
class EmailNotification(base.BaseNotificationHandler):
    """
    Basic email notification handler. Will
    send an email with the given templates.
    """

    config_group = groups.DynamicNameConfigGroup(children=[
        fields.ListConfig(
            "emails",
            help_text="List of email addresses to send this notification to.",
            item_type=types.String(regex=constants.EMAIL_REGEX),
            default=[],
        ),
        fields.StrConfig(
            "from",
            help_text="From email for this notification.",
            regex=constants.EMAIL_WITH_TEMPLATE_REGEX,
            sample_default="bounce+%(task_uuid)[email protected]",
        ),
        fields.StrConfig(
            "reply",
            help_text="Reply-to email for this notification.",
            regex=constants.EMAIL_REGEX,
            sample_default="*****@*****.**",
        ),
        fields.StrConfig(
            "template",
            help_text="Email template for this notification. "
            "No template will cause the email not to send.",
            default="notification.txt",
        ),
        fields.StrConfig(
            "html_template",
            help_text="Email html template for this notification.",
        ),
    ])

    def _notify(self, task, notification):
        conf = self.config(task, notification)
        if not conf or not conf["emails"]:
            # Log that we did this!!
            note = ("Skipped sending notification for task: %s (%s) "
                    "as notification handler conf is None, or no emails "
                    "were configured." % (task.task_type, task.uuid))
            self.logger.info("(%s) - %s" % (timezone.now(), note))
            return

        template = loader.get_template(conf["template"],
                                       using="include_etc_templates")
        html_template = conf["html_template"]
        if html_template:
            html_template = loader.get_template(html_template,
                                                using="include_etc_templates")

        context = {"task": task, "notification": notification}

        if CONF.workflow.horizon_url:
            task_url = CONF.workflow.horizon_url
            notification_url = CONF.workflow.horizon_url
            if not task_url.endswith("/"):
                task_url += "/"
            if not notification_url.endswith("/"):
                notification_url += "/"
            task_url += "management/tasks/%s" % task.uuid
            notification_url += "management/notifications/%s" % notification.uuid
            context["task_url"] = task_url
            context["notification_url"] = notification_url

        if notification.error:
            subject = "Error - %s notification" % task.task_type
        else:
            subject = "%s notification" % task.task_type
        try:
            message = template.render(context)

            # from_email is the return-path and is distinct from the
            # message headers
            from_email = conf["from"]
            if not from_email:
                from_email = conf["reply"]
            elif "%(task_uuid)s" in from_email:
                from_email = from_email % {"task_uuid": task.uuid}

            # these are the message headers which will be visible to
            # the email client.
            headers = {
                "X-Adjutant-Task-UUID": task.uuid,
                # From needs to be set to be disctinct from return-path
                "From": conf["reply"],
                "Reply-To": conf["reply"],
            }

            email = EmailMultiAlternatives(subject,
                                           message,
                                           from_email,
                                           conf["emails"],
                                           headers=headers)

            if html_template:
                email.attach_alternative(html_template.render(context),
                                         "text/html")

            email.send(fail_silently=False)
            notification.acknowledged = True
            notification.save()
        except SMTPException as e:
            notes = {
                "errors":
                [("Error: '%s' while sending email notification") % e]
            }
            error_notification = Notification.objects.create(
                task=notification.task, notes=notes, error=True)
            error_notification.save()
Esempio n. 7
0
        default="Do not ever use this awful secret in prod!!!!",
        secret=True,
        unsafe_default=True,
    ))
config_group.register_child_config(
    fields.BoolConfig(
        "debug",
        help_text="Django debug mode is turned on.",
        default=False,
        unsafe_default=True,
    ))
config_group.register_child_config(
    fields.ListConfig(
        "allowed_hosts",
        help_text="The Django allowed hosts",
        required=True,
        default=["*"],
        unsafe_default=True,
    ))
config_group.register_child_config(
    fields.StrConfig(
        "secure_proxy_ssl_header",
        help_text="The header representing a HTTP header/value combination "
        "that signifies a request is secure.",
        default="HTTP_X_FORWARDED_PROTO",
    ))
config_group.register_child_config(
    fields.StrConfig(
        "secure_proxy_ssl_header_value",
        help_text="The value representing a HTTP header/value combination "
        "that signifies a request is secure.",
Esempio n. 8
0
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)[email protected]",
        ))
    email_group.register_child_config(
        fields.StrConfig(
            "reply",
            help_text="Reply-to email for this stage.",
            regex=constants.EMAIL_WITH_TEMPLATE_REGEX,
            default="*****@*****.**",
        ))
    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
Esempio n. 9
0
class UserList(tasks.InviteUser):

    url = r"^openstack/users/?$"

    config_group = groups.DynamicNameConfigGroup(
        children=[
            fields.ListConfig(
                "blacklisted_roles",
                help_text="Users with any of these roles will be hidden from the user list.",
                default=[],
                sample_default=["admin"],
            ),
        ]
    )

    @utils.mod_or_admin
    def get(self, request):
        """Get a list of all users who have been added to a project"""
        class_conf = self.config
        blacklisted_roles = class_conf.blacklisted_roles

        user_list = []
        id_manager = user_store.IdentityManager()
        project_id = request.keystone_user["project_id"]
        project = id_manager.get_project(project_id)

        can_manage_roles = id_manager.get_manageable_roles(
            request.keystone_user["roles"]
        )

        active_emails = set()
        for user in id_manager.list_users(project):
            skip = False
            roles = []
            for role in user.roles:
                if role.name in blacklisted_roles:
                    skip = True
                    continue
                roles.append(role.name)
            if skip:
                continue
            inherited_roles = []
            for role in user.inherited_roles:
                if role.name in blacklisted_roles:
                    skip = True
                    continue
                inherited_roles.append(role.name)
            if skip:
                continue

            email = getattr(user, "email", "")
            enabled = user.enabled
            user_status = "Active" if enabled else "Account Disabled"
            active_emails.add(email)
            user_list.append(
                {
                    "id": user.id,
                    "name": user.name,
                    "email": email,
                    "roles": roles,
                    "inherited_roles": inherited_roles,
                    "cohort": "Member",
                    "status": user_status,
                    "manageable": set(can_manage_roles).issuperset(roles),
                }
            )

        for user in id_manager.list_inherited_users(project):
            skip = False
            roles = []
            for role in user.roles:
                if role.name in blacklisted_roles:
                    skip = True
                    continue
                roles.append(role.name)
            if skip:
                continue

            email = getattr(user, "email", "")
            enabled = user.enabled
            user_status = "Active" if enabled else "Account Disabled"
            user_list.append(
                {
                    "id": user.id,
                    "name": user.name,
                    "email": email,
                    "roles": roles,
                    "inherited_roles": [],
                    "cohort": "Inherited",
                    "status": user_status,
                    "manageable": False,
                }
            )

        # Get my active tasks for this project:
        project_tasks = models.Task.objects.filter(
            project_id=project_id,
            task_type="invite_user_to_project",
            completed=0,
            cancelled=0,
        )

        registrations = []
        for task in project_tasks:
            status = "Invited"
            for token in task.tokens:
                if token.expired:
                    status = "Expired"

            for notification in task.notifications:
                if notification.error:
                    status = "Failed"

            for action in task.actions:
                if not action.valid:
                    status = "Invalid"

            task_data = {}
            for action in task.actions:
                task_data.update(action.action_data)

            registrations.append(
                {"uuid": task.uuid, "task_data": task_data, "status": status}
            )

        for task in registrations:
            # NOTE(adriant): commenting out for now as it causes more confusion
            # than it helps. May uncomment once different duplication checking
            # measures are in place.
            # if task['task_data']['email'] not in active_emails:
            user = {
                "id": task["uuid"],
                "name": task["task_data"]["email"],
                "email": task["task_data"]["email"],
                "roles": task["task_data"]["roles"],
                "inherited_roles": task["task_data"]["inherited_roles"],
                "cohort": "Invited",
                "status": task["status"],
            }
            if not CONF.identity.username_is_email:
                user["name"] = task["task_data"]["username"]

            user_list.append(user)

        return Response({"users": user_list})
Esempio n. 10
0
class UserRoles(BaseDelegateAPI):

    url = r"^openstack/users/(?P<user_id>\w+)/roles/?$"

    config_group = groups.DynamicNameConfigGroup(
        children=[
            fields.ListConfig(
                "blacklisted_roles",
                help_text="User with these roles will return not found.",
                default=[],
                sample_default=["admin"],
            ),
        ]
    )

    task_type = "edit_user_roles"

    @utils.mod_or_admin
    def get(self, request, user_id):
        """ Get role info based on the user id. """
        id_manager = user_store.IdentityManager()
        user = id_manager.get_user(user_id)

        no_user = {"errors": ["No user with this id."]}
        if not user:
            return Response(no_user, status=404)

        project_id = request.keystone_user["project_id"]
        project = id_manager.get_project(project_id)

        class_conf = self.config
        blacklisted_roles = class_conf.blacklisted_roles

        roles = [role.name for role in id_manager.get_roles(user, project)]
        roles_blacklisted = set(blacklisted_roles) & set(roles)
        inherited_roles = [
            role.name for role in id_manager.get_roles(user, project, True)
        ]
        inherited_roles_blacklisted = set(blacklisted_roles) & set(inherited_roles)

        if not roles or roles_blacklisted or inherited_roles_blacklisted:
            return Response(no_user, status=404)
        return Response({"roles": roles, "inherited_roles": inherited_roles})

    @utils.mod_or_admin
    def put(self, args, **kwargs):
        """ Add user roles to the current project. """
        kwargs["remove_role"] = False
        return self._edit_user(args, **kwargs)

    @utils.mod_or_admin
    def delete(self, args, **kwargs):
        """Revoke user roles to the current project.

        This only supports Active users
        """
        kwargs["remove_role"] = True
        return self._edit_user(args, **kwargs)

    def _edit_user(self, request, user_id, remove_role=False, format=None):
        """ Helper function to add or remove roles from a user """
        request.data["remove"] = remove_role
        if "project_id" not in request.data:
            request.data["project_id"] = request.keystone_user["project_id"]
        request.data["user_id"] = user_id

        self.logger.info(
            "(%s) - New EditUser %s request." % (timezone.now(), request.method)
        )

        self.task_manager.create_from_request(self.task_type, request)

        return Response({"notes": ["task created"]}, status=202)
Esempio n. 11
0
class UserDetail(BaseDelegateAPI):

    url = r"^openstack/users/(?P<user_id>\w+)/?$"

    config_group = groups.DynamicNameConfigGroup(
        children=[
            fields.ListConfig(
                "blacklisted_roles",
                help_text="User with these roles will return not found.",
                default=[],
                sample_default=["admin"],
            ),
        ]
    )

    @utils.mod_or_admin
    def get(self, request, user_id):
        """
        Get user info based on the user id.

        Will only find users in your project.
        """
        id_manager = user_store.IdentityManager()
        user = id_manager.get_user(user_id)

        no_user = {"errors": ["No user with this id."]}
        if not user:
            return Response(no_user, status=404)

        class_conf = self.config
        blacklisted_roles = class_conf.blacklisted_roles

        project_id = request.keystone_user["project_id"]
        project = id_manager.get_project(project_id)

        roles = [role.name for role in id_manager.get_roles(user, project)]
        roles_blacklisted = set(blacklisted_roles) & set(roles)
        inherited_roles = [
            role.name for role in id_manager.get_roles(user, project, True)
        ]
        inherited_roles_blacklisted = set(blacklisted_roles) & set(inherited_roles)

        if not roles or roles_blacklisted or inherited_roles_blacklisted:
            return Response(no_user, status=404)
        return Response(
            {
                "id": user.id,
                "username": user.name,
                "email": getattr(user, "email", ""),
                "roles": roles,
                "inherited_roles": inherited_roles,
            }
        )

    @utils.mod_or_admin
    def delete(self, request, user_id):
        """
        Remove this user from the project.
        This may cancel a pending user invite, or simply revoke roles.
        """
        id_manager = user_store.IdentityManager()
        user = id_manager.get_user(user_id)
        project_id = request.keystone_user["project_id"]
        # NOTE(dale): For now, we only support cancelling pending invites.
        if user:
            return Response(
                {
                    "errors": [
                        "Revoking keystone users not implemented. "
                        "Try removing all roles instead."
                    ]
                },
                status=501,
            )
        project_tasks = models.Task.objects.filter(
            project_id=project_id,
            task_type="invite_user_to_project",
            completed=0,
            cancelled=0,
        )
        for task in project_tasks:
            if task.uuid == user_id:
                self.task_manager.cancel(task)
                return Response("Cancelled pending invite task!", status=200)
        return Response("Not found.", status=404)
Esempio n. 12
0
class ResetUserPasswordAction(UserNameAction, UserMixin):
    """
    Simple action to reset a password for a given user.
    """

    required = ["domain_name", "username", "email"]

    serializer = serializers.ResetUserPasswordSerializer

    config_group = groups.DynamicNameConfigGroup(
        children=[
            fields.ListConfig(
                "blacklisted_roles",
                help_text="Users with these roles cannot reset their passwords.",
                default=[],
                sample_default=["admin"],
            ),
        ],
    )

    def __init__(self, *args, **kwargs):
        super(ResetUserPasswordAction, self).__init__(*args, **kwargs)

    def _validate_user_roles(self):
        id_manager = user_store.IdentityManager()

        roles = id_manager.get_all_roles(self.user)

        user_roles = []
        for roles in roles.values():
            user_roles.extend(role.name for role in roles)

        if set(self.config.blacklisted_roles) & set(user_roles):
            self.add_note("Cannot reset users with blacklisted roles.")
            return False

        return True

    def _validate_user_email(self):
        # NOTE(adriant): We only need to check the USERNAME_IS_EMAIL=False
        # case since '_validate_username_exists' will ensure the True case
        if not CONF.identity.username_is_email:
            if self.user and (
                getattr(self.user, "email", None).lower() != self.email.lower()
            ):
                self.add_note("Existing user with non-matching email.")
                return False

        self.action.need_token = True
        self.set_token_fields(["password"])
        self.add_note("Existing user with matching email.")
        return True

    def _validate(self):
        # Here, the order of validation matters
        # as each one adds new class variables
        self.action.valid = validate_steps(
            [
                self._validate_domain_name,
                self._validate_username_exists,
                self._validate_user_roles,
                self._validate_user_email,
            ]
        )
        self.action.save()

    def _prepare(self):
        self._validate()
        self.set_auto_approve()

    def _approve(self):
        self._validate()

    def _submit(self, token_data, keystone_user=None):
        self._validate()

        if not self.valid:
            return

        self.update_password(token_data["password"])
        self.add_note("User %s password has been changed." % self.username)
Esempio n. 13
0
class MocNewProjectAction(base.MocBaseAction):
    """Creates a new project for the current authenticated user."""

    required = [
        'project_name',
        'description',
        'domain_id',

        # TODO(knikolla): It should be possible to fetch these from
        # SSO once we support OAuth 2.0 access tokens.
        'organization',
        'organization_role',
        'services',
        'phone',
        'moc_contact',
    ]

    serializer = serializers.MocNewProjectSerializer

    config_group = config_groups.DynamicNameConfigGroup(children=[
        config_fields.ListConfig(
            "default_roles",
            help_text="Roles to be given on project to the creating user.",
            default=["member", "project_admin"],
            sample_default=["member", "project_admin"]),
        config_fields.ListConfig(
            "enabled_services",
            help_text="Other services configured in the cloud.",
            default=['openshift'],
        ),
    ], )

    def _validate_project_name(self):
        # Make sure project id doesn't exist.
        project = self.identity.find_project(self.project_name, self.domain_id)
        if project:
            return False
        return True

    def _validate_services(self):
        for service in self.services:
            if service not in self.config.enabled_services:
                return False
        return True

    def _get_email(self):
        return self.action.task.keystone_user['username']

    def write_to_approve_journal(self):
        user_ref = self._get_user()
        project_ref = {
            'name': self.project_name,
            'domain_id': self.domain_id,
            'description': self.description,
            'organization': self.organization,
            'owner': self._get_email(),
        }
        self.approve_journal.append(
            operations.CreateProjectOperation(self.services, project_ref))
        self.approve_journal.append(
            operations.AddUserToProjectOperation(self.services, user_ref,
                                                 project_ref,
                                                 self.config.default_roles))

    def write_to_submit_journal(self, token_data):
        pass