summaryrefslogtreecommitdiff
path: root/lib/gitlab/kubernetes/helm/api.rb
blob: 3ed07818302677c3effcc9789cfab9583f350192 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# frozen_string_literal: true

module Gitlab
  module Kubernetes
    module Helm
      class Api
        def initialize(kubeclient)
          @kubeclient = kubeclient
          @namespace = Gitlab::Kubernetes::Namespace.new(
            Gitlab::Kubernetes::Helm::NAMESPACE,
            kubeclient,
            labels: Gitlab::Kubernetes::Helm::NAMESPACE_LABELS
          )
        end

        def install(command)
          namespace.ensure_exists!

          create_service_account(command)
          create_cluster_role_binding(command)
          create_config_map(command)

          delete_pod!(command.pod_name)
          kubeclient.create_pod(command.pod_resource)
        end

        alias_method :update, :install

        def uninstall(command)
          namespace.ensure_exists!
          create_config_map(command)

          delete_pod!(command.pod_name)
          kubeclient.create_pod(command.pod_resource)
        end

        ##
        # Returns Pod phase
        #
        # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase
        #
        # values: "Pending", "Running", "Succeeded", "Failed", "Unknown"
        #
        def status(pod_name)
          kubeclient.get_pod(pod_name, namespace.name).status.phase
        end

        def log(pod_name)
          kubeclient.get_pod_log(pod_name, namespace.name).body
        end

        def delete_pod!(pod_name)
          kubeclient.delete_pod(pod_name, namespace.name)
        rescue ::Kubeclient::ResourceNotFoundError
          # no-op
        end

        def get_config_map(config_map_name)
          namespace.ensure_exists!

          kubeclient.get_config_map(config_map_name, namespace.name)
        end

        private

        attr_reader :kubeclient, :namespace

        def create_config_map(command)
          command.config_map_resource.tap do |config_map_resource|
            break unless config_map_resource

            if config_map_exists?(config_map_resource)
              kubeclient.update_config_map(config_map_resource)
            else
              kubeclient.create_config_map(config_map_resource)
            end
          end
        end

        def update_config_map(command)
          command.config_map_resource.tap do |config_map_resource|
            kubeclient.update_config_map(config_map_resource)
          end
        end

        def create_service_account(command)
          command.service_account_resource.tap do |service_account_resource|
            break unless service_account_resource

            if service_account_exists?(service_account_resource)
              kubeclient.update_service_account(service_account_resource)
            else
              kubeclient.create_service_account(service_account_resource)
            end
          end
        end

        def create_cluster_role_binding(command)
          command.cluster_role_binding_resource.tap do |cluster_role_binding_resource|
            break unless cluster_role_binding_resource

            if cluster_role_binding_exists?(cluster_role_binding_resource)
              kubeclient.update_cluster_role_binding(cluster_role_binding_resource)
            else
              kubeclient.create_cluster_role_binding(cluster_role_binding_resource)
            end
          end
        end

        def config_map_exists?(resource)
          kubeclient.get_config_map(resource.metadata.name, resource.metadata.namespace)
        rescue ::Kubeclient::ResourceNotFoundError
          false
        end

        def service_account_exists?(resource)
          kubeclient.get_service_account(resource.metadata.name, resource.metadata.namespace)
        rescue ::Kubeclient::ResourceNotFoundError
          false
        end

        def cluster_role_binding_exists?(resource)
          kubeclient.get_cluster_role_binding(resource.metadata.name)
        rescue ::Kubeclient::ResourceNotFoundError
          false
        end
      end
    end
  end
end