func (p Plugin) createPackage() error {
	return run(exec.Command(helmBin, "package", "--version", p.ChartVersion, p.ChartPath), p.Debug)
}
createPackage creates Helm package for Kubernetes.
helm package --version $PLUGIN_CHART_VERSION $PLUGIN_CHART_PATH
package main
import (
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"regexp"
	"strings"
	"time"
	sops_decrypt "go.mozilla.org/sops/v3/decrypt"
)
type Plugin struct {
	Debug          bool     `envconfig:"DEBUG"`
	ShowEnv        bool     `envconfig:"SHOW_ENV"`
	Wait           bool     `envconfig:"WAIT"`
	Recreate       bool     `envconfig:"RECREATE_PODS" default:"false"`
	WaitTimeout    uint32   `envconfig:"WAIT_TIMEOUT" default:"300"`
	Actions        []string `envconfig:"ACTIONS" required:"true"`
	AuthKey        string   `envconfig:"AUTH_KEY"`
	KeyPath        string   `envconfig:"KEY_PATH"`
	Zone           string   `envconfig:"ZONE"`
	Region         string   `envconfig:"REGION"`
	Cluster        string   `envconfig:"CLUSTER"`
	Project        string   `envconfig:"PROJECT"`
	Namespace      string   `envconfig:"NAMESPACE"`
	ChartRepo      string   `envconfig:"CHART_REPO"`
	Bucket         string   `envconfig:"BUCKET"`
	ChartPath      string   `envconfig:"CHART_PATH" required:"true"`
	ChartVersion   string   `envconfig:"CHART_VERSION"`
	Release        string   `envconfig:"RELEASE"`
	Package        string   `envconfig:"PACKAGE"`
	Values         []string `envconfig:"VALUES"`
	ValueFiles     []string `envconfig:"VALUE_FILES"`
	Secrets        []string `envconfig:"SECRETS"`
	HelmStableRepo string   `envconfig:"HELM_STABLE_REPO" default:"https://charts.helm.sh/stable"`
}
const (
	gcloudBin  = "gcloud"
	gsutilBin  = "gsutil"
	kubectlBin = "kubectl"
	helmBin    = "helm"
	lintPkg       = "lint"
	createPkg     = "create"
	pushPkg       = "push"
	pullPkg       = "pull"
	deployPkg     = "deploy"
	testPkg       = "test"
	dependencyPkg = "dep"
	updateWaitTime = 10 * time.Second
	updateRetries  = 10
)
func (p Plugin) Exec() error {
	if p.Project != "" && p.Cluster != "" && (p.Zone != "" || p.Region != "") {
		if err := setupProject(p.Project, p.Cluster, p.Zone, p.Region, p.Debug); err != nil {
			return err
		}
	}
	for _, a := range p.Actions {
		switch a {
		case lintPkg:
			if err := p.lintPackage(); err != nil {
				return err
			}
		case createPkg:
			if err := p.createPackage(); err != nil {
				return err
			}
		case pushPkg:
			if err := p.pushPackage(); err != nil {
				return err
			}
		case pullPkg:
			if err := p.pullPackage(); err != nil {
				return err
			}
		case deployPkg:
			if err := p.deployPackage(); err != nil {
				return err
			}
		case testPkg:
			if err := p.testPackage(); err != nil {
				return err
			}
		case dependencyPkg:
			if err := p.addRepo(); err != nil {
				return err
			}
			if err := p.dependencyUpdate(); err != nil {
				return err
			}
		default:
			return errors.New("unknown action")
		}
	}
	return nil
}
func setupProject(project, cluster, zone, region string, debug bool) error {
	cmd := exec.Command(gcloudBin, "config", "set", "project", project)
	if err := run(cmd, debug); err != nil {
		return fmt.Errorf("could not the configure the project with glcoud: %v", err)
	}
	cmd = exec.Command(gcloudBin, "container", "clusters", "get-credentials", cluster, "--zone", zone)
	if region != "" {
		cmd = exec.Command(gcloudBin, "container", "clusters", "get-credentials", cluster, "--region", region)
	}
	if err := run(cmd, debug); err != nil {
		return fmt.Errorf("could not configure the cluster with glcoud: %v", err)
	}
	return nil
}
func setupAuth(authFile string, debug bool) error {
	if err := os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", authFile); err != nil {
		return fmt.Errorf("could not set GOOGLE_APPLICATION_CREDENTIALS env variable: %v", err)
	}
	cmd := exec.Command(gcloudBin, "auth", "activate-service-account", fmt.Sprintf("--key-file=%s", authFile))
	if err := run(cmd, debug); err != nil {
		return fmt.Errorf("could not authorize with glcoud: %v", err)
	}
	return nil
}