Skip to content

Commit da81f0d

Browse files
committed
Show cluster type
Debug build target Print kubeconfig in 'env' command Integrate logger into env initialization, add convenience logging when running containerized Deleted file
1 parent 03d5890 commit da81f0d

7 files changed

Lines changed: 99 additions & 43 deletions

File tree

‎cmd/deploy.go‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,8 @@ Examples:
5050

5151
func runDeploy(cmd *cobra.Command, args []string) error {
5252
log := logger.New()
53-
54-
if env.RunningInContainer {
55-
log.Dim("Running containerized.")
53+
if err := env.Initialize(log); err != nil {
54+
return err
5655
}
5756

5857
if env.RunningInteractively {
@@ -98,9 +97,9 @@ func runDeploy(cmd *cobra.Command, args []string) error {
9897
}
9998

10099
// On infra OpenShift we already get image pull secrets for Quay automatically.
101-
if env.GetCurrentClusterType() != env.InfraOpenShift4 {
100+
if clusterType := env.GetCurrentClusterType(); clusterType != env.InfraOpenShift4 {
102101
if os.Getenv("REGISTRY_USERNAME") == "" || os.Getenv("REGISTRY_PASSWORD") == "" {
103-
return errors.New("containerized mode requires REGISTRY_USERNAME and REGISTRY_PASSWORD environment variables")
102+
return fmt.Errorf("containerized mode requires REGISTRY_USERNAME and REGISTRY_PASSWORD environment variables for clusters of type %s", clusterType)
104103
}
105104
if _, err := os.Stat("/kubeconfig"); err != nil {
106105
return fmt.Errorf("containerized mode requires /kubeconfig file: %w", err)

‎cmd/env.go‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ package main
22

33
import (
44
"fmt"
5+
"os"
56

67
"github.com/spf13/cobra"
78
"github.com/stackrox/roxie/internal/env"
9+
"github.com/stackrox/roxie/internal/logger"
810
)
911

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

1921
return cmd
2022
}
2123

22-
func runEnv(cmd *cobra.Command, args []string) {
24+
func runEnv(cmd *cobra.Command, args []string) error {
25+
log := logger.New()
26+
if err := env.Initialize(log); err != nil {
27+
return err
28+
}
29+
2330
fmt.Println("Roxie Environment Information:")
2431
fmt.Println("==============================")
32+
fmt.Printf("Kube config: %s\n", os.Getenv("KUBECONFIG"))
2533
fmt.Printf("Running in Container: %v\n", env.RunningInContainer)
2634
fmt.Printf("Current Context: %s\n", env.GetCurrentContext())
2735
fmt.Printf("Cluster Type: %s\n", env.GetCurrentClusterType().String())
36+
37+
return nil
2838
}

‎cmd/main.go‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ var (
2727
)
2828

2929
func main() {
30+
3031
if err := rootCmd.Execute(); err != nil {
3132
red := color.New(color.FgRed, color.Bold)
3233
red.Fprintf(os.Stderr, "Error: %v\n", err)

‎cmd/teardown.go‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"github.com/spf13/cobra"
99
"github.com/stackrox/roxie/internal/deployer"
10+
"github.com/stackrox/roxie/internal/env"
1011
"github.com/stackrox/roxie/internal/logger"
1112
)
1213

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

3031
func runTeardown(cmd *cobra.Command, args []string) error {
32+
log := logger.New()
33+
if err := env.Initialize(log); err != nil {
34+
return err
35+
}
36+
3137
component := "both"
3238
if len(args) > 0 {
3339
component = args[0]
3440
}
3541

36-
log := logger.New()
37-
3842
log.Infof("Tearing down %s", component)
3943

4044
d, err := deployer.New(log, "", []string{})

‎internal/env/env.go‎

Lines changed: 73 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@ package env
22

33
import (
44
"encoding/json"
5+
"errors"
56
"fmt"
67
"net/url"
78
"os"
89
"os/exec"
10+
"path/filepath"
911
"strings"
1012

1113
"github.com/stackrox/roxie/internal/containerutil"
14+
"github.com/stackrox/roxie/internal/logger"
1215
"golang.org/x/term"
1316
)
1417

@@ -65,25 +68,33 @@ func isRunningInteractively() bool {
6568

6669
// ensureInitialized performs lazy initialization of cluster information
6770
// This avoids contacting the cluster on package import
68-
func ensureInitialized() {
71+
func ensureInitialized(log *logger.Logger) error {
6972
if !initialized {
70-
kubeConfig := fetchKubeConfig()
73+
if RunningInContainer {
74+
log.Dim("Running containerized.")
75+
}
76+
kubeConfig, err := fetchKubeConfig(log)
77+
if err != nil {
78+
return err
79+
}
7180
currentContext = kubeConfig.CurrentContext
72-
apiResources := fetchAPIResources()
81+
apiResources, err := fetchAPIResources()
82+
if err != nil {
83+
return err
84+
}
7385
currentClusterType = detectClusterType(kubeConfig, apiResources)
7486
initialized = true
7587
}
88+
return nil
7689
}
7790

7891
// GetCurrentClusterType returns the current cluster type, initializing if needed
7992
func GetCurrentClusterType() ClusterType {
80-
ensureInitialized()
8193
return currentClusterType
8294
}
8395

8496
// GetCurrentContext returns the current kubectl context, initializing if needed
8597
func GetCurrentContext() string {
86-
ensureInitialized()
8798
return currentContext
8899
}
89100

@@ -113,13 +124,15 @@ type KubeCluster struct {
113124
Server string
114125
}
115126

116-
// DetectClusterType identifies the cluster type for the current kubectl context
117-
// This is a convenience wrapper that fetches the kubeconfig and API resources,
118-
// then delegates to detectClusterType for the actual detection logic
119-
func DetectClusterType() ClusterType {
120-
kubeConfig := fetchKubeConfig()
121-
apiResources := fetchAPIResources()
122-
return detectClusterType(kubeConfig, apiResources)
127+
// Initialize performs environment initialization and sets the global variables.
128+
func Initialize(log *logger.Logger) error {
129+
if log == nil {
130+
log = logger.New()
131+
}
132+
if err := ensureInitialized(log); err != nil {
133+
return fmt.Errorf("failed to initialize environment: %w", err)
134+
}
135+
return nil
123136
}
124137

125138
// detectClusterType implements the cluster type detection logic
@@ -180,20 +193,23 @@ func isOpenShift4(apiResources []string) bool {
180193
}
181194

182195
// fetchKubeConfig retrieves the current kubectl configuration
183-
func fetchKubeConfig() KubeConfig {
196+
func fetchKubeConfig(log *logger.Logger) (KubeConfig, error) {
197+
if err := kubeconfigChecks(log); err != nil {
198+
return KubeConfig{}, err
199+
}
184200
// Get current context
185201
cmd := exec.Command("kubectl", "config", "current-context")
186202
output, err := cmd.Output()
187203
if err != nil {
188-
return KubeConfig{}
204+
return KubeConfig{}, errors.New("failed to get current context")
189205
}
190206
currentContext := strings.TrimSpace(string(output))
191207

192208
// Get cluster info
193209
cmd = exec.Command("kubectl", "config", "view", "--minify", "-o", "json")
194210
output, err = cmd.Output()
195211
if err != nil {
196-
return KubeConfig{CurrentContext: currentContext}
212+
return KubeConfig{}, fmt.Errorf("failed to obtain minified kubeconfig: %w", err)
197213
}
198214

199215
var rawConfig struct {
@@ -207,7 +223,7 @@ func fetchKubeConfig() KubeConfig {
207223
}
208224

209225
if err := json.Unmarshal(output, &rawConfig); err != nil {
210-
return KubeConfig{CurrentContext: currentContext}
226+
return KubeConfig{}, fmt.Errorf("failed to unmarshal kubeconfig: %w", err)
211227
}
212228

213229
clusters := make([]KubeCluster, len(rawConfig.Clusters))
@@ -221,19 +237,57 @@ func fetchKubeConfig() KubeConfig {
221237
return KubeConfig{
222238
CurrentContext: currentContext,
223239
Clusters: clusters,
240+
}, nil
241+
}
242+
243+
func kubeconfigChecks(log *logger.Logger) error {
244+
kubeConfigPath, err := getKubeConfigPath()
245+
if err != nil {
246+
return fmt.Errorf("getting kubeconfig path: %w", err)
247+
}
248+
log.Infof("Using kubeconfig %s", kubeConfigPath)
249+
if _, err := os.Stat(kubeConfigPath); err != nil {
250+
log.Warningf("Kubeconfig %s cannot be found.", kubeConfigPath)
251+
if RunningInContainer {
252+
log.Warningf("Make sure that your kubeconfig is mounted into the container, as in: -v $KUBECONFIG:/kubeconfig:U")
253+
}
254+
return fmt.Errorf("failed to stat kubeconfig %s: %w", kubeConfigPath, err)
255+
}
256+
257+
file, err := os.Open(kubeConfigPath)
258+
if err != nil {
259+
log.Warningf("Kubeconfig %s cannot be opened for reading.", kubeConfigPath)
260+
if RunningInContainer {
261+
log.Warningf("Make sure that your kubeconfig is mounted with the 'U' option, as in: -v $KUBECONFIG:/kubeconfig:U")
262+
}
263+
return fmt.Errorf("failed to open kubeconfig %s: %w", kubeConfigPath, err)
264+
}
265+
_ = file.Close()
266+
return nil
267+
}
268+
269+
func getKubeConfigPath() (string, error) {
270+
kubeConfigPath := os.Getenv("KUBECONFIG")
271+
if kubeConfigPath == "" {
272+
home := os.Getenv("HOME")
273+
if home == "" {
274+
return "", errors.New("HOME environment variable is not set")
275+
}
276+
kubeConfigPath = filepath.Join(home, ".kube", "config")
224277
}
278+
return kubeConfigPath, nil
225279
}
226280

227281
// fetchAPIResources retrieves the list of API resources from the cluster
228-
func fetchAPIResources() []string {
282+
func fetchAPIResources() ([]string, error) {
229283
cmd := exec.Command("kubectl", "api-resources", "-o", "name")
230284
output, err := cmd.Output()
231285
if err != nil {
232-
return nil
286+
return nil, fmt.Errorf("failed to retrieve API resources: %w", err)
233287
}
234288

235289
lines := strings.Split(strings.TrimSpace(string(output)), "\n")
236-
return lines
290+
return lines, nil
237291
}
238292

239293
func IsInStackroxRepository() bool {

‎internal/env/env_test.go‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,11 @@ func TestDetectClusterType_GKE_DifferentProject(t *testing.T) {
189189
}
190190

191191
func TestDetectClusterType_Integration(t *testing.T) {
192+
Initialize(nil)
193+
192194
// This test uses the current kubectl context
193195
// The result will depend on the active cluster
194-
clusterType := DetectClusterType()
196+
clusterType := GetCurrentClusterType()
195197

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

‎internal/env/example_test.go‎

Lines changed: 0 additions & 14 deletions
This file was deleted.

0 commit comments

Comments
 (0)