Skip to content
This repository has been archived by the owner on Jun 29, 2022. It is now read-only.

Commit

Permalink
Merge pull request #1018 from kinvolk/invidian/cli-cleanup-part3
Browse files Browse the repository at this point in the history
cli/cmd: cleanups part 3
  • Loading branch information
knrt10 authored Oct 22, 2020
2 parents 6bd08f6 + 2c86b58 commit d0e87eb
Show file tree
Hide file tree
Showing 10 changed files with 214 additions and 86 deletions.
36 changes: 29 additions & 7 deletions cli/cmd/cluster-apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,32 @@ func runClusterApply(cmd *cobra.Command, args []string) {
"args": args,
})

if err := clusterApply(contextLogger); err != nil {
options := clusterApplyOptions{
confirm: confirm,
upgradeKubelets: upgradeKubelets,
skipComponents: skipComponents,
verbose: verbose,
}

if err := clusterApply(contextLogger, options); err != nil {
contextLogger.Fatalf("Applying cluster failed: %v", err)
}
}

type clusterApplyOptions struct {
confirm bool
upgradeKubelets bool
skipComponents bool
verbose bool
}

//nolint:funlen
func clusterApply(contextLogger *log.Entry) error {
c, err := initialize(contextLogger)
func clusterApply(contextLogger *log.Entry, options clusterApplyOptions) error {
cc := clusterConfig{
verbose: options.verbose,
}

c, err := cc.initialize(contextLogger)
if err != nil {
return fmt.Errorf("initializing: %w", err)
}
Expand All @@ -74,7 +92,7 @@ func clusterApply(contextLogger *log.Entry) error {
return fmt.Errorf("checking if cluster exists: %w", err)
}

if exists && !confirm {
if exists && !options.confirm {
// TODO: We could plan to a file and use it when installing.
if err := c.terraformExecutor.Plan(); err != nil {
return fmt.Errorf("reconciling cluster state: %v", err)
Expand All @@ -93,7 +111,11 @@ func clusterApply(contextLogger *log.Entry) error {

fmt.Printf("\nYour configurations are stored in %s\n", c.assetDir)

kubeconfig, err := getKubeconfig(contextLogger, c.lokomotiveConfig, true)
kg := kubeconfigGetter{
platformRequired: true,
}

kubeconfig, err := kg.getKubeconfig(contextLogger, c.lokomotiveConfig)
if err != nil {
return fmt.Errorf("getting kubeconfig: %v", err)
}
Expand Down Expand Up @@ -121,7 +143,7 @@ func clusterApply(contextLogger *log.Entry) error {

charts := platform.CommonControlPlaneCharts()

if upgradeKubelets {
if options.upgradeKubelets {
charts = append(charts, helm.LokomotiveChart{
Name: "kubelet",
Namespace: "kube-system",
Expand All @@ -141,7 +163,7 @@ func clusterApply(contextLogger *log.Entry) error {
}
}

if skipComponents {
if options.skipComponents {
return nil
}

Expand Down
22 changes: 18 additions & 4 deletions cli/cmd/cluster-destroy.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,27 @@ func runClusterDestroy(cmd *cobra.Command, args []string) {
"args": args,
})

if err := clusterDestroy(contextLogger); err != nil {
options := clusterDestroyOptions{
confirm: confirm,
verbose: verbose,
}

if err := clusterDestroy(contextLogger, options); err != nil {
contextLogger.Fatalf("Destroying cluster: %v", err)
}
}

func clusterDestroy(contextLogger *log.Entry) error {
c, err := initialize(contextLogger)
type clusterDestroyOptions struct {
confirm bool
verbose bool
}

func clusterDestroy(contextLogger *log.Entry, options clusterDestroyOptions) error {
cc := clusterConfig{
verbose: options.verbose,
}

c, err := cc.initialize(contextLogger)
if err != nil {
return fmt.Errorf("initializing: %w", err)
}
Expand All @@ -64,7 +78,7 @@ func clusterDestroy(contextLogger *log.Entry) error {
return nil
}

if !confirm {
if !options.confirm {
confirmation := askForConfirmation("WARNING: This action cannot be undone. Do you really want to destroy the cluster?")
if !confirmation {
contextLogger.Println("Cluster destroy canceled")
Expand Down
12 changes: 8 additions & 4 deletions cli/cmd/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,13 @@ type cluster struct {
assetDir string
}

type clusterConfig struct {
verbose bool
}

// initialize does common initialization actions between cluster operations
// and returns created objects to the caller for further use.
func initialize(contextLogger *log.Entry) (*cluster, error) {
func (cc clusterConfig) initialize(contextLogger *log.Entry) (*cluster, error) {
lokoConfig, diags := getLokoConfig()
if diags.HasErrors() {
return nil, diags
Expand Down Expand Up @@ -92,7 +96,7 @@ func initialize(contextLogger *log.Entry) (*cluster, error) {
return nil, fmt.Errorf("validating backend configuration: %v", err)
}

ex, err := initializeTerraform(p, b)
ex, err := cc.initializeTerraform(p, b)
if err != nil {
return nil, fmt.Errorf("initializing Terraform: %w", err)
}
Expand All @@ -107,7 +111,7 @@ func initialize(contextLogger *log.Entry) (*cluster, error) {

// initializeTerraform initialized Terraform directory using given backend and platform
// and returns configured executor.
func initializeTerraform(p platform.Platform, b backend.Backend) (*terraform.Executor, error) {
func (cc clusterConfig) initializeTerraform(p platform.Platform, b backend.Backend) (*terraform.Executor, error) {
assetDir, err := homedir.Expand(p.Meta().AssetDir)
if err != nil {
return nil, fmt.Errorf("expanding path %q: %w", p.Meta().AssetDir, err)
Expand All @@ -126,7 +130,7 @@ func initializeTerraform(p platform.Platform, b backend.Backend) (*terraform.Exe

conf := terraform.Config{
WorkingDir: terraform.GetTerraformRootDir(assetDir),
Verbose: verbose,
Verbose: cc.verbose,
}

ex, err := terraform.NewExecutor(conf)
Expand Down
19 changes: 16 additions & 3 deletions cli/cmd/component-apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,22 @@ func runApply(cmd *cobra.Command, args []string) {
log.SetLevel(log.DebugLevel)
}

if err := componentApply(contextLogger, args); err != nil {
options := componentApplyOptions{
kubeconfigPath: kubeconfigFlag,
}

if err := componentApply(contextLogger, args, options); err != nil {
contextLogger.Fatalf("Applying components failed: %v", err)
}
}

type componentApplyOptions struct {
kubeconfigPath string
}

// componentApply implements 'lokoctl component apply' separated from CLI
// dependencies.
func componentApply(contextLogger *log.Entry, componentsList []string) error {
func componentApply(contextLogger *log.Entry, componentsList []string, options componentApplyOptions) error {
lokoConfig, diags := getLokoConfig()
if diags.HasErrors() {
return diags
Expand All @@ -79,7 +87,12 @@ func componentApply(contextLogger *log.Entry, componentsList []string) error {
return fmt.Errorf("getting component objects: %w", err)
}

kubeconfig, err := getKubeconfig(contextLogger, lokoConfig, false)
kg := kubeconfigGetter{
platformRequired: false,
path: options.kubeconfigPath,
}

kubeconfig, err := kg.getKubeconfig(contextLogger, lokoConfig)
if err != nil {
contextLogger.Debugf("Error in finding kubeconfig file: %s", err)

Expand Down
48 changes: 38 additions & 10 deletions cli/cmd/component-delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,38 +63,66 @@ func runDelete(cmd *cobra.Command, args []string) {
log.SetLevel(log.DebugLevel)
}

options := componentDeleteOptions{
confirm: confirm,
deleteNamespace: deleteNamespace,
kubeconfigPath: kubeconfigFlag,
}

if err := componentDelete(contextLogger, args, options); err != nil {
contextLogger.Fatalf("Deleting components failed: %v", err)
}
}

type componentDeleteOptions struct {
confirm bool
deleteNamespace bool
kubeconfigPath string
}

// componentDelete implements 'lokoctl component delete' separated from CLI
// dependencies.
func componentDelete(contextLogger *log.Entry, componentsList []string, options componentDeleteOptions) error {
lokoConfig, diags := getLokoConfig()
if diags.HasErrors() {
contextLogger.Fatal(diags)
return diags
}

componentsToDelete := selectComponentNames(args, *lokoConfig.RootConfig)
componentsToDelete := selectComponentNames(componentsList, *lokoConfig.RootConfig)

componentObjects, err := componentNamesToObjects(componentsToDelete)
if err != nil {
contextLogger.Fatalf("getting component objects: %v", err)
return fmt.Errorf("getting component objects: %v", err)
}

confirmationMessage := fmt.Sprintf(
"The following components will be deleted:\n\t%s\n\nAre you sure you want to proceed?",
strings.Join(componentsToDelete, "\n\t"),
)

if !confirm && !askForConfirmation(confirmationMessage) {
if !options.confirm && !askForConfirmation(confirmationMessage) {
contextLogger.Info("Components deletion cancelled.")

return
return nil
}

kg := kubeconfigGetter{
platformRequired: false,
path: options.kubeconfigPath,
}

kubeconfig, err := getKubeconfig(contextLogger, lokoConfig, false)
kubeconfig, err := kg.getKubeconfig(contextLogger, lokoConfig)
if err != nil {
contextLogger.Debugf("Error in finding kubeconfig file: %s", err)
contextLogger.Fatal("Suitable kubeconfig file not found. Did you run 'lokoctl cluster apply' ?")

return fmt.Errorf("suitable kubeconfig file not found. Did you run 'lokoctl cluster apply' ?")
}

if err := deleteComponents(kubeconfig, componentObjects); err != nil {
contextLogger.Fatal(err)
if err := deleteComponents(kubeconfig, componentObjects, options.deleteNamespace); err != nil {
return fmt.Errorf("deleting components: %w", err)
}

return nil
}

// selectComponentNames returns list of components to operate on. If explicit list is empty,
Expand Down Expand Up @@ -128,7 +156,7 @@ func componentNamesToObjects(componentNames []string) ([]components.Component, e
return c, nil
}

func deleteComponents(kubeconfig []byte, componentObjects []components.Component) error {
func deleteComponents(kubeconfig []byte, componentObjects []components.Component, deleteNamespace bool) error {
for _, compObj := range componentObjects {
fmt.Printf("Deleting component '%s'...\n", compObj.Metadata().Name)

Expand Down
30 changes: 16 additions & 14 deletions cli/cmd/component-render-manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,37 +40,39 @@ func runComponentRender(cmd *cobra.Command, args []string) {
"args": args,
})

if err := componentRenderManifest(contextLogger, args); err != nil {
contextLogger.Fatalf("Rendering component manifests failed: %v", err)
}
}

func componentRenderManifest(contextLogger *log.Entry, componentsList []string) error {
lokoConfig, diags := getLokoConfig()
if diags.HasErrors() {
for _, diagnostic := range diags {
contextLogger.Error(diagnostic.Error())
}
contextLogger.Fatal("Errors found while loading configuration")
}

var componentsToRender []string
if len(args) > 0 {
componentsToRender = append(componentsToRender, args...)
} else {
for _, component := range lokoConfig.RootConfig.Components {
componentsToRender = append(componentsToRender, component.Name)
}
return diags
}

if err := renderComponentManifests(lokoConfig, componentsToRender...); err != nil {
contextLogger.Fatal(err)
componentsToRender := selectComponentNames(componentsList, *lokoConfig.RootConfig)

if err := renderComponentManifests(lokoConfig, componentsToRender); err != nil {
return fmt.Errorf("rendering component manifests: %w", err)
}

return nil
}

func renderComponentManifests(lokoConfig *config.Config, componentNames ...string) error {
func renderComponentManifests(lokoConfig *config.Config, componentNames []string) error {
for _, componentName := range componentNames {
contextLogger := log.WithFields(log.Fields{
"component": componentName,
})

component, err := components.Get(componentName)
if err != nil {
return err
return fmt.Errorf("getting component %q: %w", componentName, err)
}

componentConfigBody := lokoConfig.LoadComponentConfigBody(componentName)
Expand All @@ -84,7 +86,7 @@ func renderComponentManifests(lokoConfig *config.Config, componentNames ...strin

manifests, err := component.RenderManifests()
if err != nil {
return err
return fmt.Errorf("rendering manifest of component %q: %w", componentName, err)
}

fmt.Printf("# manifests for component %s\n", componentName)
Expand Down
Loading

0 comments on commit d0e87eb

Please sign in to comment.