Skip to content

Commit

Permalink
typo fixes + unittests
Browse files Browse the repository at this point in the history
  • Loading branch information
lfkdev committed Jun 24, 2024
1 parent 3be3a55 commit 91df999
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 8 deletions.
27 changes: 27 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Ansible-Link CI

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run tests
run: python -m unittest discover tests
- name: Run linter
run: |
pip install flake8
flake8 .
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<div>
<h1>ANSIBLE LINK</h1>
<p>
RESTful API for executing Ansible playbooks remotely. It allows users to trigger playbook executions, pass custom variables, and track the status of each execution.
RESTful API for executing Ansible playbooks remotely
</p>
</div>
</div>
Expand Down Expand Up @@ -59,7 +59,7 @@ playbook_dir: '/etc/ansible/'
inventory_dir: '/etc/ansible/hosts'
ansible_playbook_cmd: 'ansible-playbook'

job_storage_dir: '/var/lib/ansible-link/job_storage'
job_storage_dir: '/var/lib/ansible-link/job-storage'

log_level: 'INFO'
log_file: '/var/log/ansible-link/api.log'
Expand Down
8 changes: 6 additions & 2 deletions ansible-link/ansible-link.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,12 @@

app = Flask(__name__)
app.wsgi_app = ProxyFix(app.wsgi_app)
api = Api(app, version='0.9', title='ANSIBLE-LINK',
description='API for executing Ansible playbooks')
api = Api(app,
version='0.9',
title='ANSIBLE-LINK',
description='API for executing Ansible playbooks',
external_doc={'description': 'GitHub', 'url': 'https://github.com/lfkdev/ansible-link'}
)

ns = api.namespace('ansible', description='Ansible operations')

Expand Down
10 changes: 6 additions & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
Flask==2.0.1
flask-restx==0.5.1
PyYAML==5.4.1
ansible-runner==2.3.2
flask
flask-restx
ansible-runner
werkzeug
pyyaml
pytest
91 changes: 91 additions & 0 deletions tests/test_ansible_link.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import unittest
from unittest.mock import patch, MagicMock
from flask import Flask
from flask.testing import FlaskClient
import json
import yaml
from pathlib import Path

# Import the main application
from ansible_link.ansible_link import app, load_config, validate_playbook, run_playbook

class TestAnsibleLink(unittest.TestCase):
def setUp(self):
self.app = app.test_client()
self.app.testing = True

@patch('ansible_link.load_config')
def test_load_config(self, mock_load_config):
mock_config = {
'playbook_dir': '/tmp/playbooks',
'inventory_dir': '/tmp/inventory',
'job_storage_dir': '/tmp/job-storage',
'playbook_whitelist': ['test_playbook.yml']
}
mock_load_config.return_value = mock_config
config = load_config()
self.assertEqual(config, mock_config)

@patch('ansible_link.config')
@patch('pathlib.Path.is_file')
def test_validate_playbook_valid(self, mock_is_file, mock_config):
mock_config.__getitem__.return_value = '/tmp/playbooks'
mock_is_file.return_value = True
result = validate_playbook('test_playbook.yml')
self.assertEqual(result, '/tmp/playbooks/test_playbook.yml')

@patch('ansible_link.config')
@patch('pathlib.Path.is_file')
def test_validate_playbook_invalid(self, mock_is_file, mock_config):
mock_config.__getitem__.return_value = '/tmp/playbooks'
mock_is_file.return_value = False
with self.assertRaises(ValueError):
validate_playbook('invalid_playbook.yml')

@patch('ansible_runner.run')
@patch('ansible_link.validate_playbook')
def test_run_playbook(self, mock_validate_playbook, mock_ansible_runner):
mock_validate_playbook.return_value = '/tmp/playbooks/test_playbook.yml'
mock_runner = MagicMock()
mock_runner.status = 'successful'
mock_runner.stdout.read.return_value = 'Playbook output'
mock_runner.stderr.read.return_value = ''
mock_runner.stats = {'ok': 1, 'failed': 0}
mock_ansible_runner.return_value = mock_runner

job_id = 'test_job_id'
playbook = 'test_playbook.yml'
inventory = 'test_inventory'
vars = {'test_var': 'value'}

run_playbook(job_id, playbook, inventory, vars)

self.assertEqual(mock_ansible_runner.call_count, 1)
self.assertEqual(mock_validate_playbook.call_count, 1)

def test_playbook_endpoint(self):
data = {
'playbook': 'test_playbook.yml',
'inventory': 'test_inventory',
'vars': {'test_var': 'value'}
}
response = self.app.post('/ansible/playbook', json=data)
self.assertEqual(response.status_code, 202)
result = json.loads(response.data)
self.assertIn('job_id', result)
self.assertEqual(result['status'], 'running')

def test_jobs_endpoint(self):
response = self.app.get('/ansible/jobs')
self.assertEqual(response.status_code, 200)
result = json.loads(response.data)
self.assertIsInstance(result, dict)

def test_health_check(self):
response = self.app.get('/health')
self.assertEqual(response.status_code, 200)
result = json.loads(response.data)
self.assertEqual(result['status'], 'healthy')

if __name__ == '__main__':
unittest.main()

0 comments on commit 91df999

Please sign in to comment.