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

[WIP] chore: restructure CLI init and begin logging refactor #2350

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
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
26 changes: 13 additions & 13 deletions cmd/aws/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ package aws

import (
"fmt"
"io"

"github.com/konstructio/kubefirst-api/pkg/constants"
"github.com/konstructio/kubefirst/internal/common"
"github.com/konstructio/kubefirst/internal/progress"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -44,34 +44,34 @@ var (
supportedGitProtocolOverride = []string{"https", "ssh"}
)

func NewCommand() *cobra.Command {
awsCmd := &cobra.Command{
func NewCommand(logger common.Logger, writer io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "aws",
Short: "kubefirst aws installation",
Long: "kubefirst aws",
Run: func(_ *cobra.Command, _ []string) {
fmt.Println("To learn more about aws in kubefirst, run:")
fmt.Println(" kubefirst help")

if progress.Progress != nil {
progress.Progress.Quit()
}
fmt.Println(" kubefirst aws help")
},
}

service := AwsService{
logger,
writer,
}

// wire up new commands
awsCmd.AddCommand(Create(), Destroy(), Quota(), RootCredentials())
cmd.AddCommand(Create(service), Destroy(), Quota(), RootCredentials())

return awsCmd
return cmd
}

func Create() *cobra.Command {
func Create(service AwsService) *cobra.Command {
createCmd := &cobra.Command{
Use: "create",
Short: "create the kubefirst platform running in aws",
TraverseChildren: true,
RunE: createAws,
// PreRun: common.CheckDocker,
RunE: service.createAws,
}

awsDefaults := constants.GetCloudDefaults().Aws
Expand Down
50 changes: 35 additions & 15 deletions cmd/aws/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,66 +27,85 @@
"github.com/spf13/viper"
)

func createAws(cmd *cobra.Command, _ []string) error {
func (s *AwsService) createAws(cmd *cobra.Command, _ []string) error {
fmt.Fprintln(s.writer, "Starting to create AWS cluster")

cliFlags, err := utilities.GetFlags(cmd, "aws")
if err != nil {
progress.Error(err.Error())
return nil
s.logger.Error("failed to get flags", "error", err)
return fmt.Errorf("failed to get flags: %w", err)
}

progress.DisplayLogHints(40)
//TODO - Add progress steps

Check failure on line 39 in cmd/aws/create.go

View workflow job for this annotation

GitHub Actions / build

commentFormatting: put a space between `//` and comment text (gocritic)
//progress.DisplayLogHints(40)

isValid, catalogApps, err := catalog.ValidateCatalogApps(cliFlags.InstallCatalogApps)
if !isValid {
s.logger.Error("invalid catalog apps", "error", err)
return fmt.Errorf("invalid catalog apps: %w", err)
}

err = ValidateProvidedFlags(cliFlags.GitProvider)
if err != nil {
progress.Error(err.Error())
s.logger.Error("failed to validate provided flags", "error", err)
return fmt.Errorf("failed to validate provided flags: %w", err)
}

utilities.CreateK1ClusterDirectory(cliFlags.ClusterName)
// Create k1 cluster directory
homePath, err := os.UserHomeDir()

if err != nil {
s.logger.Error("failed to get user home directory", "error", err)
return fmt.Errorf("failed to get user home directory: %w", err)
}

err = utilities.CreateK1ClusterDirectoryE(homePath, cliFlags.ClusterName)

if err != nil {
s.logger.Error("failed to create k1 cluster directory", "error", err)
return fmt.Errorf("failed to create k1 cluster directory: %w", err)
}

// If cluster setup is complete, return
clusterSetupComplete := viper.GetBool("kubefirst-checks.cluster-install-complete")
if clusterSetupComplete {
err = fmt.Errorf("this cluster install process has already completed successfully")
progress.Error(err.Error())
s.logger.Info("cluster install process has already completed successfully")
fmt.Fprintln(s.writer, "Cluster install process has already completed successfully")
return nil
}

// Validate aws region
config, err := awsinternal.NewAwsV2(cloudRegionFlag)
if err != nil {
progress.Error(err.Error())
s.logger.Error("failed to validate AWS region", "error", err)
return fmt.Errorf("failed to validate AWS region: %w", err)
}

awsClient := &awsinternal.Configuration{Config: config}
creds, err := awsClient.Config.Credentials.Retrieve(aws.BackgroundContext())
if err != nil {
progress.Error(err.Error())
s.logger.Error("failed to retrieve AWS credentials", "error", err)
return fmt.Errorf("failed to retrieve AWS credentials: %w", err)
}

viper.Set("kubefirst.state-store-creds.access-key-id", creds.AccessKeyID)
viper.Set("kubefirst.state-store-creds.secret-access-key-id", creds.SecretAccessKey)
viper.Set("kubefirst.state-store-creds.token", creds.SessionToken)
if err := viper.WriteConfig(); err != nil {
s.logger.Error("failed to write config", "error", err)

return fmt.Errorf("failed to write config: %w", err)
}

_, err = awsClient.CheckAvailabilityZones(cliFlags.CloudRegion)
if err != nil {
progress.Error(err.Error())
s.logger.Error("failed to check availability zones", "error", err)
return fmt.Errorf("failed to check availability zones: %w", err)
}

gitAuth, err := gitShim.ValidateGitCredentials(cliFlags.GitProvider, cliFlags.GithubOrg, cliFlags.GitlabGroup)
if err != nil {
progress.Error(err.Error())
s.logger.Error("failed to validate Git credentials", "error", err)
return fmt.Errorf("failed to validate Git credentials: %w", err)
}

Expand All @@ -105,13 +124,14 @@

err = gitShim.InitializeGitProvider(&initGitParameters)
if err != nil {
progress.Error(err.Error())
s.logger.Error("failed to initialize Git provider", "error", err)
return fmt.Errorf("failed to initialize Git provider: %w", err)
}
}

viper.Set(fmt.Sprintf("kubefirst-checks.%s-credentials", cliFlags.GitProvider), true)
if err := viper.WriteConfig(); err != nil {
s.logger.Error("failed to write config", "error", err)
return fmt.Errorf("failed to write config: %w", err)
}

Expand All @@ -124,12 +144,12 @@

err = pkg.IsAppAvailable(fmt.Sprintf("%s/api/proxyHealth", cluster.GetConsoleIngressURL()), "kubefirst api")
if err != nil {
progress.Error("unable to start kubefirst api")
s.logger.Error("failed to check kubefirst API availability", "error", err)
return fmt.Errorf("failed to check kubefirst API availability: %w", err)
}

if err := provision.CreateMgmtCluster(gitAuth, cliFlags, catalogApps); err != nil {
progress.Error(err.Error())
s.logger.Error("failed to create management cluster", "error", err)
return fmt.Errorf("failed to create management cluster: %w", err)
}

Expand Down
12 changes: 12 additions & 0 deletions cmd/aws/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package aws

import (
"io"

"github.com/konstructio/kubefirst/internal/common"
)

type AwsService struct {

Check failure on line 9 in cmd/aws/types.go

View workflow job for this annotation

GitHub Actions / build

exported: type name will be used as aws.AwsService by other packages, and that stutters; consider calling this Service (revive)
logger common.Logger
writer io.Writer
}
4 changes: 0 additions & 4 deletions cmd/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,3 @@ var infoCmd = &cobra.Command{
return nil
},
}

func init() {
rootCmd.AddCommand(infoCmd)
}
4 changes: 0 additions & 4 deletions cmd/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,3 @@ var logsCmd = &cobra.Command{
return nil
},
}

func init() {
rootCmd.AddCommand(logsCmd)
}
4 changes: 0 additions & 4 deletions cmd/reset.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,6 @@ var resetCmd = &cobra.Command{
},
}

func init() {
rootCmd.AddCommand(resetCmd)
}

// parseConfigEntryKubefirstChecks gathers the kubefirst-checks section of the Viper
// config file and parses as a map[string]bool
func parseConfigEntryKubefirstChecks(checks map[string]interface{}) (map[string]bool, error) {
Expand Down
75 changes: 40 additions & 35 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package cmd

import (
"fmt"
"os"

"github.com/konstructio/kubefirst-api/pkg/configs"
"github.com/konstructio/kubefirst-api/pkg/progressPrinter"
Expand All @@ -20,52 +21,56 @@ import (
"github.com/spf13/cobra"
)

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "kubefirst",
Short: "kubefirst management cluster installer base command",
Long: `kubefirst management cluster installer provisions an
open source application delivery platform in under an hour.
checkout the docs at https://kubefirst.konstruct.io/docs/.`,
PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
// wire viper config for flags for all commands
return configs.InitializeViperConfig(cmd)
},
Run: func(_ *cobra.Command, _ []string) {
fmt.Println("To learn more about kubefirst, run:")
fmt.Println(" kubefirst help")
progress.Progress.Quit()
},
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
// This will allow all child commands to have informUser available for free.
// Refers: https://github.com/konstructio/runtime/issues/525
// Before removing next line, please read ticket above.
common.CheckForVersionUpdate()
progressPrinter.GetInstance()
if err := rootCmd.Execute(); err != nil {
fmt.Println("Error occurred during command execution:", err)
fmt.Println("If a detailed error message was available, please make the necessary corrections before retrying.")
fmt.Println("You can re-run the last command to try the operation again.")
progress.Progress.Quit()
func Execute(logger common.Logger) {
// rootCmd represents the base command when called without any subcommands
rootCmd := &cobra.Command{
Use: "kubefirst",
Short: "kubefirst management cluster installer base command",
Long: `kubefirst management cluster installer provisions an
open source application delivery platform in under an hour.
checkout the docs at https://kubefirst.konstruct.io/docs/.`,
PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
// wire viper config for flags for all commands
return configs.InitializeViperConfig(cmd)
},
Run: func(_ *cobra.Command, _ []string) {
fmt.Println("To learn more about kubefirst, run:")
fmt.Println(" kubefirst help")
progress.Progress.Quit()
},
SilenceUsage: true,
SilenceErrors: true,
}
}

func init() {
cobra.OnInitialize()
rootCmd.SilenceUsage = true
rootCmd.SetErr(os.Stderr)
rootCmd.SetOut(os.Stdout)

rootCmd.AddCommand(
betaCmd,
aws.NewCommand(),
aws.NewCommand(logger, os.Stderr),
civo.NewCommand(),
digitalocean.NewCommand(),
k3d.NewCommand(),
k3d.LocalCommandAlias(),
LaunchCommand(),
LetsEncryptCommand(),
TerraformCommand(),
betaCmd,
infoCmd,
versionCmd,
resetCmd,
logsCmd,
)
// This will allow all child commands to have informUser available for free.
// Refers: https://github.com/konstructio/runtime/issues/525
// Before removing next line, please read ticket above.
common.CheckForVersionUpdate()
progressPrinter.GetInstance()
if err := rootCmd.Execute(); err != nil {
fmt.Printf("Error occurred during command execution: %v\n", err)
fmt.Println("If a detailed error message was available, please make the necessary corrections before retrying.")
fmt.Println("You can re-run the last command to try the operation again.")
os.Exit(1)
}
}
4 changes: 0 additions & 4 deletions cmd/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ import (
"github.com/spf13/cobra"
)

func init() {
rootCmd.AddCommand(versionCmd)
}

var versionCmd = &cobra.Command{
Use: "version",
Short: "print the version number for kubefirst-cli",
Expand Down
8 changes: 8 additions & 0 deletions internal/common/logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package common

type Logger interface {
Debug(msg string, args ...any)
Info(msg string, args ...any)
Warn(msg string, args ...any)
Error(msg string, args ...any)
}
31 changes: 31 additions & 0 deletions internal/common/printer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package common

import (
"fmt"
"io"
)

type Printer struct {
writers []io.Writer
}

func NewPrinter(writers ...io.Writer) *Printer {
return &Printer{
writers: writers,
}
}

func (p *Printer) AddWriter(w io.Writer) {
p.writers = append(p.writers, w)
}

func (p *Printer) Print(s string) error {
for _, w := range p.writers {
_, err := fmt.Fprint(w, s)
if err != nil {
return fmt.Errorf("failed to write to writer: %w", err)
}
}

return nil
}
Loading
Loading