Skip to content

Commit

Permalink
feat: check nginx chart needs to be installed before installing (#62)
Browse files Browse the repository at this point in the history
  • Loading branch information
colesnodgrass authored Jul 26, 2024
1 parent f2a6d28 commit 7eda42f
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 19 deletions.
97 changes: 78 additions & 19 deletions internal/cmd/local/local/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"github.com/airbytehq/abctl/internal/cmd/local/helm"
"github.com/airbytehq/abctl/internal/cmd/local/migrate"
"github.com/airbytehq/abctl/internal/cmd/local/paths"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/release"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/yaml"
"net/http"
Expand Down Expand Up @@ -409,13 +411,14 @@ func (c *Command) Install(ctx context.Context, opts InstallOpts) error {
}

if err := c.handleChart(ctx, chartRequest{
name: "nginx",
repoName: nginxRepoName,
repoURL: nginxRepoURL,
chartName: nginxChartName,
chartRelease: nginxChartRelease,
namespace: nginxNamespace,
values: append(c.provider.HelmNginx, fmt.Sprintf("controller.service.ports.http=%d", c.portHTTP)),
name: "nginx",
checkShouldInstall: true,
repoName: nginxRepoName,
repoURL: nginxRepoURL,
chartName: nginxChartName,
chartRelease: nginxChartRelease,
namespace: nginxNamespace,
values: append(c.provider.HelmNginx, fmt.Sprintf("controller.service.ports.http=%d", c.portHTTP)),
}); err != nil {
// If we timed out, there is a good chance it's due to an unavailable port, check if this is the case.
// As the kubernetes client doesn't return usable error types, have to check for a specific string value.
Expand Down Expand Up @@ -659,15 +662,16 @@ func (c *Command) Status(_ context.Context) error {

// chartRequest exists to make all the parameters to handleChart somewhat manageable
type chartRequest struct {
name string
repoName string
repoURL string
chartName string
chartRelease string
chartVersion string
namespace string
values []string
valuesYAML string
name string
repoName string
repoURL string
chartName string
chartRelease string
chartVersion string
namespace string
values []string
valuesYAML string
checkShouldInstall bool
}

// handleChart will handle the installation of a chart
Expand All @@ -694,6 +698,14 @@ func (c *Command) handleChart(

c.tel.Attr(fmt.Sprintf("helm_%s_chart_version", req.name), helmChart.Metadata.Version)

if req.checkShouldInstall && !checkHelmReleaseShouldInstall(c.helm, helmChart, req.chartRelease) {
pterm.Success.Println(fmt.Sprintf(
"Found matching existing Helm Chart %s:\n Name: %s\n Namespace: %s\n Version: %s\n AppVersion: %s",
req.chartName, req.chartName, req.namespace, helmChart.Metadata.Version, helmChart.Metadata.AppVersion,
))
return nil
}

pterm.Info.Println(fmt.Sprintf(
"Starting Helm Chart installation of '%s' (version: %s)",
req.chartName, helmChart.Metadata.Version,
Expand Down Expand Up @@ -722,9 +734,10 @@ func (c *Command) handleChart(

c.tel.Attr(fmt.Sprintf("helm_%s_release_version", req.name), strconv.Itoa(helmRelease.Version))

pterm.Success.Printfln(
"Installed Helm Chart %s:\n Name: %s\n Namespace: %s\n Version: %s\n Release: %d",
req.chartName, helmRelease.Name, helmRelease.Namespace, helmRelease.Chart.Metadata.Version, helmRelease.Version)
pterm.Success.Println(fmt.Sprintf(
"Installed Helm Chart %s:\n Name: %s\n Namespace: %s\n Version: %s\n AppVersion: %s\n Release: %d",
req.chartName, helmRelease.Name, helmRelease.Namespace, helmRelease.Chart.Metadata.Version, helmRelease.Chart.Metadata.AppVersion, helmRelease.Version,
))
return nil
}

Expand Down Expand Up @@ -812,3 +825,49 @@ func k8sClientConfig(kubecfg, kubectx string) (clientcmd.ClientConfig, error) {
&clientcmd.ConfigOverrides{CurrentContext: kubectx},
), nil
}

// checkHelmReleaseShouldInstall returns true if the provided release needs to be installed,
// false otherwise.
func checkHelmReleaseShouldInstall(helm helm.Client, chart *chart.Chart, releaseName string) bool {
// look for an existing release, see if it matches the existing chart
rel, err := helm.GetRelease(releaseName)
if err != nil {
if strings.Contains(err.Error(), "not found") {
// chart hasn't been installed previously
pterm.Debug.Println(fmt.Sprintf("Unable to find %s Helm Release", releaseName))
} else {
// chart may or may not exist, log error and ignore
pterm.Debug.Println(fmt.Sprintf("Unable to fetch %s Helm Release: %s", releaseName, err))
}
return true
}

if rel.Info.Status != release.StatusDeployed {
pterm.Debug.Println(fmt.Sprintf("Chart has the status of %s", rel.Info.Status))
return true
}

if rel.Chart.Metadata.Version != chart.Metadata.Version {
pterm.Debug.Println(fmt.Sprintf(
"Chart version (%s) does not match Helm Release (%s)",
chart.Metadata.Version, rel.Chart.Metadata.Version,
))
return true
}

if rel.Chart.Metadata.AppVersion != chart.Metadata.AppVersion {
pterm.Debug.Println(fmt.Sprintf(
"Chart app-version (%s) does not match Helm Release (%s)",
chart.Metadata.AppVersion, rel.Chart.Metadata.AppVersion,
))
return true
}

pterm.Debug.Println(fmt.Sprintf(
"Chart matched Helm Release\n Version: %s - %s\n AppVersion: %s - %s",
chart.Metadata.Version, rel.Chart.Metadata.Version,
chart.Metadata.AppVersion, rel.Chart.Metadata.AppVersion,
))

return false
}
26 changes: 26 additions & 0 deletions internal/cmd/local/local/cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,19 @@ func TestCommand_Install(t *testing.T) {
}
},

getRelease: func(name string) (*release.Release, error) {
switch {
case name == airbyteChartRelease:
t.Error("should not have been called", name)
return nil, errors.New("should not have been called")
case name == nginxChartRelease:
return nil, errors.New("not found")
default:
t.Error("unsupported chart name", name)
return nil, errors.New("unexpected chart name")
}
},

installOrUpgradeChart: func(ctx context.Context, spec *helmclient.ChartSpec, opts *helmclient.GenericHelmOptions) (*release.Release, error) {
if d := cmp.Diff(&expChart[expChartCnt].chart, spec); d != "" {
t.Error("chart mismatch", d)
Expand Down Expand Up @@ -250,6 +263,19 @@ func TestCommand_Install_ValuesFile(t *testing.T) {
}
},

getRelease: func(name string) (*release.Release, error) {
switch {
case name == airbyteChartRelease:
t.Error("should not have been called", name)
return nil, errors.New("should not have been called")
case name == nginxChartRelease:
return nil, errors.New("not found")
default:
t.Error("unsupported chart name", name)
return nil, errors.New("unexpected chart name")
}
},

installOrUpgradeChart: func(ctx context.Context, spec *helmclient.ChartSpec, opts *helmclient.GenericHelmOptions) (*release.Release, error) {
if d := cmp.Diff(&expChart[expChartCnt].chart, spec); d != "" {
t.Error("chart mismatch", d)
Expand Down

0 comments on commit 7eda42f

Please sign in to comment.