def create_conf(self): """ create the config file """ confdata = self.config % ( self.data['repopath'], ','.join(p.__name__ for p in self.data['plugins']), self.data['password'], self.data['certpath'], self.data['keypath'], self.data['certpath'], self.data['server_uri']) # Don't overwrite existing bcfg2.conf file if os.path.exists(self.data['configfile']): result = safe_input("\nWarning: %s already exists. " "Overwrite? [y/N]: " % self.data['configfile']) if result not in ['Y', 'y']: print("Leaving %s unchanged" % self.data['configfile']) return try: open(self.data['configfile'], "w").write(confdata) os.chmod(self.data['configfile'], stat.S_IRUSR | stat.S_IWUSR) # 0600 except: # pylint: disable=W0702 self.errExit("Error trying to write configuration file '%s': %s" % (self.data['configfile'], sys.exc_info()[1]))
def _get_elements(self, xdata): """ Get the list of elements to encrypt or decrypt """ if Bcfg2.Options.setup.xpath: elements = xdata.xpath(Bcfg2.Options.setup.xpath) if not elements: self.logger.warning("XPath expression %s matched no elements" % Bcfg2.Options.setup.xpath) else: elements = xdata.xpath(self.default_xpath) if not elements: elements = list(xdata.getiterator(tag=lxml.etree.Element)) # filter out elements without text data for el in elements[:]: if not el.text: elements.remove(el) if Bcfg2.Options.setup.interactive: for element in elements[:]: if len(element): elt = copy.copy(element) for child in elt.iterchildren(): elt.remove(child) else: elt = element print(lxml.etree.tostring( elt, xml_declaration=False).decode("UTF-8").strip()) ans = safe_input("Encrypt this element? [y/N] ") if not ans.lower().startswith("y"): elements.remove(element) return elements
def RunAction(self, entry): """This method handles command execution and status return.""" shell = False shell_string = '' if entry.get('shell', 'false') == 'true': shell = True shell_string = '(in shell) ' if not Bcfg2.Options.setup.dry_run: if Bcfg2.Options.setup.interactive: prompt = ('Run Action %s%s, %s: (y/N): ' % (shell_string, entry.get('name'), entry.get('command'))) ans = safe_input(prompt) if ans not in ['y', 'Y']: return False if Bcfg2.Options.setup.service_mode == 'build': if entry.get('build', 'true') == 'false': self.logger.debug("Action: Deferring execution of %s due " "to build mode" % entry.get('command')) return False self.logger.debug("Running Action %s %s" % (shell_string, entry.get('name'))) rv = self.cmd.run(entry.get('command'), shell=shell) self.logger.debug("Action: %s got return code %s" % (entry.get('command'), rv.retval)) entry.set('rc', str(rv.retval)) return entry.get('status', 'check') == 'ignore' or rv.success else: self.logger.debug("In dryrun mode: not running action: %s" % (entry.get('name'))) return False
def _prompt_repopath(self): """Ask for the repository path.""" while True: self.input_with_default("Location of Bcfg2 repository", 'repopath') if os.path.isdir(self.data['repopath']): response = safe_input("Directory %s exists. Overwrite? [y/N]:" % self.data['repopath']) if response.lower().strip() == 'y': break else: break
def prompt(msg): """ Helper to give a yes/no prompt to the user. Flushes input buffers, handles exceptions, etc. Returns True if the user answers in the affirmative, False otherwise. :param msg: The message to show to the user. The message is not altered in any way for display; i.e., it should contain "[y/N]" if desired, etc. :type msg: string :returns: bool - True if yes, False if no """ try: ans = safe_input(msg) return ans in ['y', 'Y'] except UnicodeEncodeError: ans = safe_input(msg.encode('utf-8')) return ans in ['y', 'Y'] except (EOFError, KeyboardInterrupt): # handle ^C raise SystemExit(1) except: print("Error while reading input: %s" % sys.exc_info()[1]) return False
def Choose(self, choices): """Determine where to put pull data.""" if self.interactive: for choice in choices: print("Plugin returned choice:") if id(choice) == id(choices[0]): print("(current entry) ") if choice.all: print(" => global entry") elif choice.group: print(" => group entry: %s (prio %d)" % (choice.group, choice.prio)) else: print(" => host entry: %s" % (choice.hostname)) # flush input buffer ans = safe_input("Use this entry? [yN]: ") in ['y', 'Y'] if ans: return choice return False else: if not choices: return False return choices[0]
def input_with_default(self, msg, default_name): """ Prompt for input with the given message, taking the default from ``self.data`` """ val = safe_input("%s [%s]: " % (msg, self.data[default_name])) if val: self.data[default_name] = val