Skip to content
Merged
15 changes: 14 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,21 @@ test-e2e: build ## Run end-to-end tests (requires kubectl context and cluster ac
fi
$(GOTEST) -v -tags=e2e -timeout=120m -parallel=1 ./tests/e2e/...

.PHONY: test-integration
test-integration: build ## Run integration tests (requires kubectl context and cluster access)
@echo "🧪 Running integration tests..."
@if [ -z "$(shell kubectl config current-context 2>/dev/null)" ]; then \
echo "❌ No kubectl context found. Please configure kubectl first."; \
exit 1; \
fi
@if ! command -v podman >/dev/null 2>&1; then \
echo "❌ podman not found. Please install podman for integration tests."; \
exit 1; \
fi
$(GOTEST) -v -tags=integration -run=_Integration$$ -timeout=120m -parallel=1 ./...

.PHONY: test-all
test-all: test test-e2e ## Run all tests (unit + e2e)
test-all: test test-integration test-e2e ## Run all tests (unit + integration + e2e)

# Benchmarks
.PHONY: bench
Expand Down
65 changes: 40 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,39 +26,39 @@ Support for Helm charts might be dropped in the future.

## Quick start

### Option 1: Deploying using Docker image (Recommended for non-developers)
### Option 1: Deploying using image (Recommended for non-developers)

**Requirements:**
* Working Docker setup
* Podman (or Docker) is set up
* kubeconfig configuration file
* quay.io registry credentials in the environment variables REGISTRY_USERNAME and REGISTRY_PASSWORD.

Note that **Podman is currently not supported** for running
containerized roxie due to incomplete mapping of user IDs on macOS. This prevents the passing-in of the gcloud
configuration directory to be functional within the container, which is required for interacting with GKE clusters.
And, depending on the cluster:
* credentials for the `quay.io` registry in the environment variables `REGISTRY_USERNAME` and `REGISTRY_PASSWORD`.

Example for deploying Central and SecuredCluster to the current Kubernetes cluster context:
```bash
docker run --rm -it --privileged \
-v ~/.config/gcloud:/.config/gcloud \
-v $KUBECONFIG:/kubeconfig \
-e REGISTRY_USERNAME=$REGISTRY_USERNAME \
-e REGISTRY_PASSWORD=$REGISTRY_PASSWORD \
ghcr.io/stackrox/roxie:latest deploy
```

A new roxie image for the current platform can be built using:
Infra OpenShift4 clusters come already equipped with image pull secrets for `quay.io`, so in this case
passing of `REGISTRY_USERNAME` and `REGISTRY_PASSWORD` to the container is not required:

Example for deploying Central and SecuredCluster to an Infra OpenShift 4 cluster:
```bash
make docker-build
podman run --rm -it --privileged \
-v $KUBECONFIG:/kubeconfig:U \
-e MAIN_IMAGE_TAG=4.9.2 \
quay.io/rhacs-eng/roxie:latest deploy --resources=auto
```
Specify the `MAIN_IMAGE_TAG` as desired.

This creates two tags:
- `localhost/roxie:latest`
- `localhost/roxie:<version-tag>`

Docker images can be built for the platforms `linux/amd64` and `linux/arm64`. See the `Makefile` for more
docker related targets.
Deploying to a GKE cluster requires passing of some more arguments:
```
podman run --rm -it --privileged \
-v ~/.config/gcloud:/.config/gcloud:U \
-v $KUBECONFIG:/kubeconfig:U \
-e MAIN_IMAGE_TAG=4.9.2 \
-e REGISTRY_USERNAME=$REGISTRY_USERNAME \
-e REGISTRY_PASSWORD=$REGISTRY_PASSWORD \
quay.io/rhacs-eng/roxie:latest deploy --resources=auto
```
Note that in this case we also need to pass the gcloud configuration for the authentication towards
the cluster to succeed.

### Option 2: Deploying using local build

Expand All @@ -80,9 +80,10 @@ Get help:

Deploy using:
```bash
./roxie deploy [ <component> ]
MAIN_IMAGE_TAG=4.9.2 ./roxie deploy [ <component> ]
```
where `component` can be `central` or `sensor`. If not specified, both components will be deployed.
Specify the `MAIN_IMAGE_TAG` as desired.

Similarly, the deployment(s) can be torn down using:
```bash
Expand All @@ -104,6 +105,20 @@ make test # Unit tests
make test-e2e # E2E tests (requires a real cluster context)
```

A new roxie image for the current platform can be built using:

```bash
make docker-build
```

This creates two tags:
- `localhost/roxie:latest`
- `localhost/roxie:<version-tag>`

Docker images can be built for the platforms `linux/amd64` and `linux/arm64`. See the `Makefile` for more
docker related targets.


## Testing (E2E)

The E2E suite expects a valid `kubectl` context.
9 changes: 4 additions & 5 deletions cmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,8 @@ Examples:

func runDeploy(cmd *cobra.Command, args []string) error {
log := logger.New()

if env.RunningInContainer {
log.Dim("Running containerized.")
if err := env.Initialize(log); err != nil {
return err
}

if env.RunningInteractively {
Expand Down Expand Up @@ -99,9 +98,9 @@ func runDeploy(cmd *cobra.Command, args []string) error {
}

// On infra OpenShift we already get image pull secrets for Quay automatically.
if env.GetCurrentClusterType() != env.InfraOpenShift4 {
if clusterType := env.GetCurrentClusterType(); clusterType != env.InfraOpenShift4 {
if os.Getenv("REGISTRY_USERNAME") == "" || os.Getenv("REGISTRY_PASSWORD") == "" {
return errors.New("containerized mode requires REGISTRY_USERNAME and REGISTRY_PASSWORD environment variables")
return fmt.Errorf("containerized mode requires REGISTRY_USERNAME and REGISTRY_PASSWORD environment variables for clusters of type %s", clusterType)
}
if _, err := os.Stat("/kubeconfig"); err != nil {
return fmt.Errorf("containerized mode requires /kubeconfig file: %w", err)
Expand Down
14 changes: 12 additions & 2 deletions cmd/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package main

import (
"fmt"
"os"

"github.com/spf13/cobra"
"github.com/stackrox/roxie/internal/env"
"github.com/stackrox/roxie/internal/logger"
)

func newEnvCmd() *cobra.Command {
Expand All @@ -13,16 +15,24 @@ func newEnvCmd() *cobra.Command {
Short: "Display environment information",
Long: `Display detected environment information including cluster type and container status.`,
Hidden: true, // Hidden command for debugging/inspection
Run: runEnv,
RunE: runEnv,
}

return cmd
}

func runEnv(cmd *cobra.Command, args []string) {
func runEnv(cmd *cobra.Command, args []string) error {
log := logger.New()
if err := env.Initialize(log); err != nil {
return err
}

fmt.Println("Roxie Environment Information:")
fmt.Println("==============================")
fmt.Printf("Kube config: %s\n", os.Getenv("KUBECONFIG"))
fmt.Printf("Running in Container: %v\n", env.RunningInContainer)
fmt.Printf("Current Context: %s\n", env.GetCurrentContext())
fmt.Printf("Cluster Type: %s\n", env.GetCurrentClusterType().String())

return nil
}
8 changes: 6 additions & 2 deletions cmd/teardown.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/spf13/cobra"
"github.com/stackrox/roxie/internal/deployer"
"github.com/stackrox/roxie/internal/env"
"github.com/stackrox/roxie/internal/logger"
)

Expand All @@ -28,13 +29,16 @@ func newTeardownCmd() *cobra.Command {
}

func runTeardown(cmd *cobra.Command, args []string) error {
log := logger.New()
if err := env.Initialize(log); err != nil {
return err
}

component := "both"
if len(args) > 0 {
component = args[0]
}

log := logger.New()

log.Infof("Tearing down %s", component)

d, err := deployer.New(log, "", []string{})
Expand Down
7 changes: 5 additions & 2 deletions internal/deployer/deployer.go
Original file line number Diff line number Diff line change
Expand Up @@ -421,8 +421,11 @@ func (d *Deployer) Deploy(ctx context.Context, component, resources, exposure st
d.exposure = exposure

// Prepare and verify credentials early to fail fast
if err := d.prepareCredentials(); err != nil {
return fmt.Errorf("failed to prepare credentials: %w", err)

if env.GetCurrentClusterType() != env.InfraOpenShift4 {
if err := d.prepareCredentials(); err != nil {
return fmt.Errorf("failed to prepare credentials: %w", err)
}
}

d.logger.Infof("Initiating deployment of %s", formatComponentName(component))
Expand Down
Loading