def remove_keys(_total_down): for minion in list(_total_down): if _total_down[minion] > 3: wheel.cmd_async({'fun': 'key.delete', 'match': minion}) log.warning( "Keys Maintenance Runner - minion down exceeded limit, removing key for %s", minion) _total_down.pop(minion, None) return _total_down
def wheel_async(self, fun, **kwargs): ''' Run :ref:`wheel modules <all-salt.wheel>` asynchronously Wraps :py:meth:`salt.wheel.WheelClient.master_call`. :return: Returns the result from the wheel module ''' kwargs['fun'] = fun wheel = salt.wheel.WheelClient(self.opts) return wheel.cmd_async(kwargs)
def deploy_vm_system_view(): error = None if request.method == 'GET': # socketio.start_background_task(cct_swx, '/dev/ttyUSB0', 'sw1usbsignal', 'sw1portsignal') # socketio.start_background_task(cct_swx, '/dev/ttyUSB1', 'sw2usbsignal', 'sw2portsignal') # deploy_sw_1_baseconfig = get_deploy_device_last_build_log('deploy_sw_1_baseconfig') # deploy_sw_1_baseconfig_job_info = get_deploy_device_get_job_info('deploy_sw_1_baseconfig') # deploy_sw_1_portconfig = get_deploy_device_last_build_log('deploy_sw_1_portconfig') # deploy_sw_1_portconfig_job_info = get_deploy_device_get_job_info('deploy_sw_1_portconfig') # deploy_sw_1_singleport = get_deploy_device_last_build_log('deploy_sw_1_singleport') # deploy_sw_1_singleport_job_info = get_deploy_device_get_job_info('deploy_sw_1_singleport') return render_template( 'deploy-vm-system.html', deploy_vm_systems=System_vm_profiles.query.all(), salt_pxe_nodes=Saltstack_pxe_nodes.query.all()) elif request.method == 'POST': if 'deploy_vm_system' in request.form: if not request.form['id']: flash('Please fill all the fields before sending a request!', 'danger') return redirect(request.url) else: deploy_vm_system = request.form.getlist('id') for deploy in deploy_vm_system: reboot_vm_system = Saltstack_pxe_nodes.query.filter_by( pxemac=deploy).one() reboot_vm_system_ip = reboot_vm_system.pxeipaddr reboot_vm_system_send_cmd = local.cmd( reboot_vm_system_ip, 'cmd.run', ['shutdown -r now']) # reboot_vm_system.pxeinstalled = True db.session.delete(reboot_vm_system) db.session.commit() wheel.cmd_async({ 'fun': 'key.delete', 'match': reboot_vm_system_ip }) return "<div class='alert alert-success' role='alert'><a href='#' class='close' data-dismiss='alert'>×</a>System Rebooted for PXE Installation.</div>" else: flash('Malformed form submitted !', 'danger') return redirect(request.url)
def wheel_async(self, fun, **kwargs): ''' Run :ref:`wheel modules <all-salt.wheel>` asynchronously Wraps :py:meth:`salt.wheel.WheelClient.master_call`. Note that wheel functions must be called using keyword arguments. Positional arguments are not supported. :return: Returns the result from the wheel module ''' kwargs['fun'] = fun wheel = salt.wheel.WheelClient(self.opts) return wheel.cmd_async(kwargs)
def delete_salt_minion(minion_name): opts = salt.config.master_config('/etc/salt/master.d/susemanager.conf') wheel = salt.wheel.WheelClient(opts) minion_pre_list = wheel.cmd('key.list', ['pre']) if len(minion_pre_list['minions_pre']) > 0: for p in minion_pre_list['minions_pre']: if minion_name in p: p_dict = { 'minions_pre': [ p, ], } print("Deleting minion from pending key accept: %s" % p_dict) wheel.cmd_async({'fun': 'key.delete_dict', 'match': p_dict}) minion_denied_list = wheel.cmd('key.list', ['denied']) if len(minion_denied_list['minions_denied']) > 0: for p in minion_denied_list['minions_denied']: if minion_name in p: p_dict = { 'minions_denied': [ p, ], } print("Deleting minion from denied key: %s" % p_dict) wheel.cmd_async({'fun': 'key.delete_dict', 'match': p_dict}) minion_rejected_list = wheel.cmd('key.list', ['rejected']) if len(minion_rejected_list['minions_rejected']) > 0: for p in minion_rejected_list['minions_rejected']: if minion_name in p: p_dict = { 'minions_rejected': [ p, ], } print("Deleting minion from rejected key: %s" % p_dict) wheel.cmd_async({'fun': 'key.delete_dict', 'match': p_dict})
def key_create(id_, host, force=False): ''' Generates minion keypair, accepts it on master and injects it to minion via SSH. :param id_: expected minion ID of target node :param host: IP address or resolvable hostname/FQDN of target node CLI Examples: .. code-block:: bash salt-call saltkey.key_create <MINION_ID> <MINION_IP_ADDRESS> force=False ''' ret = { 'retcode': 0, 'msg': 'Salt Key for minion %s is already accepted' % id_, } opts = salt.config.master_config('/etc/salt/master') wheel = salt.wheel.WheelClient(opts) keys = wheel.cmd('key.gen_accept', arg=[id_], kwarg={'force': force}) pub_key = keys.get('pub', None) priv_key = keys.get('priv', None) if pub_key and priv_key: ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # Establish SSH connection to minion try: ssh.connect(host) except paramiko.ssh_exception.AuthenticationException: msg = ( 'Could not establish SSH connection to minion "%s" on address %s, please ensure ' 'that current user\'s SSH key is present in minions authorized_keys.' ) % (id_, host) LOG.error(msg) ret['retcode'] = 1 ret['msg'] = msg wheel.cmd_async({'fun': 'key.delete', 'match': id_}) return ret except Exception as e: msg = ('Unknown error occured while establishing SSH connection ' 'to minion "%s" on address %s: %s') % (id_, host, repr(e)) LOG.error(msg) ret['retcode'] = 1 ret['msg'] = msg wheel.cmd_async({'fun': 'key.delete', 'match': id_}) return ret # Setup the keys on minion side the ugly way, nice one didn't work key_path = '/etc/salt/pki/minion' command = ( 'echo "%(pub_key)s" > %(pub_path)s && chmod 644 %(pub_path)s && ' 'echo "%(priv_key)s" > %(priv_path)s && chmod 400 %(priv_path)s && ' 'salt-call --local service.restart salt-minion') % { 'pub_path': os.path.join(key_path, 'minion.pub'), 'pub_key': pub_key, 'priv_path': os.path.join(key_path, 'minion.pem'), 'priv_key': priv_key } ssh_chan = ssh.get_transport().open_session() ssh_chan.exec_command(command) # Wait for command return while True: if ssh_chan.exit_status_ready(): exit_status = ssh_chan.recv_exit_status() stderr = ssh_chan.recv_stderr(1000) stdout = ssh_chan.recv(1000) break ssh.close() # Evaluate SSH command exit status if exit_status != 0: msg = 'Keypair injection to Salt minion failed on target with following error: %s' % stderr LOG.error(msg) ret['retcode'] = exit_status ret['msg'] = msg return ret ret['msg'] = 'Salt Key successfully created' return ret
def saltstack_view(): error = None if request.method == 'GET': salt_svc_check = salt_service_check() salt_keys_acc = salt_keys_accepted() salt_keys_unacc = salt_keys_unaccepted() salt_keys_den = salt_keys_denied() salt_keys_rej = salt_keys_rejected() return render_template('saltstack.html', pxe_nodes=Saltstack_pxe_nodes.query.all(), salt_svc_check=salt_svc_check, salt_keys_acc=salt_keys_acc, salt_keys_unacc=salt_keys_unacc, salt_keys_den=salt_keys_den, salt_keys_rej=salt_keys_rej) elif request.method == 'POST': if 'salt_keys_denied_delete' in request.form: if not request.form['salt_keys_denied_delete'] or request.form[ 'key_ip'] == '': flash('Please fill all the fields before sending a request!', 'danger') return redirect(request.url) else: key_ip = request.form['key_ip'] wheel.cmd_async({'fun': 'key.delete', 'match': key_ip}) pxe_node = Saltstack_pxe_nodes.query.filter_by( pxeipaddr=key_ip).first() if str(key_ip) == str(pxe_node): db.session.delete(pxe_node) db.session.commit() flash('Requested key ' + key_ip + ' has been removed!', 'success') return redirect(request.url) elif 'salt_keys_rejected_delete' in request.form: if not request.form['salt_keys_rejected_delete'] or request.form[ 'key_ip'] == '': flash('Please fill all the fields before sending a request!', 'danger') return redirect(request.url) else: key_ip = request.form['key_ip'] wheel.cmd_async({'fun': 'key.delete', 'match': key_ip}) pxe_node = Saltstack_pxe_nodes.query.filter_by( pxeipaddr=key_ip).first() if str(key_ip) == str(pxe_node): db.session.delete(pxe_node) db.session.commit() flash('Requested key ' + key_ip + ' has been removed!', 'success') return redirect(request.url) elif 'salt_keys_unaccepted_accept' in request.form: if not request.form['salt_keys_unaccepted_accept'] or request.form[ 'key_ip'] == '': flash('Please fill all the fields before sending a request!', 'danger') return redirect(request.url) else: key_ip = request.form['key_ip'] wheel.cmd('key.accept', [key_ip]) flash('Requested key ' + key_ip + ' has been accepted!', 'success') return redirect(request.url) elif 'salt_keys_unaccepted_delete' in request.form: if not request.form['salt_keys_unaccepted_delete'] or request.form[ 'key_ip'] == '': flash('Please fill all the fields before sending a request!', 'danger') return redirect(request.url) else: key_ip = request.form['key_ip'] wheel.cmd_async({'fun': 'key.delete', 'match': key_ip}) pxe_node = Saltstack_pxe_nodes.query.filter_by( pxeipaddr=key_ip).first() if str(key_ip) == str(pxe_node): db.session.delete(pxe_node) db.session.commit() flash('Requested key ' + key_ip + ' has been removed!', 'success') return redirect(request.url) elif 'salt_keys_accepted_delete' in request.form: if not request.form['salt_keys_accepted_delete'] or request.form[ 'key_ip'] == '': flash('Please fill all the fields before sending a request!', 'danger') return redirect(request.url) else: key_ip = request.form['key_ip'] wheel.cmd_async({'fun': 'key.delete', 'match': key_ip}) pxe_node = Saltstack_pxe_nodes.query.filter_by( pxeipaddr=key_ip).first() if str(key_ip) == str(pxe_node): db.session.delete(pxe_node) db.session.commit() flash('Requested key ' + key_ip + ' has been removed!', 'success') return redirect(request.url) elif 'salt_keys_audit_save' in request.form: if not request.form['salt_keys_audit_save'] or request.form[ 'key_ip'] == '': flash('Please fill all the fields before sending a request!', 'danger') return redirect(request.url) else: key_ip = request.form['key_ip'] pxe_node_check = Saltstack_pxe_nodes.query.filter_by( pxeipaddr=key_ip).first() if str(key_ip) == str(pxe_node_check): flash( 'Candidate ' + key_ip + ' has already been audited !', 'danger') return redirect(request.url) else: pxe_int_name = local.cmd(key_ip, 'network.ifacestartswith', [key_ip]) pxe_mac_addr = local.cmd(key_ip, 'network.hwaddr', [pxe_int_name[key_ip][0]]) pxe_node = Saltstack_pxe_nodes(key_ip, pxe_int_name[key_ip][0], pxe_mac_addr[key_ip]) db.session.add(pxe_node) db.session.commit() # print pxe_int_name[key_ip][0], pxe_mac_addr[key_ip] flash( 'Requested key ' + key_ip + ' has been audited! INT: ' + pxe_int_name[key_ip][0] + ' MAC: ' + pxe_mac_addr[key_ip] + ' ', 'success') return redirect(request.url) else: flash('Malformed form submitted !', 'danger') return redirect(request.url)