Beispiel #1
0
class MocProjects(base.MocBaseApi):
    """
    API Endpoint for applying, or listing accessible projects.
    """

    url = r'^moc/Projects/?$'
    task_type = 'moc_create_project'

    config_group = config_groups.DynamicNameConfigGroup(
        children=[
            config_fields.BoolConfig(
                'create_default_network',
                help_text='If set to faulse, overrides what is in setup_network.',
                default=True,
                sample_default=True,
            ),
            config_fields.StrConfig(
                'region',
                help_text='Region for creating default network and quota.',
                default='RegionOne',
                sample_default='RegionOne'
            ),
            config_fields.StrConfig(
                "project_domain_id",
                help_text="Domain id for projects.",
                default="default",
                sample_default="Default"
            ),
        ]
    )

    @utils.authenticated
    def post(self, request, format=None):
        request.data['email'] = request.keystone_user['username']
        request.data['region'] = self.config['region']
        request.data['domain_id'] = self.config['project_domain_id']

        if not self.config['create_default_network']:
            request.data['setup_network'] = False

        if 'project_name' not in request.data:
            message = 'Missing project_name in request.'
            self.logger.info(message)
            return self.response(message, 400)

        project = self.identity.find_project(
            request.data['project_name'], self.config.project_domain_id)
        if project:
            message = ('Project %s already exists.'
                       % request.data['project_name'])
            self.logger.info(message)
            return self.response_error(message, 409)

        return self.create_task(request)

    @utils.authenticated
    def get(self, request, format=None):
        # List other projects that a user has access to, or has applied for.
        pass
Beispiel #2
0
class CreateProjectAndUser(BaseDelegateAPI):

    url = r"^actions/CreateProjectAndUser/?$"

    config_group = groups.DynamicNameConfigGroup(
        children=[
            fields.StrConfig(
                "default_region",
                help_text="Default region in which any potential resources may be created.",
                required=True,
                default="RegionOne",
            ),
            fields.StrConfig(
                "default_domain_id",
                help_text="Domain in which project and users will be created.",
                default="default",
                required=True,
            ),
            fields.StrConfig(
                "default_parent_id",
                help_text="Parent id under which this project will be created. "
                "Default is None, and will create under default domain.",
                default=None,
            ),
        ]
    )

    task_type = "create_project_and_user"

    def post(self, request, format=None):
        """
        Unauthenticated endpoint bound primarily to NewProjectWithUser.

        This process requires approval, so this will validate
        incoming data and create a task to be approved
        later.
        """
        self.logger.info("(%s) - Starting new project task." % timezone.now())

        class_conf = self.config

        # we need to set the region the resources will be created in:
        request.data["region"] = class_conf.default_region

        # domain
        request.data["domain_id"] = class_conf.default_domain_id

        # parent_id for new project, if null defaults to domain:
        request.data["parent_id"] = class_conf.default_parent_id

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

        return Response({"notes": ["task created"]}, status=202)
Beispiel #3
0
def _build_default_email_group(
    group_name,
    email_subject,
    email_from,
    email_reply,
    email_template,
    email_html_template,
):
    email_group = groups.ConfigGroup(group_name)
    email_group.register_child_config(
        fields.StrConfig(
            "subject",
            help_text="Default email subject for this stage",
            default=email_subject,
        ))
    email_group.register_child_config(
        fields.StrConfig("from",
                         help_text="Default from email for this stage",
                         default=email_from))
    email_group.register_child_config(
        fields.StrConfig(
            "reply",
            help_text="Default reply-to email for this stage",
            default=email_reply,
        ))
    email_group.register_child_config(
        fields.StrConfig(
            "template",
            help_text="Default email template for this stage",
            default=email_template,
        ))
    email_group.register_child_config(
        fields.StrConfig(
            "html_template",
            help_text="Default email html template for this stage",
            default=email_html_template,
        ))
    return email_group
Beispiel #4
0
class MocInviteUserAction(base.MocBaseAction):

    required = [
        'email',
        'project_id',
        'roles',
    ]

    serializer = serializers.MocInviteUserSerializer

    config_group = config_groups.DynamicNameConfigGroup(children=[
        config_fields.StrConfig("user_domain_id",
                                help_text="Domain to create projects in.",
                                default="default",
                                sample_default="Default")
    ])

    def _get_email(self):
        """This is the email where the invitation will be sent."""
        return self.email

    def _prepare(self):
        if not self._validate():
            self.add_note('Validation failed at _prepare')
            return

        self.action.auto_approve = True
        self.action.state = "pending"
        self.action.need_token = True
        self.set_token_fields(["confirm", "user"])

    def validate_token(self, token_data):
        if not self.valid or not token_data.get('confirm'):
            self.add_note('Invitation not valid or not accepted.')
            return False
        return True

    def write_to_approve_journal(self):
        pass

    def write_to_submit_journal(self, token_data):
        project = self.leader_identity.get_project(self.project_id)
        project_ref = {'name': project.name, 'domain_id': project.domain_id}
        services = self.find_services_for_project(project)
        self.submit_journal.append(
            operations.AddUserToProjectOperation(services, token_data['user'],
                                                 project_ref, self.roles))
Beispiel #5
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
Beispiel #6
0
class MailingListSubscribeAction(base.MocBaseAction):

    required = ['email']

    serializer = serializers.MailingListSubscribeSerializer

    config_group = conf_group.DynamicNameConfigGroup(children=[
        conf_field.StrConfig(
            "private_key",
            help_text="Location of private key for mailing list server.",
            default="/.ssh/id_rsa",
            sample_default="/.ssh/id_rsa",
        ),
        conf_field.HostNameConfig(
            "host",
            help_text="Mailing list server host.",
            default="mail.massopen.cloud",
            sample_default="mail.massopen.cloud",
        ),
        conf_field.IntConfig(
            "port",
            help_text="Mailing list server SSH port",
            default=22,
            sample_default=22,
        ),
        conf_field.StrConfig(
            "user",
            help_text="Mailing list server user.",
            default="moc-tools",
            sample_default="moc-tools",
        ),
        conf_field.StrConfig(
            "list",
            help_text="Mailing list to add users to.",
            default="kaizen-users",
            sample_default="kaizen-users",
        ),
    ], )

    def _get_email(self):
        if CONF.identity.username_is_email:
            return self.action.task.keystone_user['username']

    def _approve(self):
        try:
            with Mailman(self.config.host, self.config.port, self.config.user,
                         self.config.private_key) as mailman:
                if mailman.is_already_subscribed(self._get_email(),
                                                 self.config.list):
                    self.add_note('%s already subscribed to mailing list.' %
                                  self._get_email())
                else:
                    mailman.subscribe(self._get_email(), self.config.list)
                    self.add_note(
                        '%s successfully subscribed to mailing list.' %
                        self._get_email())
        except paramiko.ssh_exception.SSHException as e:
            self.add_note('Unable to connect to Mailing List server. '
                          'Proceeding regardless. %s' % str(e))

        self.action.state = 'complete'
        self.action.save()

    def _submit(self, token_data):
        pass
Beispiel #7
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()
Beispiel #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
Beispiel #9
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 confspirator import groups
from confspirator import fields

config_group = groups.ConfigGroup("django")

config_group.register_child_config(
    fields.StrConfig(
        "secret_key",
        help_text="The Django secret key.",
        required=True,
        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,
Beispiel #10
0
            "project_admin": [
                "project_mod",
                "member",
                "heat_stack_owner",
                "project_admin",
            ],
            "project_mod": ["member", "heat_stack_owner", "project_mod"],
        },
    )
)

_auth_group = groups.ConfigGroup("auth")
_auth_group.register_child_config(
    fields.StrConfig(
        "username",
        help_text="Username for Adjutant Keystone admin user.",
        required=True,
        required_for_tests=False,
    )
)
_auth_group.register_child_config(
    fields.StrConfig(
        "password",
        help_text="Password for Adjutant Keystone admin user.",
        required=True,
        secret=True,
        required_for_tests=False,
    )
)
_auth_group.register_child_config(
    fields.StrConfig(
        "project_name",