Skip to content

Feature: Add kasm_sessions and kasm_session_status data sources #47

Feature: Add kasm_sessions and kasm_session_status data sources

Feature: Add kasm_sessions and kasm_session_status data sources #47

Workflow file for this run

name: Terraform Provider CI/CD
on:
push:
branches: [ main ]
paths-ignore:
- 'docs/**'
- '**.md'
pull_request:
branches: [ main ]
workflow_call:
inputs:
run_tests:
description: 'Whether to run acceptance tests'
required: false
default: true
type: boolean
secrets:
ADMIN_PASSWORD:
required: true
USER_PASSWORD:
required: true
permissions:
contents: read
checks: write # Required for test-reporter to create check runs
env:
KASM_BASE_URL: "https://localhost"
ADMIN_USERNAME: "admin@kasm.local"
ADMIN_PASSWORD: ${{ secrets.ADMIN_PASSWORD }}
USER_PASSWORD: ${{ secrets.USER_PASSWORD }}
GO_VERSION: '1.22.0'
KASM_SKIP_BROWSER_TEST: 'true' # Skip tests that require browser interaction
jobs:
# Stage 1: Initial checks that don't need Kasm
initial_checks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
cache: true
- name: Verify Dependencies
run: |
go mod verify
go mod tidy
git diff --exit-code go.mod go.sum
- name: Install gotestsum
run: go install gotest.tools/gotestsum@latest
- name: Run Unit Tests
run: |
mkdir -p test-results
gotestsum --junitfile test-results/unit-tests.xml -- -tags=unit ./...
- name: Test Report
uses: dorny/test-reporter@v1
if: success() || failure() # run this step even if previous step failed
with:
name: Unit Tests # Name of the check run which will be created
path: test-results/unit-tests.xml # Path to test results
reporter: java-junit # Format of test results
# Stage 2: Code Quality
code_quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
cache: true
# - name: Check Formatting
# run: |
# go fmt ./...
# if [ -n "$(git status --porcelain)" ]; then
# echo "Code is not properly formatted. Please run 'go fmt ./...'"
# exit 1
# fi
# - name: Run Linters
# uses: golangci/golangci-lint-action@v3
# with:
# version: latest
# Stage 3: Security Scanning
# security:
# needs: [initial_checks]
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v4
# - name: Run Gosec Security Scanner
# uses: securego/gosec@v2.18.2
# env:
# GO111MODULE: on
# GOFLAGS: "-mod=mod"
# GOTOOLCHAIN: auto
# with:
# args: -go=1.22.0 ./...
# - name: Run dependency vulnerability scan
# uses: golang/govulncheck-action@v1
# with:
# go-version-input: ${{ env.GO_VERSION }}
# check-latest: true
# Stage 4: Setup Kasm and Run Acceptance Tests
# Only run on pull requests or when explicitly triggered
acceptance_tests:
# needs: [code_quality, security]
needs: [code_quality]
runs-on: ubuntu-latest
if: github.event_name == 'pull_request' || inputs.run_tests
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
cache: true
- name: Install gotestsum
run: go install gotest.tools/gotestsum@latest
- name: Install System Dependencies
run: |
sudo docker ps
# sudo apt-get update
# sudo apt-get install -y curl jq docker.io docker-compose
# sudo systemctl start docker
# sudo usermod -aG docker $USER
- name: Download and Extract Kasm Workspaces
run: |
KASM_RELEASE="kasm_release_1.16.1.98d6fa.tar.gz"
KASM_RELEASE_PATH="/tmp/$KASM_RELEASE"
echo "Downloading Kasm release..."
curl -o "$KASM_RELEASE_PATH" https://kasm-static-content.s3.amazonaws.com/kasm_release_1.16.1.98d6fa.tar.gz
mkdir -p /tmp/kasm_release
tar -xf "$KASM_RELEASE_PATH" -C /tmp/kasm_release
sudo bash /tmp/kasm_release/kasm_release/install.sh \
--admin-password "$ADMIN_PASSWORD" \
--user-password "$USER_PASSWORD" \
--accept-eula \
--swap-size 4096
echo "Waiting for Kasm to be fully up..."
for i in {1..30}; do
if curl -k -s "$KASM_BASE_URL/api/__healthcheck" | grep -q "ok"; then
echo "Kasm is up and running"
break
fi
if [ $i -eq 30 ]; then
echo "Timeout waiting for Kasm to start"
exit 1
fi
echo "Waiting... attempt $i/30"
sleep 10
done
- name: Set Up API Key for Acceptance Tests
id: api_key
run: |
# Get auth token and store it
AUTH_RESPONSE=$(curl -k -s -X POST "$KASM_BASE_URL/api/authenticate" \
-H "Content-Type: application/json" \
-d "{\"username\":\"$ADMIN_USERNAME\",\"password\":\"$ADMIN_PASSWORD\"}")
echo "Authentication Response: $AUTH_RESPONSE"
# Extract and store token
AUTH_TOKEN=$(echo $AUTH_RESPONSE | jq -r .token)
echo "AUTH_TOKEN=$AUTH_TOKEN" >> $GITHUB_ENV
if [ -z "$AUTH_TOKEN" ] || [ "$AUTH_TOKEN" = "null" ]; then
echo "Error: Failed to get authentication token"
exit 1
fi
echo "Authentication successful"
# Create API key
PAYLOAD=$(cat <<EOF
{
"api_config": {
"enabled": true,
"name": "terraform_provider_test_key",
"read_only": false,
"expires": null
},
"token": "$AUTH_TOKEN",
"username": "$ADMIN_USERNAME"
}
EOF
)
API_RESPONSE=$(curl -k -s -X POST "$KASM_BASE_URL/api/public/create_api_configs" \
-H "Content-Type: application/json" \
-d "$PAYLOAD")
echo "API Key Creation Response: $API_RESPONSE"
KASM_API_KEY=$(echo $API_RESPONSE | jq -r '.api_config.api_key')
KASM_API_SECRET=$(echo $API_RESPONSE | jq -r '.api_config.api_key_secret')
KASM_API_ID=$(echo $API_RESPONSE | jq -r '.api_config.api_id')
if [ -z "$KASM_API_KEY" ] || [ "$KASM_API_KEY" = "null" ]; then
echo "Error: Failed to get API key"
exit 1
fi
echo "KASM_API_KEY=$KASM_API_KEY" >> $GITHUB_ENV
echo "KASM_API_SECRET=$KASM_API_SECRET" >> $GITHUB_ENV
echo "KASM_API_ID=$KASM_API_ID" >> $GITHUB_ENV
- name: Update API Key Permissions
run: |
# Use stored AUTH_TOKEN from environment
PERMISSION_PAYLOAD=$(cat <<EOF
{
"token": "$AUTH_TOKEN",
"username": "$ADMIN_USERNAME",
"target_api_config": {
"api_id": "$KASM_API_ID"
},
"target_permissions": [100, 200, 352]
}
EOF
)
echo "Sending permission payload: $PERMISSION_PAYLOAD"
PERMISSION_RESPONSE=$(curl -k -s -X POST "$KASM_BASE_URL/api/public/add_permissions_group" \
-H "Content-Type: application/json" \
-H "Cookie: session_token=$AUTH_TOKEN; username=$ADMIN_USERNAME" \
-d "$PERMISSION_PAYLOAD")
echo "Permission Update Response: $PERMISSION_RESPONSE"
if echo "$PERMISSION_RESPONSE" | jq -e '.permissions' > /dev/null; then
echo "Successfully updated API key permissions"
else
echo "Failed to update API key permissions"
echo "Response: $PERMISSION_RESPONSE"
exit 1
fi
# Create directory for test results
- name: Create Test Results Directory
run: mkdir -p test-results
# Create empty XML files for any test groups that might not run
- name: Create Empty XML Files for Missing Test Groups
run: |
# Create a minimal valid JUnit XML file
create_empty_junit_xml() {
local file_path=$1
if [ ! -f "$file_path" ]; then
echo '<?xml version="1.0" encoding="UTF-8"?>' > "$file_path"
echo '<testsuites name="No Tests Run" tests="0" failures="0" errors="0" time="0">' >> "$file_path"
echo ' <testsuite name="NoTests" tests="0" failures="0" errors="0" skipped="0" time="0">' >> "$file_path"
echo ' <properties></properties>' >> "$file_path"
echo ' </testsuite>' >> "$file_path"
echo '</testsuites>' >> "$file_path"
echo "Created empty test file: $file_path"
else
echo "File already exists: $file_path"
fi
}
# Create empty XML files for all test groups
create_empty_junit_xml "test-results/user-management-tests.xml"
create_empty_junit_xml "test-results/session-management-tests.xml"
create_empty_junit_xml "test-results/image-management-tests.xml"
create_empty_junit_xml "test-results/registry-management-tests.xml"
create_empty_junit_xml "test-results/cast-management-tests.xml"
create_empty_junit_xml "test-results/group-management-tests.xml"
create_empty_junit_xml "test-results/remaining-tests.xml"
# Run tests in groups based on API categories with JUnit output
- name: Run User Management Tests
run: |
TF_ACC=1 gotestsum --junitfile test-results/user-management-tests.xml --format standard-verbose -- -tags=acceptance \
./internal/resources/user/tests/... \
./internal/datasources/users_list/tests/...
- name: Run Session Management Tests
run: |
TF_ACC=1 gotestsum --junitfile test-results/session-management-tests.xml --format standard-verbose -- -tags=acceptance \
./internal/resources/kasm/session/tests/... \
./internal/resources/join/tests/... \
./internal/resources/session_permission/tests/... \
./internal/resources/keepalive/tests/... \
./internal/resources/stats/tests/... \
./internal/datasources/sessions/tests/... \
./internal/datasources/session_status/tests/... \
./internal/datasources/rdp/tests/...
- name: Ensure cleanup of any test images
if: always()
run: |
echo "Cleaning up any test resources..."
TF_ACC=1 go test -tags=acceptance ./testutils -run TestCleanupResources
- name: Run Image Management Tests
run: |
TF_ACC=1 gotestsum --junitfile test-results/image-management-tests.xml -- -tags=acceptance \
./internal/resources/image/tests/... \
./internal/datasources/images/tests/...
- name: Run Registry Management Tests
run: |
TF_ACC=1 gotestsum --junitfile test-results/registry-management-tests.xml -- -tags=acceptance \
./internal/resources/registry/tests/... \
./internal/datasources/registries/tests/... \
./internal/datasources/registry_images/tests/...
- name: Run Cast Management Tests
run: |
TF_ACC=1 gotestsum --junitfile test-results/cast-management-tests.xml -- -tags=acceptance \
./internal/resources/cast/tests/...
- name: Run Group Management Tests
run: |
TF_ACC=1 gotestsum --junitfile test-results/group-management-tests.xml -- -tags=acceptance \
./internal/resources/group/tests/... \
./internal/resources/group_membership/tests/... \
./internal/resources/group_image/tests/... \
./internal/datasources/group_images/tests/...
- name: Run Remaining Tests
run: |
REMAINING_TESTS=$(go list ./... | grep -v 'user/tests\|users_list/tests\|session/tests\|join/tests\|session_permission/tests\|keepalive/tests\|stats/tests\|sessions/tests\|session_status/tests\|rdp/tests\|image/tests\|images/tests\|registry/tests\|registries/tests\|registry_images/tests\|cast/tests\|group/tests\|group_membership/tests\|group_image/tests\|group_images/tests')
if [ ! -z "$REMAINING_TESTS" ]; then
TF_ACC=1 gotestsum --junitfile test-results/remaining-tests.xml -- -tags=acceptance $REMAINING_TESTS
else
echo "No remaining tests to run"
echo '<?xml version="1.0" encoding="UTF-8"?><testsuites></testsuites>' > test-results/remaining-tests.xml
fi
# Generate test reports for each category
- name: Generate User Management Test Report
uses: dorny/test-reporter@v1
if: success() || failure()
with:
name: User Management Tests
path: test-results/user-management-tests.xml
reporter: java-junit
fail-on-error: false
fail-on-empty: false
- name: Generate Session Management Test Report
uses: dorny/test-reporter@v1
if: success() || failure()
with:
name: Session Management Tests
path: test-results/session-management-tests.xml
reporter: java-junit
fail-on-error: false
fail-on-empty: false
- name: Generate Image Management Test Report
uses: dorny/test-reporter@v1
if: success() || failure()
with:
name: Image Management Tests
path: test-results/image-management-tests.xml
reporter: java-junit
fail-on-error: false
fail-on-empty: false
- name: Generate Registry Management Test Report
uses: dorny/test-reporter@v1
if: success() || failure()
with:
name: Registry Management Tests
path: test-results/registry-management-tests.xml
reporter: java-junit
fail-on-error: false
fail-on-empty: false
- name: Generate Cast Management Test Report
uses: dorny/test-reporter@v1
if: success() || failure()
with:
name: Cast Management Tests
path: test-results/cast-management-tests.xml
reporter: java-junit
fail-on-error: false
fail-on-empty: false
- name: Generate Group Management Test Report
uses: dorny/test-reporter@v1
if: success() || failure()
with:
name: Group Management Tests
path: test-results/group-management-tests.xml
reporter: java-junit
fail-on-error: false
fail-on-empty: false
- name: Generate Remaining Tests Report
uses: dorny/test-reporter@v1
if: success() || failure()
with:
name: Remaining Tests
path: test-results/remaining-tests.xml
reporter: java-junit
fail-on-error: false
fail-on-empty: false
- name: Upload Test Logs
if: always()
uses: actions/upload-artifact@v4
with:
name: acceptance-test-logs
path: |
terraform.log
test-results/*.xml
- name: Cleanup Kasm
if: always()
run: |
echo "Stopping Kasm containers..."
# First try graceful shutdown
if sudo test -f /opt/kasm/current/bin/stop; then
sudo bash /opt/kasm/current/bin/stop || true
fi
# Force remove any remaining containers
KASM_CONTAINERS=$(sudo docker ps -q --filter "name=kasm_")
if [ ! -z "$KASM_CONTAINERS" ]; then
echo "Force removing remaining Kasm containers..."
sudo docker rm -f $KASM_CONTAINERS || true
fi