def main(): client = Client() sssd_conf = None if client.call('notifier.common', 'system', 'ldap_enabled') and client.call( 'notifier.common', 'system', 'ldap_anonymous_bind'): sys.exit(1) sssd_setup() if os.path.exists(SSSD_CONFIGFILE): sssd_conf = SSSD_CONFIGFILE cookie = get_directoryservice_cookie(client) if not cookie: sys.exit(1) def nullfunc(): pass sc = SSSDConf(client=client, path=sssd_conf, parse=nullfunc, cookie=cookie) sc.add_sssd_section() sc.add_nss_section() sc.add_pam_section() if client.call('notifier.common', 'system', 'activedirectory_enabled' ) and activedirectory_has_unix_extensions(client): add_activedirectory_section(client, sc) if client.call('notifier.common', 'system', 'ldap_enabled'): add_ldap_section(client, sc) sc.save(SSSD_CONFIGFILE)
def main(): client = Client() cifs_config = Struct( client.call('datastore.query', 'services.cifs', None, {'get': True})) krb_config = Struct( client.call('datastore.query', 'services.cifs', None, {'get': True})) if not validate_hosts(cifs_config): print("restarting ix-hostname service") service_launcher("ix-hostname", "quietstart") # validate_klist("krb_config.krb_realm") service_launcher("ix-kerberos", "quietstart") service_launcher("ix-nsswitch", "quietstart") if not service_launcher("ix-kinit", "status"): if not service_launcher("ix-kinit", "quietstart"): print("ix-kinit failed") service_launcher("ix-pre-samba", "quietstart") service_launcher("ix-activedirectory", "quietstart") service_launcher("samba_server", "restart") service_launcher("ix-pam", "quietstart") service_launcher("ix-cache", "quietstart")
def make_it_so(args): parent_dir = None args.pathName if not os.path.exists(args.pathName): """ This is experimental and doesn't get called yet. Samba bails out early if the path doesn't exist. I can probably modify samba to allow this in this case. """ parent_dir = os.path.dirname(args.pathName) bn = os.path.basename(args.pathName) if not os.path.exists(parent_dir): return 1 pds = Client().call('pool.dataset.query', [('mountpoint', '=', parent_dir)])['id'] Client.call('pool.dataset.create', { 'name': f'{pds}/{bn}', 'share_type': 'SMB', 'atime': 'OFF', }) Client().call('sharing.smb.create', { 'path': args.pathName, 'name': args.shareName, 'comment': args.comment, }) return 0
def main(): client = Client() sssd_conf = None if client.call('notifier.common', 'system', 'ldap_enabled') and client.call('notifier.common', 'system', 'ldap_anonymous_bind'): sys.exit(1) sssd_setup() if os.path.exists(SSSD_CONFIGFILE): sssd_conf = SSSD_CONFIGFILE cookie = get_directoryservice_cookie(client) if not cookie: sys.exit(1) def nullfunc(): pass sc = SSSDConf(client=client, path=sssd_conf, parse=nullfunc, cookie=cookie) sc.add_sssd_section() sc.add_nss_section() sc.add_pam_section() if client.call('notifier.common', 'system', 'activedirectory_enabled') and activedirectory_has_unix_extensions(client): add_activedirectory_section(client, sc) if client.call('notifier.common', 'system', 'ldap_enabled'): add_ldap_section(client, sc) sc.save(SSSD_CONFIGFILE)
def main(): client = Client() ldap_conf = "/usr/local/etc/openldap/ldap.conf" if client.call('notifier.common', 'system', 'ldap_enabled'): ldap_conf_ldap(client, ldap_conf) elif client.call('notifier.common', 'system', 'activedirectory_enabled'): ldap_conf_activedirectory(client, ldap_conf)
def main(): client = Client() ldap_conf = "/usr/local/etc/openldap/ldap.conf" if client.call('notifier.common', 'system', 'ldap_enabled'): ldap_conf_ldap(client, ldap_conf) elif client.call('notifier.common', 'system', 'activedirectory_enabled'): ldap_conf_activedirectory(client, ldap_conf)
def main(): client = Client() certs = client.call('certificate.query') write_certificates(certs) certs = client.call('certificateauthority.query') write_certificates(certs)
def main(): client = Client() certs = client.call('certificate.query') write_certificates(certs) certs = client.call('certificateauthority.query') write_certificates(certs)
def get_client(self): try: c = Client(self.websocket) except (FileNotFoundError, ConnectionRefusedError): exit('middlewared is not running.') if self.user and self.password: c.call('auth.login', self.user, self.password) return c
def main(): client = Client() smb_conf_path = "/usr/local/etc/smb4.conf" smb4_tdb = [] smb4_conf = [] smb4_shares = [] backup_secrets_database() smb4_setup(client) old_samba4_datasets = get_old_samba4_datasets(client) if migration_available(old_samba4_datasets): do_migration(client, old_samba4_datasets) role = get_server_role(client) generate_smbusers(client) generate_smb4_tdb(client, smb4_tdb) generate_smb4_conf(client, smb4_conf, role) generate_smb4_system_shares(client, smb4_shares) generate_smb4_shares(client, smb4_shares) if role == 'dc' and not client.call('notifier.samba4', 'domain_provisioned'): provision_smb4(client) with open(smb_conf_path, "w") as f: for line in smb4_conf: f.write(line + '\n') for line in smb4_shares: f.write(line + '\n') smb4_set_SID(client) if role == 'member' and smb4_ldap_enabled(client): set_ldap_password(client) backup_secrets_database() if role != 'dc': if not client.call('notifier.samba4', 'users_imported'): smb4_import_users( client, smb_conf_path, smb4_tdb, "/var/db/samba4/private/passdb.tdb" ) smb4_grant_rights() client.call('notifier.samba4', 'user_import_sentinel_file_create') smb4_map_groups(client) if role == 'member' and client.call('notifier.common', 'system', 'activedirectory_enabled') and idmap_backend_rfc2307(client): set_idmap_rfc2307_secret(client) restore_secrets_database()
def main(): client = Client() smb_conf_path = "/usr/local/etc/smb4.conf" smb4_tdb = [] smb4_conf = [] smb4_shares = [] backup_secrets_database() smb4_setup(client) old_samba4_datasets = get_old_samba4_datasets(client) if migration_available(old_samba4_datasets): do_migration(client, old_samba4_datasets) role = get_server_role(client) generate_smbusers(client) generate_smb4_tdb(client, smb4_tdb) generate_smb4_conf(client, smb4_conf, role) generate_smb4_system_shares(client, smb4_shares) generate_smb4_shares(client, smb4_shares) if role == 'dc' and not client.call('notifier.samba4', 'domain_provisioned'): provision_smb4(client) with open(smb_conf_path, "w") as f: for line in smb4_conf: f.write(line + '\n') for line in smb4_shares: f.write(line + '\n') smb4_set_SID(client, role) if role == 'member' and smb4_ldap_enabled(client): set_ldap_password(client) backup_secrets_database() if role != 'dc': if not client.call('notifier.samba4', 'users_imported'): smb4_import_users( client, smb_conf_path, smb4_tdb, "/var/db/samba4/private/passdb.tdb" ) smb4_grant_rights() client.call('notifier.samba4', 'user_import_sentinel_file_create') smb4_map_groups(client) if role == 'member' and client.call('notifier.common', 'system', 'activedirectory_enabled') and idmap_backend_rfc2307(client): set_idmap_rfc2307_secret(client) restore_secrets_database()
class Connection(object): def __init__(self): self.conf = ConfigTarget() self.rest = Client( f'http://{self.conf.target_hostname()}', self.conf.target_api(), self.conf.target_username(), self.conf.target_password(), ) self.ws = WSClient(f'ws://{self.conf.target_hostname()}/websocket') self.ws.call('auth.login', self.conf.target_username(), self.conf.target_password())
class Connection(object): def __init__(self): self.conf = ConfigTarget() self.rest = Client( f'http://{self.conf.target_hostname()}', self.conf.target_api(), self.conf.target_username(), self.conf.target_password(), ) self.ws = WSClient(f'ws://{self.conf.target_hostname()}/websocket') self.ws.call('auth.login', self.conf.target_username(), self.conf.target_password())
def receive_events(): c = Client('ws+unix:///var/run/middlewared-internal.sock', py_exceptions=True) c.subscribe('core.environ', lambda *args, **kwargs: environ_update(kwargs['fields'])) c.subscribe('core.reconfigure_logging', reconfigure_logging) environ_update(c.call('core.environ'))
def main(): client = Client() try: hostname = socket.gethostname().split(".")[0] except IndexError: hostname = socket.gethostname() ssh_service = client.call('datastore.query', 'services.services', [('srv_service', '=', 'ssh'), ('srv_enable', '=', True)]) if ssh_service: sshport = client.call('datastore.query', 'services.ssh', None, {'get': True})['ssh_tcpport'] t = threading.Thread(target=register, args=(hostname, '_ssh._tcp.', sshport)) t.daemon = False t.start() t = threading.Thread(target=register, args=(hostname, '_sftp-ssh._tcp.', sshport)) t.daemon = False t.start() webui = client.call('datastore.query', 'system.settings') if (webui[0]['stg_guiprotocol'] == 'http' or webui[0]['stg_guiprotocol'] == 'httphttps'): http_port = int(webui[0]['stg_guiport'] or 80) t = threading.Thread(target=register, args=(hostname, '_http._tcp.', http_port)) t.daemon = False t.start() t = threading.Thread(target=register, args=(hostname, '_middlwre-http._tcp.', http_port)) t.daemon = False t.start() if (webui[0]['stg_guiprotocol'] == 'https' or webui[0]['stg_guiprotocol'] == 'httphttps'): https_port = int(webui[0]['stg_guihttpsport'] or 443) t = threading.Thread(target=register, args=(hostname, '_https._tcp.', https_port)) t.daemon = False t.start() t = threading.Thread(target=register, args=(hostname, '_middlwre-https._tcp.', https_port)) t.daemon = False t.start()
def main(): client = Client() try: hostname = socket.gethostname().split(".")[0] except IndexError: hostname = socket.gethostname() ssh_service = client.call('datastore.query', 'services.services', [('srv_service', '=', 'ssh'), ('srv_enable', '=', True)]) if ssh_service: sshport = client.call('datastore.query', 'services.ssh', None, {'get': True})['ssh_tcpport'] t = threading.Thread(target=register, args=(hostname, '_ssh._tcp.', sshport)) t.daemon = False t.start() t = threading.Thread(target=register, args=(hostname, '_sftp-ssh._tcp.', sshport)) t.daemon = False t.start() webui = client.call('datastore.query', 'system.settings') if (webui[0]['stg_guiprotocol'] == 'http' or webui[0]['stg_guiprotocol'] == 'httphttps'): http_port = int(webui[0]['stg_guiport'] or 80) t = threading.Thread(target=register, args=(hostname, '_http._tcp.', http_port)) t.daemon = False t.start() t = threading.Thread(target=register, args=(hostname, '_middlwre-http._tcp.', http_port)) t.daemon = False t.start() if (webui[0]['stg_guiprotocol'] == 'https' or webui[0]['stg_guiprotocol'] == 'httphttps'): https_port = int(webui[0]['stg_guihttpsport'] or 443) t = threading.Thread(target=register, args=(hostname, '_https._tcp.', https_port)) t.daemon = False t.start() t = threading.Thread(target=register, args=(hostname, '_middlwre-https._tcp.', https_port)) t.daemon = False t.start()
def receive_environ(): def callback(*args, **kwargs): environ_update(kwargs['fields']) c = Client('ws+unix:///var/run/middlewared-internal.sock', py_exceptions=True) c.subscribe('core.environ', callback) environ_update(c.call('core.environ'))
def get_client(self): while True: try: c = Client(self.websocket) break except Exception as e: if isinstance(e, (FileNotFoundError, ConnectionRefusedError)): error = 'middleware is not running' elif isinstance(e, socket.timeout): error = 'middleware is not responding' else: error = f'Unknown middleware error: {e!r}' if is_main_cli(): print(f'{error}. Press Enter to open root shell.') input() spawn_shell() else: exit(f'{error}.') if self.user and self.password: c.call('auth.login', self.user, self.password) return c
def main(): """Use the middleware client to generate a config file. We'll build the config file as a series of lines, and once that is done write it out in one go""" client = Client() gconf = Struct(client.call('datastore.query', 'services.iSCSITargetGlobalConfiguration', None, {'get': True})) if gconf.iscsi_isns_servers: for server in gconf.iscsi_isns_servers.split(' '): addline('isns-server %s\n\n' % server) # Generate the portal-group section addline('portal-group default {\n}\n\n') for portal in client.call('datastore.query', 'services.iSCSITargetPortal'): portal = Struct(portal) # Prepare auth group for the portal group if portal.iscsi_target_portal_discoveryauthgroup: auth_list = [ Struct(i) for i in client.call('datastore.query', 'services.iSCSITargetAuthCredential', [('iscsi_target_auth_tag', '=', portal.iscsi_target_portal_discoveryauthgroup)]) ] else: auth_list = [] agname = '4pg%d' % portal.iscsi_target_portal_tag auth = auth_group_config(auth_tag=agname, auth_list=auth_list, auth_type=portal.iscsi_target_portal_discoveryauthmethod) addline("portal-group pg%s {\n" % portal.iscsi_target_portal_tag) addline("\tdiscovery-filter portal-name\n") if auth: addline("\tdiscovery-auth-group ag%s\n" % agname) else: addline("\tdiscovery-auth-group no-authentication\n") listen = [ Struct(i) for i in client.call('datastore.query', 'services.iSCSITargetPortalIP', [('iscsi_target_portalip_portal', '=', portal.id)]) ] for obj in listen: if ':' in obj.iscsi_target_portalip_ip: address = '[%s]' % obj.iscsi_target_portalip_ip else: address = obj.iscsi_target_portalip_ip addline("\tlisten %s:%s\n" % (address, obj.iscsi_target_portalip_port)) addline("\toption ha_shared on\n") addline("}\n\n") # Cache zpool threshold poolthreshold = {} zpoollist = client.call('notifier.zpool_list') # Generate the LUN section for extent in client.call('datastore.query', 'services.iSCSITargetExtent'): extent = Struct(extent) path = extent.iscsi_target_extent_path poolname = None lunthreshold = None if extent.iscsi_target_extent_type == 'Disk': disk = client.call('datastore.query', 'storage.Disk', [('disk_identifier', '=', path)], {'order_by': ['disk_enabled']}) if not disk: continue disk = Struct(disk[0]) if disk.disk_multipath_name: path = "/dev/multipath/%s" % disk.disk_multipath_name else: path = "/dev/%s" % client.call('notifier.identifier_to_device', disk.disk_identifier) else: if not path.startswith("/mnt"): poolname = path.split('/', 2)[1] if gconf.iscsi_pool_avail_threshold: if poolname in zpoollist: poolthreshold[poolname] = int( zpoollist.get(poolname).get('size') * ( gconf.iscsi_pool_avail_threshold / 100.0 ) ) if extent.iscsi_target_extent_avail_threshold: zvolname = path.split('/', 1)[1] zfslist = client.call('notifier.zfs_list', zvolname, False, False, False, ['volume']) if zfslist: lunthreshold = int(zfslist[zvolname]['volsize'] * (extent.iscsi_target_extent_avail_threshold / 100.0)) path = "/dev/" + path else: if extent.iscsi_target_extent_avail_threshold and os.path.exists(path): try: stat = os.stat(path) lunthreshold = int(stat.st_size * (extent.iscsi_target_extent_avail_threshold / 100.0)) except OSError: pass addline("lun \"%s\" {\n" % extent.iscsi_target_extent_name) size = extent.iscsi_target_extent_filesize addline("\tpath \"%s\"\n" % path) addline("\tblocksize %s\n" % extent.iscsi_target_extent_blocksize) if extent.iscsi_target_extent_pblocksize: addline("\toption pblocksize 0\n") addline("\tserial \"%s\"\n" % (extent.iscsi_target_extent_serial, )) padded_serial = extent.iscsi_target_extent_serial if not extent.iscsi_target_extent_xen: for i in xrange(31 - len(extent.iscsi_target_extent_serial)): padded_serial += " " addline('\tdevice-id "iSCSI Disk %s"\n' % padded_serial) if size != "0": if size.endswith('B'): size = size.strip('B') addline("\t\tsize %s\n" % size) # We can't change the vendor name of existing # LUNs without angering VMWare, but we can # use the right names going forward. if extent.iscsi_target_extent_legacy is True: addline('\toption vendor "FreeBSD"\n') else: if client.call('notifier.is_freenas'): addline('\toption vendor "FreeNAS"\n') else: addline('\toption vendor "TrueNAS"\n') addline('\toption product "iSCSI Disk"\n') addline('\toption revision "0123"\n') addline('\toption naa %s\n' % extent.iscsi_target_extent_naa) if extent.iscsi_target_extent_insecure_tpc: addline('\toption insecure_tpc on\n') if lunthreshold: addline('\toption avail-threshold %s\n' % lunthreshold) if poolname is not None and poolname in poolthreshold: addline('\toption pool-avail-threshold %s\n' % poolthreshold[poolname]) if extent.iscsi_target_extent_rpm == "Unknown": addline('\toption rpm 0\n') elif extent.iscsi_target_extent_rpm == "SSD": addline('\toption rpm 1\n') else: addline('\toption rpm %s\n' % extent.iscsi_target_extent_rpm) if extent.iscsi_target_extent_ro: addline('\toption readonly on\n') addline("}\n") addline("\n") # Generate the target section target_basename = gconf.iscsi_basename for target in client.call('datastore.query', 'services.iSCSITarget'): target = Struct(target) authgroups = {} for grp in client.call('datastore.query', 'services.iscsitargetgroups', [('iscsi_target', '=', target.id)]): grp = Struct(grp) if grp.iscsi_target_authgroup: auth_list = [ Struct(i) for i in client.call('datastore.query', 'services.iSCSITargetAuthCredential', [('iscsi_target_auth_tag', '=', grp.iscsi_target_authgroup)]) ] else: auth_list = [] agname = '4tg%d_%d' % (target.id, grp.id) if auth_group_config(auth_tag=agname, auth_list=auth_list, auth_type=grp.iscsi_target_authtype, initiator=grp.iscsi_target_initiatorgroup): authgroups[grp.id] = agname if (target.iscsi_target_name.startswith("iqn.") or target.iscsi_target_name.startswith("eui.") or target.iscsi_target_name.startswith("naa.")): addline("target %s {\n" % target.iscsi_target_name) else: addline("target %s:%s {\n" % (target_basename, target.iscsi_target_name)) if target.iscsi_target_alias: addline("\talias \"%s\"\n" % target.iscsi_target_alias) elif target.iscsi_target_name: addline("\talias \"%s\"\n" % target.iscsi_target_name) for fctt in client.call('datastore.query', 'services.fibrechanneltotarget', [('fc_target', '=', target.id)]): fctt = Struct(fctt) addline("\tport %s\n" % fctt.fc_port) for grp in client.call('datastore.query', 'services.iscsitargetgroups', [('iscsi_target', '=', target.id)]): grp = Struct(grp) agname = authgroups.get(grp.id) or None addline("\tportal-group pg%d %s\n" % ( grp.iscsi_target_portalgroup.iscsi_target_portal_tag, 'ag' + agname if agname else 'no-authentication', )) addline("\n") used_lunids = [ o['iscsi_lunid'] for o in client.call('datastore.query', 'services.iscsitargettoextent', [('iscsi_target', '=', target.id), ('iscsi_lunid', '!=', None)]) ] cur_lunid = 0 for t2e in client.call('datastore.query', 'services.iscsitargettoextent', [('iscsi_target', '=', target.id)], {'extra': {'select': {'null_first': 'iscsi_lunid IS NULL'}}, 'order_by': ['null_first', 'iscsi_lunid']}): t2e = Struct(t2e) if t2e.iscsi_lunid is None: while cur_lunid in used_lunids: cur_lunid += 1 addline("\tlun %s \"%s\"\n" % (cur_lunid, t2e.iscsi_extent.iscsi_target_extent_name)) cur_lunid += 1 else: addline("\tlun %s \"%s\"\n" % (t2e.iscsi_lunid, t2e.iscsi_extent.iscsi_target_extent_name)) addline("}\n\n") os.umask(077) # Write out the CTL config file fh = open(ctl_config, "w") for line in cf_contents: fh.write(line) fh.close() # Write out the CTL config file with redacted CHAP passwords fh = open(ctl_config_shadow, "w") for line in cf_contents_shadow: fh.write(line) fh.close()
--kernel-reserved=2147483648 \ --userland-reserved=4294967296 """ import argparse import atexit import os import shlex import subprocess import sys from middlewared.client import Client c = Client() if c.call('system.is_freenas'): TRUENAS = False else: TRUENAS = True hardware = c.call('truenas.get_chassis_hardware') hardware = hardware.replace('TRUENAS-', '') hardware = hardware.split('-') KiB = 1024 ** 1 MiB = 1024 ** 2 GiB = 1024 ** 3 NO_HASYNC = "/tmp/.sqlite3_ha_skip"
def main(): """Use the django ORM to generate a config file. We'll build the config file as a series of lines, and once that is done write it out in one go""" map_acls_mode = False afp_config = "/usr/local/etc/afp.conf" cf_contents = [] client = Client() afp = Struct( client.call('datastore.query', 'services.afp', None, {'get': True})) cf_contents.append("[Global]\n") uam_list = ['uams_dhx.so', 'uams_dhx2.so'] if afp.afp_srv_guest: uam_list.append('uams_guest.so') cf_contents.append('\tguest account = %s\n' % afp.afp_srv_guest_user) # uams_gss.so bails out with an error if kerberos isn't configured if client.call('datastore.query', 'directoryservice.kerberoskeytab', None, {'count': True}) > 0: uam_list.append('uams_gss.so') cf_contents.append('\tuam list = %s\n' % (" ").join(uam_list)) if afp.afp_srv_bindip: cf_contents.append("\tafp listen = %s\n" % ' '.join(afp.afp_srv_bindip)) ifaces = get_interface(afp.afp_srv_bindip) cf_contents.append("\tafp interfaces = %s\n" % ' '.join(ifaces)) cf_contents.append("\tmax connections = %s\n" % afp.afp_srv_connections_limit) cf_contents.append("\tmimic model = RackMac\n") if afp.afp_srv_dbpath: cf_contents.append("\tvol dbnest = no\n") cf_contents.append("\tvol dbpath = %s\n" % afp.afp_srv_dbpath) else: cf_contents.append("\tvol dbnest = yes\n") if afp.afp_srv_global_aux: cf_contents.append("\t%s\n" % afp.afp_srv_global_aux) if afp.afp_srv_map_acls: cf_contents.append("\tmap acls = %s\n" % afp.afp_srv_map_acls) if afp.afp_srv_chmod_request: cf_contents.append("\tchmod request = %s\n" % afp.afp_srv_chmod_request) if afp.afp_srv_map_acls == 'mode' and client.call( 'notifier.common', 'system', 'activedirectory_enabled'): map_acls_mode = True if map_acls_mode: ad = Struct(client.call('notifier.directoryservice', 'AD')) cf_contents.append("\tldap auth method = %s\n" % "simple") cf_contents.append("\tldap auth dn = %s\n" % ad.binddn) cf_contents.append("\tldap auth pw = %s\n" % ad.bindpw) cf_contents.append("\tldap server = %s\n" % ad.domainname) # This should be configured when using this option if ad.userdn: cf_contents.append("\tldap userbase = %s\n" % ad.userdn) cf_contents.append("\tldap userscope = %s\n" % "sub") # This should be configured when using this option if ad.groupdn: cf_contents.append("\tldap groupbase = %s\n" % ad.groupdn) cf_contents.append("\tldap groupscope = %s\n" % "sub") cf_contents.append("\tldap user filter = %s\n" % "objectclass=user") cf_contents.append("\tldap group filter = %s\n" % "objectclass=group") cf_contents.append("\tldap uuid attr = %s\n" % "objectGUID") cf_contents.append("\tldap uuid encoding = %s\n" % "ms-guid") cf_contents.append("\tldap name attr = %s\n" % "sAMAccountName") cf_contents.append("\tldap group attr = %s\n" % "sAMAccountName") cf_contents.append("\n") for share in client.call('datastore.query', 'sharing.afp_share'): share = Struct(share) if share.afp_home: cf_contents.append("[Homes]\n") cf_contents.append("\tbasedir regex = %s\n" % share.afp_path) if share.afp_name and share.afp_name != "Homes": cf_contents.append("\thome name = %s\n" % share.afp_name) else: cf_contents.append("[%s]\n" % share.afp_name) cf_contents.append("\tpath = %s\n" % share.afp_path) if share.afp_allow: cf_contents.append("\tvalid users = %s\n" % share.afp_allow) if share.afp_deny: cf_contents.append("\tinvalid users = %s\n" % share.afp_deny) if share.afp_hostsallow: cf_contents.append("\thosts allow = %s\n" % share.afp_hostsallow) if share.afp_hostsdeny: cf_contents.append("\thosts deny = %s\n" % share.afp_hostsdeny) if share.afp_ro: cf_contents.append("\trolist = %s\n" % share.afp_ro) if share.afp_rw: cf_contents.append("\trwlist = %s\n" % share.afp_rw) if share.afp_timemachine: cf_contents.append("\ttime machine = yes\n") if not share.afp_nodev: cf_contents.append("\tcnid dev = no\n") if share.afp_nostat: cf_contents.append("\tstat vol = no\n") if not share.afp_upriv: cf_contents.append("\tunix priv = no\n") else: if share.afp_fperm and not map_acls_mode: cf_contents.append("\tfile perm = %s\n" % share.afp_fperm) if share.afp_dperm and not map_acls_mode: cf_contents.append("\tdirectory perm = %s\n" % share.afp_dperm) if share.afp_umask and not map_acls_mode: cf_contents.append("\tumask = %s\n" % share.afp_umask) cf_contents.append("\tveto files = .windows/.mac/\n") if map_acls_mode: cf_contents.append("\tacls = yes\n") # Do not fail if aux params are not properly entered by the user try: aux_params = [ "\t{0}\n".format(p) for p in share.afp_auxparams.split("\n") ] except: pass else: cf_contents += aux_params # Update TimeMachine special files timemachine_supported_path = os.path.join( share.afp_path, ".com.apple.timemachine.supported") timemachine_quota_plist_path = os.path.join( share.afp_path, ".com.apple.TimeMachine.quota.plist") timemachine_quota_plist_managed_flag = os.path.join( share.afp_path, ".com.apple.TimeMachine.quota.plist.FreeNAS-managed") if share.afp_timemachine and share.afp_timemachine_quota: try: with open(timemachine_supported_path, "w"): pass except IOError: pass try: with open(timemachine_quota_plist_path, "w") as f: f.write( textwrap.dedent("""\ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>GlobalQuota</key> <integer>%d</integer> </dict> </plist> """ % (share.afp_timemachine_quota * 1024 * 1024))) except IOError: pass try: with open(timemachine_quota_plist_managed_flag, "w") as f: pass except IOError: pass try: stat = os.stat(share.afp_path) os.chmod(timemachine_supported_path, 0o644) os.chown(timemachine_supported_path, stat.st_uid, stat.st_gid) os.chmod(timemachine_quota_plist_path, 0o644) os.chown(timemachine_quota_plist_path, stat.st_uid, stat.st_gid) os.chmod(timemachine_quota_plist_managed_flag, 0o644) os.chown(timemachine_quota_plist_managed_flag, stat.st_uid, stat.st_gid) except IOError: pass else: if os.path.exists(timemachine_quota_plist_managed_flag): try: os.unlink(timemachine_supported_path) except IOError: pass try: os.unlink(timemachine_quota_plist_path) except IOError: pass with open(afp_config, "w") as fh: for line in cf_contents: fh.write(line)
def main(): """Use the django ORM to generate a config file. We'll build the config file as a series of lines, and once that is done write it out in one go""" map_acls_mode = False afp_config = "/usr/local/etc/afp.conf" cf_contents = [] client = Client() afp = Struct( client.call('datastore.query', 'services.afp', None, {'get': True})) cf_contents.append("[Global]\n") uam_list = ['uams_dhx.so', 'uams_dhx2.so'] if afp.afp_srv_guest: uam_list.append('uams_guest.so') cf_contents.append('\tguest account = %s\n' % afp.afp_srv_guest_user) # uams_gss.so bails out with an error if kerberos isn't configured if client.call('datastore.query', 'directoryservice.kerberoskeytab', None, {'count': True}) > 0: uam_list.append('uams_gss.so') cf_contents.append('\tuam list = %s\n' % (" ").join(uam_list)) if afp.afp_srv_bindip: cf_contents.append("\tafp listen = %s\n" % ' '.join(afp.afp_srv_bindip)) ifaces = get_interface(afp.afp_srv_bindip) cf_contents.append("\tafp interfaces = %s\n" % ' '.join(ifaces)) cf_contents.append("\tmax connections = %s\n" % afp.afp_srv_connections_limit) cf_contents.append("\tmimic model = RackMac\n") if afp.afp_srv_dbpath: cf_contents.append("\tvol dbnest = no\n") cf_contents.append("\tvol dbpath = %s\n" % afp.afp_srv_dbpath) else: cf_contents.append("\tvol dbnest = yes\n") if afp.afp_srv_global_aux: cf_contents.append("\t%s\n" % afp.afp_srv_global_aux) if afp.afp_srv_map_acls: cf_contents.append("\tmap acls = %s\n" % afp.afp_srv_map_acls) if afp.afp_srv_chmod_request: cf_contents.append("\tchmod request = %s\n" % afp.afp_srv_chmod_request) if afp.afp_srv_map_acls == 'mode' and client.call( 'notifier.common', 'system', 'activedirectory_enabled'): map_acls_mode = True if map_acls_mode: ad = Struct(client.call('notifier.directoryservice', 'AD')) cf_contents.append("\tldap auth method = %s\n" % "simple") cf_contents.append("\tldap auth dn = %s\n" % ad.binddn) cf_contents.append("\tldap auth pw = %s\n" % ad.bindpw) cf_contents.append("\tldap server = %s\n" % ad.domainname) # This should be configured when using this option if ad.userdn: cf_contents.append("\tldap userbase = %s\n" % ad.userdn) cf_contents.append("\tldap userscope = %s\n" % "sub") # This should be configured when using this option if ad.groupdn: cf_contents.append("\tldap groupbase = %s\n" % ad.groupdn) cf_contents.append("\tldap groupscope = %s\n" % "sub") cf_contents.append("\tldap user filter = %s\n" % "objectclass=user") cf_contents.append("\tldap group filter = %s\n" % "objectclass=group") cf_contents.append("\tldap uuid attr = %s\n" % "objectGUID") cf_contents.append("\tldap uuid encoding = %s\n" % "ms-guid") cf_contents.append("\tldap name attr = %s\n" % "sAMAccountName") cf_contents.append("\tldap group attr = %s\n" % "sAMAccountName") cf_contents.append("\n") if afp.afp_srv_homedir_enable: cf_contents.append("[Homes]\n") cf_contents.append("\tbasedir regex = %s\n" % afp.afp_srv_homedir) if afp.afp_srv_homename: cf_contents.append("\thome name = %s\n" % afp.afp_srv_homename) if afp.afp_srv_hometimemachine: cf_contents.append(f"\ttime machine = yes\n") cf_contents.append("\n") for share in client.call('datastore.query', 'sharing.afp_share'): share = Struct(share) cf_contents.append("[%s]\n" % share.afp_name) cf_contents.append("\tpath = %s\n" % share.afp_path) if share.afp_allow: cf_contents.append("\tvalid users = %s\n" % share.afp_allow) if share.afp_deny: cf_contents.append("\tinvalid users = %s\n" % share.afp_deny) if share.afp_hostsallow: cf_contents.append("\thosts allow = %s\n" % share.afp_hostsallow) if share.afp_hostsdeny: cf_contents.append("\thosts deny = %s\n" % share.afp_hostsdeny) if share.afp_ro: cf_contents.append("\trolist = %s\n" % share.afp_ro) if share.afp_rw: cf_contents.append("\trwlist = %s\n" % share.afp_rw) if share.afp_timemachine: cf_contents.append("\ttime machine = yes\n") if not share.afp_nodev: cf_contents.append("\tcnid dev = no\n") if share.afp_nostat: cf_contents.append("\tstat vol = no\n") if not share.afp_upriv: cf_contents.append("\tunix priv = no\n") else: if share.afp_fperm and not map_acls_mode: cf_contents.append("\tfile perm = %s\n" % share.afp_fperm) if share.afp_dperm and not map_acls_mode: cf_contents.append("\tdirectory perm = %s\n" % share.afp_dperm) if share.afp_umask and not map_acls_mode: cf_contents.append("\tumask = %s\n" % share.afp_umask) cf_contents.append("\tveto files = .windows/.mac/\n") if map_acls_mode: cf_contents.append("\tacls = yes\n") # Do not fail if aux params are not properly entered by the user try: aux_params = [ "\t{0}\n".format(p) for p in share.afp_auxparams.split("\n") ] except: pass else: cf_contents += aux_params with open(afp_config, "w") as fh: for line in cf_contents: fh.write(line)
def main(): """Use the django ORM to generate a config file. We'll build the config file as a series of lines, and once that is done write it out in one go""" map_acls_mode = False afp_config = "/usr/local/etc/afp.conf" cf_contents = [] client = Client() afp = Struct(client.call("datastore.query", "services.afp", None, {"get": True})) cf_contents.append("[Global]\n") uam_list = ["uams_dhx.so", "uams_dhx2.so"] if afp.afp_srv_guest: uam_list.append("uams_guest.so") cf_contents.append("\tguest account = %s\n" % afp.afp_srv_guest_user) # uams_gss.so bails out with an error if kerberos isn't configured if client.call("datastore.query", "directoryservice.kerberoskeytab", None, {"count": True}) > 0: uam_list.append("uams_gss.so") cf_contents.append("\tuam list = %s\n" % (" ").join(uam_list)) if afp.afp_srv_bindip: cf_contents.append("\tafp listen = %s\n" % " ".join(afp.afp_srv_bindip)) cf_contents.append("\tmax connections = %s\n" % afp.afp_srv_connections_limit) cf_contents.append("\tmimic model = RackMac\n") if afp.afp_srv_dbpath: cf_contents.append("\tvol dbnest = no\n") cf_contents.append("\tvol dbpath = %s\n" % afp.afp_srv_dbpath) else: cf_contents.append("\tvol dbnest = yes\n") if afp.afp_srv_global_aux: cf_contents.append("\t%s" % afp.afp_srv_global_aux.encode("utf8")) if afp.afp_srv_map_acls: cf_contents.append("\tmap acls = %s\n" % afp.afp_srv_map_acls) if afp.afp_srv_map_acls == "mode" and client.call("notifier.common", "system", "activedirectory_enabled"): map_acls_mode = True if map_acls_mode: ad = Struct(client.call("notifier.directoryservice", "AD")) cf_contents.append("\tldap auth method = %s\n" % "simple") cf_contents.append("\tldap auth dn = %s\n" % ad.binddn) cf_contents.append("\tldap auth pw = %s\n" % ad.bindpw) cf_contents.append("\tldap server = %s\n" % ad.domainname) # This should be configured when using this option if ad.userdn: cf_contents.append("\tldap userbase = %s\n" % ad.userdn) cf_contents.append("\tldap userscope = %s\n" % "sub") # This should be configured when using this option if ad.groupdn: cf_contents.append("\tldap groupbase = %s\n" % ad.groupdn) cf_contents.append("\tldap groupscope = %s\n" % "sub") cf_contents.append("\tldap user filter = %s\n" % "objectclass=user") cf_contents.append("\tldap group filter = %s\n" % "objectclass=group") cf_contents.append("\tldap uuid attr = %s\n" % "objectGUID") cf_contents.append("\tldap uuid encoding = %s\n" % "ms-guid") cf_contents.append("\tldap name attr = %s\n" % "sAMAccountName") cf_contents.append("\tldap group attr = %s\n" % "sAMAccountName") cf_contents.append("\n") if afp.afp_srv_homedir_enable: cf_contents.append("[Homes]\n") cf_contents.append("\tbasedir regex = %s\n" % afp.afp_srv_homedir) if afp.afp_srv_homename: cf_contents.append("\thome name = %s\n" % afp.afp_srv_homename) cf_contents.append("\n") for share in client.call("datastore.query", "sharing.afp_share"): share = Struct(share) cf_contents.append("[%s]\n" % share.afp_name) cf_contents.append("\tpath = %s\n" % share.afp_path) if share.afp_allow: cf_contents.append("\tvalid users = %s\n" % share.afp_allow) if share.afp_deny: cf_contents.append("\tinvalid users = %s\n" % share.afp_deny) if share.afp_hostsallow: cf_contents.append("\thosts allow = %s\n" % share.afp_hostsallow) if share.afp_hostsdeny: cf_contents.append("\thosts deny = %s\n" % share.afp_hostsdeny) if share.afp_ro: cf_contents.append("\trolist = %s\n" % share.afp_ro) if share.afp_rw: cf_contents.append("\trwlist = %s\n" % share.afp_rw) if share.afp_timemachine: cf_contents.append("\ttime machine = yes\n") if not share.afp_nodev: cf_contents.append("\tcnid dev = no\n") if share.afp_nostat: cf_contents.append("\tstat vol = no\n") if not share.afp_upriv: cf_contents.append("\tunix priv = no\n") else: if share.afp_fperm and not map_acls_mode: cf_contents.append("\tfile perm = %s\n" % share.afp_fperm) if share.afp_dperm and not map_acls_mode: cf_contents.append("\tdirectory perm = %s\n" % share.afp_dperm) if share.afp_umask and not map_acls_mode: cf_contents.append("\tumask = %s\n" % share.afp_umask) cf_contents.append("\tveto files = .windows/.mac/\n") if map_acls_mode: cf_contents.append("\tacls = yes\n") with open(afp_config, "w") as fh: for line in cf_contents: fh.write(line)
def main(): """Use the django ORM to generate a config file. We'll build the config file as a series of lines, and once that is done write it out in one go""" map_acls_mode = False afp_config = "/usr/local/etc/afp.conf" cf_contents = [] client = Client() afp = Struct(client.call('datastore.query', 'services.afp', None, {'get': True})) cf_contents.append("[Global]\n") uam_list = ['uams_dhx.so', 'uams_dhx2.so'] if afp.afp_srv_guest: uam_list.append('uams_guest.so') cf_contents.append('\tguest account = %s\n' % afp.afp_srv_guest_user) # uams_gss.so bails out with an error if kerberos isn't configured if client.call('datastore.query', 'directoryservice.kerberoskeytab', None, {'count': True}) > 0: uam_list.append('uams_gss.so') cf_contents.append('\tuam list = %s\n' % (" ").join(uam_list)) if afp.afp_srv_bindip: cf_contents.append("\tafp listen = %s\n" % ' '.join(afp.afp_srv_bindip)) ifaces = get_interface(afp.afp_srv_bindip) cf_contents.append("\tafp interfaces = %s\n" % ' '.join(ifaces)) cf_contents.append("\tmax connections = %s\n" % afp.afp_srv_connections_limit) cf_contents.append("\tmimic model = RackMac\n") cf_contents.append("\tafpstats = yes\n") if afp.afp_srv_dbpath: cf_contents.append("\tvol dbnest = no\n") cf_contents.append("\tvol dbpath = %s\n" % afp.afp_srv_dbpath) else: cf_contents.append("\tvol dbnest = yes\n") if afp.afp_srv_global_aux: cf_contents.append("\t%s\n" % afp.afp_srv_global_aux) if afp.afp_srv_map_acls: cf_contents.append("\tmap acls = %s\n" % afp.afp_srv_map_acls) if afp.afp_srv_chmod_request: cf_contents.append("\tchmod request = %s\n" % afp.afp_srv_chmod_request) if afp.afp_srv_map_acls == 'mode' and client.call('notifier.common', 'system', 'activedirectory_enabled'): map_acls_mode = True if map_acls_mode: ad = Struct(client.call('notifier.directoryservice', 'AD')) cf_contents.append("\tldap auth method = %s\n" % "simple") cf_contents.append("\tldap auth dn = %s\n" % ad.binddn) cf_contents.append("\tldap auth pw = %s\n" % ad.bindpw) cf_contents.append("\tldap server = %s\n" % ad.domainname) # This should be configured when using this option if ad.userdn: cf_contents.append("\tldap userbase = %s\n" % ad.userdn) cf_contents.append("\tldap userscope = %s\n" % "sub") # This should be configured when using this option if ad.groupdn: cf_contents.append("\tldap groupbase = %s\n" % ad.groupdn) cf_contents.append("\tldap groupscope = %s\n" % "sub") cf_contents.append("\tldap user filter = %s\n" % "objectclass=user") cf_contents.append("\tldap group filter = %s\n" % "objectclass=group") cf_contents.append("\tldap uuid attr = %s\n" % "objectGUID") cf_contents.append("\tldap uuid encoding = %s\n" % "ms-guid") cf_contents.append("\tldap name attr = %s\n" % "sAMAccountName") cf_contents.append("\tldap group attr = %s\n" % "sAMAccountName") cf_contents.append("\tlog file = %s\n" % "/var/log/afp.log") cf_contents.append("\tlog level = %s\n" % "default:info") cf_contents.append("\n") for share in client.call('datastore.query', 'sharing.afp_share'): share = Struct(share) if share.afp_home: cf_contents.append("[Homes]\n") cf_contents.append("\tbasedir regex = %s\n" % share.afp_path) if share.afp_name and share.afp_name != "Homes": cf_contents.append("\thome name = %s\n" % share.afp_name) else: cf_contents.append("[%s]\n" % share.afp_name) cf_contents.append("\tpath = %s\n" % share.afp_path) if share.afp_allow: cf_contents.append("\tvalid users = %s\n" % share.afp_allow) if share.afp_deny: cf_contents.append("\tinvalid users = %s\n" % share.afp_deny) if share.afp_hostsallow: cf_contents.append("\thosts allow = %s\n" % share.afp_hostsallow) if share.afp_hostsdeny: cf_contents.append("\thosts deny = %s\n" % share.afp_hostsdeny) if share.afp_ro: cf_contents.append("\trolist = %s\n" % share.afp_ro) if share.afp_rw: cf_contents.append("\trwlist = %s\n" % share.afp_rw) if share.afp_timemachine: cf_contents.append("\ttime machine = yes\n") if not share.afp_nodev: cf_contents.append("\tcnid dev = no\n") if share.afp_nostat: cf_contents.append("\tstat vol = no\n") if not share.afp_upriv: cf_contents.append("\tunix priv = no\n") else: if share.afp_fperm and not map_acls_mode: cf_contents.append("\tfile perm = %s\n" % share.afp_fperm) if share.afp_dperm and not map_acls_mode: cf_contents.append("\tdirectory perm = %s\n" % share.afp_dperm) if share.afp_umask and not map_acls_mode: cf_contents.append("\tumask = %s\n" % share.afp_umask) cf_contents.append("\tveto files = .windows/.mac/\n") if map_acls_mode: cf_contents.append("\tacls = yes\n") # Do not fail if aux params are not properly entered by the user try: aux_params = ["\t{0}\n".format(p) for p in share.afp_auxparams.split("\n")] except: pass else: cf_contents += aux_params # Update TimeMachine special files timemachine_supported_path = os.path.join(share.afp_path, ".com.apple.timemachine.supported") timemachine_quota_plist_path = os.path.join(share.afp_path, ".com.apple.TimeMachine.quota.plist") timemachine_quota_plist_managed_flag = os.path.join(share.afp_path, ".com.apple.TimeMachine.quota.plist.FreeNAS-managed") if share.afp_timemachine and share.afp_timemachine_quota: try: with open(timemachine_supported_path, "w"): pass except IOError: pass try: with open(timemachine_quota_plist_path, "w") as f: f.write(textwrap.dedent("""\ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>GlobalQuota</key> <integer>%d</integer> </dict> </plist> """ % (share.afp_timemachine_quota * 1024 * 1024 * 1024))) except IOError: pass try: with open(timemachine_quota_plist_managed_flag, "w") as f: pass except IOError: pass try: stat = os.stat(share.afp_path) os.chmod(timemachine_supported_path, 0o644) os.chown(timemachine_supported_path, stat.st_uid, stat.st_gid) os.chmod(timemachine_quota_plist_path, 0o644) os.chown(timemachine_quota_plist_path, stat.st_uid, stat.st_gid) os.chmod(timemachine_quota_plist_managed_flag, 0o644) os.chown(timemachine_quota_plist_managed_flag, stat.st_uid, stat.st_gid) except IOError: pass else: if os.path.exists(timemachine_quota_plist_managed_flag): try: os.unlink(timemachine_supported_path) except IOError: pass try: os.unlink(timemachine_quota_plist_path) except IOError: pass with open(afp_config, "w") as fh: for line in cf_contents: fh.write(line)
def main(): client = Client() ldap_conf = "/usr/local/etc/nss_ldap.conf" if client.call('notifier.common', 'system', 'ldap_enabled'): ldap_conf_ldap(client, ldap_conf)
def main(): nsswitch_conf = { 'group': ['files'], 'hosts': ['files', 'mdns', 'dns'], 'networks': ['files'], 'passwd': ['files'], 'shells': ['files'], 'services': ['files'], 'protocols': ['files'], 'rpc': ['files'], 'sudoers': ['files'] } verb = "start" if len(sys.argv) > 1: verb = sys.argv[1].lower() client = Client() activedirectory_enabled = client.call('notifier.common', 'system', 'activedirectory_enabled') domaincontroller_enabled = client.call('notifier.common', 'system', 'domaincontroller_enabled') ldap_enabled = client.call('notifier.common', 'system', 'ldap_enabled') nis_enabled = client.call('notifier.common', 'system', 'nis_enabled') nt4_enabled = client.call('notifier.common', 'system', 'nt4_enabled') if verb == 'start': if activedirectory_enabled and \ client.call('notifier.common', 'system', 'activedirectory_has_unix_extensions') and \ client.call('notifier.common', 'system', 'activedirectory_has_principal'): nsswitch_conf['passwd'].append('sss') nsswitch_conf['group'].append('sss') elif activedirectory_enabled or \ domaincontroller_enabled or nt4_enabled: nsswitch_conf['passwd'].append('winbind') nsswitch_conf['group'].append('winbind') #if nt4_enabled(): # nsswitch_conf['hosts'].append('wins') if ldap_enabled and client.call('notifier.common', 'system', 'ldap_anonymous_bind'): nsswitch_conf['passwd'].append('ldap') nsswitch_conf['group'].append('ldap') elif ldap_enabled: nsswitch_conf['passwd'].append('sss') nsswitch_conf['group'].append('sss') if client.call('notifier.common', 'system', 'ldap_sudo_configured'): nsswitch_conf['sudoers'].append('sss') if nis_enabled: nsswitch_conf['passwd'].append('nis') nsswitch_conf['group'].append('nis') nsswitch_conf['hosts'].append('nis') try: fd = os.open(NSSWITCH_CONF_PATH, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0644) for key in nsswitch_conf: line = "%s: %s\n" % ( key.strip(), string.join(map(lambda x: x.strip(), nsswitch_conf[key]), ' ') ) os.write(fd, line) os.close(fd) except Exception as e: print >> sys.stderr, "can't create %s: %s" % (NSSWITCH_CONF_PATH, e) sys.exit(1)
def main(): """Use the django ORM to generate a config file. We'll build the config file as a series of lines, and once that is done write it out in one go""" map_acls_mode = False afp_config = "/usr/local/etc/afp.conf" cf_contents = [] client = Client() afp = Struct(client.call('datastore.query', 'services.afp', None, {'get': True})) cf_contents.append("[Global]\n") uam_list = ['uams_dhx.so', 'uams_dhx2.so'] if afp.afp_srv_guest: uam_list.append('uams_guest.so') cf_contents.append('\tguest account = %s\n' % afp.afp_srv_guest_user) # uams_gss.so bails out with an error if kerberos isn't configured if client.call('datastore.query', 'directoryservice.kerberoskeytab', None, {'count': True}) > 0: uam_list.append('uams_gss.so') cf_contents.append('\tuam list = %s\n' % (" ").join(uam_list)) if afp.afp_srv_bindip: cf_contents.append("\tafp listen = %s\n" % ' '.join(afp.afp_srv_bindip)) ifaces = get_interface(afp.afp_srv_bindip) cf_contents.append("\tafp interfaces = %s\n" % ' '.join(ifaces)) cf_contents.append("\tmax connections = %s\n" % afp.afp_srv_connections_limit) cf_contents.append("\tmimic model = RackMac\n") if afp.afp_srv_dbpath: cf_contents.append("\tvol dbnest = no\n") cf_contents.append("\tvol dbpath = %s\n" % afp.afp_srv_dbpath) else: cf_contents.append("\tvol dbnest = yes\n") if afp.afp_srv_global_aux: cf_contents.append("\t%s\n" % afp.afp_srv_global_aux) if afp.afp_srv_map_acls: cf_contents.append("\tmap acls = %s\n" % afp.afp_srv_map_acls) if afp.afp_srv_chmod_request: cf_contents.append("\tchmod request = %s\n" % afp.afp_srv_chmod_request) if afp.afp_srv_map_acls == 'mode' and client.call('notifier.common', 'system', 'activedirectory_enabled'): map_acls_mode = True if map_acls_mode: ad = Struct(client.call('notifier.directoryservice', 'AD')) cf_contents.append("\tldap auth method = %s\n" % "simple") cf_contents.append("\tldap auth dn = %s\n" % ad.binddn) cf_contents.append("\tldap auth pw = %s\n" % ad.bindpw) cf_contents.append("\tldap server = %s\n" % ad.domainname) # This should be configured when using this option if ad.userdn: cf_contents.append("\tldap userbase = %s\n" % ad.userdn) cf_contents.append("\tldap userscope = %s\n" % "sub") # This should be configured when using this option if ad.groupdn: cf_contents.append("\tldap groupbase = %s\n" % ad.groupdn) cf_contents.append("\tldap groupscope = %s\n" % "sub") cf_contents.append("\tldap user filter = %s\n" % "objectclass=user") cf_contents.append("\tldap group filter = %s\n" % "objectclass=group") cf_contents.append("\tldap uuid attr = %s\n" % "objectGUID") cf_contents.append("\tldap uuid encoding = %s\n" % "ms-guid") cf_contents.append("\tldap name attr = %s\n" % "sAMAccountName") cf_contents.append("\tldap group attr = %s\n" % "sAMAccountName") cf_contents.append("\n") if afp.afp_srv_homedir_enable: cf_contents.append("[Homes]\n") cf_contents.append("\tbasedir regex = %s\n" % afp.afp_srv_homedir) if afp.afp_srv_homename: cf_contents.append("\thome name = %s\n" % afp.afp_srv_homename) if afp.afp_srv_hometimemachine: cf_contents.append(f"\ttime machine = yes\n") cf_contents.append("\n") for share in client.call('datastore.query', 'sharing.afp_share'): share = Struct(share) cf_contents.append("[%s]\n" % share.afp_name) cf_contents.append("\tpath = %s\n" % share.afp_path) if share.afp_allow: cf_contents.append("\tvalid users = %s\n" % share.afp_allow) if share.afp_deny: cf_contents.append("\tinvalid users = %s\n" % share.afp_deny) if share.afp_hostsallow: cf_contents.append("\thosts allow = %s\n" % share.afp_hostsallow) if share.afp_hostsdeny: cf_contents.append("\thosts deny = %s\n" % share.afp_hostsdeny) if share.afp_ro: cf_contents.append("\trolist = %s\n" % share.afp_ro) if share.afp_rw: cf_contents.append("\trwlist = %s\n" % share.afp_rw) if share.afp_timemachine: cf_contents.append("\ttime machine = yes\n") if not share.afp_nodev: cf_contents.append("\tcnid dev = no\n") if share.afp_nostat: cf_contents.append("\tstat vol = no\n") if not share.afp_upriv: cf_contents.append("\tunix priv = no\n") else: if share.afp_fperm and not map_acls_mode: cf_contents.append("\tfile perm = %s\n" % share.afp_fperm) if share.afp_dperm and not map_acls_mode: cf_contents.append("\tdirectory perm = %s\n" % share.afp_dperm) if share.afp_umask and not map_acls_mode: cf_contents.append("\tumask = %s\n" % share.afp_umask) cf_contents.append("\tveto files = .windows/.mac/\n") if map_acls_mode: cf_contents.append("\tacls = yes\n") # Do not fail if aux params are not properly entered by the user try: aux_params = ["\t{0}\n".format(p) for p in share.afp_auxparams.split("\n")] except: pass else: cf_contents += aux_params with open(afp_config, "w") as fh: for line in cf_contents: fh.write(line)
autotune.py --conf loader \ --kernel-reserved=2147483648 \ --userland-reserved=4294967296 """ import argparse import atexit import os import shlex import subprocess import sys from middlewared.client import Client c = Client('ws+unix:///var/run/middlewared-internal.sock') if not c.call('system.is_enterprise'): ENTERPRISE = False else: ENTERPRISE = True hardware = c.call('truenas.get_chassis_hardware') hardware = hardware.replace('TRUENAS-', '') hardware = hardware.split('-') KiB = 1024**1 MiB = 1024**2 GiB = 1024**3 NO_HASYNC = "/tmp/.sqlite3_ha_skip" @atexit.register
def main(): """Use middleware client to generate a config file.""" client = Client() # Obtain the various webdav configuration details from services object webby = Struct( client.call('datastore.query', 'services.WebDAV', None, {'get': True})) dav_tcpport = webby.webdav_tcpport dav_tcpportssl = webby.webdav_tcpportssl dav_protocol = webby.webdav_protocol dav_auth_type = webby.webdav_htauth dav_passwd = webby.webdav_password if dav_protocol != 'http': dav_ssl_certfile = '/etc/certificates/%s.crt' % webby.webdav_certssl.cert_name dav_ssl_keyfile = '/etc/certificates/%s.key' % webby.webdav_certssl.cert_name # Declaring the config file locations as well as making some # generic config-text blocks dav_config_file = '/etc/local/apache24/Includes/webdav.conf' davssl_config_file = '/etc/local/apache24/Includes/webdav-ssl.conf' dav_auth_text = "" if dav_auth_type == 'digest': dav_auth_text = "AuthDigestProvider file" dav_config_pretext = """ DavLockDB "/etc/local/apache24/var/DavLock" AssignUserId webdav webdav <Directory /> AuthType %s AuthName webdav AuthUserFile "/etc/local/apache24/webdavht%s" %s Require valid-user Dav On IndexOptions Charset=utf-8 AddDefaultCharset UTF-8 AllowOverride None Order allow,deny Allow from all Options Indexes FollowSymLinks </Directory>\n""" % (dav_auth_type, dav_auth_type, dav_auth_text) dav_config_posttext = """ # The following directives disable redirects on non-GET requests for # a directory that does not include the trailing slash. This fixes a # problem with several clients that do not appropriately handle # redirects for folders with DAV methods. BrowserMatch "Microsoft Data Access Internet Publishing Provider" redirect-carefully BrowserMatch "MS FrontPage" redirect-carefully BrowserMatch "^WebDrive" redirect-carefully BrowserMatch "^WebDAVFS/1.[01234]" redirect-carefully BrowserMatch "^gnome-vfs/1.0" redirect-carefully BrowserMatch "^XML Spy" redirect-carefully BrowserMatch "^Dreamweaver-WebDAV-SCM1" redirect-carefully BrowserMatch " Konqueror/4" redirect-carefully </VirtualHost>""" # Generate the webdav password files dav_passwd_change(dav_passwd, dav_auth_type) # Check to see if there is a webdav lock databse directory, if not create # one. Take care of necessary permissions whilst creating it! oscmd = "/etc/local/apache24/var" if not os.path.isdir(oscmd): os.mkdir(oscmd, 0o774) _chownrecur(oscmd, pwd.getpwnam("webdav").pw_uid, grp.getgrnam("webdav").gr_gid) # Now getting to the actual webdav share details and all webshares = [ Struct(i) for i in client.call('datastore.query', 'sharing.WebDAV_Share') ] if dav_protocol in ['http', 'httphttps']: if dav_protocol == 'http': with open(davssl_config_file, 'w') as f2: f2.write("") with open(dav_config_file, 'w') as f: f.write(" Listen " + str(dav_tcpport) + "\n") f.write("\t <VirtualHost *:" + str(dav_tcpport) + ">\n") f.write(dav_config_pretext) for share in webshares: temp_path = """ "%s" """ % share.webdav_path f.write("\t Alias /" + share.webdav_name + temp_path + "\n") f.write("\t <Directory " + temp_path + ">\n") f.write("\t </Directory>\n") if share.webdav_ro == 1: f.write( "\t <Location /" + share.webdav_name + ">\n\t\t AllowMethods GET OPTIONS PROPFIND\n\t </Location>\n" ) if share.webdav_perm: _pipeopen("chown -R webdav:webdav %s" % share.webdav_path) f.write(dav_config_posttext) if dav_protocol in ['https', 'httphttps']: if dav_protocol == 'https': with open(dav_config_file, 'w') as f: f.write("") with open(davssl_config_file, 'w') as f2: f2.write(" Listen " + str(dav_tcpportssl) + "\n") f2.write("\t <VirtualHost *:" + str(dav_tcpportssl) + ">\n") f2.write("\t SSLEngine on\n") f2.write("""\t SSLCertificateFile "%s"\n""" % dav_ssl_certfile) f2.write("""\t SSLCertificateKeyFile "%s"\n""" % dav_ssl_keyfile) f2.write( "\t SSLProtocol +TLSv1 +TLSv1.1 +TLSv1.2\n\t SSLCipherSuite HIGH:MEDIUM\n" ) f2.write(dav_config_pretext) # Note: The for loop below is essentially code duplication, # but since two different files are being written to I could # not at the moment find a more efficient way of doing this. # (if you can fix it, please do so) for share in webshares: temp_path = """ "%s" """ % share.webdav_path f2.write("\t Alias /" + share.webdav_name + temp_path + "\n") f2.write("\t <Directory " + temp_path + ">\n") f2.write("\t </Directory>\n") if share.webdav_ro == 1: f2.write( "\t <Location /" + share.webdav_name + ">\n\t\t AllowMethods GET OPTIONS PROPFIND\n\t </Location>\n" ) # Note: the 'and' in the if statement below is to ensure # that we do not waste time in changin permisions twice # (once while in http block) if (share.webdav_perm and dav_protocol != "httphttps"): _pipeopen("chown -R webdav:webdav %s" % share.webdav_path) f2.write(dav_config_posttext)
def main(): client = Client() realms = client.call('datastore.query', 'directoryservice.KerberosRealm') try: settings = client.call('datastore.query', 'directoryservice.KerberosSettings') if settings: settings = Struct(settings[0]) else: settings = None except: settings = None default_realm = None if len(sys.argv) == 3 and sys.argv[1].lower() == 'default': default_realm = sys.argv[2].upper() kc = KerberosConfig(settings=settings, default_realm=default_realm) kc.create_default_config() ad = ldap = None ldap_objects = client.call('datastore.query', 'directoryservice.LDAP') if ldap_objects and ldap_objects[0]['ldap_enable']: ldap = Struct(client.call('notifier.directoryservice', 'LDAP', timeout=fs().directoryservice.kerberos.timeout.start)) ad_objects = client.call('datastore.query', 'directoryservice.ActiveDirectory') if ad_objects and ad_objects[0]['ad_enable']: ad = Struct(client.call('notifier.directoryservice', 'AD', timeout=fs().directoryservice.kerberos.timeout.start)) for kr in realms: kr = Struct(kr) if not kr.krb_realm: continue krb_kdc, krb_admin_server, krb_kpasswd_server = get_kerberos_servers( kr, ad, ldap ) bc = KerberosConfigBindingCollection(name=kr.krb_realm) if krb_kdc: bc.append( KerberosConfigBinding( name="kdc", value=krb_kdc ) ) if krb_admin_server: bc.append( KerberosConfigBinding( name="admin_server", value=krb_admin_server ) ) if krb_kpasswd_server: bc.append( KerberosConfigBinding( name="kpasswd_server", value=krb_kpasswd_server ) ) bc.append( KerberosConfigBinding( name="default_domain", value=kr.krb_realm ) ) kc.add_bindings(['realms'], bc) bc = KerberosConfigBindingCollection() bc.append( KerberosConfigBinding( name=kr.krb_realm.lower(), value=kr.krb_realm.upper() ) ) bc.append( KerberosConfigBinding( name=".%s" % kr.krb_realm.lower(), value=kr.krb_realm.upper() ) ) bc.append( KerberosConfigBinding( name=kr.krb_realm.upper(), value=kr.krb_realm.upper() ) ) bc.append( KerberosConfigBinding( name=".%s" % kr.krb_realm.upper(), value=kr.krb_realm.upper() ) ) kc.add_bindings(['domain_realm'], bc) fp = open("/etc/krb5.conf", "w+") kc.generate_krb5_conf(stdout=fp) fp.close()
def main(): client = Client() ldap_conf = "/usr/local/etc/nss_ldap.conf" if client.call('notifier.common', 'system', 'ldap_enabled'): ldap_conf_ldap(client, ldap_conf)
def main(): client = Client() realms = client.call('datastore.query', 'directoryservice.KerberosRealm') try: settings = Struct( client.call('datastore.config', 'directoryservice.KerberosSettings')) except: settings = None default_realm = None if len(sys.argv) == 3 and sys.argv[1].lower() == 'default': default_realm = sys.argv[2].upper() kc = KerberosConfig(settings=settings, default_realm=default_realm) kc.create_default_config() ad = ldap = None ldap_objects = client.call('datastore.query', 'directoryservice.LDAP') if ldap_objects and ldap_objects[0]['ldap_enable']: ldap = Struct(client.call('notifier.directoryservice', 'LDAP')) ad_objects = client.call('datastore.query', 'directoryservice.ActiveDirectory') if ad_objects and ad_objects[0]['ad_enable']: ad = Struct(client.call('notifier.directoryservice', 'AD')) for kr in realms: kr = Struct(kr) if not kr.krb_realm: continue krb_kdc, krb_admin_server, krb_kpasswd_server = get_kerberos_servers( kr, ad, ldap) bc = KerberosConfigBindingCollection(name=kr.krb_realm) if krb_kdc: bc.append(KerberosConfigBinding(name="kdc", value=krb_kdc)) if krb_admin_server: bc.append( KerberosConfigBinding(name="admin_server", value=krb_admin_server)) if krb_kpasswd_server: bc.append( KerberosConfigBinding(name="kpasswd_server", value=krb_kpasswd_server)) bc.append( KerberosConfigBinding(name="default_domain", value=kr.krb_realm)) kc.add_bindings(['realms'], bc) bc = KerberosConfigBindingCollection() bc.append( KerberosConfigBinding(name=kr.krb_realm.lower(), value=kr.krb_realm.upper())) bc.append( KerberosConfigBinding(name=".%s" % kr.krb_realm.lower(), value=kr.krb_realm.upper())) bc.append( KerberosConfigBinding(name=kr.krb_realm.upper(), value=kr.krb_realm.upper())) bc.append( KerberosConfigBinding(name=".%s" % kr.krb_realm.upper(), value=kr.krb_realm.upper())) kc.add_bindings(['domain_realm'], bc) fp = open("/etc/krb5.conf", "w+") kc.generate_krb5_conf(stdout=fp) fp.close()
def main(): """Use middleware client to generate a config file.""" client = Client() # Obtain the various webdav configuration details from services object webby = Struct(client.call('datastore.query', 'services.WebDAV', None, {'get': True})) dav_tcpport = webby.webdav_tcpport dav_tcpportssl = webby.webdav_tcpportssl dav_protocol = webby.webdav_protocol dav_auth_type = webby.webdav_htauth dav_passwd = webby.webdav_password if dav_protocol != 'http': dav_ssl_certfile = '/etc/certificates/%s.crt' % webby.webdav_certssl.cert_name dav_ssl_keyfile = '/etc/certificates/%s.key' % webby.webdav_certssl.cert_name # Declaring the config file locations as well as making some # generic config-text blocks dav_config_file = '/etc/local/apache24/Includes/webdav.conf' davssl_config_file = '/etc/local/apache24/Includes/webdav-ssl.conf' dav_auth_text = "" if dav_auth_type == 'digest': dav_auth_text = "AuthDigestProvider file" dav_config_pretext = """ DavLockDB "/etc/local/apache24/var/DavLock" AssignUserId webdav webdav <Directory /> AuthType %s AuthName webdav AuthUserFile "/etc/local/apache24/webdavht%s" %s Require valid-user Dav On IndexOptions Charset=utf-8 AddDefaultCharset UTF-8 AllowOverride None Order allow,deny Allow from all Options Indexes FollowSymLinks </Directory>\n""" % (dav_auth_type, dav_auth_type, dav_auth_text) dav_config_posttext = """ # The following directives disable redirects on non-GET requests for # a directory that does not include the trailing slash. This fixes a # problem with several clients that do not appropriately handle # redirects for folders with DAV methods. BrowserMatch "Microsoft Data Access Internet Publishing Provider" redirect-carefully BrowserMatch "MS FrontPage" redirect-carefully BrowserMatch "^WebDrive" redirect-carefully BrowserMatch "^WebDAVFS/1.[01234]" redirect-carefully BrowserMatch "^gnome-vfs/1.0" redirect-carefully BrowserMatch "^XML Spy" redirect-carefully BrowserMatch "^Dreamweaver-WebDAV-SCM1" redirect-carefully BrowserMatch " Konqueror/4" redirect-carefully </VirtualHost>""" # Generate the webdav password files dav_passwd_change(dav_passwd, dav_auth_type) # Check to see if there is a webdav lock databse directory, if not create # one. Take care of necessary permissions whilst creating it! oscmd = "/etc/local/apache24/var" if not os.path.isdir(oscmd): os.mkdir(oscmd, 0o774) _chownrecur(oscmd, pwd.getpwnam("webdav").pw_uid, grp.getgrnam("webdav").gr_gid) # Now getting to the actual webdav share details and all webshares = [Struct(i) for i in client.call('datastore.query', 'sharing.WebDAV_Share')] if dav_protocol in ['http', 'httphttps']: if dav_protocol == 'http': with open(davssl_config_file, 'w') as f2: f2.write("") with open(dav_config_file, 'w') as f: f.write(" Listen " + str(dav_tcpport) + "\n") f.write("\t <VirtualHost *:" + str(dav_tcpport) + ">\n") f.write(dav_config_pretext) for share in webshares: temp_path = """ "%s" """ % share.webdav_path f.write("\t Alias /" + share.webdav_name + temp_path + "\n") f.write("\t <Directory " + temp_path + ">\n") f.write("\t </Directory>\n") if share.webdav_ro == 1: f.write( "\t <Location /" + share.webdav_name + ">\n\t\t AllowMethods GET OPTIONS PROPFIND\n\t </Location>\n" ) if share.webdav_perm: _pipeopen("chown -R webdav:webdav %s" % share.webdav_path) f.write(dav_config_posttext) if dav_protocol in ['https', 'httphttps']: if dav_protocol == 'https': with open(dav_config_file, 'w') as f: f.write("") with open(davssl_config_file, 'w') as f2: f2.write(" Listen " + str(dav_tcpportssl) + "\n") f2.write("\t <VirtualHost *:" + str(dav_tcpportssl) + ">\n") f2.write("\t SSLEngine on\n") f2.write("""\t SSLCertificateFile "%s"\n""" % dav_ssl_certfile) f2.write("""\t SSLCertificateKeyFile "%s"\n""" % dav_ssl_keyfile) f2.write("\t SSLProtocol +TLSv1 +TLSv1.1 +TLSv1.2\n\t SSLCipherSuite HIGH:MEDIUM\n") f2.write(dav_config_pretext) # Note: The for loop below is essentially code duplication, # but since two different files are being written to I could # not at the moment find a more efficient way of doing this. # (if you can fix it, please do so) for share in webshares: temp_path = """ "%s" """ % share.webdav_path f2.write("\t Alias /" + share.webdav_name + temp_path + "\n") f2.write("\t <Directory " + temp_path + ">\n") f2.write("\t </Directory>\n") if share.webdav_ro == 1: f2.write( "\t <Location /" + share.webdav_name + ">\n\t\t AllowMethods GET OPTIONS PROPFIND\n\t </Location>\n" ) # Note: the 'and' in the if statement below is to ensure # that we do not waste time in changin permisions twice # (once while in http block) if (share.webdav_perm and dav_protocol != "httphttps"): _pipeopen("chown -R webdav:webdav %s" % share.webdav_path) f2.write(dav_config_posttext)
def main(): """Use the middleware client to generate a config file. We'll build the config file as a series of lines, and once that is done write it out in one go""" client = Client() gconf = Struct( client.call('datastore.query', 'services.iSCSITargetGlobalConfiguration', None, {'get': True})) if gconf.iscsi_alua: node = client.call('notifier.failover_node') if gconf.iscsi_isns_servers: for server in gconf.iscsi_isns_servers.split(' '): addline('isns-server %s\n\n' % server) # Generate the portal-group section addline('portal-group default {\n}\n\n') for pg in client.call('datastore.query', 'services.iSCSITargetPortal'): pg = Struct(pg) # Prepare auth group for the portal group if pg.iscsi_target_portal_discoveryauthgroup: auth_list = [ Struct(i) for i in client.call( 'datastore.query', 'services.iSCSITargetAuthCredential', [( 'iscsi_target_auth_tag', '=', pg.iscsi_target_portal_discoveryauthgroup)]) ] else: auth_list = [] agname = 'ag4pg%d' % pg.iscsi_target_portal_tag if not auth_group_config( auth_tag=agname, auth_list=auth_list, auth_type=pg.iscsi_target_portal_discoveryauthmethod): agname = "no-authentication" # Prepare IPs to listen on for all portal groups. portals = [ Struct(i) for i in client.call( 'datastore.query', 'services.iSCSITargetPortalIP', [( 'iscsi_target_portalip_portal', '=', pg.id)]) ] listen = [] listenA = [] listenB = [] for portal in portals: if ':' in portal.iscsi_target_portalip_ip: address = '[%s]' % portal.iscsi_target_portalip_ip else: address = portal.iscsi_target_portalip_ip found = False if gconf.iscsi_alua: if address == "0.0.0.0": listenA.append( "%s:%s" % (address, portal.iscsi_target_portalip_port)) listenB.append( "%s:%s" % (address, portal.iscsi_target_portalip_port)) found = True break if not found: for net in client.call('datastore.query', 'network.Interfaces'): if net['int_vip'] == address and net[ 'int_ipv4address'] and net['int_ipv4address_b']: listenA.append("%s:%s" % (net['int_ipv4address'], portal.iscsi_target_portalip_port)) listenB.append("%s:%s" % (net['int_ipv4address_b'], portal.iscsi_target_portalip_port)) found = True break if not found: for alias in client.call('datastore.query', 'network.Alias'): if alias['alias_vip'] == address and alias[ 'alias_v4address'] and alias[ 'alias_v4address_b']: listenA.append("%s:%s" % (alias['alias_v4address'], portal.iscsi_target_portalip_port)) listenB.append("%s:%s" % (alias['alias_v4address_b'], portal.iscsi_target_portalip_port)) found = True break else: listen.append("%s:%s" % (address, portal.iscsi_target_portalip_port)) if gconf.iscsi_alua: # Two portal groups for ALUA HA case. addline("portal-group pg%dA {\n" % pg.iscsi_target_portal_tag) addline("\ttag 0x%04x\n" % pg.iscsi_target_portal_tag) addline("\tdiscovery-filter portal-name\n") addline("\tdiscovery-auth-group %s\n" % agname) for i in listenA: addline("\tlisten %s\n" % i) if node != "A": addline("\tforeign\n") addline("}\n") addline("portal-group pg%dB {\n" % pg.iscsi_target_portal_tag) addline("\ttag 0x%04x\n" % (pg.iscsi_target_portal_tag + 0x8000)) addline("\tdiscovery-filter portal-name\n") addline("\tdiscovery-auth-group %s\n" % agname) for i in listenB: addline("\tlisten %s\n" % i) if node != "B": addline("\tforeign\n") addline("}\n\n") else: # One portal group for non-HA and CARP HA cases. addline("portal-group pg%d {\n" % pg.iscsi_target_portal_tag) addline("\ttag 0x%04x\n" % pg.iscsi_target_portal_tag) addline("\tdiscovery-filter portal-name\n") addline("\tdiscovery-auth-group %s\n" % agname) for i in listen: addline("\tlisten %s\n" % i) addline("\toption ha_shared on\n") addline("}\n\n") # Cache zpool threshold poolthreshold = {} zpoollist = client.call('notifier.zpool_list') # Generate the LUN section for extent in client.call('datastore.query', 'services.iSCSITargetExtent'): extent = Struct(extent) path = extent.iscsi_target_extent_path if not path: log.warn('Path for extent id %d is null, skipping', extent.id) continue poolname = None lunthreshold = None if extent.iscsi_target_extent_type == 'Disk': disk = client.call('datastore.query', 'storage.Disk', [('disk_identifier', '=', path)], {'order_by': ['disk_expiretime']}) if not disk: continue disk = Struct(disk[0]) if disk.disk_multipath_name: path = "/dev/multipath/%s" % disk.disk_multipath_name else: path = "/dev/%s" % client.call('notifier.identifier_to_device', disk.disk_identifier) else: if not path.startswith("/mnt"): poolname = path.split('/', 2)[1] if gconf.iscsi_pool_avail_threshold: if poolname in zpoollist: poolthreshold[poolname] = int( zpoollist.get(poolname).get('size') * (gconf.iscsi_pool_avail_threshold / 100.0)) if extent.iscsi_target_extent_avail_threshold: zvolname = path.split('/', 1)[1] zfslist = client.call('notifier.zfs_list', zvolname, False, False, False, ['volume']) if zfslist: lunthreshold = int( zfslist[zvolname]['volsize'] * (extent.iscsi_target_extent_avail_threshold / 100.0)) path = "/dev/" + path else: if extent.iscsi_target_extent_avail_threshold and os.path.exists( path): try: stat = os.stat(path) lunthreshold = int( stat.st_size * (extent.iscsi_target_extent_avail_threshold / 100.0)) except OSError: pass addline("lun \"%s\" {\n" % extent.iscsi_target_extent_name) addline("\tctl-lun %d\n" % (extent.id - 1)) size = extent.iscsi_target_extent_filesize addline("\tpath \"%s\"\n" % path) addline("\tblocksize %s\n" % extent.iscsi_target_extent_blocksize) if extent.iscsi_target_extent_pblocksize: addline("\toption pblocksize 0\n") addline("\tserial \"%s\"\n" % (extent.iscsi_target_extent_serial, )) padded_serial = extent.iscsi_target_extent_serial if not extent.iscsi_target_extent_xen: for i in range(31 - len(extent.iscsi_target_extent_serial)): padded_serial += " " addline('\tdevice-id "iSCSI Disk %s"\n' % padded_serial) if size != "0": if size.endswith('B'): size = size.strip('B') addline("\t\tsize %s\n" % size) # We can't change the vendor name of existing # LUNs without angering VMWare, but we can # use the right names going forward. if extent.iscsi_target_extent_legacy is True: addline('\toption vendor "FreeBSD"\n') else: if client.call('notifier.is_freenas'): addline('\toption vendor "FreeNAS"\n') else: addline('\toption vendor "TrueNAS"\n') addline('\toption product "iSCSI Disk"\n') addline('\toption revision "0123"\n') addline('\toption naa %s\n' % extent.iscsi_target_extent_naa) if extent.iscsi_target_extent_insecure_tpc: addline('\toption insecure_tpc on\n') if lunthreshold: addline('\toption avail-threshold %s\n' % lunthreshold) if poolname is not None and poolname in poolthreshold: addline('\toption pool-avail-threshold %s\n' % poolthreshold[poolname]) if extent.iscsi_target_extent_rpm == "Unknown": addline('\toption rpm 0\n') elif extent.iscsi_target_extent_rpm == "SSD": addline('\toption rpm 1\n') else: addline('\toption rpm %s\n' % extent.iscsi_target_extent_rpm) if extent.iscsi_target_extent_ro: addline('\toption readonly on\n') addline("}\n") addline("\n") # Generate the target section target_basename = gconf.iscsi_basename for target in client.call('datastore.query', 'services.iSCSITarget'): target = Struct(target) authgroups = {} for grp in client.call('datastore.query', 'services.iscsitargetgroups', [('iscsi_target', '=', target.id)]): grp = Struct(grp) if grp.iscsi_target_authgroup: auth_list = [ Struct(i) for i in client.call('datastore.query', 'services.iSCSITargetAuthCredential', [('iscsi_target_auth_tag', '=', grp.iscsi_target_authgroup)]) ] else: auth_list = [] agname = 'ag4tg%d_%d' % (target.id, grp.id) if auth_group_config(auth_tag=agname, auth_list=auth_list, auth_type=grp.iscsi_target_authtype, initiator=grp.iscsi_target_initiatorgroup): authgroups[grp.id] = agname if (target.iscsi_target_name.startswith("iqn.") or target.iscsi_target_name.startswith("eui.") or target.iscsi_target_name.startswith("naa.")): addline("target %s {\n" % target.iscsi_target_name) else: addline("target %s:%s {\n" % (target_basename, target.iscsi_target_name)) if target.iscsi_target_alias: addline("\talias \"%s\"\n" % target.iscsi_target_alias) elif target.iscsi_target_name: addline("\talias \"%s\"\n" % target.iscsi_target_name) for fctt in client.call('datastore.query', 'services.fibrechanneltotarget', [('fc_target', '=', target.id)]): fctt = Struct(fctt) addline("\tport %s\n" % fctt.fc_port) for grp in client.call('datastore.query', 'services.iscsitargetgroups', [('iscsi_target', '=', target.id)]): grp = Struct(grp) agname = authgroups.get(grp.id) or 'no-authentication' if gconf.iscsi_alua: addline("\tportal-group pg%dA %s\n" % (grp.iscsi_target_portalgroup.iscsi_target_portal_tag, agname)) addline("\tportal-group pg%dB %s\n" % (grp.iscsi_target_portalgroup.iscsi_target_portal_tag, agname)) else: addline("\tportal-group pg%d %s\n" % (grp.iscsi_target_portalgroup.iscsi_target_portal_tag, agname)) addline("\n") used_lunids = [ o['iscsi_lunid'] for o in client.call('datastore.query', 'services.iscsitargettoextent', [( 'iscsi_target', '=', target.id), ('iscsi_lunid', '!=', None)]) ] cur_lunid = 0 for t2e in client.call( 'datastore.query', 'services.iscsitargettoextent', [('iscsi_target', '=', target.id)], { 'extra': { 'select': { 'null_first': 'iscsi_lunid IS NULL' } }, 'order_by': ['null_first', 'iscsi_lunid'] }): t2e = Struct(t2e) if t2e.iscsi_lunid is None: while cur_lunid in used_lunids: cur_lunid += 1 addline("\tlun %s \"%s\"\n" % (cur_lunid, t2e.iscsi_extent.iscsi_target_extent_name)) cur_lunid += 1 else: addline("\tlun %s \"%s\"\n" % (t2e.iscsi_lunid, t2e.iscsi_extent.iscsi_target_extent_name)) addline("}\n\n") os.umask(0o77) # Write out the CTL config file fh = open(ctl_config, "w") for line in cf_contents: fh.write(line) fh.close() # Write out the CTL config file with redacted CHAP passwords fh = open(ctl_config_shadow, "w") for line in cf_contents_shadow: fh.write(line) fh.close()