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.
21 "github.com/sirupsen/logrus"
22 "helm.sh/helm/v3/pkg/action"
23 "helm.sh/helm/v3/pkg/chart/loader"
24 "helm.sh/helm/v3/pkg/kube"
28 // Constants to be taken from deployment file
30 releaseNamespace = "default"
31 chartPath = "/go/release/charts/"
32 kubeconfigPath = "/go/release/kubeconfig/"
36 type HelmClient struct {
42 // Constructor of helm client for a given host IP
43 func NewHelmClient(hostIP string, logger *logrus.Logger) (*HelmClient, error) {
44 // Kubeconfig file will be picked based on host IP and will be check for existence
45 exists, err := fileExists(kubeconfigPath + hostIP)
47 return &HelmClient{hostIP: hostIP, kubeconfig: kubeconfigPath + hostIP, logger: logger}, nil
49 logger.Errorf("No file exist with name: %s. Err: %s", kubeconfigPath + hostIP)
54 // Install a given helm chart
55 func (hc *HelmClient) installChart(helmPkg bytes.Buffer) (string, error) {
56 hc.logger.Info("Inside helm client")
58 // Create temporary file to hold helm chart
59 file, err := os.Create(chartPath + "temp.tar.gz")
61 hc.logger.Errorf("Unable to create file: %s. Err: %s", chartPath + "temp.tar.gz", err)
64 defer os.Remove(chartPath + "temp.tar.gz")
66 // Write input bytes to temp file
67 _, err = helmPkg.WriteTo(file)
69 hc.logger.Errorf("Unable to write to file: %s. Err: %s", chartPath + "temp.tar.gz", err)
73 // Load the file to chart
74 chart, err := loader.Load(chartPath + "temp.tar.gz")
76 hc.logger.Errorf("Unable to load chart from file: %s. Err: %s", chartPath + "temp.tar.gz", err)
80 // Release name will be taken from the name in chart's metadata
81 relName := chart.Metadata.Name
83 // Initialize action config
84 actionConfig := new(action.Configuration)
85 if err := actionConfig.Init(kube.GetConfig(hc.kubeconfig, "", releaseNamespace), releaseNamespace,
86 os.Getenv("HELM_DRIVER"), func(format string, v ...interface{}) {
87 fmt.Sprintf(format, v)
89 hc.logger.Errorf("Unable to initialize action config Err: %s", err)
93 // Prepare chart install action and install chart
94 installer := action.NewInstall(actionConfig)
95 installer.Namespace = releaseNamespace
96 installer.ReleaseName = relName
97 rel, err := installer.Run(chart, nil)
99 hc.logger.Errorf("Unable to install chart with release name: %s. Err: %s", relName, err)
102 hc.logger.Info("Successfully create chart with release name: %s", relName)
106 // Un-Install a given helm chart
107 func (hc *HelmClient) uninstallChart(relName string) (error) {
108 // Prepare action config and uninstall chart
109 actionConfig := new(action.Configuration)
110 if err := actionConfig.Init(kube.GetConfig(hc.kubeconfig, "", releaseNamespace), releaseNamespace,
111 os.Getenv("HELM_DRIVER"), func(format string, v ...interface{}) {
112 fmt.Sprintf(format, v)
114 hc.logger.Errorf("Unable to initialize action config Err: %s", err)
118 ui := action.NewUninstall(actionConfig)
119 res, err := ui.Run(relName);
121 hc.logger.Errorf("Unable to uninstall chart with release name: %s. Err: %s", relName, err)
124 hc.logger.Info("Successfully uninstalled chart with release name: %s. Response Info: %s", res.Release.Name, res.Info)
128 // Query a given chart
129 func (hc *HelmClient) queryChart(relName string) (string, error) {
130 actionConfig := new(action.Configuration)
131 if err := actionConfig.Init(kube.GetConfig(hc.kubeconfig, "", releaseNamespace), releaseNamespace,
132 os.Getenv("HELM_DRIVER"), func(format string, v ...interface{}) {
133 fmt.Sprintf(format, v)
135 hc.logger.Errorf("Unable to initialize action config Err: %s", err)
138 s := action.NewStatus(actionConfig)
139 res, err := s.Run(relName)
141 hc.logger.Errorf("Unable to query chart with release name: %s. Err: %s", relName, err)
144 return res.Info.Status.String(), nil
147 // fileExists checks if a file exists and is not a directory before we
148 // try using it to prevent further errors.
149 func fileExists(filename string) (bool, error) {
150 info, err := os.Stat(filename)
151 if os.IsNotExist(err) {
154 return !info.IsDir(), nil