def get_panel_pdf(handler, panel, server_name, dash_user, pdf_file='/tmp/table.pdf', args=[], provider=None, kwargs={}, filter_field=''): if not args: args = list(args) cl = LocalClient() panel = yield get_panel_for_user(handler=handler, panel=panel, server_name=server_name, dash_user=dash_user, args=args, provider=provider, kwargs=kwargs) result = cl.cmd('va-master', 'va_utils.get_pdf', kwarg={ 'panel': panel, 'pdf_file': pdf_file, 'filter_field': filter_field }) if not result['va-master']: yield handler.serve_file(pdf_file) raise tornado.gen.Return({'data_type': 'file'}) raise Exception('PDF returned a value - probably because of an error. ')
def __init__(self,main_config): self.opts=master_config(main_config) self.wheel=Wheel(self.opts) self.client=LocalClient() self.connected_minions_list=self.wheel.call_func('minions.connected') self.key_dict=self.wheel.call_func('key.list_all') self.total=len(self.key_dict['minions'])+len(self.key_dict['minions_pre'])+len(self.key_dict['minions_denied'])+len(self.key_dict['minions_rejected'])
def syncAsset(): salt = LocalClient() grains = salt.cmd('*', 'grains.items') obj = Asset.objects.all() host_list = [] for i in obj: host_list.append(i.hostname) try: for host in grains.keys(): ip = grains[host]['ipv4'][-1] hostname_id = grains[host]['id'] cpu = grains[host]['cpu_model'] memory = grains[host]['mem_total'] if grains[host].has_key('virtual'): asset_type = grains[host]['virtual'] else: asset_type = 'physical' if grains[host].has_key('osfinger'): os = grains[host]['osfinger'] else: os = grains[host]['osfullname'] if host not in host_list: try: Asset.objects.create(ip=ip, hostname=hostname_id, system_type=os, cpu=cpu, memory=memory, asset_type=asset_type) except Exception, e: print e except Exception, e: print e
def serve_file(self, source, chunk_size = 10**6, salt_source = {}, url_source = ''): self.set_header('Content-Type', 'application/octet-stream') self.set_header('Content-Disposition', 'attachment; filename=test.zip') try: offset = 0 if salt_source: client = LocalClient() source = client.cmd kwargs = salt_source kwargs['kwarg'] = kwargs.get('kwarg', {}) kwargs['kwarg']['range_from'] = 0 elif url_source: def streaming_callback(chunk): self.write(chunk) self.flush() source = AsyncHTTPClient().fetch request = HTTPRequest(url = url_source, streaming_callback = streaming_callback) request = url_source kwargs = {"request" : request, 'streaming_callback' : streaming_callback} else: f = open(source, 'r') source = f.read kwargs = {"source_args" : [chunk_size]} print ('Serving file with : ', source, kwargs, chunk_size) result = yield self.send_data(source, kwargs, chunk_size) print ('Sent data and result is : ', result) self.finish() except: import traceback traceback.print_exc()
def get_all_monitoring_data(datastore_handler): """ description: Returns all icinga data from connected monitoring minions. """ cl = LocalClient() result = cl.cmd('G@role:monitoring', fun='va_monitoring.icinga2', tgt_type='compound') monitoring_errors = [] for minion in result: if type(result[minion]) == str: print( 'Error getting monitoring data for %s, salt returned %s, but will go on as usual. ' % (minion, result[minion])) monitoring_errors.append(minion) continue for host in result[minion]: if 'va_master' in host['host_name']: panel = {'icon': 'fa-circle'} else: panel = yield datastore_handler.find_panel_for_server( host['host_name']) host['icon'] = panel['icon'] if monitoring_errors: monitoring_errors = 'There was an error with the monitoring server(s): ' + ', '.join( monitoring_errors) result = { 'success': True, 'data': result, 'message': monitoring_errors } raise tornado.gen.Return(result)
def flushMemcached(request): data = request.POST.getlist('mcName') project = 'memcache flush' username = request.user ip = request.META['REMOTE_ADDR'] saltCmd = LocalClient() result = [] for name in data: for info in memcache.objects.filter(memcacheName=name): try: cmd = saltCmd.cmd( info.saltMinion.saltname, 'cmd.run', ['echo "flush_all" | nc %s %s' % (info.ip, info.port)]) result.append(cmd) if cmd[info.saltMinion.saltname] == 'OK': msg = 'Success' else: msg = 'error' host = info.ip + ":" + info.port dingding_robo(host, project, msg, username, request.POST['phone_number']) print result except Exception, e: print e
def get_all_roles(): cl = LocalClient() result = cl.cmd('*', 'grains.get', arg=['role']) return { x: result[x] for x in result if result[x] not in error_msgs and result[x] }
def export_table(handler, panel, server_name, dash_user, export_type='pdf', table_file='/tmp/table', args=[], provider=None, kwargs={}, filter_field=''): table_func = 'va_utils.get_%s' % export_type table_file = table_file + '.' + export_type if not args: args = list(args) cl = LocalClient() panel = yield get_panel_for_user(handler=handler, panel=panel, server_name=server_name, dash_user=dash_user, args=args, provider=provider, kwargs=kwargs) print('Getting ', export_type, ' with filter : ', filter_field) result = cl.cmd('G@role:va-master', fun=table_func, tgt_type='compound', kwarg={ 'panel': panel, 'table_file': table_file, 'filter_field': filter_field }) yield handler.serve_file(table_file)
def salt_local_client(): global _salt_local_client # TODO IMPROVE in case of minion retsart old handler will # lead to Authentication error, so always recreate it # as a workaround for now if not _salt_local_client or True: _salt_local_client = LocalClient() return _salt_local_client
def get_all_salt_functions(datastore_handler): """ Gets all salt functions for all minions. """ cl = LocalClient() states = yield datastore_handler.get_states_and_apps() functions = cl.cmd('*', 'sys.doc') result = {[i for i in x if x[states[x]['module']] in i] for x in functions} raise tornado.gen.Return(result)
def salt_runner(*args, **kwargs): print "In salt_runner" client = LocalClient() t = client.cmd(target, instruction, arg=cmd_arg, timeout=120) if (instruction == "state.sls"): ans = formatter_state(t) else: ans = formatter_raw(t) return ans
def run(self, quiet=False): ''' do all the work note that 'quiet' applies only to remotely run, and the same is true for returning the contents. maybe we want to fix that ''' while True: client = LocalClient() module_args = [self.path, self.batchno, self.batchsize, quiet] result = client.cmd([self.host], "retentionaudit.examine_dir", module_args, expr_form='list', timeout=self.timeout) if self.host in result: lines = result[self.host].split("\n") maxlen = 0 for line in lines: if (line.startswith("WARNING:") or line.startswith("INFO:")): continue else: try: entry = json.loads( line, object_hook=JsonHelper.decode_dict) if len(entry['path']) > maxlen: maxlen = len(entry['path']) except: continue if not quiet: for line in lines: if (line.startswith("WARNING:") or line.startswith("INFO:")): print line else: try: entry = json.loads( line, object_hook=JsonHelper.decode_dict) EntryInfo.display_from_dict( entry, True, maxlen) except: print line return result[self.host] else: print "Failed to retrieve dir content for", self.path, "on", self.host continuing = ("Try again? Y/N [N]: ") if continuing == "": continuing = "N" if continuing.upper() != "Y": return None
def system(hostname): try: local = LocalClient() sys = local.cmd(hostname,'grains.item',['kernel']) if sys[hostname]['kernel'] == 'Linux': return 'linux' elif sys[hostname]['kernel'] == 'Windows': return 'windows' except Exception,e: print e
def install_zfs(cls, data): client = LocalClient() subprocess.call(["mkdir", "-p", "/srv/salt"]) subprocess.call(["mv", "%(app_root)s/application/utils/install_zfs.sh" % {'app_root': CONFIGS['APP_ROOT']}, "/srv/salt/"]) response = client.cmd(data['Storage-Node'], "cmd.script", ["salt://install_zfs.sh"]) return response
def run_cmd(command, retcodes=[0], **kwargs): from salt.client import LocalClient global salt_client if not salt_client: salt_client = LocalClient() res = salt_client.cmd('*', 'cmd.run', [command], full_return=True) if retcodes: for _id, _res in res.items(): assert _res['retcode'] in retcodes return res
def get_openvpn_users(): """ description: Gets openvpn users and current status. Then merges users to find currently active ones and their usage data. output: active: - test_user revoked: - test_user_2 status: {} visible: True """ cl = LocalClient() openvpn_users = call_master_cmd('openvpn.list_users') if type(openvpn_users) == str: raise Exception( "Could not get openvpn users list. Contact your administrator for more information. " ) #openvpn_users returns {"revoked" : [list, of, revoked, users], "active" : [list, of, active, users], "status" : {"client_list" : [], "routing_table" : []}} #We want to convert it to {"revoked" : [], "status" : [client, list], active" : [{"name" : "", "check" : False, "connected" : True/False}]} users = {'revoked': openvpn_users['revoked']} users_names = [ i['Common Name'] for i in openvpn_users['status']['client_list'] ] users['active'] = [{ 'name': x, 'check': False, 'connected': x in users_names } for x in openvpn_users['active']] users['status'] = openvpn_users['status']['client_list'] or [] #Virtual address is missing from client_list, we have to find it in the routing table and update it. for x in openvpn_users['status']['client_list']: x.update({ 'Real Address': [ y.get('Virtual Address') for y in openvpn_users['status']['routing_table'] if y['Real Address'] == x['Real Address'] ][0] }) #Make bytes human readable for k in ['Bytes Received', 'Bytes Sent']: for x in openvpn_users['status']['client_list']: x[k] = bytes_to_readable(x[k]) raise tornado.gen.Return(users)
def call_master_cmd(fun, arg=[], kwarg={}): ''' Calls the salt function on the va-master. Used to work with salt-call but a recent salt version made it incompatible with tornado, so we resort to using the `role` grain to find the va-master and call the function that way. ''' cl = LocalClient() result = cl.cmd('G@role:va-master', fun=fun, tgt_type='compound', arg=arg, kwarg=kwarg) result = [result[i] for i in result if result[i]] if not result: raise Exception('Tried to run ' + str(fun) + ' on va-master, but there was no response. arg was ' + str(arg) + ' and kwarg was ' + str(kwarg)) return result[0]
def tick(self): """ For walltime-based monitoring of running requests. Long-running requests get a periodic call to saltutil.running to verify that things really are still happening. """ if not self._by_jid: return else: log.debug("RequestCollection.tick: %s JIDs underway" % len(self._by_jid)) # Identify JIDs who haven't had a saltutil.running reponse for too long. # Kill requests in a separate phase because request:JID is not 1:1 stale_jobs = set() _now = now() for request in self._by_jid.values(): if _now - request.alive_at > datetime.timedelta( seconds=TICK_PERIOD * 3): log.error("Request %s JID %s stale: now=%s, alive_at=%s" % (request.id, request.jid, _now, request.alive_at)) stale_jobs.add(request) # Any identified stale jobs are errored out. for request in stale_jobs: with self._update_index(request): request.set_error("Lost contact") request.jid = None request.complete() # Identify minions associated with JIDs in flight query_minions = set() for jid, request in self._by_jid.items(): query_minions.add(request.minion_id) # Attempt to emit a saltutil.running to ping jobs, next tick we # will see if we got updates to the alive_at attribute to indicate non-staleness if query_minions: log.info("RequestCollection.tick: sending saltutil.running to {0}". format(query_minions)) client = LocalClient(config.get('cthulhu', 'salt_config_path')) pub_data = client.run_job(list(query_minions), 'saltutil.running', [], expr_form="list") if not pub_data: log.warning("Failed to publish saltutil.running to {0}".format( query_minions))
def get_salt_functions(): cl = LocalClient() salt_functions = cl.cmd('G@role:va-master', fun='va_utils.get_documented_module_functions', tgt_type='compound') salt_functions = salt_functions.items()[0][1] print('Salt : ', salt_functions) salt_functions = { method: [[function[0], yaml.load(function[1])] for function in salt_functions[method] if function_is_documented(function[1], func_name=function[0])] for method in salt_functions } return salt_functions
def run(self): ''' do all the work ''' client = LocalClient() module_args = [self.path, self.num_lines] result = client.cmd([self.host], "retentionaudit.examine_file", module_args, expr_form='list', timeout=self.timeout) if self.host in result: if not self.quiet: print result[self.host] return result[self.host]
def _submit(self, commands): self.log.debug("Request._submit: %s/%s/%s" % (self._minion_id, self._cluster_name, commands)) client = LocalClient(config.get('cthulhu', 'salt_config_path')) pub_data = client.run_job(self._minion_id, 'ceph.rados_commands', [self._fsid, self._cluster_name, commands]) if not pub_data: # FIXME: LocalClient uses 'print' to record the # details of what went wrong :-( raise PublishError("Failed to publish job") self.log.info("Request %s started job %s" % (self.id, pub_data['jid'])) self.alive_at = now() self.jid = pub_data['jid'] return self.jid
def restart_infra_impl(infra_name, target_server): # check if infra is supported if infra_name not in supported_infra: raise NoSuchInfrastructureException('', 1) logger.info('restart infra:%s on %s' % (infra_name, target_server)) sls_arg = supported_infra[infra_name] # send saltstack cmd to restart infra client = LocalClient() client.cmd(target_server, 'state.apply', [sls_arg]) # check if the infrastructure is up if not check_module_is_up(target_server, infra_name): raise InfraIsNotUpException(infra_name) logger.info('restart infra:%s on %s success' % (infra_name, target_server))
def get_opts(self, region=None, group=None): if not os.path.exists("/tmp/salt/"): os.mkdir("/tmp/salt/") if not os.path.exists("/tmp/salt/cache"): os.mkdir("/tmp/salt/cache") if not os.path.exists("/tmp/salt/run"): os.mkdir("/tmp/salt/run") if not os.path.exists("/tmp/salt/run/master"): os.mkdir("/tmp/salt/run/master") mopts = {} mopts["cachedir"] = "/tmp/salt/cache" mopts["sock_dir"] = "/tmp/salt/run/master" mopts["transport"] = "zeromq" mopts["extension_modules"] = "" mopts["file_roots"] = {} lc = LocalClient(mopts=mopts) opts = lc.opts opts["parallel"] = True opts["pki_dir"] = pki_dir opts["extension_modules"] = "" opts["cachedir"] = "/tmp/salt/cloud" opts['log_level'] = "debug" opts['log_level_logfile'] = "debug" opts["log_file"] = log_file opts["update_cachedir"] = False opts["log_file"] = log_file opts["log_level_logfile"] = "debug" opts["log_file"] = log_file opts['providers'] = {} if self.cloud == "azure": if region: self.provider_opts['location'] = region if group: self.provider_opts['resource_group'] = group opts['providers'] = { self.provider: { 'azurearm': self.provider_opts } } elif self.cloud == "vmware": opts['providers'] = {self.provider: {'vmware': self.provider_opts}} elif self.cloud == "aws": opts['providers'] = {} return opts
def getServices(request): action = request.POST.get('action') data = request.POST.getlist('id') username = request.user saltCmd = LocalClient() result = [] ip = request.META['REMOTE_ADDR'] for v in data: goName,host = v.split(',') getMes = saltCmd.cmd('%s'%host,'cmd.run',['supervisorctl %s %s'% (action,goName)]) result.append(getMes) info = action + ' ' + goName dingding_robo(host,info,getMes,username,request.POST['phone_number']) logs(username,ip,'%s services' % action,result) return render(request,'getdata.html',{'result':result})
def cancel(self, request_id): """ Immediately mark a request as cancelled, and in the background try and cancel any outstanding JID for it. """ request = self._by_request_id[request_id] with self._update_index(request): request.set_error("Cancelled") request.complete() if request.jid: client = LocalClient(config.get('cthulhu', 'salt_config_path')) client.run_job(request.minion_id, 'saltutil.kill_job', [request.jid]) # We don't check for completion or errors from kill_job, it's a best-effort thing. If we're # cancelling something we will do our best to kill any subprocess but can't # any guarantees because running nodes may be out of touch with the calamari server. request.jid = None
def get_local_client(cfgdir=None, cfg=None, conn=None, **kwargs): ''' Get a local client cfgdir/cfg args given to localclient ''' if isinstance(conn, LocalClient): return conn kw = {} if cfgdir: kw['cfgdir'] = cfgdir if cfg: kw['cfg'] = cfg key = '{0}_{1}'.format(cfgdir, cfg) if key not in _CLIENTS: _CLIENTS[key] = LocalClient(mopts=_master_opts(**kw)) return _CLIENTS[key]
def do_macro(registry, user, instruction, match): macro = match.group('target') if (macro not in deployments.keys()): return { 'success': False, 'answer': "I don't currently know about %s" % macro } tgt = deployments[macro] print "Starting macro %s" % macro client = LocalClient() t = client.cmd(tgt['target'], tgt['instruction'], arg=tgt['arg'], timeout=120) if (tgt['instruction'] == "state.sls"): ans = formatter_state(t) else: ans = formatter_raw(t) return {'success': True, 'answer': ans}
def run(self): try: from salt.client import LocalClient client = LocalClient(c_path=get_config().getstring( 'salt', 'master_config_path', '/etc/salt/master')) try: log.debug('Running action against "%s": %s args: %s', self.hostname, self.action, self.args) data = client.cmd(self.hostname, self.action, arg=self.args) except SystemExit as e: log.error('Failed action %s on host: %s (%s)', self.action, self.hostname, e) self.q.put(cPickle.dumps({})) else: pdata = cPickle.dumps(data) self.q.put(pdata) except Exception as e: log.err(system='salt-local') self.q.put(cPickle.dumps({'_error': e}))
def do_run(cmd, channel, body): # {'cid': 'blahblah', 'target': '*', 'instruction': 'test.ping', cmd_arg: ['']} try: cmd_arg = body.get('cmd_arg', ()) instruction = body.get('instruction', 'test.ping') target = body.get('target', '*') client = LocalClient() t = client.cmd(target, instruction, arg=cmd_arg, timeout=240) if (instruction == "state.sls"): ans = formatter_state(t) else: ans = formatter_raw(t) result = {'cid': body.get('cid', None), 'result': ans} zmq_sock.send_multipart('MSG', 'input/salt/run', json.dumps(result)) except: traceback.print_exc(None) result = { 'cid': body.get('cid', None), 'result': 'An exception occurred' } zmq_sock.send_multipart('MSG', 'input/salt/run', json.dumps(result))
def server_list(): try: linux_k_list=[] local = LocalClient() for item in hostname('/etc/salt/pki/master/minions'): sys = local.cmd(item, 'grains.item', ['kernel']) if sys[item]['kernel'] == 'Linux': for k,v in sys.items(): linux_k = unicode.encode(k) #os_list_path = os.path.abspath(os.path.dirname(os.getcwd()) + os.path.sep + ".." + os.path.sep + "data") os_list_path = os.path.abspath(os.getcwd() + os.path.sep + "data") os_list_file_linux = os.path.join(os_list_path,"linux_list.txt") f = open(os_list_file_linux,'a') f.write("|") f.write(linux_k) f.close() elif sys[item]['kernel'] == 'Windows': pass else: print 'other os' except Exception,e: print e