# # Copyright (c) 2019 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # import ipaddress import json import logging import re import requests import six import subprocess import time from cephclient.exception import CephMonRestfulListKeysError from cephclient.exception import CephMonRestfulJsonError from cephclient.exception import CephMonRestfulMissingUserCredentials from cephclient.exception import CephMgrDumpError from cephclient.exception import CephMgrJsonError from cephclient.exception import CephMgrMissingRestfulService from cephclient.exception import CephClientFormatNotSupported from cephclient.exception import CephClientResponseFormatNotImplemented from cephclient.exception import CephClientInvalidChoice from cephclient.exception import CephClientTypeError from cephclient.exception import CephClientValueOutOfBounds from cephclient.exception import CephClientInvalidPgid from cephclient.exception import CephClientInvalidIPAddr from cephclient.exception import CephClientInvalidOsdIdValue from cephclient.exception import CephClientNoSuchUser from cephclient.exception import CephClientIncorrectPassword CEPH_MON_RESTFUL_USER = 'admin' CEPH_MON_RESTFUL_SERVICE = 'restful' CEPH_CLIENT_RETRY_COUNT = 2 CEPH_CLIENT_RETRY_TIMEOUT_SEC = 5 CEPH_CLI_TIMEOUT_SEC = 5 API_SUPPORTED_RESPONSE_FORMATS = [ 'text', 'json', 'xml', 'binary' ] LOG = logging.getLogger('ceph_client') LOG.setLevel(logging.DEBUG) ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) ch.setFormatter(logging.Formatter( '%(asctime)s %(levelname)s %(name)s %(message)s')) LOG.addHandler(ch) class CephClient(object): def __init__(self, username=CEPH_MON_RESTFUL_USER, password=None, retry_count=CEPH_CLIENT_RETRY_COUNT, retry_timeout=CEPH_CLIENT_RETRY_TIMEOUT_SEC): self.username = username self.password = password self.check_certificate = True self.service_url = None # TODO: fix certificates self._disable_certificate_checks() self.session = None self.retry_count = retry_count self.retry_timeout = retry_timeout def _refresh_session(self): self.session = requests.Session() self.session.auth = (self.username, self.password) def _disable_certificate_checks(self): self.check_certificate = False requests.packages.urllib3.disable_warnings() LOG.warning('skip checking server certificate') def _get_password(self): try: output = subprocess.check_output( ('ceph restful list-keys ' '--connect-timeout {}').format( CEPH_CLI_TIMEOUT_SEC), shell=True) except subprocess.CalledProcessError as e: raise CephMonRestfulListKeysError(str(e)) try: keys = json.loads(output) except (KeyError, ValueError): raise CephMonRestfulJsonError(output) try: self.password = keys[self.username] except KeyError: raise CephMonRestfulMissingUserCredentials(self.username) def _get_service_url(self): try: output = subprocess.check_output( ('ceph mgr dump ' '--connect-timeout {}').format( CEPH_CLI_TIMEOUT_SEC), shell=True) except subprocess.CalledProcessError as e: raise CephMgrDumpError(str(e)) try: status = json.loads(output) except (KeyError, ValueError): raise CephMgrJsonError(output) try: self.service_url = status["services"][CEPH_MON_RESTFUL_SERVICE] except (KeyError, TypeError): raise CephMgrMissingRestfulService( status.get('services', '')) def _make_text_result(self, prefix, result): if result.get('has_failed'): assert(len(result['failed']) == 1) response = requests.Response() response.status_code = requests.codes.internal_server_error response.reason = result['failed'][0]['outs'].rstrip() return response, response.reason else: assert(len(result['finished']) == 1) response = requests.Response() response.status_code = requests.codes.ok response.reason = "OK" return response, result['finished'][0]['outb'].rstrip() def _apply_json_result_workarounds(self, prefix, outb): if prefix == 'osd crush tree': # ceph mgr strangely adds a pair of square brackets at the end while outb.endswith('][]'): LOG.info("Trim 'osd crush tree' json response") outb = outb[:-2] return outb def _make_json_result(self, prefix, result): if result.get('has_failed'): assert(len(result['failed']) == 1) response = requests.Response() response.status_code = requests.codes.internal_server_error response.reason = result['failed'][0]['outs'] return response, dict( status=result['failed'][0]['outs'], output=result['failed'][0]['outb']) else: assert(len(result['finished']) == 1) outb = result['finished'][0]['outb'] outb = self._apply_json_result_workarounds(prefix, outb) response = requests.Response() response.status_code = requests.codes.ok response.reason = "OK" try: return response, dict( status=result['finished'][0]['outs'], output=json.loads(outb or 'null')) except (ValueError, TypeError): raise CephMgrJsonError(outb) def _request(self, prefix, *args, **kwargs): if not self.password: self._get_password() if not self.service_url: self._get_service_url() if not self.session: self._refresh_session() format = kwargs.get('body', 'json').lower() if format not in API_SUPPORTED_RESPONSE_FORMATS: raise CephClientFormatNotSupported( prefix=prefix, format=format) del kwargs['body'] req_json = dict(kwargs) req_json['format'] = format assert('prefix' not in kwargs) req_json['prefix'] = prefix if 'timeout' in req_json: timeout = req_json['timeout'] del req_json['timeout'] else: timeout = None LOG.info('Request params: url={}, json={}'.format( self.service_url + 'request?wait=1', req_json)) credit = self.retry_count + 1 while credit > 0: credit -= 1 try: result = self.session.post( self.service_url + 'request?wait=1', json=req_json, verify=self.check_certificate, timeout=timeout).json() LOG.info('Result: {}'.format(result)) if 'is_finished' in result: self.session.delete( self.service_url + 'request?id=' + result['id']) else: assert('message' in result) if 'auth: No such user' in result['message']: raise CephClientNoSuchUser(user=self.username) elif 'auth: Incorrect password' in result['message']: raise CephClientIncorrectPassword( user=self.username) break except CephClientIncorrectPassword: if not credit: raise LOG.warning('Incorrect password for user \'{}\'. ' 'Fetch user password via list-keys ' 'and retry.'.format(self.username)) if self.retry_timeout > 0: time.sleep(self.retry_timeout) self._get_password() self._refresh_session() except (requests.ConnectionError, requests.Timeout, requests.HTTPError) as e: if not credit: raise IOError(str(e)) LOG.warning( 'Request error: {}. ' 'Refresh restful service URL and retry'.format(e)) if self.retry_timeout > 0: time.sleep(self.retry_timeout) self._get_service_url() self._refresh_session() if format == 'json': return self._make_json_result(prefix, result) elif format == 'text': return self._make_text_result(prefix, result) else: raise CephClientResponseFormatNotImplemented( format=format, reason=result["finished"][0]["outb"]) def pg_stat(self, body='json', timeout=None): """show placement group status.""" return self._request('pg stat', body=body, timeout=timeout) def pg_getmap(self, body='json', timeout=None): """get binary pg map to -o/stdout""" return self._request('pg getmap', body=body, timeout=timeout) PG_DUMP_DUMPCONTENTS_VALUES = \ ['all', 'summary', 'sum', 'delta', 'pools', 'osds', 'pgs', 'pgs_brief'] def pg_dump(self, dumpcontents=None, body='json', timeout=None): """show human-readable versions of pg map (only 'all' valid with plain)""" kwargs = dict(body=body, timeout=timeout) if dumpcontents is not None: if not isinstance(dumpcontents, six.string_types): raise CephClientTypeError( name='dumpcontents', actual=type(dumpcontents), expected=six.string_types) supported = CephClient.PG_DUMP_DUMPCONTENTS_VALUES if dumpcontents not in supported: raise CephClientInvalidChoice( function='pg_dump', option='dumpcontents', value=dumpcontents, supported=', '.join(supported)) if not isinstance(dumpcontents, list): dumpcontents = [dumpcontents] kwargs['dumpcontents'] = dumpcontents return self._request('pg dump', **kwargs) PG_DUMP_JSON_DUMPCONTENTS_VALUES = [ 'all', 'summary', 'sum', 'pools', 'osds', 'pgs'] def pg_dump_json(self, dumpcontents=None, body='json', timeout=None): """show human-readable version of pg map in json only""" kwargs = dict(body=body, timeout=timeout) if dumpcontents is not None: if not isinstance(dumpcontents, six.string_types): raise CephClientTypeError( name='dumpcontents', actual=type(dumpcontents), expected=six.string_types) supported = CephClient.PG_DUMP_JSON_DUMPCONTENTS_VALUES if dumpcontents not in supported: raise CephClientInvalidChoice( function='pg_dump_json', option='dumpcontents', value=dumpcontents, supported=', '.join(supported)) if not isinstance(dumpcontents, list): dumpcontents = [dumpcontents] kwargs['dumpcontents'] = dumpcontents return self._request('pg dump_json', **kwargs) def pg_dump_pools_json(self, body='json', timeout=None): """show pg pools info in json only""" return self._request('pg dump_pools_json', body=body, timeout=timeout) def pg_ls_by_pool(self, poolstr, states=None, body='json', timeout=None): """list pg with pool = [poolname]""" kwargs = dict(body=body, timeout=timeout) if not isinstance(poolstr, six.string_types): raise CephClientTypeError( name='poolstr', actual=type(poolstr), expected=six.string_types) kwargs['poolstr'] = poolstr if states is not None: if isinstance(states, list): for item in states: if not isinstance(item, six.string_types): raise CephClientTypeError( name='states', actual=item, expected='list of strings') else: if not isinstance(states, six.string_types): raise CephClientTypeError( name='states', actual=type(states), expected=six.string_types) if not isinstance(states, list): states = [states] kwargs['states'] = states return self._request('pg ls-by-pool', **kwargs) def pg_ls_by_primary(self, osd, pool=None, states=None, body='json', timeout=None): """list pg with primary = [osd]""" kwargs = dict(body=body, timeout=timeout) if isinstance(osd, six.integer_types): pass elif isinstance(osd, six.string_types): osd = osd.lower() prefix = 'osd.' if not osd.startswith(prefix): raise CephClientInvalidOsdIdValue(osdid=osd) osd = int(osd[len(prefix):]) else: raise CephClientTypeError( name='osd', actual=type(osd), expected='int or string') kwargs['osd'] = osd if pool is not None: if not isinstance(pool, six.integer_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=int) kwargs['pool'] = pool if states is not None: if isinstance(states, list): for item in states: if not isinstance(item, six.string_types): raise CephClientTypeError( name='states', actual=item, expected='list of strings') else: if not isinstance(states, six.string_types): raise CephClientTypeError( name='states', actual=type(states), expected=six.string_types) if not isinstance(states, list): states = [states] kwargs['states'] = states return self._request('pg ls-by-primary', **kwargs) def pg_ls_by_osd(self, osd, pool=None, states=None, body='json', timeout=None): """list pg on osd [osd]""" kwargs = dict(body=body, timeout=timeout) if isinstance(osd, six.integer_types): pass elif isinstance(osd, six.string_types): osd = osd.lower() prefix = 'osd.' if not osd.startswith(prefix): raise CephClientInvalidOsdIdValue(osdid=osd) osd = int(osd[len(prefix):]) else: raise CephClientTypeError( name='osd', actual=type(osd), expected='int or string') kwargs['osd'] = osd if pool is not None: if not isinstance(pool, six.integer_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=int) kwargs['pool'] = pool if states is not None: if isinstance(states, list): for item in states: if not isinstance(item, six.string_types): raise CephClientTypeError( name='states', actual=item, expected='list of strings') else: if not isinstance(states, six.string_types): raise CephClientTypeError( name='states', actual=type(states), expected=six.string_types) if not isinstance(states, list): states = [states] kwargs['states'] = states return self._request('pg ls-by-osd', **kwargs) def pg_ls(self, pool=None, states=None, body='json', timeout=None): """list pg with specific pool, osd, state""" kwargs = dict(body=body, timeout=timeout) if pool is not None: if not isinstance(pool, six.integer_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=int) kwargs['pool'] = pool if states is not None: if isinstance(states, list): for item in states: if not isinstance(item, six.string_types): raise CephClientTypeError( name='states', actual=item, expected='list of strings') else: if not isinstance(states, six.string_types): raise CephClientTypeError( name='states', actual=type(states), expected=six.string_types) if not isinstance(states, list): states = [states] kwargs['states'] = states return self._request('pg ls', **kwargs) PG_DUMP_STUCK_STUCKOPS_VALUES = \ ['inactive', 'unclean', 'stale', 'undersized', 'degraded'] def pg_dump_stuck(self, stuckops=None, threshold=None, body='json', timeout=None): """show information about stuck pgs""" kwargs = dict(body=body, timeout=timeout) if stuckops is not None: if not isinstance(stuckops, six.string_types): raise CephClientTypeError( name='stuckops', actual=type(stuckops), expected=six.string_types) supported = CephClient.PG_DUMP_STUCK_STUCKOPS_VALUES if stuckops not in supported: raise CephClientInvalidChoice( function='pg_dump_stuck', option='stuckops', value=stuckops, supported=', '.join(supported)) if not isinstance(stuckops, list): stuckops = [stuckops] kwargs['stuckops'] = stuckops if threshold is not None: if not isinstance(threshold, six.integer_types): raise CephClientTypeError( name='threshold', actual=type(threshold), expected=int) kwargs['threshold'] = threshold return self._request('pg dump_stuck', **kwargs) PG_DEBUG_DEBUGOP_VALUES = \ ['unfound_objects_exist', 'degraded_pgs_exist'] def pg_debug(self, debugop, body='json', timeout=None): """show debug info about pgs""" kwargs = dict(body=body, timeout=timeout) if not isinstance(debugop, six.string_types): raise CephClientTypeError( name='debugop', actual=type(debugop), expected=six.string_types) supported = CephClient.PG_DEBUG_DEBUGOP_VALUES if debugop not in supported: raise CephClientInvalidChoice( function='pg_debug', option='debugop', value=debugop, supported=', '.join(supported)) kwargs['debugop'] = debugop return self._request('pg debug', **kwargs) def pg_scrub(self, pgid, body='json', timeout=None): """start scrub on """ kwargs = dict(body=body, timeout=timeout) if not isinstance(pgid, six.string_types): raise CephClientTypeError( name='pgid', actual=type(pgid), expected=six.string_types) if not re.match(r'[0-9]+\.[0-9a-fA-F]+', pgid): raise CephClientInvalidPgid( name='pgid', actual=pgid) kwargs['pgid'] = pgid return self._request('pg scrub', **kwargs) def pg_deep_scrub(self, pgid, body='json', timeout=None): """start deep-scrub on """ kwargs = dict(body=body, timeout=timeout) if not isinstance(pgid, six.string_types): raise CephClientTypeError( name='pgid', actual=type(pgid), expected=six.string_types) if not re.match(r'[0-9]+\.[0-9a-fA-F]+', pgid): raise CephClientInvalidPgid( name='pgid', actual=pgid) kwargs['pgid'] = pgid return self._request('pg deep-scrub', **kwargs) def pg_repair(self, pgid, body='json', timeout=None): """start repair on """ kwargs = dict(body=body, timeout=timeout) if not isinstance(pgid, six.string_types): raise CephClientTypeError( name='pgid', actual=type(pgid), expected=six.string_types) if not re.match(r'[0-9]+\.[0-9a-fA-F]+', pgid): raise CephClientInvalidPgid( name='pgid', actual=pgid) kwargs['pgid'] = pgid return self._request('pg repair', **kwargs) def pg_force_recovery(self, pgid, body='json', timeout=None): """force recovery of first""" kwargs = dict(body=body, timeout=timeout) if not isinstance(pgid, six.string_types): raise CephClientTypeError( name='pgid', actual=type(pgid), expected=six.string_types) if not re.match(r'[0-9]+\.[0-9a-fA-F]+', pgid): raise CephClientInvalidPgid( name='pgid', actual=pgid) if not isinstance(pgid, list): pgid = [pgid] kwargs['pgid'] = pgid return self._request('pg force-recovery', **kwargs) def pg_force_backfill(self, pgid, body='json', timeout=None): """force backfill of first""" kwargs = dict(body=body, timeout=timeout) if not isinstance(pgid, six.string_types): raise CephClientTypeError( name='pgid', actual=type(pgid), expected=six.string_types) if not re.match(r'[0-9]+\.[0-9a-fA-F]+', pgid): raise CephClientInvalidPgid( name='pgid', actual=pgid) if not isinstance(pgid, list): pgid = [pgid] kwargs['pgid'] = pgid return self._request('pg force-backfill', **kwargs) def pg_cancel_force_recovery(self, pgid, body='json', timeout=None): """restore normal recovery priority of """ kwargs = dict(body=body, timeout=timeout) if not isinstance(pgid, six.string_types): raise CephClientTypeError( name='pgid', actual=type(pgid), expected=six.string_types) if not re.match(r'[0-9]+\.[0-9a-fA-F]+', pgid): raise CephClientInvalidPgid( name='pgid', actual=pgid) if not isinstance(pgid, list): pgid = [pgid] kwargs['pgid'] = pgid return self._request('pg cancel-force-recovery', **kwargs) def pg_cancel_force_backfill(self, pgid, body='json', timeout=None): """restore normal backfill priority of """ kwargs = dict(body=body, timeout=timeout) if not isinstance(pgid, six.string_types): raise CephClientTypeError( name='pgid', actual=type(pgid), expected=six.string_types) if not re.match(r'[0-9]+\.[0-9a-fA-F]+', pgid): raise CephClientInvalidPgid( name='pgid', actual=pgid) if not isinstance(pgid, list): pgid = [pgid] kwargs['pgid'] = pgid return self._request('pg cancel-force-backfill', **kwargs) def osd_perf(self, body='json', timeout=None): """print dump of OSD perf summary stats""" return self._request('osd perf', body=body, timeout=timeout) OSD_DF_OUTPUT_METHOD_VALUES = ['plain', 'tree'] def osd_df(self, output_method=None, body='json', timeout=None): """show OSD utilization""" kwargs = dict(body=body, timeout=timeout) if output_method is not None: if not isinstance(output_method, six.string_types): raise CephClientTypeError( name='output_method', actual=type(output_method), expected=six.string_types) supported = CephClient.OSD_DF_OUTPUT_METHOD_VALUES if output_method not in supported: raise CephClientInvalidChoice( function='osd_df', option='output_method', value=output_method, supported=', '.join(supported)) kwargs['output_method'] = output_method return self._request('osd df', **kwargs) def osd_blocked_by(self, body='json', timeout=None): """print histogram of which OSDs are blocking their peers""" return self._request('osd blocked-by', body=body, timeout=timeout) def osd_pool_stats(self, pool_name=None, body='json', timeout=None): """obtain stats from all pools, or from specified pool""" kwargs = dict(body=body, timeout=timeout) if pool_name is not None: if not isinstance(pool_name, six.string_types): raise CephClientTypeError( name='pool_name', actual=type(pool_name), expected=six.string_types) kwargs['pool_name'] = pool_name return self._request('osd pool stats', **kwargs) OSD_REWEIGHT_BY_UTILIZATION_NO_INCREASING_VALUES = ['--no-increasing'] def osd_reweight_by_utilization( self, oload=None, max_change=None, max_osds=None, no_increasing=None, body='json', timeout=None): """reweight OSDs by utilization [overload-percentage-for-consideration,default 120] """ kwargs = dict(body=body, timeout=timeout) if oload is not None: if not isinstance(oload, six.integer_types): raise CephClientTypeError( name='oload', actual=type(oload), expected=int) kwargs['oload'] = oload if max_change is not None: if not isinstance(max_change, (six.integer_types, float)): raise CephClientTypeError( name='max_change', actual=type(max_change), expected=int) kwargs['max_change'] = max_change if max_osds is not None: if not isinstance(max_osds, six.integer_types): raise CephClientTypeError( name='max_osds', actual=type(max_osds), expected=int) kwargs['max_osds'] = max_osds if no_increasing is not None: if not isinstance(no_increasing, six.string_types): raise CephClientTypeError( name='no_increasing', actual=type(no_increasing), expected=six.string_types) supported = CephClient.OSD_REWEIGHT_BY_UTILIZATION_NO_INCREASING_VALUES # noqa E501 if no_increasing not in supported: raise CephClientInvalidChoice( function='osd_reweight_by_utilization', option='no_increasing', value=no_increasing, supported=', '.join(supported)) kwargs['no_increasing'] = no_increasing return self._request('osd reweight-by-utilization', **kwargs) OSD_TEST_REWEIGHT_BY_UTILIZATION_NO_INCREASING_VALUES = [ '--no-increasing'] def osd_test_reweight_by_utilization( self, oload=None, max_change=None, max_osds=None, no_increasing=None, body='json', timeout=None): """dry run of reweight OSDs by utilization [overload-percentage-for-consideration, default 120] """ kwargs = dict(body=body, timeout=timeout) if oload is not None: if not isinstance(oload, six.integer_types): raise CephClientTypeError( name='oload', actual=type(oload), expected=int) kwargs['oload'] = oload if max_change is not None: if not isinstance(max_change, (six.integer_types, float)): raise CephClientTypeError( name='max_change', actual=type(max_change), expected=int) kwargs['max_change'] = max_change if max_osds is not None: if not isinstance(max_osds, six.integer_types): raise CephClientTypeError( name='max_osds', actual=type(max_osds), expected=int) kwargs['max_osds'] = max_osds if no_increasing is not None: if not isinstance(no_increasing, six.string_types): raise CephClientTypeError( name='no_increasing', actual=type(no_increasing), expected=six.string_types) supported = CephClient.OSD_TEST_REWEIGHT_BY_UTILIZATION_NO_INCREASING_VALUES # noqa E501 if no_increasing not in supported: raise CephClientInvalidChoice( function='osd_test_reweight_by_utilization', option='no_increasing', value=no_increasing, supported=', '.join(supported)) kwargs['no_increasing'] = no_increasing return self._request('osd test-reweight-by-utilization', **kwargs) def osd_reweight_by_pg( self, oload=None, max_change=None, max_osds=None, pools=None, body='json', timeout=None): """reweight OSDs by PG distribution [overload-percentage-for-consideration, default 120] """ kwargs = dict(body=body, timeout=timeout) if oload is not None: if not isinstance(oload, six.integer_types): raise CephClientTypeError( name='oload', actual=type(oload), expected=int) kwargs['oload'] = oload if max_change is not None: if not isinstance(max_change, (six.integer_types, float)): raise CephClientTypeError( name='max_change', actual=type(max_change), expected=int) kwargs['max_change'] = max_change if max_osds is not None: if not isinstance(max_osds, six.integer_types): raise CephClientTypeError( name='max_osds', actual=type(max_osds), expected=int) kwargs['max_osds'] = max_osds if pools is not None: if isinstance(pools, list): for item in pools: if not isinstance(item, six.string_types): raise CephClientTypeError( name='pools', actual=item, expected='list of strings') else: if not isinstance(pools, six.string_types): raise CephClientTypeError( name='pools', actual=type(pools), expected=six.string_types) if not isinstance(pools, list): pools = [pools] kwargs['pools'] = pools return self._request('osd reweight-by-pg', **kwargs) def osd_test_reweight_by_pg( self, oload=None, max_change=None, max_osds=None, pools=None, body='json', timeout=None): """dry run of reweight OSDs by PG distribution [overload-percentage-for-consideration, default 120] """ kwargs = dict(body=body, timeout=timeout) if oload is not None: if not isinstance(oload, six.integer_types): raise CephClientTypeError( name='oload', actual=type(oload), expected=int) kwargs['oload'] = oload if max_change is not None: if not isinstance(max_change, (six.integer_types, float)): raise CephClientTypeError( name='max_change', actual=type(max_change), expected=int) kwargs['max_change'] = max_change if max_osds is not None: if not isinstance(max_osds, six.integer_types): raise CephClientTypeError( name='max_osds', actual=type(max_osds), expected=int) kwargs['max_osds'] = max_osds if pools is not None: if isinstance(pools, list): for item in pools: if not isinstance(item, six.string_types): raise CephClientTypeError( name='pools', actual=item, expected='list of strings') else: if not isinstance(pools, six.string_types): raise CephClientTypeError( name='pools', actual=type(pools), expected=six.string_types) if not isinstance(pools, list): pools = [pools] kwargs['pools'] = pools return self._request('osd test-reweight-by-pg', **kwargs) def osd_safe_to_destroy(self, ids, body='json', timeout=None): """check whether osd(s) can be safely destroyed without reducing datadurability """ kwargs = dict(body=body, timeout=timeout) if isinstance(ids, list): for item in ids: if not isinstance(item, six.string_types): raise CephClientTypeError( name='ids', actual=item, expected='list of strings') else: if not isinstance(ids, six.string_types): raise CephClientTypeError( name='ids', actual=type(ids), expected=six.string_types) if not isinstance(ids, list): ids = [ids] kwargs['ids'] = ids return self._request('osd safe-to-destroy', **kwargs) def osd_ok_to_stop(self, ids, body='json', timeout=None): """check whether osd(s) can be safely stopped without reducing immediatedata availability """ kwargs = dict(body=body, timeout=timeout) if isinstance(ids, list): for item in ids: if not isinstance(item, six.string_types): raise CephClientTypeError( name='ids', actual=item, expected='list of strings') else: if not isinstance(ids, six.string_types): raise CephClientTypeError( name='ids', actual=type(ids), expected=six.string_types) if not isinstance(ids, list): ids = [ids] kwargs['ids'] = ids return self._request('osd ok-to-stop', **kwargs) def osd_scrub(self, who, body='json', timeout=None): """initiate scrub on osd , or use to scrub all""" kwargs = dict(body=body, timeout=timeout) if not isinstance(who, six.string_types): raise CephClientTypeError( name='who', actual=type(who), expected=six.string_types) kwargs['who'] = who return self._request('osd scrub', **kwargs) def osd_deep_scrub(self, who, body='json', timeout=None): """initiate deep scrub on osd , or use to deep scrub all""" kwargs = dict(body=body, timeout=timeout) if not isinstance(who, six.string_types): raise CephClientTypeError( name='who', actual=type(who), expected=six.string_types) kwargs['who'] = who return self._request('osd deep-scrub', **kwargs) def osd_repair(self, who, body='json', timeout=None): """initiate repair on osd , or use to repair all""" kwargs = dict(body=body, timeout=timeout) if not isinstance(who, six.string_types): raise CephClientTypeError( name='who', actual=type(who), expected=six.string_types) kwargs['who'] = who return self._request('osd repair', **kwargs) def service_dump(self, body='json', timeout=None): """dump service map""" return self._request('service dump', body=body, timeout=timeout) def service_status(self, body='json', timeout=None): """dump service state""" return self._request('service status', body=body, timeout=timeout) def config_show(self, who, key, body='json', timeout=None): """Show running configuration""" kwargs = dict(body=body, timeout=timeout) if not isinstance(who, six.string_types): raise CephClientTypeError( name='who', actual=type(who), expected=six.string_types) kwargs['who'] = who if not isinstance(key, six.string_types): raise CephClientTypeError( name='key', actual=type(key), expected=six.string_types) kwargs['key'] = key return self._request('config show', **kwargs) def config_show_with_defaults(self, who, body='json', timeout=None): """Show running configuration (including compiled-in defaults)""" kwargs = dict(body=body, timeout=timeout) if not isinstance(who, six.string_types): raise CephClientTypeError( name='who', actual=type(who), expected=six.string_types) kwargs['who'] = who return self._request('config show-with-defaults', **kwargs) def pg_map(self, pgid, body='json', timeout=None): """show mapping of pg to osds""" kwargs = dict(body=body, timeout=timeout) if not isinstance(pgid, six.string_types): raise CephClientTypeError( name='pgid', actual=type(pgid), expected=six.string_types) if not re.match(r'[0-9]+\.[0-9a-fA-F]+', pgid): raise CephClientInvalidPgid( name='pgid', actual=pgid) kwargs['pgid'] = pgid return self._request('pg map', **kwargs) def osd_last_stat_seq(self, _id, body='json', timeout=None): """get the last pg stats sequence number reported for this osd""" kwargs = dict(body=body, timeout=timeout) if isinstance(_id, six.integer_types): pass elif isinstance(_id, six.string_types): _id = _id.lower() prefix = 'osd.' if not _id.startswith(prefix): raise CephClientInvalidOsdIdValue(osdid=_id) _id = int(_id[len(prefix):]) else: raise CephClientTypeError( name='_id', actual=type(_id), expected='int or string') kwargs['id'] = _id return self._request('osd last-stat-seq', **kwargs) def auth_export(self, entity=None, body='json', timeout=None): """write keyring for requested entity, or master keyring if none given""" kwargs = dict(body=body, timeout=timeout) if entity is not None: if not isinstance(entity, six.string_types): raise CephClientTypeError( name='entity', actual=type(entity), expected=six.string_types) kwargs['entity'] = entity return self._request('auth export', **kwargs) def auth_get(self, entity, body='json', timeout=None): """write keyring file with requested key""" kwargs = dict(body=body, timeout=timeout) if not isinstance(entity, six.string_types): raise CephClientTypeError( name='entity', actual=type(entity), expected=six.string_types) kwargs['entity'] = entity return self._request('auth get', **kwargs) def auth_get_key(self, entity, body='json', timeout=None): """display requested key""" kwargs = dict(body=body, timeout=timeout) if not isinstance(entity, six.string_types): raise CephClientTypeError( name='entity', actual=type(entity), expected=six.string_types) kwargs['entity'] = entity return self._request('auth get-key', **kwargs) def auth_print_key(self, entity, body='json', timeout=None): """display requested key""" kwargs = dict(body=body, timeout=timeout) if not isinstance(entity, six.string_types): raise CephClientTypeError( name='entity', actual=type(entity), expected=six.string_types) kwargs['entity'] = entity return self._request('auth print-key', **kwargs) def auth_list(self, body='json', timeout=None): """list authentication state""" return self._request('auth list', body=body, timeout=timeout) def auth_ls(self, body='json', timeout=None): """list authentication state""" return self._request('auth ls', body=body, timeout=timeout) def auth_import(self, body='json', timeout=None): """auth import: read keyring file from -i """ return self._request('auth import', body=body, timeout=timeout) def auth_add(self, entity, caps=None, body='json', timeout=None): """add auth info for from input file, or random key if no inputis given, and/or any caps specified in the command """ kwargs = dict(body=body, timeout=timeout) if not isinstance(entity, six.string_types): raise CephClientTypeError( name='entity', actual=type(entity), expected=six.string_types) kwargs['entity'] = entity if caps is not None: if isinstance(caps, list): for item in caps: if not isinstance(item, six.string_types): raise CephClientTypeError( name='caps', actual=item, expected='list of strings') else: if not isinstance(caps, six.string_types): raise CephClientTypeError( name='caps', actual=type(caps), expected=six.string_types) if not isinstance(caps, list): caps = [caps] kwargs['caps'] = caps return self._request('auth add', **kwargs) def auth_get_or_create_key( self, entity, caps=None, body='json', timeout=None): """get, or add, key for from system/caps pairs specified in thecommand. If key already exists, any given caps must match the existing caps for that key. """ kwargs = dict(body=body, timeout=timeout) if not isinstance(entity, six.string_types): raise CephClientTypeError( name='entity', actual=type(entity), expected=six.string_types) kwargs['entity'] = entity if caps is not None: if isinstance(caps, list): for item in caps: if not isinstance(item, six.string_types): raise CephClientTypeError( name='caps', actual=item, expected='list of strings') else: if not isinstance(caps, six.string_types): raise CephClientTypeError( name='caps', actual=type(caps), expected=six.string_types) if not isinstance(caps, list): caps = [caps] kwargs['caps'] = caps return self._request('auth get-or-create-key', **kwargs) def auth_get_or_create(self, entity, caps=None, body='json', timeout=None): """add auth info for from input file, or random key if no inputgiven, and/or any caps specified in the command """ kwargs = dict(body=body, timeout=timeout) if not isinstance(entity, six.string_types): raise CephClientTypeError( name='entity', actual=type(entity), expected=six.string_types) kwargs['entity'] = entity if caps is not None: if isinstance(caps, list): for item in caps: if not isinstance(item, six.string_types): raise CephClientTypeError( name='caps', actual=item, expected='list of strings') else: if not isinstance(caps, six.string_types): raise CephClientTypeError( name='caps', actual=type(caps), expected=six.string_types) if not isinstance(caps, list): caps = [caps] kwargs['caps'] = caps return self._request('auth get-or-create', **kwargs) def fs_authorize(self, filesystem, entity, caps, body='json', timeout=None): """add auth for to access file system based onfollowing directory and permissions pairs """ kwargs = dict(body=body, timeout=timeout) if not isinstance(filesystem, six.string_types): raise CephClientTypeError( name='filesystem', actual=type(filesystem), expected=six.string_types) kwargs['filesystem'] = filesystem if not isinstance(entity, six.string_types): raise CephClientTypeError( name='entity', actual=type(entity), expected=six.string_types) kwargs['entity'] = entity if isinstance(caps, list): for item in caps: if not isinstance(item, six.string_types): raise CephClientTypeError( name='caps', actual=item, expected='list of strings') else: if not isinstance(caps, six.string_types): raise CephClientTypeError( name='caps', actual=type(caps), expected=six.string_types) if not isinstance(caps, list): caps = [caps] kwargs['caps'] = caps return self._request('fs authorize', **kwargs) def auth_caps(self, entity, caps, body='json', timeout=None): """update caps for from caps specified in the command""" kwargs = dict(body=body, timeout=timeout) if not isinstance(entity, six.string_types): raise CephClientTypeError( name='entity', actual=type(entity), expected=six.string_types) kwargs['entity'] = entity if isinstance(caps, list): for item in caps: if not isinstance(item, six.string_types): raise CephClientTypeError( name='caps', actual=item, expected='list of strings') else: if not isinstance(caps, six.string_types): raise CephClientTypeError( name='caps', actual=type(caps), expected=six.string_types) if not isinstance(caps, list): caps = [caps] kwargs['caps'] = caps return self._request('auth caps', **kwargs) def auth_del(self, entity, body='json', timeout=None): """delete all caps for """ kwargs = dict(body=body, timeout=timeout) if not isinstance(entity, six.string_types): raise CephClientTypeError( name='entity', actual=type(entity), expected=six.string_types) kwargs['entity'] = entity return self._request('auth del', **kwargs) def auth_rm(self, entity, body='json', timeout=None): """remove all caps for """ kwargs = dict(body=body, timeout=timeout) if not isinstance(entity, six.string_types): raise CephClientTypeError( name='entity', actual=type(entity), expected=six.string_types) kwargs['entity'] = entity return self._request('auth rm', **kwargs) def compact(self, body='json', timeout=None): """cause compaction of monitor's leveldb/rocksdb storage""" return self._request('compact', body=body, timeout=timeout) def scrub(self, body='json', timeout=None): """scrub the monitor stores""" return self._request('scrub', body=body, timeout=timeout) def fsid(self, body='json', timeout=None): """show cluster FSID/UUID""" return self._request('fsid', body=body, timeout=timeout) def log(self, logtext, body='json', timeout=None): """log supplied text to the monitor log""" kwargs = dict(body=body, timeout=timeout) if isinstance(logtext, list): for item in logtext: if not isinstance(item, six.string_types): raise CephClientTypeError( name='logtext', actual=item, expected='list of strings') else: if not isinstance(logtext, six.string_types): raise CephClientTypeError( name='logtext', actual=type(logtext), expected=six.string_types) if not isinstance(logtext, list): logtext = [logtext] kwargs['logtext'] = logtext return self._request('log', **kwargs) LOG_LAST_LEVEL_VALUES = ['debug', 'info', 'sec', 'warn', 'error'] LOG_LAST_CHANNEL_VALUES = ['*', 'cluster', 'audit'] def log_last( self, num=None, level=None, channel=None, body='json', timeout=None): """print last few lines of the cluster log""" kwargs = dict(body=body, timeout=timeout) if num is not None: if not isinstance(num, six.integer_types): raise CephClientTypeError( name='num', actual=type(num), expected=int) if num < 1: raise CephClientValueOutOfBounds( name='num', actual=num, min=1, max='unlimited') kwargs['num'] = num if level is not None: if not isinstance(level, six.string_types): raise CephClientTypeError( name='level', actual=type(level), expected=six.string_types) supported = CephClient.LOG_LAST_LEVEL_VALUES if level not in supported: raise CephClientInvalidChoice( function='log_last', option='level', value=level, supported=', '.join(supported)) kwargs['level'] = level if channel is not None: if not isinstance(channel, six.string_types): raise CephClientTypeError( name='channel', actual=type(channel), expected=six.string_types) supported = CephClient.LOG_LAST_CHANNEL_VALUES if channel not in supported: raise CephClientInvalidChoice( function='log_last', option='channel', value=channel, supported=', '.join(supported)) kwargs['channel'] = channel return self._request('log last', **kwargs) def injectargs(self, injected_args, body='json', timeout=None): """inject config arguments into monitor""" kwargs = dict(body=body, timeout=timeout) if isinstance(injected_args, list): for item in injected_args: if not isinstance(item, six.string_types): raise CephClientTypeError( name='injected_args', actual=item, expected='list of strings') else: if not isinstance(injected_args, six.string_types): raise CephClientTypeError( name='injected_args', actual=type(injected_args), expected=six.string_types) if not isinstance(injected_args, list): injected_args = [injected_args] kwargs['injected_args'] = injected_args return self._request('injectargs', **kwargs) def status(self, body='json', timeout=None): """show cluster status""" return self._request('status', body=body, timeout=timeout) HEALTH_DETAIL_VALUES = ['detail'] def health(self, detail=None, body='json', timeout=None): """show cluster health""" kwargs = dict(body=body, timeout=timeout) if detail is not None: if not isinstance(detail, six.string_types): raise CephClientTypeError( name='detail', actual=type(detail), expected=six.string_types) supported = CephClient.HEALTH_DETAIL_VALUES if detail not in supported: raise CephClientInvalidChoice( function='health', option='detail', value=detail, supported=', '.join(supported)) kwargs['detail'] = detail return self._request('health', **kwargs) def time_sync_status(self, body='json', timeout=None): """show time sync status""" return self._request('time-sync-status', body=body, timeout=timeout) DF_DETAIL_VALUES = ['detail'] def df(self, detail=None, body='json', timeout=None): """show cluster free space stats""" kwargs = dict(body=body, timeout=timeout) if detail is not None: if not isinstance(detail, six.string_types): raise CephClientTypeError( name='detail', actual=type(detail), expected=six.string_types) supported = CephClient.DF_DETAIL_VALUES if detail not in supported: raise CephClientInvalidChoice( function='df', option='detail', value=detail, supported=', '.join(supported)) kwargs['detail'] = detail return self._request('df', **kwargs) def report(self, tags=None, body='json', timeout=None): """report full status of cluster, optional title tag strings""" kwargs = dict(body=body, timeout=timeout) if tags is not None: if isinstance(tags, list): for item in tags: if not isinstance(item, six.string_types): raise CephClientTypeError( name='tags', actual=item, expected='list of strings') else: if not isinstance(tags, six.string_types): raise CephClientTypeError( name='tags', actual=type(tags), expected=six.string_types) if not isinstance(tags, list): tags = [tags] kwargs['tags'] = tags return self._request('report', **kwargs) def features(self, body='json', timeout=None): """report of connected features""" return self._request('features', body=body, timeout=timeout) def quorum_status(self, body='json', timeout=None): """report status of monitor quorum""" return self._request('quorum_status', body=body, timeout=timeout) def mon_status(self, body='json', timeout=None): """report status of monitors""" return self._request('mon_status', body=body, timeout=timeout) SYNC_FORCE_VALIDATE1_VALUES = ['--yes-i-really-mean-it'] SYNC_FORCE_VALIDATE2_VALUES = ['--i-know-what-i-am-doing'] def sync_force( self, validate1=None, validate2=None, body='json', timeout=None): """force sync of and clear monitor store""" kwargs = dict(body=body, timeout=timeout) if validate1 is not None: if not isinstance(validate1, six.string_types): raise CephClientTypeError( name='validate1', actual=type(validate1), expected=six.string_types) supported = CephClient.SYNC_FORCE_VALIDATE1_VALUES if validate1 not in supported: raise CephClientInvalidChoice( function='sync_force', option='validate1', value=validate1, supported=', '.join(supported)) kwargs['validate1'] = validate1 if validate2 is not None: if not isinstance(validate2, six.string_types): raise CephClientTypeError( name='validate2', actual=type(validate2), expected=six.string_types) supported = CephClient.SYNC_FORCE_VALIDATE2_VALUES if validate2 not in supported: raise CephClientInvalidChoice( function='sync_force', option='validate2', value=validate2, supported=', '.join(supported)) kwargs['validate2'] = validate2 return self._request('sync force', **kwargs) HEAP_HEAPCMD_VALUES = \ ['dump', 'start_profiler', 'stop_profiler', 'release', 'stats'] def heap(self, heapcmd, body='json', timeout=None): """show heap usage info (available only if compiled with tcmalloc)""" kwargs = dict(body=body, timeout=timeout) if not isinstance(heapcmd, six.string_types): raise CephClientTypeError( name='heapcmd', actual=type(heapcmd), expected=six.string_types) supported = CephClient.HEAP_HEAPCMD_VALUES if heapcmd not in supported: raise CephClientInvalidChoice( function='heap', option='heapcmd', value=heapcmd, supported=', '.join(supported)) kwargs['heapcmd'] = heapcmd return self._request('heap', **kwargs) QUORUM_QUORUMCMD_VALUES = ['enter', 'exit'] def quorum(self, quorumcmd, body='json', timeout=None): """enter or exit quorum""" kwargs = dict(body=body, timeout=timeout) if not isinstance(quorumcmd, six.string_types): raise CephClientTypeError( name='quorumcmd', actual=type(quorumcmd), expected=six.string_types) supported = CephClient.QUORUM_QUORUMCMD_VALUES if quorumcmd not in supported: raise CephClientInvalidChoice( function='quorum', option='quorumcmd', value=quorumcmd, supported=', '.join(supported)) kwargs['quorumcmd'] = quorumcmd return self._request('quorum', **kwargs) def tell(self, target, args, body='json', timeout=None): """send a command to a specific daemon""" kwargs = dict(body=body, timeout=timeout) kwargs['target'] = target if isinstance(args, list): for item in args: if not isinstance(item, six.string_types): raise CephClientTypeError( name='args', actual=item, expected='list of strings') else: if not isinstance(args, six.string_types): raise CephClientTypeError( name='args', actual=type(args), expected=six.string_types) if not isinstance(args, list): args = [args] kwargs['args'] = args return self._request('tell', **kwargs) def version(self, body='json', timeout=None): """show mon daemon version""" return self._request('version', body=body, timeout=timeout) NODE_LS__TYPE_VALUES = ['all', 'osd', 'mon', 'mds', 'mgr'] def node_ls(self, _type=None, body='json', timeout=None): """list all nodes in cluster [type]""" kwargs = dict(body=body, timeout=timeout) if _type is not None: if not isinstance(_type, six.string_types): raise CephClientTypeError( name='_type', actual=type(_type), expected=six.string_types) supported = CephClient.NODE_LS__TYPE_VALUES if _type not in supported: raise CephClientInvalidChoice( function='node_ls', option='_type', value=_type, supported=', '.join(supported)) kwargs['type'] = _type return self._request('node ls', **kwargs) def mon_compact(self, body='json', timeout=None): """cause compaction of monitor's leveldb/rocksdb storage""" return self._request('mon compact', body=body, timeout=timeout) def mon_scrub(self, body='json', timeout=None): """scrub the monitor stores""" return self._request('mon scrub', body=body, timeout=timeout) MON_SYNC_FORCE_VALIDATE1_VALUES = ['--yes-i-really-mean-it'] MON_SYNC_FORCE_VALIDATE2_VALUES = ['--i-know-what-i-am-doing'] def mon_sync_force( self, validate1=None, validate2=None, body='json', timeout=None): """force sync of and clear monitor store""" kwargs = dict(body=body, timeout=timeout) if validate1 is not None: if not isinstance(validate1, six.string_types): raise CephClientTypeError( name='validate1', actual=type(validate1), expected=six.string_types) supported = CephClient.MON_SYNC_FORCE_VALIDATE1_VALUES if validate1 not in supported: raise CephClientInvalidChoice( function='mon_sync_force', option='validate1', value=validate1, supported=', '.join(supported)) kwargs['validate1'] = validate1 if validate2 is not None: if not isinstance(validate2, six.string_types): raise CephClientTypeError( name='validate2', actual=type(validate2), expected=six.string_types) supported = CephClient.MON_SYNC_FORCE_VALIDATE2_VALUES if validate2 not in supported: raise CephClientInvalidChoice( function='mon_sync_force', option='validate2', value=validate2, supported=', '.join(supported)) kwargs['validate2'] = validate2 return self._request('mon sync force', **kwargs) def mon_metadata(self, _id=None, body='json', timeout=None): """fetch metadata for mon """ kwargs = dict(body=body, timeout=timeout) if _id is not None: if not isinstance(_id, six.string_types): raise CephClientTypeError( name='_id', actual=type(_id), expected=six.string_types) kwargs['id'] = _id return self._request('mon metadata', **kwargs) def mon_count_metadata(self, _property, body='json', timeout=None): """count mons by metadata field property""" kwargs = dict(body=body, timeout=timeout) if not isinstance(_property, six.string_types): raise CephClientTypeError( name='_property', actual=type(_property), expected=six.string_types) kwargs['property'] = _property return self._request('mon count-metadata', **kwargs) def mon_versions(self, body='json', timeout=None): """check running versions of monitors""" return self._request('mon versions', body=body, timeout=timeout) def versions(self, body='json', timeout=None): """check running versions of ceph daemons""" return self._request('versions', body=body, timeout=timeout) def mds_stat(self, body='json', timeout=None): """show MDS status""" return self._request('mds stat', body=body, timeout=timeout) def mds_dump(self, epoch=None, body='json', timeout=None): """dump legacy MDS cluster info, optionally from epoch""" kwargs = dict(body=body, timeout=timeout) if epoch is not None: if not isinstance(epoch, six.integer_types): raise CephClientTypeError( name='epoch', actual=type(epoch), expected=int) if epoch < 0: raise CephClientValueOutOfBounds( name='epoch', actual=epoch, min=0, max='unlimited') kwargs['epoch'] = epoch return self._request('mds dump', **kwargs) def fs_dump(self, epoch=None, body='json', timeout=None): """dump all CephFS status, optionally from epoch""" kwargs = dict(body=body, timeout=timeout) if epoch is not None: if not isinstance(epoch, six.integer_types): raise CephClientTypeError( name='epoch', actual=type(epoch), expected=int) if epoch < 0: raise CephClientValueOutOfBounds( name='epoch', actual=epoch, min=0, max='unlimited') kwargs['epoch'] = epoch return self._request('fs dump', **kwargs) def mds_getmap(self, epoch=None, body='json', timeout=None): """get MDS map, optionally from epoch""" kwargs = dict(body=body, timeout=timeout) if epoch is not None: if not isinstance(epoch, six.integer_types): raise CephClientTypeError( name='epoch', actual=type(epoch), expected=int) if epoch < 0: raise CephClientValueOutOfBounds( name='epoch', actual=epoch, min=0, max='unlimited') kwargs['epoch'] = epoch return self._request('mds getmap', **kwargs) def mds_metadata(self, who=None, body='json', timeout=None): """fetch metadata for mds """ kwargs = dict(body=body, timeout=timeout) if who is not None: if not isinstance(who, six.string_types): raise CephClientTypeError( name='who', actual=type(who), expected=six.string_types) kwargs['who'] = who return self._request('mds metadata', **kwargs) def mds_count_metadata(self, _property, body='json', timeout=None): """count MDSs by metadata field property""" kwargs = dict(body=body, timeout=timeout) if not isinstance(_property, six.string_types): raise CephClientTypeError( name='_property', actual=type(_property), expected=six.string_types) kwargs['property'] = _property return self._request('mds count-metadata', **kwargs) def mds_versions(self, body='json', timeout=None): """check running versions of MDSs""" return self._request('mds versions', body=body, timeout=timeout) def mds_tell(self, who, args, body='json', timeout=None): """send command to particular mds""" kwargs = dict(body=body, timeout=timeout) if not isinstance(who, six.string_types): raise CephClientTypeError( name='who', actual=type(who), expected=six.string_types) kwargs['who'] = who if isinstance(args, list): for item in args: if not isinstance(item, six.string_types): raise CephClientTypeError( name='args', actual=item, expected='list of strings') else: if not isinstance(args, six.string_types): raise CephClientTypeError( name='args', actual=type(args), expected=six.string_types) if not isinstance(args, list): args = [args] kwargs['args'] = args return self._request('mds tell', **kwargs) def mds_compat_show(self, body='json', timeout=None): """show mds compatibility settings""" return self._request('mds compat show', body=body, timeout=timeout) def mds_stop(self, role, body='json', timeout=None): """stop mds""" kwargs = dict(body=body, timeout=timeout) if not isinstance(role, six.string_types): raise CephClientTypeError( name='role', actual=type(role), expected=six.string_types) kwargs['role'] = role return self._request('mds stop', **kwargs) def mds_deactivate(self, role, body='json', timeout=None): """clean up specified MDS rank (use with `set max_mds` to shrink cluster)""" kwargs = dict(body=body, timeout=timeout) if not isinstance(role, six.string_types): raise CephClientTypeError( name='role', actual=type(role), expected=six.string_types) kwargs['role'] = role return self._request('mds deactivate', **kwargs) def mds_set_max_mds(self, maxmds, body='json', timeout=None): """set max MDS index""" kwargs = dict(body=body, timeout=timeout) if not isinstance(maxmds, six.integer_types): raise CephClientTypeError( name='maxmds', actual=type(maxmds), expected=int) if maxmds < 0: raise CephClientValueOutOfBounds( name='maxmds', actual=maxmds, min=0, max='unlimited') kwargs['maxmds'] = maxmds return self._request('mds set_max_mds', **kwargs) MDS_SET_VAR_VALUES = \ ['max_mds', 'max_file_size', 'inline_data', 'allow_new_snaps', 'allow_multimds', 'allow_multimds_snaps', 'allow_dirfrags'] def mds_set(self, var, val, confirm=None, body='json', timeout=None): """set mds parameter to """ kwargs = dict(body=body, timeout=timeout) if not isinstance(var, six.string_types): raise CephClientTypeError( name='var', actual=type(var), expected=six.string_types) supported = CephClient.MDS_SET_VAR_VALUES if var not in supported: raise CephClientInvalidChoice( function='mds_set', option='var', value=var, supported=', '.join(supported)) kwargs['var'] = var if not isinstance(val, six.string_types): raise CephClientTypeError( name='val', actual=type(val), expected=six.string_types) kwargs['val'] = val if confirm is not None: if not isinstance(confirm, six.string_types): raise CephClientTypeError( name='confirm', actual=type(confirm), expected=six.string_types) kwargs['confirm'] = confirm return self._request('mds set', **kwargs) def mds_set_state(self, gid, state, body='json', timeout=None): """set mds state of to """ kwargs = dict(body=body, timeout=timeout) if not isinstance(gid, six.integer_types): raise CephClientTypeError( name='gid', actual=type(gid), expected=int) if gid < 0: raise CephClientValueOutOfBounds( name='gid', actual=gid, min=0, max='unlimited') kwargs['gid'] = gid if not isinstance(state, six.integer_types): raise CephClientTypeError( name='state', actual=type(state), expected=int) if state < 0 or state > 20: raise CephClientValueOutOfBounds( name='state', actual=state, min=0, max=20) kwargs['state'] = state return self._request('mds set_state', **kwargs) def mds_fail(self, role_or_gid, body='json', timeout=None): """Mark MDS failed: trigger a failover if a standby is available""" kwargs = dict(body=body, timeout=timeout) if not isinstance(role_or_gid, six.string_types): raise CephClientTypeError( name='role_or_gid', actual=type(role_or_gid), expected=six.string_types) kwargs['role_or_gid'] = role_or_gid return self._request('mds fail', **kwargs) def mds_repaired(self, role, body='json', timeout=None): """mark a damaged MDS rank as no longer damaged""" kwargs = dict(body=body, timeout=timeout) if not isinstance(role, six.string_types): raise CephClientTypeError( name='role', actual=type(role), expected=six.string_types) kwargs['role'] = role return self._request('mds repaired', **kwargs) def mds_rm(self, gid, body='json', timeout=None): """remove nonactive mds""" kwargs = dict(body=body, timeout=timeout) if not isinstance(gid, six.integer_types): raise CephClientTypeError( name='gid', actual=type(gid), expected=int) if gid < 0: raise CephClientValueOutOfBounds( name='gid', actual=gid, min=0, max='unlimited') kwargs['gid'] = gid return self._request('mds rm', **kwargs) def mds_rmfailed(self, role, confirm=None, body='json', timeout=None): """remove failed mds""" kwargs = dict(body=body, timeout=timeout) if not isinstance(role, six.string_types): raise CephClientTypeError( name='role', actual=type(role), expected=six.string_types) kwargs['role'] = role if confirm is not None: if not isinstance(confirm, six.string_types): raise CephClientTypeError( name='confirm', actual=type(confirm), expected=six.string_types) kwargs['confirm'] = confirm return self._request('mds rmfailed', **kwargs) def mds_cluster_down(self, body='json', timeout=None): """take MDS cluster down""" return self._request('mds cluster_down', body=body, timeout=timeout) def mds_cluster_up(self, body='json', timeout=None): """bring MDS cluster up""" return self._request('mds cluster_up', body=body, timeout=timeout) def mds_compat_rm_compat(self, feature, body='json', timeout=None): """remove compatible feature""" kwargs = dict(body=body, timeout=timeout) if not isinstance(feature, six.integer_types): raise CephClientTypeError( name='feature', actual=type(feature), expected=int) if feature < 0: raise CephClientValueOutOfBounds( name='feature', actual=feature, min=0, max='unlimited') kwargs['feature'] = feature return self._request('mds compat rm_compat', **kwargs) def mds_compat_rm_incompat(self, feature, body='json', timeout=None): """remove incompatible feature""" kwargs = dict(body=body, timeout=timeout) if not isinstance(feature, six.integer_types): raise CephClientTypeError( name='feature', actual=type(feature), expected=int) if feature < 0: raise CephClientValueOutOfBounds( name='feature', actual=feature, min=0, max='unlimited') kwargs['feature'] = feature return self._request('mds compat rm_incompat', **kwargs) def mds_add_data_pool(self, pool, body='json', timeout=None): """add data pool """ kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool return self._request('mds add_data_pool', **kwargs) def mds_rm_data_pool(self, pool, body='json', timeout=None): """remove data pool """ kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool return self._request('mds rm_data_pool', **kwargs) def mds_remove_data_pool(self, pool, body='json', timeout=None): """remove data pool """ kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool return self._request('mds remove_data_pool', **kwargs) MDS_NEWFS_SURE_VALUES = ['--yes-i-really-mean-it'] def mds_newfs(self, metadata, data, sure=None, body='json', timeout=None): """make new filesystem using pools and """ kwargs = dict(body=body, timeout=timeout) if not isinstance(metadata, six.integer_types): raise CephClientTypeError( name='metadata', actual=type(metadata), expected=int) if metadata < 0: raise CephClientValueOutOfBounds( name='metadata', actual=metadata, min=0, max='unlimited') kwargs['metadata'] = metadata if not isinstance(data, six.integer_types): raise CephClientTypeError( name='data', actual=type(data), expected=int) if data < 0: raise CephClientValueOutOfBounds( name='data', actual=data, min=0, max='unlimited') kwargs['data'] = data if sure is not None: if not isinstance(sure, six.string_types): raise CephClientTypeError( name='sure', actual=type(sure), expected=six.string_types) supported = CephClient.MDS_NEWFS_SURE_VALUES if sure not in supported: raise CephClientInvalidChoice( function='mds_newfs', option='sure', value=sure, supported=', '.join(supported)) kwargs['sure'] = sure return self._request('mds newfs', **kwargs) FS_NEW_FORCE_VALUES = ['--force'] FS_NEW_SURE_VALUES = ['--allow-dangerous-metadata-overlay'] def fs_new(self, fs_name, metadata, data, force=None, sure=None, body='json', timeout=None): """make new filesystem using named pools and """ kwargs = dict(body=body, timeout=timeout) if not isinstance(fs_name, six.string_types): raise CephClientTypeError( name='fs_name', actual=type(fs_name), expected=six.string_types) kwargs['fs_name'] = fs_name if not isinstance(metadata, six.string_types): raise CephClientTypeError( name='metadata', actual=type(metadata), expected=six.string_types) kwargs['metadata'] = metadata if not isinstance(data, six.string_types): raise CephClientTypeError( name='data', actual=type(data), expected=six.string_types) kwargs['data'] = data if force is not None: if not isinstance(force, six.string_types): raise CephClientTypeError( name='force', actual=type(force), expected=six.string_types) supported = CephClient.FS_NEW_FORCE_VALUES if force not in supported: raise CephClientInvalidChoice( function='fs_new', option='force', value=force, supported=', '.join(supported)) kwargs['force'] = force if sure is not None: if not isinstance(sure, six.string_types): raise CephClientTypeError( name='sure', actual=type(sure), expected=six.string_types) supported = CephClient.FS_NEW_SURE_VALUES if sure not in supported: raise CephClientInvalidChoice( function='fs_new', option='sure', value=sure, supported=', '.join(supported)) kwargs['sure'] = sure return self._request('fs new', **kwargs) FS_RM_SURE_VALUES = ['--yes-i-really-mean-it'] def fs_rm(self, fs_name, sure=None, body='json', timeout=None): """disable the named filesystem""" kwargs = dict(body=body, timeout=timeout) if not isinstance(fs_name, six.string_types): raise CephClientTypeError( name='fs_name', actual=type(fs_name), expected=six.string_types) kwargs['fs_name'] = fs_name if sure is not None: if not isinstance(sure, six.string_types): raise CephClientTypeError( name='sure', actual=type(sure), expected=six.string_types) supported = CephClient.FS_RM_SURE_VALUES if sure not in supported: raise CephClientInvalidChoice( function='fs_rm', option='sure', value=sure, supported=', '.join(supported)) kwargs['sure'] = sure return self._request('fs rm', **kwargs) FS_RESET_SURE_VALUES = ['--yes-i-really-mean-it'] def fs_reset(self, fs_name, sure=None, body='json', timeout=None): """disaster recovery only: reset to a single-MDS map""" kwargs = dict(body=body, timeout=timeout) if not isinstance(fs_name, six.string_types): raise CephClientTypeError( name='fs_name', actual=type(fs_name), expected=six.string_types) kwargs['fs_name'] = fs_name if sure is not None: if not isinstance(sure, six.string_types): raise CephClientTypeError( name='sure', actual=type(sure), expected=six.string_types) supported = CephClient.FS_RESET_SURE_VALUES if sure not in supported: raise CephClientInvalidChoice( function='fs_reset', option='sure', value=sure, supported=', '.join(supported)) kwargs['sure'] = sure return self._request('fs reset', **kwargs) def fs_ls(self, body='json', timeout=None): """list filesystems""" return self._request('fs ls', body=body, timeout=timeout) def fs_get(self, fs_name, body='json', timeout=None): """get info about one filesystem""" kwargs = dict(body=body, timeout=timeout) if not isinstance(fs_name, six.string_types): raise CephClientTypeError( name='fs_name', actual=type(fs_name), expected=six.string_types) kwargs['fs_name'] = fs_name return self._request('fs get', **kwargs) FS_SET_VAR_VALUES = \ ['max_mds', 'max_file_size', 'allow_new_snaps', 'inline_data', 'cluster_down', 'allow_dirfrags', 'balancer', 'standby_count_wanted', 'session_timeout', 'session_autoclose', 'down', 'joinable', 'min_compat_client'] def fs_set(self, fs_name, var, val, confirm=None, body='json', timeout=None): """set fs parameter to """ kwargs = dict(body=body, timeout=timeout) if not isinstance(fs_name, six.string_types): raise CephClientTypeError( name='fs_name', actual=type(fs_name), expected=six.string_types) kwargs['fs_name'] = fs_name if not isinstance(var, six.string_types): raise CephClientTypeError( name='var', actual=type(var), expected=six.string_types) supported = CephClient.FS_SET_VAR_VALUES if var not in supported: raise CephClientInvalidChoice( function='fs_set', option='var', value=var, supported=', '.join(supported)) kwargs['var'] = var if not isinstance(val, six.string_types): raise CephClientTypeError( name='val', actual=type(val), expected=six.string_types) kwargs['val'] = val if confirm is not None: if not isinstance(confirm, six.string_types): raise CephClientTypeError( name='confirm', actual=type(confirm), expected=six.string_types) kwargs['confirm'] = confirm return self._request('fs set', **kwargs) FS_FLAG_SET_FLAG_NAME_VALUES = ['enable_multiple'] FS_FLAG_SET_CONFIRM_VALUES = ['--yes-i-really-mean-it'] def fs_flag_set(self, flag_name, val, confirm=None, body='json', timeout=None): """Set a global CephFS flag""" kwargs = dict(body=body, timeout=timeout) if not isinstance(flag_name, six.string_types): raise CephClientTypeError( name='flag_name', actual=type(flag_name), expected=six.string_types) supported = CephClient.FS_FLAG_SET_FLAG_NAME_VALUES if flag_name not in supported: raise CephClientInvalidChoice( function='fs_flag_set', option='flag_name', value=flag_name, supported=', '.join(supported)) kwargs['flag_name'] = flag_name if not isinstance(val, six.string_types): raise CephClientTypeError( name='val', actual=type(val), expected=six.string_types) kwargs['val'] = val if confirm is not None: if not isinstance(confirm, six.string_types): raise CephClientTypeError( name='confirm', actual=type(confirm), expected=six.string_types) supported = CephClient.FS_FLAG_SET_CONFIRM_VALUES if confirm not in supported: raise CephClientInvalidChoice( function='fs_flag_set', option='confirm', value=confirm, supported=', '.join(supported)) kwargs['confirm'] = confirm return self._request('fs flag set', **kwargs) def fs_add_data_pool(self, fs_name, pool, body='json', timeout=None): """add data pool """ kwargs = dict(body=body, timeout=timeout) if not isinstance(fs_name, six.string_types): raise CephClientTypeError( name='fs_name', actual=type(fs_name), expected=six.string_types) kwargs['fs_name'] = fs_name if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool return self._request('fs add_data_pool', **kwargs) def fs_rm_data_pool(self, fs_name, pool, body='json', timeout=None): """remove data pool """ kwargs = dict(body=body, timeout=timeout) if not isinstance(fs_name, six.string_types): raise CephClientTypeError( name='fs_name', actual=type(fs_name), expected=six.string_types) kwargs['fs_name'] = fs_name if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool return self._request('fs rm_data_pool', **kwargs) def fs_set_default(self, fs_name, body='json', timeout=None): """set the default to the named filesystem""" kwargs = dict(body=body, timeout=timeout) if not isinstance(fs_name, six.string_types): raise CephClientTypeError( name='fs_name', actual=type(fs_name), expected=six.string_types) kwargs['fs_name'] = fs_name return self._request('fs set_default', **kwargs) def mon_dump(self, epoch=None, body='json', timeout=None): """dump formatted monmap (optionally from epoch)""" kwargs = dict(body=body, timeout=timeout) if epoch is not None: if not isinstance(epoch, six.integer_types): raise CephClientTypeError( name='epoch', actual=type(epoch), expected=int) if epoch < 0: raise CephClientValueOutOfBounds( name='epoch', actual=epoch, min=0, max='unlimited') kwargs['epoch'] = epoch return self._request('mon dump', **kwargs) def mon_stat(self, body='json', timeout=None): """summarize monitor status""" return self._request('mon stat', body=body, timeout=timeout) def mon_getmap(self, epoch=None, body='json', timeout=None): """get monmap""" kwargs = dict(body=body, timeout=timeout) if epoch is not None: if not isinstance(epoch, six.integer_types): raise CephClientTypeError( name='epoch', actual=type(epoch), expected=int) if epoch < 0: raise CephClientValueOutOfBounds( name='epoch', actual=epoch, min=0, max='unlimited') kwargs['epoch'] = epoch return self._request('mon getmap', **kwargs) def mon_add(self, name, addr, body='json', timeout=None): """add new monitor named at """ kwargs = dict(body=body, timeout=timeout) if not isinstance(name, six.string_types): raise CephClientTypeError( name='name', actual=type(name), expected=six.string_types) kwargs['name'] = name try: ipaddress.ip_address(addr) except ValueError: raise CephClientInvalidIPAddr( name='addr', actual=addr) kwargs['addr'] = addr return self._request('mon add', **kwargs) def mon_rm(self, name, body='json', timeout=None): """remove monitor named """ kwargs = dict(body=body, timeout=timeout) if not isinstance(name, six.string_types): raise CephClientTypeError( name='name', actual=type(name), expected=six.string_types) kwargs['name'] = name return self._request('mon rm', **kwargs) def mon_remove(self, name, body='json', timeout=None): """remove monitor named """ kwargs = dict(body=body, timeout=timeout) if not isinstance(name, six.string_types): raise CephClientTypeError( name='name', actual=type(name), expected=six.string_types) kwargs['name'] = name return self._request('mon remove', **kwargs) MON_FEATURE_LS_WITH_VALUE_VALUES = ['--with-value'] def mon_feature_ls(self, with_value=None, body='json', timeout=None): """list available mon map features to be set/unset""" kwargs = dict(body=body, timeout=timeout) if with_value is not None: if not isinstance(with_value, six.string_types): raise CephClientTypeError( name='with_value', actual=type(with_value), expected=six.string_types) supported = CephClient.MON_FEATURE_LS_WITH_VALUE_VALUES if with_value not in supported: raise CephClientInvalidChoice( function='mon_feature_ls', option='with_value', value=with_value, supported=', '.join(supported)) kwargs['with_value'] = with_value return self._request('mon feature ls', **kwargs) MON_FEATURE_SET_SURE_VALUES = ['--yes-i-really-mean-it'] def mon_feature_set(self, feature_name, sure=None, body='json', timeout=None): """set provided feature on mon map""" kwargs = dict(body=body, timeout=timeout) if not isinstance(feature_name, six.string_types): raise CephClientTypeError( name='feature_name', actual=type(feature_name), expected=six.string_types) kwargs['feature_name'] = feature_name if sure is not None: if not isinstance(sure, six.string_types): raise CephClientTypeError( name='sure', actual=type(sure), expected=six.string_types) supported = CephClient.MON_FEATURE_SET_SURE_VALUES if sure not in supported: raise CephClientInvalidChoice( function='mon_feature_set', option='sure', value=sure, supported=', '.join(supported)) kwargs['sure'] = sure return self._request('mon feature set', **kwargs) def osd_stat(self, body='json', timeout=None): """print summary of OSD map""" return self._request('osd stat', body=body, timeout=timeout) def osd_dump(self, epoch=None, body='json', timeout=None): """print summary of OSD map""" kwargs = dict(body=body, timeout=timeout) if epoch is not None: if not isinstance(epoch, six.integer_types): raise CephClientTypeError( name='epoch', actual=type(epoch), expected=int) if epoch < 0: raise CephClientValueOutOfBounds( name='epoch', actual=epoch, min=0, max='unlimited') kwargs['epoch'] = epoch return self._request('osd dump', **kwargs) OSD_TREE_STATES_VALUES = ['up', 'down', 'in', 'out', 'destroyed'] def osd_tree(self, epoch=None, states=None, body='json', timeout=None): """print OSD tree""" kwargs = dict(body=body, timeout=timeout) if epoch is not None: if not isinstance(epoch, six.integer_types): raise CephClientTypeError( name='epoch', actual=type(epoch), expected=int) if epoch < 0: raise CephClientValueOutOfBounds( name='epoch', actual=epoch, min=0, max='unlimited') kwargs['epoch'] = epoch if states is not None: if not isinstance(states, six.string_types): raise CephClientTypeError( name='states', actual=type(states), expected=six.string_types) supported = CephClient.OSD_TREE_STATES_VALUES if states not in supported: raise CephClientInvalidChoice( function='osd_tree', option='states', value=states, supported=', '.join(supported)) if not isinstance(states, list): states = [states] kwargs['states'] = states return self._request('osd tree', **kwargs) OSD_TREE_FROM_STATES_VALUES = [ 'up', 'down', 'in', 'out', 'destroyed'] def osd_tree_from( self, bucket, epoch=None, states=None, body='json', timeout=None): """print OSD tree in bucket""" kwargs = dict(body=body, timeout=timeout) if not isinstance(bucket, six.string_types): raise CephClientTypeError( name='bucket', actual=type(bucket), expected=six.string_types) kwargs['bucket'] = bucket if epoch is not None: if not isinstance(epoch, six.integer_types): raise CephClientTypeError( name='epoch', actual=type(epoch), expected=int) if epoch < 0: raise CephClientValueOutOfBounds( name='epoch', actual=epoch, min=0, max='unlimited') kwargs['epoch'] = epoch if states is not None: if not isinstance(states, six.string_types): raise CephClientTypeError( name='states', actual=type(states), expected=six.string_types) supported = CephClient.OSD_TREE_FROM_STATES_VALUES if states not in supported: raise CephClientInvalidChoice( function='osd_tree_from', option='states', value=states, supported=', '.join(supported)) if not isinstance(states, list): states = [states] kwargs['states'] = states return self._request('osd tree-from', **kwargs) def osd_ls(self, epoch=None, body='json', timeout=None): """show all OSD ids""" kwargs = dict(body=body, timeout=timeout) if epoch is not None: if not isinstance(epoch, six.integer_types): raise CephClientTypeError( name='epoch', actual=type(epoch), expected=int) if epoch < 0: raise CephClientValueOutOfBounds( name='epoch', actual=epoch, min=0, max='unlimited') kwargs['epoch'] = epoch return self._request('osd ls', **kwargs) def osd_getmap(self, epoch=None, body='json', timeout=None): """get OSD map""" kwargs = dict(body=body, timeout=timeout) if epoch is not None: if not isinstance(epoch, six.integer_types): raise CephClientTypeError( name='epoch', actual=type(epoch), expected=int) if epoch < 0: raise CephClientValueOutOfBounds( name='epoch', actual=epoch, min=0, max='unlimited') kwargs['epoch'] = epoch return self._request('osd getmap', **kwargs) def osd_getcrushmap(self, epoch=None, body='json', timeout=None): """get CRUSH map""" kwargs = dict(body=body, timeout=timeout) if epoch is not None: if not isinstance(epoch, six.integer_types): raise CephClientTypeError( name='epoch', actual=type(epoch), expected=int) if epoch < 0: raise CephClientValueOutOfBounds( name='epoch', actual=epoch, min=0, max='unlimited') kwargs['epoch'] = epoch return self._request('osd getcrushmap', **kwargs) def osd_getmaxosd(self, body='json', timeout=None): """show largest OSD id""" return self._request('osd getmaxosd', body=body, timeout=timeout) def osd_ls_tree(self, name, epoch=None, body='json', timeout=None): """show OSD ids under bucket in the CRUSH map""" kwargs = dict(body=body, timeout=timeout) if not isinstance(name, six.string_types): raise CephClientTypeError( name='name', actual=type(name), expected=six.string_types) kwargs['name'] = name if epoch is not None: if not isinstance(epoch, six.integer_types): raise CephClientTypeError( name='epoch', actual=type(epoch), expected=int) if epoch < 0: raise CephClientValueOutOfBounds( name='epoch', actual=epoch, min=0, max='unlimited') kwargs['epoch'] = epoch return self._request('osd ls-tree', **kwargs) def osd_find(self, _id, body='json', timeout=None): """find osd in the CRUSH map and show its location""" kwargs = dict(body=body, timeout=timeout) if isinstance(_id, six.integer_types): pass elif isinstance(_id, six.string_types): _id = _id.lower() prefix = 'osd.' if not _id.startswith(prefix): raise CephClientInvalidOsdIdValue(osdid=_id) _id = int(_id[len(prefix):]) else: raise CephClientTypeError( name='_id', actual=type(_id), expected='int or string') kwargs['id'] = _id return self._request('osd find', **kwargs) def osd_metadata(self, _id=None, body='json', timeout=None): """fetch metadata for osd {id} (default all)""" kwargs = dict(body=body, timeout=timeout) if _id is not None: if isinstance(_id, six.integer_types): pass elif isinstance(_id, six.string_types): _id = _id.lower() prefix = 'osd.' if not _id.startswith(prefix): raise CephClientInvalidOsdIdValue(osdid=_id) _id = int(_id[len(prefix):]) else: raise CephClientTypeError( name='_id', actual=type(_id), expected='int or string') kwargs['id'] = _id return self._request('osd metadata', **kwargs) def osd_count_metadata(self, _property, body='json', timeout=None): """count OSDs by metadata field property""" kwargs = dict(body=body, timeout=timeout) if not isinstance(_property, six.string_types): raise CephClientTypeError( name='_property', actual=type(_property), expected=six.string_types) kwargs['property'] = _property return self._request('osd count-metadata', **kwargs) def osd_versions(self, body='json', timeout=None): """check running versions of OSDs""" return self._request('osd versions', body=body, timeout=timeout) def osd_map(self, pool, _object, nspace=None, body='json', timeout=None): """find pg for in with [namespace]""" kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool kwargs['object'] = _object if nspace is not None: if not isinstance(nspace, six.string_types): raise CephClientTypeError( name='nspace', actual=type(nspace), expected=six.string_types) kwargs['nspace'] = nspace return self._request('osd map', **kwargs) def osd_lspools(self, auid=None, body='json', timeout=None): """list pools""" kwargs = dict(body=body, timeout=timeout) if auid is not None: if not isinstance(auid, six.integer_types): raise CephClientTypeError( name='auid', actual=type(auid), expected=int) kwargs['auid'] = auid return self._request('osd lspools', **kwargs) def osd_crush_rule_list(self, body='json', timeout=None): """list crush rules""" return self._request('osd crush rule list', body=body, timeout=timeout) def osd_crush_rule_ls(self, body='json', timeout=None): """list crush rules""" return self._request('osd crush rule ls', body=body, timeout=timeout) def osd_crush_rule_ls_by_class( self, _class, body='json', timeout=None): """list all crush rules that reference the same """ kwargs = dict(body=body, timeout=timeout) if not isinstance(_class, six.string_types): raise CephClientTypeError( name='_class', actual=type(_class), expected=six.string_types) kwargs['class'] = _class return self._request('osd crush rule ls-by-class', **kwargs) def osd_crush_rule_dump(self, name=None, body='json', timeout=None): """dump crush rule (default all)""" kwargs = dict(body=body, timeout=timeout) if name is not None: if not isinstance(name, six.string_types): raise CephClientTypeError( name='name', actual=type(name), expected=six.string_types) kwargs['name'] = name return self._request('osd crush rule dump', **kwargs) def osd_crush_dump(self, body='json', timeout=None): """dump crush map""" return self._request('osd crush dump', body=body, timeout=timeout) def osd_crush_add_bucket( self, name, _type, args=None, body='json', timeout=None): """add no-parent (probably root) crush bucket of type tolocation """ kwargs = dict(body=body, timeout=timeout) if not isinstance(name, six.string_types): raise CephClientTypeError( name='name', actual=type(name), expected=six.string_types) kwargs['name'] = name if not isinstance(_type, six.string_types): raise CephClientTypeError( name='_type', actual=type(_type), expected=six.string_types) kwargs['type'] = _type if args is not None: if isinstance(args, list): for item in args: if not isinstance(item, six.string_types): raise CephClientTypeError( name='args', actual=item, expected='list of strings') else: if not isinstance(args, six.string_types): raise CephClientTypeError( name='args', actual=type(args), expected=six.string_types) if not isinstance(args, list): args = [args] kwargs['args'] = args return self._request('osd crush add-bucket', **kwargs) def osd_crush_rename_bucket( self, srcname, dstname, body='json', timeout=None): """rename bucket to """ kwargs = dict(body=body, timeout=timeout) if not isinstance(srcname, six.string_types): raise CephClientTypeError( name='srcname', actual=type(srcname), expected=six.string_types) kwargs['srcname'] = srcname if not isinstance(dstname, six.string_types): raise CephClientTypeError( name='dstname', actual=type(dstname), expected=six.string_types) kwargs['dstname'] = dstname return self._request('osd crush rename-bucket', **kwargs) def osd_crush_set(self, _id, weight, args, body='json', timeout=None): """update crushmap position and weight for to withlocation """ kwargs = dict(body=body, timeout=timeout) if isinstance(_id, six.integer_types): pass elif isinstance(_id, six.string_types): _id = _id.lower() prefix = 'osd.' if not _id.startswith(prefix): raise CephClientInvalidOsdIdValue(osdid=_id) _id = int(_id[len(prefix):]) else: raise CephClientTypeError( name='_id', actual=type(_id), expected='int or string') kwargs['id'] = _id if not isinstance(weight, (six.integer_types, float)): raise CephClientTypeError( name='weight', actual=type(weight), expected=int) if weight < 0.0: raise CephClientValueOutOfBounds( name='weight', actual=weight, min=0.0, max='unlimited') kwargs['weight'] = weight if isinstance(args, list): for item in args: if not isinstance(item, six.string_types): raise CephClientTypeError( name='args', actual=item, expected='list of strings') else: if not isinstance(args, six.string_types): raise CephClientTypeError( name='args', actual=type(args), expected=six.string_types) if not isinstance(args, list): args = [args] kwargs['args'] = args return self._request('osd crush set', **kwargs) def osd_crush_add(self, _id, weight, args, body='json', timeout=None): """add or update crushmap position and weight for with and location """ kwargs = dict(body=body, timeout=timeout) if isinstance(_id, six.integer_types): pass elif isinstance(_id, six.string_types): _id = _id.lower() prefix = 'osd.' if not _id.startswith(prefix): raise CephClientInvalidOsdIdValue(osdid=_id) _id = int(_id[len(prefix):]) else: raise CephClientTypeError( name='_id', actual=type(_id), expected='int or string') kwargs['id'] = _id if not isinstance(weight, (six.integer_types, float)): raise CephClientTypeError( name='weight', actual=type(weight), expected=int) if weight < 0.0: raise CephClientValueOutOfBounds( name='weight', actual=weight, min=0.0, max='unlimited') kwargs['weight'] = weight if isinstance(args, list): for item in args: if not isinstance(item, six.string_types): raise CephClientTypeError( name='args', actual=item, expected='list of strings') else: if not isinstance(args, six.string_types): raise CephClientTypeError( name='args', actual=type(args), expected=six.string_types) if not isinstance(args, list): args = [args] kwargs['args'] = args return self._request('osd crush add', **kwargs) def osd_crush_set_all_straw_buckets_to_straw2( self, body='json', timeout=None): """convert all CRUSH current straw buckets to use the straw2 algorithm""" return self._request( 'osd crush set-all-straw-buckets-to-straw2', body=body, timeout=timeout) def osd_crush_set_device_class( self, _class, ids, body='json', timeout=None): """set the of the osd(s) [...],or use to setall. """ kwargs = dict(body=body, timeout=timeout) if not isinstance(_class, six.string_types): raise CephClientTypeError( name='_class', actual=type(_class), expected=six.string_types) kwargs['class'] = _class if isinstance(ids, list): for item in ids: if not isinstance(item, six.string_types): raise CephClientTypeError( name='ids', actual=item, expected='list of strings') else: if not isinstance(ids, six.string_types): raise CephClientTypeError( name='ids', actual=type(ids), expected=six.string_types) if not isinstance(ids, list): ids = [ids] kwargs['ids'] = ids return self._request('osd crush set-device-class', **kwargs) def osd_crush_rm_device_class(self, ids, body='json', timeout=None): """remove class of the osd(s) [...],or use to removeall. """ kwargs = dict(body=body, timeout=timeout) if isinstance(ids, list): for item in ids: if not isinstance(item, six.string_types): raise CephClientTypeError( name='ids', actual=item, expected='list of strings') else: if not isinstance(ids, six.string_types): raise CephClientTypeError( name='ids', actual=type(ids), expected=six.string_types) if not isinstance(ids, list): ids = [ids] kwargs['ids'] = ids return self._request('osd crush rm-device-class', **kwargs) def osd_crush_class_rename( self, srcname, dstname, body='json', timeout=None): """rename crush device class to """ kwargs = dict(body=body, timeout=timeout) if not isinstance(srcname, six.string_types): raise CephClientTypeError( name='srcname', actual=type(srcname), expected=six.string_types) kwargs['srcname'] = srcname if not isinstance(dstname, six.string_types): raise CephClientTypeError( name='dstname', actual=type(dstname), expected=six.string_types) kwargs['dstname'] = dstname return self._request('osd crush class rename', **kwargs) def osd_crush_create_or_move( self, _id, weight, args, body='json', timeout=None): """create entry or move existing entry for at/to location """ kwargs = dict(body=body, timeout=timeout) if isinstance(_id, six.integer_types): pass elif isinstance(_id, six.string_types): _id = _id.lower() prefix = 'osd.' if not _id.startswith(prefix): raise CephClientInvalidOsdIdValue(osdid=_id) _id = int(_id[len(prefix):]) else: raise CephClientTypeError( name='_id', actual=type(_id), expected='int or string') kwargs['id'] = _id if not isinstance(weight, (six.integer_types, float)): raise CephClientTypeError( name='weight', actual=type(weight), expected=int) if weight < 0.0: raise CephClientValueOutOfBounds( name='weight', actual=weight, min=0.0, max='unlimited') kwargs['weight'] = weight if isinstance(args, list): for item in args: if not isinstance(item, six.string_types): raise CephClientTypeError( name='args', actual=item, expected='list of strings') else: if not isinstance(args, six.string_types): raise CephClientTypeError( name='args', actual=type(args), expected=six.string_types) if not isinstance(args, list): args = [args] kwargs['args'] = args return self._request('osd crush create-or-move', **kwargs) def osd_crush_move(self, name, args, body='json', timeout=None): """move existing entry for to location """ kwargs = dict(body=body, timeout=timeout) if not isinstance(name, six.string_types): raise CephClientTypeError( name='name', actual=type(name), expected=six.string_types) kwargs['name'] = name if isinstance(args, list): for item in args: if not isinstance(item, six.string_types): raise CephClientTypeError( name='args', actual=item, expected='list of strings') else: if not isinstance(args, six.string_types): raise CephClientTypeError( name='args', actual=type(args), expected=six.string_types) if not isinstance(args, list): args = [args] kwargs['args'] = args return self._request('osd crush move', **kwargs) OSD_CRUSH_SWAP_BUCKET_FORCE_VALUES = ['--yes-i-really-mean-it'] def osd_crush_swap_bucket( self, source, dest, force=None, body='json', timeout=None): """swap existing bucket contents from (orphan) bucket and """ kwargs = dict(body=body, timeout=timeout) if not isinstance(source, six.string_types): raise CephClientTypeError( name='source', actual=type(source), expected=six.string_types) kwargs['source'] = source if not isinstance(dest, six.string_types): raise CephClientTypeError( name='dest', actual=type(dest), expected=six.string_types) kwargs['dest'] = dest if force is not None: if not isinstance(force, six.string_types): raise CephClientTypeError( name='force', actual=type(force), expected=six.string_types) supported = CephClient.OSD_CRUSH_SWAP_BUCKET_FORCE_VALUES if force not in supported: raise CephClientInvalidChoice( function='osd_crush_swap_bucket', option='force', value=force, supported=', '.join(supported)) kwargs['force'] = force return self._request('osd crush swap-bucket', **kwargs) def osd_crush_link(self, name, args, body='json', timeout=None): """link existing entry for under location """ kwargs = dict(body=body, timeout=timeout) if not isinstance(name, six.string_types): raise CephClientTypeError( name='name', actual=type(name), expected=six.string_types) kwargs['name'] = name if isinstance(args, list): for item in args: if not isinstance(item, six.string_types): raise CephClientTypeError( name='args', actual=item, expected='list of strings') else: if not isinstance(args, six.string_types): raise CephClientTypeError( name='args', actual=type(args), expected=six.string_types) if not isinstance(args, list): args = [args] kwargs['args'] = args return self._request('osd crush link', **kwargs) def osd_crush_rm(self, name, ancestor=None, body='json', timeout=None): """remove from crush map (everywhere, or just at )""" kwargs = dict(body=body, timeout=timeout) if not isinstance(name, six.string_types): raise CephClientTypeError( name='name', actual=type(name), expected=six.string_types) kwargs['name'] = name if ancestor is not None: if not isinstance(ancestor, six.string_types): raise CephClientTypeError( name='ancestor', actual=type(ancestor), expected=six.string_types) kwargs['ancestor'] = ancestor return self._request('osd crush rm', **kwargs) def osd_crush_remove(self, name, ancestor=None, body='json', timeout=None): """remove from crush map (everywhere, or just at )""" kwargs = dict(body=body, timeout=timeout) if not isinstance(name, six.string_types): raise CephClientTypeError( name='name', actual=type(name), expected=six.string_types) kwargs['name'] = name if ancestor is not None: if not isinstance(ancestor, six.string_types): raise CephClientTypeError( name='ancestor', actual=type(ancestor), expected=six.string_types) kwargs['ancestor'] = ancestor return self._request('osd crush remove', **kwargs) def osd_crush_unlink(self, name, ancestor=None, body='json', timeout=None): """unlink from crush map (everywhere, or just at )""" kwargs = dict(body=body, timeout=timeout) if not isinstance(name, six.string_types): raise CephClientTypeError( name='name', actual=type(name), expected=six.string_types) kwargs['name'] = name if ancestor is not None: if not isinstance(ancestor, six.string_types): raise CephClientTypeError( name='ancestor', actual=type(ancestor), expected=six.string_types) kwargs['ancestor'] = ancestor return self._request('osd crush unlink', **kwargs) def osd_crush_reweight_all(self, body='json', timeout=None): """recalculate the weights for the tree to ensure they sum correctly""" return self._request('osd crush reweight-all', body=body, timeout=timeout) def osd_crush_reweight(self, name, weight, body='json', timeout=None): """change 's weight to in crush map""" kwargs = dict(body=body, timeout=timeout) if not isinstance(name, six.string_types): raise CephClientTypeError( name='name', actual=type(name), expected=six.string_types) kwargs['name'] = name if not isinstance(weight, (six.integer_types, float)): raise CephClientTypeError( name='weight', actual=type(weight), expected=int) if weight < 0.0: raise CephClientValueOutOfBounds( name='weight', actual=weight, min=0.0, max='unlimited') kwargs['weight'] = weight return self._request('osd crush reweight', **kwargs) def osd_crush_reweight_subtree( self, name, weight, body='json', timeout=None): """change all leaf items beneath to in crush map""" kwargs = dict(body=body, timeout=timeout) if not isinstance(name, six.string_types): raise CephClientTypeError( name='name', actual=type(name), expected=six.string_types) kwargs['name'] = name if not isinstance(weight, (six.integer_types, float)): raise CephClientTypeError( name='weight', actual=type(weight), expected=int) if weight < 0.0: raise CephClientValueOutOfBounds( name='weight', actual=weight, min=0.0, max='unlimited') kwargs['weight'] = weight return self._request('osd crush reweight-subtree', **kwargs) OSD_CRUSH_TUNABLES_PROFILE_VALUES = \ ['legacy', 'argonaut', 'bobtail', 'firefly', 'hammer', 'jewel', 'optimal', 'default'] def osd_crush_tunables(self, profile, body='json', timeout=None): """set crush tunables values to """ kwargs = dict(body=body, timeout=timeout) if not isinstance(profile, six.string_types): raise CephClientTypeError( name='profile', actual=type(profile), expected=six.string_types) supported = CephClient.OSD_CRUSH_TUNABLES_PROFILE_VALUES if profile not in supported: raise CephClientInvalidChoice( function='osd_crush_tunables', option='profile', value=profile, supported=', '.join(supported)) kwargs['profile'] = profile return self._request('osd crush tunables', **kwargs) OSD_CRUSH_SET_TUNABLE_TUNABLE_VALUES = ['straw_calc_version'] def osd_crush_set_tunable( self, tunable, value, body='json', timeout=None): """set crush tunable to """ kwargs = dict(body=body, timeout=timeout) if not isinstance(tunable, six.string_types): raise CephClientTypeError( name='tunable', actual=type(tunable), expected=six.string_types) supported = CephClient.OSD_CRUSH_SET_TUNABLE_TUNABLE_VALUES if tunable not in supported: raise CephClientInvalidChoice( function='osd_crush_set_tunable', option='tunable', value=tunable, supported=', '.join(supported)) kwargs['tunable'] = tunable if not isinstance(value, six.integer_types): raise CephClientTypeError( name='value', actual=type(value), expected=int) kwargs['value'] = value return self._request('osd crush set-tunable', **kwargs) OSD_CRUSH_GET_TUNABLE_TUNABLE_VALUES = ['straw_calc_version'] def osd_crush_get_tunable(self, tunable, body='json', timeout=None): """get crush tunable """ kwargs = dict(body=body, timeout=timeout) if not isinstance(tunable, six.string_types): raise CephClientTypeError( name='tunable', actual=type(tunable), expected=six.string_types) supported = CephClient.OSD_CRUSH_GET_TUNABLE_TUNABLE_VALUES if tunable not in supported: raise CephClientInvalidChoice( function='osd_crush_get_tunable', option='tunable', value=tunable, supported=', '.join(supported)) kwargs['tunable'] = tunable return self._request('osd crush get-tunable', **kwargs) def osd_crush_show_tunables(self, body='json', timeout=None): """show current crush tunables""" return self._request('osd crush show-tunables', body=body, timeout=timeout) OSD_CRUSH_RULE_CREATE_SIMPLE_MODE_VALUES = ['firstn', 'indep'] def osd_crush_rule_create_simple( self, name, root, _type, mode=None, body='json', timeout=None): """create crush rule to start from , replicate acrossbuckets of type , using a choose mode of (default firstn; indep best for erasure pools) """ kwargs = dict(body=body, timeout=timeout) if not isinstance(name, six.string_types): raise CephClientTypeError( name='name', actual=type(name), expected=six.string_types) kwargs['name'] = name if not isinstance(root, six.string_types): raise CephClientTypeError( name='root', actual=type(root), expected=six.string_types) kwargs['root'] = root if not isinstance(_type, six.string_types): raise CephClientTypeError( name='_type', actual=type(_type), expected=six.string_types) kwargs['type'] = _type if mode is not None: if not isinstance(mode, six.string_types): raise CephClientTypeError( name='mode', actual=type(mode), expected=six.string_types) supported = CephClient.OSD_CRUSH_RULE_CREATE_SIMPLE_MODE_VALUES if mode not in supported: raise CephClientInvalidChoice( function='osd_crush_rule_create_simple', option='mode', value=mode, supported=', '.join(supported)) kwargs['mode'] = mode return self._request('osd crush rule create-simple', **kwargs) def osd_crush_rule_create_replicated( self, name, root, _type, _class=None, body='json', timeout=None): """create crush rule for replicated pool to start from ,replicate across buckets of type , using a choose mode of (default firstn; indep best for erasure pools) """ kwargs = dict(body=body, timeout=timeout) if not isinstance(name, six.string_types): raise CephClientTypeError( name='name', actual=type(name), expected=six.string_types) kwargs['name'] = name if not isinstance(root, six.string_types): raise CephClientTypeError( name='root', actual=type(root), expected=six.string_types) kwargs['root'] = root if not isinstance(_type, six.string_types): raise CephClientTypeError( name='_type', actual=type(_type), expected=six.string_types) kwargs['type'] = _type if _class is not None: if not isinstance(_class, six.string_types): raise CephClientTypeError( name='_class', actual=type(_class), expected=six.string_types) kwargs['class'] = _class return self._request('osd crush rule create-replicated', **kwargs) def osd_crush_rule_create_erasure( self, name, profile=None, body='json', timeout=None): """create crush rule for erasure coded pool created with (default default) """ kwargs = dict(body=body, timeout=timeout) if not isinstance(name, six.string_types): raise CephClientTypeError( name='name', actual=type(name), expected=six.string_types) kwargs['name'] = name if profile is not None: if not isinstance(profile, six.string_types): raise CephClientTypeError( name='profile', actual=type(profile), expected=six.string_types) kwargs['profile'] = profile return self._request('osd crush rule create-erasure', **kwargs) def osd_crush_rule_rm(self, name, body='json', timeout=None): """remove crush rule """ kwargs = dict(body=body, timeout=timeout) if not isinstance(name, six.string_types): raise CephClientTypeError( name='name', actual=type(name), expected=six.string_types) kwargs['name'] = name return self._request('osd crush rule rm', **kwargs) def osd_crush_rule_rename( self, srcname, dstname, body='json', timeout=None): """rename crush rule to """ kwargs = dict(body=body, timeout=timeout) if not isinstance(srcname, six.string_types): raise CephClientTypeError( name='srcname', actual=type(srcname), expected=six.string_types) kwargs['srcname'] = srcname if not isinstance(dstname, six.string_types): raise CephClientTypeError( name='dstname', actual=type(dstname), expected=six.string_types) kwargs['dstname'] = dstname return self._request('osd crush rule rename', **kwargs) OSD_CRUSH_TREE_SHADOW_VALUES = ['--show-shadow'] def osd_crush_tree(self, shadow=None, body='json', timeout=None): """dump crush buckets and items in a tree view""" kwargs = dict(body=body, timeout=timeout) if shadow is not None: if not isinstance(shadow, six.string_types): raise CephClientTypeError( name='shadow', actual=type(shadow), expected=six.string_types) supported = CephClient.OSD_CRUSH_TREE_SHADOW_VALUES if shadow not in supported: raise CephClientInvalidChoice( function='osd_crush_tree', option='shadow', value=shadow, supported=', '.join(supported)) kwargs['shadow'] = shadow return self._request('osd crush tree', **kwargs) def osd_crush_ls(self, node, body='json', timeout=None): """list items beneath a node in the CRUSH tree""" kwargs = dict(body=body, timeout=timeout) if not isinstance(node, six.string_types): raise CephClientTypeError( name='node', actual=type(node), expected=six.string_types) kwargs['node'] = node return self._request('osd crush ls', **kwargs) def osd_crush_class_ls(self, body='json', timeout=None): """list all crush device classes""" return self._request('osd crush class ls', body=body, timeout=timeout) def osd_crush_class_ls_osd(self, _class, body='json', timeout=None): """list all osds belonging to the specific """ kwargs = dict(body=body, timeout=timeout) if not isinstance(_class, six.string_types): raise CephClientTypeError( name='_class', actual=type(_class), expected=six.string_types) kwargs['class'] = _class return self._request('osd crush class ls-osd', **kwargs) def osd_crush_weight_set_ls(self, body='json', timeout=None): """list crush weight sets""" return self._request('osd crush weight-set ls', body=body, timeout=timeout) def osd_crush_weight_set_dump(self, body='json', timeout=None): """dump crush weight sets""" return self._request('osd crush weight-set dump', body=body, timeout=timeout) def osd_crush_weight_set_create_compat( self, body='json', timeout=None): """create a default backward-compatible weight-set""" return self._request( 'osd crush weight-set create-compat', body=body, timeout=timeout) OSD_CRUSH_WEIGHT_SET_CREATE_MODE_VALUES = ['flat', 'positional'] def osd_crush_weight_set_create( self, pool, mode, body='json', timeout=None): """create a weight-set for a given pool""" kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool if not isinstance(mode, six.string_types): raise CephClientTypeError( name='mode', actual=type(mode), expected=six.string_types) supported = CephClient.OSD_CRUSH_WEIGHT_SET_CREATE_MODE_VALUES if mode not in supported: raise CephClientInvalidChoice( function='osd_crush_weight_set_create', option='mode', value=mode, supported=', '.join(supported)) kwargs['mode'] = mode return self._request('osd crush weight-set create', **kwargs) def osd_crush_weight_set_rm(self, pool, body='json', timeout=None): """remove the weight-set for a given pool""" kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool return self._request('osd crush weight-set rm', **kwargs) def osd_crush_weight_set_rm_compat(self, body='json', timeout=None): """remove the backward-compatible weight-set""" return self._request( 'osd crush weight-set rm-compat', body=body, timeout=timeout) def osd_crush_weight_set_reweight( self, pool, item, weight, body='json', timeout=None): """set weight for an item (bucket or osd) in a pool's weight-set""" kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool if not isinstance(item, six.string_types): raise CephClientTypeError( name='item', actual=type(item), expected=six.string_types) kwargs['item'] = item if not isinstance(weight, (six.integer_types, float)): raise CephClientTypeError( name='weight', actual=type(weight), expected=int) if weight < 0.0: raise CephClientValueOutOfBounds( name='weight', actual=weight, min=0.0, max='unlimited') if not isinstance(weight, list): weight = [weight] kwargs['weight'] = weight return self._request('osd crush weight-set reweight', **kwargs) def osd_crush_weight_set_reweight_compat( self, item, weight, body='json', timeout=None): """set weight for an item (bucket or osd) in the backward-compatibleweight-set """ kwargs = dict(body=body, timeout=timeout) if not isinstance(item, six.string_types): raise CephClientTypeError( name='item', actual=type(item), expected=six.string_types) kwargs['item'] = item if not isinstance(weight, (six.integer_types, float)): raise CephClientTypeError( name='weight', actual=type(weight), expected=int) if weight < 0.0: raise CephClientValueOutOfBounds( name='weight', actual=weight, min=0.0, max='unlimited') if not isinstance(weight, list): weight = [weight] kwargs['weight'] = weight return self._request( 'osd crush weight-set reweight-compat', **kwargs) def osd_setmaxosd(self, newmax, body='json', timeout=None): """set new maximum osd value""" kwargs = dict(body=body, timeout=timeout) if not isinstance(newmax, six.integer_types): raise CephClientTypeError( name='newmax', actual=type(newmax), expected=int) if newmax < 0: raise CephClientValueOutOfBounds( name='newmax', actual=newmax, min=0, max='unlimited') kwargs['newmax'] = newmax return self._request('osd setmaxosd', **kwargs) def osd_set_full_ratio(self, ratio, body='json', timeout=None): """set usage ratio at which OSDs are marked full""" kwargs = dict(body=body, timeout=timeout) if not isinstance(ratio, (six.integer_types, float)): raise CephClientTypeError( name='ratio', actual=type(ratio), expected=int) if ratio < 0.0 or ratio > 1.0: raise CephClientValueOutOfBounds( name='ratio', actual=ratio, min=0.0, max=1.0) kwargs['ratio'] = ratio return self._request('osd set-full-ratio', **kwargs) def osd_set_backfillfull_ratio(self, ratio, body='json', timeout=None): """set usage ratio at which OSDs are marked too full to backfill""" kwargs = dict(body=body, timeout=timeout) if not isinstance(ratio, (six.integer_types, float)): raise CephClientTypeError( name='ratio', actual=type(ratio), expected=int) if ratio < 0.0 or ratio > 1.0: raise CephClientValueOutOfBounds( name='ratio', actual=ratio, min=0.0, max=1.0) kwargs['ratio'] = ratio return self._request('osd set-backfillfull-ratio', **kwargs) def osd_set_nearfull_ratio(self, ratio, body='json', timeout=None): """set usage ratio at which OSDs are marked near-full""" kwargs = dict(body=body, timeout=timeout) if not isinstance(ratio, (six.integer_types, float)): raise CephClientTypeError( name='ratio', actual=type(ratio), expected=int) if ratio < 0.0 or ratio > 1.0: raise CephClientValueOutOfBounds( name='ratio', actual=ratio, min=0.0, max=1.0) kwargs['ratio'] = ratio return self._request('osd set-nearfull-ratio', **kwargs) def osd_get_require_min_compat_client(self, body='json', timeout=None): """get the minimum client version we will maintain compatibility with""" return self._request( 'osd get-require-min-compat-client', body=body, timeout=timeout) OSD_SET_REQUIRE_MIN_COMPAT_CLIENT_SURE_VALUES = [ '--yes-i-really-mean-it'] def osd_set_require_min_compat_client( self, version, sure=None, body='json', timeout=None): """set the minimum client version we will maintain compatibility with""" kwargs = dict(body=body, timeout=timeout) if not isinstance(version, six.string_types): raise CephClientTypeError( name='version', actual=type(version), expected=six.string_types) kwargs['version'] = version if sure is not None: if not isinstance(sure, six.string_types): raise CephClientTypeError( name='sure', actual=type(sure), expected=six.string_types) supported = CephClient.OSD_SET_REQUIRE_MIN_COMPAT_CLIENT_SURE_VALUES # noqa E501 if sure not in supported: raise CephClientInvalidChoice( function='osd_set_require_min_compat_client', option='sure', value=sure, supported=', '.join(supported)) kwargs['sure'] = sure return self._request('osd set-require-min-compat-client', **kwargs) def osd_pause(self, body='json', timeout=None): """pause osd""" return self._request('osd pause', body=body, timeout=timeout) def osd_unpause(self, body='json', timeout=None): """unpause osd""" return self._request('osd unpause', body=body, timeout=timeout) def osd_erasure_code_profile_set( self, name, profile=None, body='json', timeout=None): """create erasure code profile with [ ...] pairs. Adda --force at the end to override an existing profile (VERY DANGEROUS) """ kwargs = dict(body=body, timeout=timeout) if not isinstance(name, six.string_types): raise CephClientTypeError( name='name', actual=type(name), expected=six.string_types) kwargs['name'] = name if profile is not None: if isinstance(profile, list): for item in profile: if not isinstance(item, six.string_types): raise CephClientTypeError( name='profile', actual=item, expected='list of strings') else: if not isinstance(profile, six.string_types): raise CephClientTypeError( name='profile', actual=type(profile), expected=six.string_types) if not isinstance(profile, list): profile = [profile] kwargs['profile'] = profile return self._request('osd erasure-code-profile set', **kwargs) def osd_erasure_code_profile_get( self, name, body='json', timeout=None): """get erasure code profile """ kwargs = dict(body=body, timeout=timeout) if not isinstance(name, six.string_types): raise CephClientTypeError( name='name', actual=type(name), expected=six.string_types) kwargs['name'] = name return self._request('osd erasure-code-profile get', **kwargs) def osd_erasure_code_profile_rm(self, name, body='json', timeout=None): """remove erasure code profile """ kwargs = dict(body=body, timeout=timeout) if not isinstance(name, six.string_types): raise CephClientTypeError( name='name', actual=type(name), expected=six.string_types) kwargs['name'] = name return self._request('osd erasure-code-profile rm', **kwargs) def osd_erasure_code_profile_ls(self, body='json', timeout=None): """list all erasure code profiles""" return self._request( 'osd erasure-code-profile ls', body=body, timeout=timeout) OSD_SET_KEY_VALUES = \ ['full', 'pause', 'noup', 'nodown', 'noout', 'noin', 'nobackfill', 'norebalance', 'norecover', 'noscrub', 'nodeep-scrub', 'notieragent', 'nosnaptrim', 'sortbitwise', 'recovery_deletes', 'require_jewel_osds', 'require_kraken_osds'] OSD_SET_SURE_VALUES = ['--yes-i-really-mean-it'] def osd_set(self, key, sure=None, body='json', timeout=None): """set """ kwargs = dict(body=body, timeout=timeout) if not isinstance(key, six.string_types): raise CephClientTypeError( name='key', actual=type(key), expected=six.string_types) supported = CephClient.OSD_SET_KEY_VALUES if key not in supported: raise CephClientInvalidChoice( function='osd_set', option='key', value=key, supported=', '.join(supported)) kwargs['key'] = key if sure is not None: if not isinstance(sure, six.string_types): raise CephClientTypeError( name='sure', actual=type(sure), expected=six.string_types) supported = CephClient.OSD_SET_SURE_VALUES if sure not in supported: raise CephClientInvalidChoice( function='osd_set', option='sure', value=sure, supported=', '.join(supported)) kwargs['sure'] = sure return self._request('osd set', **kwargs) OSD_UNSET_KEY_VALUES = \ ['full', 'pause', 'noup', 'nodown', 'noout', 'noin', 'nobackfill', 'norebalance', 'norecover', 'noscrub', 'nodeep-scrub', 'notieragent', 'nosnaptrim'] def osd_unset(self, key, body='json', timeout=None): """unset """ kwargs = dict(body=body, timeout=timeout) if not isinstance(key, six.string_types): raise CephClientTypeError( name='key', actual=type(key), expected=six.string_types) supported = CephClient.OSD_UNSET_KEY_VALUES if key not in supported: raise CephClientInvalidChoice( function='osd_unset', option='key', value=key, supported=', '.join(supported)) kwargs['key'] = key return self._request('osd unset', **kwargs) OSD_REQUIRE_OSD_RELEASE_RELEASE_VALUES = ['luminous', 'mimic'] OSD_REQUIRE_OSD_RELEASE_SURE_VALUES = ['--yes-i-really-mean-it'] def osd_require_osd_release( self, release, sure=None, body='json', timeout=None): """set the minimum allowed OSD release to participate in the cluster""" kwargs = dict(body=body, timeout=timeout) if not isinstance(release, six.string_types): raise CephClientTypeError( name='release', actual=type(release), expected=six.string_types) supported = CephClient.OSD_REQUIRE_OSD_RELEASE_RELEASE_VALUES if release not in supported: raise CephClientInvalidChoice( function='osd_require_osd_release', option='release', value=release, supported=', '.join(supported)) kwargs['release'] = release if sure is not None: if not isinstance(sure, six.string_types): raise CephClientTypeError( name='sure', actual=type(sure), expected=six.string_types) supported = CephClient.OSD_REQUIRE_OSD_RELEASE_SURE_VALUES if sure not in supported: raise CephClientInvalidChoice( function='osd_require_osd_release', option='sure', value=sure, supported=', '.join(supported)) kwargs['sure'] = sure return self._request('osd require-osd-release', **kwargs) def osd_down(self, ids, body='json', timeout=None): """set osd(s) [...] down, or use to set all osds down""" kwargs = dict(body=body, timeout=timeout) if isinstance(ids, list): for item in ids: if not isinstance(item, six.string_types): raise CephClientTypeError( name='ids', actual=item, expected='list of strings') else: if not isinstance(ids, six.string_types): raise CephClientTypeError( name='ids', actual=type(ids), expected=six.string_types) if not isinstance(ids, list): ids = [ids] kwargs['ids'] = ids return self._request('osd down', **kwargs) def osd_out(self, ids, body='json', timeout=None): """set osd(s) [...] out, or use to set all osds out""" kwargs = dict(body=body, timeout=timeout) if isinstance(ids, list): for item in ids: if not isinstance(item, six.string_types): raise CephClientTypeError( name='ids', actual=item, expected='list of strings') else: if not isinstance(ids, six.string_types): raise CephClientTypeError( name='ids', actual=type(ids), expected=six.string_types) if not isinstance(ids, list): ids = [ids] kwargs['ids'] = ids return self._request('osd out', **kwargs) def osd_in(self, ids, body='json', timeout=None): """set osd(s) [...] in, can use to automatically setall previously out osds in """ kwargs = dict(body=body, timeout=timeout) if isinstance(ids, list): for item in ids: if not isinstance(item, six.string_types): raise CephClientTypeError( name='ids', actual=item, expected='list of strings') else: if not isinstance(ids, six.string_types): raise CephClientTypeError( name='ids', actual=type(ids), expected=six.string_types) if not isinstance(ids, list): ids = [ids] kwargs['ids'] = ids return self._request('osd in', **kwargs) def osd_rm(self, ids, body='json', timeout=None): """remove osd(s) [...], or use to remove all osds""" kwargs = dict(body=body, timeout=timeout) if isinstance(ids, list): for item in ids: if not isinstance(item, six.string_types): raise CephClientTypeError( name='ids', actual=item, expected='list of strings') else: if not isinstance(ids, six.string_types): raise CephClientTypeError( name='ids', actual=type(ids), expected=six.string_types) if not isinstance(ids, list): ids = [ids] kwargs['ids'] = ids return self._request('osd rm', **kwargs) def osd_add_noup(self, ids, body='json', timeout=None): """mark osd(s) [...] as noup, or use to mark all osdsas noup """ kwargs = dict(body=body, timeout=timeout) if isinstance(ids, list): for item in ids: if not isinstance(item, six.string_types): raise CephClientTypeError( name='ids', actual=item, expected='list of strings') else: if not isinstance(ids, six.string_types): raise CephClientTypeError( name='ids', actual=type(ids), expected=six.string_types) if not isinstance(ids, list): ids = [ids] kwargs['ids'] = ids return self._request('osd add-noup', **kwargs) def osd_add_nodown(self, ids, body='json', timeout=None): """mark osd(s) [...] as nodown, or use to mark allosds as nodown """ kwargs = dict(body=body, timeout=timeout) if isinstance(ids, list): for item in ids: if not isinstance(item, six.string_types): raise CephClientTypeError( name='ids', actual=item, expected='list of strings') else: if not isinstance(ids, six.string_types): raise CephClientTypeError( name='ids', actual=type(ids), expected=six.string_types) if not isinstance(ids, list): ids = [ids] kwargs['ids'] = ids return self._request('osd add-nodown', **kwargs) def osd_add_noin(self, ids, body='json', timeout=None): """mark osd(s) [...] as noin, or use to mark all osdsas noin """ kwargs = dict(body=body, timeout=timeout) if isinstance(ids, list): for item in ids: if not isinstance(item, six.string_types): raise CephClientTypeError( name='ids', actual=item, expected='list of strings') else: if not isinstance(ids, six.string_types): raise CephClientTypeError( name='ids', actual=type(ids), expected=six.string_types) if not isinstance(ids, list): ids = [ids] kwargs['ids'] = ids return self._request('osd add-noin', **kwargs) def osd_add_noout(self, ids, body='json', timeout=None): """mark osd(s) [...] as noout, or use to mark all osdsas noout """ kwargs = dict(body=body, timeout=timeout) if isinstance(ids, list): for item in ids: if not isinstance(item, six.string_types): raise CephClientTypeError( name='ids', actual=item, expected='list of strings') else: if not isinstance(ids, six.string_types): raise CephClientTypeError( name='ids', actual=type(ids), expected=six.string_types) if not isinstance(ids, list): ids = [ids] kwargs['ids'] = ids return self._request('osd add-noout', **kwargs) def osd_rm_noup(self, ids, body='json', timeout=None): """allow osd(s) [...] to be marked up (if they are currentlymarked as noup), can use to automatically filter out all noup osds """ kwargs = dict(body=body, timeout=timeout) if isinstance(ids, list): for item in ids: if not isinstance(item, six.string_types): raise CephClientTypeError( name='ids', actual=item, expected='list of strings') else: if not isinstance(ids, six.string_types): raise CephClientTypeError( name='ids', actual=type(ids), expected=six.string_types) if not isinstance(ids, list): ids = [ids] kwargs['ids'] = ids return self._request('osd rm-noup', **kwargs) def osd_rm_nodown(self, ids, body='json', timeout=None): """allow osd(s) [...] to be marked down (if they are currentlymarked as nodown), can use to automatically filter out all nodown osds """ kwargs = dict(body=body, timeout=timeout) if isinstance(ids, list): for item in ids: if not isinstance(item, six.string_types): raise CephClientTypeError( name='ids', actual=item, expected='list of strings') else: if not isinstance(ids, six.string_types): raise CephClientTypeError( name='ids', actual=type(ids), expected=six.string_types) if not isinstance(ids, list): ids = [ids] kwargs['ids'] = ids return self._request('osd rm-nodown', **kwargs) def osd_rm_noin(self, ids, body='json', timeout=None): """allow osd(s) [...] to be marked in (if they are currentlymarked as noin), can use to automatically filter out all noin osds """ kwargs = dict(body=body, timeout=timeout) if isinstance(ids, list): for item in ids: if not isinstance(item, six.string_types): raise CephClientTypeError( name='ids', actual=item, expected='list of strings') else: if not isinstance(ids, six.string_types): raise CephClientTypeError( name='ids', actual=type(ids), expected=six.string_types) if not isinstance(ids, list): ids = [ids] kwargs['ids'] = ids return self._request('osd rm-noin', **kwargs) def osd_rm_noout(self, ids, body='json', timeout=None): """allow osd(s) [...] to be marked out (if they are currentlymarked as noout), can use to automatically filter out all noout osds """ kwargs = dict(body=body, timeout=timeout) if isinstance(ids, list): for item in ids: if not isinstance(item, six.string_types): raise CephClientTypeError( name='ids', actual=item, expected='list of strings') else: if not isinstance(ids, six.string_types): raise CephClientTypeError( name='ids', actual=type(ids), expected=six.string_types) if not isinstance(ids, list): ids = [ids] kwargs['ids'] = ids return self._request('osd rm-noout', **kwargs) def osd_reweight(self, _id, weight, body='json', timeout=None): """reweight osd to 0.0 < < 1.0""" kwargs = dict(body=body, timeout=timeout) if isinstance(_id, six.integer_types): pass elif isinstance(_id, six.string_types): _id = _id.lower() prefix = 'osd.' if not _id.startswith(prefix): raise CephClientInvalidOsdIdValue(osdid=_id) _id = int(_id[len(prefix):]) else: raise CephClientTypeError( name='_id', actual=type(_id), expected='int or string') kwargs['id'] = _id if not isinstance(weight, (six.integer_types, float)): raise CephClientTypeError( name='weight', actual=type(weight), expected=int) if weight < 0.0 or weight > 1.0: raise CephClientValueOutOfBounds( name='weight', actual=weight, min=0.0, max=1.0) kwargs['weight'] = weight return self._request('osd reweight', **kwargs) def osd_reweightn(self, weights, body='json', timeout=None): """reweight osds with {: ,...})""" kwargs = dict(body=body, timeout=timeout) if not isinstance(weights, six.string_types): raise CephClientTypeError( name='weights', actual=type(weights), expected=six.string_types) kwargs['weights'] = weights return self._request('osd reweightn', **kwargs) OSD_FORCE_CREATE_PG_SURE_VALUES = ['--yes-i-really-mean-it'] def osd_force_create_pg(self, pgid, sure=None, body='json', timeout=None): """force creation of pg """ kwargs = dict(body=body, timeout=timeout) if not isinstance(pgid, six.string_types): raise CephClientTypeError( name='pgid', actual=type(pgid), expected=six.string_types) if not re.match(r'[0-9]+\.[0-9a-fA-F]+', pgid): raise CephClientInvalidPgid( name='pgid', actual=pgid) kwargs['pgid'] = pgid if sure is not None: if not isinstance(sure, six.string_types): raise CephClientTypeError( name='sure', actual=type(sure), expected=six.string_types) supported = CephClient.OSD_FORCE_CREATE_PG_SURE_VALUES if sure not in supported: raise CephClientInvalidChoice( function='osd_force_create_pg', option='sure', value=sure, supported=', '.join(supported)) kwargs['sure'] = sure return self._request('osd force-create-pg', **kwargs) def osd_pg_temp(self, pgid, _id=None, body='json', timeout=None): """set pg_temp mapping pgid:[ [...]] (developers only)""" kwargs = dict(body=body, timeout=timeout) if not isinstance(pgid, six.string_types): raise CephClientTypeError( name='pgid', actual=type(pgid), expected=six.string_types) if not re.match(r'[0-9]+\.[0-9a-fA-F]+', pgid): raise CephClientInvalidPgid( name='pgid', actual=pgid) kwargs['pgid'] = pgid if _id is not None: if isinstance(_id, six.integer_types): pass elif isinstance(_id, six.string_types): _id = _id.lower() prefix = 'osd.' if not _id.startswith(prefix): raise CephClientInvalidOsdIdValue(osdid=_id) _id = int(_id[len(prefix):]) else: raise CephClientTypeError( name='_id', actual=type(_id), expected='int or string') if not isinstance(_id, list): _id = [_id] kwargs['id'] = _id return self._request('osd pg-temp', **kwargs) def osd_pg_upmap(self, pgid, _id, body='json', timeout=None): """set pg_upmap mapping :[ [...]] (developers only)""" kwargs = dict(body=body, timeout=timeout) if not isinstance(pgid, six.string_types): raise CephClientTypeError( name='pgid', actual=type(pgid), expected=six.string_types) if not re.match(r'[0-9]+\.[0-9a-fA-F]+', pgid): raise CephClientInvalidPgid( name='pgid', actual=pgid) kwargs['pgid'] = pgid if isinstance(_id, six.integer_types): pass elif isinstance(_id, six.string_types): _id = _id.lower() prefix = 'osd.' if not _id.startswith(prefix): raise CephClientInvalidOsdIdValue(osdid=_id) _id = int(_id[len(prefix):]) else: raise CephClientTypeError( name='_id', actual=type(_id), expected='int or string') if not isinstance(_id, list): _id = [_id] kwargs['id'] = _id return self._request('osd pg-upmap', **kwargs) def osd_rm_pg_upmap(self, pgid, body='json', timeout=None): """clear pg_upmap mapping for (developers only)""" kwargs = dict(body=body, timeout=timeout) if not isinstance(pgid, six.string_types): raise CephClientTypeError( name='pgid', actual=type(pgid), expected=six.string_types) if not re.match(r'[0-9]+\.[0-9a-fA-F]+', pgid): raise CephClientInvalidPgid( name='pgid', actual=pgid) kwargs['pgid'] = pgid return self._request('osd rm-pg-upmap', **kwargs) def osd_pg_upmap_items(self, pgid, _id, body='json', timeout=None): """set pg_upmap_items mapping :{ to , [...]} (developersonly) """ kwargs = dict(body=body, timeout=timeout) if not isinstance(pgid, six.string_types): raise CephClientTypeError( name='pgid', actual=type(pgid), expected=six.string_types) if not re.match(r'[0-9]+\.[0-9a-fA-F]+', pgid): raise CephClientInvalidPgid( name='pgid', actual=pgid) kwargs['pgid'] = pgid if isinstance(_id, six.integer_types): pass elif isinstance(_id, six.string_types): _id = _id.lower() prefix = 'osd.' if not _id.startswith(prefix): raise CephClientInvalidOsdIdValue(osdid=_id) _id = int(_id[len(prefix):]) else: raise CephClientTypeError( name='_id', actual=type(_id), expected='int or string') if not isinstance(_id, list): _id = [_id] kwargs['id'] = _id return self._request('osd pg-upmap-items', **kwargs) def osd_rm_pg_upmap_items(self, pgid, body='json', timeout=None): """clear pg_upmap_items mapping for (developers only)""" kwargs = dict(body=body, timeout=timeout) if not isinstance(pgid, six.string_types): raise CephClientTypeError( name='pgid', actual=type(pgid), expected=six.string_types) if not re.match(r'[0-9]+\.[0-9a-fA-F]+', pgid): raise CephClientInvalidPgid( name='pgid', actual=pgid) kwargs['pgid'] = pgid return self._request('osd rm-pg-upmap-items', **kwargs) def osd_primary_temp(self, pgid, _id, body='json', timeout=None): """set primary_temp mapping pgid:|-1 (developers only)""" kwargs = dict(body=body, timeout=timeout) if not isinstance(pgid, six.string_types): raise CephClientTypeError( name='pgid', actual=type(pgid), expected=six.string_types) if not re.match(r'[0-9]+\.[0-9a-fA-F]+', pgid): raise CephClientInvalidPgid( name='pgid', actual=pgid) kwargs['pgid'] = pgid if isinstance(_id, six.integer_types): pass elif isinstance(_id, six.string_types): _id = _id.lower() prefix = 'osd.' if not _id.startswith(prefix): raise CephClientInvalidOsdIdValue(osdid=_id) _id = int(_id[len(prefix):]) else: raise CephClientTypeError( name='_id', actual=type(_id), expected='int or string') kwargs['id'] = _id return self._request('osd primary-temp', **kwargs) def osd_primary_affinity(self, _id, weight, body='json', timeout=None): """adjust osd primary-affinity from 0.0 <= <= 1.0""" kwargs = dict(body=body, timeout=timeout) if isinstance(_id, six.integer_types): pass elif isinstance(_id, six.string_types): _id = _id.lower() prefix = 'osd.' if not _id.startswith(prefix): raise CephClientInvalidOsdIdValue(osdid=_id) _id = int(_id[len(prefix):]) else: raise CephClientTypeError( name='_id', actual=type(_id), expected='int or string') kwargs['id'] = _id if not isinstance(weight, (six.integer_types, float)): raise CephClientTypeError( name='weight', actual=type(weight), expected=int) if weight < 0.0 or weight > 1.0: raise CephClientValueOutOfBounds( name='weight', actual=weight, min=0.0, max=1.0) kwargs['weight'] = weight return self._request('osd primary-affinity', **kwargs) OSD_DESTROY_SURE_VALUES = ['--yes-i-really-mean-it'] def osd_destroy(self, _id, sure=None, body='json', timeout=None): """mark osd as being destroyed. Keeps the ID intact (allowing reuse), butremoves cephx keys, config-key data and lockbox keys, rendering data permanently unreadable. """ kwargs = dict(body=body, timeout=timeout) if isinstance(_id, six.integer_types): pass elif isinstance(_id, six.string_types): _id = _id.lower() prefix = 'osd.' if not _id.startswith(prefix): raise CephClientInvalidOsdIdValue(osdid=_id) _id = int(_id[len(prefix):]) else: raise CephClientTypeError( name='_id', actual=type(_id), expected='int or string') kwargs['id'] = _id if sure is not None: if not isinstance(sure, six.string_types): raise CephClientTypeError( name='sure', actual=type(sure), expected=six.string_types) supported = CephClient.OSD_DESTROY_SURE_VALUES if sure not in supported: raise CephClientInvalidChoice( function='osd_destroy', option='sure', value=sure, supported=', '.join(supported)) kwargs['sure'] = sure return self._request('osd destroy', **kwargs) OSD_PURGE_NEW_SURE_VALUES = ['--yes-i-really-mean-it'] def osd_purge_new(self, _id, sure=None, body='json', timeout=None): """purge all traces of an OSD that was partially created but neverstarted """ kwargs = dict(body=body, timeout=timeout) if isinstance(_id, six.integer_types): pass elif isinstance(_id, six.string_types): _id = _id.lower() prefix = 'osd.' if not _id.startswith(prefix): raise CephClientInvalidOsdIdValue(osdid=_id) _id = int(_id[len(prefix):]) else: raise CephClientTypeError( name='_id', actual=type(_id), expected='int or string') kwargs['id'] = _id if sure is not None: if not isinstance(sure, six.string_types): raise CephClientTypeError( name='sure', actual=type(sure), expected=six.string_types) supported = CephClient.OSD_PURGE_NEW_SURE_VALUES if sure not in supported: raise CephClientInvalidChoice( function='osd_purge_new', option='sure', value=sure, supported=', '.join(supported)) kwargs['sure'] = sure return self._request('osd purge-new', **kwargs) OSD_PURGE_SURE_VALUES = ['--yes-i-really-mean-it'] def osd_purge(self, _id, sure=None, body='json', timeout=None): """purge all osd data from the monitors. Combines `osd destroy`, `osdrm`, and `osd crush rm`. """ kwargs = dict(body=body, timeout=timeout) if isinstance(_id, six.integer_types): pass elif isinstance(_id, six.string_types): _id = _id.lower() prefix = 'osd.' if not _id.startswith(prefix): raise CephClientInvalidOsdIdValue(osdid=_id) _id = int(_id[len(prefix):]) else: raise CephClientTypeError( name='_id', actual=type(_id), expected='int or string') kwargs['id'] = _id if sure is not None: if not isinstance(sure, six.string_types): raise CephClientTypeError( name='sure', actual=type(sure), expected=six.string_types) supported = CephClient.OSD_PURGE_SURE_VALUES if sure not in supported: raise CephClientInvalidChoice( function='osd_purge', option='sure', value=sure, supported=', '.join(supported)) kwargs['sure'] = sure return self._request('osd purge', **kwargs) OSD_LOST_SURE_VALUES = ['--yes-i-really-mean-it'] def osd_lost(self, _id, sure=None, body='json', timeout=None): """mark osd as permanently lost. THIS DESTROYS DATA IF NO MORE REPLICAS EXIST, BE CAREFUL """ kwargs = dict(body=body, timeout=timeout) if isinstance(_id, six.integer_types): pass elif isinstance(_id, six.string_types): _id = _id.lower() prefix = 'osd.' if not _id.startswith(prefix): raise CephClientInvalidOsdIdValue(osdid=_id) _id = int(_id[len(prefix):]) else: raise CephClientTypeError( name='_id', actual=type(_id), expected='int or string') kwargs['id'] = _id if sure is not None: if not isinstance(sure, six.string_types): raise CephClientTypeError( name='sure', actual=type(sure), expected=six.string_types) supported = CephClient.OSD_LOST_SURE_VALUES if sure not in supported: raise CephClientInvalidChoice( function='osd_lost', option='sure', value=sure, supported=', '.join(supported)) kwargs['sure'] = sure return self._request('osd lost', **kwargs) def osd_create(self, uuid=None, _id=None, body='json', timeout=None): """create new osd (with optional UUID and ID)""" kwargs = dict(body=body, timeout=timeout) if uuid is not None: kwargs['uuid'] = uuid if _id is not None: if isinstance(_id, six.integer_types): pass elif isinstance(_id, six.string_types): _id = _id.lower() prefix = 'osd.' if not _id.startswith(prefix): raise CephClientInvalidOsdIdValue(osdid=_id) _id = int(_id[len(prefix):]) else: raise CephClientTypeError( name='_id', actual=type(_id), expected='int or string') kwargs['id'] = _id return self._request('osd create', **kwargs) def osd_new(self, uuid, _id=None, body='json', timeout=None): """Create a new OSD. If supplied, the `id` to be replaced needs to existand have been previously destroyed. Reads secrets from JSON file via `-i ` (see man page). """ kwargs = dict(body=body, timeout=timeout) kwargs['uuid'] = uuid if _id is not None: if isinstance(_id, six.integer_types): pass elif isinstance(_id, six.string_types): _id = _id.lower() prefix = 'osd.' if not _id.startswith(prefix): raise CephClientInvalidOsdIdValue(osdid=_id) _id = int(_id[len(prefix):]) else: raise CephClientTypeError( name='_id', actual=type(_id), expected='int or string') kwargs['id'] = _id return self._request('osd new', **kwargs) OSD_BLACKLIST_BLACKLISTOP_VALUES = ['add', 'rm'] def osd_blacklist( self, blacklistop, addr, expire=None, body='json', timeout=None): """add (optionally until seconds from now) or remove fromblacklist """ kwargs = dict(body=body, timeout=timeout) if not isinstance(blacklistop, six.string_types): raise CephClientTypeError( name='blacklistop', actual=type(blacklistop), expected=six.string_types) supported = CephClient.OSD_BLACKLIST_BLACKLISTOP_VALUES if blacklistop not in supported: raise CephClientInvalidChoice( function='osd_blacklist', option='blacklistop', value=blacklistop, supported=', '.join(supported)) kwargs['blacklistop'] = blacklistop kwargs['addr'] = addr if expire is not None: if not isinstance(expire, (six.integer_types, float)): raise CephClientTypeError( name='expire', actual=type(expire), expected=int) if expire < 0.0: raise CephClientValueOutOfBounds( name='expire', actual=expire, min=0.0, max='unlimited') kwargs['expire'] = expire return self._request('osd blacklist', **kwargs) def osd_blacklist_ls(self, body='json', timeout=None): """show blacklisted clients""" return self._request('osd blacklist ls', body=body, timeout=timeout) def osd_blacklist_clear(self, body='json', timeout=None): """clear all blacklisted clients""" return self._request('osd blacklist clear', body=body, timeout=timeout) def osd_pool_mksnap(self, pool, snap, body='json', timeout=None): """make snapshot in """ kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool if not isinstance(snap, six.string_types): raise CephClientTypeError( name='snap', actual=type(snap), expected=six.string_types) kwargs['snap'] = snap return self._request('osd pool mksnap', **kwargs) def osd_pool_rmsnap(self, pool, snap, body='json', timeout=None): """remove snapshot from """ kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool if not isinstance(snap, six.string_types): raise CephClientTypeError( name='snap', actual=type(snap), expected=six.string_types) kwargs['snap'] = snap return self._request('osd pool rmsnap', **kwargs) OSD_POOL_LS_DETAIL_VALUES = ['detail'] def osd_pool_ls(self, detail=None, body='json', timeout=None): """list pools""" kwargs = dict(body=body, timeout=timeout) if detail is not None: if not isinstance(detail, six.string_types): raise CephClientTypeError( name='detail', actual=type(detail), expected=six.string_types) supported = CephClient.OSD_POOL_LS_DETAIL_VALUES if detail not in supported: raise CephClientInvalidChoice( function='osd_pool_ls', option='detail', value=detail, supported=', '.join(supported)) kwargs['detail'] = detail return self._request('osd pool ls', **kwargs) OSD_POOL_CREATE_POOL_TYPE_VALUES = ['replicated', 'erasure'] def osd_pool_create( self, pool, pg_num, pgp_num=None, pool_type=None, erasure_code_profile=None, rule=None, expected_num_objects=None, body='json', timeout=None): """create pool""" kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool if not isinstance(pg_num, six.integer_types): raise CephClientTypeError( name='pg_num', actual=type(pg_num), expected=int) if pg_num < 0: raise CephClientValueOutOfBounds( name='pg_num', actual=pg_num, min=0, max='unlimited') kwargs['pg_num'] = pg_num if pgp_num is not None: if not isinstance(pgp_num, six.integer_types): raise CephClientTypeError( name='pgp_num', actual=type(pgp_num), expected=int) if pgp_num < 0: raise CephClientValueOutOfBounds( name='pgp_num', actual=pgp_num, min=0, max='unlimited') kwargs['pgp_num'] = pgp_num if pool_type is not None: if not isinstance(pool_type, six.string_types): raise CephClientTypeError( name='pool_type', actual=type(pool_type), expected=six.string_types) supported = CephClient.OSD_POOL_CREATE_POOL_TYPE_VALUES if pool_type not in supported: raise CephClientInvalidChoice( function='osd_pool_create', option='pool_type', value=pool_type, supported=', '.join(supported)) kwargs['pool_type'] = pool_type if erasure_code_profile is not None: if not isinstance(erasure_code_profile, six.string_types): raise CephClientTypeError( name='erasure_code_profile', actual=type(erasure_code_profile), expected=six.string_types) kwargs['erasure_code_profile'] = erasure_code_profile if rule is not None: if not isinstance(rule, six.string_types): raise CephClientTypeError( name='rule', actual=type(rule), expected=six.string_types) kwargs['rule'] = rule if expected_num_objects is not None: if not isinstance(expected_num_objects, six.integer_types): raise CephClientTypeError( name='expected_num_objects', actual=type(expected_num_objects), expected=int) kwargs['expected_num_objects'] = expected_num_objects return self._request('osd pool create', **kwargs) def osd_pool_delete(self, pool, pool2=None, sure=None, body='json', timeout=None): """delete pool""" kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool if pool2 is not None: if not isinstance(pool2, six.string_types): raise CephClientTypeError( name='pool2', actual=type(pool2), expected=six.string_types) kwargs['pool2'] = pool2 if sure is not None: if not isinstance(sure, six.string_types): raise CephClientTypeError( name='sure', actual=type(sure), expected=six.string_types) kwargs['sure'] = sure return self._request('osd pool delete', **kwargs) def osd_pool_rm(self, pool, pool2=None, sure=None, body='json', timeout=None): """remove pool""" kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool if pool2 is not None: if not isinstance(pool2, six.string_types): raise CephClientTypeError( name='pool2', actual=type(pool2), expected=six.string_types) kwargs['pool2'] = pool2 if sure is not None: if not isinstance(sure, six.string_types): raise CephClientTypeError( name='sure', actual=type(sure), expected=six.string_types) kwargs['sure'] = sure return self._request('osd pool rm', **kwargs) def osd_pool_rename(self, srcpool, destpool, body='json', timeout=None): """rename to """ kwargs = dict(body=body, timeout=timeout) if not isinstance(srcpool, six.string_types): raise CephClientTypeError( name='srcpool', actual=type(srcpool), expected=six.string_types) kwargs['srcpool'] = srcpool if not isinstance(destpool, six.string_types): raise CephClientTypeError( name='destpool', actual=type(destpool), expected=six.string_types) kwargs['destpool'] = destpool return self._request('osd pool rename', **kwargs) OSD_POOL_GET_VAR_VALUES = \ ['size', 'min_size', 'pg_num', 'pgp_num', 'crush_rule', 'hashpspool', 'nodelete', 'nopgchange', 'nosizechange', 'write_fadvise_dontneed', 'noscrub', 'nodeep-scrub', 'hit_set_type', 'hit_set_period', 'hit_set_count', 'hit_set_fpp', 'use_gmt_hitset', 'auid', 'target_max_objects', 'target_max_bytes', 'cache_target_dirty_ratio', 'cache_target_dirty_high_ratio', 'cache_target_full_ratio', 'cache_min_flush_age', 'cache_min_evict_age', 'erasure_code_profile', 'min_read_recency_for_promote', 'all', 'min_write_recency_for_promote', 'fast_read', 'hit_set_grade_decay_rate', 'hit_set_search_last_n', 'scrub_min_interval', 'scrub_max_interval', 'deep_scrub_interval', 'recovery_priority', 'recovery_op_priority', 'scrub_priority', 'compression_mode', 'compression_algorithm', 'compression_required_ratio', 'compression_max_blob_size', 'compression_min_blob_size', 'csum_type', 'csum_min_block', 'csum_max_block', 'allow_ec_overwrites'] def osd_pool_get(self, pool, var, body='json', timeout=None): """get pool parameter """ kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool if not isinstance(var, six.string_types): raise CephClientTypeError( name='var', actual=type(var), expected=six.string_types) supported = CephClient.OSD_POOL_GET_VAR_VALUES if var not in supported: raise CephClientInvalidChoice( function='osd_pool_get', option='var', value=var, supported=', '.join(supported)) kwargs['var'] = var return self._request('osd pool get', **kwargs) OSD_POOL_SET_VAR_VALUES = \ ['size', 'min_size', 'pg_num', 'pgp_num', 'crush_rule', 'hashpspool', 'nodelete', 'nopgchange', 'nosizechange', 'write_fadvise_dontneed', 'noscrub', 'nodeep-scrub', 'hit_set_type', 'hit_set_period', 'hit_set_count', 'hit_set_fpp', 'use_gmt_hitset', 'target_max_bytes', 'target_max_objects', 'cache_target_dirty_ratio', 'cache_target_dirty_high_ratio', 'cache_target_full_ratio', 'cache_min_flush_age', 'cache_min_evict_age', 'auid', 'min_read_recency_for_promote', 'min_write_recency_for_promote', 'fast_read', 'hit_set_grade_decay_rate', 'hit_set_search_last_n', 'scrub_min_interval', 'scrub_max_interval', 'deep_scrub_interval', 'recovery_priority', 'recovery_op_priority', 'scrub_priority', 'compression_mode', 'compression_algorithm', 'compression_required_ratio', 'compression_max_blob_size', 'compression_min_blob_size', 'csum_type', 'csum_min_block', 'csum_max_block', 'allow_ec_overwrites'] OSD_POOL_SET_FORCE_VALUES = ['--yes-i-really-mean-it'] def osd_pool_set(self, pool, var, val, force=None, body='json', timeout=None): """set pool parameter to """ kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool if not isinstance(var, six.string_types): raise CephClientTypeError( name='var', actual=type(var), expected=six.string_types) supported = CephClient.OSD_POOL_SET_VAR_VALUES if var not in supported: raise CephClientInvalidChoice( function='osd_pool_set', option='var', value=var, supported=', '.join(supported)) kwargs['var'] = var if not isinstance(val, six.string_types): raise CephClientTypeError( name='val', actual=type(val), expected=six.string_types) kwargs['val'] = val if force is not None: if not isinstance(force, six.string_types): raise CephClientTypeError( name='force', actual=type(force), expected=six.string_types) supported = CephClient.OSD_POOL_SET_FORCE_VALUES if force not in supported: raise CephClientInvalidChoice( function='osd_pool_set', option='force', value=force, supported=', '.join(supported)) kwargs['force'] = force return self._request('osd pool set', **kwargs) OSD_POOL_SET_QUOTA_FIELD_VALUES = ['max_objects', 'max_bytes'] def osd_pool_set_quota(self, pool, field, val, body='json', timeout=None): """set object or byte limit on pool""" kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool if not isinstance(field, six.string_types): raise CephClientTypeError( name='field', actual=type(field), expected=six.string_types) supported = CephClient.OSD_POOL_SET_QUOTA_FIELD_VALUES if field not in supported: raise CephClientInvalidChoice( function='osd_pool_set_quota', option='field', value=field, supported=', '.join(supported)) kwargs['field'] = field if not isinstance(val, six.string_types): raise CephClientTypeError( name='val', actual=type(val), expected=six.string_types) kwargs['val'] = val return self._request('osd pool set-quota', **kwargs) def osd_pool_get_quota(self, pool, body='json', timeout=None): """obtain object or byte limits for pool""" kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool return self._request('osd pool get-quota', **kwargs) OSD_POOL_APPLICATION_ENABLE_FORCE_VALUES = ['--yes-i-really-mean-it'] def osd_pool_application_enable( self, pool, app, force=None, body='json', timeout=None): """enable use of an application [cephfs,rbd,rgw] on pool """ kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool if not isinstance(app, six.string_types): raise CephClientTypeError( name='app', actual=type(app), expected=six.string_types) kwargs['app'] = app if force is not None: if not isinstance(force, six.string_types): raise CephClientTypeError( name='force', actual=type(force), expected=six.string_types) supported = CephClient.OSD_POOL_APPLICATION_ENABLE_FORCE_VALUES if force not in supported: raise CephClientInvalidChoice( function='osd_pool_application_enable', option='force', value=force, supported=', '.join(supported)) kwargs['force'] = force return self._request('osd pool application enable', **kwargs) OSD_POOL_APPLICATION_DISABLE_FORCE_VALUES = ['--yes-i-really-mean-it'] def osd_pool_application_disable( self, pool, app, force=None, body='json', timeout=None): """disables use of an application on pool """ kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool if not isinstance(app, six.string_types): raise CephClientTypeError( name='app', actual=type(app), expected=six.string_types) kwargs['app'] = app if force is not None: if not isinstance(force, six.string_types): raise CephClientTypeError( name='force', actual=type(force), expected=six.string_types) supported = CephClient.OSD_POOL_APPLICATION_DISABLE_FORCE_VALUES if force not in supported: raise CephClientInvalidChoice( function='osd_pool_application_disable', option='force', value=force, supported=', '.join(supported)) kwargs['force'] = force return self._request('osd pool application disable', **kwargs) def osd_pool_application_set( self, pool, app, key, value, body='json', timeout=None): """sets application metadata key to on pool """ kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool if not isinstance(app, six.string_types): raise CephClientTypeError( name='app', actual=type(app), expected=six.string_types) kwargs['app'] = app if not isinstance(key, six.string_types): raise CephClientTypeError( name='key', actual=type(key), expected=six.string_types) kwargs['key'] = key if not isinstance(value, six.string_types): raise CephClientTypeError( name='value', actual=type(value), expected=six.string_types) kwargs['value'] = value return self._request('osd pool application set', **kwargs) def osd_pool_application_rm( self, pool, app, key, body='json', timeout=None): """removes application metadata key on pool """ kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool if not isinstance(app, six.string_types): raise CephClientTypeError( name='app', actual=type(app), expected=six.string_types) kwargs['app'] = app if not isinstance(key, six.string_types): raise CephClientTypeError( name='key', actual=type(key), expected=six.string_types) kwargs['key'] = key return self._request('osd pool application rm', **kwargs) def osd_pool_application_get( self, pool, app=None, key=None, body='json', timeout=None): """get value of key of application on pool """ kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool if app is not None: if not isinstance(app, six.string_types): raise CephClientTypeError( name='app', actual=type(app), expected=six.string_types) kwargs['app'] = app if key is not None: if not isinstance(key, six.string_types): raise CephClientTypeError( name='key', actual=type(key), expected=six.string_types) kwargs['key'] = key return self._request('osd pool application get', **kwargs) def osd_utilization(self, body='json', timeout=None): """get basic pg distribution stats""" return self._request('osd utilization', body=body, timeout=timeout) OSD_TIER_ADD_FORCE_NONEMPTY_VALUES = ['--force-nonempty'] def osd_tier_add( self, pool, tierpool, force_nonempty=None, body='json', timeout=None): """add the tier (the second one) to base pool (thefirst one)""" kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool if not isinstance(tierpool, six.string_types): raise CephClientTypeError( name='tierpool', actual=type(tierpool), expected=six.string_types) kwargs['tierpool'] = tierpool if force_nonempty is not None: if not isinstance(force_nonempty, six.string_types): raise CephClientTypeError( name='force_nonempty', actual=type(force_nonempty), expected=six.string_types) supported = CephClient.OSD_TIER_ADD_FORCE_NONEMPTY_VALUES if force_nonempty not in supported: raise CephClientInvalidChoice( function='osd_tier_add', option='force_nonempty', value=force_nonempty, supported=', '.join(supported)) kwargs['force_nonempty'] = force_nonempty return self._request('osd tier add', **kwargs) def osd_tier_rm(self, pool, tierpool, body='json', timeout=None): """remove the tier (the second one) from base pool (thefirst one)""" kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool if not isinstance(tierpool, six.string_types): raise CephClientTypeError( name='tierpool', actual=type(tierpool), expected=six.string_types) kwargs['tierpool'] = tierpool return self._request('osd tier rm', **kwargs) def osd_tier_remove(self, pool, tierpool, body='json', timeout=None): """remove the tier (the second one) from base pool (thefirst one)""" kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool if not isinstance(tierpool, six.string_types): raise CephClientTypeError( name='tierpool', actual=type(tierpool), expected=six.string_types) kwargs['tierpool'] = tierpool return self._request('osd tier remove', **kwargs) OSD_TIER_CACHE_MODE_MODE_VALUES = \ ['none', 'writeback', 'forward', 'readonly', 'readforward', 'proxy', 'readproxy'] OSD_TIER_CACHE_MODE_SURE_VALUES = ['--yes-i-really-mean-it'] def osd_tier_cache_mode( self, pool, mode, sure=None, body='json', timeout=None): """specify the caching mode for cache tier """ kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool if not isinstance(mode, six.string_types): raise CephClientTypeError( name='mode', actual=type(mode), expected=six.string_types) supported = CephClient.OSD_TIER_CACHE_MODE_MODE_VALUES if mode not in supported: raise CephClientInvalidChoice( function='osd_tier_cache_mode', option='mode', value=mode, supported=', '.join(supported)) kwargs['mode'] = mode if sure is not None: if not isinstance(sure, six.string_types): raise CephClientTypeError( name='sure', actual=type(sure), expected=six.string_types) supported = CephClient.OSD_TIER_CACHE_MODE_SURE_VALUES if sure not in supported: raise CephClientInvalidChoice( function='osd_tier_cache_mode', option='sure', value=sure, supported=', '.join(supported)) kwargs['sure'] = sure return self._request('osd tier cache-mode', **kwargs) def osd_tier_set_overlay( self, pool, overlaypool, body='json', timeout=None): """set the overlay pool for base pool to be """ kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool if not isinstance(overlaypool, six.string_types): raise CephClientTypeError( name='overlaypool', actual=type(overlaypool), expected=six.string_types) kwargs['overlaypool'] = overlaypool return self._request('osd tier set-overlay', **kwargs) def osd_tier_rm_overlay(self, pool, body='json', timeout=None): """remove the overlay pool for base pool """ kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool return self._request('osd tier rm-overlay', **kwargs) def osd_tier_remove_overlay(self, pool, body='json', timeout=None): """remove the overlay pool for base pool """ kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool return self._request('osd tier remove-overlay', **kwargs) def osd_tier_add_cache(self, pool, tierpool, size, body='json', timeout=None): """add a cache (the second one) of size to existingpool (the first one) """ kwargs = dict(body=body, timeout=timeout) if not isinstance(pool, six.string_types): raise CephClientTypeError( name='pool', actual=type(pool), expected=six.string_types) kwargs['pool'] = pool if not isinstance(tierpool, six.string_types): raise CephClientTypeError( name='tierpool', actual=type(tierpool), expected=six.string_types) kwargs['tierpool'] = tierpool if not isinstance(size, six.integer_types): raise CephClientTypeError( name='size', actual=type(size), expected=int) if size < 0: raise CephClientValueOutOfBounds( name='size', actual=size, min=0, max='unlimited') kwargs['size'] = size return self._request('osd tier add-cache', **kwargs) def config_key_get(self, key, body='json', timeout=None): """get """ kwargs = dict(body=body, timeout=timeout) if not isinstance(key, six.string_types): raise CephClientTypeError( name='key', actual=type(key), expected=six.string_types) kwargs['key'] = key return self._request('config-key get', **kwargs) def config_key_set(self, key, val=None, body='json', timeout=None): """set to value """ kwargs = dict(body=body, timeout=timeout) if not isinstance(key, six.string_types): raise CephClientTypeError( name='key', actual=type(key), expected=six.string_types) kwargs['key'] = key if val is not None: if not isinstance(val, six.string_types): raise CephClientTypeError( name='val', actual=type(val), expected=six.string_types) kwargs['val'] = val return self._request('config-key set', **kwargs) def config_key_put(self, key, val=None, body='json', timeout=None): """put , value """ kwargs = dict(body=body, timeout=timeout) if not isinstance(key, six.string_types): raise CephClientTypeError( name='key', actual=type(key), expected=six.string_types) kwargs['key'] = key if val is not None: if not isinstance(val, six.string_types): raise CephClientTypeError( name='val', actual=type(val), expected=six.string_types) kwargs['val'] = val return self._request('config-key put', **kwargs) def config_key_del(self, key, body='json', timeout=None): """delete """ kwargs = dict(body=body, timeout=timeout) if not isinstance(key, six.string_types): raise CephClientTypeError( name='key', actual=type(key), expected=six.string_types) kwargs['key'] = key return self._request('config-key del', **kwargs) def config_key_rm(self, key, body='json', timeout=None): """rm """ kwargs = dict(body=body, timeout=timeout) if not isinstance(key, six.string_types): raise CephClientTypeError( name='key', actual=type(key), expected=six.string_types) kwargs['key'] = key return self._request('config-key rm', **kwargs) def config_key_exists(self, key, body='json', timeout=None): """check for 's existence""" kwargs = dict(body=body, timeout=timeout) if not isinstance(key, six.string_types): raise CephClientTypeError( name='key', actual=type(key), expected=six.string_types) kwargs['key'] = key return self._request('config-key exists', **kwargs) def config_key_list(self, body='json', timeout=None): """list keys""" return self._request('config-key list', body=body, timeout=timeout) def config_key_ls(self, body='json', timeout=None): """list keys""" return self._request('config-key ls', body=body, timeout=timeout) def config_key_dump(self, key=None, body='json', timeout=None): """dump keys and values (with optional prefix)""" kwargs = dict(body=body, timeout=timeout) if key is not None: if not isinstance(key, six.string_types): raise CephClientTypeError( name='key', actual=type(key), expected=six.string_types) kwargs['key'] = key return self._request('config-key dump', **kwargs) def mgr_dump(self, epoch=None, body='json', timeout=None): """dump the latest MgrMap""" kwargs = dict(body=body, timeout=timeout) if epoch is not None: if not isinstance(epoch, six.integer_types): raise CephClientTypeError( name='epoch', actual=type(epoch), expected=int) if epoch < 0: raise CephClientValueOutOfBounds( name='epoch', actual=epoch, min=0, max='unlimited') kwargs['epoch'] = epoch return self._request('mgr dump', **kwargs) def mgr_fail(self, who, body='json', timeout=None): """treat the named manager daemon as failed""" kwargs = dict(body=body, timeout=timeout) if not isinstance(who, six.string_types): raise CephClientTypeError( name='who', actual=type(who), expected=six.string_types) kwargs['who'] = who return self._request('mgr fail', **kwargs) def mgr_module_ls(self, body='json', timeout=None): """list active mgr modules""" return self._request('mgr module ls', body=body, timeout=timeout) def mgr_services(self, body='json', timeout=None): """list service endpoints provided by mgr modules""" return self._request('mgr services', body=body, timeout=timeout) MGR_MODULE_ENABLE_FORCE_VALUES = ['--force'] def mgr_module_enable(self, module, force=None, body='json', timeout=None): """enable mgr module""" kwargs = dict(body=body, timeout=timeout) if not isinstance(module, six.string_types): raise CephClientTypeError( name='module', actual=type(module), expected=six.string_types) kwargs['module'] = module if force is not None: if not isinstance(force, six.string_types): raise CephClientTypeError( name='force', actual=type(force), expected=six.string_types) supported = CephClient.MGR_MODULE_ENABLE_FORCE_VALUES if force not in supported: raise CephClientInvalidChoice( function='mgr_module_enable', option='force', value=force, supported=', '.join(supported)) kwargs['force'] = force return self._request('mgr module enable', **kwargs) def mgr_module_disable(self, module, body='json', timeout=None): """disable mgr module""" kwargs = dict(body=body, timeout=timeout) if not isinstance(module, six.string_types): raise CephClientTypeError( name='module', actual=type(module), expected=six.string_types) kwargs['module'] = module return self._request('mgr module disable', **kwargs) def mgr_metadata(self, who=None, body='json', timeout=None): """dump metadata for all daemons or a specific daemon""" kwargs = dict(body=body, timeout=timeout) if who is not None: if not isinstance(who, six.string_types): raise CephClientTypeError( name='who', actual=type(who), expected=six.string_types) kwargs['who'] = who return self._request('mgr metadata', **kwargs) def mgr_count_metadata(self, _property, body='json', timeout=None): """count ceph-mgr daemons by metadata field property""" kwargs = dict(body=body, timeout=timeout) if not isinstance(_property, six.string_types): raise CephClientTypeError( name='_property', actual=type(_property), expected=six.string_types) kwargs['property'] = _property return self._request('mgr count-metadata', **kwargs) def mgr_versions(self, body='json', timeout=None): """check running versions of ceph-mgr daemons""" return self._request('mgr versions', body=body, timeout=timeout) def config_set(self, who, name, value, body='json', timeout=None): """Set a configuration option for one or more entities""" kwargs = dict(body=body, timeout=timeout) if not isinstance(who, six.string_types): raise CephClientTypeError( name='who', actual=type(who), expected=six.string_types) kwargs['who'] = who if not isinstance(name, six.string_types): raise CephClientTypeError( name='name', actual=type(name), expected=six.string_types) kwargs['name'] = name if not isinstance(value, six.string_types): raise CephClientTypeError( name='value', actual=type(value), expected=six.string_types) kwargs['value'] = value return self._request('config set', **kwargs) def config_rm(self, who, name, body='json', timeout=None): """Clear a configuration option for one or more entities""" kwargs = dict(body=body, timeout=timeout) if not isinstance(who, six.string_types): raise CephClientTypeError( name='who', actual=type(who), expected=six.string_types) kwargs['who'] = who if not isinstance(name, six.string_types): raise CephClientTypeError( name='name', actual=type(name), expected=six.string_types) kwargs['name'] = name return self._request('config rm', **kwargs) def config_get(self, who, key, body='json', timeout=None): """Show configuration option(s) for an entity""" kwargs = dict(body=body, timeout=timeout) if not isinstance(who, six.string_types): raise CephClientTypeError( name='who', actual=type(who), expected=six.string_types) kwargs['who'] = who if not isinstance(key, six.string_types): raise CephClientTypeError( name='key', actual=type(key), expected=six.string_types) kwargs['key'] = key return self._request('config get', **kwargs) def config_dump(self, body='json', timeout=None): """Show all configuration option(s)""" return self._request('config dump', body=body, timeout=timeout) def config_help(self, key, body='json', timeout=None): """Describe a configuration option""" kwargs = dict(body=body, timeout=timeout) if not isinstance(key, six.string_types): raise CephClientTypeError( name='key', actual=type(key), expected=six.string_types) kwargs['key'] = key return self._request('config help', **kwargs) def config_assimilate_conf(self, body='json', timeout=None): """Assimilate options from a conf, and return a new, minimal conf file""" return self._request('config assimilate-conf', body=body, timeout=timeout) def config_log(self, num, body='json', timeout=None): """Show recent history of config changes""" kwargs = dict(body=body, timeout=timeout) if not isinstance(num, six.integer_types): raise CephClientTypeError( name='num', actual=type(num), expected=int) kwargs['num'] = num return self._request('config log', **kwargs) def config_reset(self, num, body='json', timeout=None): """Revert configuration to previous state""" kwargs = dict(body=body, timeout=timeout) if not isinstance(num, six.integer_types): raise CephClientTypeError( name='num', actual=type(num), expected=int) kwargs['num'] = num return self._request('config reset', **kwargs)