def test_default_value(self): schema = Schema({ "key": str, Optional('op_key'): Default(IntVal(min=10), default=50) }) data = schema.validate({'key': 'abc'}) self.assertEqual({'key': 'abc', 'op_key': 50}, data) data = schema.validate({'key': 'abc', 'op_key': 20}) self.assertEqual({'key': 'abc', 'op_key': 20}, data) with self.assertRaises(SchemaError): schema.validate({'key': 'abc', 'op_key': 0})
def __init__(self): # need a mutex to protect create/delete bond interface self.lock = lock() self.support_fs_type = {} self.conf_file = os.path.join(STORLEVER_CONF_DIR, FS_CONF_FILE_NAME) self.fs_conf_schema = Schema({ "type": Use(str), # filesystem type "dev_file": Use(str), # dev file "dev_uuid": Use(str), # dev uuid "mount_point": Use(str), # mount point of this fs, "mount_option": Use(str), # mount option of this fs "check_onboot": BoolVal(), # fsck fs on boot Optional("comment"): Default(Use(str), default=""), # comment, AutoDel(str): object # for all other key we auto delete }) self.fs_dict_schema = Schema({ DoNotCare(str): self.fs_conf_schema }) # sync fs conf to fstab on boot self.sync_to_fstab()
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 Optional("passive_check_server_list"):
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 = {}
@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), # Specifies the stratum number assigned to the driver, an
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),
"rpms": [ "vsftpd" ], "comment": "Provides the management functions for FTP server" } FTP_CONF_FILE_NAME = "ftp_conf.yaml" VSFTPD_ETC_CONF_DIR = "/etc/vsftpd/" VSFTPD_ETC_CONF_FILE = "vsftpd.conf" VSFTPD_ETC_USER_LIST = "user_list" VSFTPD_ETC_CHROOT_LIST = "chroot_list" FTP_USER_CONF_SCHEMA = Schema({ "user_name": Use(str), # When enabled, the user can log in ftp Optional("login_enable"): Default(BoolVal(), default=True), # When enabled, the user will be placed into the chroot jail Optional("chroot_enable"): Default(BoolVal(), default=False), AutoDel(str): object # for all other key we auto delete }) FTP_CONF_SCHEMA = Schema({ Optional("listen"): Default(BoolVal(), default=False), # ftp service listen on ipv4 port Optional("listen6"): Default(BoolVal(), default=False), # ftp service listen on ipv6 port Optional("listen_port"): Default(IntVal(min=1, max=65535), default=21), # 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"): Default(Use(int), default=300),
MODULE_INFO = { "module_name": "mail", "rpms": ["mailx"], "comment": "Provides the support to send email by mailx utility" } MAIL_CONF_FILE_NAME = "mail_conf.yaml" MAIL_ETC_CONF_DIR = "/etc/" MAIL_ETC_CONF_FILE = "mail.rc" MAIL_CMD = "/bin/mail" MAIL_CONF_SCHEMA = Schema({ # the email address of user's account, it would also be place in the FROM header of the email Optional("email_addr"): Default(Use(str), default=""), # smtp server address to send the mail Optional("smtp_server"): Default(Use(str), default=""), # password for the account Optional("password"): Default(Use(str), default=""), AutoDel(str): object # for all other key we auto delete }) class MailManager(object): """contains all methods to manage NTP server in linux system"""
scsi_list_dict.append(scsi_dev) return scsi_list_dict # http://192.168.1.10:6543/storlever/api/v1/block/scsi/host_list @get_view(route_name='dev_host_list') def host_list_get(request): scsi_mgr = scsimgr.scsi_mgr() scsi_list = scsi_mgr.get_scsi_host_list() return scsi_list scan_bus_schema = Schema({ Optional("opt"): StrRe(r"^(re_scan)$"), Optional("host"): Default(ListVal(IntVal(0, 16)), default=[]), Optional("channels"): Default(ListVal(IntVal(0, 1)), default=[]), Optional("targets"): Default(ListVal(IntVal(0, 16)), default=[]), Optional("luns"): Default(ListVal(IntVal(0, 7)), default=[]), Optional("remove"): BoolVal(), Optional("force_rescan"): BoolVal(), Optional("force_remove"): BoolVal(), DoNotCare(Use(str)): object # for all those key we don't care }) # curl -v -X put -d opt=re_scan http://192.168.1.10:6543/storlever/api/v1/block/scsi/scan_bus @put_view(route_name='scan_bus') def scan_bus(request): scsi_mgr = scsimgr.scsi_mgr() params = get_params_from_request(request, scan_bus_schema) remove = params.get("remove", False), force_rescan = params.get("force_rescan", False),
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
cpus = sys_mgr.get_cpu_list() cpu_list_dict = [] for cpu in cpus: cpu_info = { 'processor': int(cpu["processor"]), 'model_name': cpu["model name"], 'cpu_MHz': float(cpu["cpu MHz"]), 'cache_size': cpu["cache size"] } cpu_list_dict.append(cpu_info) return cpu_list_dict cpu_persent_schema = Schema({ Optional("interval"): Default(Use(float), default=1), # name should be string DoNotCare(Use(str)): object # for all those key we don't care }) @get_view(route_name='cpu_percent') def system_cpu_percent_get(request): params = get_params_from_request(request, cpu_persent_schema) cpu_percent = psutil.cpu_percent(interval=params["interval"]) return cpu_percent @get_view(route_name='per_cpu_percent') def system_per_cpu_percent_get(request): params = get_params_from_request(request, cpu_persent_schema)
# 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=""), DoNotCare(Use(str)): object # for all other key we don't care }) nfs_export_schema = Schema({ # export point name "name": StrRe(r"^\w+$"), # absolute path Optional("path"): StrRe(r"^\S+$"), # client list for this export point Optional("clients"): [nfs_client_schema],
# # 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=""), # Run Self-Tests or Offline Immediate Tests, at scheduled times. A Self- or
'/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')
"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] })
'name': bond_object.name, 'mode': bond_object.mode, 'miimon': bond_object.miimon, 'slaves': bond_object.slaves } bond_info_dict.append(bond_info) return bond_info_dict bond_add_schema = Schema({ "mode": IntVal(0, 6), "miimon": IntVal(0, 65535), Optional("ifs"): Default(ListVal(Use(str)), default=[]), Optional("ip"): Default(StrRe(r"^(|\d+\.\d+\.\d+\.\d+)$"), default=""), # ip addr Optional("netmask"): Default(StrRe(r"^(|\d+\.\d+\.\d+\.\d+)$"), default=""), # netmask addr Optional("gateway"): Default(StrRe(r"^(|\d+\.\d+\.\d+\.\d+)$"), default=""), # gateway addr DoNotCare(Use(str)): object # for all those key we don't care }) #curl -v -X POST -d ifs=eth0,eth1 -d ip=192.168.1.123 -d netmask=255.255.255.0 -d mode=1 -d miimon=1000 -d gateway=192.168.1.1 http://192.168.1.123:6543/storlever/api/v1/network/bond/bond_list @post_view(route_name='bond_list') def add_bond_group(request): params = get_params_from_request(request, bond_add_schema)
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. Optional("create_mask"):
for vg in vgs: vg_info = { 'name': vgs[vg].name, 'uuid': vgs[vg].uuid, 'size': vgs[vg].size, 'free_size': vgs[vg].free_size, } vg_dict.append(vg_info) return vg_dict new_vg_schema = Schema({ "vgname": StrRe(r"^([a-zA-Z].+)$"), "dev": Default(ListVal(StrRe(r"^(/dev/sd[a-z]|/dev/md.+)$")), default=[]), DoNotCare(Use(str)): object # for all those key we don't care }) #curl -v -X POST -d vgname=vg1 -d dev=/dev/sdb,/dev/sdc http://192.168.1.123:6543/storlever/api/v1/block/lvm/vg_list #enable eth* or disable eth* @post_view(route_name='vg_list') def create_vg(request): lvm_mng = lvm.lvm_mgr() params = get_params_from_request(request, new_vg_schema) vg = lvm_mng.new_vg(params['vgname'], params['dev']) if vg is None: return Response(status=500)
"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), # enable write cache or not