def get_form(params): # Clear rbac cache before check (this is in its own thread). rbac.clear() if not self.user.has_perm(self._meta.create_permission): raise HandlerPermissionError() request = HttpRequest() request.user = self.user form = PodForm( data=self.preprocess_form("create", params), request=request ) if not form.is_valid(): raise HandlerValidationError(form.errors) else: return form
def unmount_special(self, params): """Unmount a special-purpose filesystem, like tmpfs. :param mount_point: Path on the filesystem to unmount. :attention: This is more or less a copy of `unmount_special` from `m.api.machines`. """ machine = self.get_object(params) if machine.locked: raise HandlerPermissionError() self._preflight_special_filesystem_modifications("unmount", machine) form = UnmountNonStorageFilesystemForm(machine, data=params) if form.is_valid(): form.save() else: raise HandlerValidationError(form.errors)
def mount_special(self, params): """Mount a special-purpose filesystem, like tmpfs. :param fstype: The filesystem type. This must be a filesystem that does not require a block special device. :param mount_point: Path on the filesystem to mount. :param mount_option: Options to pass to mount(8). :attention: This is more or less a copy of `mount_special` from `m.api.machines`. """ machine = self.get_object(params) self._preflight_special_filesystem_modifications("mount", machine) form = MountNonStorageFilesystemForm(machine, data=params) if form.is_valid(): form.save() else: raise HandlerValidationError(form.errors)
def get_form(params): # Clear rbac cache before check (this is in its own thread). rbac.clear() obj = self.get_object(params) if not self.user.has_perm(self._meta.edit_permission, obj): raise HandlerPermissionError() request = HttpRequest() request.user = self.user form = PodForm( instance=obj, data=self.preprocess_form("update", params), request=request) if not form.is_valid(): raise HandlerValidationError(form.errors) else: form.cleaned_data['tags'] = params['tags'] return form
def configure_dhcp(self, parameters): """Helper method to look up rack controllers based on the parameters provided in the action input, and then reconfigure DHCP on the VLAN based on them. Requires a dictionary of parameters containing an ordered list of each desired rack controller system_id. If no controllers are specified, disables DHCP on the VLAN. """ vlan = self.get_object(parameters) self.user = reload_object(self.user) assert self.user.has_perm(NodePermission.admin, vlan), "Permission denied." # Make sure the dictionary both exists, and has the expected number # of parameters, to prevent spurious log statements. if 'extra' in parameters: self._configure_iprange_and_gateway(parameters['extra']) if 'relay_vlan' not in parameters: iprange_count = IPRange.objects.filter(type=IPRANGE_TYPE.DYNAMIC, subnet__vlan=vlan).count() if iprange_count == 0: raise ValueError( "Cannot configure DHCP: At least one dynamic range is " "required.") controllers = parameters.get('controllers', []) data = { "dhcp_on": True if len(controllers) > 0 else False, "primary_rack": controllers[0] if len(controllers) > 0 else None, "secondary_rack": controllers[1] if len(controllers) > 1 else None, } if 'relay_vlan' in parameters: data['relay_vlan'] = parameters['relay_vlan'] form = VLANForm(instance=vlan, data=data) if form.is_valid(): form.save() else: raise HandlerValidationError(form.errors)
async def compose(self, params): """Compose a machine in a Pod.""" @transactional def get_object(params): # Running inside new database thread, be sure the rbac cache is # cleared so accessing information will not be already cached. rbac.clear() obj = self.get_object(params) if not self.user.has_perm(PodPermission.compose, obj): raise HandlerPermissionError() return obj @transactional def get_form(obj, params): request = HttpRequest() request.user = self.user form = ComposeMachineForm(pod=obj, data=params, request=request) if not form.is_valid(): raise HandlerValidationError(form.errors) return form @transactional def render_obj(obj): return self.full_dehydrate(reload_object(obj)) pod = await deferToDatabase(get_object, params) if Capabilities.COMPOSABLE not in pod.capabilities: raise HandlerValidationError("Pod does not support composability.") form = await deferToDatabase(get_form, pod, params) try: await form.compose( skip_commissioning=params.get("skip_commissioning", False) ) except Exception as error: log.err(error, "Failed to compose machine.") raise PodProblem("Pod unable to compose machine: %s" % str(error)) return await deferToDatabase(render_obj, pod)
def composable(obj): if Capabilities.COMPOSABLE not in obj.capabilities: raise HandlerValidationError( "Pod does not support composability.") return obj