+++ /dev/null
-from pecan import expose, request, response
-from pecan.rest import RestController
-
-import common
-
-from collections import defaultdict
-
-from decorators import auth, catch, lock
-
-## We need this to access the instance of the module
-#
-# We can't use 'from module import instance' because
-# the instance is not ready, yet (would be None)
-import module
-
-
-class ServerFqdn(RestController):
- def __init__(self, fqdn):
- self.fqdn = fqdn
-
-
- @expose(template='json')
- @catch
- @auth
- def get(self, **kwargs):
- """
- Show the information for the server fqdn
- """
- return module.instance.get_server(self.fqdn)
-
-
-
-class Server(RestController):
- @expose(template='json')
- @catch
- @auth
- def get(self, **kwargs):
- """
- Show the information for all the servers
- """
- return module.instance.list_servers()
-
-
- @expose()
- def _lookup(self, fqdn, *remainder):
- return ServerFqdn(fqdn), remainder
-
-
-
-class RequestId(RestController):
- def __init__(self, request_id):
- self.request_id = request_id
-
-
- @expose(template='json')
- @catch
- @auth
- def get(self, **kwargs):
- """
- Show the information for the request id
- """
- request = filter(
- lambda x: x.id == self.request_id,
- module.instance.requests
- )
-
- if len(request) != 1:
- response.status = 500
- return {'message': 'Unknown request id "%s"' % str(self.request_id)}
-
- request = request[0]
- return request
-
-
- @expose(template='json')
- @catch
- @auth
- @lock
- def delete(self, **kwargs):
- """
- Remove the request id from the database
- """
- for index in range(len(module.instance.requests)):
- if module.instance.requests[index].id == self.request_id:
- return module.instance.requests.pop(index)
-
- # Failed to find the job to cancel
- response.status = 500
- return {'message': 'No such request id'}
-
-
-
-class Request(RestController):
- @expose(template='json')
- @catch
- @auth
- def get(self, **kwargs):
- """
- List all the available requests and their state
- """
- states = {}
- for _request in module.instance.requests:
- states[_request.id] = _request.get_state()
-
- return states
-
-
- @expose(template='json')
- @catch
- @auth
- @lock
- def delete(self, **kwargs):
- """
- Remove all the finished requests
- """
- num_requests = len(module.instance.requests)
-
- module.instance.requests = filter(
- lambda x: not x.is_finished(),
- module.instance.requests
- )
-
- # Return the job statistics
- return {
- 'cleaned': num_requests - len(module.instance.requests),
- 'remaining': len(module.instance.requests),
- }
-
-
- @expose(template='json')
- @catch
- @auth
- def post(self, **kwargs):
- """
- Pass through method to create any request
- """
- return module.instance.submit_request([[request.json]], **kwargs)
-
-
- @expose()
- def _lookup(self, request_id, *remainder):
- return RequestId(request_id), remainder
-
-
-
-class PoolId(RestController):
- def __init__(self, pool_id):
- self.pool_id = pool_id
-
-
- @expose(template='json')
- @catch
- @auth
- def get(self, **kwargs):
- """
- Show the information for the pool id
- """
- pool = module.instance.get_pool_by_id(self.pool_id)
-
- if not pool:
- response.status = 500
- return {'message': 'Failed to identify the pool id "%d"' % self.pool_id}
-
- # pgp_num is called pg_placement_num, deal with that
- if 'pg_placement_num' in pool:
- pool['pgp_num'] = pool.pop('pg_placement_num')
- return pool
-
-
- @expose(template='json')
- @catch
- @auth
- def patch(self, **kwargs):
- """
- Modify the information for the pool id
- """
- args = request.json
-
- # Get the pool info for its name
- pool = module.instance.get_pool_by_id(self.pool_id)
- if not pool:
- response.status = 500
- return {'message': 'Failed to identify the pool id "%d"' % self.pool_id}
-
- # Check for invalid pool args
- invalid = common.invalid_pool_args(args)
- if invalid:
- response.status = 500
- return {'message': 'Invalid arguments found: "%s"' % str(invalid)}
-
- # Schedule the update request
- return module.instance.submit_request(common.pool_update_commands(pool['pool_name'], args), **kwargs)
-
-
- @expose(template='json')
- @catch
- @auth
- def delete(self, **kwargs):
- """
- Remove the pool data for the pool id
- """
- pool = module.instance.get_pool_by_id(self.pool_id)
-
- if not pool:
- response.status = 500
- return {'message': 'Failed to identify the pool id "%d"' % self.pool_id}
-
- return module.instance.submit_request([[{
- 'prefix': 'osd pool delete',
- 'pool': pool['pool_name'],
- 'pool2': pool['pool_name'],
- 'sure': '--yes-i-really-really-mean-it'
- }]], **kwargs)
-
-
-
-class Pool(RestController):
- @expose(template='json')
- @catch
- @auth
- def get(self, **kwargs):
- """
- Show the information for all the pools
- """
- pools = module.instance.get('osd_map')['pools']
-
- # pgp_num is called pg_placement_num, deal with that
- for pool in pools:
- if 'pg_placement_num' in pool:
- pool['pgp_num'] = pool.pop('pg_placement_num')
-
- return pools
-
-
- @expose(template='json')
- @catch
- @auth
- def post(self, **kwargs):
- """
- Create a new pool
- Requires name and pg_num dict arguments
- """
- args = request.json
-
- # Check for the required arguments
- pool_name = args.pop('name', None)
- if pool_name is None:
- response.status = 500
- return {'message': 'You need to specify the pool "name" argument'}
-
- pg_num = args.pop('pg_num', None)
- if pg_num is None:
- response.status = 500
- return {'message': 'You need to specify the "pg_num" argument'}
-
- # Run the pool create command first
- create_command = {
- 'prefix': 'osd pool create',
- 'pool': pool_name,
- 'pg_num': pg_num
- }
-
- # Check for invalid pool args
- invalid = common.invalid_pool_args(args)
- if invalid:
- response.status = 500
- return {'message': 'Invalid arguments found: "%s"' % str(invalid)}
-
- # Schedule the creation and update requests
- return module.instance.submit_request(
- [[create_command]] +
- common.pool_update_commands(pool_name, args),
- **kwargs
- )
-
-
- @expose()
- def _lookup(self, pool_id, *remainder):
- return PoolId(int(pool_id)), remainder
-
-
-
-class OsdIdCommand(RestController):
- def __init__(self, osd_id):
- self.osd_id = osd_id
-
-
- @expose(template='json')
- @catch
- @auth
- def get(self, **kwargs):
- """
- Show implemented commands for the OSD id
- """
- osd = module.instance.get_osd_by_id(self.osd_id)
-
- if not osd:
- response.status = 500
- return {'message': 'Failed to identify the OSD id "%d"' % self.osd_id}
-
- if osd['up']:
- return common.OSD_IMPLEMENTED_COMMANDS
- else:
- return []
-
-
- @expose(template='json')
- @catch
- @auth
- def post(self, **kwargs):
- """
- Run the implemented command for the OSD id
- """
- command = request.json.get('command', None)
-
- osd = module.instance.get_osd_by_id(self.osd_id)
-
- if not osd:
- response.status = 500
- return {'message': 'Failed to identify the OSD id "%d"' % self.osd_id}
-
- if not osd['up'] or command not in common.OSD_IMPLEMENTED_COMMANDS:
- response.status = 500
- return {'message': 'Command "%s" not available' % command}
-
- return module.instance.submit_request([[{
- 'prefix': 'osd ' + command,
- 'who': str(self.osd_id)
- }]], **kwargs)
-
-
-
-class OsdId(RestController):
- def __init__(self, osd_id):
- self.osd_id = osd_id
- self.command = OsdIdCommand(osd_id)
-
-
- @expose(template='json')
- @catch
- @auth
- def get(self, **kwargs):
- """
- Show the information for the OSD id
- """
- osd = module.instance.get_osds(ids=[str(self.osd_id)])
- if len(osd) != 1:
- response.status = 500
- return {'message': 'Failed to identify the OSD id "%d"' % self.osd_id}
-
- return osd[0]
-
-
- @expose(template='json')
- @catch
- @auth
- def patch(self, **kwargs):
- """
- Modify the state (up, in) of the OSD id or reweight it
- """
- args = request.json
-
- commands = []
-
- if 'in' in args:
- if args['in']:
- commands.append({
- 'prefix': 'osd in',
- 'ids': [str(self.osd_id)]
- })
- else:
- commands.append({
- 'prefix': 'osd out',
- 'ids': [str(self.osd_id)]
- })
-
- if 'up' in args:
- if args['up']:
- response.status = 500
- return {'message': "It is not valid to set a down OSD to be up"}
- else:
- commands.append({
- 'prefix': 'osd down',
- 'ids': [str(self.osd_id)]
- })
-
- if 'reweight' in args:
- commands.append({
- 'prefix': 'osd reweight',
- 'id': self.osd_id,
- 'weight': args['reweight']
- })
-
- return module.instance.submit_request([commands], **kwargs)
-
-
-
-class Osd(RestController):
- @expose(template='json')
- @catch
- @auth
- def get(self, **kwargs):
- """
- Show the information for all the OSDs
- """
- # Parse request args
- # TODO Filter by ids
- pool_id = kwargs.get('pool', None)
-
- return module.instance.get_osds(pool_id)
-
-
- @expose()
- def _lookup(self, osd_id, *remainder):
- return OsdId(int(osd_id)), remainder
-
-
-
-class MonName(RestController):
- def __init__(self, name):
- self.name = name
-
-
- @expose(template='json')
- @catch
- @auth
- def get(self, **kwargs):
- """
- Show the information for the monitor name
- """
- mon = filter(
- lambda x: x['name'] == self.name,
- module.instance.get_mons()
- )
-
- if len(mon) != 1:
- response.status = 500
- return {'message': 'Failed to identify the monitor node "%s"' % self.name}
-
- return mon[0]
-
-
-
-class Mon(RestController):
- @expose(template='json')
- @catch
- @auth
- def get(self, **kwargs):
- """
- Show the information for all the monitors
- """
- return module.instance.get_mons()
-
-
- @expose()
- def _lookup(self, name, *remainder):
- return MonName(name), remainder
-
-
-
-class Doc(RestController):
- @expose(template='json')
- @catch
- def get(self, **kwargs):
- """
- Show documentation information
- """
- return module.instance.get_doc_api(Root)
-
-
-
-class CrushRuleset(RestController):
- @expose(template='json')
- @catch
- @auth
- def get(self, **kwargs):
- """
- Show crush rulesets
- """
- rules = module.instance.get('osd_map_crush')['rules']
- nodes = module.instance.get('osd_map_tree')['nodes']
-
- ruleset = defaultdict(list)
- for rule in rules:
- rule['osd_count'] = len(common.crush_rule_osds(nodes, rule))
- ruleset[rule['ruleset']].append(rule)
-
- return ruleset
-
-
-
-class CrushRule(RestController):
- @expose(template='json')
- @catch
- @auth
- def get(self, **kwargs):
- """
- Show crush rules
- """
- rules = module.instance.get('osd_map_crush')['rules']
- nodes = module.instance.get('osd_map_tree')['nodes']
-
- for rule in rules:
- rule['osd_count'] = len(common.crush_rule_osds(nodes, rule))
-
- return rules
-
-
-
-class Crush(RestController):
- rule = CrushRule()
- ruleset = CrushRuleset()
-
-
-
-class ConfigOsd(RestController):
- @expose(template='json')
- @catch
- @auth
- def get(self, **kwargs):
- """
- Show OSD configuration options
- """
- flags = module.instance.get("osd_map")['flags']
-
- # pause is a valid osd config command that sets pauserd,pausewr
- flags = flags.replace('pauserd,pausewr', 'pause')
-
- return flags.split(',')
-
-
- @expose(template='json')
- @catch
- @auth
- def patch(self, **kwargs):
- """
- Modify OSD configration options
- """
- args = request.json
-
- commands = []
-
- valid_flags = set(args.keys()) & set(common.OSD_FLAGS)
- invalid_flags = list(set(args.keys()) - valid_flags)
- if invalid_flags:
- module.instance.log.warn("%s not valid to set/unset" % invalid_flags)
-
- for flag in list(valid_flags):
- if args[flag]:
- mode = 'set'
- else:
- mode = 'unset'
-
- commands.append({
- 'prefix': 'osd ' + mode,
- 'key': flag,
- })
-
- return module.instance.submit_request([commands], **kwargs)
-
-
-
-class ConfigClusterKey(RestController):
- def __init__(self, key):
- self.key = key
-
-
- @expose(template='json')
- @catch
- @auth
- def get(self, **kwargs):
- """
- Show specific configuration option
- """
- return module.instance.get("config").get(self.key, None)
-
-
-
-class ConfigCluster(RestController):
- @expose(template='json')
- @catch
- @auth
- def get(self, **kwargs):
- """
- Show all cluster configuration options
- """
- return module.instance.get("config")
-
-
- @expose()
- def _lookup(self, key, *remainder):
- return ConfigClusterKey(key), remainder
-
-
-
-class Config(RestController):
- cluster = ConfigCluster()
- osd = ConfigOsd()
-
-
-
-class Root(RestController):
- config = Config()
- crush = Crush()
- doc = Doc()
- mon = Mon()
- osd = Osd()
- pool = Pool()
- request = Request()
- server = Server()
-
- @expose(template='json')
- @catch
- def get(self, **kwargs):
- """
- Show the basic information for the REST API
- This includes values like api version or auth method
- """
- return {
- 'api_version': 1,
- 'auth':
- 'Use ceph auth key pair as HTTP Basic user/password '
- '(requires caps mon allow * to function properly)',
- 'doc': 'See /doc endpoint',
- 'info': "Ceph Manager RESTful API server",
- }
--- /dev/null
+from pecan import expose
+from pecan.rest import RestController
+
+from config import Config
+from crush import Crush
+from doc import Doc
+from mon import Mon
+from osd import Osd
+from pool import Pool
+from request import Request
+from server import Server
+
+from restful.decorators import catch
+
+
+class Root(RestController):
+ config = Config()
+ crush = Crush()
+ doc = Doc()
+ mon = Mon()
+ osd = Osd()
+ pool = Pool()
+ request = Request()
+ server = Server()
+
+ @expose(template='json')
+ @catch
+ def get(self, **kwargs):
+ """
+ Show the basic information for the REST API
+ This includes values like api version or auth method
+ """
+ return {
+ 'api_version': 1,
+ 'auth':
+ 'Use ceph auth key pair as HTTP Basic user/password '
+ '(requires caps mon allow * to function properly)',
+ 'doc': 'See /doc endpoint',
+ 'info': "Ceph Manager RESTful API server",
+ }
--- /dev/null
+from pecan import expose, request
+from pecan.rest import RestController
+
+from restful import common, module
+from restful.decorators import auth, catch
+
+
+class ConfigOsd(RestController):
+ @expose(template='json')
+ @catch
+ @auth
+ def get(self, **kwargs):
+ """
+ Show OSD configuration options
+ """
+ flags = module.instance.get("osd_map")['flags']
+
+ # pause is a valid osd config command that sets pauserd,pausewr
+ flags = flags.replace('pauserd,pausewr', 'pause')
+
+ return flags.split(',')
+
+
+ @expose(template='json')
+ @catch
+ @auth
+ def patch(self, **kwargs):
+ """
+ Modify OSD configration options
+ """
+ args = request.json
+
+ commands = []
+
+ valid_flags = set(args.keys()) & set(common.OSD_FLAGS)
+ invalid_flags = list(set(args.keys()) - valid_flags)
+ if invalid_flags:
+ module.instance.log.warn("%s not valid to set/unset" % invalid_flags)
+
+ for flag in list(valid_flags):
+ if args[flag]:
+ mode = 'set'
+ else:
+ mode = 'unset'
+
+ commands.append({
+ 'prefix': 'osd ' + mode,
+ 'key': flag,
+ })
+
+ return module.instance.submit_request([commands], **kwargs)
+
+
+
+class ConfigClusterKey(RestController):
+ def __init__(self, key):
+ self.key = key
+
+
+ @expose(template='json')
+ @catch
+ @auth
+ def get(self, **kwargs):
+ """
+ Show specific configuration option
+ """
+ return module.instance.get("config").get(self.key, None)
+
+
+
+class ConfigCluster(RestController):
+ @expose(template='json')
+ @catch
+ @auth
+ def get(self, **kwargs):
+ """
+ Show all cluster configuration options
+ """
+ return module.instance.get("config")
+
+
+ @expose()
+ def _lookup(self, key, *remainder):
+ return ConfigClusterKey(key), remainder
+
+
+
+class Config(RestController):
+ cluster = ConfigCluster()
+ osd = ConfigOsd()
--- /dev/null
+from pecan import expose
+from pecan.rest import RestController
+
+from restful import common, module
+from collections import defaultdict
+
+from restful.decorators import auth, catch
+
+
+class CrushRuleset(RestController):
+ @expose(template='json')
+ @catch
+ @auth
+ def get(self, **kwargs):
+ """
+ Show crush rulesets
+ """
+ rules = module.instance.get('osd_map_crush')['rules']
+ nodes = module.instance.get('osd_map_tree')['nodes']
+
+ ruleset = defaultdict(list)
+ for rule in rules:
+ rule['osd_count'] = len(common.crush_rule_osds(nodes, rule))
+ ruleset[rule['ruleset']].append(rule)
+
+ return ruleset
+
+
+
+class CrushRule(RestController):
+ @expose(template='json')
+ @catch
+ @auth
+ def get(self, **kwargs):
+ """
+ Show crush rules
+ """
+ rules = module.instance.get('osd_map_crush')['rules']
+ nodes = module.instance.get('osd_map_tree')['nodes']
+
+ for rule in rules:
+ rule['osd_count'] = len(common.crush_rule_osds(nodes, rule))
+
+ return rules
+
+
+
+class Crush(RestController):
+ rule = CrushRule()
+ ruleset = CrushRuleset()
--- /dev/null
+from pecan import expose
+from pecan.rest import RestController
+
+from restful import module
+from restful.decorators import catch
+
+import restful
+
+
+class Doc(RestController):
+ @expose(template='json')
+ @catch
+ def get(self, **kwargs):
+ """
+ Show documentation information
+ """
+ return module.instance.get_doc_api(restful.api.Root)
--- /dev/null
+from pecan import expose, response
+from pecan.rest import RestController
+
+from restful import module
+from restful.decorators import auth, catch
+
+
+class MonName(RestController):
+ def __init__(self, name):
+ self.name = name
+
+
+ @expose(template='json')
+ @catch
+ @auth
+ def get(self, **kwargs):
+ """
+ Show the information for the monitor name
+ """
+ mon = filter(
+ lambda x: x['name'] == self.name,
+ module.instance.get_mons()
+ )
+
+ if len(mon) != 1:
+ response.status = 500
+ return {'message': 'Failed to identify the monitor node "%s"' % self.name}
+
+ return mon[0]
+
+
+
+class Mon(RestController):
+ @expose(template='json')
+ @catch
+ @auth
+ def get(self, **kwargs):
+ """
+ Show the information for all the monitors
+ """
+ return module.instance.get_mons()
+
+
+ @expose()
+ def _lookup(self, name, *remainder):
+ return MonName(name), remainder
--- /dev/null
+from pecan import expose, request, response
+from pecan.rest import RestController
+
+from restful import common, module
+from restful.decorators import auth, catch
+
+
+class OsdIdCommand(RestController):
+ def __init__(self, osd_id):
+ self.osd_id = osd_id
+
+
+ @expose(template='json')
+ @catch
+ @auth
+ def get(self, **kwargs):
+ """
+ Show implemented commands for the OSD id
+ """
+ osd = module.instance.get_osd_by_id(self.osd_id)
+
+ if not osd:
+ response.status = 500
+ return {'message': 'Failed to identify the OSD id "%d"' % self.osd_id}
+
+ if osd['up']:
+ return common.OSD_IMPLEMENTED_COMMANDS
+ else:
+ return []
+
+
+ @expose(template='json')
+ @catch
+ @auth
+ def post(self, **kwargs):
+ """
+ Run the implemented command for the OSD id
+ """
+ command = request.json.get('command', None)
+
+ osd = module.instance.get_osd_by_id(self.osd_id)
+
+ if not osd:
+ response.status = 500
+ return {'message': 'Failed to identify the OSD id "%d"' % self.osd_id}
+
+ if not osd['up'] or command not in common.OSD_IMPLEMENTED_COMMANDS:
+ response.status = 500
+ return {'message': 'Command "%s" not available' % command}
+
+ return module.instance.submit_request([[{
+ 'prefix': 'osd ' + command,
+ 'who': str(self.osd_id)
+ }]], **kwargs)
+
+
+
+class OsdId(RestController):
+ def __init__(self, osd_id):
+ self.osd_id = osd_id
+ self.command = OsdIdCommand(osd_id)
+
+
+ @expose(template='json')
+ @catch
+ @auth
+ def get(self, **kwargs):
+ """
+ Show the information for the OSD id
+ """
+ osd = module.instance.get_osds(ids=[str(self.osd_id)])
+ if len(osd) != 1:
+ response.status = 500
+ return {'message': 'Failed to identify the OSD id "%d"' % self.osd_id}
+
+ return osd[0]
+
+
+ @expose(template='json')
+ @catch
+ @auth
+ def patch(self, **kwargs):
+ """
+ Modify the state (up, in) of the OSD id or reweight it
+ """
+ args = request.json
+
+ commands = []
+
+ if 'in' in args:
+ if args['in']:
+ commands.append({
+ 'prefix': 'osd in',
+ 'ids': [str(self.osd_id)]
+ })
+ else:
+ commands.append({
+ 'prefix': 'osd out',
+ 'ids': [str(self.osd_id)]
+ })
+
+ if 'up' in args:
+ if args['up']:
+ response.status = 500
+ return {'message': "It is not valid to set a down OSD to be up"}
+ else:
+ commands.append({
+ 'prefix': 'osd down',
+ 'ids': [str(self.osd_id)]
+ })
+
+ if 'reweight' in args:
+ commands.append({
+ 'prefix': 'osd reweight',
+ 'id': self.osd_id,
+ 'weight': args['reweight']
+ })
+
+ return module.instance.submit_request([commands], **kwargs)
+
+
+
+class Osd(RestController):
+ @expose(template='json')
+ @catch
+ @auth
+ def get(self, **kwargs):
+ """
+ Show the information for all the OSDs
+ """
+ # Parse request args
+ # TODO Filter by ids
+ pool_id = kwargs.get('pool', None)
+
+ return module.instance.get_osds(pool_id)
+
+
+ @expose()
+ def _lookup(self, osd_id, *remainder):
+ return OsdId(int(osd_id)), remainder
--- /dev/null
+from pecan import expose, request, response
+from pecan.rest import RestController
+
+from restful import common, module
+from restful.decorators import auth, catch
+
+
+class PoolId(RestController):
+ def __init__(self, pool_id):
+ self.pool_id = pool_id
+
+
+ @expose(template='json')
+ @catch
+ @auth
+ def get(self, **kwargs):
+ """
+ Show the information for the pool id
+ """
+ pool = module.instance.get_pool_by_id(self.pool_id)
+
+ if not pool:
+ response.status = 500
+ return {'message': 'Failed to identify the pool id "%d"' % self.pool_id}
+
+ # pgp_num is called pg_placement_num, deal with that
+ if 'pg_placement_num' in pool:
+ pool['pgp_num'] = pool.pop('pg_placement_num')
+ return pool
+
+
+ @expose(template='json')
+ @catch
+ @auth
+ def patch(self, **kwargs):
+ """
+ Modify the information for the pool id
+ """
+ args = request.json
+
+ # Get the pool info for its name
+ pool = module.instance.get_pool_by_id(self.pool_id)
+ if not pool:
+ response.status = 500
+ return {'message': 'Failed to identify the pool id "%d"' % self.pool_id}
+
+ # Check for invalid pool args
+ invalid = common.invalid_pool_args(args)
+ if invalid:
+ response.status = 500
+ return {'message': 'Invalid arguments found: "%s"' % str(invalid)}
+
+ # Schedule the update request
+ return module.instance.submit_request(common.pool_update_commands(pool['pool_name'], args), **kwargs)
+
+
+ @expose(template='json')
+ @catch
+ @auth
+ def delete(self, **kwargs):
+ """
+ Remove the pool data for the pool id
+ """
+ pool = module.instance.get_pool_by_id(self.pool_id)
+
+ if not pool:
+ response.status = 500
+ return {'message': 'Failed to identify the pool id "%d"' % self.pool_id}
+
+ return module.instance.submit_request([[{
+ 'prefix': 'osd pool delete',
+ 'pool': pool['pool_name'],
+ 'pool2': pool['pool_name'],
+ 'sure': '--yes-i-really-really-mean-it'
+ }]], **kwargs)
+
+
+
+class Pool(RestController):
+ @expose(template='json')
+ @catch
+ @auth
+ def get(self, **kwargs):
+ """
+ Show the information for all the pools
+ """
+ pools = module.instance.get('osd_map')['pools']
+
+ # pgp_num is called pg_placement_num, deal with that
+ for pool in pools:
+ if 'pg_placement_num' in pool:
+ pool['pgp_num'] = pool.pop('pg_placement_num')
+
+ return pools
+
+
+ @expose(template='json')
+ @catch
+ @auth
+ def post(self, **kwargs):
+ """
+ Create a new pool
+ Requires name and pg_num dict arguments
+ """
+ args = request.json
+
+ # Check for the required arguments
+ pool_name = args.pop('name', None)
+ if pool_name is None:
+ response.status = 500
+ return {'message': 'You need to specify the pool "name" argument'}
+
+ pg_num = args.pop('pg_num', None)
+ if pg_num is None:
+ response.status = 500
+ return {'message': 'You need to specify the "pg_num" argument'}
+
+ # Run the pool create command first
+ create_command = {
+ 'prefix': 'osd pool create',
+ 'pool': pool_name,
+ 'pg_num': pg_num
+ }
+
+ # Check for invalid pool args
+ invalid = common.invalid_pool_args(args)
+ if invalid:
+ response.status = 500
+ return {'message': 'Invalid arguments found: "%s"' % str(invalid)}
+
+ # Schedule the creation and update requests
+ return module.instance.submit_request(
+ [[create_command]] +
+ common.pool_update_commands(pool_name, args),
+ **kwargs
+ )
+
+
+ @expose()
+ def _lookup(self, pool_id, *remainder):
+ return PoolId(int(pool_id)), remainder
--- /dev/null
+from pecan import expose, request, response
+from pecan.rest import RestController
+
+from restful import module
+from restful.decorators import auth, catch, lock
+
+
+class RequestId(RestController):
+ def __init__(self, request_id):
+ self.request_id = request_id
+
+
+ @expose(template='json')
+ @catch
+ @auth
+ def get(self, **kwargs):
+ """
+ Show the information for the request id
+ """
+ request = filter(
+ lambda x: x.id == self.request_id,
+ module.instance.requests
+ )
+
+ if len(request) != 1:
+ response.status = 500
+ return {'message': 'Unknown request id "%s"' % str(self.request_id)}
+
+ request = request[0]
+ return request
+
+
+ @expose(template='json')
+ @catch
+ @auth
+ @lock
+ def delete(self, **kwargs):
+ """
+ Remove the request id from the database
+ """
+ for index in range(len(module.instance.requests)):
+ if module.instance.requests[index].id == self.request_id:
+ return module.instance.requests.pop(index)
+
+ # Failed to find the job to cancel
+ response.status = 500
+ return {'message': 'No such request id'}
+
+
+
+class Request(RestController):
+ @expose(template='json')
+ @catch
+ @auth
+ def get(self, **kwargs):
+ """
+ List all the available requests and their state
+ """
+ states = {}
+ for _request in module.instance.requests:
+ states[_request.id] = _request.get_state()
+
+ return states
+
+
+ @expose(template='json')
+ @catch
+ @auth
+ @lock
+ def delete(self, **kwargs):
+ """
+ Remove all the finished requests
+ """
+ num_requests = len(module.instance.requests)
+
+ module.instance.requests = filter(
+ lambda x: not x.is_finished(),
+ module.instance.requests
+ )
+
+ # Return the job statistics
+ return {
+ 'cleaned': num_requests - len(module.instance.requests),
+ 'remaining': len(module.instance.requests),
+ }
+
+
+ @expose(template='json')
+ @catch
+ @auth
+ def post(self, **kwargs):
+ """
+ Pass through method to create any request
+ """
+ return module.instance.submit_request([[request.json]], **kwargs)
+
+
+ @expose()
+ def _lookup(self, request_id, *remainder):
+ return RequestId(request_id), remainder
--- /dev/null
+from pecan import expose
+from pecan.rest import RestController
+
+from restful import module
+from restful.decorators import auth, catch
+
+
+class ServerFqdn(RestController):
+ def __init__(self, fqdn):
+ self.fqdn = fqdn
+
+
+ @expose(template='json')
+ @catch
+ @auth
+ def get(self, **kwargs):
+ """
+ Show the information for the server fqdn
+ """
+ return module.instance.get_server(self.fqdn)
+
+
+
+class Server(RestController):
+ @expose(template='json')
+ @catch
+ @auth
+ def get(self, **kwargs):
+ """
+ Show the information for all the servers
+ """
+ return module.instance.list_servers()
+
+
+ @expose()
+ def _lookup(self, fqdn, *remainder):
+ return ServerFqdn(fqdn), remainder