Skip to content

Commit

Permalink
cli: status command (#768)
Browse files Browse the repository at this point in the history
Finished status command, resolved git issues.

Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
  • Loading branch information
sadjamz and ndhanushkodi authored Oct 25, 2021
1 parent 039542f commit a185c0a
Show file tree
Hide file tree
Showing 7 changed files with 532 additions and 76 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
IMPROVEMENTS:
* Helm Chart
* Automatic retry for `gossip-encryption-autogenerate-job` on failure [[GH-789](https://github.com/hashicorp/consul-k8s/pull/789)]
* CLI
* Add `status` command. [[GH-768](https://github.com/hashicorp/consul-k8s/pull/768)]

## 0.35.0 (October 19, 2021)

Expand Down
34 changes: 34 additions & 0 deletions cli/cmd/common/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package common

import (
"embed"
"errors"
"fmt"
"os"
"path/filepath"
Expand Down Expand Up @@ -95,3 +96,36 @@ func InitActionConfig(actionConfig *action.Configuration, namespace string, sett
}
return actionConfig, nil
}

// CheckForPreviousInstallations uses the helm Go SDK to find helm releases in all namespaces where the chart name is
// "consul", and returns the release name and namespace if found, or an error if not found.
func CheckForInstallations(settings *helmCLI.EnvSettings, uiLogger action.DebugLog) (string, string, error) {
// Need a specific action config to call helm list, where namespace is NOT specified.
listConfig := new(action.Configuration)
if err := listConfig.Init(settings.RESTClientGetter(), "",
os.Getenv("HELM_DRIVER"), uiLogger); err != nil {
return "", "", fmt.Errorf("couldn't initialize helm config: %s", err)
}

lister := action.NewList(listConfig)
lister.AllNamespaces = true
lister.StateMask = action.ListAll
res, err := lister.Run()
if err != nil {
return "", "", fmt.Errorf("couldn't check for installations: %s", err)
}

for _, rel := range res {
if rel.Chart.Metadata.Name == "consul" {
return rel.Name, rel.Namespace, nil
}
}
return "", "", errors.New("couldn't find consul installation")
}

func CloseWithError(c *BaseCommand) {
if err := c.Close(); err != nil {
c.Log.Error(err.Error())
os.Exit(1)
}
}
47 changes: 8 additions & 39 deletions cli/cmd/install/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,12 +169,7 @@ func (c *Command) Run(args []string) int {
// The logger is initialized in main with the name cli. Here, we reset the name to install so log lines would be prefixed with install.
c.Log.ResetNamed("install")

defer func() {
if err := c.Close(); err != nil {
c.Log.Error(err.Error())
os.Exit(1)
}
}()
defer common.CloseWithError(c.BaseCommand)

if err := c.validateFlags(args); err != nil {
c.UI.Output(err.Error())
Expand Down Expand Up @@ -218,9 +213,14 @@ func (c *Command) Run(args []string) int {

c.UI.Output("Pre-Install Checks", terminal.WithHeaderStyle())

if err := c.checkForPreviousInstallations(settings, uiLogger); err != nil {
c.UI.Output(err.Error(), terminal.WithErrorStyle())
// Note the logic here, common's CheckForPreviousInstallations function returns an error if
// the release is not found, which in the install command is what we need for a successful install.
if name, ns, err := common.CheckForInstallations(settings, uiLogger); err == nil {
c.UI.Output(fmt.Sprintf("existing Consul installation found (name=%s, namespace=%s) - run "+
"consul-k8s uninstall if you wish to re-install", name, ns), terminal.WithErrorStyle())
return 1
} else {
c.UI.Output("No existing installations found.")
}

// Ensure there's no previous PVCs lying around.
Expand Down Expand Up @@ -341,37 +341,6 @@ func (c *Command) Synopsis() string {
return "Install Consul on Kubernetes."
}

// checkForPreviousInstallations uses the helm Go SDK to find helm releases in all namespaces where the chart name is
// "consul", and returns an error if there is an existing installation.
// Note that this function is tricky to test because mocking out the action.Configuration struct requires a
// RegistryClient field that is from an internal helm package, so we are not unit testing it.
func (c *Command) checkForPreviousInstallations(settings *helmCLI.EnvSettings, uiLogger action.DebugLog) error {
// Need a specific action config to call helm list, where namespace is NOT specified.
listConfig := new(action.Configuration)
if err := listConfig.Init(settings.RESTClientGetter(), "",
os.Getenv("HELM_DRIVER"), uiLogger); err != nil {
return fmt.Errorf("couldn't initialize helm config: %s", err)
}

lister := action.NewList(listConfig)
lister.AllNamespaces = true
res, err := lister.Run()
if err != nil {
return fmt.Errorf("couldn't check for installations: %s", err)
}

for _, rel := range res {
if rel.Chart.Metadata.Name == "consul" {
// TODO: In the future the user will be prompted with our own uninstall command.
return fmt.Errorf("existing Consul installation found (name=%s, namespace=%s) - run helm "+
"delete %s -n %s if you wish to re-install",
rel.Name, rel.Namespace, rel.Name, rel.Namespace)
}
}
c.UI.Output("No existing installations found", terminal.WithSuccessStyle())
return nil
}

// checkForPreviousPVCs checks for existing PVCs with a name containing "consul-server" and returns an error and lists
// the PVCs it finds matches.
func (c *Command) checkForPreviousPVCs() error {
Expand Down
Loading

0 comments on commit a185c0a

Please sign in to comment.