Skip to content
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
11 changes: 8 additions & 3 deletions internal/commands/loglevel/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ limitations under the License.
package loglevel

var (
ShowLogSettings = showLogSettings
UpdateDebuggingConfiguration = updateDebuggingConfiguration
UnsetDebuggingConfiguration = unsetDebuggingConfiguration
ShowLogSettings = showLogSettings
UpdateDebuggingConfiguration = updateDebuggingConfiguration
UnsetDebuggingConfiguration = unsetDebuggingConfiguration
UpdateDebuggingConfigurationInManaged = updateDebuggingConfigurationInManaged
CollectLogLevelConfigurationFromClient = collectLogLevelConfigurationFromClient
UpdateLogLevelConfigurationWithClient = updateLogLevelConfigurationWithClient
ShowLogSettingsInManaged = showLogSettingsInManaged
UnsetDebuggingConfigurationInManaged = unsetDebuggingConfigurationInManaged
)
75 changes: 59 additions & 16 deletions internal/commands/loglevel/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
"fmt"
"strings"

docopt "github.com/docopt/docopt-go"
"github.com/docopt/docopt-go"

libsveltosv1beta1 "github.com/projectsveltos/libsveltos/api/v1beta1"
)
Expand All @@ -34,17 +34,42 @@ func updateDebuggingConfiguration(ctx context.Context, logSeverity libsveltosv1b
return nil
}

found := false
spec := make([]libsveltosv1beta1.ComponentConfiguration, len(cc))
spec := buildUpdatedSpec(cc, component, logSeverity)
return updateLogLevelConfiguration(ctx, spec)
}

func updateDebuggingConfigurationInManaged(ctx context.Context, logSeverity libsveltosv1beta1.LogLevel,
component, namespace, clusterName string, clusterType libsveltosv1beta1.ClusterType) error {

managedClient, err := getManagedClusterClient(ctx, namespace, clusterName, clusterType)
if err != nil {
return err
}

cc, err := collectLogLevelConfigurationFromClient(ctx, managedClient)
if err != nil {
return err
}

spec := buildUpdatedSpec(cc, component, logSeverity)
return updateLogLevelConfigurationWithClient(ctx, managedClient, spec)
}

// buildUpdatedSpec returns the ComponentConfiguration slice that would result
// from setting component to logSeverity, preserving existing entries for other
// components.
func buildUpdatedSpec(cc []*componentConfiguration, component string,
logSeverity libsveltosv1beta1.LogLevel) []libsveltosv1beta1.ComponentConfiguration {

spec := make([]libsveltosv1beta1.ComponentConfiguration, len(cc))
found := false
for i, c := range cc {
if string(c.component) == component {
spec[i] = libsveltosv1beta1.ComponentConfiguration{
Component: c.component,
LogLevel: logSeverity,
}
found = true
break
} else {
spec[i] = libsveltosv1beta1.ComponentConfiguration{
Component: c.component,
Expand All @@ -62,22 +87,31 @@ func updateDebuggingConfiguration(ctx context.Context, logSeverity libsveltosv1b
)
}

return updateLogLevelConfiguration(ctx, spec)
return spec
}

// Set displays/changes log verbosity for a given component
// Set displays/changes log verbosity for a given component.
//
// When --namespace and --clusterName are provided, the DebuggingConfiguration
// is updated in the specified managed cluster. Otherwise, it is updated in the
// management cluster.
func Set(ctx context.Context, args []string) error {
doc := `Usage:
sveltosctl log-level set --component=<name> (--info|--debug|--verbose)
sveltosctl log-level set --component=<name> (--info|--debug|--verbose) [--namespace=<namespace>] [--clusterName=<cluster-name>] [--clusterType=<cluster-type>]
Options:
-h --help Show this screen.
--component=<name> Name of the component for which log severity is being set.
--info Set log severity to info.
--debug Set log severity to debug.
--verbose Set log severity to verbose.

-h --help Show this screen.
--component=<name> Name of the component for which log severity is being set.
--info Set log severity to info.
--debug Set log severity to debug.
--verbose Set log severity to verbose.
--namespace=<namespace> (Optional) Namespace of the managed cluster.
--clusterName=<cluster-name> (Optional) Name of the managed cluster.
--clusterType=<cluster-type> (Optional) Type of managed cluster: Capi or Sveltos. Defaults to Capi.

Description:
The log-level set command set log severity for the specified component.
If --namespace and --clusterName are provided, log severity is set in the
specified managed cluster. Otherwise it is set in the management cluster.
`
parsedArgs, err := docopt.ParseArgs(doc, nil, "1.0")
if err != nil {
Expand All @@ -95,18 +129,27 @@ Description:
component = passedComponent.(string)
}

namespace, clusterName, clusterType, err := parseManagedClusterArgs(parsedArgs)
if err != nil {
return err
}

info := parsedArgs["--info"].(bool)
debug := parsedArgs["--debug"].(bool)
verbose := parsedArgs["--verbose"].(bool)

var logSeverity libsveltosv1beta1.LogLevel
if info {
switch {
case info:
logSeverity = libsveltosv1beta1.LogLevelInfo
} else if debug {
case debug:
logSeverity = libsveltosv1beta1.LogLevelDebug
} else if verbose {
case verbose:
logSeverity = libsveltosv1beta1.LogLevelVerbose
}

if namespace != "" && clusterName != "" {
return updateDebuggingConfigurationInManaged(ctx, logSeverity, component, namespace, clusterName, clusterType)
}
return updateDebuggingConfiguration(ctx, logSeverity, component)
}
108 changes: 108 additions & 0 deletions internal/commands/loglevel/set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client/fake"

libsveltosv1beta1 "github.com/projectsveltos/libsveltos/api/v1beta1"
Expand Down Expand Up @@ -59,4 +60,111 @@ var _ = Describe("Set", func() {
Expect(currentDC.Spec.Configuration[0].Component).To(Equal(libsveltosv1beta1.ComponentAddonManager))
Expect(currentDC.Spec.Configuration[0].LogLevel).To(Equal(libsveltosv1beta1.LogLevelInfo))
})

It("collectLogLevelConfigurationFromClient returns empty configuration when DebuggingConfiguration does not exist", func() {
scheme, err := utils.GetScheme()
Expect(err).To(BeNil())
c := fake.NewClientBuilder().WithScheme(scheme).Build()

configs, err := loglevel.CollectLogLevelConfigurationFromClient(context.TODO(), c)
Expect(err).To(BeNil())
Expect(configs).ToNot(BeNil())
Expect(len(configs)).To(Equal(0))
})

It("collectLogLevelConfigurationFromClient returns existing configuration", func() {
scheme, err := utils.GetScheme()
Expect(err).To(BeNil())

// Create a DebuggingConfiguration with some initial settings
dc := &libsveltosv1beta1.DebuggingConfiguration{
ObjectMeta: metav1.ObjectMeta{
Name: "default",
},
Spec: libsveltosv1beta1.DebuggingConfigurationSpec{
Configuration: []libsveltosv1beta1.ComponentConfiguration{
{
Component: libsveltosv1beta1.ComponentClassifier,
LogLevel: libsveltosv1beta1.LogLevelDebug,
},
{
Component: libsveltosv1beta1.ComponentAddonManager,
LogLevel: libsveltosv1beta1.LogLevelInfo,
},
},
},
}

c := fake.NewClientBuilder().WithScheme(scheme).WithObjects(dc).Build()

configs, err := loglevel.CollectLogLevelConfigurationFromClient(context.TODO(), c)
Expect(err).To(BeNil())
Expect(configs).ToNot(BeNil())
Expect(len(configs)).To(Equal(2))
})

It("updateLogLevelConfigurationWithClient creates new DebuggingConfiguration when it does not exist", func() {
scheme, err := utils.GetScheme()
Expect(err).To(BeNil())
c := fake.NewClientBuilder().WithScheme(scheme).Build()

spec := []libsveltosv1beta1.ComponentConfiguration{
{
Component: libsveltosv1beta1.ComponentClassifier,
LogLevel: libsveltosv1beta1.LogLevelDebug,
},
}

err = loglevel.UpdateLogLevelConfigurationWithClient(context.TODO(), c, spec)
Expect(err).To(BeNil())

// Verify the configuration was created
configs, err := loglevel.CollectLogLevelConfigurationFromClient(context.TODO(), c)
Expect(err).To(BeNil())
Expect(configs).ToNot(BeNil())
Expect(len(configs)).To(Equal(1))
})

It("updateLogLevelConfigurationWithClient updates existing DebuggingConfiguration", func() {
scheme, err := utils.GetScheme()
Expect(err).To(BeNil())

// Create a DebuggingConfiguration with initial settings
dc := &libsveltosv1beta1.DebuggingConfiguration{
ObjectMeta: metav1.ObjectMeta{
Name: "default",
},
Spec: libsveltosv1beta1.DebuggingConfigurationSpec{
Configuration: []libsveltosv1beta1.ComponentConfiguration{
{
Component: libsveltosv1beta1.ComponentClassifier,
LogLevel: libsveltosv1beta1.LogLevelInfo,
},
},
},
}

c := fake.NewClientBuilder().WithScheme(scheme).WithObjects(dc).Build()

// Update the configuration
spec := []libsveltosv1beta1.ComponentConfiguration{
{
Component: libsveltosv1beta1.ComponentClassifier,
LogLevel: libsveltosv1beta1.LogLevelDebug,
},
{
Component: libsveltosv1beta1.ComponentAddonManager,
LogLevel: libsveltosv1beta1.LogLevelVerbose,
},
}

err = loglevel.UpdateLogLevelConfigurationWithClient(context.TODO(), c, spec)
Expect(err).To(BeNil())

// Verify the configuration was updated
configs, err := loglevel.CollectLogLevelConfigurationFromClient(context.TODO(), c)
Expect(err).To(BeNil())
Expect(configs).ToNot(BeNil())
Expect(len(configs)).To(Equal(2))
})
})
60 changes: 47 additions & 13 deletions internal/commands/loglevel/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ import (
"os"
"strings"

docopt "github.com/docopt/docopt-go"
"github.com/docopt/docopt-go"
"github.com/olekukonko/tablewriter"

libsveltosv1beta1 "github.com/projectsveltos/libsveltos/api/v1beta1"
)

func showLogSettings(ctx context.Context) error {
Expand All @@ -32,33 +34,57 @@ func showLogSettings(ctx context.Context) error {
return err
}

return renderLogSettings(componentConfiguration)
}

func showLogSettingsInManaged(ctx context.Context, namespace, clusterName string,
clusterType libsveltosv1beta1.ClusterType) error {

managedClient, err := getManagedClusterClient(ctx, namespace, clusterName, clusterType)
if err != nil {
return err
}

componentConfiguration, err := collectLogLevelConfigurationFromClient(ctx, managedClient)
if err != nil {
return err
}

return renderLogSettings(componentConfiguration)
}

func renderLogSettings(cc []*componentConfiguration) error {
table := tablewriter.NewWriter(os.Stdout)
table.Header([]string{"COMPONENT", "VERBOSITY"})
genRow := func(component, verbosity string) []string {
return []string{
component,
verbosity,
}
}

for _, c := range componentConfiguration {
if err := table.Append(genRow(string(c.component), string(c.logSeverity))); err != nil {
for _, c := range cc {
if err := table.Append([]string{string(c.component), string(c.logSeverity)}); err != nil {
return err
}
}

return table.Render()
}

// Show displays information about log verbosity (if set)
// Show displays information about log verbosity (if set).
//
// When --namespace and --clusterName are provided, settings are read from the
// specified managed cluster. Otherwise they are read from the management
// cluster.
func Show(ctx context.Context, args []string) error {
doc := `Usage:
sveltosctl log-level show
sveltosctl log-level show [--namespace=<namespace>] [--clusterName=<cluster-name>] [--clusterType=<cluster-type>]
Options:
-h --help Show this screen.

-h --help Show this screen.
--namespace=<namespace> (Optional) Namespace of the managed cluster.
--clusterName=<cluster-name> (Optional) Name of the managed cluster.
--clusterType=<cluster-type> (Optional) Type of managed cluster: Capi or Sveltos. Defaults to Capi.

Description:
The log-level show command shows information about current log verbosity.
If --namespace and --clusterName are provided, settings are read from the
specified managed cluster. Otherwise they are read from the management
cluster.
`
parsedArgs, err := docopt.ParseArgs(doc, nil, "1.0")
if err != nil {
Expand All @@ -71,5 +97,13 @@ Description:
return nil
}

namespace, clusterName, clusterType, err := parseManagedClusterArgs(parsedArgs)
if err != nil {
return err
}

if namespace != "" && clusterName != "" {
return showLogSettingsInManaged(ctx, namespace, clusterName, clusterType)
}
return showLogSettings(ctx)
}
29 changes: 29 additions & 0 deletions internal/commands/loglevel/show_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
Expand Down Expand Up @@ -82,4 +83,32 @@ var _ = Describe("Show", func() {
Expect(found).To(BeTrue())
os.Stdout = old
})

It("showLogSettingsInManaged displays log level settings from managed cluster", func() {
scheme, err := utils.GetScheme()
Expect(err).To(BeNil())

// Create a DebuggingConfiguration for the managed cluster
dc := &libsveltosv1beta1.DebuggingConfiguration{
ObjectMeta: metav1.ObjectMeta{
Name: "default",
},
Spec: libsveltosv1beta1.DebuggingConfigurationSpec{
Configuration: []libsveltosv1beta1.ComponentConfiguration{
{
Component: libsveltosv1beta1.ComponentClassifier,
LogLevel: libsveltosv1beta1.LogLevelInfo,
},
},
},
}

managedClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(dc).Build()

// Test the helper function directly with the managed client
componentConfiguration, err := loglevel.CollectLogLevelConfigurationFromClient(context.TODO(), managedClient)
Expect(err).To(BeNil())
Expect(componentConfiguration).ToNot(BeNil())
Expect(len(componentConfiguration)).To(Equal(1))
})
})
Loading