'/fs/list/{fsname}/quota_user/{user_name}') #put dete config.add_route('share_list', '/fs/fs_list/{fs}/share_list') #http://192.168.1.2:6543/storlever/api/v1/fs/type_list @get_view(route_name='type_list') def get_fs_type_list(request): fs_mrg = fsmgr.fs_mgr() type_list = fs_mrg.fs_type_list() return type_list mk_fs_schema = Schema({ "type": StrRe(r"^([a-zA-Z].+)$"), "dev": StrRe(r"^(/dev/.+)$"), Optional("options"): Default(StrRe(), default=""), DoNotCare(Use(str)): object # for all those key we don't care }) #curl -v -X POST -d type=ext4 -d dev=/dev/mapper/vg1-lv http://192.168.1.2:6543/storlever/api/v1/fs/mkfs @post_view(route_name='mkfs') def mk_fs(request): fs_mrg = fsmgr.fs_mgr() params = get_params_from_request(request, mk_fs_schema) fs_mrg.mkfs_on_dev(params["type"], params["dev"], params["options"]) return Response(status=200) #http://192.168.1.2:6543/storlever/api/v1/fs_list @get_view(route_name='fs_list')
return Response(status=200) #curl -v -X delete http://192.168.1.123:6543/storlever/api/v1/block/md_list/name @delete_view(route_name='md') def delete_md_rest(request): md_mgr = md.md_mgr() mds = md_mgr.get_all_md() name = request.matchdict['md_name'] mds.delete(name) return Response(status=200) md_op_schema = Schema({ "opt": StrRe(r"^(refresh|remove|add|grow)$"), Optional("dev"): StrRe(r"^(/dev/sd[a-z]|/dev/vxd[a-z])$"), Optional("sum"): IntVal(), DoNotCare(Use(str)): object # for all those key we don't care }) #curl -v -X post -d opt=refresh http://192.168.1.123:6543/storlever/api/v1/block/md_list/name/opt @post_view(route_name='md_op') def post_md_op(request): params = get_params_from_request(request, md_op_schema) md_name = request.matchdict['md_name'] mds_mgr = md.md_mgr() mds = mds_mgr.get_all_md() md_mgr = mds.get_md(md_name) if (params['opt']) == 'refresh':
import re import tarfile import os from storlever.lib.exception import StorLeverCmdError, StorLeverError from storlever.lib.command import check_output from storlever.lib.schema import Schema, Use, Optional, \ Default, DoNotCare, BoolVal, IntVal, AutoDel MODULE_CONF_SCHEMA = Schema({ "module_name": Use(str), Optional("rpms"): Default([Use(str)], default=[]), Optional("extra_files"): Default([Use(str)], default=[]), Optional("comment"): Default(Use(str), default=""), AutoDel(str): object # for all other key we auto delete }) RPM_CMD = "/bin/rpm" class ModuleManager(object): """contains all methods to manage the storlever cfg""" def __init__(self): self.managed_modules = {}
from storlever.mngr.system.cfgmgr import STORLEVER_CONF_DIR, cfg_mgr from storlever.mngr.system.servicemgr import service_mgr from storlever.mngr.system.modulemgr import ModuleManager MODULE_INFO = { "module_name": "zabbix_agent", "rpms": ["zabbix-agent"], "comment": "Provides the support of zabbix agent config for storlever" } ZABBIX_AGENT_CONF_FILE_NAME = "zabbix_agentd_conf.yaml" ZABBIX_AGENT_ETC_CONF_DIR = "/etc/zabbix/" ZABBIX_AGENT_CONF_FILE = "zabbix_agentd.conf" ZABBIX_AGENT_CONF_SCHEMA = Schema({ Optional("hostname"): Default(Use(str), default=""), # How often list of active checks is refreshed, in seconds. # Note that after failing to refresh active checks the next refresh # will be attempted after 60 seconds. Optional("refresh_active_check"): Default(IntVal(min=60, max=3600), default=120), # the server ip:port list for active check.zabbix_agent would get the active check list # from each server at the refresh_active_check frequency. Entry string Format is IP:PORT Optional("active_check_server_list"): Default([Use(str)], default=[]), # the server ip list for passive check. each passive check's source ip must # exist in this list. Entry string Format is IP
} SMB_CONF_FILE_NAME = "smb_conf.yaml" SMB_ETC_CONF_DIR = "/etc/samba/" SMB_ETC_CONF_FILE = "smb.conf" SMBSTATUS_CMD = "/usr/bin/smbstatus" PDBEDIT_CMD = "/usr/bin/pdbedit" SHARE_CONF_SCHEMA = Schema({ # Name of this share "share_name": Use(str), # This parameter specifies a directory to which the user of the service is to # be given access.default is empty Optional("path"): Default(Use(str), default=""), # This is a text field that is seen next to a share when a client does a # queries the server, either via the network neighborhood or via net view to # list what shares are available. Default is empty Optional("comment"): Default(Use(str), default=""), # When a file is created, the necessary permissions are calculated according # to the mapping from DOS modes to UNIX permissions, and the resulting UNIX # mode is then bit-wise ?AND?ed with this parameter. This parameter may be # thought of as a bit-wise MASK for the UNIX modes of a file. Any bit not set # here will be removed from the modes set on a file when it is created. # Default is 0744, which means removes the group and other write and # execute bits from the UNIX modes.
'/utils/snmp_agent/trap_sink_list') @get_view(route_name='ntp_server_list') def get_ntp_server_list(request): ntp_mgr = ntpmgr.NtpManager return ntp_mgr.get_server_conf_list() ntp_server_list_schema = Schema([{ # it can be a ipv4 address, ipv6 address, or host dns name "server_addr": StrRe(r"^\S+$"), # if set to True, it would be forced to resolve the host name to # ipv6 address in DNS resolution Optional("ipv6"): Default(BoolVal(), default=False), # Marks the server as preferred. All other things being equal, # this host will be chosen for synchronization among set of correctly operating hosts Optional("prefer"): Default(BoolVal(), default=False), # Specifies a mode number which is interpreted in a device # specific fashion. For instance, it selects a dialing, # protocol in the ACTS driver and a device subtype in the # parse drivers. # Only valid for reference clock server, i.e. server_addr is 127.127.t.n Optional("mode"): Default(IntVal(min=0, max=65535), default=0),
block_info = block_mgr.get_block_dev_by_name(block_name) block = { 'name':block_info.name, 'major':block_info.major, 'minor':block_info.minor, 'size':block_info.size, 'type':block_info.type, 'readonly':block_info.readonly, 'fs_type':block_info.fs_type, 'mount_point':block_info.mount_point } return block block_clean_meta_schema = Schema({ Optional("opt"): StrRe(r"^(clean_meta|flush_buf)$"), DoNotCare(Use(str)): object # for all those key we don't care }) # curl -v -X put -d opt=clean_meta 'http://192.168.1.123:6543/storlever/api/v1/block/block_list/sdb' @put_view(route_name='block') def block_clean_meta(request): block_name = request.matchdict['block'] params = get_params_from_request(request, block_clean_meta_schema) if params['opt'] == "clean_meta": block_mgr = blockmgr.block_mgr() block_dev = block_mgr.get_block_dev_by_name(block_name) block_dev.clean_meta() elif params['opt'] == "flush_buf": block_mgr = blockmgr.block_mgr() block_dev = block_mgr.get_block_dev_by_name(block_name)
from storlever.mngr.system.cfgmgr import STORLEVER_CONF_DIR, cfg_mgr from storlever.mngr.system.servicemgr import service_mgr SNMP_CONF_FILE_NAME = "snmp_conf.yaml" SNMP_ETC_CONF_DIR = "/etc/snmp/" SNMP_ETC_CONF_FILE = "snmpd.conf" SNMP_MONITOR_CONF_SCHEMA = Schema({ # monitor name "monitor_name": Use(str), # options to control the monitor's behavior, # see monitor options section of man snmpd.conf for more detail Optional("option"): Default(Use(str), default=""), # expression to check of this monitor, # see monitor expression of man snmpd.conf for more detail "expression": Use(str), AutoDel(str): object # for all other key we auto delete }) SNMP_SINK_CONF_SCHEMA = Schema({ # address of the host to which send the trap "host": Use(str),
'system': sys_uname[0], 'release': sys_uname[2], 'version': sys_uname[3], 'machine': sys_uname[4], 'processor': sys_uname[5], 'dist_name': dist_name, 'dist_version': dist_version, 'dist_id': dist_id, "uptime": str(uptime).split('.')[0], "loadavg": [av1, av2, av3] } return info local_host_schema = Schema({ Optional("hostname"): Use(str), # name should be string DoNotCare(Use(str)): object # for all those key we don't care }) @put_view(route_name='system_localhost') def put_system_localhost(request): sys_mgr = sysinfo.sys_mgr() # get sys manager params = get_params_from_request(request, local_host_schema) if "hostname" in params: sys_mgr.set_hostname(params["hostname"], user=request.client_addr) return Response(status=200) @get_view(route_name='cpu_list') def system_cpu_list_get(request):
NTP_CONF_FILE_NAME = "ntp_conf.yaml" NTP_ETC_CONF_DIR = "/etc/" NTP_ETC_CONF_FILE = "ntp.conf" NTP_ETC_STORLEVER_CONF_DIR = "/etc/ntp/" NTP_ETC_STORLEVER_CONF_FILE = "ntp.storlever.conf" NTPQ_CMD = "/usr/sbin/ntpq" NTP_SERVER_CONF_SCHEMA = Schema({ # it can be a ipv4 address, ipv6 address, or host dns name "server_addr": Use(str), # if set to True, it would be forced to resolve the host name to # ipv6 address in DNS resolution Optional("ipv6"): Default(BoolVal(), default=False), # Marks the server as preferred. All other things being equal, # this host will be chosen for synchronization among set of correctly operating hosts Optional("prefer"): Default(BoolVal(), default=False), # Specifies a mode number which is interpreted in a device # specific fashion. For instance, it selects a dialing, # protocol in the ACTS driver and a device subtype in the # parse drivers. # Only valid for reference clock server, i.e. server_addr is 127.127.t.n Optional("mode"): Default(IntVal(min=0, max=65535), default=0), # Specifies the stratum number assigned to the driver, an # integer between 0 and 15. This number overrides the
config.add_route('smb_share_list', '/nas/smb/share_list') config.add_route('smb_share_conf', '/nas/smb/share_list/{share_name}') config.add_route('smb_connection_list', '/nas/smb/connection_list') config.add_route('smb_account_list', '/nas/smb/account_list') config.add_route('smb_account_conf', '/nas/smb/account_list/{account_name}') @get_view(route_name='ftp_conf') def get_ftp_conf(request): ftp_mgr = ftpmgr.FtpManager return ftp_mgr.get_ftp_conf() ftp_conf_schema = Schema({ Optional("listen"): BoolVal(), # ftp service listen on ipv4 port Optional("listen6"): BoolVal(), # ftp service listen on ipv6 port Optional("listen_port"): IntVal(min=1, max=65535), # ftp port number # The maximum amount of time between commands from a remote client. # Once triggered, the connection to the remote client is closed Optional("idle_session_timeout"): Use(int), # the maximum data transfer rate for anonymous users in bytes per second. # The default value is 0, which does not limit the transfer rate. Optional("anon_max_rate"): Use(int),
# # IP networks # You can also export directories to all hosts on an IP (sub-) network # simultaneously. This is done by specifying an IP address and netmask # pair as address/netmask where the netmask can be specified in dotted- # decimal format, or as a contiguous mask length. For example, either # 255.255.252.0 or 22 appended to the network base IPv4 address # results in identical subnetworks with 10 bits of host. IPv6 addresses # must use a contiguous mask length and must not be inside square brackets # to avoid confusion with character-class wildcards. Wildcard characters # generally do not work on IP addresses, though they may work by accident # when reverse DNS lookups fail. "host": StrRe("^(\S)*$"), # The options to be used for host Optional("options"): Default(StrRe("^(\S)*$"), default=""), AutoDel(str): object # for all other key we auto delete }) EXPORT_POINT_CONF_SCHEMA = Schema({ # export point name "name": Use(str), # absolute path "path": Use(str), # client list for this export point Optional("clients"): Default([EXPORT_CLIENT_CONF_SCHEMA],default=[]),
} SMARTD_CONF_FILE_NAME = "smartd_conf.yaml" SMARTD_ETC_CONF_DIR = "/etc/" SMARTD_CONF_FILE = "smartd.conf" MONITOR_CONF_SCHEMA = Schema({ # the dev's file to monitor "dev": Use(str), # the (e)mail address to which smartd would send when a error is detected. # To send email to more than one user, please use the following "comma separated" # form for the address: user1@add1,user2@add2,...,userN@addN (with no spaces). Optional("mail_to"): Default(Use(str), default=""), # test the mail. if true, send a single test email immediately upon smartd startup. # This allows one to verify that email is delivered correctly Optional("mail_test"): Default(BoolVal(), default=False), # run the executable PATH instead of the default mail command. # if this list is empty, smartd would run the default "/bin/mail" utility # to send warning email to user in "mail_to" option. Otherwise, smartd would run # the scripts in this option. See man smartd.conf # for more detail Optional("mail_exec"): Default(Use(str), default=""),
"like date, time, log, shutdown, reboot, and etc" } LOG_DIR = "/var/log" LOG_FILE_PATH_PREFIX = "/tmp/syslog" SELINUX_CONF_DIR = "/etc/selinux/" SELINUX_CONF_FILE = "config" ETC_HOSTS_FILE = "/etc/hosts" ETC_NETWORK_FILE = "/etc/sysconfig/network" HOST_LIST_SCHEMA = Schema([{ "addr": Use(str), "hostname": Use(str), Optional("alias"): Default(Use(str), default=""), AutoDel(str): object # for all other key we auto delete }]) class SysManager(object): """contains all methods to manage the system""" def __init__(self): self.dist_name = None self.dist_version = None self.dist_id = None def system_restore_cb(self): self.set_hostname("localhost", "System Restore") def get_hostname(self):
def test_dict(self): schema = Schema({ "key1": str, # key1 should be string "key2": Use(int), # key3 should be in or int in string "key3": [IntVal(min=10, max=20)], # key4 is optional, Optional("key4"): str, Optional('key5'): Default(IntVal(min=100, max=200), default=100), DoNotCare(str): object # for all those key we don't care }) data = schema.validate({ "key1": "abc", "key2": '123', "key3": [10, 15, 20], "key5": 199, }) self.assertEqual(data, { "key1": "abc", "key2": 123, "key3": [10, 15, 20], "key5": 199 }) data = schema.validate({ "key1": "abc", "key2": '123', "key3": [10, 15, 20], }) self.assertEqual(data, { "key1": "abc", "key2": 123, "key3": [10, 15, 20], "key5": 100 }) data = schema.validate({ "key1": "abc", "key2": '123', "key3": [10, 15, 20], "key4": 'abc' }) self.assertEqual( data, { "key1": "abc", "key2": 123, "key3": [10, 15, 20], "key4": 'abc', "key5": 100 }) data = schema.validate({ "key1": "abc", "key2": '123', "key3": [10, 15, 20], "key4": 'abc', "key100": 'bbc', 'key200': [123, 23, 334] }) self.assertEqual( data, { "key1": "abc", "key2": 123, "key3": [10, 15, 20], "key4": 'abc', "key5": 100, "key100": 'bbc', 'key200': [123, 23, 334] }) with self.assertRaises(SchemaError): schema.validate({ 'key1': 123, "key2": '123', "key3": [10, 15, 20], "key4": 223, }) with self.assertRaises(SchemaError): schema.validate({ 'key1': 123, "key2": '123', "key3": [10, 15, 20], "key4": 'abc', "key100": 'bbc', 'key200': [123, 23, 334] }) with self.assertRaises(SchemaError): schema.validate({ 'key1': 'abc', "key2": '123', "key3": [10, 15, 20], "key4": 'abc', 'key5': 0, "key100": 'bbc', 'key200': [123, 23, 334] })
config.add_route( 'tgt_target_lun_info', '/san/tgt/target_list/{target_iqn}/lun_list/{lun_number}') @get_view(route_name='tgt_conf') def get_tgt_conf(request): tgt_mgr = tgtmgr.TgtManager return tgt_mgr.get_tgt_conf() tgt_conf_schema = Schema({ # Define iscsi incoming discovery authentication setting. If it is # empty, no authentication is performed. The format is username:passwd Optional("incomingdiscoveryuser"): StrRe(r"^(|\w+:\w+)$"), # Define iscsi outgoing discovery authentication setting. If it is # empty, no authentication is performe The format is username:passwd Optional("outgoingdiscoveryuser"): StrRe(r"^(|\w+:\w+)$"), DoNotCare(Use(str)): object # for all other key we don't care }) @put_view(route_name='tgt_conf') def put_tgt_conf(request): tgt_mgr = tgtmgr.TgtManager tgt_conf = get_params_from_request(request, tgt_conf_schema)
# lun number "lun": IntVal(1, 255), # path to a regular file, or block device, or a sg char device "path": Use(str), # the type of device . Possible device-types are: # disk : emulate a disk device # tape : emulate a tape reader # ssc : same as tape # cd : emulate a DVD drive # changer : emulate a media changer device # pt : passthrough type to export a /dev/sg device Optional("device_type"): Default(Use(str), default="disk"), # the type of backend storage. Possible backend types are: # rdwr : Use normal file I/O. This is the default for disk devices # aio : Use Asynchronous I/O # sg : Special backend type for passthrough devices # ssc : Special backend type for tape emulation Optional("bs_type"): Default(Use(str), default="rdwr"), # if true, a direct mapped logical unit (LUN) with the same properties as the # physical device (such as VENDOR_ID, SERIAL_NUM, etc.) Optional("direct_map"): Default(BoolVal(), default=False),