Skip to content
Draft
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
2 changes: 1 addition & 1 deletion .github/configs/ct.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ target-branch: main
chart-dirs:
- charts
chart-repos: []
validate-chart-schema: false
validate-chart-schema: true
validate-maintainers: true
validate-yaml: true
exclude-deprecated: true
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/helm-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ name: CI

# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the "main" branch
# Triggers the workflow on push or pull request events for all branches
push:
branches: [ "main" ]
branches: [ "**" ]
pull_request:
branches: [ "main" ]
branches: [ "**" ]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
Expand Down
131 changes: 131 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# OpenCost Helm Chart Makefile
# Provides targets for local development, testing, and CI validation

.PHONY: help lint lint-default lint-ci lint-all template template-ci validate-schema test-all clean

# Default target
help:
@echo "OpenCost Helm Chart - Available targets:"
@echo ""
@echo " make lint - Lint chart with default values"
@echo " make lint-ci - Lint chart with all CI test scenarios"
@echo " make lint-all - Lint default + all CI scenarios"
@echo " make template - Template chart with default values"
@echo " make template-ci - Template chart with all CI scenarios"
@echo " make validate-schema - Validate values.schema.json"
@echo " make test-all - Run all tests (lint + template + schema)"
@echo " make clean - Clean generated files"
@echo ""

# Chart directory
CHART_DIR := charts/opencost
CI_DIR := $(CHART_DIR)/ci

# Find all CI values files
CI_FILES := $(wildcard $(CI_DIR)/*.yaml)
CI_FILES := $(filter-out $(CI_DIR)/README.md,$(CI_FILES))

# Colors for output
RED := \033[0;31m
GREEN := \033[0;32m
YELLOW := \033[1;33m
NC := \033[0m # No Color

# Lint chart with default values
lint-default:
@echo "$(YELLOW)Linting chart with default values...$(NC)"
@helm lint $(CHART_DIR) --strict
@echo "$(GREEN)✓ Default values lint passed$(NC)"

# Lint chart with all CI scenarios
lint-ci:
@echo "$(YELLOW)Linting chart with CI scenarios...$(NC)"
@failed=0; \
for file in $(CI_FILES); do \
echo " Testing $$(basename $$file)..."; \
if helm lint $(CHART_DIR) -f $$file --strict > /dev/null 2>&1; then \
echo " $(GREEN)✓ PASSED$(NC)"; \
else \
echo " $(RED)✗ FAILED$(NC)"; \
helm lint $(CHART_DIR) -f $$file --strict; \
failed=$$((failed + 1)); \
fi; \
done; \
if [ $$failed -eq 0 ]; then \
echo "$(GREEN)✓ All CI scenarios passed$(NC)"; \
else \
echo "$(RED)✗ $$failed scenario(s) failed$(NC)"; \
exit 1; \
fi

# Lint both default and CI scenarios
lint-all: lint-default lint-ci
@echo "$(GREEN)✓ All linting passed$(NC)"

# Alias for lint-all
lint: lint-all

# Template chart with default values
template-default:
@echo "$(YELLOW)Templating chart with default values...$(NC)"
@helm template opencost $(CHART_DIR) > /dev/null
@echo "$(GREEN)✓ Default template rendered successfully$(NC)"

# Template chart with all CI scenarios
template-ci:
@echo "$(YELLOW)Templating chart with CI scenarios...$(NC)"
@failed=0; \
for file in $(CI_FILES); do \
echo " Templating $$(basename $$file)..."; \
if helm template opencost $(CHART_DIR) -f $$file > /dev/null 2>&1; then \
echo " $(GREEN)✓ PASSED$(NC)"; \
else \
echo " $(RED)✗ FAILED$(NC)"; \
helm template opencost $(CHART_DIR) -f $$file; \
failed=$$((failed + 1)); \
fi; \
done; \
if [ $$failed -eq 0 ]; then \
echo "$(GREEN)✓ All CI scenarios templated successfully$(NC)"; \
else \
echo "$(RED)✗ $$failed scenario(s) failed$(NC)"; \
exit 1; \
fi

# Template both default and CI scenarios
template: template-default template-ci
@echo "$(GREEN)✓ All templating passed$(NC)"

# Validate JSON schema
validate-schema:
@echo "$(YELLOW)Validating values.schema.json...$(NC)"
@if command -v python3 > /dev/null 2>&1; then \
python3 -m json.tool $(CHART_DIR)/values.schema.json > /dev/null && \
echo "$(GREEN)✓ Schema is valid JSON$(NC)"; \
else \
echo "$(YELLOW)⚠ python3 not found, skipping schema validation$(NC)"; \
fi

# Run all tests
test-all: validate-schema lint-all template
@echo ""
@echo "$(GREEN)========================================$(NC)"
@echo "$(GREEN)✓ All tests passed!$(NC)"
@echo "$(GREEN)========================================$(NC)"

# Clean generated files (if any)
clean:
@echo "$(YELLOW)Cleaning generated files...$(NC)"
@rm -f $(CHART_DIR)/*.tgz
@echo "$(GREEN)✓ Clean complete$(NC)"

# Quick test (lint only, faster for iteration)
quick: lint-default
@echo "$(GREEN)✓ Quick test passed$(NC)"

# List all CI test files
list-ci:
@echo "CI test scenarios:"
@for file in $(CI_FILES); do \
echo " - $$(basename $$file)"; \
done
2 changes: 1 addition & 1 deletion charts/opencost/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ keywords:
- finops
- monitoring
- opencost
version: 2.5.23
version: 2.5.24
maintainers:
- name: jessegoodier
- name: toscott
Expand Down
223 changes: 223 additions & 0 deletions charts/opencost/ci/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
# OpenCost Helm Chart CI Test Values

This directory contains test values files for CI/CD validation of the OpenCost Helm chart. Each file tests a specific configuration scenario to ensure the chart works correctly across different use cases.

## Test Scenarios

### 1. `mcp-enabled-values.yaml`
**Purpose:** Tests MCP (Model Context Protocol) server configuration
**Use Case:** AI agent integration for cost data access
**Key Features:**
- MCP server enabled on port 8081
- Ingress configuration for MCP endpoint

### 2. `external-prometheus-values.yaml`
**Purpose:** Tests external Prometheus configuration
**Use Case:** Using Grafana Cloud or other external Prometheus
**Key Features:**
- External Prometheus URL
- Basic authentication
- Internal Prometheus disabled

### 3. `aws-amp-values.yaml`
**Purpose:** Tests AWS AMP (Amazon Managed Prometheus) integration
**Use Case:** AWS EKS clusters with AMP
**Key Features:**
- AMP workspace configuration
- SigV4 proxy for AWS authentication
- IAM role annotations

### 4. `cloud-costs-enabled-values.yaml`
**Purpose:** Tests cloud cost integration
**Use Case:** Multi-cloud cost visibility
**Key Features:**
- Cloud cost ingestion enabled
- Cloud integration secret reference
- AWS credentials configuration

### 5. `custom-pricing-values.yaml`
**Purpose:** Tests custom pricing configuration
**Use Case:** On-premises or custom pricing models
**Key Features:**
- Custom cost model
- ConfigMap creation
- Custom provider settings

### 6. `ingress-enabled-values.yaml`
**Purpose:** Tests ingress configuration for UI and API
**Use Case:** External access to OpenCost
**Key Features:**
- UI ingress with TLS
- API ingress with TLS
- Cert-manager integration

### 7. `persistence-enabled-values.yaml`
**Purpose:** Tests persistent storage configuration
**Use Case:** Data persistence and collector data source
**Key Features:**
- PVC configuration
- Collector data source enabled
- Custom storage class

### 8. `plugins-enabled-values.yaml`
**Purpose:** Tests plugin installation and configuration
**Use Case:** Third-party integrations (e.g., Datadog)
**Key Features:**
- Plugin installation enabled
- Datadog plugin configuration
- Security context for plugin installer

### 9. `high-availability-values.yaml`
**Purpose:** Tests HA configuration
**Use Case:** Production deployments requiring high availability
**Key Features:**
- Multiple replicas (3)
- Pod Disruption Budget
- Topology spread constraints
- Anti-affinity rules

### 10. `servicemonitor-enabled-values.yaml`
**Purpose:** Tests Prometheus Operator ServiceMonitor
**Use Case:** Prometheus Operator-based monitoring
**Key Features:**
- ServiceMonitor creation
- Metric relabeling
- KSM metrics configuration
- Custom metrics config

## Running Tests Locally

### Quick Start with Makefile (Recommended)

The repository includes a Makefile for easy local testing:

```bash
# Show all available targets
make help

# Quick test (lint default values only - fastest for iteration)
make quick

# Lint all CI scenarios
make lint-ci

# Lint default + all CI scenarios
make lint-all

# Template all scenarios
make template

# Run all tests (lint + template + schema validation)
make test-all

# List all CI test files
make list-ci
```

### Manual Testing

The chart uses [chart-testing (ct)](https://github.com/helm/chart-testing) which automatically discovers and tests all files in the `ci/` directory.

#### Test Individual Scenarios

```bash
# Lint a specific scenario
helm lint . -f ci/mcp-enabled-values.yaml

# Template a specific scenario
helm template opencost . -f ci/mcp-enabled-values.yaml

# Template and validate with kubectl
helm template opencost . -f ci/mcp-enabled-values.yaml | kubectl apply --dry-run=client -f -
```

#### Test All Scenarios with chart-testing

```bash
# Install chart-testing
brew install chart-testing # macOS
# or follow: https://github.com/helm/chart-testing#installation

# Run chart-testing lint (tests all ci/*.yaml files automatically)
ct lint --config .github/configs/ct.yaml --lint-conf .github/configs/lintconf.yaml --charts charts/opencost

# Run chart-testing install (requires kind cluster)
kind create cluster
ct install --config .github/configs/ct.yaml --charts charts/opencost
```

#### Schema Validation

Schema validation is enabled in the CI workflow via `validate-chart-schema: true` in `.github/configs/ct.yaml`.

```bash
# Validate schema manually
make validate-schema

# Or with python directly
python3 -m json.tool charts/opencost/values.schema.json > /dev/null
```

## CI/CD Integration

This chart uses the standard [chart-testing](https://github.com/helm/chart-testing) workflow which automatically:
- Discovers all `ci/*.yaml` files
- Lints each configuration
- Validates against the schema
- Installs and tests in a kind cluster

The CI workflow is defined in `.github/workflows/helm-test.yml` and uses:
- `.github/configs/ct.yaml` - chart-testing configuration
- `.github/configs/lintconf.yaml` - yamllint configuration

### How chart-testing Works

When you add a new file to `ci/`, chart-testing will automatically:
1. **Lint** the chart with those values
2. **Validate** against `values.schema.json` (if `validate-chart-schema: true`)
3. **Install** the chart in a test cluster
4. **Test** the deployment

No additional workflow changes needed!

## Adding New Test Scenarios

When adding new features to the chart:

1. Create a new `feature-name-values.yaml` file in this directory
2. Include only the values relevant to testing that feature
3. Add documentation to this README
4. Ensure the file passes `helm lint --strict`
5. Test with `helm template` to verify rendered manifests

## Best Practices

- **Keep files focused:** Each file should test a specific scenario
- **Use realistic values:** Even test values should be plausible
- **Document purpose:** Clear comments in each file
- **Test combinations:** Consider creating files that test feature interactions
- **Validate schema:** Ensure all values conform to `values.schema.json`

## Troubleshooting

### Lint Failures

If `helm lint` fails:
1. Check the error message for the specific issue
2. Verify values against `values.schema.json`
3. Ensure all required fields are present
4. Check for YAML syntax errors

### Template Failures

If `helm template` fails:
1. Check template logic in `templates/` directory
2. Verify conditional statements handle the test values
3. Ensure all referenced values exist
4. Check for missing required values

## Related Files

- [`values.yaml`](../values.yaml) - Default chart values
- [`values.schema.json`](../values.schema.json) - JSON Schema for validation
- [`values-openshift.yaml`](../values-openshift.yaml) - OpenShift-specific values
Loading
Loading