Skip to content

refactored the nomos commands for better separation of concerns #1742

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
79 changes: 0 additions & 79 deletions cmd/nomos/bugreport/bugreport.go

This file was deleted.

48 changes: 48 additions & 0 deletions cmd/nomos/bugreport/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package bugreport

import (
"fmt"

"github.com/spf13/cobra"
"kpt.dev/configsync/cmd/nomos/flags"
"kpt.dev/configsync/pkg/api/configmanagement"
)

// Cmd retrieves readers for all relevant nomos container logs and cluster state commands and writes them to a zip file
var Cmd = &cobra.Command{
Use: "bugreport",
Short: fmt.Sprintf("Generates a zip file of relevant %v debug information.", configmanagement.CLIName),
Long: "Generates a zip file in your current directory containing an aggregate of the logs and cluster state for debugging purposes.",
RunE: func(cmd *cobra.Command, _ []string) error {
// Don't show usage on error, as argument validation passed.
cmd.SilenceUsage = true

// Create execution parameters from parsed flags
params := ExecParams{
ClientTimeout: flags.ClientTimeout,
}

// Execute the bugreport command logic
return ExecuteBugreport(cmd.Context(), params)
},
}

func init() {
// Initialize flags for the bugreport command
// This separation keeps flag definitions isolated from command execution logic
flags.AddClientTimeout(Cmd)
}
68 changes: 68 additions & 0 deletions cmd/nomos/bugreport/exec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package bugreport

import (
"context"
"fmt"
"time"

"k8s.io/client-go/kubernetes"
"kpt.dev/configsync/pkg/bugreport"
"kpt.dev/configsync/pkg/client/restconfig"
"sigs.k8s.io/controller-runtime/pkg/client"
)

// ExecParams contains all parameters needed to execute the bugreport command
// This struct is completely independent of cobra command structures
type ExecParams struct {
ClientTimeout time.Duration
}

// ExecuteBugreport executes the core bugreport command logic without any cobra dependencies
// This function encapsulates all the business logic for the bugreport command
func ExecuteBugreport(ctx context.Context, params ExecParams) error {

cfg, err := restconfig.NewRestConfig(params.ClientTimeout)
if err != nil {
return fmt.Errorf("failed to create rest config: %w", err)
}
cs, err := kubernetes.NewForConfig(cfg)
if err != nil {
return fmt.Errorf("failed to create kubernetes client set: %w", err)
}
c, err := client.New(cfg, client.Options{})
if err != nil {
return fmt.Errorf("failed to create kubernetes client: %w", err)
}

report, err := bugreport.New(ctx, c, cs)
if err != nil {
return fmt.Errorf("failed to initialize bug reporter: %w", err)
}

if err = report.Open(); err != nil {
return err
}

report.WriteRawInZip(report.FetchLogSources(ctx))
report.WriteRawInZip(report.FetchResources(ctx))
report.WriteRawInZip(report.FetchCMSystemPods(ctx))
report.AddNomosStatusToZip(ctx)
report.AddNomosVersionToZip(ctx)

report.Close()
return nil
}
8 changes: 8 additions & 0 deletions cmd/nomos/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

// Package flags contains flags used by several CLI commands.
// The local flags will be found in the command folder in the flags.go file.
package flags

import (
Expand Down Expand Up @@ -119,6 +121,12 @@ func AddOutputFormat(cmd *cobra.Command) {
`Output format. Accepts 'yaml' and 'json'.`)
}

// AddClientTimeout adds the --timeout flag
func AddClientTimeout(cmd *cobra.Command) {
cmd.Flags().DurationVar(&ClientTimeout, "timeout", restconfig.DefaultTimeout,
fmt.Sprintf("Timeout for client connections; defaults to %s", restconfig.DefaultTimeout))
}

// AddAPIServerTimeout adds the --api-server-timeout flag
func AddAPIServerTimeout(cmd *cobra.Command) {
cmd.Flags().DurationVar(&APIServerTimeout, "api-server-timeout", restconfig.DefaultTimeout, fmt.Sprintf("Client-side timeout for talking to the API server; defaults to %s", restconfig.DefaultTimeout))
Expand Down
61 changes: 61 additions & 0 deletions cmd/nomos/hydrate/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package hydrate

import (
"github.com/spf13/cobra"
"kpt.dev/configsync/cmd/nomos/flags"
"kpt.dev/configsync/pkg/api/configsync"
)

// localFlags holds the hydrate command flags
var localFlags = NewFlags()

func init() {
// Initialize flags for the hydrate command
// This separation keeps flag definitions isolated from command execution logic
localFlags.AddFlags(Cmd)
}

// Cmd is the Cobra object representing the hydrate command.
var Cmd = &cobra.Command{
Use: "hydrate",
Short: "Compiles the local repository to the exact form that would be sent to the APIServer.",
Long: `Compiles the local repository to the exact form that would be sent to the APIServer.

The output directory consists of one directory per declared Cluster, and defaultcluster/ for
clusters without declarations. Each directory holds the full set of configs for a single cluster,
which you could kubectl apply -fR to the cluster, or have Config Sync sync to the cluster.`,
Args: cobra.ExactArgs(0),
RunE: func(cmd *cobra.Command, _ []string) error {
// Don't show usage on error, as argument validation passed.
cmd.SilenceUsage = true

// Create execution parameters from parsed flags
params := ExecParams{
Clusters: flags.Clusters,
Path: flags.Path,
SkipAPIServer: flags.SkipAPIServer,
SourceFormat: configsync.SourceFormat(flags.SourceFormat),
OutputFormat: flags.OutputFormat,
APIServerTimeout: flags.APIServerTimeout,
Flat: localFlags.Flat,
OutPath: localFlags.OutPath,
}

// Execute the hydrate command logic
return ExecuteHydrate(cmd.Context(), params)
},
}
Loading