def do_stop(): try: (code, r) = get_opsbro_local('/stop') except get_request_errors() as exp: logger.error(exp) return cprint(r, color='green')
def do_docker_show(): d = get_opsbro_json('/docker/stats') scontainers = d.get('containers') simages = d.get('images') print_info_title('Docker Stats') if not scontainers: cprint("No running containers", color='grey') for (cid, stats) in scontainers.items(): print_info_title('Container:%s' % cid) keys = stats.keys() keys.sort() e = [] for k in keys: sd = stats[k] e.append((k, sd['value'])) # Normal agent information print_2tab(e, capitalize=False, col_size=30) for (cid, stats) in simages.items(): print_info_title('Image:%s (sum)' % cid) keys = stats.keys() keys.sort() e = [] for k in keys: sd = stats[k] e.append((k, sd['value'])) # Normal agent information print_2tab(e, capitalize=False, col_size=30)
def do_compliance_state(compliance_name=''): uri = '/compliance/state' try: (code, r) = get_opsbro_local(uri) except get_request_errors() as exp: logger.error(exp) return try: compliances = jsoner.loads(r) except ValueError as exp: # bad json logger.error('Bad return from the server %s' % exp) return print_h1('Compliances') packs = {} for (cname, compliance) in compliances.items(): if compliance_name and compliance['name'] != compliance_name: continue pack_name = compliance['pack_name'] if pack_name not in packs: packs[pack_name] = {} packs[pack_name][cname] = compliance pnames = list(packs.keys()) # python3 pnames.sort() for pname in pnames: pack_entries = packs[pname] cprint('* Pack %s' % pname, color='blue') cnames = list(pack_entries.keys()) # python3 cnames.sort() for cname in cnames: cprint(' - %s' % pname, color='blue', end='') compliance = pack_entries[cname] __print_compliance_entry(compliance)
def do_detect_list(): try: (code, r) = get_opsbro_local('/agent/detectors') except get_request_errors() as exp: logger.error(exp) return try: d = jsoner.loads(r) except ValueError as exp: # bad json logger.error('Bad return from the server %s' % exp) return print_info_title('Detectors') logger.debug(str(d)) e = [] d = sorted(d, key=lambda i: i['name']) for i in d: # aligne name too name = '%-20s' % i['name'].split('/')[-1] groups = i['add_groups'] # align pack level pack_level = '%-6s' % i['pack_level'] # Aligne pack name pack_name = '%-10s' % i['pack_name'] print_element_breadcumb(pack_name, pack_level, 'detector', name, set_pack_color=True) cprint('') cprint(' if: ', color='grey', end='') cprint(i['apply_if'], color='green') cprint(' add groups: ', color='grey', end='') cprint(','.join(groups), color='magenta')
def do_detect_history(): uri = '/agent/detectors/history' try: (code, r) = get_opsbro_local(uri) except get_request_errors() as exp: logger.error(exp) return try: histories = jsoner.loads(r) except ValueError as exp: # bad json logger.error('Bad return from the server %s' % exp) return print_h1('Detected groups history for this node') for history in histories: epoch = history['date'] # We want only group type events entries = [entry for entry in history['entries'] if entry['type'] in ('group-add', 'group-remove')] if not entries: continue print_h2(' Date: %s ' % time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime(epoch))) for entry in entries: _type = entry['type'] op = {'group-add': '+', 'group-remove': '-'}.get(_type, '?') color = {'group-add': 'green', 'group-remove': 'red'}.get(_type, 'grey') cprint(' %s %s' % (op, entry['group']), color=color)
def _compute_stats(self): self._reset_stats() for (node_uuid, manager) in ALL_NODES.items(): raft_node = manager.raft_node state = raft_node._state cprint("Node: %s is %s" % (node_uuid, state)) if state not in self.stats: self.stats[state] = 0 self.stats[state] += 1 # Save candidate votes if state == 'candidate': self.stats['votes'][node_uuid] = raft_node._nb_vote_received # Display election turns election_turn = raft_node._election_turn if election_turn not in self.stats['election_turn']: self.stats['election_turn'][election_turn] = 0 self.stats['election_turn'][election_turn] += 1 # and frozen number # if n.frozen_number not in self.stats['frozen_number']: # self.stats['frozen_number'][n.frozen_number] = 0 # self.stats['frozen_number'][n.frozen_number] += 1 # self.stats['is_frozen'][n.is_frozen] += 1 self.stats['with_leader'][(raft_node._leader is not None)] += 1
def do_dashboards_show(dashboard_name, occurences): import codecs stdout_utf8 = codecs.getwriter("utf-8")(sys.stdout) sys.stdout = stdout_utf8 from opsbro.dashboardmanager import get_dashboarder dashboarder = get_dashboarder() dashboard = dashboarder.dashboards.get(dashboard_name, None) if dashboard is None: logger.error( 'There is no such dashboard %s. Please use the dashboards list command to view all available dashboards' % dashboard_name) sys.exit(2) ui = _get_ui_from_dashboard(dashboard) if ui is None: sys.exit(1) i = 0 while True: try: ui.display(dashboard['title']) time.sleep(10) except KeyboardInterrupt: # Clean the screen before exiting cprint('\033c') return if occurences != 0 and i > occurences: return i += 1
def test_encryption(self): cprint("ENCRYPTER: %s" % encrypter) orig_test = 'Hi I am Alice' bobread = encrypter.encrypt(orig_test) clear = encrypter.decrypt(bobread) cprint('CLEAN: %s' % clear) self.assert_(clear == orig_test)
def do_node_uuid(): try: d = get_opsbro_json('/agent/info') except get_request_errors() as exp: logger.error('Cannot join opsbro agent for info: %s' % exp) sys.exit(1) _uuid = d.get('uuid') cprint(_uuid)
def do_node_public_addr(): try: d = get_opsbro_json('/agent/info') except get_request_errors() as exp: logger.error('Cannot join opsbro agent for info: %s' % exp) sys.exit(1) public_addr = d.get('public_addr') cprint(public_addr)
def do_follow_log(part=''): if not part: return try: import fcntl except ImportError: cprint("Error: this action is not availabe on your OS.") return cprint('Try to follow log part %s' % part) p = '/tmp/opsbro-follow-%s' % part # Clean fifo to be sure to clean previous runs if os.path.exists(p): os.unlink(p) if not os.path.exists(p): os.mkfifo(p) colors = { 'DEBUG': 'magenta', 'INFO': 'blue', 'WARNING': 'yellow', 'ERROR': 'red' } try: w = 0.001 while True: with open(p, 'rb', 0) as fifo: fd = fifo.fileno() flag = fcntl.fcntl(fd, fcntl.F_GETFD) fcntl.fcntl(fd, fcntl.F_SETFL, flag | os.O_NONBLOCK) while True: try: data = fifo.read() except IOError: w *= 2 w = min(w, 0.1) time.sleep(w) continue if len(data) == 0: break w = 0.001 for line in data.splitlines(): already_print = False for (k, color) in colors.items(): if k in line: cprint(line, color=color) already_print = True break if not already_print: cprint(line) finally: try: cprint("\nDisabling log dumping for the part %s" % part) os.unlink(p) except: pass
def __print_pack_breadcumb(pack_name, pack_level, end='\n', topic_picto='large'): cprint(__get_pack_breadcumb(pack_name, pack_level, end=end, topic_picto=topic_picto), end='')
def _display(self, tbox, parent): self._refresh_value() self.title = self.title_orig + (': %d %s' % (self.value, self.unit)) tbox = self._draw_borders_and_title(tbox) self._jump_to(tbox.x, tbox.y) value_ratio = max(0, min(1, self.value / 100.0)) bar = HBarPrinter().get_hbar(value_ratio, tbox.w) cprint(bar, end='')
def do_agent_parameters_get(parameter_name): parameters_file_path = DEFAULT_CFG_FILE yml_parameter_get(parameters_file_path, parameter_name, file_display='agent.%s' % parameter_name) cprint( 'NOTE: only the yml configuration file is modified. You need to restart your agent to use this modification', color='grey') return
def do_list_follow_log(): try: parts = get_opsbro_json('/log/parts/') except get_request_errors() as exp: logger.error('Cannot join opsbro agent to list logs: %s' % exp) sys.exit(1) parts.sort() cprint("Available parts to follow logs:") for p in parts: cprint(" * %s" % p)
def test_cgroup(self): if self.con is None: return cprint(self.conts) cids = [c['Id'] for c in self.conts] print('CIDS: %s' % cids) metrics = cgroupmgr.get_containers_metrics(cids) cprint("METRICS: %s" % metrics)
def do_evaluator_eval(expr): expr = string_encode(expr) expr_64 = base64.b64encode(expr) try: r = post_opsbro_json('/agent/evaluator/eval', {'expr': expr_64}, timeout=30) except Exception as exp: logger.error(exp) sys.exit(2) print_info_title('Result') cprint(r)
def do_kv_store_list(): expr_64 = base64.b64encode(expr) try: r = post_opsbro_json('/agent/evaluator/eval', {'expr': expr_64}, timeout=30) except get_request_errors() as exp: logger.error(exp) return print_info_title('Result') cprint(r)
def do_kv_store_get(key_name): try: (code, value) = get_opsbro_local('/kv/%s' % key_name) except get_request_errors() as exp: logger.error('Cannot join opsbro agent for info: %s' % exp) sys.exit(1) if code == 404: cprint('ERROR: the key %s does not exist' % key_name, color='red') sys.exit(2) value = bytes_to_unicode(value) cprint("%s::%s" % (key_name, value))
def __print_collector_state(collector): state = collector['state'] log = collector['log'] name = collector['name'] color = COLLECTORS_STATE_COLORS.get(state) cprint(' - ', end='') cprint('%s' % name.ljust(20), color='magenta', end='') cprint(' %s ' % CHARACTERS.arrow_left, end='') cprint(state, color=color) if log: cprint(' | %s' % log, color='grey')
def _display(self, tbox, parent): self._refresh_value() tbox = self._draw_borders_and_title(tbox) dx = 0 for dx, line in enumerate(self.text.splitlines()): self._jump_to(tbox.x + dx, tbox.y) cprint(line + ' ' * (tbox.w - len(line)), color='white', end='') dx += 1 while dx < tbox.h: self._jump_to(tbox.x + dx, tbox.y) cprint(' ' * tbox.w, end='') dx += 1
def do_agent_parameters_set(parameter_name, str_value): if parameter_name in list_type_parameters: cprint( 'Error: the parameter %s is a list. Cannot use the set. Please use add/remove instead' % parameter_name) sys.exit(2) parameters_file_path = DEFAULT_CFG_FILE yml_parameter_set(parameters_file_path, parameter_name, str_value, file_display='agent.%s' % parameter_name) return
def do_zone_change(name=''): if not name: cprint("Need a zone name") return cprint("Switching to zone", name) try: r = put_opsbro_json('/agent/zone', name) except get_request_errors() as exp: logger.error(exp) return print_info_title('Result') print(r)
def compute_stats(self): self.stats = { 'votes': {}, 'election_turn': {}, 'frozen_number': {}, 'is_frozen': { True: 0, False: 0 }, 'with_leader': { True: 0, False: 0 } } for d in self.nodes: n = d['node'] # s = n.state states_values_base = { 'did-vote': 1, 'leader': 2, 'follower': 3, 'candidate': 4, 'wait_for_candidate': 5, 'leaved': 6 } states_values = {} for (k, v) in states_values_base.items(): states_values[v] = k s = states_values.get(n.export_state.value) cprint("NODE EXPORT STATE: %s => %s(%s)" % (n.i, n.export_state.value, s)) if s not in self.stats: self.stats[s] = 0 self.stats[s] += 1 # Save candidate votes if n.state == 'candidate': self.stats['votes'][n.i] = n.nb_vote # Display election turns if n.election_turn not in self.stats['election_turn']: self.stats['election_turn'][n.election_turn] = 0 self.stats['election_turn'][n.election_turn] += 1 # and frozen number if n.frozen_number not in self.stats['frozen_number']: self.stats['frozen_number'][n.frozen_number] = 0 self.stats['frozen_number'][n.frozen_number] += 1 self.stats['is_frozen'][n.is_frozen] += 1 self.stats['with_leader'][(n.leader is not None)] += 1
def do_evaluator_list(details=False): try: (code, r) = get_opsbro_local('/agent/evaluator/list') except get_request_errors() as exp: logger.error(exp) return try: d = jsoner.loads(r) except ValueError as exp: # bad json logger.error('Bad return from the server %s' % exp) return # Group by groups = {} for f in d: fname = f['name'] gname = f['group'] if gname not in groups: groups[gname] = {} groups[gname][fname] = f gnames = groups.keys() gnames.sort() for gname in gnames: print_h1(gname) group_functions = groups[gname] fnames = group_functions.keys() fnames.sort() for fname in fnames: f = group_functions[fname] prototype = f['prototype'] doc = f['doc'] cprint(fname, color='green', end='') cprint('(', end='') if prototype: _s_args = [] for arg in prototype: kname = arg[0] def_value = arg[1] if def_value != '__NO_DEFAULT__': _s_args.append('%s=%s' % (kname, def_value)) else: _s_args.append('%s' % kname) cprint(', '.join(_s_args), color='yellow', end='') cprint(')') if details: cprint(doc, color='grey')
def do_zone_key_import(zone, key, erase=False): from opsbro.defaultpaths import DEFAULT_CFG_DIR from opsbro.configurationmanager import ZONE_KEYS_DIRECTORY_NAME from opsbro.encrypter import GOSSIP_KEY_FILE_FORMAT key_path = os.path.join(DEFAULT_CFG_DIR, ZONE_KEYS_DIRECTORY_NAME, GOSSIP_KEY_FILE_FORMAT % zone) if os.path.exists(key_path) and not erase: cprint('ERROR: the key %s is already existing', color='red') cprint( ' %s Note: You can use the --erase parameter to erase over an existing key' % (CHARACTERS.corner_bottom_left), color='grey') sys.exit(2) # check key is base64(len16) try: raw_key = base64.b64decode(key) except TypeError: # bad key cprint('ERROR: the key is not valid. (not base4 encoded)', color='red') sys.exit(2) if len(raw_key) != 16: cprint('ERROR: the key is not valid. (not 128bits)', color='red') sys.exit(2) # Note: key is the original b64 encoded one, we did check it _save_key(key, zone, key_path)
def _save_key(key_string, zone_name, key_path): with open(key_path, 'wb') as f: f.write(unicode_to_bytes(key_string)) cprint('%s OK the key is saved as file %s' % (CHARACTERS.check, key_path)) # Try to send the information to the agent, so it can reload the key try: get_opsbro_json('/agent/zones-keys/reload/%s' % zone_name) except get_request_errors(): cprint( ' | The agent seems to not be started. Skipping hot key reload.', color='grey') return
def do_tutorials_list(): from opsbro.tutorial import tutorialmgr tutorials = tutorialmgr.tutorials print_h1('Tutorials') if len(tutorials) == 0: cprint('No tutorials', color='grey') sys.exit(0) packs = {} for tutorial in tutorials: tutorial_name = tutorial.name pack_name = tutorial.pack_name if pack_name not in packs: packs[pack_name] = {} packs[pack_name][tutorial_name] = tutorial pnames = list(packs.keys()) pnames.sort() for pname in pnames: pack_entries = packs[pname] tnames = list(pack_entries.keys()) tnames.sort() for tname in tnames: tutorial = pack_entries[tname] duration = ceil(tutorial.get_duration()) level = tutorial.pack_level __print_pack_breadcumb(pname, level, end='', topic_picto='small') cprint(' %-20s ' % tname, color='magenta', end='') cprint(' (Duration: %ds) ' % duration, end='') cprint(tutorial.title, color='grey')
def do_agent_parameters_remove(parameter_name, str_value): if parameter_name not in list_type_parameters: cprint( 'Error: the parameter %s is not a list. Cannot use the add/remove. Please use set instead' % parameter_name) sys.exit(2) parameters_file_path = DEFAULT_CFG_FILE yml_parameter_remove(parameters_file_path, parameter_name, str_value, file_display='agent.%s' % parameter_name) # Groups is a bit special as it can be load directly by the agent if parameter_name == 'groups': try: did_change = get_opsbro_json('/agent/parameters/remove/groups/%s' % str_value) except get_request_errors(): cprint( ' | The agent seems to not be started. Skipping hot group removing.', color='grey') return if did_change: cprint( " | The agent groups are updated too. You don't need to restart your daemon.", color='grey') return cprint( 'NOTE: only the yml configuration file is modified. You need to restart your agent to use this modification', color='grey') return
def do_tutorial_show(tutorial_name): from opsbro.tutorial import tutorialmgr tutorials = tutorialmgr.tutorials tutorial = None for tuto in tutorials: if tuto.name == tutorial_name: tutorial = tuto break if tutorial is None: logger.error('Cannot find the tutorial %s' % tutorial_name) sys.exit(2) tuto_data = tutorial.get_tutorial_data() stdout_entries = tuto_data['stdout'] cprint('\n\nTutorial is starting:', color='magenta') cprint(' | please note that is is only a screencast and nothing will be executed or changed in your system.\n\n', color='grey') for e in stdout_entries: wait_time = e[0] line = e[1] time.sleep(wait_time) cprint(line, end='') sys.stdout.flush() cprint('\n\nTutorial is ended', color='magenta')