def _ntp_check(self, request): ntpo = Service.objects.get(name='ntpd') if (not self._get_status(ntpo)): e_msg = ('NTP must be configured and running first before Rockstor' ' can join AD. Configure NTP service first ' 'and try again.') handle_exception(Exception(e_msg), request)
def delete(self, request, id): try: sftpo = SFTP.objects.get(id=id) except: e_msg = ('SFTP config for the id(%s) does not exist' % id) handle_exception(Exception(e_msg), request) try: mnt_prefix = ('%s%s/' % (settings.SFTP_MNT_ROOT, sftpo.share.owner)) if (is_share_mounted(sftpo.share.name, mnt_prefix)): sftp_snap_toggle(sftpo.share, mount=False) mnt_pt = ('%s%s' % (mnt_prefix, sftpo.share.name)) umount_root(mnt_pt) if (os.path.isdir(mnt_pt)): shutil.rmtree(mnt_pt) sftpo.delete() input_map = {} for so in SFTP.objects.all(): if (so.id != sftpo.id): input_map[so.share.owner] = ( '%s%s' % (settings.SFTP_MNT_ROOT, so.share.owner)) update_sftp_config(input_map) return Response() except RockStorAPIException: raise except Exception, e: handle_exception(e, request)
def _create(self, share, snap_name, request, uvisible, snap_type, writable): if (Snapshot.objects.filter(share=share, name=snap_name).exists()): # Note e_msg is consumed by replication/util.py create_snapshot() e_msg = ('Snapshot ({}) already exists for ' 'the share ({}).').format(snap_name, share.name) handle_exception(Exception(e_msg), request) snap_size = 0 qgroup_id = '0/na' if (snap_type == 'replication'): writable = False add_snap(share.pool, share.subvol_name, snap_name, writable) snap_id = share_id(share.pool, snap_name) qgroup_id = ('0/%s' % snap_id) if share.pqgroup is not settings.MODEL_DEFS['pqgroup']: pool_mnt_pt = '{}{}'.format(settings.MNT_PT, share.pool.name) qgroup_assign(qgroup_id, share.pqgroup, pool_mnt_pt) snap_size, eusage = volume_usage(share.pool, qgroup_id) s = Snapshot(share=share, name=snap_name, real_name=snap_name, size=snap_size, qgroup=qgroup_id, uvisible=uvisible, snap_type=snap_type, writable=writable) # The following share.save() was informed by test_snapshot.py share.save() s.save() return Response(SnapshotSerializer(s).data)
def _config(self, service, request): try: return self._get_config(service) except Exception, e: e_msg = ('Missing configuration. Please configure the ' 'service and try again. Exception: %s' % e.__str__()) handle_exception(Exception(e_msg), request)
def _refresh_and_reload(request): try: refresh_afp_config(list(NetatalkShare.objects.all())) return systemctl('netatalk', 'reload-or-restart') except Exception as e: e_msg = ('Failed to reload Netatalk server. Exception: %s' % e.__str__()) handle_exception(Exception(e_msg), request)
def post(self, request): with self._handle_exception(request): if ('shares' not in request.data): e_msg = ('Cannot export without specifying shares') handle_exception(Exception(e_msg), request) shares = [validate_share(s, request) for s in request.data['shares']] options = parse_options(request) for s in shares: dup_export_check(s, options['host_str'], request) cur_exports = list(NFSExport.objects.all()) eg = NFSExportGroup(**options) eg.save() for s in shares: mnt_pt = ('%s%s' % (settings.MNT_PT, s.name)) export_pt = ('%s%s' % (settings.NFS_EXPORT_ROOT, s.name)) if (not is_share_mounted(s.name)): pool_device = Disk.objects.filter(pool=s.pool)[0].name mount_share(s, pool_device, mnt_pt) export = NFSExport(export_group=eg, share=s, mount=export_pt) export.full_clean() export.save() cur_exports.append(export) exports = create_nfs_export_input(cur_exports) adv_entries = [e.export_str for e in AdvancedNFSExport.objects.all()] exports_d = create_adv_nfs_export_input(adv_entries, request) exports.update(exports_d) refresh_wrapper(exports, request, logger) nfs_serializer = NFSExportGroupSerializer(eg) return Response(nfs_serializer.data)
def delete(self, request, id): try: appliance = Appliance.objects.get(pk=id) except Exception, e: logger.exception(e) e_msg = ('Appliance(%s) does not exist' % id) handle_exception(Exception(e_msg), request)
def put(self, request, username): user = self._get_user_object(request, username) try: # if password is present in input data, change password if ('password' in request.DATA): # change password password = request.DATA['password'] usermod(username, password) smbpasswd(username, password) user.set_password(password) user.save() # check if admin attribute has changed if ('is_active' in request.DATA): is_active = request.DATA['is_active'] # put is through bacbone model save so is_active comes in # as a boolean if is_active != user.is_active: if request.user.username == username: e_msg = ('Cannot modify admin attribute of the ' 'currently logged in user') handle_exception(Exception(e_msg), request) user.is_active = is_active shell = settings.DEFAULT_SHELL if (is_active is True): shell = settings.ADMIN_SHELL update_shell(username, shell) user.save() return Response(UserSerializer(user).data) except RockStorAPIException: raise except Exception, e: handle_exception(e, request)
def _validate_enabled(request): enabled = request.data.get('enabled', True) if (type(enabled) != bool): e_msg = ('enabled flag must be a boolean and not %s' % type(enabled)) handle_exception(Exception(e_msg), request) return enabled
def post(self, request, *args, **kwargs): with self._handle_exception(request): ip = request.data['ip'] current_appliance = request.data['current_appliance'] # authenticate if not adding current appliance if (Appliance.objects.filter(ip=ip).exists()): e_msg = ('The appliance with ip = %s already exists and ' 'cannot be added again' % ip) handle_exception(Exception(e_msg), request) if (current_appliance is False): client_id = request.data.get('client_id', None) if (client_id is None): raise Exception('ID is required') client_secret = request.data.get('client_secret', None) if (client_secret is None): raise Exception('Secret is required') try: mgmt_port = int(request.data['mgmt_port']) except Exception, e: logger.exception(e) e_msg = ('Invalid management port(%s) supplied. Try ' 'again' % request.data['mgmt_port']) handle_exception(Exception(e_msg), request) url = ('https://%s' % ip) if (mgmt_port != 443): url = ('%s:%s' % (url, mgmt_port)) ra_uuid = self._get_remote_appliance(request, ip, mgmt_port, client_id, client_secret) appliance = Appliance(uuid=ra_uuid, ip=ip, mgmt_port=mgmt_port, client_id=client_id, client_secret=client_secret) appliance.save() else:
def post(self, request, sname, snap_name, command=None): with self._handle_exception(request): share = self._validate_share(sname, request) uvisible = request.data.get('uvisible', False) if (type(uvisible) != bool): e_msg = ('uvisible must be a boolean, not %s' % type(uvisible)) handle_exception(Exception(e_msg), request) snap_type = request.data.get('snap_type', 'admin') writable = request.data.get('writable', 'rw') writable = True if (writable == 'rw') else False if (command is None): ret = self._create(share, snap_name, request, uvisible=uvisible, snap_type=snap_type, writable=writable) if (uvisible): try: self._toggle_visibility(share, ret.data['real_name']) except Exception, e: msg = ('Failed to make the Snapshot(%s) visible. ' 'Exception: %s' % (snap_name, e.__str__())) logger.error(msg) logger.exception(e) try: toggle_sftp_visibility(share, ret.data['real_name']) except Exception, e: msg = ('Failed to make the Snapshot(%s) visible for ' 'SFTP. Exception: %s' % (snap_name, e.__str__())) logger.error(msg) logger.exception(e) return ret
def _handle_exception(request, msg): try: yield except RockStorAPIException: raise except Exception, e: handle_exception(e, request, msg)
def post(self, request, command): """ execute a command on the service """ e_msg = ('Failed to %s SNMP service due to system error.' % command) with self._handle_exception(request, e_msg): if (command == 'config'): service = Service.objects.get(name=self.service_name) config = request.data.get('config', {}) if (type(config) != dict): e_msg = ('config dictionary is required input') handle_exception(Exception(e_msg), request) for option in ('syslocation', 'syscontact', 'rocommunity',): if (option not in config): e_msg = ('%s is missing in config' % option) handle_exception(Exception(e_msg), request) if (config[option] is None or config[option] == ''): e_msg = ('%s cannot be empty' % option) handle_exception(Exception(e_msg), request) if ('aux' not in config): e_msg = ('aux is missing in config: %s' % config) handle_exception(Exception(e_msg), request) if (type(config['aux']) != list): e_msg = ('aux must be a list in config: %s' % config) handle_exception(Exception(e_msg), request) configure_snmp(config) self._save_config(service, config) else: self._switch_snmp(command) return Response()
def post(self, request, sname, command): with self._handle_exception(request): share = self._validate_share(request, sname) if (command == 'clone'): new_name = request.data.get('name', '') return create_clone(share, new_name, request, logger) if (command == 'rollback'): snap = self._validate_snapshot(request, share) if (NFSExport.objects.filter(share=share).exists()): e_msg = ('Share(%s) cannot be rolled back as it is ' 'exported via nfs. Delete nfs exports and ' 'try again' % sname) handle_exception(Exception(e_msg), request) if (SambaShare.objects.filter(share=share).exists()): e_msg = ('Share(%s) cannot be rolled back as it is shared' ' via Samba. Unshare and try again' % sname) handle_exception(Exception(e_msg), request) rollback_snap(snap.real_name, share.name, share.subvol_name, share.pool) update_quota(share.pool, snap.qgroup, share.size * 1024) share.qgroup = snap.qgroup share.save() snap.delete() return Response()
def put(self, request, sname): with self._handle_exception(request): share = self._validate_share(request, sname) if ('size' in request.data): new_size = self._validate_share_size(request, share.pool) disk = Disk.objects.filter(pool=share.pool)[0] qid = qgroup_id(share.pool, share.subvol_name) cur_rusage, cur_eusage = share_usage(share.pool, qid) if (new_size < cur_rusage): e_msg = ('Unable to resize because requested new size(%dKB) ' 'is less than current usage(%dKB) of the share.' % (new_size, cur_rusage)) handle_exception(Exception(e_msg), request) update_quota(share.pool, share.pqgroup, new_size * 1024) share.size = new_size if ('compression' in request.data): new_compression = self._validate_compression(request) if (share.compression_algo != new_compression): share.compression_algo = new_compression mnt_pt = '%s%s' % (settings.MNT_PT, sname) if (new_compression == 'no'): new_compression = '' set_property(mnt_pt, 'compression', new_compression) share.save() return Response(ShareSerializer(share).data)
def post(self, request, command): """ execute a command on the service """ service = Service.objects.get(name=self.name) if (command == 'config'): try: config = request.data.get('config') try: listener_port = int(config['listener_port']) except ValueError: raise Exception('Listener Port must be a valid port number between 0-65535') if (listener_port < 0 or listener_port > 65535): raise Exception('Invalid listener port(%d)' % listener_port) ni = config['network_interface'] try: nco = NetworkConnection.objects.get(name=ni) except NetworkConnection.DoesNotExist: raise Exception('Network Connection(%s) does not exist.' % ni) #@todo: we should make restart transparent to the user. ztask_helpers.restart_rockstor.async(nco.ipaddr, listener_port) self._save_config(service, config) return Response() except Exception, e: e_msg = ('Failed to configure Rockstor service. Try again. Exception: %s' % e.__str__()) handle_exception(Exception(e_msg), request)
def delete(self, request, id): try: sftpo = SFTP.objects.get(id=id) except: e_msg = ('SFTP config for the id(%s) does not exist' % id) handle_exception(Exception(e_msg), request) try: mnt_prefix = ('%s%s/' % (settings.SFTP_MNT_ROOT, sftpo.share.owner)) if (is_share_mounted(sftpo.share.name, mnt_prefix)): sftp_snap_toggle(sftpo.share, mount=False) umount_root(('%s%s' % (mnt_prefix, sftpo.share.name))) import shutil shutil.rmtree(mnt_prefix) sftpo.delete() input_list = [] for so in SFTP.objects.all(): if (so.id != sftpo.id): input_list.append({'user': so.share.owner, 'dir': ('%s%s' % (settings.SFTP_MNT_ROOT, so.share.name)), }) update_sftp_config(input_list) return Response() except RockStorAPIException: raise except Exception, e: handle_exception(e, request)
def _btrfs_disk_import(self, dname, request): try: disk = self._validate_disk(dname, request) p_info = get_pool_info(dname) # get some options from saved config? po = Pool(name=p_info['label'], raid="unknown") # need to save it so disk objects get updated properly in the for # loop below. po.save() for d in p_info['disks']: do = Disk.objects.get(name=d) do.pool = po do.parted = False do.save() mount_root(po) po.raid = pool_raid('%s%s' % (settings.MNT_PT, po.name))['data'] po.size = pool_usage('%s%s' % (settings.MNT_PT, po.name))[0] po.save() enable_quota(po) import_shares(po, request) for share in Share.objects.filter(pool=po): import_snapshots(share) return Response(DiskInfoSerializer(disk).data) except Exception, e: e_msg = ('Failed to import any pool on this device(%s). Error: %s' % (dname, e.__str__())) handle_exception(Exception(e_msg), request)
def _validate_input(request): meta = {} crontab = request.data.get('crontab') crontabwindow = request.data.get('crontabwindow') meta = request.data.get('meta', {}) if (type(meta) != dict): e_msg = ('meta must be a dictionary, not %s' % type(meta)) handle_exception(Exception(e_msg), request) if 'pool' in meta: if not Pool.objects.filter(id=meta['pool']).exists(): raise Exception('Non-existent Pool(%s) in meta. %s' % (meta['pool'], meta)) # Add pool_name to task meta dictionary pool = Pool.objects.get(id=meta['pool']) meta['pool_name'] = pool.name if 'share' in meta: if not meta['share'].isdigit(): raise Exception('Non-digit share element ({}) in meta {}' .format(meta['share'], meta)) if not Share.objects.filter(id=meta['share']).exists(): raise Exception('Non-existent Share id (%s) in meta. %s' % (meta['pool'], meta)) if 'rtc_hour' in meta: meta['rtc_hour'] = int(meta['rtc_hour']) meta['rtc_minute'] = int(meta['rtc_minute']) return crontab, crontabwindow, meta
def get_queryset(self, *args, **kwargs): with self._handle_exception(self.request): try: share = Share.objects.get(name=self.kwargs['sname']) except: if ('sname' not in self.kwargs): return Snapshot.objects.filter().order_by('-id') e_msg = ('Share with name: %s does not exist' % self.kwargs['sname']) handle_exception(Exception(e_msg), self.request) if ('snap_name' in self.kwargs): self.paginate_by = 0 try: return Snapshot.objects.get(share=share, name=self.kwargs['snap_name']) except: return [] snap_type = self.request.query_params.get('snap_type', None) if (snap_type is not None and snap_type != ''): return Snapshot.objects.filter( share=share, snap_type=snap_type).order_by('-id') return Snapshot.objects.filter(share=share).order_by('-id')
def post(self, request, command, dname=None): with self._handle_exception(request): if (command == 'scan'): return self._update_disk_state() e_msg = ('Unsupported command(%s).' % command) handle_exception(Exception(e_msg), request)
def _create(self, share, snap_name, pool_device, request, uvisible, snap_type, writable): if (Snapshot.objects.filter(share=share, name=snap_name).exists()): e_msg = ('Snapshot(%s) already exists for the Share(%s).' % (snap_name, share.name)) handle_exception(Exception(e_msg), request) real_name = snap_name snap_size = 0 qgroup_id = '0/na' if (snap_type != 'receiver'): if (snap_type == 'replication'): writable = False add_snap(share.pool, pool_device, share.subvol_name, real_name, readonly=not writable) snap_id = share_id(share.pool, pool_device, real_name) qgroup_id = ('0/%s' % snap_id) snap_size = share_usage(share.pool, pool_device, qgroup_id) s = Snapshot(share=share, name=snap_name, real_name=real_name, size=snap_size, qgroup=qgroup_id, uvisible=uvisible, snap_type=snap_type, writable=writable) s.save() return Response(SnapshotSerializer(s).data)
def post(self, request): name = request.DATA['name'] if (name not in self.valid_tasks): e_msg = ('Unknown task type: %s cannot be scheduled' % name) handle_exception(Exception(e_msg), request) frequency = None if ('frequency' in request.DATA): frequency = int(request.DATA['frequency']) if (frequency < 60): frequency = None else: frequency = frequency - (frequency % 60) logger.info('meta: %s' % request.DATA['meta']) json_meta = json.dumps(request.DATA['meta']) logger.info('json_meta: %s' % json_meta) logger.info('request: %s' % request.DATA) ts = int(float(request.DATA['ts'])) ts_dto = datetime.utcfromtimestamp(float(ts)).replace(second=0, microsecond=0, tzinfo=utc) td = TaskDefinition(name=name, ts=ts_dto, frequency=frequency, json_meta=json_meta) td.save() return Response()
def refresh_wrapper(exports, request, logger): try: refresh_nfs_exports(exports) except Exception as e: e_msg = ('A lower level error occured while refreshing ' 'NFS exports: %s' % e.__str__()) handle_exception(Exception(e_msg), request)
def _validate_snapshot(self, request, share): try: snap_name = request.DATA.get("name", "") return Snapshot.objects.get(share=share, name=snap_name) except: e_msg = "Snapshot(%s) does not exist for this Share(%s)" % (snap_name, share.name) handle_exception(Exception(e_msg), request)
def _validate_input(request): time_machine = request.data.get('time_machine', 'yes') if (time_machine != 'yes' and time_machine != 'no'): e_msg = ('time_machine must be yes or no. not %s' % time_machine) handle_exception(Exception(e_msg), request) return time_machine
def _delete_snapshot(self, request, sid, id=None, snap_name=None): share = self._validate_share(sid, request) try: snapshot = None if (id is not None): snapshot = Snapshot.objects.get(id=id) elif (snap_name is not None): snapshot = Snapshot.objects.get(share=share, name=snap_name) else: return True except: e_msg = '' if (id is not None): e_msg = 'Snapshot id ({}) does not exist.'.format(id) else: # Note e_msg consumed by replication/util.py update_repclone() # and delete_snapshot() e_msg = 'Snapshot name ({}) does not exist.'.format(snap_name) handle_exception(Exception(e_msg), request) if (snapshot.uvisible): self._toggle_visibility(share, snapshot.real_name, snapshot.qgroup, on=False) toggle_sftp_visibility(share, snapshot.real_name, snapshot.qgroup, on=False) remove_snap(share.pool, share.name, snapshot.name, snapshot.qgroup) snapshot.delete() return Response()
def _validate_input(backup_id, request): try: return ConfigBackup.objects.get(id=backup_id) except ConfigBackup.DoesNotExist: e_msg = ('Config backup for the id ({}) ' 'does not exist.').format(backup_id) handle_exception(Exception(e_msg), request)
def _delete_snapshot(self, request, sname, id=None, snap_name=None): share = self._validate_share(sname, request) try: snapshot = None if (id is not None): snapshot = Snapshot.objects.get(id=id) elif (snap_name is not None): snapshot = Snapshot.objects.get(share=share, name=snap_name) else: return True except: e_msg = '' if (id is not None): e_msg = ('Snapshot(%s) does not exist.' % id) else: e_msg = ('Snapshot(%s) does not exist.' % snap_name) handle_exception(Exception(e_msg), request) if (snapshot.uvisible): self._toggle_visibility(share, snapshot.real_name, on=False) toggle_sftp_visibility(share, snapshot.real_name, on=False) remove_snap(share.pool, sname, snapshot.name) snapshot.delete() return Response()
def post(self, request, pname, command=None): pool = self._validate_pool(pname, request) if (command is not None and command != 'status'): e_msg = ('Unknown scrub command: %s' % command) handle_exception(Exception(e_msg), request) with self._handle_exception(request): ps = self._scrub_status(pool) if (command == 'status'): return Response(PoolScrubSerializer(ps).data) force = request.data.get('force', False) if ((PoolScrub.objects.filter(pool=pool, status__regex=r'(started|running)') .exists())): if (force): p = PoolScrub.objects.filter( pool=pool, status__regex=r'(started|running)').order_by('-id')[0] p.status = 'terminated' p.save() else: e_msg = ('A Scrub process is already running for ' 'pool(%s). If you really want to kill it ' 'and start a new scrub, use force option' % pname) handle_exception(Exception(e_msg), request) scrub_pid = scrub_start(pool, force=force) ps = PoolScrub(pool=pool, pid=scrub_pid) ps.save() return Response(PoolScrubSerializer(ps).data)
def delete(self, request, id): try: smbo = SambaShare.objects.get(id=id) smbo.delete() except: e_msg = ('Samba export for the id(%s) does not exist' % id) handle_exception(Exception(e_msg), request) try: refresh_smb_config(list(SambaShare.objects.all())) restart_samba() return Response() except Exception, e: e_msg = ('System error occured while restarting Samba server') handle_exception(Exception(e_msg), request)
def post(self, request, command): """ execute a command on the service """ service = Service.objects.get(name='nfs') service_name = 'nfs-server' if (command == 'config'): #nothing to really configure atm. just save the model try: config = request.data['config'] self._save_config(service, config) except Exception, e: e_msg = ('NFS could not be configured due to the following ' 'exception. You could try again. %s' % e.__str__()) handle_exception(Exception(e_msg), request)
def post(self, request, command): """ execute a command on the service """ service = Service.objects.get(name='nfs') service_name = 'nfs-server' if (command == 'config'): #nothing to really configure atm. just save the model try: config = request.DATA['config'] self._save_config(service, config) except Exception, e: logger.exception(e) e_msg = ('NFS could not be configured. Try again') handle_exception(Exception(e_msg), request)
def delete(self, request, username): user = self._get_user_object(request, username) try: if request.user.username == username: raise Exception("Cannot delete the currently logged in user") epw = get_epasswd(username) logger.debug('epw: %s' % repr(epw)) if (epw is not None): userdel(username) user.delete() logger.debug('deleted user %s' % username) return Response() except Exception, e: handle_exception(e, request)
def put(self, request, tdid): with self._handle_exception(request): tdo = self._task_def(request, tdid) enabled = request.data.get('enabled', True) if (type(enabled) != bool): e_msg = ('enabled flag must be a boolean and not %s' % type(enabled)) handle_exception(Exception(e_msg), request) tdo.enabled = enabled tdo.frequency, new_meta = self._validate_input(request) meta = json.loads(tdo.json_meta) meta.update(new_meta) tdo.json_meta = json.dumps(meta) tdo.save() return Response(TaskDefinitionSerializer(tdo).data)
def put(self, request): try: current_user = request.user widgets = request.data["widgets"] dcs = DashboardConfig.objects.filter(user__pk=current_user.id) if len(dcs) > 0: dc = dcs[0] dc.widgets = widgets else: dc = DashboardConfig(widgets=widgets) dc.user_id = current_user.id dc.save() return Response(DashboardConfigSerializer(dc).data) except Exception as e: handle_exception(e, request)
def post(self, request, command): """ execute a command on the service """ service = Service.objects.get(name='winbind') if (command == 'config'): try: config = request.DATA['config'] toggle_auth_service('winbind', 'start', config) logger.info('authconfig executed') self._save_config(service, config) except Exception, e: logger.exception(e) e_msg = ('Winbind could not be configured. Try again') handle_exception(Exception(e_msg), request)
def get(self, request, caseid=None): try: if (caseid is None): ss = SupportSerializer(SupportCase.objects.all()) return Response(ss.data) try: sc_o = SupportCase.objects.get(id=caseid) return Response(SupportSerializer(sc_o).data) except: e_msg = ('Unknown support case: %s' % caseid) handle_exception(Exception(e_msg), request) except RockStorAPIException: raise except Exception, e: handle_exception(e, request)
def delete(self, request, smb_id): try: smbo = SambaShare.objects.get(id=smb_id) SambaCustomConfig.objects.filter(smb_share=smbo).delete() smbo.delete() except: e_msg = ( "Samba export for the id ({}) does not exist.").format(smb_id) handle_exception(Exception(e_msg), request) with self._handle_exception(request): refresh_smb_config(list(SambaShare.objects.all())) refresh_smb_discovery(list(SambaShare.objects.all())) self._restart_samba() return Response()
def post(self, request, command): """ execute a command on the service """ service = Service.objects.get(name='nis') if (command == 'config'): try: config = request.DATA['config'] configure_nis(config['domain'], config['server']) service.config = config service.save() except Exception, e: logger.exception(e) e_msg = ('NIS could not be configured. Try again') handle_exception(Exception(e_msg), request)
def get_queryset(self, *args, **kwargs): if docker_status(): pending_rids = {} failed_rids = {} for t in Task.objects.filter( function_name__regex="rockon_helpers"): # noqa E501 rid = pickle.loads(t.args)[0] if t.retry_count == 0 and t.failed is not None: failed_rids[rid] = t else: pending_rids[rid] = t # Remove old failed attempts @todo: we should prune all failed # tasks of the past, not here though. for rid in pending_rids.keys(): if rid in failed_rids: pt = pending_rids[rid] ft = failed_rids[rid] if failed_rids[rid].created > pending_rids[rid].created: # this should never be the case. pending tasks either # succeed and get deleted or they are marked failed. msg = ("Found a failed Task ({}) in the future of a " "pending Task ({}).").format(ft.uuid, pt.uuid) handle_exception(Exception(msg), self.request) failed_rids[rid].delete() del failed_rids[rid] for ro in RockOn.objects.all(): if ro.state == "installed": # update current running status of installed rockons. if ro.id not in pending_rids: ro.status = rockon_status(ro.name) elif re.search("pending", ro.state) is not None: if ro.id in failed_rids: # we update the status on behalf of the task runner func_name = t.function_name.split(".")[-1] ro.state = "%s_failed" % func_name elif ro.id not in pending_rids: logger.error(("Rockon ({}) is in pending state but " "there is no pending or failed task " "for it.").format(ro.name)) ro.state = "%s_failed" % ro.state.split("_")[1] else: logger.debug( ("Rockon ({}) is in pending state.").format( ro.name)) elif ro.state == "uninstall_failed": ro.state = "installed" ro.save() return RockOn.objects.filter().order_by("name")
def get_queryset(self, *args, **kwargs): if (docker_status()): pending_rids = {} failed_rids = {} for t in Task.objects.filter( function_name__regex='rockon_helpers'): rid = pickle.loads(t.args)[0] if (t.retry_count == 0 and t.failed is not None): failed_rids[rid] = t else: pending_rids[rid] = t #Remove old failed attempts #@todo: we should prune all failed tasks of the past, not here though. for rid in pending_rids.keys(): if (rid in failed_rids): pt = pending_rids[rid] ft = failed_rids[rid] if (failed_rids[rid].created > pending_rids[rid].created): #this should never be the case. pending tasks either #succeed and get deleted or they are marked failed. msg = ('Found a failed Task(%s) in the future of a ' 'pending Task(%s).' % (ft.uuid, pt.uuid)) handle_exception(Exception(msg), self.request) failed_rids[rid].delete() logger.debug('deleted failed task') del failed_rids[rid] for ro in RockOn.objects.all(): if (ro.state == 'installed'): # update current running status of installed rockons. if (ro.id not in pending_rids): ro.status = rockon_status(ro.name) elif (re.search('pending', ro.state) is not None): if (ro.id in failed_rids): #we update the status on behalf of the task runner func_name = t.function_name.split('.')[-1] ro.state = '%s_failed' % func_name elif (ro.id not in pending_rids): logger.error( 'Rockon(%s) is in pending state but there ' 'is no pending or failed task for it. ' % ro.name) ro.state = '%s_failed' % ro.state.split('_')[1] else: logger.debug('Rockon(%s) is in pending state' % ro.name) elif (ro.state == 'uninstall_failed'): ro.state = 'installed' ro.save() return RockOn.objects.filter().order_by('name')
def post(self, request, *args, **kwargs): with self._handle_exception(request): ip = request.data.get("ip", "") current_appliance = request.data.get("current_appliance") # authenticate if not adding current appliance if Appliance.objects.filter(ip=ip).exists(): e_msg = ( "The appliance with ip = {} already exists and " "cannot be added again." ).format(ip) handle_exception(Exception(e_msg), request) if current_appliance is False: client_id = request.data.get("client_id", None) if client_id is None: raise Exception("ID is required") client_secret = request.data.get("client_secret", None) if client_secret is None: raise Exception("Secret is required") try: mgmt_port = int(request.data["mgmt_port"]) except Exception as e: logger.exception(e) e_msg = ( "Invalid management port ({}) supplied. Try again." ).format(request.data["mgmt_port"]) handle_exception(Exception(e_msg), request) url = "https://%s" % ip if mgmt_port != 443: url = "%s:%s" % (url, mgmt_port) ra_uuid = self._get_remote_appliance( request, ip, mgmt_port, client_id, client_secret ) appliance = Appliance( uuid=ra_uuid, ip=ip, mgmt_port=mgmt_port, client_id=client_id, client_secret=client_secret, ) appliance.save() else: appliance = Appliance(uuid=hostid(), ip=ip, current_appliance=True) if "hostname" in request.data: appliance.hostname = request.data["hostname"] appliance.save() sethostname(appliance.hostname) return Response(ApplianceSerializer(appliance).data)
def post(self, request): sname = request.data['share'] if (ReplicaShare.objects.filter(share=sname).exists()): e_msg = ('Replicashare(%s) already exists.' % sname) handle_exception(Exception(e_msg), request) share = self._validate_share(sname, request) aip = request.data['appliance'] self._validate_appliance(aip, request) src_share = request.data['src_share'] ts = datetime.utcnow().replace(tzinfo=utc) r = ReplicaShare(share=sname, appliance=aip, pool=share.pool.name, src_share=src_share, ts=ts) r.save() return Response(ReplicaShareSerializer(r).data)
def post(self, request, command): """ execute a command on the service """ with self._handle_exception(request): service = Service.objects.get(name=self.service_name) if command == 'config': try: config = request.data.get('config') configure_nut(config) self._save_config(service, config) except Exception, e: logger.exception(e) e_msg = ('NUT could not be configured. Please try again') handle_exception(Exception(e_msg), request) else:
def delete(self, request, rid): with self._handle_exception(request): try: rs = ReplicaShare.objects.get(id=rid) except: e_msg = ('ReplicaShare(%d) does not exist.' % rid) handle_exception(Exception(e_msg), request) if (Share.objects.filter(name=rs.share).exists()): e_msg = ('Share(%s) linked to this receive exists. If you are ' 'sure, delete it and try again.' % rs.share) handle_exception(Exception(e_msg), request) ReceiveTrail.objects.filter(rshare=rs).delete() rs.delete() return Response()
class ApplianceDetailView(rfc.GenericView): serializer_class = ApplianceSerializer def get(self, *args, **kwargs): with self._handle_exception(self.request): data = Appliance.objects.get(id=self.kwargs.get('appid')) serialized_data = ApplianceSerializer(data) return Response(serialized_data.data) @transaction.atomic def put(self, request, appid): try: appliance = Appliance.objects.get(pk=appid) except Exception, e: logger.exception(e) e_msg = ('Appliance(%s) does not exist' % appid) handle_exception(Exception(e_msg), request) try: appliance.hostname = request.data['hostname'] appliance.save() sethostname(appliance.hostname) if (EmailClient.objects.count() > 0): current_email = EmailClient.objects.all()[0] update_generic(current_email.sender) return Response() except Exception, e: logger.exception(e) e_msg = ('Failed updating hostname for appliance with id = %d' % appid) handle_exception(e, request)
def delete(self, request, sname): try: share = Share.objects.get(name=sname) if (not SambaShare.objects.filter(share=share).exists()): e_msg = ('Share is not exported via Samba. Nothing to delete') handle_exception(Exception(e_msg), request) samba_share = SambaShare.objects.get(share=share) samba_share.delete() refresh_smb_config(list(SambaShare.objects.all()), settings.SMB_CONF) restart_samba() return Response() except RockStorAPIException: raise except Exception, e: handle_exception(e, request)
def delete(self, request, rid): with self._handle_exception(request): try: r = Replica.objects.get(id=rid) except: e_msg = ('Replica(%s) does not exist' % rid) handle_exception(Exception(e_msg), request) if (r.enabled is True): e_msg = ('Replica(%s) is still enabled. Disable it and ' 'retry.' % rid) handle_exception(Exception(e_msg), request) ReplicaTrail.objects.filter(replica=r).delete() r.delete() return Response()
def post(self, request, command): """ execute a command on the service """ with self._handle_exception(request): service = Service.objects.get(name='ldap') if (command == 'config'): try: config = request.data['config'] self._save_config(service, config) except Exception, e: logger.exception(e) e_msg = ('Ldap could not be configured. Try again') handle_exception(Exception(e_msg), request) else:
def delete(self, request, pname): try: pool = Pool.objects.get(name=pname) if (Share.objects.filter(pool=pool).exists()): e_msg = ('Pool: %s is not empty. Cannot delete until all ' 'shares in the pool are deleted' % (pname)) handle_exception(Exception(e_msg), request) pool_path = ('%s%s' % (settings.MNT_PT, pname)) remove_pool(pool_path) umount_root(pool_path) pool.delete() return Response() except RockStorAPIException: raise except Exception, e: handle_exception(e, request)
def get_queryset(self, *args, **kwargs): try: share = Share.objects.get(name=kwargs['sname']) except: e_msg = ('Share with name: %s does not exist' % kwargs['sname']) handle_exception(Exception(e_msg), self.request) if ('snap_name' in kwargs): self.paginate_by = None try: return Snapshot.objects.get(share=share, name=kwargs['snap_name']) except: return [] return Snapshot.objects.filter(share=share)
def put(self, request, id): with self._handle_exception(request): nco = self._nco(request, id) method = request.data.get("method") mtu = DEFAULT_MTU try: e_msg = ( "The mtu must be an integer in {} - {} range.").format( MIN_MTU, MAX_MTU) mtu = int(request.data.get("mtu", DEFAULT_MTU)) if mtu < MIN_MTU or mtu > MAX_MTU: handle_exception(Exception(e_msg), request) except ValueError: handle_exception(Exception(e_msg), request) ipaddr = gateway = dns_servers = search_domains = None if method == "manual": ipaddr = request.data.get("ipaddr", None) gateway = request.data.get("gateway", None) dns_servers = request.data.get("dns_servers", None) search_domains = request.data.get("search_domains", None) if nco.ctype == "ethernet": device = nco.networkdevice_set.first().name self._delete_connection(nco) network.new_ethernet_connection(nco.name, device, ipaddr, gateway, dns_servers, search_domains, mtu) elif nco.ctype == "team": team_profile = nco.team_profile devices = [] for child_nco in NetworkConnection.objects.filter(master=nco): devices.append(child_nco.networkdevice_set.first().name) self._delete_connection(nco) network.new_team_connection( nco.name, self.runners[team_profile], devices, ipaddr, gateway, dns_servers, search_domains, mtu, ) return Response(NetworkConnectionSerializer(nco).data)
def post(self, request, command): with self._handle_exception(request): method = 'winbind' service = Service.objects.get(name='active-directory') if (command == 'config'): config = request.data.get('config') self._validate_config(config, request) #1. Name resolution check self._resolve_check(config.get('domain'), request) #2. ntp check self._ntp_check(request) #3. realm discover check? #@todo: phase our realm and just use net? domain = config.get('domain') try: cmd = ['realm', 'discover', '--name-only', domain] o, e, rc = run_command(cmd) except Exception, e: e_msg = ('Failed to discover the given(%s) AD domain. ' 'Error: %s' % (domain, e.__str__())) handle_exception(Exception(e_msg), request) default_range = '10000 - 999999' idmap_range = config.get('idmap_range', '10000 - 999999') idmap_range = idmap_range.strip() if (len(idmap_range) > 0): rfields = idmap_range.split() if (len(rfields) != 3): raise Exception('Invalid idmap range. valid format is ' 'two integers separated by a -. eg: ' '10000 - 999999') try: rlow = int(rfields[0].strip()) rhigh = int(rfields[2].strip()) except Exception, e: raise Exception('Invalid idmap range. Numbers in the ' 'range must be valid integers. ' 'Error: %s.' % e.__str__()) if (rlow >= rhigh): raise Exception('Invalid idmap range. Numbers in the ' 'range must go from low to high. eg: ' '10000 - 999999') else:
def _validate_input(cls, request, smbo=None): options = {} def_opts = cls.DEF_OPTS if (smbo is not None): def_opts = cls.DEF_OPTS.copy() def_opts['comment'] = smbo.comment def_opts['browsable'] = smbo.browsable def_opts['guest_ok'] = smbo.guest_ok def_opts['read_only'] = smbo.read_only def_opts['shadow_copy'] = smbo.shadow_copy options['comment'] = request.data.get('comment', def_opts['comment']) options['browsable'] = request.data.get('browsable', def_opts['browsable']) options['custom_config'] = request.data.get('custom_config', []) if (type(options['custom_config']) != list): e_msg = ('custom config must be a list of strings') handle_exception(Exception(e_msg), request) if (options['browsable'] not in cls.BOOL_OPTS): e_msg = ('Invalid choice for browsable. Possible ' 'choices are yes or no.') handle_exception(Exception(e_msg), request) options['guest_ok'] = request.data.get('guest_ok', def_opts['guest_ok']) if (options['guest_ok'] not in cls.BOOL_OPTS): e_msg = ('Invalid choice for guest_ok. Possible ' 'options are yes or no.') handle_exception(Exception(e_msg), request) options['read_only'] = request.data.get('read_only', def_opts['read_only']) if (options['read_only'] not in cls.BOOL_OPTS): e_msg = ('Invalid choice for read_only. Possible ' 'options are yes or no.') handle_exception(Exception(e_msg), request) options['shadow_copy'] = request.data.get('shadow_copy', def_opts['shadow_copy']) if (options['shadow_copy']): options['snapshot_prefix'] = request.data.get( 'snapshot_prefix', def_opts['snapshot_prefix']) if (options['snapshot_prefix'] is None or len(options['snapshot_prefix'].strip()) == 0): e_msg = ('Invalid choice for snapshot_prefix. It must be a ' 'valid non-empty string') handle_exception(Exception(e_msg), request) return options
def put(self, request, smb_id): with self._handle_exception(request): try: smbo = SambaShare.objects.get(id=smb_id) except: e_msg = ('Samba export for the id(%s) does not exist' % smb_id) handle_exception(Exception(e_msg), request) options = self._validate_input(request, smbo=smbo) custom_config = options['custom_config'] del (options['custom_config']) smbo.__dict__.update(**options) admin_users = request.data.get('admin_users', None) if (admin_users is None): admin_users = [] for uo in User.objects.filter(smb_shares=smbo): if (uo.username not in admin_users): uo.smb_shares.remove(smbo) for u in admin_users: if (not User.objects.filter(username=u, smb_shares=smbo).exists()): auo = User.objects.get(username=u) auo.smb_shares.add(smbo) smbo.save() for cco in SambaCustomConfig.objects.filter(smb_share=smbo): if (cco.custom_config not in custom_config): cco.delete() else: custom_config.remove(cco.custom_config) for cc in custom_config: cco = SambaCustomConfig(smb_share=smbo, custom_config=cc) cco.save() for smb_o in SambaShare.objects.all(): if (not is_share_mounted(smb_o.share.name)): mnt_pt = ('%s%s' % (settings.MNT_PT, smb_o.share.name)) try: mount_share(smb_o.share, mnt_pt) except Exception, e: logger.exception(e) if (smb_o.id == smbo.id): e_msg = ('Failed to mount share(%s) due to a low ' 'level error.' % smb_o.share.name) handle_exception(Exception(e_msg), request) refresh_smb_config(list(SambaShare.objects.all())) self._restart_samba() return Response(SambaShareSerializer(smbo).data)
def _get_remote_appliance(self, request, ip, port, client_id, client_secret): try: base_url = ('https://%s:%s' % (ip, port)) set_token(client_id=client_id, client_secret=client_secret, url=base_url) ad = api_call('%s/api/appliances/1' % base_url) logger.debug('remote appliance: %s' % ad) return ad['uuid'] except RockStorAPIException: raise except Exception, e: e_msg = ('Failed to get remote appliance uuid') logger.error(e_msg) logger.exception(e) handle_exception(e_msg, request)
def delete(self, request, rid): with self._handle_exception(request): try: r = Replica.objects.get(id=rid) except: e_msg = ('Replica(%s) does not exist' % rid) handle_exception(Exception(e_msg), request) if (r.enabled is True): e_msg = ('Replica(%s) is enabled. If you are sure, disable it ' 'first and then delete.' % rid) handle_exception(Exception(e_msg), request) ReplicaTrail.objects.filter(replica=r).delete() r.delete() self._refresh_crontab() return Response()
def _rockon_check(request, sname, force): s = Service.objects.get(name='docker') if (s.config is None): return config = json.loads(s.config) if (config.get('root_share') == sname): if (force): #turn off docker service, nullify config. systemctl(s.name, 'stop') systemctl(s.name, 'disable') s.config = None return s.save() e_msg = ('Share(%s) cannot be deleted because it is in use ' 'by Rock-on service. If you must delete anyway, select ' 'the force checkbox and try again.' % sname) handle_exception(Exception(e_msg), request)
def delete(self, request, rid): with self._handle_exception(request): try: rs = ReplicaShare.objects.get(id=rid) except: e_msg = ('ReplicaShare(%d) does not exist.' % rid) handle_exception(Exception(e_msg), request) if (Share.objects.filter(name=rs.share).exists()): e_msg = ('To delete this, you need to first delete this ' 'Share: %s. If you are sure, try again after ' 'deleting it.' % rs.share) handle_exception(Exception(e_msg), request) ReceiveTrail.objects.filter(rshare=rs).delete() rs.delete() return Response()