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
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
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(
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
"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,
# 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.",