Add nfdeployment handlers
[pti/o2.git] / helm_sdk / __init__.py
diff --git a/helm_sdk/__init__.py b/helm_sdk/__init__.py
new file mode 100644 (file)
index 0000000..bdf0cf9
--- /dev/null
@@ -0,0 +1,212 @@
+########
+# Copyright (c) 2019 Cloudify Platform Ltd. All rights reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+#    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    * See the License for the specific language governing permissions and
+#    * limitations under the License.
+
+import json
+
+from .exceptions import CloudifyHelmSDKError
+from helm_sdk.utils import (
+    run_subprocess,
+    prepare_parameter,
+    prepare_set_parameters,
+    validate_no_collisions_between_params_and_flags)
+
+# Helm cli flags names
+HELM_KUBECONFIG_FLAG = 'kubeconfig'
+HELM_KUBE_API_SERVER_FLAG = 'kube-apiserver'
+HELM_KUBE_TOKEN_FLAG = 'kube-token'
+HELM_VALUES_FLAG = 'values'
+APPEND_FLAG_STRING = '--{name}={value}'
+
+
+class Helm(object):
+
+    def __init__(self,
+                 logger,
+                 binary_path,
+                 environment_variables
+                 ):
+        self.binary_path = binary_path
+        self.logger = logger
+        if not isinstance(environment_variables, dict):
+            raise Exception(
+                "Unexpected type for environment variables (should be a "
+                "dict): {0}".format(type(
+                    environment_variables)))
+
+        self.env = environment_variables
+
+    def execute(self, command, return_output=False):
+        return run_subprocess(
+            command,
+            self.logger,
+            cwd=None,
+            additional_env=self.env,
+            additional_args=None,
+            return_output=return_output)
+
+    def _helm_command(self, args):
+        cmd = [self.binary_path]
+        cmd.extend(args)
+        return cmd
+
+    @staticmethod
+    def handle_auth_params(cmd,
+                           kubeconfig=None,
+                           token=None,
+                           apiserver=None):
+        """
+            Validation of authentication params.
+            Until helm will support --insecure, kubeconfig must be provided.
+            :param kubeconfig: Kubeconfig file path
+            :param: token: bearer token used for authentication.
+            :param: apiserver: the address and the port for the Kubernetes API
+            server.
+        """
+        if kubeconfig is None:
+            raise CloudifyHelmSDKError(
+                'Must provide kubeconfig file path.')
+        else:
+            cmd.append(APPEND_FLAG_STRING.format(name=HELM_KUBECONFIG_FLAG,
+                                                 value=kubeconfig))
+
+        if token:
+            cmd.append(APPEND_FLAG_STRING.format(name=HELM_KUBE_TOKEN_FLAG,
+                                                 value=token))
+
+        if apiserver:
+            cmd.append(
+                APPEND_FLAG_STRING.format(name=HELM_KUBE_API_SERVER_FLAG,
+                                          value=apiserver))
+
+    def install(self,
+                name,
+                chart,
+                flags=None,
+                set_values=None,
+                values_file=None,
+                kubeconfig=None,
+                token=None,
+                apiserver=None,
+                **_):
+        """
+        Execute helm install command.
+        :param name: name for the created release.
+        :param chart: chart name to install.
+        :param flags: list of flags to add to the install command.
+        :param set_values: list of variables and their values for --set.
+        :param kubeconfig: path to kubeconfig file.
+        :param values_file: values file path.
+        :param token: bearer token used for authentication.
+        :param apiserver: the address and the port for the Kubernetes API
+        server.
+        :return output of install command.
+        """
+        cmd = ['install', name, chart, '--wait', '--output=json']
+        self.handle_auth_params(cmd, kubeconfig, token, apiserver)
+        if values_file:
+            cmd.append(APPEND_FLAG_STRING.format(name=HELM_VALUES_FLAG,
+                                                 value=values_file))
+        flags = flags or []
+        validate_no_collisions_between_params_and_flags(flags)
+        cmd.extend([prepare_parameter(flag) for flag in flags])
+        set_arguments = set_values or []
+        cmd.extend(prepare_set_parameters(set_arguments))
+        output = self.execute(self._helm_command(cmd), True)
+        return json.loads(output)
+
+    def uninstall(self,
+                  name,
+                  flags=None,
+                  kubeconfig=None,
+                  token=None,
+                  apiserver=None,
+                  **_):
+        cmd = ['uninstall', name]
+        self.handle_auth_params(cmd, kubeconfig, token, apiserver)
+        flags = flags or []
+        validate_no_collisions_between_params_and_flags(flags)
+        cmd.extend([prepare_parameter(flag) for flag in flags])
+        self.execute(self._helm_command(cmd))
+
+    def repo_add(self,
+                 name,
+                 repo_url,
+                 flags=None,
+                 **_):
+        cmd = ['repo', 'add', name, repo_url]
+        flags = flags or []
+        cmd.extend([prepare_parameter(flag) for flag in flags])
+        self.execute(self._helm_command(cmd))
+
+    def repo_remove(self,
+                    name,
+                    flags=None,
+                    **_):
+        cmd = ['repo', 'remove', name]
+        flags = flags or []
+        cmd.extend([prepare_parameter(flag) for flag in flags])
+        self.execute(self._helm_command(cmd))
+
+    def repo_list(self):
+        cmd = ['repo', 'list', '--output=json']
+        output = self.execute(self._helm_command(cmd), True)
+        return json.loads(output)
+
+    def repo_update(self, flags):
+        cmd = ['repo', 'update']
+        flags = flags or []
+        cmd.extend([prepare_parameter(flag) for flag in flags])
+        self.execute(self._helm_command(cmd))
+
+    def upgrade(self,
+                release_name,
+                chart=None,
+                flags=None,
+                set_values=None,
+                values_file=None,
+                kubeconfig=None,
+                token=None,
+                apiserver=None,
+                **_):
+        """
+        Execute helm upgrade command.
+        :param release_name: name of the release to upgrade.
+        :param chart: The chart to upgrade the release with.
+        The chart argument can be either: a chart reference('example/mariadb'),
+        a packaged chart, or a fully qualified URL.
+        :param flags: list of flags to add to the upgrade command.
+        :param set_values: list of variables and their values for --set.
+        :param kubeconfig: path to kubeconfig file.
+        :param values_file: values file path.
+        :param token: bearer token used for authentication.
+        :param apiserver: the address and the port for the Kubernetes API
+        server.
+        :return output of helm upgrade command.
+        """
+        if not chart:
+            raise CloudifyHelmSDKError(
+                'Must provide chart for upgrade release.')
+        cmd = ['upgrade', release_name, chart, '--atomic', '-o=json']
+        self.handle_auth_params(cmd, kubeconfig, token, apiserver)
+        if values_file:
+            cmd.append(APPEND_FLAG_STRING.format(name=HELM_VALUES_FLAG,
+                                                 value=values_file))
+        flags = flags or []
+        validate_no_collisions_between_params_and_flags(flags)
+        cmd.extend([prepare_parameter(flag) for flag in flags])
+        set_arguments = set_values or []
+        cmd.extend(prepare_set_parameters(set_arguments))
+        output = self.execute(self._helm_command(cmd), True)
+        return json.loads(output)