summaryrefslogtreecommitdiff
path: root/app/models/clusters/applications/jupyter.rb
blob: 9e4b87d09934166d102cfe0a47a4eb87a6e233b6 (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
131
# frozen_string_literal: true

require 'securerandom'

module Clusters
  module Applications
    class Jupyter < ApplicationRecord
      VERSION = '0.9-174bbd5'.freeze

      self.table_name = 'clusters_applications_jupyter'

      include ::Clusters::Concerns::ApplicationCore
      include ::Clusters::Concerns::ApplicationStatus
      include ::Clusters::Concerns::ApplicationVersion
      include ::Clusters::Concerns::ApplicationData

      belongs_to :oauth_application, class_name: 'Doorkeeper::Application'

      default_value_for :version, VERSION

      def set_initial_status
        return unless not_installable?
        return unless cluster&.application_ingress_available?

        ingress = cluster.application_ingress
        if ingress.external_ip || ingress.external_hostname
          self.status = 'installable'
        end
      end

      def chart
        "#{name}/jupyterhub"
      end

      def repository
        'https://jupyterhub.github.io/helm-chart/'
      end

      def values
        content_values.to_yaml
      end

      def install_command
        Gitlab::Kubernetes::Helm::InstallCommand.new(
          name: name,
          version: VERSION,
          rbac: cluster.platform_kubernetes_rbac?,
          chart: chart,
          files: files,
          repository: repository
        )
      end

      def callback_url
        "http://#{hostname}/hub/oauth_callback"
      end

      def oauth_scopes
        'api read_repository write_repository'
      end

      private

      def specification
        {
          "ingress" => {
            "hosts" => [hostname],
            "tls" => [{
              "hosts" => [hostname],
              "secretName" => "jupyter-cert"
            }]
          },
          "hub" => {
            "extraEnv" => {
              "GITLAB_HOST" => gitlab_url
            },
            "cookieSecret" => cookie_secret
          },
          "proxy" => {
            "secretToken" => secret_token
          },
          "auth" => {
            "state" => {
              "cryptoKey" => crypto_key
            },
            "gitlab" => {
              "clientId" => oauth_application.uid,
              "clientSecret" => oauth_application.secret,
              "callbackUrl" => callback_url,
              "gitlabProjectIdWhitelist" => [project_id]
            }
          },
          "singleuser" => {
            "extraEnv" => {
              "GITLAB_CLUSTER_ID" => cluster.id.to_s,
              "GITLAB_HOST" => gitlab_host
            }
          }
        }
      end

      def crypto_key
        @crypto_key ||= SecureRandom.hex(32)
      end

      def project_id
        cluster&.project&.id
      end

      def gitlab_url
        Gitlab.config.gitlab.url
      end

      def gitlab_host
        Gitlab.config.gitlab.host
      end

      def content_values
        YAML.load_file(chart_values_file).deep_merge!(specification)
      end

      def secret_token
        @secret_token ||= SecureRandom.hex(32)
      end

      def cookie_secret
        @cookie_secret ||= SecureRandom.hex(32)
      end
    end
  end
end