def Dependencies(tools): """ Takes in a list of tools that are being updated and returns any tools that depend on linking to them """ dependencies = [] if tools: path_dirs = PathDirs() man = Template(join(path_dirs.meta_dir, 'plugin_manifest.cfg')) for section in man.sections()[1]: # don't worry about dealing with tool if it's not running running = man.option(section, 'running') if not running[0] or running[1] != 'yes': continue t_name = man.option(section, 'name')[1] t_branch = man.option(section, 'branch')[1] t_version = man.option(section, 'version')[1] t_identifier = {'name': t_name, 'branch': t_branch, 'version': t_version} options = man.options(section)[1] if 'docker' in options: d_settings = json.loads(man.option(section, 'docker')[1]) if 'links' in d_settings: for link in json.loads(d_settings['links']): if link in tools: dependencies.append(t_identifier) return dependencies
def DropLocation(): """ Get the directory that file drop is watching """ template = Template(template=PathDirs().cfg_file) drop_loc = template.option('main', 'files')[1] drop_loc = expanduser(drop_loc) drop_loc = abspath(drop_loc) return (True, drop_loc)
def Checkout(path, branch='master', version='HEAD', **kargs): status = (True, None) path_dirs = PathDirs(**kargs) status = path_dirs.apply_path(path) git_stdout = '' if status[0]: try: git_stdout += check_output(shlex.split('git checkout ' + branch), stderr=STDOUT, close_fds=True).decode('utf-8') git_stdout += check_output(shlex.split('git pull origin ' + version), stderr=STDOUT, close_fds=True).decode('utf-8') if version: git_stdout += check_output(shlex.split('git reset --hard ' + version), stderr=STDOUT, close_fds=True).decode('utf-8') chdir(status[1]) except Exception as e: # pragma: no cover if str(e).endswith('exit status 128.'): status = (True, 'Repo has already been checked out.') else: logger.error('Checkout failed with error: {0} {1}'.format( str(e), git_stdout)) status = (False, str(e)) return status
def __init__(self, **kargs): self.path_dirs = PathDirs(**kargs) self.manifest = join(self.path_dirs.meta_dir, 'plugin_manifest.cfg') self.p_helper = PluginHelper(**kargs) self.d_client = docker.from_env() self.logger = Logger(__name__) self.plugin_config_file = self.path_dirs.plugin_config_file
def Tools(**kargs): """ Get tools that exist in the manifest """ path_dirs = PathDirs(**kargs) manifest = os.path.join(path_dirs.meta_dir, "plugin_manifest.cfg") template = Template(template=manifest) tools = template.sections() return tools[1]
def test_file_queue(): """ Tests simulation of new file """ path_dirs = PathDirs() images = file_watch.file_queue('/tmp/foo') assert images[0] == False images = file_watch.file_queue('host_/tmp/foo', template_path=path_dirs.base_dir) assert images[0] == True assert type(images[1]) == list
def __init__(self, *args, **kwargs): self.d_client = docker.from_env() self.path_dirs = PathDirs(**kwargs) self.manifest = join(self.path_dirs.meta_dir, 'plugin_manifest.cfg') self.vent_config = self.path_dirs.cfg_file self.startup_file = self.path_dirs.startup_file self.logger = Logger(__name__) self._auto_install()
def Core(branch="master", **kargs): """ Get the normal core tools, and the currently installed/built/running ones, including custom core services """ # !! TODO this might need to store namespaces/branches/versions core = {'built':[], 'running':[], 'installed':[], 'normal':[]} # get normal core tools plugins = Plugin(plugins_dir=".internals/plugins") status, cwd = plugins.clone('https://github.com/cyberreboot/vent') if status: plugins.version = 'HEAD' plugins.branch = branch response = plugins.checkout() matches = plugins._available_tools(groups='core') for match in matches: core['normal'].append(match[0].split('/')[-1]) else: core['normal'] = 'failed' # get core tools that have been installed path_dirs = PathDirs(**kargs) manifest = os.path.join(path_dirs.meta_dir, "plugin_manifest.cfg") template = Template(template=manifest) tools = template.sections() if tools[0]: for tool in tools[1]: groups = template.option(tool, "groups") if groups[0] and "core" in groups[1]: name = template.option(tool, "name") if name[0]: core['installed'].append(name[1]) # get core tools that have been built and/or are running try: d_client = docker.from_env() images = d_client.images.list() for image in images: try: if "vent.groups" in image.attrs['Labels'] and 'core' in image.attrs['Labels']['vent.groups']: if 'vent.name' in image.attrs['Labels']: core['built'].append(image.attrs['Labels']['vent.name']) except Exception as err: # pragma: no cover pass containers = d_client.containers.list() for container in containers: try: if "vent.groups" in container.attrs['Config']['Labels'] and 'core' in container.attrs['Config']['Labels']['vent.groups']: if 'vent.name' in container.attrs['Config']['Labels']: core['running'].append(container.attrs['Config']['Labels']['vent.name']) except Exception as err: # pragma: no cover pass except Exception as e: # pragma: no cover pass return core
def run_menu(test_input): """ Actually run the menu and process any input """ # initialize tutorial paths = PathDirs() first_time = paths.ensure_file(paths.init_file) assert first_time[0] == True npyscreen.TEST_SETTINGS['TEST_INPUT'] = test_input A = VentApp() try: A.run(fork=False) except npyscreen.ExhaustedTestInput as e: pass
def Logger(name, **kargs): """ Create and return logger """ path_dirs = PathDirs(**kargs) logging.captureWarnings(True) logger = logging.getLogger(name) logger.setLevel(logging.INFO) handler = logging.handlers.WatchedFileHandler( os.path.join(path_dirs.meta_dir, "vent.log")) handler.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - ' '%(message)s') handler.setFormatter(formatter) if not len(logger.handlers): logger.addHandler(handler) return logger
def __init__(self, version='HEAD', branch='master', user=None, pw=None, *args, **kwargs): self.version = version self.branch = branch self.user = user self.pw = pw self.d_client = docker.from_env() self.path_dirs = PathDirs(**kwargs) self.path_dirs.host_config() self.manifest = join(self.path_dirs.meta_dir, 'plugin_manifest.cfg') self.logger = Logger(__name__)
def test_file_queue(): """ Tests simulation of new file """ path_dirs = PathDirs() images = file_queue('/tmp/foo') assert not images[0] images = file_queue('host_/tmp/foo', template_path=path_dirs.base_dir, r_host='localhost') assert isinstance(images, tuple) assert images[0] assert isinstance(images[1], list) images = file_queue('host_/tmp/foo.matrix', template_path=path_dirs.base_dir, r_host='localhost') assert isinstance(images, tuple) assert images[0] assert isinstance(images[1], list)
def Checkout(path, branch='master', version='HEAD', **kargs): status = (True, None) path_dirs = PathDirs(**kargs) status = path_dirs.apply_path(path) if status[0]: try: check_output(shlex.split('git checkout ' + branch), stderr=STDOUT, close_fds=True).decode('utf-8') check_output(shlex.split('git pull origin ' + version), stderr=STDOUT, close_fds=True).decode('utf-8') if version: check_output(shlex.split('git reset --hard ' + version), stderr=STDOUT, close_fds=True).decode('utf-8') chdir(status[1]) except Exception as e: # pragma: no cover logger.error( 'Checkout failed with error: {0}'.format(str(e))) status = (False, str(e)) return status
def test_jobs(): """ Test the jobs function """ jobs = Jobs() assert isinstance(jobs, tuple) path = PathDirs() status = path.host_config() assert isinstance(status, tuple) assert status[0] # run test job with open('/opt/vent_files/foo.matrix', 'w') as f: f.write('24,23\n10,22') pcap = 'https://s3.amazonaws.com/tcpreplay-pcap-files/test.pcap' r = requests.get(pcap, stream=True) if r.status_code == 200: with open('/opt/vent_files/foo.pcap', 'wb') as f: r.raw.decode_content = True shutil.copyfileobj(r.raw, f) services = Services(True) assert isinstance(services, list) jobs = Jobs() assert isinstance(jobs, tuple)
def test_jobs(): """ Test the jobs function """ jobs = Jobs() assert isinstance(jobs, tuple) path = PathDirs() status = path.host_config() assert isinstance(status, tuple) assert status[0] m_helper = MenuHelper() status = m_helper.cores('install') assert isinstance(status, tuple) assert status[0] status = m_helper.cores('build') assert isinstance(status, tuple) assert status[0] status = m_helper.cores('start') assert isinstance(status, tuple) assert status[0] status = m_helper.api_action.add( 'https://github.com/cyberreboot/vent-plugins', tools=[('tcpdump_hex_parser', ''), ('gpu_example', '')]) assert isinstance(status, tuple) assert status[0] # run test job with open('/opt/vent_files/foo.matrix', 'w') as f: f.write('24,23\n10,22') pcap = 'https://s3.amazonaws.com/tcpreplay-pcap-files/test.pcap' r = requests.get(pcap, stream=True) if r.status_code == 200: with open('/opt/vent_files/foo.pcap', 'wb') as f: r.raw.decode_content = True shutil.copyfileobj(r.raw, f) services = Services(True) assert isinstance(services, list) jobs = Jobs() assert isinstance(jobs, tuple)
def test_file_queue(): """ Tests simulation of new file """ path_dirs = PathDirs() images = watch.file_queue('/tmp/foo') assert not images[0] images = watch.file_queue('host_/tmp/foo', template_path=path_dirs.base_dir, r_host="localhost") assert isinstance(images, tuple) assert images[0] assert isinstance(images[1], list) instance = Action() status = instance.add('https://github.com/cyberreboot/vent-plugins', branch='master', tools=[('gpu_example', '')], build=True) assert isinstance(status, tuple) assert status[0] images = watch.file_queue('host_/tmp/foo.matrix', template_path=path_dirs.base_dir, r_host="localhost") assert isinstance(images, tuple) assert images[0] assert isinstance(images[1], list)
def __init__(self, manifest, *args, **kwargs): self.path_dirs = PathDirs(**kwargs) self.manifest = manifest self.d_client = docker.from_env() self.logger = Logger(__name__)
class VentApp(npyscreen.NPSAppManaged): """ Main menu app for vent CLI """ keypress_timeout_default = 10 repo_value = {} paths = PathDirs() first_time = paths.ensure_file(paths.init_file) if first_time[0] and first_time[1] != "exists": npyscreen.NPSAppManaged.STARTING_FORM = "TUTORIALINTRO" else: npyscreen.NPSAppManaged.STARTING_FORM = "MAIN" def onStart(self): """ Override onStart method for npyscreen """ curses.mousemask(0) self.paths.host_config() version = Version() # setup initial runtime stuff if self.first_time[0] and self.first_time[1] != "exists": plugins = Plugin() actions = Action() thr = Thread(target=MainForm.t_status, args=(), kwargs={'core': True}) thr.start() while thr.is_alive(): npyscreen.notify_wait( "Please wait while Vent initializes...1/4", title="Setting up things...") time.sleep(1) thr.join() thr = Thread(target=MainForm.t_status, args=(), kwargs={'core': False}) thr.start() while thr.is_alive(): npyscreen.notify_wait( "Please wait while Vent initializes...2/4", title="Setting up things...") time.sleep(1) thr.join() thr = Thread(target=plugins.auto_install, args=(), kwargs={}) thr.start() while thr.is_alive(): npyscreen.notify_wait( "Please wait while Vent initializes...3/4", title="Setting up things...") time.sleep(1) thr.join() thr = Thread(target=actions.startup, args=(), kwargs={}) thr.start() while thr.is_alive(): npyscreen.notify_wait( "Please wait while Vent initializes...4/4", title="Setting up things...") time.sleep(1) thr.join() quit_s = "\t" * 4 + "^Q to quit" tab_esc = "\t" * 4 + "TAB to close menu popup" self.addForm("MAIN", MainForm, name="Vent " + version + "\t\t\t\t\t^T for help" + quit_s + tab_esc, color="IMPORTANT") self.addForm("HELP", HelpForm, name="Help\t\t\t\t\t\t\t\t^T to toggle previous" + quit_s, color="DANGER") self.addForm("TUTORIALINTRO", TutorialIntroForm, name="Vent Tutorial" + quit_s, color="DANGER") self.addForm("TUTORIALBACKGROUND", TutorialBackgroundForm, name="About Vent" + quit_s, color="DANGER") self.addForm("TUTORIALTERMINOLOGY", TutorialTerminologyForm, name="About Vent" + quit_s, color="DANGER") self.addForm("TUTORIALGETTINGSETUP", TutorialGettingSetupForm, name="About Vent" + quit_s, color="DANGER") self.addForm("TUTORIALBUILDINGCORES", TutorialBuildingCoresForm, name="Working with Cores" + quit_s, color="DANGER") self.addForm("TUTORIALSTARTINGCORES", TutorialStartingCoresForm, name="Working with Cores" + quit_s, color="DANGER") self.addForm("TUTORIALADDINGPLUGINS", TutorialAddingPluginsForm, name="Working with Plugins" + quit_s, color="DANGER") self.addForm("TUTORIALADDINGFILES", TutorialAddingFilesForm, name="Files" + quit_s, color="DANGER") self.addForm("TUTORIALTROUBLESHOOTING", TutorialTroubleshootingForm, name="Troubleshooting" + quit_s, color="DANGER") def change_form(self, name): """ Changes the form (window) that is displayed """ self.switchForm(name)
class VentApp(npyscreen.NPSAppManaged): """ Main menu app for vent CLI """ keypress_timeout_default = 10 repo_value = {} paths = PathDirs() first_time = paths.ensure_file(paths.init_file) if first_time[0] == True and first_time[1] != "exists": npyscreen.NPSAppManaged.STARTING_FORM = "TUTORIALINTRO" else: npyscreen.NPSAppManaged.STARTING_FORM = "MAIN" def add_forms(self): """ Add in forms that will have dynamic data """ self.addForm("COREINVENTORY", CoreInventoryForm, name="Inventory of core tools\t\t\t\t\t\t\t\tPress ^T to toggle main\t\t\t\t\t\tPress ^Q to quit", color="STANDOUT") self.addForm("INVENTORY", InventoryForm, name="Inventory of plugins\t\t\t\t\t\t\t\tPress ^T to toggle main\t\t\t\t\t\tPress ^Q to quit", color="STANDOUT") self.addForm("ADD", AddForm, name="Add\t\t\t\t\t\t\t\tPress ^T to toggle help\t\t\t\t\t\tPress ^Q to quit", color="CONTROL") self.addForm("ADDOPTIONS", AddOptionsForm, name="Set options for new plugin\t\t\t\t\t\tPress ^Q to quit", color="CONTROL") self.addForm("CHOOSETOOLS", ChooseToolsForm, name="Choose tools to add for new plugin\t\t\t\t\t\tPress ^Q to quit", color="CONTROL") self.addForm("SERVICES", ServicesForm, name="Services\t\t\t\t\t\t\t\tPress ^T to toggle main\t\t\t\t\t\tPress ^Q to quit", color="STANDOUT") self.addForm("BUILDTOOLS", BuildToolsForm, name="Build tools\t\t\t\t\t\t\t\tPress ^T to toggle main\t\t\t\t\t\tPress ^Q to quit", color="CONTROL") self.addForm("STARTTOOLS", StartToolsForm, name="Start tools\t\t\t\t\t\t\t\tPress ^T to toggle main\t\t\t\t\t\tPress ^Q to quit", color="CONTROL") self.addForm("STOPTOOLS", StopToolsForm, name="Stop tools\t\t\t\t\t\t\t\tPress ^T to toggle main\t\t\t\t\t\tPress ^Q to quit", color="CONTROL") self.addForm("CLEANTOOLS", CleanToolsForm, name="Clean tools\t\t\t\t\t\t\t\tPress ^T to toggle main\t\t\t\t\t\tPress ^Q to quit", color="CONTROL") self.addForm("BUILDCORETOOLS", BuildCoreToolsForm, name="Build core tools\t\t\t\t\t\t\t\tPress ^T to toggle main\t\t\t\t\t\tPress ^Q to quit", color="CONTROL") self.addForm("STARTCORETOOLS", StartCoreToolsForm, name="Start core tools\t\t\t\t\t\t\t\tPress ^T to toggle main\t\t\t\t\t\tPress ^Q to quit", color="CONTROL") self.addForm("STOPCORETOOLS", StopCoreToolsForm, name="Stop core tools\t\t\t\t\t\t\t\tPress ^T to toggle main\t\t\t\t\t\tPress ^Q to quit", color="CONTROL") self.addForm("CLEANCORETOOLS", CleanCoreToolsForm, name="Clean core tools\t\t\t\t\t\t\t\tPress ^T to toggle main\t\t\t\t\t\tPress ^Q to quit", color="CONTROL") self.addForm("LOGS", LogsForm, name="Logs\t\t\t\t\t\t\t\tPress ^T to toggle main\t\t\t\t\t\tPress ^Q to quit", color="STANDOUT") self.addForm("REMOVETOOLS", RemoveToolsForm, name="Remove tools\t\t\t\t\t\t\t\tPress ^T to toggle help\t\t\t\t\t\tPress ^Q to quit", color="CONTROL") self.addForm("REMOVECORETOOLS", RemoveCoreToolsForm, name="Remove core tools\t\t\t\t\t\t\t\tPress ^T to toggle help\t\t\t\t\t\tPress ^Q to quit", color="CONTROL") self.addForm("UPDATETOOLS", UpdateToolsForm, name="Update tools\t\t\t\t\t\t\t\tPress ^T to toggle help\t\t\t\t\t\tPress ^Q to quit", color="CONTROL") self.addForm("UPDATECORETOOLS", UpdateCoreToolsForm, name="Update core tools\t\t\t\t\t\t\t\tPress ^T to toggle help\t\t\t\t\t\tPress ^Q to quit", color="CONTROL") def remove_forms(self): """ Remove forms that will have dynamic data """ self.removeForm("COREINVENTORY") self.removeForm("INVENTORY") self.removeForm("ADD") self.removeForm("ADDOPTIONS") self.removeForm("CHOOSETOOLS") self.removeForm("SERVICES") self.removeForm("BUILDTOOLS") self.removeForm("STARTTOOLS") self.removeForm("STOPTOOLS") self.removeForm("CLEANTOOLS") self.removeForm("BUILDCORETOOLS") self.removeForm("STARTCORETOOLS") self.removeForm("STOPCORETOOLS") self.removeForm("CLEANCORETOOLS") self.removeForm("LOGS") self.removeForm("REMOVETOOLS") self.removeForm("REMOVECORETOOLS") self.removeForm("UPDATETOOLS") self.removeForm("UPDATECORETOOLS") def onStart(self): """ Override onStart method for npyscreen """ self.paths.host_config() version = Version() self.addForm("MAIN", MainForm, name="Vent "+version+"\t\t\t\t\tPress ^T to toggle help\t\t\t\t\t\tPress ^Q to quit", color="IMPORTANT") self.addForm("HELP", HelpForm, name="Help\t\t\t\t\t\t\t\tPress ^T to toggle previous\t\t\t\t\t\tPress ^Q to quit", color="DANGER") self.addForm("TUTORIALINTRO", TutorialIntroForm, name="Vent Tutorial"+"\t\t\t\t\t\tPress ^Q to quit", color="DANGER") self.addForm("TUTORIALBACKGROUND", TutorialBackgroundForm, name="About Vent"+"\t\t\t\t\t\tPress ^Q to quit", color="DANGER") self.addForm("TUTORIALTERMINOLOGY", TutorialTerminologyForm, name="About Vent"+"\t\t\t\t\t\tPress ^Q to quit", color="DANGER") self.addForm("TUTORIALGETTINGSETUP", TutorialGettingSetupForm, name="About Vent"+"\t\t\t\t\t\tPress ^Q to quit", color="DANGER") self.addForm("TUTORIALBUILDINGCORES", TutorialBuildingCoresForm, name="Working with Cores"+"\t\t\t\t\t\tPress ^Q to quit", color="DANGER") self.addForm("TUTORIALSTARTINGCORES", TutorialStartingCoresForm, name="Working with Cores"+"\t\t\t\t\t\tPress ^Q to quit", color="DANGER") self.addForm("TUTORIALADDINGPLUGINS", TutorialAddingPluginsForm, name="Working with Plugins"+"\t\t\t\t\t\tPress ^Q to quit", color="DANGER") self.addForm("TUTORIALADDINGFILES", TutorialAddingFilesForm, name="Files"+"\t\t\t\t\t\tPress ^Q to quit", color="DANGER") self.addForm("TUTORIALSETTINGUPSERVICES", TutorialSettingUpServicesForm, name="Services"+"\t\t\t\t\t\tPress ^Q to quit", color="DANGER") self.add_forms() def change_form(self, name): """ Changes the form (window) that is displayed """ self.switchForm(name)
def test_pathdirs(): """ Test the pathdirs class """ path = PathDirs() path.host_config()
def test_ensure_file(): """ Test the ensure_file function """ paths = PathDirs() status = paths.ensure_file(paths.init_file) assert isinstance(status, tuple) assert status[0] == True
def create(self): """ Override method for creating FormBaseNewWithMenu form """ try: self.api_action = System() except DockerException as de: # pragma: no cover notify_confirm(str(de), title='Docker Error', form_color='DANGER', wrap=True) MainForm.exit() self.add_handlers({'^T': self.help_form, '^Q': MainForm.exit}) # all forms that can toggle view by group self.view_togglable = ['inventory', 'remove'] ####################### # MAIN SCREEN WIDGETS # ####################### self.addfield = self.add(npyscreen.TitleFixedText, name='Date:', labelColor='DEFAULT', value=Timestamp()) self.addfield2 = self.add(npyscreen.TitleFixedText, name='Uptime:', labelColor='DEFAULT', value=Uptime()) self.cpufield = self.add(npyscreen.TitleFixedText, name='Logical CPUs:', labelColor='DEFAULT', value=Cpu()) self.gpufield = self.add(npyscreen.TitleFixedText, name='GPUs:', labelColor='DEFAULT', value=Gpu()[1]) self.location = self.add(npyscreen.TitleFixedText, name='User Data:', value=PathDirs().meta_dir, labelColor='DEFAULT') self.file_drop = self.add(npyscreen.TitleFixedText, name='File Drop:', value=DropLocation()[1], labelColor='DEFAULT') self.addfield3 = self.add(npyscreen.TitleFixedText, name='Containers:', labelColor='DEFAULT', value='0 ' + ' running') self.multifield1 = self.add(npyscreen.MultiLineEdit, max_height=22, editable=False, value=""" '., 'b * '$ #. $: #: *# @): :@,@): ,.**:' , :@@*: ..**' '#o. .:(@'.@*"' 'bq,..:,@@*' ,* ,p$q8,:@)' .p*' ' '@@Pp@@*' Y7'.' :@):. .:@:'. .::(@:. _ __ _____ _ __ | |_ \ \ / / _ \ '_ \| __| \ V / __/ | | | |_ \_/ \___|_| |_|\__| """) ################ # MENU OPTIONS # ################ # Tool Menu Items self.m3 = self.add_menu(name='Tools', shortcut='p') self.m3.addItem(text='Add New Tool', onSelect=self.perform_action, arguments=['add'], shortcut='a') self.m3.addItem(text='Configure Tools', onSelect=self.perform_action, arguments=['configure'], shortcut='t') self.m3.addItem(text='Inventory', onSelect=self.perform_action, arguments=['inventory'], shortcut='i') self.m3.addItem(text='Remove Tools', onSelect=self.perform_action, arguments=['remove'], shortcut='r') self.m3.addItem(text='Start Tools', onSelect=self.perform_action, arguments=['start'], shortcut='s') self.m3.addItem(text='Stop Tools', onSelect=self.perform_action, arguments=['stop'], shortcut='p') # Services Menu Items self.m5 = self.add_menu(name='Services Running', shortcut='s') self.m5.addItem(text='External Services', onSelect=self.perform_action, arguments=['services_external'], shortcut='e') self.m5.addItem(text='Tool Services', onSelect=self.perform_action, arguments=['services'], shortcut='t') # System Commands Menu Items self.m6 = self.add_menu(name='System Commands', shortcut='y') self.m6.addItem(text='Backup', onSelect=self.system_commands, arguments=['backup'], shortcut='b') self.m6.addItem(text='Change Vent Configuration', onSelect=self.system_commands, arguments=['configure'], shortcut='c') self.m6.addItem(text='Detect GPUs', onSelect=self.system_commands, arguments=['gpu'], shortcut='g') self.m6.addItem(text='Factory Reset', onSelect=self.system_commands, arguments=['reset'], shortcut='r') self.m6.addItem(text='Restore (To Be Implemented...', onSelect=self.system_commands, arguments=['restore'], shortcut='t') # TODO this should be either or depending on whether or not it's running already self.m6.addItem(text='Start', onSelect=self.system_commands, arguments=['start'], shortcut='s') self.m6.addItem(text='Stop', onSelect=self.system_commands, arguments=['stop'], shortcut='o') self.m6.addItem(text='Upgrade (To Be Implemented...)', onSelect=self.system_commands, arguments=['upgrade'], shortcut='u') # Tutorial Menu Items self.m7 = self.add_menu(name='Tutorials', shortcut='t') self.s1 = self.m7.addNewSubmenu(name='About Vent', shortcut='v') self.s1.addItem(text='Background', onSelect=self.switch_tutorial, arguments=['background'], shortcut='b') self.s1.addItem(text='Terminology', onSelect=self.switch_tutorial, arguments=['terminology'], shortcut='t') self.s1.addItem(text='Getting Setup', onSelect=self.switch_tutorial, arguments=['setup'], shortcut='s') self.s2 = self.m7.addNewSubmenu(name='Working with Tools', shortcut='c') self.s2.addItem(text='Starting Tools', onSelect=self.switch_tutorial, arguments=['starting_tools'], shortcut='s') self.s3 = self.m7.addNewSubmenu(name='Working with Plugins', shortcut='p') self.s3.addItem(text='Adding Tools', onSelect=self.switch_tutorial, arguments=['adding_tools'], shortcut='a') self.s4 = self.m7.addNewSubmenu(name='Files', shortcut='f') self.s4.addItem(text='Adding Files', onSelect=self.switch_tutorial, arguments=['adding_files'], shortcut='a') self.s5 = self.m7.addNewSubmenu(name='Help', shortcut='s') self.s5.addItem(text='Basic Troubleshooting', onSelect=self.switch_tutorial, arguments=['basic_troubleshooting'], shortcut='t')
def Services(core, vent=True, external=False, **kargs): """ Get services that have exposed ports, expects param core to be True or False based on which type of services to return, by default limit to vent containers and processes not running externally, if not limited by vent containers, then core is ignored. """ services = [] path_dirs = PathDirs(**kargs) template = Template(template=path_dirs.cfg_file) services_uri = template.option('main', 'services_uri') try: # look for internal services if not external: d_client = docker.from_env() if vent: c_filter = {'label': 'vent'} containers = d_client.containers.list(filters=c_filter) else: containers = d_client.containers.list() for c in containers: uris = {} name = None if vent and 'vent.name' in c.attrs['Config']['Labels']: if ((core and 'vent.groups' in c.attrs['Config']['Labels'] and 'core' in c.attrs['Config']['Labels']['vent.groups']) or (not core and 'vent.groups' in c.attrs['Config']['Labels'] and 'core' not in c.attrs['Config']['Labels']['vent.groups'])): name = c.attrs['Config']['Labels']['vent.name'] if name == '': name = c.attrs['Config']['Labels']['vent.namespace'].split( '/')[1] for label in c.attrs['Config']['Labels']: if label.startswith('uri'): try: val = int(label[-1]) if val not in uris: uris[val] = {} uris[val][label[:-1] ] = c.attrs['Config']['Labels'][label] except Exception as e: # pragma: no cover logger.error('Malformed services section' ' in the template file ' + str(e)) else: name = c.name if name and 'vent.repo' in c.attrs['Config']['Labels']: name = c.attrs['Config']['Labels']['vent.repo'].split( '/')[-1] + ': ' + name ports = c.attrs['NetworkSettings']['Ports'] p = [] port_num = 1 for port in ports: if ports[port]: try: service_str = '' if 'uri_prefix' in uris[port_num]: service_str += uris[port_num]['uri_prefix'] host = ports[port][0]['HostIp'] if services_uri[0] and host == '0.0.0.0': host = services_uri[1] service_str += host + ':' service_str += ports[port][0]['HostPort'] if 'uri_postfix' in uris[port_num]: service_str += uris[port_num]['uri_postfix'] uri_creds = '' if 'uri_user' in uris[port_num]: uri_creds += ' user:'******'uri_user'] if 'uri_pw' in uris[port_num]: uri_creds += ' pw:' uri_creds += uris[port_num]['uri_pw'] if uri_creds: service_str += ' - (' + uri_creds + ' )' p.append(service_str) except Exception as e: # pragma: no cover logger.info('No services defined for ' + str(name) + ' with exposed port ' + str(port_num) + ' because: ' + str(e)) port_num += 1 if p and name: services.append((name, p)) logger.info(services) # look for external services else: ext_tools = template.section('external-services')[1] for ext_tool in ext_tools: try: name = ext_tool[0].lower() p = [] settings_dict = json.loads(ext_tool[1]) if ('locally_active' in settings_dict and settings_dict['locally_active'] == 'no'): # default protocol to display will be http protocol = 'http' ip_address = '' port = '' for setting in settings_dict: if setting == 'ip_address': ip_address = settings_dict[setting] if setting == 'port': port = settings_dict[setting] if setting == 'protocol': protocol = settings_dict[setting] p.append(protocol + '://' + ip_address + ':' + port) if p and name: services.append((name, p)) except Exception: # pragma: no cover p = None except Exception as e: # pragma: no cover logger.error('Could not get services ' + str(e)) return services
def __init__(self, **kargs): self.path_dirs = PathDirs(**kargs) self.manifest = os.path.join(self.path_dirs.meta_dir, "plugin_manifest.cfg") self.d_client = docker.from_env() self.logger = Logger(__name__)
def Jobs(): """ Get the number of jobs that are running and finished, and the number of total tools running and finished for those jobs """ jobs = [0, 0, 0, 0] # get running jobs try: d_client = docker.from_env() c = d_client.containers.list(all=False, filters={'label': 'vent-plugin'}) files = [] for container in c: jobs[1] += 1 if 'file' in container.attrs['Config']['Labels']: if container.attrs['Config']['Labels']['file'] not in files: files.append(container.attrs['Config']['Labels']['file']) jobs[0] = len(files) except Exception as e: # pragma: no cover logger.error('Could not get running jobs ' + str(e)) # get finished jobs try: d_client = docker.from_env() c = d_client.containers.list(all=True, filters={'label': 'vent-plugin', 'status': 'exited'}) file_names = [] tool_names = [] finished_jobs = [] path_dirs = PathDirs() manifest = join(path_dirs.meta_dir, 'status.json') if exists(manifest): file_status = 'a' else: file_status = 'w' # get a list of past jobs' file names if status.json exists if file_status == 'a': with open(manifest, 'r') as infile: for line in infile: finished_jobs.append(json.loads(line)) # get a list of file names so we can check against each container file_names = [d['FileName'] for d in finished_jobs] # multiple tools can run on 1 file. Use a tuple to status check tool_names = [(d['FileName'], d['VentPlugin']) for d in finished_jobs] for container in c: jobs[3] += 1 if 'file' in container.attrs['Config']['Labels']: # make sure the file name and the tool tup exists because # multiple tools can run on 1 file. if (container.attrs['Config']['Labels']['file'], container.attrs['Config']['Labels']['vent.name']) not in \ tool_names: # TODO figure out a nicer way of getting desired values # from containers.attrs. new_file = {} new_file['FileName'] = \ container.attrs['Config']['Labels']['file'] new_file['VentPlugin'] = \ container.attrs['Config']['Labels']['vent.name'] new_file['StartedAt'] = \ container.attrs['State']['StartedAt'] new_file['FinishedAt'] = \ container.attrs['State']['FinishedAt'] new_file['ID'] = \ container.attrs['Id'][:12] # create/append a json file with all wanted information with open(manifest, file_status) as outfile: json.dump(new_file, outfile) outfile.write('\n') # delete any containers with 'vent-plugin' in the groups if 'vent-plugin' in container.attrs['Config']['Labels']: container.remove() # add extra one to account for file that just finished if the file was # just created since file_names is processed near the beginning if file_status == 'w' and len(file_names) == 1: jobs[2] = len(set(file_names)) + 1 else: jobs[2] = len(set(file_names)) jobs[3] = jobs[3] - jobs[1] except Exception as e: # pragma: no cover logger.error('Could not get finished jobs ' + str(e)) return tuple(jobs)
def GpuUsage(**kargs): """ Get the current GPU usage of available GPUs """ usage = (False, None) gpu_status = {'vent_usage': {'dedicated': [], 'mem_mb': {}}} path_dirs = PathDirs(**kargs) path_dirs.host_config() template = Template(template=path_dirs.cfg_file) # get running jobs using gpus try: d_client = docker.from_env() c = d_client.containers.list(all=False, filters={'label': 'vent-plugin'}) for container in c: if ('vent.gpu' in container.attrs['Config']['Labels'] and container.attrs['Config']['Labels']['vent.gpu'] == 'yes'): device = container.attrs['Config']['Labels']['vent.gpu.device'] if ('vent.gpu.dedicated' in container.attrs['Config']['Labels'] and container.attrs['Config']['Labels']['vent.gpu.dedicated'] == 'yes'): gpu_status['vent_usage']['dedicated'].append(device) elif 'vent.gpu.mem_mb' in container.attrs['Config']['Labels']: if device not in gpu_status['vent_usage']['mem_mb']: gpu_status['vent_usage']['mem_mb'][device] = 0 gpu_status['vent_usage']['mem_mb'][device] += int( container.attrs['Config']['Labels']['vent.gpu.mem_mb']) except Exception as e: # pragma: no cover logger.error('Could not get running jobs ' + str(e)) port = '3476' # default docker gateway host = '172.17.0.1' result = template.option('nvidia-docker-plugin', 'port') if result[0]: port = result[1] result = template.option('nvidia-docker-plugin', 'host') if result[0]: host = result[1] else: try: # now just requires ip, ifconfig route = check_output(('ip', 'route')).decode('utf-8').split('\n') default = '' # grab the default network device. for device in route: if 'default' in device: default = device.split()[4] break # grab the IP address for the default device ip_addr = check_output(('ifconfig', default)).decode('utf-8') ip_addr = ip_addr.split('\n')[1].split()[1] host = ip_addr except Exception as e: # pragma: no cover logger.error('Something with the ip addresses' 'went wrong ' + str(e)) # have to get the info separately to determine how much memory is availabe nd_url = 'http://' + host + ':' + port + '/v1.0/gpu/info/json' try: r = requests.get(nd_url) if r.status_code == 200: status = r.json() for i, device in enumerate(status['Devices']): gm = int(round(math.log(int(device['Memory']['Global']), 2))) gpu_status[i] = {'global_memory': 2**gm, 'cores': device['Cores']} else: usage = (False, 'Unable to get GPU usage request error code: ' + str(r.status_code)) except Exception as e: # pragma: no cover usage = (False, 'Error: ' + str(e)) # get actual status of each gpu nd_url = 'http://' + host + ':' + port + '/v1.0/gpu/status/json' try: r = requests.get(nd_url) if r.status_code == 200: status = r.json() for i, device in enumerate(status['Devices']): if i not in gpu_status: gpu_status[i] = {} gpu_status[i]['utilization'] = device['Utilization'] gpu_status[i]['memory'] = device['Memory'] gpu_status[i]['processes'] = device['Processes'] usage = (True, gpu_status) else: usage = (False, 'Unable to get GPU usage request error code: ' + str(r.status_code)) except Exception as e: # pragma: no cover usage = (False, 'Error: ' + str(e)) return usage
def create(self): """ Override method for creating FormBaseNewWithMenu form """ try: self.api_action = Action() except DockerException as de: # pragma: no cover notify_confirm(str(de), title='Docker Error', form_color='DANGER', wrap=True) MainForm.exit() self.add_handlers({'^T': self.help_form, '^Q': MainForm.exit}) # all forms that can toggle view by group self.view_togglable = [ 'inventory', 'remove', 'update', 'enable', 'disable', 'build' ] ####################### # MAIN SCREEN WIDGETS # ####################### self.addfield = self.add(npyscreen.TitleFixedText, name='Date:', labelColor='DEFAULT', value=Timestamp()) self.addfield2 = self.add(npyscreen.TitleFixedText, name='Uptime:', labelColor='DEFAULT', value=Uptime()) self.cpufield = self.add(npyscreen.TitleFixedText, name='Logical CPUs:', labelColor='DEFAULT', value=Cpu()) self.gpufield = self.add(npyscreen.TitleFixedText, name='GPUs:', labelColor='DEFAULT', value=Gpu()[1]) self.location = self.add(npyscreen.TitleFixedText, name='User Data:', value=PathDirs().meta_dir, labelColor='DEFAULT') self.file_drop = self.add(npyscreen.TitleFixedText, name='File Drop:', value=DropLocation()[1], labelColor='DEFAULT') self.addfield3 = self.add(npyscreen.TitleFixedText, name='Containers:', labelColor='DEFAULT', value='0 ' + ' running') self.addfield4 = self.add(npyscreen.TitleFixedText, name='Status:', labelColor='CAUTION', value='Idle') self.addfield5 = self.add(npyscreen.TitleFixedText, name='Core Tools:', labelColor='DANGER', value='Not built') self.addfield6 = self.add(npyscreen.TitleFixedText, name='Plugin Tools:', labelColor='DEFAULT', value='Not built') self.addfield7 = self.add(npyscreen.TitleFixedText, name='Jobs:', value='0 jobs running (0 tool containers),' ' 0 completed jobs', labelColor='DEFAULT') self.multifield1 = self.add(npyscreen.MultiLineEdit, max_height=22, editable=False, value=""" '., 'b * '$ #. $: #: *# @): :@,@): ,.**:' , :@@*: ..**' '#o. .:(@'.@*"' 'bq,..:,@@*' ,* ,p$q8,:@)' .p*' ' '@@Pp@@*' Y7'.' :@):. .:@:'. .::(@:. _ __ _____ _ __ | |_ \ \ / / _ \ '_ \| __| \ V / __/ | | | |_ \_/ \___|_| |_|\__| """) ################ # MENU OPTIONS # ################ # Core Tools Menu Items self.m2 = self.add_menu(name='Core Tools', shortcut='c') self.m2.addItem(text='Add all latest core tools', onSelect=MainForm.core_tools, arguments=['install'], shortcut='i') self.m2.addItem(text='Build core tools', onSelect=self.perform_action, arguments=['build_core'], shortcut='b') self.m2.addItem(text='Clean core tools', onSelect=self.perform_action, arguments=['clean_core'], shortcut='c') self.m2.addItem(text='Configure core tools', onSelect=self.perform_action, arguments=['configure_core'], shortcut='t') self.m2.addItem(text='Disable core tools', onSelect=self.perform_action, arguments=['disable_core'], shortcut='d') self.m2.addItem(text='Enable core tools', onSelect=self.perform_action, arguments=['enable_core'], shortcut='e') self.m2.addItem(text='Inventory of core tools', onSelect=self.perform_action, arguments=['inventory_core'], shortcut='v') self.m2.addItem(text='Remove core tools', onSelect=self.perform_action, arguments=['remove_core'], shortcut='r') self.m2.addItem(text='Start core tools', onSelect=self.perform_action, arguments=['start_core'], shortcut='s') self.m2.addItem(text='Stop core tools', onSelect=self.perform_action, arguments=['stop_core'], shortcut='p') self.m2.addItem(text='Update core tools', onSelect=self.perform_action, arguments=['update_core'], shortcut='u') # Plugin Menu Items self.m3 = self.add_menu(name='Plugins', shortcut='p') self.m3.addItem(text='Add new plugin', onSelect=self.perform_action, arguments=['add'], shortcut='a') self.m3.addItem(text='Build plugin tools', onSelect=self.perform_action, arguments=['build'], shortcut='b') self.m3.addItem(text='Clean plugin tools', onSelect=self.perform_action, arguments=['clean'], shortcut='c') self.m3.addItem(text='Configure plugin tools', onSelect=self.perform_action, arguments=['configure'], shortcut='t') self.m3.addItem(text='Disable plugin tools', onSelect=self.perform_action, arguments=['disable'], shortcut='d') self.m3.addItem(text='Enable plugin tools', onSelect=self.perform_action, arguments=['enable'], shortcut='e') self.m3.addItem(text='Inventory of installed plugins', onSelect=self.perform_action, arguments=['inventory'], shortcut='i') self.m3.addItem(text='Remove plugins', onSelect=self.perform_action, arguments=['remove'], shortcut='r') self.m3.addItem(text='Start plugin tools', onSelect=self.perform_action, arguments=['start'], shortcut='s') self.m3.addItem(text='Stop plugin tools', onSelect=self.perform_action, arguments=['stop'], shortcut='p') self.m3.addItem(text='Update plugins', onSelect=self.perform_action, arguments=['update'], shortcut='u') # Log Menu Items self.m4 = self.add_menu(name='Logs', shortcut='l') self.m4.addItem(text='Get container logs', arguments=['logs'], onSelect=self.perform_action) # Services Menu Items self.m5 = self.add_menu(name='Services Running', shortcut='s') self.m5.addItem(text='Core Services', onSelect=self.perform_action, arguments=['services_core'], shortcut='c') self.m5.addItem(text='External Services', onSelect=self.perform_action, arguments=['services_external'], shortcut='e') self.m5.addItem(text='Plugin Services', onSelect=self.perform_action, arguments=['services'], shortcut='p') # System Commands Menu Items self.m6 = self.add_menu(name='System Commands', shortcut='y') self.m6.addItem(text='Backup', onSelect=self.system_commands, arguments=['backup'], shortcut='b') self.m6.addItem(text='Change vent configuration', onSelect=self.system_commands, arguments=['configure'], shortcut='c') self.m6.addItem(text='Detect GPUs', onSelect=self.system_commands, arguments=['gpu'], shortcut='g') self.m6.addItem(text='Enable Swarm Mode (To Be Implemented...)', onSelect=self.system_commands, arguments=['swarm'], shortcut='s') self.m6.addItem(text='Factory reset', onSelect=self.system_commands, arguments=['reset'], shortcut='r') self.s6 = self.m6.addNewSubmenu(name='Network Tap Interface', shortcut='n') self.m6.addItem(text='Restore', onSelect=self.system_commands, arguments=['restore'], shortcut='t') self.m6.addItem(text='Upgrade (To Be Implemented...)', onSelect=self.system_commands, arguments=['upgrade'], shortcut='u') self.s6.addItem(text='Create', onSelect=self.system_commands, shortcut='c', arguments=['ntapcreate']) self.s6.addItem(text='Delete', onSelect=self.system_commands, shortcut='d', arguments=['ntapdelete']) self.s6.addItem(text='List', onSelect=self.system_commands, shortcut='l', arguments=['ntaplist']) self.s6.addItem(text='NICs', onSelect=self.system_commands, shortcut='n', arguments=['ntapnics']) self.s6.addItem(text='Start', onSelect=self.system_commands, shortcut='s', arguments=['ntapstart']) self.s6.addItem(text='Stop', onSelect=self.system_commands, shortcut='t', arguments=['ntapstop']) # Tutorial Menu Items self.m7 = self.add_menu(name='Tutorials', shortcut='t') self.s1 = self.m7.addNewSubmenu(name='About Vent', shortcut='v') self.s1.addItem(text='Background', onSelect=self.switch_tutorial, arguments=['background'], shortcut='b') self.s1.addItem(text='Terminology', onSelect=self.switch_tutorial, arguments=['terminology'], shortcut='t') self.s1.addItem(text='Getting Setup', onSelect=self.switch_tutorial, arguments=['setup'], shortcut='s') self.s2 = self.m7.addNewSubmenu(name='Working with Cores', shortcut='c') self.s2.addItem(text='Building Cores', onSelect=self.switch_tutorial, arguments=['building_cores'], shortcut='b') self.s2.addItem(text='Starting Cores', onSelect=self.switch_tutorial, arguments=['starting_cores'], shortcut='c') self.s3 = self.m7.addNewSubmenu(name='Working with Plugins', shortcut='p') self.s3.addItem(text='Adding Plugins', onSelect=self.switch_tutorial, arguments=['adding_plugins'], shortcut='a') self.s4 = self.m7.addNewSubmenu(name='Files', shortcut='f') self.s4.addItem(text='Adding Files', onSelect=self.switch_tutorial, arguments=['adding_files'], shortcut='a') self.s5 = self.m7.addNewSubmenu(name='Help', shortcut='s') self.s5.addItem(text='Basic Troubleshooting', onSelect=self.switch_tutorial, arguments=['basic_troubleshooting'], shortcut='t')
class VentApp(npyscreen.NPSAppManaged): """ Main menu app for vent CLI """ keypress_timeout_default = 10 repo_value = {} paths = PathDirs() first_time = paths.ensure_file(paths.init_file) if first_time[0] and first_time[1] != 'exists': npyscreen.NPSAppManaged.STARTING_FORM = 'TUTORIALINTRO' else: npyscreen.NPSAppManaged.STARTING_FORM = 'MAIN' def onStart(self): """ Override onStart method for npyscreen """ curses.mousemask(0) self.paths.host_config() version = Version() # setup initial runtime stuff if self.first_time[0] and self.first_time[1] != 'exists': plugins = Plugin() actions = Action() thr = Thread(target=MainForm.t_status, args=(), kwargs={'core': True}) thr.start() while thr.is_alive(): npyscreen.notify_wait( 'Please wait while Vent initializes...1/4', title='Setting up things...') time.sleep(1) thr.join() thr = Thread(target=MainForm.t_status, args=(), kwargs={'core': False}) thr.start() while thr.is_alive(): npyscreen.notify_wait( 'Please wait while Vent initializes...2/4', title='Setting up things...') time.sleep(1) thr.join() thr = Thread(target=plugins.auto_install, args=(), kwargs={}) thr.start() while thr.is_alive(): npyscreen.notify_wait( 'Please wait while Vent initializes...3/4', title='Setting up things...') time.sleep(1) thr.join() thr = Thread(target=actions.startup, args=(), kwargs={}) thr.start() while thr.is_alive(): npyscreen.notify_wait( 'Please wait while Vent initializes...4/4', title='Setting up things...') time.sleep(1) thr.join() quit_s = '\t' * 4 + '^Q to quit' tab_esc = '\t' * 4 + 'TAB to close menu popup' self.addForm('MAIN', MainForm, name='Vent ' + version + '\t\t\t\t\t^T for help' + quit_s + tab_esc, color='IMPORTANT') self.addForm('HELP', HelpForm, name='Help\t\t\t\t\t\t\t\t^T to toggle previous' + quit_s, color='DANGER') self.addForm('TUTORIALINTRO', TutorialIntroForm, name='Vent Tutorial' + quit_s, color='DANGER') self.addForm('TUTORIALBACKGROUND', TutorialBackgroundForm, name='About Vent' + quit_s, color='DANGER') self.addForm('TUTORIALTERMINOLOGY', TutorialTerminologyForm, name='About Vent' + quit_s, color='DANGER') self.addForm('TUTORIALGETTINGSETUP', TutorialGettingSetupForm, name='About Vent' + quit_s, color='DANGER') self.addForm('TUTORIALBUILDINGCORES', TutorialBuildingCoresForm, name='Working with Cores' + quit_s, color='DANGER') self.addForm('TUTORIALSTARTINGCORES', TutorialStartingCoresForm, name='Working with Cores' + quit_s, color='DANGER') self.addForm('TUTORIALADDINGPLUGINS', TutorialAddingPluginsForm, name='Working with Plugins' + quit_s, color='DANGER') self.addForm('TUTORIALADDINGFILES', TutorialAddingFilesForm, name='Files' + quit_s, color='DANGER') self.addForm('TUTORIALTROUBLESHOOTING', TutorialTroubleshootingForm, name='Troubleshooting' + quit_s, color='DANGER') def change_form(self, name): """ Changes the form (window) that is displayed """ self.switchForm(name)
def Services(core, vent=True, external=False, **kargs): """ Get services that have exposed ports, expects param core to be True or False based on which type of services to return, by default limit to vent containers and processes not running externally, if not limited by vent containers, then core is ignored. """ services = [] path_dirs = PathDirs(**kargs) template = Template(template=path_dirs.cfg_file) services_uri = template.option("main", "services_uri") try: # look for internal services if not external: d_client = docker.from_env() if vent: c_filter = {'label': 'vent'} containers = d_client.containers.list(filters=c_filter) else: containers = d_client.containers.list() for c in containers: uri_prefix = '' uri_postfix = '' uri_user = '' uri_pw = '' name = None if vent and 'vent.name' in c.attrs['Config']['Labels']: if ((core and 'vent.groups' in c.attrs['Config']['Labels'] and 'core' in c.attrs['Config']['Labels']['vent.groups']) or (not core and 'vent.groups' in c.attrs['Config']['Labels'] and 'core' not in c.attrs['Config']['Labels']['vent.groups'])): name = c.attrs['Config']['Labels']['vent.name'] if 'uri_prefix' in c.attrs['Config']['Labels']: uri_prefix = c.attrs['Config']['Labels'][ 'uri_prefix'] if 'uri_postfix' in c.attrs['Config']['Labels']: uri_postfix = c.attrs['Config']['Labels'][ 'uri_postfix'] if 'uri_user' in c.attrs['Config']['Labels']: uri_user = "******" uri_user += c.attrs['Config']['Labels']['uri_user'] if 'uri_pw' in c.attrs['Config']['Labels']: uri_pw = " pw:" uri_pw += c.attrs['Config']['Labels']['uri_pw'] else: name = c.name ports = c.attrs['NetworkSettings']['Ports'] p = [] for port in ports: if ports[port]: uri_creds = '' if uri_user or uri_pw: uri_creds = " - (" + uri_user + uri_pw + " )" host = ports[port][0]['HostIp'] if services_uri[0] and host == '0.0.0.0': host = services_uri[1] p.append(uri_prefix + host + ":" + ports[port][0]['HostPort'] + uri_postfix + uri_creds) if p and name: services.append((name, p)) # look for external services else: ext_tools = template.section('external-services')[1] for ext_tool in ext_tools: try: name = ext_tool[0].lower() p = [] settings_dict = json.loads(ext_tool[1]) if ('locally_active' in settings_dict and settings_dict['locally_active'] == 'no'): # default protocol to display will be http protocol = 'http' ip_address = '' port = '' for setting in settings_dict: if setting == 'ip_address': ip_address = settings_dict[setting] if setting == 'port': port = settings_dict[setting] if setting == 'protocol': protocol = settings_dict[setting] p.append(protocol + '://' + ip_address + ':' + port) if p and name: services.append((name, p)) except Exception: # pragma: no cover p = None except Exception as e: # pragma: no cover pass return services