From 03790c7e9862d881f9fa477b890fdd7e618d4582 Mon Sep 17 00:00:00 2001 From: SquirrelDevelopper Date: Tue, 15 Oct 2024 09:51:27 +0200 Subject: [PATCH 1/7] Append --vault-id to ansible runner command Add --vault-id ssm@ssm-ansible-vault-password-client.py to the command line arguments if 'cmdline' exists in runner_args. This ensures the vault ID is always passed for secure password management. --- server/src/ansible/ssm-ansible-run.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/src/ansible/ssm-ansible-run.py b/server/src/ansible/ssm-ansible-run.py index 49ceba9c..c2043b99 100644 --- a/server/src/ansible/ssm-ansible-run.py +++ b/server/src/ansible/ssm-ansible-run.py @@ -103,6 +103,8 @@ def execute(): runner_args['cmdline'] += ' --diff' else: runner_args['cmdline'] = '--diff' + if 'cmdline' in runner_args: + runner_args['cmdline'] += ' --vault-id ssm@ssm-ansible-vault-password-client.py' thread_obj, runner_obj = ansible_runner.run_async(**runner_args) sys.stdout.write(runner_obj.config.ident) From 12a54fea2009f595c62f467edc006857a1a3a7f0 Mon Sep 17 00:00:00 2001 From: SquirrelDevelopper Date: Tue, 15 Oct 2024 11:01:12 +0200 Subject: [PATCH 2/7] Add unit tests for `ssm-ansible-run.py` and update workflow Added comprehensive unit tests for `ssm-ansible-run.py` to validate different flag and parameter combinations. Updated GitHub workflow to include Python tests, ensuring thorough CI coverage. --- .github/workflows/test-server.yml | 3 + server/src/ansible/test_ssm_ansible_run.py | 147 +++++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 server/src/ansible/test_ssm_ansible_run.py diff --git a/.github/workflows/test-server.yml b/.github/workflows/test-server.yml index 603f561a..af33c926 100644 --- a/.github/workflows/test-server.yml +++ b/.github/workflows/test-server.yml @@ -44,3 +44,6 @@ jobs: - name: Test working-directory: ./server run: npm test + - name: Test Python + working-directory: ./server + run: npm test:python \ No newline at end of file diff --git a/server/src/ansible/test_ssm_ansible_run.py b/server/src/ansible/test_ssm_ansible_run.py new file mode 100644 index 00000000..72563be7 --- /dev/null +++ b/server/src/ansible/test_ssm_ansible_run.py @@ -0,0 +1,147 @@ +import unittest +from unittest.mock import patch, MagicMock +import subprocess + +class TestSSMAnsibleRun(unittest.TestCase): + + @patch('requests.post') + @patch('requests_unixsocket.Session.post') + def test_execute_with_check_and_diff(self, mock_unix_post, mock_post): + + mock_post.return_value = MagicMock(status_code=200) + mock_unix_post.return_value = MagicMock(status_code=200) + + test_args = [ + 'python3', 'ssm-ansible-run.py', + '--playbook', 'test_playbook.yml', + '--ident', 'test_uuid', + '--check', '--diff' + ] + + result = subprocess.run(test_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + self.assertEqual(result.returncode, 0) + self.assertIn('test_uuid', result.stdout.decode()) + + @patch('requests.post') + @patch('requests_unixsocket.Session.post') + def test_execute_without_check_and_diff(self, mock_unix_post, mock_post): + + mock_post.return_value = MagicMock(status_code=200) + mock_unix_post.return_value = MagicMock(status_code=200) + + test_args = [ + 'python3', 'ssm-ansible-run.py', + '--playbook', 'test_playbook.yml', + '--ident', 'test_uuid' + ] + + result = subprocess.run(test_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + self.assertEqual(result.returncode, 0) + self.assertIn('test_uuid', result.stdout.decode()) + + @patch('requests.post') + @patch('requests_unixsocket.Session.post') + def test_execute_with_extra_vars_and_host_pattern(self, mock_unix_post, mock_post): + + mock_post.return_value = MagicMock(status_code=200) + mock_unix_post.return_value = MagicMock(status_code=200) + + extra_vars_json = '{"var1": "value1", "var2": "value2"}' + test_args = [ + 'python3', 'ssm-ansible-run.py', + '--playbook', 'test_playbook.yml', + '--ident', 'test_uuid', + '--extra-vars', extra_vars_json, + '--host-pattern', 'test_host' + ] + + result = subprocess.run(test_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + self.assertEqual(result.returncode, 0) + self.assertIn('test_uuid', result.stdout.decode()) + + @patch('requests.post') + @patch('requests_unixsocket.Session.post') + def test_execute_with_specific_host(self, mock_unix_post, mock_post): + + mock_post.return_value = MagicMock(status_code=200) + mock_unix_post.return_value = MagicMock(status_code=200) + + specific_host_json = '{"name": "test_host", "address": "127.0.0.1"}' # Ensure specific host JSON is a proper string + test_args = [ + 'python3', 'ssm-ansible-run.py', + '--playbook', 'test_playbook.yml', + '--ident', 'test_uuid', + '--specific-host', specific_host_json + ] + + result = subprocess.run(test_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + self.assertEqual(result.returncode, 0) + self.assertIn('test_uuid', result.stdout.decode()) + + @patch('requests.post') + @patch('requests_unixsocket.Session.post') + def test_execute_with_invalid_extra_vars(self, mock_unix_post, mock_post): + + mock_post.return_value = MagicMock(status_code=200) + mock_unix_post.return_value = MagicMock(status_code=200) + + invalid_extra_vars_json = "{invalid_json}" + test_args = [ + 'python3', 'ssm-ansible-run.py', + '--playbook', 'test_playbook.yml', + '--ident', 'test_uuid', + '--extra-vars', invalid_extra_vars_json + ] + + result = subprocess.run(test_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + self.assertNotEqual(result.returncode, 0) + self.assertIn('Expecting property name enclosed in double quotes', result.stderr.decode()) + + + @patch('requests.post') + @patch('requests_unixsocket.Session.post') + def test_execute_with_mixed_flags_and_options(self, mock_unix_post, mock_post): + + mock_post.return_value = MagicMock(status_code=200) + mock_unix_post.return_value = MagicMock(status_code=200) + + extra_vars_json = '{"var1": "value1", "var2": "value2"}' # Correct JSON format + specific_host_json = '{"name": "test_host", "address": "127.0.0.1"}' # Ensure it's a proper string + test_args = [ + 'python3', 'ssm-ansible-run.py', + '--playbook', 'test_playbook.yml', + '--ident', 'test_uuid', + '--extra-vars', extra_vars_json, + '--specific-host', specific_host_json, + '--check', '--diff' + ] + + result = subprocess.run(test_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + self.assertEqual(result.returncode, 0) + self.assertIn('test_uuid', result.stdout.decode()) + + @patch('requests.post') + @patch('requests_unixsocket.Session.post') + def test_execute_without_required_arguments(self, mock_unix_post, mock_post): + + mock_post.return_value = MagicMock(status_code=200) + mock_unix_post.return_value = MagicMock(status_code=200) + + test_args = [ + 'python3', 'ssm-ansible-run.py' + ] + + result = subprocess.run(test_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + self.assertNotEqual(result.returncode, 0) + self.assertIn('the following arguments are required: --playbook, --ident', result.stderr.decode()) + + +if __name__ == '__main__': + unittest.main() From e3bdb733b18135e86e84ab2c52457663e16dd69a Mon Sep 17 00:00:00 2001 From: SquirrelDevelopper Date: Tue, 15 Oct 2024 11:04:38 +0200 Subject: [PATCH 3/7] Fix Python test script command in CI workflow Updated the command to run Python tests within the CI workflow from 'npm test:python' to 'npm run test:python'. This ensures the correct execution of the Python test script. --- .github/workflows/test-server.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-server.yml b/.github/workflows/test-server.yml index af33c926..69870516 100644 --- a/.github/workflows/test-server.yml +++ b/.github/workflows/test-server.yml @@ -46,4 +46,4 @@ jobs: run: npm test - name: Test Python working-directory: ./server - run: npm test:python \ No newline at end of file + run: npm run test:python \ No newline at end of file From 00fcd79b1704239b64838f22daaa81e720aab69a Mon Sep 17 00:00:00 2001 From: SquirrelDevelopper Date: Tue, 15 Oct 2024 11:06:30 +0200 Subject: [PATCH 4/7] Add Python unit test script to package.json Included a new npm script 'test:python' to run Python unit tests located in the Ansible directory using unittest. This update ensures Python tests can be executed consistently within the same workflow as other npm scripts. --- server/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/server/package.json b/server/package.json index e216f801..072739b4 100644 --- a/server/package.json +++ b/server/package.json @@ -8,6 +8,7 @@ "start": "npm run build-shared && npm run build && cross-env NODE_ENV=production node dist/index.js", "build": "tsc", "test": "vitest --disable-console-intercept --reporter=basic ", + "test:python": "cd ./src/ansible && python3 -m unittest discover -s . -p \"*.py\"", "coverage": "vitest run --coverage" }, "version": "0.1.21", From 2dec2e2e680391f8463d157a4972aa4d1f0380b5 Mon Sep 17 00:00:00 2001 From: SquirrelDevelopper Date: Tue, 15 Oct 2024 11:11:24 +0200 Subject: [PATCH 5/7] Add Python test dependencies auto-install Updated the npm "test:python" script to automatically install required Python dependencies from requirements.txt. This ensures that all necessary dependencies are installed before running the tests, improving test reliability and developer experience. --- server/package.json | 4 +++- server/src/ansible/requirements.txt | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 server/src/ansible/requirements.txt diff --git a/server/package.json b/server/package.json index 072739b4..55971bba 100644 --- a/server/package.json +++ b/server/package.json @@ -8,7 +8,9 @@ "start": "npm run build-shared && npm run build && cross-env NODE_ENV=production node dist/index.js", "build": "tsc", "test": "vitest --disable-console-intercept --reporter=basic ", - "test:python": "cd ./src/ansible && python3 -m unittest discover -s . -p \"*.py\"", + "test:python:install": "pip install -r ./src/ansible/requirements.txt", + "test:python": "npm run test:python:install && npm run test:python:run", + "test:python:run": "cd ./src/ansible && python3 -m unittest discover -s . -p \"*.py\"", "coverage": "vitest run --coverage" }, "version": "0.1.21", diff --git a/server/src/ansible/requirements.txt b/server/src/ansible/requirements.txt new file mode 100644 index 00000000..a3e2b3af --- /dev/null +++ b/server/src/ansible/requirements.txt @@ -0,0 +1,3 @@ +requests +mock +requests_unixsocket From b2db28e20769334dbc9e8e34ade53d4e7144265d Mon Sep 17 00:00:00 2001 From: SquirrelDevelopper Date: Tue, 15 Oct 2024 11:13:18 +0200 Subject: [PATCH 6/7] Add flag to Python dependency installation command Updated the `test:python:install` script to include the `--break-system-packages` flag. This ensures compatibility with certain Python environments and prevents issues related to system package conflicts during installation. --- server/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/package.json b/server/package.json index 55971bba..6b49cfdc 100644 --- a/server/package.json +++ b/server/package.json @@ -8,7 +8,7 @@ "start": "npm run build-shared && npm run build && cross-env NODE_ENV=production node dist/index.js", "build": "tsc", "test": "vitest --disable-console-intercept --reporter=basic ", - "test:python:install": "pip install -r ./src/ansible/requirements.txt", + "test:python:install": "pip install -r ./src/ansible/requirements.txt --break-system-packages", "test:python": "npm run test:python:install && npm run test:python:run", "test:python:run": "cd ./src/ansible && python3 -m unittest discover -s . -p \"*.py\"", "coverage": "vitest run --coverage" From a7af59c4e98da169dcff2c0b8ea628376868feb6 Mon Sep 17 00:00:00 2001 From: SquirrelDevelopper Date: Tue, 15 Oct 2024 11:15:43 +0200 Subject: [PATCH 7/7] Add ansible-runner to requirements This change adds the ansible-runner package to the requirements.txt file. It ensures that ansible-runner is available as a dependency for project builds and deployments. --- server/src/ansible/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/server/src/ansible/requirements.txt b/server/src/ansible/requirements.txt index a3e2b3af..591a30c9 100644 --- a/server/src/ansible/requirements.txt +++ b/server/src/ansible/requirements.txt @@ -1,3 +1,4 @@ requests mock requests_unixsocket +ansible-runner