2 * Copyright 2020 Huawei Technologies Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 "github.com/sirupsen/logrus"
23 "helm.sh/helm/v3/pkg/action"
24 "helm.sh/helm/v3/pkg/chart/loader"
25 "helm.sh/helm/v3/pkg/kube"
29 // Variables to be defined in deployment file
31 chartPath = os.Getenv("CHART_PATH")
32 kubeconfigPath = os.Getenv("KUBECONFIG_DIR_PATH")
33 releaseNamespace = os.Getenv("RELEASE_NAMESPACE")
38 type HelmClient struct {
44 // Constructor of helm client for a given host IP
45 func NewHelmClient(hostIP string, logger *logrus.Logger) (*HelmClient, error) {
46 // Kubeconfig file will be picked based on host IP and will be check for existence
47 exists, err := fileExists(kubeconfigPath + hostIP)
49 return &HelmClient{hostIP: hostIP, kubeconfig: kubeconfigPath + hostIP, logger: logger}, nil
51 logger.Errorf("No file exist with name: %s. Err: %s", kubeconfigPath + hostIP)
56 // Install a given helm chart
57 func (hc *HelmClient) installChart(helmPkg bytes.Buffer) (string, error) {
58 hc.logger.Debug("Inside helm client")
60 // Create temporary file to hold helm chart
61 file, err := os.Create(chartPath + "temp.tar.gz")
63 hc.logger.Errorf("Unable to create file: %s. Err: %s", chartPath + "temp.tar.gz", err)
66 defer os.Remove(chartPath + "temp.tar.gz")
68 // Write input bytes to temp file
69 _, err = helmPkg.WriteTo(file)
71 hc.logger.Errorf("Unable to write to file: %s. Err: %s", chartPath + "temp.tar.gz", err)
75 // Load the file to chart
76 chart, err := loader.Load(chartPath + "temp.tar.gz")
78 hc.logger.Errorf("Unable to load chart from file: %s. Err: %s", chartPath + "temp.tar.gz", err)
82 // Release name will be taken from the name in chart's metadata
83 relName := chart.Metadata.Name
85 // Initialize action config
86 actionConfig := new(action.Configuration)
87 if err := actionConfig.Init(kube.GetConfig(hc.kubeconfig, "", releaseNamespace), releaseNamespace,
88 os.Getenv("HELM_DRIVER"), func(format string, v ...interface{}) {
89 fmt.Sprintf(format, v)
91 hc.logger.Errorf("Unable to initialize action config Err: %s", err)
95 // Prepare chart install action and install chart
96 installer := action.NewInstall(actionConfig)
97 installer.Namespace = releaseNamespace
98 installer.ReleaseName = relName
99 rel, err := installer.Run(chart, nil)
101 hc.logger.Errorf("Unable to install chart with release name: %s. Err: %s", relName, err)
104 hc.logger.Info("Successfully create chart with release name: %s", relName)
108 // Un-Install a given helm chart
109 func (hc *HelmClient) uninstallChart(relName string) (error) {
110 // Prepare action config and uninstall chart
111 actionConfig := new(action.Configuration)
112 if err := actionConfig.Init(kube.GetConfig(hc.kubeconfig, "", releaseNamespace), releaseNamespace,
113 os.Getenv("HELM_DRIVER"), func(format string, v ...interface{}) {
114 fmt.Sprintf(format, v)
116 hc.logger.Errorf("Unable to initialize action config Err: %s", err)
120 ui := action.NewUninstall(actionConfig)
121 res, err := ui.Run(relName);
123 hc.logger.Errorf("Unable to uninstall chart with release name: %s. Err: %s", relName, err)
126 hc.logger.Info("Successfully uninstalled chart with release name: %s. Response Info: %s", res.Release.Name, res.Info)
130 // Query a given chart
131 func (hc *HelmClient) queryChart(relName string) (string, error) {
132 actionConfig := new(action.Configuration)
133 if err := actionConfig.Init(kube.GetConfig(hc.kubeconfig, "", releaseNamespace), releaseNamespace,
134 os.Getenv("HELM_DRIVER"), func(format string, v ...interface{}) {
135 fmt.Sprintf(format, v)
137 hc.logger.Errorf("Unable to initialize action config Err: %s", err)
140 s := action.NewStatus(actionConfig)
141 res, err := s.Run(relName)
143 hc.logger.Errorf("Unable to query chart with release name: %s. Err: %s", relName, err)
146 return res.Info.Status.String(), nil
149 // fileExists checks if a file exists and is not a directory before we
150 // try using it to prevent further errors.
151 func fileExists(filename string) (bool, error) {
152 info, err := os.Stat(filename)
153 if os.IsNotExist(err) {
156 return !info.IsDir(), nil