Skip to content

Commit fa1b914

Browse files
authored
Merge pull request #421 from rundeck-plugins/inventory_with_auth
RUN-4085 Generate Inventory with SSH password authentication
2 parents b58ee44 + 7db271f commit fa1b914

24 files changed

Lines changed: 2195 additions & 64 deletions

functional-test/README.md

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# Functional Tests for Ansible Plugin
2+
3+
This directory contains functional tests for the Rundeck Ansible plugin using Testcontainers and Docker.
4+
5+
## Prerequisites
6+
7+
- Docker (Docker Desktop or Rancher Desktop)
8+
- Java 11 or later
9+
- Gradle 7.2 or later
10+
11+
## Docker Configuration
12+
13+
The functional tests use Testcontainers to spin up Docker containers for Rundeck and SSH nodes. Depending on your Docker setup, you may need to configure the Docker socket path.
14+
15+
### Option 1: Using ~/.testcontainers.properties (Recommended)
16+
17+
Create a file at `~/.testcontainers.properties` with the following content:
18+
19+
**For Rancher Desktop on macOS:**
20+
```properties
21+
docker.host=unix:///Users/<your-username>/.rd/docker.sock
22+
```
23+
24+
**For Docker Desktop on macOS/Linux:**
25+
```properties
26+
docker.host=unix:///var/run/docker.sock
27+
```
28+
29+
**For Windows with Docker Desktop:**
30+
```properties
31+
docker.host=tcp://localhost:2375
32+
```
33+
34+
### Option 2: Modify build.gradle
35+
36+
Edit `functional-test/build.gradle` and update the `docker.host` paths on lines 52-53:
37+
38+
```gradle
39+
systemProperty('docker.host', "unix:///path/to/your/docker.sock")
40+
environment 'DOCKER_HOST', 'unix:///path/to/your/docker.sock'
41+
```
42+
43+
## Running the Tests
44+
45+
### Run All Functional Tests
46+
47+
```bash
48+
./gradlew :functional-test:functionalTest
49+
```
50+
51+
### Run Specific Test Suite
52+
53+
```bash
54+
# Multi-node authentication tests
55+
./gradlew :functional-test:functionalTest --tests "*MultiNodeAuthSpec*"
56+
57+
# Basic integration tests
58+
./gradlew :functional-test:functionalTest --tests "*BasicIntegrationSpec*"
59+
60+
# Plugin group tests
61+
./gradlew :functional-test:functionalTest --tests "*PluginGroupIntegrationSpec*"
62+
```
63+
64+
## Test Suites
65+
66+
### MultiNodeAuthSpec
67+
Tests the multi-node authentication feature where each node can have its own password stored in Rundeck's key storage.
68+
69+
**Tests:**
70+
- `test ansible playbook with multi-node authentication` - Verifies Ansible playbooks execute across multiple nodes with per-node credentials
71+
- `test multi-node authentication with different passwords` - Tests script execution on multiple nodes with different passwords
72+
- `test nodes are accessible with different credentials` - Validates node registration and discovery
73+
- `test passwords with special characters are properly escaped` - Verifies YAML escaping for special characters in passwords
74+
75+
**Test Environment:**
76+
- 3 SSH nodes (ssh-node, ssh-node-2, ssh-node-3)
77+
- Each node has a different password, including special characters
78+
- Tests both WorkflowStep (Ansible playbooks) and NodeStep (scripts) execution
79+
80+
### BasicIntegrationSpec
81+
Basic integration tests for the Ansible plugin functionality.
82+
83+
### PluginGroupIntegrationSpec
84+
Tests for plugin group configuration and execution.
85+
86+
## Test Structure
87+
88+
```
89+
functional-test/
90+
├── build.gradle # Test configuration
91+
├── README.md # This file
92+
└── src/
93+
└── test/
94+
├── groovy/functional/ # Test specifications
95+
│ ├── MultiNodeAuthSpec.groovy
96+
│ ├── BasicIntegrationSpec.groovy
97+
│ └── PluginGroupIntegrationSpec.groovy
98+
└── resources/
99+
├── docker/ # Docker compose and configs
100+
│ ├── docker-compose.yml
101+
│ ├── ansible-multi-node-auth/ # Multi-node test configs
102+
│ ├── keys/ # SSH keys for tests
103+
│ ├── node/ # SSH node Docker configs
104+
│ └── rundeck/ # Rundeck Docker configs
105+
└── project-import/ # Rundeck project definitions
106+
└── ansible-multi-node-auth/
107+
└── rundeck-ansible-multi-node-auth/
108+
├── files/etc/project.properties
109+
└── jobs/*.xml
110+
```
111+
112+
## Troubleshooting
113+
114+
### Tests Fail with "Could not find Docker socket"
115+
116+
**Problem:** Testcontainers cannot locate the Docker socket.
117+
118+
**Solution:**
119+
1. Verify Docker is running: `docker ps`
120+
2. Check your Docker socket path:
121+
- Rancher Desktop: `ls -la ~/.rd/docker.sock`
122+
- Docker Desktop: `ls -la /var/run/docker.sock`
123+
3. Update `~/.testcontainers.properties` or `build.gradle` with the correct path
124+
125+
### Tests Timeout or Hang
126+
127+
**Problem:** Tests take too long or appear to hang.
128+
129+
**Solution:**
130+
1. Check Docker container status: `docker ps -a`
131+
2. Check Docker logs: `docker logs <container-id>`
132+
3. Increase test timeout in build.gradle if needed
133+
4. Ensure sufficient Docker resources (memory/CPU)
134+
135+
### Port Conflicts
136+
137+
**Problem:** Tests fail with "port already in use" errors.
138+
139+
**Solution:**
140+
1. Check for running containers: `docker ps`
141+
2. Stop conflicting containers: `docker stop <container-name>`
142+
3. Clean up: `docker-compose down` in the docker directory
143+
144+
### Platform Mismatch Warnings (Apple Silicon)
145+
146+
**Problem:** Warnings about platform mismatch (linux/amd64 vs linux/arm64).
147+
148+
**Solution:** These warnings are expected on Apple Silicon Macs and can be safely ignored. Docker will use Rosetta 2 for emulation.
149+
150+
## Test Reports
151+
152+
After running tests, view the HTML report at:
153+
```
154+
functional-test/build/reports/tests/functionalTest/index.html
155+
```
156+
157+
## Adding New Tests
158+
159+
1. Create a new Spock specification in `src/test/groovy/functional/`
160+
2. Extend `BaseTestConfiguration` for common test utilities
161+
3. Add any required Docker configs to `src/test/resources/docker/`
162+
4. Add project imports to `src/test/resources/project-import/`
163+
5. Follow existing test patterns for consistency
164+
165+
## Multi-Node Authentication Feature
166+
167+
The multi-node authentication feature allows running Ansible playbooks across multiple nodes where each node has its own password stored in Rundeck's key storage.
168+
169+
**How it works:**
170+
1. Enable at project level: `project.ansible-generate-inventory-nodes-auth=true`
171+
2. Store per-node passwords in Key Storage with paths specified in node attributes
172+
3. Plugin generates `group_vars/all.yaml` with vault-encrypted passwords
173+
4. Ansible uses host-specific credentials from group_vars
174+
175+
**Requirements:**
176+
- Must use Ansible Playbook **Workflow Steps** (not Node Steps); the multi-node authentication logic and inventory generation are only implemented for the Workflow Step variant of the plugin and are not executed for Node Steps, so enabling `project.ansible-generate-inventory-nodes-auth` while using Node Steps will not apply per-node credentials. This limitation exists because Node Steps run independently on each target node and do not share the global inventory context that the multi-node authentication feature relies on.
177+
- Node attributes must include `ansible-ssh-password-storage-path` for each node
178+
- Passwords are automatically encrypted using Ansible Vault
179+
- Supports special characters with proper YAML escaping
180+
181+
See `MultiNodeAuthSpec.groovy` for comprehensive test examples.

functional-test/build.gradle

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,20 @@ dependencies {
4242

4343
tasks.register('functionalTest', Test) {
4444
useJUnitPlatform()
45-
systemProperty('RUNDECK_TEST_IMAGE', "rundeck/rundeck:5.1.1")
45+
46+
// Rundeck test image version
47+
// Minimum supported Rundeck version for this plugin: 5.1.1 (see main README/changelog).
48+
// Functional tests intentionally run against a newer version, Rundeck 5.18.0, to validate
49+
// compatibility with current releases. When raising the minimum supported version, update
50+
// this test image tag in tandem.
51+
systemProperty('RUNDECK_TEST_IMAGE', "rundeck/rundeck:5.18.0")
52+
53+
// Docker configuration for Testcontainers
54+
// For Rancher Desktop on macOS: Use /Users/<username>/.rd/docker.sock
55+
// For Docker Desktop on macOS: Use /var/run/docker.sock
56+
// For Linux: Use /var/run/docker.sock
57+
// You can also configure this via ~/.testcontainers.properties (see functional-test/README.md)
58+
4659
description = "Run Ansible integration tests"
4760
}
4861

0 commit comments

Comments
 (0)