pyrundeck-0.9.7/0000755000175000001440000000000013426772423014557 5ustar pschmittusers00000000000000pyrundeck-0.9.7/PKG-INFO0000644000175000001440000000103313426772423015651 0ustar pschmittusers00000000000000Metadata-Version: 2.1 Name: pyrundeck Version: 0.9.7 Summary: Python REST API client for Rundeck 2.6+ Home-page: https://github.com/pschmitt/pyrundeck Author: Philipp Schmitt Author-email: philipp.schmitt@post.lu License: UNKNOWN Description: # Rundeck REST API client This is a Python REST API client for Rundeck 2.6+ ## See also - https://github.com/marklap/rundeckrun ## LICENSE GPL3 Platform: UNKNOWN Description-Content-Type: text/markdown pyrundeck-0.9.7/README.md0000644000175000001440000000022513303470060016017 0ustar pschmittusers00000000000000# Rundeck REST API client This is a Python REST API client for Rundeck 2.6+ ## See also - https://github.com/marklap/rundeckrun ## LICENSE GPL3 pyrundeck-0.9.7/pyrundeck/0000755000175000001440000000000013426772423016563 5ustar pschmittusers00000000000000pyrundeck-0.9.7/pyrundeck/__init__.py0000644000175000001440000000010413303503046020652 0ustar pschmittusers00000000000000from __future__ import absolute_import from .rundeck import Rundeck pyrundeck-0.9.7/pyrundeck/rundeck.py0000755000175000001440000001677413426772351020612 0ustar pschmittusers00000000000000#!/usr/bin/env python # coding: utf-8 from __future__ import unicode_literals from __future__ import print_function import logging import os import requests try: # Python 2 from urlparse import urljoin except ModuleNotFoundError: # Python 3 from urllib.parse import urljoin logger = logging.getLogger(__name__) class Rundeck(): def __init__(self, rundeck_url, token=None, username=None, password=None, api_version=18, verify=True): self.rundeck_url = rundeck_url self.API_URL = urljoin(rundeck_url, '/api/{}'.format(api_version)) self.token = token self.username = username self.password = password self.verify = verify self.auth_cookie = self.auth() def auth(self): url = urljoin(self.rundeck_url, '/j_security_check') p = {'j_username': self.username, 'j_password': self.password} r = requests.post( url, params=p, verify=self.verify, # Disable redirects, otherwise we get redirected twice and need to # return r.history[0].cookies['JSESSIONID'] allow_redirects=False) return r.cookies['JSESSIONID'] def __request(self, method, url, params=None): logger.info('{} {} Params: {}'.format(method, url, params)) cookies = {'JSESSIONID': self.auth_cookie} h = { 'Accept': 'application/json', 'Content-Type': 'application/json', 'X-Rundeck-Auth-Token': self.token } r = requests.request( method, url, cookies=cookies, headers=h, json=params, verify=self.verify ) logger.debug(r.content) r.raise_for_status() try: return r.json() except ValueError as e: logger.error(e.message) return r.content def __get(self, url, params=None): return self.__request('GET', url, params) def __post(self, url, params=None): return self.__request('POST', url, params) def __delete(self, url, params=None): return self.__request('DELETE', url, params) def list_tokens(self, user=None): url = '{}/tokens'.format(self.API_URL) if user: url += '/{}'.format(user) return self.__get(url) def get_token(self, token_id): url = '{}/token/{}'.format(self.API_URL, token_id) return self.__get(url) def create_token(self, user): url = '{}/tokens/{}'.format(self.API_URL, user) return self.__post(url) def delete_token(self, token_id): url = '{}/token/{}'.format(self.API_URL, token_id) return self.__delete(url) def system_info(self): url = '{}/system/info'.format(self.API_URL) return self.__get(url) def set_active_mode(self): url = '{}/system/executions/enable'.format(self.API_URL) return self.__post(url) def set_passive_mode(self): url = '{}/system/executions/disable'.format(self.API_URL) return self.__post(url) def list_system_acl_policies(self): url = '{}/system/acl/'.format(self.API_URL) return self.__get(url) def get_acl_policy(self, policy): url = '{}/system/acl/{}'.format(self.API_URL, policy) return self.__get(url) def list_projects(self): url = '{}/projects'.format(self.API_URL) return self.__get(url) def list_jobs(self, project): url = '{}/project/{}/jobs'.format(self.API_URL, project) return self.__get(url) def list_all_jobs(self): jobs = [] for p in self.list_projects(): jobs += self.list_jobs(p['name']) return jobs def get_job(self, name, project=None): if project: jobs = self.list_jobs(project) else: jobs = [] for p in self.list_projects(): jobs += self.list_jobs(p['name']) return next(job for job in jobs if job['name'] == name) def run_job(self, job_id, args=None, options=None, log_level=None, as_user=None, node_filter=None): url = '{}/job/{}/run'.format(self.API_URL, job_id) params = { 'logLevel': log_level, 'asUser': as_user, 'filter': node_filter } if options is None: params["argString"] = args else: params["options"] = options return self.__post(url, params=params) def run_job_by_name(self, name, *args, **kwargs): job = self.get_job(name) return self.run_job(job['id'], *args, **kwargs) def get_executions_for_job(self, job_id=None, job_name=None): # http://rundeck.org/docs/api/#getting-executions-for-a-job if not job_id: if not job_name: raise RuntimeError("Either job_name or job_id is required") job_id = self.get_job(job_name).get('id') url = '{}/job/{}/executions'.format(self.API_URL, job_id) return self.__get(url) def query_executions(self, project, name=None, group=None, status=None, user=None, recent=None, older=None, begin=None, end=None, adhoc=None, max_results=20, offset=0): # http://rundeck.org/docs/api/#execution-query url = '{}/project/{}/executions'.format(self.API_URL, project) params = { 'jobListFilter': name, 'userFilter': user, 'groupPath': group, 'statusFilter': status, 'adhoc': adhoc, 'recentFilter': recent, 'olderFilter': older, 'begin': begin, 'end': end, 'max': max_results, 'offset': offset } params = {k: v for k, v in params.items() if v is not None} return self.__get(url, params=params) def list_running_executions(self, project): url = '{}/project/{}/executions/running'.format(self.API_URL, project) return self.__get(url) def execution_state(self, exec_id): url = '{}/execution/{}/state'.format(self.API_URL, exec_id) return self.__get(url) def list_jobs_by_group(self, project, groupPath=None): url = '{}/project/{}/jobs'.format(self.API_URL, project) params = {'groupPath': groupPath} return self.__post(url, params=params) def execution_output_by_id(self, exec_id): url = '{}/execution/{}/output'.format(self.API_URL, exec_id) return self.__get(url) def execution_info_by_id(self, exec_id): url = '{}/execution/{}'.format(self.API_URL, exec_id) return self.__get(url) def abort_execution(self, exec_id): url = '{}/execution/{}/abort'.format(self.API_URL, exec_id) return self.__get(url) def delete_execution(self, exec_id): url = '{}/execution/{}'.format(self.API_URL, exec_id) return self.__delete(url) def bulk_delete_executions(self, exec_ids): url = '{}/executions/{}/delete'.format(self.API_URL) params = {'ids': exec_ids} return self.__post(url, params=params) if __name__ == '__main__': from pprint import pprint rundeck_url = os.environ.get('RUNDECK_URL') username = os.environ.get('RUNDECK_USER') password = os.environ.get('RUNDECK_PASS') assert rundeck_url, 'Rundeck URL is required' assert username, 'Username is required' assert password, 'Password is required' rd = Rundeck( rundeck_url, username=username, password=password, verify=False ) pprint(rd.list_projects()) pprint(rd.list_all_jobs()) pyrundeck-0.9.7/pyrundeck.egg-info/0000755000175000001440000000000013426772423020255 5ustar pschmittusers00000000000000pyrundeck-0.9.7/pyrundeck.egg-info/PKG-INFO0000775000175000001440000000103313426772423021354 0ustar pschmittusers00000000000000Metadata-Version: 2.1 Name: pyrundeck Version: 0.9.7 Summary: Python REST API client for Rundeck 2.6+ Home-page: https://github.com/pschmitt/pyrundeck Author: Philipp Schmitt Author-email: philipp.schmitt@post.lu License: UNKNOWN Description: # Rundeck REST API client This is a Python REST API client for Rundeck 2.6+ ## See also - https://github.com/marklap/rundeckrun ## LICENSE GPL3 Platform: UNKNOWN Description-Content-Type: text/markdown pyrundeck-0.9.7/pyrundeck.egg-info/PKG-INFO.sync-conflict-20180117-195246-4CBPH4P0000775000175000001440000000076112720050564026577 0ustar pschmittusers00000000000000Metadata-Version: 1.0 Name: pyrundeck Version: 0.9 Summary: Python REST API client for Rundeck 2.6+ Home-page: https://github.com/pschmitt/pyrundeck Author: Philipp Schmitt Author-email: philipp.schmitt@post.lu License: UNKNOWN Description: # Rundeck REST API client This is a Python REST API client for Rundeck 2.6+ ## See also - https://github.com/marklap/rundeckrun ## LICENSE GPL3 Platform: UNKNOWN pyrundeck-0.9.7/pyrundeck.egg-info/SOURCES.txt0000775000175000001440000000055113426772423022147 0ustar pschmittusers00000000000000README.md setup.py pyrundeck/__init__.py pyrundeck/rundeck.py pyrundeck.egg-info/PKG-INFO pyrundeck.egg-info/PKG-INFO.sync-conflict-20180117-195246-4CBPH4P pyrundeck.egg-info/SOURCES.txt pyrundeck.egg-info/dependency_links.txt pyrundeck.egg-info/requires.sync-conflict-20180117-195246-4CBPH4P.txt pyrundeck.egg-info/requires.txt pyrundeck.egg-info/top_level.txtpyrundeck-0.9.7/pyrundeck.egg-info/dependency_links.txt0000775000175000001440000000000113426772423024330 0ustar pschmittusers00000000000000 pyrundeck-0.9.7/pyrundeck.egg-info/requires.sync-conflict-20180117-195246-4CBPH4P.txt0000775000175000001440000000002112720050564030067 0ustar pschmittusers00000000000000requests==2.10.0 pyrundeck-0.9.7/pyrundeck.egg-info/requires.txt0000775000175000001440000000001113426772423022652 0ustar pschmittusers00000000000000requests pyrundeck-0.9.7/pyrundeck.egg-info/top_level.txt0000775000175000001440000000001213426772423023005 0ustar pschmittusers00000000000000pyrundeck pyrundeck-0.9.7/setup.cfg0000644000175000001440000000004613426772423016400 0ustar pschmittusers00000000000000[egg_info] tag_build = tag_date = 0 pyrundeck-0.9.7/setup.py0000644000175000001440000000076513426772371016303 0ustar pschmittusers00000000000000#!/usr/bin/env python from setuptools import setup, find_packages setup( name='pyrundeck', version='0.9.7', description='Python REST API client for Rundeck 2.6+', long_description=open('README.md', 'r').read(), long_description_content_type='text/markdown', author='Philipp Schmitt', author_email='philipp.schmitt@post.lu', url='https://github.com/pschmitt/pyrundeck', packages=find_packages(), include_package_data=True, install_requires=['requests'] )