Skip to content
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
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