def do_update(self, db, dry_run=None, legacy_updater=None): """Update /etc/hosts. Args: db: mongdb db reference. dry_run: bool, whether or not to actually update /etc/hosts. legacy_updater: binary to run in order to update /etc/hosts (helpful for transitions). Returns: bool, True if changes are made to the system. """ if legacy_updater: # Call legacy host updater, allow it to write to /etc/hosts. retcode = subprocess.call([legacy_updater]) if retcode < 0: logging.error('Call to %s failed!' % legacy_updater) sys.exit(1) self.hosts_data = ['127.0.0.1 localhost'] # Reset data, otherwise we append aerostat_data = db.servers.find() # extract hostname, ip and aliases for item in aerostat_data: if item['ip']: self.append_hosts_line(item['ip'], item['hostname']) if item['aliases']: self.format_aliases(item['ip'], item['aliases']) if dry_run: dry_run_output = '\n'.join(self.hosts_data) + '\n' logging.debug( ('DRY RUN: Your /etc/hosts file would look' 'like this: \n%s' % dry_run_output)) return False # Only make any changes if there are actual data available to write. if self.hosts_data: logging.info('Copying /etc/hosts to /etc/hosts.bak') shutil.copyfile('/etc/hosts', '/etc/hosts.bak') logging.info('Writing new /etc/hosts file.') self.write_hosts_file() else: logging.error('No data returned from aerostat. Write aborted.') return True
def change_hostname(self, db, value, inst=None, host=None): """Change the hostname of the specified instance or hostname.""" if not inst and not host: logging.error("You need to specify either instance or hostname") return False if inst and host: logging.error("You cannot specify both inst and hostname") return False key = "instance_id" if host: key = "hostname" param = inst or host db.servers.update({key: param}, {"$set": {"hostname": value}}) return True
def _create_dir_path(self, path): """Create the directory path for the configs, if necssary. Args: path: str, path of config. Returns: bool, True if exit code for mkdir is 0, or if directory already exists. """ base_path = '/'.join(path.split('/')[:-1]) if not os.path.exists(base_path): mkdir_cmd = ['mkdir', '-p', '-m', '761', base_path] mkdir_ret = subprocess.call(mkdir_cmd) if mkdir_ret == 0: logging.info('Mkdir (%s) successful' % path) else: logging.error('Mkdir (%s) unsuccessful' % path) return mkdir_ret == 0 return True
def write_configs(self, config_data): """Write configs to appropriate paths with appropriate permisions. Args: config_data: list of dicts of configuration data for server. Returns: list, containing tuples of return codes for each file's perm ops. """ return_codes = [] for config in config_data: _size, temp_file = tempfile.mkstemp(text=True) if 'contents' in config.keys(): # Possibly an empty config # If we have Jinja templ values to insert into the config if 'keywords' in config.keys(): logging.debug('replacing keywords in config template') config['contents'] = self.customize_template( config['contents'], config['keywords']) temp = open(temp_file, 'w') temp.write(config['contents']) temp.close() if not self._create_dir_path(config['path']): logging.error( 'Could not create directory tree for %s' % config['path']) continue try: shutil.move(temp_file, config['path']) except shutil.Error, e: logging.warn( 'Invalid Path Specified: %s. Traceback:\n %s' % ( config['path'], e)) continue file_ret_codes = self._update_conf_perms( config['name'], config['path'], config['owner'], config['group'], config['mode']) return_codes.append(file_ret_codes)