예제 #1
0
class UpdateProjectQuotasAction(BaseAction, QuotaMixin):
    """ Updates quota for a project to a given size in a list of regions """

    required = [
        "size",
        "project_id",
        "regions",
    ]

    serializer = serializers.UpdateProjectQuotasSerializer

    config_group = groups.DynamicNameConfigGroup(
        children=[
            fields.FloatConfig(
                "size_difference_threshold",
                help_text="Precentage different allowed when matching quota sizes.",
                default=0.1,
                min=0,
                max=1,
            ),
            fields.IntConfig(
                "days_between_autoapprove",
                help_text="The allowed number of days between auto approved quota changes.",
                default=30,
            ),
        ]
    )

    def _get_email(self):

        if CONF.identity.username_is_email:
            return self.action.task.keystone_user["username"]
        else:
            id_manager = user_store.IdentityManager()
            user = id_manager.users.get(self.keystone_user["user_id"])
            email = user.email
            if email:
                return email

        self.add_note("User email address not set.")
        return None

    def _validate_quota_size_exists(self):
        size_list = CONF.quota.sizes.keys()
        if self.size not in size_list:
            self.add_note("Quota size: %s does not exist" % self.size)
            return False
        return True

    def _set_region_quota(self, region_name, quota_size):
        # Set the quota for an individual region
        quota_config = CONF.quota.sizes.get(quota_size, {})
        if not quota_config:
            self.add_note(
                "Project quota not defined for size '%s' in region %s."
                % (quota_size, region_name)
            )
            return

        quota_manager = QuotaManager(
            self.project_id, self.config.size_difference_threshold
        )

        quota_manager.set_region_quota(region_name, quota_config)

        self.add_note(
            "Project quota for region %s set to %s" % (region_name, quota_size)
        )

    def _can_auto_approve(self):
        wait_days = self.config.days_between_autoapprove
        task_list = models.Task.objects.filter(
            completed_on__gte=timezone.now() - timedelta(days=wait_days),
            task_type__exact=self.action.task.task_type,
            cancelled__exact=False,
            project_id__exact=self.project_id,
        )

        changed_in_period = False
        # Check to see if there have been any updates in the relavent regions
        # recently
        for task in task_list:
            for action in task.actions:
                intersect = set(action.action_data["regions"]).intersection(
                    self.regions
                )
                if intersect:
                    changed_in_period = True

        region_sizes = []

        quota_manager = QuotaManager(
            self.project_id, self.config.size_difference_threshold
        )

        for region in self.regions:
            current_size = quota_manager.get_region_quota_data(
                region, include_usage=False
            )["current_quota_size"]
            region_sizes.append(current_size)
            self.add_note(
                "Project has size '%s' in region: '%s'" % (current_size, region)
            )

        # Check for preapproved_quotas
        preapproved_quotas = []
        smaller_quotas = []

        # If all region sizes are the same
        if region_sizes.count(region_sizes[0]) == len(region_sizes):
            preapproved_quotas = quota_manager.get_quota_change_options(region_sizes[0])
            smaller_quotas = quota_manager.get_smaller_quota_options(region_sizes[0])

        if self.size in smaller_quotas:
            self.add_note(
                "Quota size '%s' is in list of smaller quotas: %s"
                % (self.size, smaller_quotas)
            )
            return True

        if changed_in_period:
            self.add_note(
                "Quota has already been updated within the auto " "approve time limit."
            )
            return False

        if self.size not in preapproved_quotas:
            self.add_note(
                "Quota size '%s' not in preapproved list: %s"
                % (self.size, preapproved_quotas)
            )
            return False

        self.add_note(
            "Quota size '%s' in preapproved list: %s" % (self.size, preapproved_quotas)
        )
        return True

    def _validate(self):
        # Make sure the project id is valid and can be used
        self.action.valid = validate_steps(
            [
                self._validate_project_id,
                self._validate_quota_size_exists,
                self._validate_regions_exist,
                self._validate_usage_lower_than_quota,
            ]
        )
        self.action.save()

    def _prepare(self):
        self._validate()
        # Set auto-approval
        self.set_auto_approve(self._can_auto_approve())

    def _approve(self):
        self._validate()

        if not self.valid or self.action.state == "completed":
            return

        # Use manager here instead, it will make it easier to add has_more
        # in later
        for region in self.regions:
            self._set_region_quota(region, self.size)

        self.action.state = "completed"
        self.action.task.cache["project_id"] = self.project_id
        self.action.task.cache["size"] = self.size

        self.action.save()

    def _submit(self, token_data, keystone_user=None):
        """
        Nothing to do here. Everything is done at approve.
        """
        pass
예제 #2
0
파일: base.py 프로젝트: urimeba2/adjutant
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
예제 #3
0
config_group = groups.ConfigGroup("workflow")

config_group.register_child_config(
    fields.URIConfig(
        "horizon_url",
        help_text=
        "The base Horizon url for Adjutant to use when producing links to Horizon.",
        schemes=["https", "http"],
        required=True,
        sample_default="http://localhost/",
        test_default="http://localhost/",
    ))
config_group.register_child_config(
    fields.IntConfig(
        "default_token_expiry",
        help_text="The default token expiry time for Task tokens.",
        default=24 * 60 * 60,  # 24hrs in seconds
    ))


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(
예제 #4
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
예제 #5
0
파일: django.py 프로젝트: urimeba2/adjutant
        "log_file",
        help_text="The name and location of the Adjutant log file, "
        "superceded by 'adjutant.django.logging'.",
        default="adjutant.log",
    ))

_email_group = groups.ConfigGroup("email")
_email_group.register_child_config(
    fields.StrConfig(
        "email_backend",
        help_text="Django email backend to use.",
        default="django.core.mail.backends.console.EmailBackend",
        required=True,
    ))
_email_group.register_child_config(
    fields.IntConfig("timeout", help_text="Email backend timeout."))
_email_group.register_child_config(
    fields.HostNameConfig("host", help_text="Email backend server location."))
_email_group.register_child_config(
    fields.PortConfig("port", help_text="Email backend server port."))
_email_group.register_child_config(
    fields.StrConfig("host_user", help_text="Email backend user."))
_email_group.register_child_config(
    fields.StrConfig("host_password",
                     help_text="Email backend user password."))
_email_group.register_child_config(
    fields.BoolConfig(
        "use_tls",
        help_text=
        "Whether to use TLS for email. Mutually exclusive with 'use_ssl'.",
        default=False,
예제 #6
0
#    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
from confspirator import types


config_group = groups.ConfigGroup("identity")

config_group.register_child_config(
    fields.IntConfig(
        "token_cache_time",
        help_text="Cache time for Keystone Tokens in the Keystone Middleware.",
        default=-1,
        required=True,
        required_for_tests=False,
    )
)
config_group.register_child_config(
    fields.BoolConfig(
        "can_edit_users",
        help_text="Is Adjutant allowed (or able) to edit users in Keystone.",
        default=True,
    )
)
config_group.register_child_config(
    fields.BoolConfig(
        "username_is_email",
        help_text="Should Adjutant assume and treat all usernames as emails.",