Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add spire-agent CLI commands integration test #4969

Merged
merged 9 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions test/integration/suites/agent-cli/00-setup
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

"${ROOTDIR}/setup/x509pop/setup.sh" conf/server conf/agent

"${ROOTDIR}/setup/debugserver/build.sh" "${RUNDIR}/conf/server/debugclient"
"${ROOTDIR}/setup/debugagent/build.sh" "${RUNDIR}/conf/agent/debugclient"
3 changes: 3 additions & 0 deletions test/integration/suites/agent-cli/01-start-server
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

docker-up spire-server
5 changes: 5 additions & 0 deletions test/integration/suites/agent-cli/02-bootstrap-agent
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

log-debug "bootstrapping agent..."
docker-compose exec -T spire-server \
/opt/spire/bin/spire-server bundle show > conf/agent/bootstrap.crt
3 changes: 3 additions & 0 deletions test/integration/suites/agent-cli/03-start-agent
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

docker-up spire-agent
33 changes: 33 additions & 0 deletions test/integration/suites/agent-cli/04-check-healthy
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/bin/bash

RETRIES=20
AGENT_FOUND=0
HEALTHCHECK=0
HEALTHCHECK_FAIL=0

for ((m=1;m<=$RETRIES;m++)); do

AGENTS=$(docker-compose exec -T spire-server /opt/spire/bin/spire-server agent list)
if [ "$AGENTS" != "No attested agents found" ]; then
AGENT_FOUND=1
break
fi

done

HEALTH=$(docker-compose exec -T spire-agent /opt/spire/bin/spire-agent healthcheck)
HEALTH_FAIL=$(docker-compose exec -T spire-agent /opt/spire/bin/spire-agent healthcheck -socketPath invalid/path 2>&1 &)

if [[ "$HEALTH" =~ "Agent is healthy." ]]; then
HEALTHCHECK=1
fi

if [[ "$HEALTH_FAIL" =~ "Agent is unhealthy: unable to determine health" ]]; then
HEALTHCHECK_FAIL=1
fi

if [ $AGENT_FOUND -eq 1 ] && [ $HEALTHCHECK -eq 1 ] && [ $HEALTHCHECK_FAIL -eq 1 ]; then
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how can we know witch one fails? may we verify one at time? (same comment for all test cases)

exit 0
else
exit 1
fi
24 changes: 24 additions & 0 deletions test/integration/suites/agent-cli/05-check-valid-config
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash

VALID_CONFIG=0
INVALID_CONFIG=0

# Assert that 'validate' command works
VALIDATE=$(docker-compose exec -T spire-agent /opt/spire/bin/spire-agent validate)

# Assert that 'validate' command fails with an invalid path
VALIDATE_FAIL=$(docker-compose exec -T spire-agent /opt/spire/bin/spire-agent validate -config invalid/path 2>&1 &)

if [[ "$VALIDATE" =~ "SPIRE agent configuration file is valid." ]]; then
VALID_CONFIG=1
fi

if [[ "$VALIDATE_FAIL" =~ "SPIRE agent configuration file is invalid" ]]; then
INVALID_CONFIG=1
fi

if [ $VALID_CONFIG -eq 1 ] && [ $INVALID_CONFIG -eq 1 ]; then
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add log to understand quickly witch one fails?

exit 0
else
exit 1
fi
32 changes: 32 additions & 0 deletions test/integration/suites/agent-cli/06-check-api-watch-fail
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/bash

SVID_RECEIVED=1
TIMEOUT_REACHED=0

# Run the background process and store its output in a temporary file
(docker-compose exec -u 1001 -T spire-agent /opt/spire/bin/spire-agent api watch < /dev/null > api_watch_output.txt) &

# Get the PID of the last background process
API_WATCH_PID=$!

# Continuously check the output file for the desired pattern with a timeout of 20 seconds
TIMEOUT=20
START_TIME=$(date +%s)
while ! grep -q "Received 1 svid after" api_watch_output.txt; do
CURRENT_TIME=$(date +%s)
ELAPSED_TIME=$((CURRENT_TIME - START_TIME))
if [ $ELAPSED_TIME -gt $TIMEOUT ]; then
echo "Timeout reached while waiting for 'Received' message, as expected"
TIMEOUT_REACHED=1
break
fi
sleep 1 # Wait for 1 second before checking again
done

# If timeout is reached, the test was succesful
if [ $TIMEOUT_REACHED -eq 1 ]; then
kill -9 $API_WATCH_PID # If timeout reached, kill the background process
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why it is required? are not we going to finish compose?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We decided to stop the api watch command in the succesful path, so we can add the entry, start to look again in another file, and after that assert that we receive the "Received" message (in 07-check-api-watch)
But that was just one of the valid approachs that we have, maybe is there another way to do it?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe this can be related to previous comment :D

exit 0
fi

exit 1
66 changes: 66 additions & 0 deletions test/integration/suites/agent-cli/07-check-api-watch
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/bin/bash

TIMEOUT_REACHED=0
RETRIES=3

docker-compose exec -T spire-server \
/opt/spire/bin/spire-server entry create \
-parentID "spiffe://domain.test/spire/agent/x509pop/$(fingerprint conf/agent/agent.crt.pem)" \
-spiffeID "spiffe://domain.test/workload-$m" \
-selector "unix:uid:1001" \
-ttl 20 &

# Get the PID of the last background process
API_WATCH_PID=$!

# Run the background process and store its output in a temporary file
(docker-compose exec -u 1001 -T spire-agent /opt/spire/bin/spire-agent api watch < /dev/null > api_watch_output.txt) &

# Wait for the background process to complete
wait $API_WATCH_PID


# Continuously check the output file for the desired pattern with a timeout of 20 seconds
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since the function behind api watch is to watch updates on SVID/bundles, what do you think about setting very log SVID rotations (1m or something like that) and verify that SVID rotates?

# Here we just care about the first one received

TIMEOUT=20
START_TIME=$(date +%s)
while ! grep -q "Received 1 svid after" api_watch_output.txt; do
CURRENT_TIME=$(date +%s)
ELAPSED_TIME=$((CURRENT_TIME - START_TIME))
if [ $ELAPSED_TIME -gt $TIMEOUT ]; then
echo "Error: Timeout reached while waiting for 'Received' message."
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fail-now

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I remove the echo message too?

TIMEOUT_REACHED=1
break
fi
sleep 1 # Wait for 1 second before checking again
done

if [ $TIMEOUT_REACHED -eq 1 ]; then
exit 1
fi

# Continuously check the output file for the desired pattern with a timeout of 60 seconds
# Here we care about the number of SVID received

TIMEOUT=60
START_TIME=$(date +%s)
while true; do
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the intention here?
Server has a ttl of 10m that measn that svids will be rotating every 5m,
but this test case is for 1m, so there is no rotation here,
maybe you can reduce ttl to 1m and verify that the svid rotated once, that will reduce the time for this for to 30s (because it will be finishing as soon an update is done)

CURRENT_TIME=$(date +%s)
ELAPSED_TIME=$((CURRENT_TIME - START_TIME))
if [ $ELAPSED_TIME -gt $TIMEOUT ]; then
fail-now "Timeout reached while waiting for 'Received' message."
fi

# Count the number of SVID received
COUNT_NOW=$(grep -c "Received 1 svid after" api_watch_output.txt)

if [ $COUNT_NOW -gt 4 ]; then
echo "SVID rotated more than 4 times"
break
fi
sleep 1 # Wait for 1 second before checking again
done

# SVID rotated more than 4 times
exit 0
5 changes: 5 additions & 0 deletions test/integration/suites/agent-cli/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Agent CLI commands

## Description

This suite validates Agent CLI commands.
31 changes: 31 additions & 0 deletions test/integration/suites/agent-cli/conf/agent/agent.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
agent {
data_dir = "/opt/spire/data/agent"
log_level = "DEBUG"
server_address = "spire-server"
server_port = "8081"
socket_path = "/tmp/spire-agent/public/api.sock"
trust_bundle_path = "/opt/spire/conf/agent/bootstrap.crt"
trust_domain = "domain.test"
admin_socket_path = "/opt/debug.sock"
experimental {
x509_svid_cache_max_size = 8
}
}

plugins {
NodeAttestor "x509pop" {
plugin_data {
private_key_path = "/opt/spire/conf/agent/agent.key.pem"
certificate_path = "/opt/spire/conf/agent/agent.crt.pem"
}
}
KeyManager "disk" {
plugin_data {
directory = "/opt/spire/data/agent"
}
}
WorkloadAttestor "unix" {
plugin_data {
}
}
}
26 changes: 26 additions & 0 deletions test/integration/suites/agent-cli/conf/server/server.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
server {
bind_address = "0.0.0.0"
bind_port = "8081"
trust_domain = "domain.test"
data_dir = "/opt/spire/data/server"
log_level = "DEBUG"
ca_ttl = "1h"
default_x509_svid_ttl = "10m"
}

plugins {
DataStore "sql" {
plugin_data {
database_type = "sqlite3"
connection_string = "/opt/spire/data/server/datastore.sqlite3"
}
}
NodeAttestor "x509pop" {
plugin_data {
ca_bundle_path = "/opt/spire/conf/server/agent-cacert.pem"
}
}
KeyManager "memory" {
plugin_data = {}
}
}
15 changes: 15 additions & 0 deletions test/integration/suites/agent-cli/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
version: '3'
services:
spire-server:
image: spire-server:latest-local
hostname: spire-server
volumes:
- ./conf/server:/opt/spire/conf/server
command: ["-config", "/opt/spire/conf/server/server.conf"]
spire-agent:
image: spire-agent:latest-local
hostname: spire-agent
depends_on: ["spire-server"]
volumes:
- ./conf/agent:/opt/spire/conf/agent
command: ["-config", "/opt/spire/conf/agent/agent.conf"]
6 changes: 6 additions & 0 deletions test/integration/suites/agent-cli/teardown
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

if [ -z "$SUCCESS" ]; then
docker-compose logs
fi
docker-down
Loading