class PlaybookContext(object): STATUS_READY = 'ready' STATUS_STARTED = 'started' STATUS_FINISHED = 'finished' STATE_RUNNING = 'running' STATE_SUCCEEDED = 'succeeded' STATE_FAILED = 'failed' # STATE_ABORTED = 'aborted' # STATE_KILLED = 'killed' STATES = (STATE_RUNNING, STATE_SUCCEEDED, STATE_FAILED) def __init__(self, runid: str, ansible_ws_config: AnsibleWebServiceConfig = None) -> None: self.logger = logging.getLogger(self.__class__.__name__) self.ansible_ws_config = AnsibleWebServiceConfig( ) if ansible_ws_config is None else ansible_ws_config self.runs_dir = self.ansible_ws_config.get('ansible.runs_dir') self.agent_path = self.ansible_ws_config.get("agent.path") self.agent_id = self.ansible_ws_config.get("agent.id") self.runid = runid self.folder = os.path.join(self.runs_dir, self.runid) self.logger.debug(self.folder) self.file_output = os.path.join(self.folder, 'run.out') self.file_error = os.path.join(self.folder, 'run.err') self.file_desc = os.path.join(self.folder, 'run.desc') self.file_status = os.path.join(self.folder, 'run.status') self._description = None @property def description(self): if self._description is None: with open(self.file_desc) as run_desc: self._description = json.load(run_desc) return self._description @property def out(self): if os.path.isfile(self.file_output): with open(self.file_output) as out: run_out = out.read() else: run_out = None return run_out @property def status(self): with open(self.file_status) as run_status: # self.logger.debug(f'read {self.file_status}') status = json.load(run_status) return status
class TestTags(unittest.TestCase): config = AnsibleWebServiceConfig() def test_tasks(self): playbook = os.path.expanduser( '~/ansible-ws/tests/data/playbooks/tags.yml') parameters = { 'playbook': playbook, } request = tests.get_sw2_request('tasks', parameters, cache='refresh') # pprint.pprint(request) sw2 = ScriptWebServiceWrapper(request, self.config) response = sw2.get_result() # pprint.pprint(response) expected = [{ 'name': value, 'value': value } for value in [ 'task11', 'task12 with long name', 'task13', 'debug', 'task21', 'task22', ]] self.assertEqual(response['results'], expected) ### test with cache request['sw2'].pop('cache') sw2 = ScriptWebServiceWrapper(request, self.config) response = sw2.get_result() self.assertEqual(response['results'], expected)
class TestRuns(unittest.TestCase): RUNS_DIR = os.path.join(tests.ANSIBLE_WS_PATH_TEST, 'data', 'runs') ansible_ws_config = AnsibleWebServiceConfig() ansible_ws_config.config['ansible']['runs_dir'] = RUNS_DIR def test_search_basic(self): parameters = { 'from': 'January 1, 2019', } request = tests.get_sw2_request('runs', parameters) # pprint.pprint(request) sw2 = ScriptWebServiceWrapper(request, self.ansible_ws_config) response = sw2.get_result() # pprint.pprint(response) # print(len(response['results'])) self.assertEqual(len(response['results']), 6) def test_search_state(self): parameters = {'from': 'January 1, 2019', 'states': 'failed'} request = tests.get_sw2_request('runs', parameters) # pprint.pprint(request) sw2 = ScriptWebServiceWrapper(request, self.ansible_ws_config) response = sw2.get_result() # pprint.pprint(response) # print(len(response['results'])) self.assertEqual(response['results'][0]['runid'], 'f14529a2-cd83-4d2c-b885-a6184b83f7bc') self.assertEqual(response['results'][1]['runid'], 'f61aef56-9700-48a8-ab1e-f049df76ec0b') self.assertEqual(len(response['results']), 2)
def __init__(self, runid: str, ansible_ws_config: AnsibleWebServiceConfig = None) -> None: self.logger = logging.getLogger(self.__class__.__name__) self.ansible_ws_config = AnsibleWebServiceConfig( ) if ansible_ws_config is None else ansible_ws_config self.runs_dir = self.ansible_ws_config.get('ansible.runs_dir') self.agent_path = self.ansible_ws_config.get("agent.path") self.agent_id = self.ansible_ws_config.get("agent.id") self.runid = runid self.folder = os.path.join(self.runs_dir, self.runid) self.logger.debug(self.folder) self.file_output = os.path.join(self.folder, 'run.out') self.file_error = os.path.join(self.folder, 'run.err') self.file_desc = os.path.join(self.folder, 'run.desc') self.file_status = os.path.join(self.folder, 'run.status') self._description = None
class TestSWSW(unittest.TestCase): config = AnsibleWebServiceConfig() inventories = [ os.path.join(tests.ANSIBLE_WS_PATH_TEST, 'data', 'inventories', 'hosts_database'), os.path.join(tests.ANSIBLE_WS_PATH_TEST, 'data', 'inventories', 'hosts_webserver') ] query = 'groupvars' def test_list(self): parameters = { 'group': 'database_app1_prod', 'key': 'countries.list', 'inventories': self.inventories } request = tests.get_sw2_request(self.query, parameters) # pprint.pprint(request) sw2 = ScriptWebServiceWrapper(request, self.config) response = sw2.get_result() # pprint.pprint(response) expected = [ {'name': value, 'value': value} for value in ['fr', 'it', 'es'] ] self.assertEqual(response['results'], expected) def test_dict(self): parameters = { 'group': 'database_app1_prod', 'key': 'countries.dict', 'inventories': self.inventories } request = tests.get_sw2_request(self.query, parameters) # pprint.pprint(request) sw2 = ScriptWebServiceWrapper(request, self.config) response = sw2.get_result() # pprint.pprint(response) expected = [ {'name': value, 'value': value} for value in ['es', 'fr', 'it'] ] self.assertEqual(response['results'], expected) def test_default(self): parameters = { 'group': 'foo', 'key': 'foo.barr', } request = tests.get_sw2_request(self.query, parameters) # pprint.pprint(request) sw2 = ScriptWebServiceWrapper(request, self.config) response = sw2.get_result() # pprint.pprint(response) expected = [] self.assertEqual(response['results'], expected)
class TestSW2(unittest.TestCase): config = AnsibleWebServiceConfig() def test(self): sw2 = ScriptWebServiceWrapper({}, self.config) response = sw2.get_result() # pprint.pprint(response) self.assertIsInstance(response['errors'], list) self.assertIsInstance(response['errors'][0], str) def test_demo(self): parameters = {'demo1': 'test', 'demo2': ['foo', 'bar']} request = tests.get_sw2_request('demo', parameters) # pprint.pprint(request) sw2 = ScriptWebServiceWrapper(request, self.config) response = sw2.get_result() # pprint.pprint(response) self.assertEqual(response['results'][3]['name'], 'test') self.assertEqual(response['results'][4]['name'], 'foo')
class TestSWSW(unittest.TestCase): config = AnsibleWebServiceConfig() inventory = os.path.join(tests.ANSIBLE_WS_PATH_TEST, 'data', 'inventories') query = 'grapher' def test_grapher(self): grapher_output = '/tmp' self.config.config['grapher']['output'] = grapher_output expected_file = '/tmp/db_prod_11.png' if os.path.isfile(expected_file): os.remove(expected_file) parameters = {'host': 'db_prod_11', 'inventory': self.inventory} request = tests.get_sw2_request(self.query, parameters) # pprint.pprint(request) sw2 = ScriptWebServiceWrapper(request, self.config) response = sw2.get_result() # pprint.pprint(response) self.assertTrue(os.path.isfile(expected_file)) os.remove(expected_file)
class TestSw2Groups(unittest.TestCase): config = AnsibleWebServiceConfig() sources = [ os.path.join(tests.ANSIBLE_WS_PATH_TEST, 'data', 'inventories', 'hosts_database'), os.path.join(tests.ANSIBLE_WS_PATH_TEST, 'data', 'inventories', 'hosts_webserver'), ] query = 'groups' def test_default(self): parameters = { 'pattern': 'all', } request = tests.get_sw2_request(self.query, parameters) # pprint.pprint(request) sw2 = ScriptWebServiceWrapper(request, self.config) response = sw2.get_result() # pprint.pprint(response) self.assertIsInstance(response['results'], list) def test_groups_pattern(self): parameters = {'pattern': 'database', 'sources': self.sources} request = tests.get_sw2_request(self.query, parameters) # pprint.pprint(request) sw2 = ScriptWebServiceWrapper(request, self.config) response = sw2.get_result() # pprint.pprint(response) values = [option['value'] for option in response['results']] expected = [ 'database_app1_dev', 'server_dev_x1', 'server_dev_x2', 'database_app1_prod', 'db_prod_11', 'db_prod_12', 'db_prod_13', 'database_app2_dev', 'server_dev_x1', 'server_dev_x2', 'database_app2_prod', 'db_prod_21', 'db_prod_22', 'db_prod_23', ] # pprint.pprint(values) self.assertEqual(values, expected) self.assertEqual(response['results'][0]['disabled'], True) self.assertEqual(response['results'][3]['disabled'], True) self.assertEqual(response['results'][7]['disabled'], True) self.assertEqual(response['results'][10]['disabled'], True) def test_groups_list(self): parameters = { 'pattern': '(database_app1_dev|database_app2_prod)', 'groups_selection': 'yes', 'sources': self.sources } request = tests.get_sw2_request(self.query, parameters) # pprint.pprint(request) sw2 = ScriptWebServiceWrapper(request, self.config) response = sw2.get_result() # pprint.pprint(response) values = [option['value'] for option in response['results']] expected = [ 'database_app1_dev', 'server_dev_x1', 'server_dev_x2', 'database_app2_prod', 'db_prod_21', 'db_prod_22', 'db_prod_23', ] # pprint.pprint(values) self.assertEqual(values, expected) self.assertEqual(response['results'][0]['disabled'], False) self.assertEqual(response['results'][3]['disabled'], False)
class TestSshAgent(unittest.TestCase): key1 = os.path.join(tests.ANSIBLE_WS_PATH_TEST, 'data', 'agent', 'key1') key2 = os.path.join(tests.ANSIBLE_WS_PATH_TEST, 'data', 'agent', 'key2') config = AnsibleWebServiceConfig() def get_public_key(self, file): with open(f'{file}.pub') as fstream: raw = fstream.read() pub_key = raw.split(os.linesep)[0] return pub_key def test(self): ssh_agent = SshAgent('ansible-ws-unittest') ssh_auth_sock = ssh_agent.env["SSH_AUTH_SOCK"] # print(ssh_auth_sock) ssh_agent = SshAgent('ansible-ws-unittest') ssh_auth_sock2 = ssh_agent.env["SSH_AUTH_SOCK"] # print(ssh_auth_sock2) self.assertEqual(ssh_auth_sock, ssh_auth_sock2) rc, output = ssh_agent.kill() self.assertEqual(rc, 0) # sure to have new agent without key ssh_agent = SshAgent('ansible-ws-unittest') ssh_agent.load_key(self.key1, 'key1') # pprint.pprint(ssh_agent.keys) pub_key1 = self.get_public_key(self.key1) # pprint.pprint(pub_key1) self.assertEqual(len(ssh_agent.keys), 1) self.assertIn(pub_key1, ssh_agent.keys) ssh_agent = SshAgent('ansible-ws-unittest') self.assertEqual(len(ssh_agent.keys), 1) self.assertIn(pub_key1, ssh_agent.keys) ssh_agent.load_key(self.key2, 'key2') pub_key2 = self.get_public_key(self.key2) # pprint.pprint(ssh_agent.keys) self.assertIn(pub_key1, ssh_agent.keys) self.assertIn(pub_key2, ssh_agent.keys) rc, output = ssh_agent.kill() self.assertEqual(rc, 0) def test_sw2(self): id = 'ansible-ws-unittest' # KILL parameters = { 'id': id, } request = tests.get_sw2_request('SSHAgentKill', parameters) # pprint.pprint(request) sw2 = ScriptWebServiceWrapper(request, self.config) response = sw2.get_result() # pprint.pprint(response) self.assertEqual(response['results']['keys'], None) self.assertEqual(response['results']['action'], 'kill') self.assertEqual(response['results']['rc'], 0) # INFO parameters = { 'id': id, } request = tests.get_sw2_request('SSHAgent', parameters) # pprint.pprint(request) sw2 = ScriptWebServiceWrapper(request, self.config) response = sw2.get_result() # pprint.pprint(response) self.assertEqual(response['results']['keys'], []) self.assertEqual(response['results']['action'], 'init') # ADD parameters = { 'id': id, 'private_key': self.key1, 'passphrase': 'key1', } request = tests.get_sw2_request('SSHAgentAdd', parameters) # pprint.pprint(request) sw2 = ScriptWebServiceWrapper(request, self.config) response = sw2.get_result() # pprint.pprint(response) self.assertEqual(response['results']['action'], 'add') self.assertTrue(response['results']['keys'][0].startswith('ssh-rsa ')) # KILL parameters = { 'id': id, } request = tests.get_sw2_request('SSHAgentKill', parameters) # pprint.pprint(request) sw2 = ScriptWebServiceWrapper(request, self.config) response = sw2.get_result() # pprint.pprint(response) self.assertEqual(response['results']['keys'], None) self.assertEqual(response['results']['action'], 'kill') self.assertEqual(response['results']['rc'], 0)
import traceback import json import logging import urllib from urllib.parse import parse_qs import wsgi_utils import ansible_ws from ansible_ws import AnsibleWebServiceConfig import sw2 from sw2 import ScriptWebServiceWrapper logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) config = AnsibleWebServiceConfig() def application(environ, start_response): try: method = environ['REQUEST_METHOD'] content_type = environ.get('CONTENT_TYPE') if content_type in (wsgi_utils.CONTENT_TYPE_JSON, None): if method == 'GET': raw_qs = environ.get('QUERY_STRING') if raw_qs == '': raw_qs = '{}' qs = urllib.parse.unquote_plus(raw_qs, encoding='utf-8') parameters = json.loads(qs) elif method == 'POST': request_body_size = int(environ.get('CONTENT_LENGTH', 0))
def test(self): config = AnsibleWebServiceConfig() value = config.get('unittest.unittest.unittest') self.assertEqual(value, 'unittest')
class TestAnsibleLaunch(unittest.TestCase): RUNS_DIR = os.path.join(tests.ANSIBLE_WS_PATH_TEST, 'data', 'runs_tmp') playbook = os.path.join(tests.ANSIBLE_WS_PATH_TEST, 'data', 'playbooks', 'tags.yml') config = AnsibleWebServiceConfig() config.config['ansible']['runs_dir'] = RUNS_DIR @classmethod def tearDownClass(cls): super(TestAnsibleLaunch, cls).tearDownClass() shutil.rmtree(cls.RUNS_DIR) def test_run(self): context = { 'playbook': self.playbook, 'cmdline': f'ansible-playbook {self.playbook} -v', 'ansible_ws_config': self.config } pcl = PlaybookContextLaunch(**context) # print(pcl.runid) pc = PlaybookContext(pcl.runid, ansible_ws_config=self.config) self.assertIsNone(pc.out) context.pop('ansible_ws_config') self.assertEqual(pc.description, context) status = pc.status runid = status['runid'] self.assertEqual(len(runid.split('-')), 5) self.assertEqual(status['status'], pc.STATUS_READY) self.assertIsNone(status['begin']) self.assertIsNone(status['end']) self.assertIsNone(status['pid']) self.assertIsNone(status['return_code']) pcl.run() # pprint.pprint(pc.out) self.assertIsNotNone(pc.out) status = pc.status # pprint.pprint(status) self.assertEqual(status['status'], pc.STATUS_FINISHED) self.assertIsInstance(status['begin'], float) self.assertIsInstance(status['end'], float) self.assertIsInstance(status['pid'], int) self.assertEqual(status['return_code'], 0) def test_sw2(self): parameters = { 'cmdline': f'ansible-playbook {self.playbook} -v', 'playbook': self.playbook, } request = tests.get_sw2_request('launch', parameters) # pprint.pprint(request) sw2 = ScriptWebServiceWrapper(request, self.config) response = sw2.get_result() # pprint.pprint(response) results = response['results'] # pprint.pprint(results) self.assertIsNone(results['return_code']) self.assertEqual(results['state'], PlaybookContext.STATE_RUNNING) self.assertEqual(results['status'], PlaybookContext.STATUS_READY) runid = results['runid'] parameters = { 'runid': runid } request = tests.get_sw2_request('run', parameters) # pprint.pprint(request) sw2 = ScriptWebServiceWrapper(request, self.config) response = sw2.get_result() # pprint.pprint(response) status = response['results']['status'] # pprint.pprint(status) self.assertEqual(status['runid'], runid) while status['status'] != PlaybookContext.STATUS_FINISHED: time.sleep(5) sw2 = ScriptWebServiceWrapper(request, self.config) response = sw2.get_result() # pprint.pprint(response) status = response['results']['status'] self.assertEqual(status['return_code'], 0) self.assertEqual(status['state'], PlaybookContext.STATE_SUCCEEDED) self.assertEqual(status['status'], PlaybookContext.STATUS_FINISHED)