Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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
21 changes: 13 additions & 8 deletions cmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,14 +347,18 @@ func runDeploy(cmd *cobra.Command, args []string) error {
}

func configureConfig(log *logger.Logger, components component.Component, deploySettings *deployer.Config) error {
clusterType := env.GetCurrentClusterType()
log.Dimf("Detected cluster type: %v", clusterType)
defaults, err := clusterdefaults.ApplyClusterDefaults(clusterType, deploySettings)
if deploySettings.Roxie.ClusterType == types.ClusterTypeUnknown {
clusterType := env.GetAutoDetectedClusterType()
log.Dimf("Detected cluster type: %v", clusterType)
deploySettings.Roxie.ClusterType = clusterType
}
clusterType := deploySettings.Roxie.ClusterType
Comment thread
coderabbitai[bot] marked this conversation as resolved.
defaults, err := clusterdefaults.ApplyClusterDefaults(deploySettings)
if err != nil {
return fmt.Errorf("applying defaults for cluster type %v: %w", clusterType, err)
return err
}
if verbose {
log.Dimf("Applying the following defaults based on detected cluster type %v:", clusterType)
log.Dimf("Applying the following defaults based on cluster type %v:", clusterType)
helpers.LogMultilineYaml(log, defaults)
}

Expand Down Expand Up @@ -409,6 +413,8 @@ func deployValidate(components component.Component, deploySettings *deployer.Con
return errors.New("running without a controlling terminal requires --envrc to be set")
}

clusterType := deploySettings.Roxie.ClusterType

if env.RunningInRoxieContainer {
// For running containerized we have specific requirements.
if deploySettings.Central.PortForwardingEnabled() {
Expand All @@ -419,7 +425,7 @@ func deployValidate(components component.Component, deploySettings *deployer.Con
}

// On infra OpenShift we already get image pull secrets for Quay automatically.
if clusterType := env.GetCurrentClusterType(); clusterType != types.ClusterTypeInfraOpenShift4 {
if clusterType.NeedsPullSecrets() {
if os.Getenv("REGISTRY_USERNAME") == "" || os.Getenv("REGISTRY_PASSWORD") == "" {
return fmt.Errorf("containerized mode requires REGISTRY_USERNAME and REGISTRY_PASSWORD environment variables for clusters of type %s", clusterType)
}
Expand All @@ -437,9 +443,8 @@ func deployValidate(components component.Component, deploySettings *deployer.Con
if deploySettings.Operator.DeployViaOlm {
return errors.New("using Konflux images while deploying operator via OLM is not supported")
}
clusterType := env.GetCurrentClusterType()
if !clusterType.IsOpenShift() {
return fmt.Errorf("--konflux flag is only supported on OpenShift 4 clusters (current cluster type: %s)", clusterType.String())
return fmt.Errorf("--konflux flag is only supported on OpenShift 4 clusters (current cluster type: %s)", clusterType)
}
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func runEnv(cmd *cobra.Command, args []string) error {
fmt.Printf("Kube config: %s\n", os.Getenv("KUBECONFIG"))
fmt.Printf("Running in roxie container: %v\n", env.RunningInRoxieContainer)
fmt.Printf("Current Context: %s\n", env.GetCurrentContext())
fmt.Printf("Cluster Type: %s\n", env.GetCurrentClusterType().String())
fmt.Printf("Cluster Type: %s\n", env.GetAutoDetectedClusterType().String())

return nil
}
6 changes: 3 additions & 3 deletions internal/clusterdefaults/clusterdefaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ import (
// provided deployer.Config.
// Returns *just* the assembled defaults for the given cluster type for logging purposes.
func ApplyClusterDefaults(
clusterType types.ClusterType,
config *deployer.Config,
) (*deployer.Config, error) {
if config == nil {
panic("applying cluster defaults to nil config")
}
clusterType := config.Roxie.ClusterType
defaults := getDefaultsForClusterType(clusterType)
if defaults == nil {
return nil, nil
Expand All @@ -27,11 +27,11 @@ func ApplyClusterDefaults(
// Make a copy.
defaultsCopy, err := defaults.DeepCopy()
if err != nil {
return nil, fmt.Errorf("deep-copying cluster defaults: %w", err)
return nil, fmt.Errorf("deep-copying cluster defaults for cluster type %s: %w", clusterType, err)
}

if err := mergo.Merge(config, defaultsCopy, mergo.WithoutDereference); err != nil {
return nil, fmt.Errorf("merging-in cluster defaults: %w", err)
return nil, fmt.Errorf("merging-in cluster defaults for cluster type %s: %w", clusterType, err)
}

return defaultsCopy, nil
Expand Down
3 changes: 2 additions & 1 deletion internal/clusterdefaults/clusterdefaults_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ func TestClusterDefaults(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
config := tt.config
_, err := ApplyClusterDefaults(tt.clusterType, &config)
config.Roxie.ClusterType = tt.clusterType
_, err := ApplyClusterDefaults(&config)
require.NoError(t, err)

if tt.wantConfig.Central.Exposure == nil {
Expand Down
7 changes: 4 additions & 3 deletions internal/deployer/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ func (c *Config) DeepCopy() (*Config, error) {

// RoxieConfig holds roxie-level settings such as version and feature flags.
type RoxieConfig struct {
Version string `yaml:"version,omitempty"`
KonfluxImages bool `yaml:"konfluxImages,omitempty"`
FeatureFlags map[string]bool `yaml:"featureFlags,omitempty"`
Version string `yaml:"version,omitempty"`
KonfluxImages bool `yaml:"konfluxImages,omitempty"`
FeatureFlags map[string]bool `yaml:"featureFlags,omitempty"`
ClusterType types.ClusterType `yaml:"clusterType,omitempty"`
Comment thread
mclasmeier marked this conversation as resolved.
}

// NewRoxieConfig returns a RoxieConfig with initialized defaults.
Expand Down
4 changes: 2 additions & 2 deletions internal/deployer/deploy_via_operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func (d *Deployer) ensureOperatorDeployed(ctx context.Context) error {
func (d *Deployer) deployCentralOperator(ctx context.Context) error {
d.logger.Info("🚀 Deploying Central via Operator...")

needPullSecrets := env.GetCurrentClusterType() != types.ClusterTypeInfraOpenShift4
needPullSecrets := d.config.Roxie.ClusterType.NeedsPullSecrets()
if err := d.prepareNamespace(ctx, d.config.Central.Namespace, needPullSecrets); err != nil {
return fmt.Errorf("failed to prepare namespace: %w", err)
}
Expand Down Expand Up @@ -655,7 +655,7 @@ func (d *Deployer) configureCentralEndpoint(ctx context.Context) error {
func (d *Deployer) deploySecuredClusterOperator(ctx context.Context) error {
d.logger.Info("🚀 Deploying SecuredCluster via Operator...")

needPullSecrets := env.GetCurrentClusterType() != types.ClusterTypeInfraOpenShift4
needPullSecrets := d.config.Roxie.ClusterType.NeedsPullSecrets()
if err := d.prepareNamespace(ctx, d.config.SecuredCluster.Namespace, needPullSecrets); err != nil {
return fmt.Errorf("failed to prepare namespace: %w", err)
}
Expand Down
6 changes: 3 additions & 3 deletions internal/deployer/deployer.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ func (d *Deployer) stopDetachedPortForward() {
// Deploy deploys the specified components to the cluster.
func (d *Deployer) Deploy(ctx context.Context, components component.Component) error {
// Prepare and verify credentials early to fail fast.
if env.GetCurrentClusterType() != types.ClusterTypeInfraOpenShift4 {
if d.config.Roxie.ClusterType.NeedsPullSecrets() {
if err := d.prepareCredentials(); err != nil {
return fmt.Errorf("failed to prepare credentials: %w", err)
}
Expand Down Expand Up @@ -778,7 +778,7 @@ func (d *Deployer) PrintCentralDeploymentSummary() {

// Deployment details
log.Info(cyan.Sprint("│") + createRow("Component", component))
log.Info(cyan.Sprint("│") + createRow("Cluster Type", env.GetCurrentClusterType().String()))
log.Info(cyan.Sprint("│") + createRow("Cluster Type", d.config.Roxie.ClusterType.String()))
log.Info(cyan.Sprint("│") + createRow("Main Tag", mainImageTag))
log.Info(cyan.Sprint("│") + createRow("Kubernetes Context", kubeContext))

Expand Down Expand Up @@ -957,7 +957,7 @@ func (d *Deployer) PrintSecuredClusterDeploymentSummary() {

// Deployment details
log.Info(cyan.Sprint("│") + createRow("Component", component))
log.Info(cyan.Sprint("│") + createRow("Cluster Type", env.GetCurrentClusterType().String()))
log.Info(cyan.Sprint("│") + createRow("Cluster Type", d.config.Roxie.ClusterType.String()))
log.Info(cyan.Sprint("│") + createRow("Main Tag", mainImageTag))
log.Info(cyan.Sprint("│") + createRow("Kubernetes Context", kubeContext))

Expand Down
8 changes: 3 additions & 5 deletions internal/deployer/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,8 @@ import (

"gopkg.in/yaml.v3"

"github.com/stackrox/roxie/internal/env"
"github.com/stackrox/roxie/internal/k8s"
"github.com/stackrox/roxie/internal/ocihelper"
"github.com/stackrox/roxie/internal/types"
)

const (
Expand Down Expand Up @@ -202,7 +200,7 @@ func (d *Deployer) getOperatorBundleImage() string {

// ensureKonfluxImageRewriting configures image rewriting for Konflux images
func (d *Deployer) ensureKonfluxImageRewriting(ctx context.Context) error {
if !env.GetCurrentClusterType().IsOpenShift() {
if !d.config.Roxie.ClusterType.IsOpenShift() {
return errors.New("image rewriting for Konflux is only supported on OpenShift4 clusters")
}

Expand Down Expand Up @@ -290,7 +288,7 @@ func (d *Deployer) applyImageContentSourcePolicy(ctx context.Context) error {

// removeKonfluxImageRewriting removes the ImageContentSourcePolicy for Konflux images if it exists
func (d *Deployer) removeKonfluxImageRewriting(ctx context.Context) error {
if !env.GetCurrentClusterType().IsOpenShift() {
if !d.config.Roxie.ClusterType.IsOpenShift() {
return nil
}

Expand Down Expand Up @@ -320,7 +318,7 @@ func (d *Deployer) deployOperatorFromCSV(ctx context.Context, bundleDir string)
}

serviceAccountName := deploymentSpec["service_account"].(string)
d.useOperatorPullSecrets = d.config.Roxie.KonfluxImages && env.GetCurrentClusterType() != types.ClusterTypeInfraOpenShift4
d.useOperatorPullSecrets = d.config.Roxie.KonfluxImages && d.config.Roxie.ClusterType.NeedsPullSecrets()

d.logger.Info("📋 Operator deployment plan:")
d.logger.Dim(fmt.Sprintf(" • Namespace: %s", operatorNamespace))
Expand Down
6 changes: 3 additions & 3 deletions internal/env/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ var (

var (
// currentClusterType holds the detected cluster type for the current kubectl context
// This is lazily populated on first access via GetCurrentClusterType()
// This is lazily populated on first access via GetAutoDetectedClusterType()
currentClusterType types.ClusterType

// currentContext holds the name of the current kubectl context
Expand Down Expand Up @@ -78,8 +78,8 @@ func ensureInitialized(log *logger.Logger) error {
return nil
}

// GetCurrentClusterType returns the current cluster type, initializing if needed
func GetCurrentClusterType() types.ClusterType {
// GetAutoDetectedClusterType returns the current cluster type, initializing if needed
func GetAutoDetectedClusterType() types.ClusterType {
return currentClusterType
}

Expand Down
2 changes: 1 addition & 1 deletion internal/env/env_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func TestDetectClusterType_Integration(t *testing.T) {

// This test uses the current kubectl context
// The result will depend on the active cluster
clusterType := GetCurrentClusterType()
clusterType := GetAutoDetectedClusterType()

t.Logf("Detected cluster type: %s", clusterType)

Expand Down
2 changes: 1 addition & 1 deletion internal/env/env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ func TestClusterTypeString(t *testing.T) {
{
name: "types.ClusterTypeInfraGKE",
clusterType: types.ClusterTypeInfraGKE,
want: "GKE",
want: "GKE (infra)",
},
{
name: "InfraOpenShift4",
Expand Down
57 changes: 36 additions & 21 deletions internal/types/cluster_type.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
package types

import "fmt"

// ClusterType represents different types of Kubernetes clusters
type ClusterType int
type ClusterType string

const (
// ClusterTypeUnknown represents an unidentified cluster type
ClusterTypeUnknown ClusterType = iota
ClusterTypeUnknown ClusterType = ""
// ClusterTypeInfraGKE represents a GKE cluster created via Infra.
ClusterTypeInfraGKE
ClusterTypeInfraGKE ClusterType = "InfraGKE"
// ClusterTypeInfraOpenShift4 represents an OpenShift 4 cluster
ClusterTypeInfraOpenShift4
ClusterTypeInfraOpenShift4 ClusterType = "InfraOpenShift4"
// Generic OpenShift4 cluster (e.g. for prow CI)
ClusterTypeOpenShift4
ClusterTypeOpenShift4 ClusterType = "OpenShift4"
// ClusterTypeKind represents a Kind (Kubernetes in Docker) cluster
ClusterTypeKind
ClusterTypeKind ClusterType = "Kind"
// ClusterTypeMinikube represents a Minikube cluster
ClusterTypeMinikube
ClusterTypeMinikube ClusterType = "Minikube"
// ClusterTypeK3s represents a K3s cluster
ClusterTypeK3s
ClusterTypeK3s ClusterType = "K3s"
// ClusterTypeCRC represents a CRC (CodeReady Containers) cluster
ClusterTypeCRC
ClusterTypeCRC ClusterType = "CRC"
)

func (ct ClusterType) IsOpenShift() bool {
Expand All @@ -30,21 +32,13 @@ func (ct ClusterType) IsOpenShift() bool {
func (ct ClusterType) String() string {
switch ct {
Comment thread
mclasmeier marked this conversation as resolved.
case ClusterTypeInfraGKE:
return "GKE"
return "GKE (infra)"
case ClusterTypeInfraOpenShift4:
return "OpenShift4 (infra)"
case ClusterTypeOpenShift4:
return "OpenShift4"
case ClusterTypeKind:
return "Kind"
case ClusterTypeMinikube:
return "minikube"
case ClusterTypeK3s:
return "k3s"
case ClusterTypeCRC:
return "crc"
default:
case ClusterTypeUnknown:
return "Unknown"
default:
return string(ct)
}
}

Expand All @@ -59,3 +53,24 @@ func AllClusterTypes() []ClusterType {
ClusterTypeOpenShift4,
}
}

func (ct *ClusterType) UnmarshalYAML(unmarshal func(any) error) error {
var s string
if err := unmarshal(&s); err != nil {
return err
}

var sAsClusterType = ClusterType(s)

for _, valid := range AllClusterTypes() {
if sAsClusterType == valid {
*ct = valid
return nil
}
}
return fmt.Errorf("unknown cluster type identifier: %q", s)
}

func (ct ClusterType) NeedsPullSecrets() bool {
return ct != ClusterTypeInfraOpenShift4
}
74 changes: 74 additions & 0 deletions internal/types/cluster_type_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package types

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v3"
)

func TestClusterTypeMarshalYAML(t *testing.T) {
tests := []struct {
clusterType ClusterType
expected string
}{
{ClusterTypeInfraGKE, "InfraGKE"},
{ClusterTypeInfraOpenShift4, "InfraOpenShift4"},
{ClusterTypeOpenShift4, "OpenShift4"},
{ClusterTypeKind, "Kind"},
{ClusterTypeMinikube, "Minikube"},
{ClusterTypeK3s, "K3s"},
{ClusterTypeCRC, "CRC"},
}
for _, tt := range tests {
t.Run(tt.expected, func(t *testing.T) {
out, err := yaml.Marshal(tt.clusterType)
require.NoError(t, err)
assert.Equal(t, tt.expected+"\n", string(out))
})
}
}

func TestClusterTypeUnmarshalYAML(t *testing.T) {
tests := []struct {
input string
expected ClusterType
}{
{"InfraGKE", ClusterTypeInfraGKE},
{"InfraOpenShift4", ClusterTypeInfraOpenShift4},
{"OpenShift4", ClusterTypeOpenShift4},
{"Kind", ClusterTypeKind},
{"Minikube", ClusterTypeMinikube},
{"K3s", ClusterTypeK3s},
{"CRC", ClusterTypeCRC},
{"", ClusterTypeUnknown},
}
for _, tt := range tests {
t.Run(tt.input, func(t *testing.T) {
var ct ClusterType
err := yaml.Unmarshal([]byte(tt.input), &ct)
require.NoError(t, err)
assert.Equal(t, tt.expected, ct)
})
}
}

func TestClusterTypeUnmarshalYAML_Invalid(t *testing.T) {
var ct ClusterType
err := yaml.Unmarshal([]byte("bogus"), &ct)
assert.ErrorContains(t, err, "unknown cluster type identifier")
}

func TestClusterTypeRoundTrip(t *testing.T) {
for _, ct := range AllClusterTypes() {
t.Run(ct.String(), func(t *testing.T) {
out, err := yaml.Marshal(ct)
require.NoError(t, err)

var parsed ClusterType
require.NoError(t, yaml.Unmarshal(out, &parsed))
assert.Equal(t, ct, parsed)
})
}
}
Loading