def discover(self): results = [] response = {'next': self.patchman_url} while response['next']: response = json.loads(GET(response['next'])) results.extend(response['results']) hosts = {} for host in results: if not re.match(self.filter_name, host['hostname']): continue host_name = jinja(self.host_name, host=host) host_args = jinja(self.args.get('host-args') or {}, host=host) if host['updates'] and self.args.get('on-package-updates'): host_args.setdefault('updates', []) host_args['updates'].extend( self.args.get('on-package-updates')) if host['reboot_required'] and self.args.get('on-reboot-required'): host_args.setdefault('updates', []) host_args['updates'].extend( self.args.get('on-reboot-required')) # skip hosts with no actionable items if not host_args and self.skip_ok: continue hosts[host_name] = host_args return hosts
def __init__(self, host_name, host_args, updater_args): super(JenkinsUpdater, self).__init__(host_name, host_args, updater_args) self.wait = self.updater_args.get('wait', True) try: self.wait_timeout = int(self.updater_args.get('wait-timeout', 500)) except (ValueError, TypeError): log.debug('[jenkins] Default to 200 seconds timeout') self.wait_timeout = 500 try: self.wait_check_interval = int( self.updater_args.get('wait-check-interval', 10)) except (ValueError, TypeError): log.debug('[jenkins] Default to 10 seconds check interval') self.wait_check_interval = 10 self.server = jinja(self.updater_args.get('server')) self.username = jinja(self.updater_args.get('username')) self.password = jinja(self.updater_args.get('password')) self.job = jinja(self.updater_args.get('job')) try: self.jenkins = jenkins.Jenkins(self.server, self.username, self.password) except: log.exception('[{}] [jenkins] Could not connect to {}'.format( self.host, self.server)) self.jenkins = None
def __init__(self, discover_args): super(NetBoxDiscoverer, self).__init__(discover_args) if 'netbox-url' not in self.args: raise ValueError('missing "netbox-url" for netbox discoverer') if 'host-name' not in self.args: raise ValueError('missing "host-name" for netbox discoverer') self.host_name = self.args['host-name'] self.netbox_url = jinja(self.args['netbox-url']) self.filter_name = jinja(self.args.get('filter-name', '.*'))
def discover(self): api_result = json.loads(GET(self.netbox_url)) hosts = {} for host in api_result.get('results', []): if not re.match(self.filter_name, host['name']): continue host_name = jinja(self.host_name, host=host) host_args = jinja(self.args.get('host-args') or {}, host=host) hosts[host_name] = host_args return hosts
def update(self): stdout, stderr = ssh_cmd( self.host, self.host_args, 'sudo DEBIAN_FRONTEND=noninteractive apt-get -y -q' ' -o Dpkg::Options::=--force-confold upgrade;') if stderr != "": return False autoremove = jinja(self.updater_args.get('autoremove', False)) if autoremove: stdout, stderr = ssh_cmd( self.host, self.host_args, 'sudo DEBIAN_FRONTEND=noninteractive apt-get -y -q' ' -o Dpkg::Options::=--force-confold autoremove;') if stderr != "": return False patchman_url = self.updater_args.get('patchman-url') if patchman_url.startswith('https'): https_proxy = self.updater_args.get('https_proxy') proxy_prefix = 'export https_proxy={}; '.format( https_proxy) if https_proxy else '' else: http_proxy = self.updater_args.get('http_proxy') proxy_prefix = 'export http_proxy={}; '.format( http_proxy) if http_proxy else '' if patchman_url is not None: ssh_cmd( self.host, self.host_args, '{}sudo patchman-client -s {}'.format(proxy_prefix, patchman_url)) return True
def discover(self): result = {} for host in self.args: host_name, host_args = str_or_dict(jinja(host)) result[host_name] = host_args return result
def update(self): if self.command: command = jinja(self.command, host=self.host, host_args=self.host_args) ssh_cmd(self.host, self.host_args, command) return True return False
def fix_hostname(self, host): """Override this to allow the handler to "rename" the host as needed. This function has access to self.host_args as well as self.service_args. Default behaviour is to render the template from the "fix-hostname" argument, or return the hostname as is""" fix_hostname = self.service_args.get('fix-hostname') if fix_hostname is not None: return jinja(fix_hostname, host=host) return host
def discover(self): response = json.loads(urllib.request.urlopen(self.request).read()) results = jinja(self.results_template, _env=None, response=response) if isinstance(results, dict): results = [{'key': k, 'value': v} for k, v in results.items()] hosts = {} for item in results: if any(not re.search(str(m['regex']), str(m['value'])) for m in jinja(self.match_filters, _env=None, item=item)): continue host_name = str( jinja(self.host_name_template, _env=None, item=item)) host_args = jinja(self.host_args_template, _env=None, item=item) hosts[host_name] = host_args return hosts
def __init__(self, discover_args): super(PatchmanDiscoverer, self).__init__(discover_args) if 'patchman-url' not in self.args: raise ValueError('missing "patchman-url" for Patchman discoverer') if 'host-name' not in self.args: raise ValueError('missing "host-name" for Patchman discoverer') self.patchman_url = self.args['patchman-url'] self.host_name = self.args['host-name'] self.filter_name = jinja(self.args.get('filter-name', '.*')) or '' self.skip_ok = self.args.get('skip-ok', False)
def update(self): stdout, stderr, rc = exec_cmd( jinja(self.updater_args, host=self.fix_hostname(self.host), **self.host_args)) expected_rc = self.updater_args.get('expect-returncode') if expected_rc is not None: return rc == expected_rc expected_stdout = self.updater_args.get('expect-stdout') if expected_stdout is not None: return stdout == expected_stdout return True
def update(self): try: self.jenkins.get_whoami() except: log.exception('[{}] [jenkins] Failed to authenticate'.format( self.host)) return False if self.job is None: log.fatal('[{}] [jenkins] Empty job name'.format(self.host)) return False raw_args = self.updater_args.get('build-arguments') try: if raw_args: queue_id = self.jenkins.build_job( self.job, jinja(raw_args, host=self.host, host_args=self.host_args)) else: queue_id = self.jenkins.build_job(self.job) except: log.exception('[{}] [jenkins] Failed to queue job {}'.format( self.host, self.job)) return False log.info('[{}] [jenkins] Queued job {} (queue id {})'.format( self.host, self.job, queue_id)) if not self.wait: return True now = datetime.now() timeout = now + timedelta(seconds=self.wait_timeout) while True: try: queue_item = self.jenkins.get_queue_item(queue_id) job_number = queue_item['executable']['number'] break except KeyError: sleep(self.wait_check_interval) log.debug('[{}] [jenkins] Waiting for job queue {}'.format( self.host, self.job)) except: log.exception('[{}] [jenkins] Failed to queue job {}'.format( self.host, self.job)) return False if datetime.now() > timeout: log.fatal( '[{}] [jenkins] Timeout waiting for job queue {}'.format( self.host, self.job)) return False log.info('[{}] [jenkins] Started job {}/{} (queue id {})'.format( self.host, self.job, job_number, queue_id)) done = False while not done and datetime.now() <= timeout: log.debug('[{}] [jenkins] Waiting for job run {}/{}'.format( self.host, self.job, job_number)) build_info = self.jenkins.get_build_info(self.job, job_number) done = build_info['result'] is not None if not done: sleep(self.wait_check_interval) if not done: log.fatal( '[{}] [jenkins] Timeout waiting for job run {}/{}'.format( self.host, self.job, job_number)) return False return build_info['result'] == 'SUCCESS'