Skip to content
Merged
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
120 changes: 66 additions & 54 deletions cmd/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ func NewApplyCmd() *cobra.Command {
applyCmd := &cobra.Command{
Use: "apply",
Short: "Apply the configuration to create, update, or upgrade a battle-tested SIGHUP Distribution cluster",
Example: ` furyctl apply Apply all the configuration to the cluster using the default configuration file name
Comment thread
ralgozino marked this conversation as resolved.
furyctl apply --config mycluster.yaml Apply a custom configuration file
furyctl apply --phase distribution Apply a single phase, for example the distribution phase
furyctl apply --post-apply-phases distribution Apply all the phases, and repeat the distribution phase afterwards
`,
PreRun: func(cmd *cobra.Command, _ []string) {
cmdEvent = analytics.NewCommandEvent(cobrax.GetFullname(cmd))

Expand All @@ -93,59 +98,31 @@ func NewApplyCmd() *cobra.Command {
tracker.Flush()

// Get flags.
flags, err := getCreateClusterCmdFlags()
if err != nil {
return err
}

outDir := flags.Outdir

// Get home dir.
logrus.Debug("Getting Home Directory Path...")

homeDir, err := os.UserHomeDir()
flags, err := getApplyCmdFlags()
if err != nil {
cmdEvent.AddErrorMessage(err)
tracker.Track(cmdEvent)

return fmt.Errorf("error while getting user home directory: %w", err)
}

if outDir == "" {
outDir = homeDir
}

if flags.BinPath == "" {
flags.BinPath = filepath.Join(outDir, ".furyctl", "bin")
return err
}

if flags.DryRun {
logrus.Info("Dry run mode enabled, no changes will be applied")
}

absDistroPatchesLocation := flags.DistroPatchesLocation

if absDistroPatchesLocation != "" {
absDistroPatchesLocation, err = filepath.Abs(flags.DistroPatchesLocation)
if err != nil {
cmdEvent.AddErrorMessage(err)
tracker.Track(cmdEvent)

return fmt.Errorf("error while getting absolute path of distro patches location: %w", err)
}
}

var distrodl *dist.Downloader

logrus.Debugf("Using configuration file from path %s", flags.FuryctlPath)

// Init first half of collaborators.
client := netx.NewGoGetterClient()
executor := execx.NewStdExecutor()
depsvl := dependencies.NewValidator(executor, flags.BinPath, flags.FuryctlPath, flags.VpnAutoConnect)

if flags.DistroLocation == "" {
distrodl = dist.NewCachingDownloader(client, outDir, flags.GitProtocol, absDistroPatchesLocation)
distrodl = dist.NewCachingDownloader(client, flags.Outdir, flags.GitProtocol, flags.DistroPatchesLocation)
} else {
distrodl = dist.NewDownloader(client, flags.GitProtocol, absDistroPatchesLocation)
distrodl = dist.NewDownloader(client, flags.GitProtocol, flags.DistroPatchesLocation)
}

// Init packages.
Expand Down Expand Up @@ -212,10 +189,10 @@ func NewApplyCmd() *cobra.Command {
}
defer lockFileHandler.Remove() //nolint:errcheck // ignore error

basePath := filepath.Join(outDir, ".furyctl", res.MinimalConf.Metadata.Name)
basePath := filepath.Join(flags.Outdir, ".furyctl", res.MinimalConf.Metadata.Name)

// Init second half of collaborators.
depsdl := dependencies.NewCachingDownloader(client, outDir, basePath, flags.BinPath, flags.GitProtocol)
depsdl := dependencies.NewCachingDownloader(client, flags.Outdir, basePath, flags.BinPath, flags.GitProtocol)

// Validate the furyctl.yaml file.
logrus.Info("Validating configuration file...")
Expand All @@ -235,6 +212,8 @@ func NewApplyCmd() *cobra.Command {

return fmt.Errorf("%w: %v", ErrDownloadDependenciesFailed, errs)
}
} else {
logrus.Info("Dependencies download skipped")
}

// Validate the dependencies, unless explicitly told to skip it.
Expand All @@ -246,19 +225,13 @@ func NewApplyCmd() *cobra.Command {

return fmt.Errorf("error while validating dependencies: %w", err)
}
}

absFuryctlPath, err := filepath.Abs(flags.FuryctlPath)
if err != nil {
cmdEvent.AddErrorMessage(err)
tracker.Track(cmdEvent)

return fmt.Errorf("error while initializing cluster creation: %w", err)
} else {
logrus.Info("Dependencies validation skipped")
}

// Define cluster creation paths.
paths := cluster.CreatorPaths{
ConfigPath: absFuryctlPath,
ConfigPath: flags.FuryctlPath,
WorkDir: basePath,
DistroPath: res.RepoPath,
BinPath: flags.BinPath,
Expand Down Expand Up @@ -308,7 +281,7 @@ func NewApplyCmd() *cobra.Command {
},
}

setupCreateClusterCmdFlags(applyCmd)
setupApplyCmdFlags(applyCmd)

return applyCmd
}
Expand All @@ -322,9 +295,44 @@ func getSkipsClusterCmdFlags() ClusterSkipsCmdFlags {
}
}

func getCreateClusterCmdFlags() (ClusterCmdFlags, error) {
func getApplyCmdFlags() (ClusterCmdFlags, error) {
Comment thread
ralgozino marked this conversation as resolved.
var err error
Comment thread
ralgozino marked this conversation as resolved.

skips := getSkipsClusterCmdFlags()

// The binPath path must be calculated here because when we launch the tools
// we sometimes change the working directory where the binary is launched
// breaking the relative path.
binPath := viper.GetString("bin-path")
if binPath == "" {
// The outdir flag is already calculated in the root command, so we can use it here.
binPath = filepath.Join(viper.GetString("outdir"), ".furyctl", "bin")
} else {
binPath, err = filepath.Abs(binPath)
if err != nil {
return ClusterCmdFlags{}, fmt.Errorf("error while getting absolute path for bin folder: %w", err)
}
}

distroPatchesLocation := viper.GetString("distro-patches")
if distroPatchesLocation != "" {
distroPatchesLocation, err = filepath.Abs(viper.GetString("distro-patches"))
if err != nil {
return ClusterCmdFlags{}, fmt.Errorf("error while getting absolute path of distro patches location: %w", err)
}
}

furyctlPath := viper.GetString("config")

if furyctlPath == "" {
return ClusterCmdFlags{}, fmt.Errorf("%w --config: cannot be an empty string", ErrParsingFlag)
}

furyctlPath, err = filepath.Abs(furyctlPath)
if err != nil {
return ClusterCmdFlags{}, fmt.Errorf("error while getting configuration file absolute path: %w", err)
}

phase := viper.GetString("phase")

if err := cluster.CheckPhase(phase); err != nil {
Expand Down Expand Up @@ -376,17 +384,21 @@ func getCreateClusterCmdFlags() (ClusterCmdFlags, error) {

postApplyPhases := viper.GetStringSlice("post-apply-phases")

if phase != cluster.OperationPhaseAll && len(postApplyPhases) > 0 {
return ClusterCmdFlags{}, fmt.Errorf("%w: phase and post-apply-phases cannot be used at the same time", ErrParsingFlag)
}

if err := validatePostApplyPhasesFlag(postApplyPhases); err != nil {
return ClusterCmdFlags{}, fmt.Errorf("%w: %s %w", ErrParsingFlag, "post-apply-phases", err)
}

return ClusterCmdFlags{
Debug: viper.GetBool("debug"),
FuryctlPath: viper.GetString("config"),
FuryctlPath: furyctlPath,
DistroLocation: viper.GetString("distro-location"),
Phase: phase,
StartFrom: startFrom,
BinPath: viper.GetString("bin-path"),
BinPath: binPath,
VpnAutoConnect: vpnAutoConnect,
DryRun: viper.GetBool("dry-run"),
NoTTY: viper.GetBool("no-tty"),
Expand All @@ -400,7 +412,7 @@ func getCreateClusterCmdFlags() (ClusterCmdFlags, error) {
Upgrade: upgrade,
UpgradePathLocation: viper.GetString("upgrade-path-location"),
UpgradeNode: upgradeNode,
DistroPatchesLocation: viper.GetString("distro-patches"),
DistroPatchesLocation: distroPatchesLocation,
ClusterSkipsCmdFlags: skips,
PostApplyPhases: postApplyPhases,
}, nil
Expand All @@ -416,7 +428,7 @@ func validatePostApplyPhasesFlag(phases []string) error {
return nil
}

func setupCreateClusterCmdFlags(cmd *cobra.Command) {
func setupApplyCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP(
"config",
"c",
Expand Down Expand Up @@ -458,7 +470,7 @@ func setupCreateClusterCmdFlags(cmd *cobra.Command) {
"Location where to download schemas, defaults, and the distribution manifests from. "+
"It can either be a local path (eg: /path/to/distribution) or "+
"a remote URL (eg: git::git@github.com:sighupio/distribution?depth=1&ref=BRANCH_NAME). "+
"Any format supported by hashicorp/go-getter can be used.",
"Any format supported by hashicorp/go-getter can be used",
)

cmd.Flags().String(
Expand All @@ -469,14 +481,14 @@ func setupCreateClusterCmdFlags(cmd *cobra.Command) {
"a remote URL (eg: git::git@github.com:your-org/distro-patches?depth=1&ref=BRANCH_NAME). "+
"Any format supported by hashicorp/go-getter can be used."+
" Patches within this location must be in a folder named after the distribution version (eg: v1.29.0) and "+
"must have the same structure as the distribution's repository.",
"must have the same structure as the distribution's repository",
)

cmd.Flags().StringP(
"bin-path",
"b",
"",
"Path to the folder where all the dependencies' binaries are installed",
"Path to the folder where all the dependencies' binaries are downloaded",
)

cmd.Flags().Bool(
Expand Down
27 changes: 10 additions & 17 deletions cmd/create/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"fmt"
"os"
"path/filepath"
"strings"

"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -85,18 +86,6 @@ func NewConfigCmd() *cobra.Command {
return fmt.Errorf("%w: %w", ErrParsingFlag, err)
}

homeDir, err := os.UserHomeDir()
if err != nil {
cmdEvent.AddErrorMessage(err)
tracker.Track(cmdEvent)

return fmt.Errorf("error while getting user home directory: %w", err)
}

if outDir == "" {
outDir = homeDir
}

minimalConf := distroconf.Furyctl{
APIVersion: apiVersion,
Kind: kind,
Expand Down Expand Up @@ -218,17 +207,21 @@ func NewConfigCmd() *cobra.Command {
"distro-location",
"",
"",
"Base URL used to download schemas, defaults and the distribution manifest. "+
"Location where to download schemas, defaults, and the distribution manifests from. "+
"It can either be a local path(eg: /path/to/distribution) or "+
"a remote URL(eg: git::git@github.com:sighupio/distribution?depth=1&ref=BRANCH_NAME)."+
"Any format supported by hashicorp/go-getter can be used.",
"Any format supported by hashicorp/go-getter can be used",
)

configCmd.Flags().String(
"distro-patches",
"",
"Location where to download distribution's user-made patches from. "+
"Any format supported by hashicorp/go-getter can be used.",
"Location where the distribution's user-made patches can be downloaded from. "+
"This can be either a local path (eg: /path/to/distro-patches) or "+
"a remote URL (eg: git::git@github.com:your-org/distro-patches?depth=1&ref=BRANCH_NAME). "+
"Any format supported by hashicorp/go-getter can be used."+
" Patches within this location must be in a folder named after the distribution version (eg: v1.29.0) and "+
"must have the same structure as the distribution's repository",
)

configCmd.Flags().StringP(
Expand All @@ -242,7 +235,7 @@ func NewConfigCmd() *cobra.Command {
"kind",
"k",
"",
"Type of cluster to create (eg: EKSCluster, KFDDistribution, OnPremises)",
"Type of cluster to create. Options are "+strings.Join(distribution.ConfigKinds(), ", "),
)

if err := configCmd.RegisterFlagCompletionFunc("kind", func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
Expand Down
19 changes: 14 additions & 5 deletions cmd/create/pki.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"errors"
"fmt"
"net"
"path/filepath"

"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -107,20 +108,28 @@ You can limit the creation of the PKI to just etcd or just Kubernetes using the
tracker := ctn.Tracker()
defer tracker.Flush()

// Get flags
// maybe we could get this path from the furyctl.yaml file.
pkiPath := viper.GetString("path")
// Get flags.
etcd := viper.GetBool("etcd")
controlplane := viper.GetBool("controlplane")
// Maybe we could get this path from the furyctl.yaml file in the future.
pkiPath := viper.GetString("path")
pkiPath, err := filepath.Abs(pkiPath)
if err != nil {
tracker.Track(cmdEvent)
cmdEvent.AddErrorMessage(err)

return fmt.Errorf("error while getting absolute path for PKI folder path: %w", err)
}

if err := NewPki(etcd, controlplane, pkiPath); err != nil {
cmdEvent.AddErrorMessage(err)

return fmt.Errorf("PKI creation failed with error: %w", err)
}

cmdEvent.AddSuccessMessage("PKI files successfully created at:" + pkiPath)
cmdEvent.AddSuccessMessage("PKI files successfully created at" + pkiPath)
tracker.Track(cmdEvent)
logrus.Infof("PKI files successfully created at %s", pkiPath)

return nil
},
Expand All @@ -130,7 +139,7 @@ You can limit the creation of the PKI to just etcd or just Kubernetes using the
"path",
"p",
"pki",
"path where to save the created PKI files. One subfolder will be created for the control plane files and another one for the etcd files.",
"path where to save the created PKI files. One subfolder will be created for the control plane files and another one for the etcd files",
)

pkiCmd.Flags().BoolP(
Expand Down
Loading