def fixup_permission(filename, permission=S_IRUSR): """ Check if the given file exists and change ownershit to root/vyattacfg and appripriate file access permissions - default is user and group readable """ if os.path.isfile(filename): os.chmod(filename, permission) chown(filename, 'root', 'vyattacfg')
def openvpn_mkdir(directory): # create directory on demand if not os.path.exists(directory): os.mkdir(directory) # fix permissions - corresponds to mode 755 chmod_x(directory) chown(directory, user, group)
def _migrate_default_keys(): if os.path.exists(f'{kdir}/private.key') and not os.path.exists(f'{kdir}/default/private.key'): location = f'{kdir}/default' if not os.path.exists(location): os.makedirs(location) chown(location, 'root', 'vyattacfg') chmod_750(location) os.rename(f'{kdir}/private.key', f'{location}/private.key') os.rename(f'{kdir}/public.key', f'{location}/public.key')
def get_wpa_suppl_config_name(intf): cfg_dir = '/var/run/wpa_supplicant' # create directory on demand if not os.path.exists(cfg_dir): os.mkdir(cfg_dir) chmod_x(cfg_dir) chown(cfg_dir, user, group) cfg_file = cfg_dir + r'/{}.cfg'.format(intf) return cfg_file
def get_pid(conf_type, intf): cfg_dir = '/var/run/' + conf_type # create directory on demand if not os.path.exists(cfg_dir): os.mkdir(cfg_dir) chmod_x(cfg_dir) chown(cfg_dir, user, group) cfg_file = cfg_dir + r'/{}.pid'.format(intf) return cfg_file
def apply(pppoe): if pppoe['deleted']: # bail out early return None if not pppoe['disable']: # "dial" PPPoE connection intf = pppoe['intf'] cmd(f'systemctl start ppp@{intf}.service') # make logfile owned by root / vyattacfg chown(pppoe['logfile'], 'root', 'vyattacfg') return None
def render(destination, template, content, trim_blocks=False, formater=None, permission=None, user=None, group=None): """ render a template from the template directory, it will raise on any errors destination: the file where the rendered template must be saved template: the path to the template relative to the template folder content: the dictionary to use to render the template This classes cache the renderer, so rendering the same file multiple time does not cause as too much overhead. If use everywhere, it could be changed and load the template from python environement variables from an import python module generated when the debian package is build (recovering the load time and overhead caused by having the file out of the code) """ # Create the directory if it does not exists folder = os.path.dirname(destination) makedir(folder, user, group) # Setup a renderer for the given template # This is cached and re-used for performance if template not in _templates_mem[trim_blocks]: _templates_mem[trim_blocks][template] = _templates_env[ trim_blocks].get_template(template) template = _templates_mem[trim_blocks][template] # As we are opening the file with 'w', we are performing the rendering # before calling open() to not accidentally erase the file if the # templating fails content = template.render(content) if formater: content = formater(content) # Write client config file with open(destination, 'w') as f: f.write(content) chmod(destination, permission) chown(destination, user, group)
def generate(salt): if not salt: return None render(config_file, 'salt-minion/minion.tmpl', salt, user=salt['user'], group=salt['group']) if not os.path.exists(master_keyfile): if salt['master_key']: req = PoolManager().request('GET', salt['master_key'], preload_content=False) with open(master_keyfile, 'wb') as f: while True: data = req.read(1024) if not data: break f.write(data) req.release_conn() chown(master_keyfile, salt['user'], salt['group']) return None
def generate(openvpn): interface = openvpn['intf'] directory = os.path.dirname(get_config_name(interface)) # we can't know in advance which clients have been removed, # thus all client configs will be removed and re-added on demand ccd_dir = os.path.join(directory, 'ccd', interface) if os.path.isdir(ccd_dir): rmtree(ccd_dir, ignore_errors=True) if openvpn['deleted'] or openvpn['disable']: return None # create config directory on demand directories = [] directories.append(f'{directory}/status') directories.append(f'{directory}/ccd/{interface}') for onedir in directories: if not os.path.exists(onedir): os.makedirs(onedir, 0o755) chown(onedir, user, group) # Fix file permissons for keys fix_permissions = [] fix_permissions.append(openvpn['shared_secret_file']) fix_permissions.append(openvpn['tls_key']) # Generate User/Password authentication file if openvpn['auth']: with open(openvpn['auth_user_pass_file'], 'w') as f: f.write('{}\n{}'.format(openvpn['auth_user'], openvpn['auth_pass'])) # also change permission on auth file fix_permissions.append(openvpn['auth_user_pass_file']) else: # delete old auth file if present if os.path.isfile(openvpn['auth_user_pass_file']): os.remove(openvpn['auth_user_pass_file']) # Generate client specific configuration for client in openvpn['client']: client_file = os.path.join(ccd_dir, client['name']) render(client_file, 'openvpn/client.conf.tmpl', client) chown(client_file, user, group) # we need to support quoting of raw parameters from OpenVPN CLI # see https://phabricator.vyos.net/T1632 render(get_config_name(interface), 'openvpn/server.conf.tmpl', openvpn, formater=lambda _: _.replace(""", '"')) chown(get_config_name(interface), user, group) # Fixup file permissions for file in fix_permissions: chmod_600(file) return None
def generate(openvpn): if openvpn['deleted'] or openvpn['disable']: return None # Prepare Jinja2 template loader from files tmpl_path = os.path.join(vyos_data_dir['data'], 'templates', 'openvpn') fs_loader = FileSystemLoader(tmpl_path) env = Environment(loader=fs_loader) interface = openvpn['intf'] directory = os.path.dirname(get_config_name(interface)) # we can't know which clients were deleted, remove all client configs if os.path.isdir(os.path.join(directory, 'ccd', interface)): rmtree(os.path.join(directory, 'ccd', interface), ignore_errors=True) # create config directory on demand openvpn_mkdir(directory) # create status directory on demand openvpn_mkdir(directory + '/status') # create client config dir on demand openvpn_mkdir(directory + '/ccd') # crete client config dir per interface on demand openvpn_mkdir(directory + '/ccd/' + interface) # Fix file permissons for keys fixup_permission(openvpn['shared_secret_file']) fixup_permission(openvpn['tls_key']) # Generate User/Password authentication file if openvpn['auth']: auth_file = '/tmp/openvpn-{}-pw'.format(interface) with open(auth_file, 'w') as f: f.write('{}\n{}'.format(openvpn['auth_user'], openvpn['auth_pass'])) fixup_permission(auth_file) else: # delete old auth file if present if os.path.isfile('/tmp/openvpn-{}-pw'.format(interface)): os.remove('/tmp/openvpn-{}-pw'.format(interface)) # Generate client specific configuration for client in openvpn['client']: client_file = directory + '/ccd/' + interface + '/' + client['name'] tmpl = env.get_template('client.conf.tmpl') client_text = tmpl.render(client) with open(client_file, 'w') as f: f.write(client_text) chown(client_file, user, group) tmpl = env.get_template('server.conf.tmpl') config_text = tmpl.render(openvpn) # we need to support quoting of raw parameters from OpenVPN CLI # see https://phabricator.vyos.net/T1632 config_text = config_text.replace(""", '"') with open(get_config_name(interface), 'w') as f: f.write(config_text) chown(get_config_name(interface), user, group) return None