Module: Dapp::Kube::Dapp::Command::Common

Included in:
Dapp
Defined in:
lib/dapp/kube/dapp/command/common.rb

Instance Method Summary collapse

Instance Method Details

#helm_releaseObject



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
# File 'lib/dapp/kube/dapp/command/common.rb', line 6

def helm_release
  kube_check_helm!
  kube_check_helm_template_plugin!
  kube_check_helm_chart!

  repo = option_repo
  tag = begin
    raise Error::Command, code: :expected_only_one_tag,
                          data: { tags: option_tags.join(', ') } if option_tags.count > 1
    option_tags.first
  end
  validate_repo_name!(repo)
  validate_tag_name!(tag)

  with_kube_tmp_chart_dir do
    kube_copy_chart
    kube_helm_decode_secrets
    kube_generate_helm_chart_tpl

    release = Helm::Release.new(
        self,
        name: kube_release_name,
        repo: repo,
        docker_tag: tag,
        namespace: kube_namespace,
        chart_path: kube_chart_path_for_helm,
        set: self.options[:helm_set_options],
        values: [*kube_values_paths, *kube_tmp_chart_secret_values_paths],
        deploy_timeout: self.options[:timeout] || 300
    )

    yield release
  end
end

#kube_chart_path(*path) ⇒ Object



186
187
188
# File 'lib/dapp/kube/dapp/command/common.rb', line 186

def kube_chart_path(*path)
  self.path('.helm', *path).expand_path
end

#kube_chart_path_for_helm(*path) ⇒ Object



196
197
198
199
200
201
# File 'lib/dapp/kube/dapp/command/common.rb', line 196

def kube_chart_path_for_helm(*path)
  chart_dir = ENV['DAPP_HELM_CHART_DIR'] || begin
    @kube_tmp_helm_chart_dir ||= Dir.mktmpdir('dapp-helm-chart-', tmp_base_dir)
  end
  make_path(chart_dir, *path).expand_path.tap { |p| p.parent.mkpath }
end

#kube_chart_secret_dir_nameObject



182
183
184
# File 'lib/dapp/kube/dapp/command/common.rb', line 182

def kube_chart_secret_dir_name
  'secret'
end

#kube_chart_secret_path(*path) ⇒ Object



178
179
180
# File 'lib/dapp/kube/dapp/command/common.rb', line 178

def kube_chart_secret_path(*path)
  kube_chart_path(kube_chart_secret_dir_name, *path).expand_path
end

#kube_chart_secret_values_pathObject



138
139
140
# File 'lib/dapp/kube/dapp/command/common.rb', line 138

def kube_chart_secret_values_path
  kube_chart_path('secret-values.yaml').expand_path
end

#kube_check_helm!Object

Raises:



142
143
144
# File 'lib/dapp/kube/dapp/command/common.rb', line 142

def kube_check_helm!
  raise Error::Command, code: :helm_not_found if shellout('which helm').exitstatus == 1
end

#kube_check_helm_chart!Object

Raises:



41
42
43
# File 'lib/dapp/kube/dapp/command/common.rb', line 41

def kube_check_helm_chart!
  raise Error::Command, code: :helm_directory_not_exist, data: { path: kube_chart_path } unless kube_chart_path.exist?
end

#kube_check_helm_template_plugin!Object



45
46
47
48
49
# File 'lib/dapp/kube/dapp/command/common.rb', line 45

def kube_check_helm_template_plugin!
  unless shellout!("helm plugin list | awk '{print $1}'").stdout.lines.map(&:strip).any? { |plugin| plugin == 'template' }
    raise Error::Command, code: :helm_template_plugin_not_installed, data: { path: kube_chart_path }
  end
end

#kube_copy_chartObject



51
52
53
# File 'lib/dapp/kube/dapp/command/common.rb', line 51

def kube_copy_chart
  FileUtils.cp_r("#{kube_chart_path}/.", kube_chart_path_for_helm)
end

#kube_generate_helm_chart_tplObject



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/dapp/kube/dapp/command/common.rb', line 91

def kube_generate_helm_chart_tpl
  cont = <<-EOF
{{/* vim: set filetype=mustache: */}}

{{- define "dimg" -}}
{{- if (ge (len (index .)) 2) -}}
{{- $name := index . 0 -}}
{{- $context := index . 1 -}}
{{- printf "%v/%v:%v" $context.Values.global.dapp.repo $name $context.Values.global.dapp.docker_tag -}}
{{- else -}}
{{- $context := index . 0 -}}
{{- printf "%v:%v" $context.Values.global.dapp.repo $context.Values.global.dapp.docker_tag -}}
{{- end -}}
{{- end -}}

{{- define "dapp_secret_file" -}}
{{- $relative_file_path := index . 0 -}}
{{- $context := index . 1 -}}
{{- $context.Files.Get (print "#{kube_tmp_chart_secret_path.subpath_of(kube_chart_path_for_helm)}/" $relative_file_path) -}}
{{- end -}}
  EOF
  kube_chart_path_for_helm('templates/_dapp_helpers.tpl').write(cont)
end

#kube_helm_decode_secret_filesObject



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/dapp/kube/dapp/command/common.rb', line 74

def kube_helm_decode_secret_files
  return unless kube_chart_secret_path.directory?
  Dir.glob(kube_chart_secret_path.join('**/*')).each do |entry|
    next if File.directory?(entry)

    secret_relative_path = Pathname(entry).subpath_of(kube_chart_secret_path)

    if secret.nil?
      File.open(kube_tmp_chart_secret_path(secret_relative_path), 'wb:ASCII-8BIT', 0600) {|f| f.write ""}
    else
      kube_secret_file_validate!(entry)
      secret_data = secret.extract(IO.binread(entry).chomp("\n"))
      File.open(kube_tmp_chart_secret_path(secret_relative_path), 'wb:ASCII-8BIT', 0600) {|f| f.write secret_data}
    end
  end
end

#kube_helm_decode_secret_valuesObject



67
68
69
70
71
72
# File 'lib/dapp/kube/dapp/command/common.rb', line 67

def kube_helm_decode_secret_values
  kube_secret_values_paths.each_with_index do |secret_values_file, index|
    decoded_data = kube_helm_decode_json(secret, yaml_load_file(secret_values_file))
    kube_tmp_chart_secret_values_paths[index].write(decoded_data.to_yaml)
  end
end

#kube_helm_decode_secretsObject



55
56
57
58
59
60
61
62
63
64
65
# File 'lib/dapp/kube/dapp/command/common.rb', line 55

def kube_helm_decode_secrets
  if secret.nil?
    log_warning(desc: {
      code: :dapp_secret_key_not_found,
      data: {not_found_in: secret_key_not_found_in.join(', ')}
    }) if !kube_secret_values_paths.empty? || kube_chart_secret_path.directory?
  end

  kube_helm_decode_secret_files
  kube_helm_decode_secret_values
end

#kube_namespaceObject



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/dapp/kube/dapp/command/common.rb', line 232

def kube_namespace
  namespace_option || begin
    namespace = "default"

    Kubernetes::Client.tap do |kube|
      kube_config = kube.kube_config(kube.kube_config_path)
      if kube_config
        kube_context_name = kube.kube_context_name(kube_config)
        kube_context_config = kube.kube_context_config(kube_config, kube_context_name)

        if kube_context_config
          context_namespace = kube.kube_context_namespace(kube_context_config)
          namespace = context_namespace if context_namespace
        end
      end
    end

    namespace
  end
end

#kube_release_nameObject



146
147
148
# File 'lib/dapp/kube/dapp/command/common.rb', line 146

def kube_release_name
  "#{name}-#{kube_namespace}".slugify
end

#kube_secret_file_validate!(file_path) ⇒ Object

Raises:



166
167
168
169
# File 'lib/dapp/kube/dapp/command/common.rb', line 166

def kube_secret_file_validate!(file_path)
  raise Error::Command, code: :secret_file_not_found, data: { path: File.expand_path(file_path) } unless File.exist?(file_path)
  raise Error::Command, code: :secret_file_empty, data: { path: File.expand_path(file_path) } if File.read(file_path).strip.empty?
end

#kube_secret_values_pathsObject



129
130
131
132
133
134
135
136
# File 'lib/dapp/kube/dapp/command/common.rb', line 129

def kube_secret_values_paths
  @kube_chart_secret_values_files ||= [].tap do |files|
    files << kube_chart_secret_values_path if kube_chart_secret_values_path.file?
    files.concat(options[:helm_secret_values_options].map { |p| Pathname(p).expand_path }.each do |f|
      kube_secret_file_validate!(f)
    end)
  end
end

#kube_tmp_chart_secret_path(*path) ⇒ Object



115
116
117
# File 'lib/dapp/kube/dapp/command/common.rb', line 115

def kube_tmp_chart_secret_path(*path)
  kube_chart_path_for_helm('decoded-secret', *path).tap { |p| p.parent.mkpath }
end

#kube_tmp_chart_secret_values_pathsObject



125
126
127
# File 'lib/dapp/kube/dapp/command/common.rb', line 125

def kube_tmp_chart_secret_values_paths
  @kube_tmp_chart_secret_values_paths ||= kube_secret_values_paths.each_with_index.map { |f, i| kube_chart_path_for_helm( "decoded-secret-values-#{i}.yaml") }
end

#kube_values_pathsObject



119
120
121
122
123
# File 'lib/dapp/kube/dapp/command/common.rb', line 119

def kube_values_paths
  self.options[:helm_values_options].map { |p| Pathname(p).expand_path }.each do |f|
    raise Error::Command, code: :values_file_not_found, data: { path: f } unless f.file?
  end
end

#kubernetesObject



253
254
255
# File 'lib/dapp/kube/dapp/command/common.rb', line 253

def kubernetes
  @kubernetes ||= Kubernetes::Client.new(namespace: kube_namespace)
end

#namespace_optionObject



228
229
230
# File 'lib/dapp/kube/dapp/command/common.rb', line 228

def namespace_option
  options[:namespace].nil? ? nil : options[:namespace].tr('_', '-')
end

#secretObject



203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/dapp/kube/dapp/command/common.rb', line 203

def secret
  @secret ||= begin
    unless (secret_key = ENV['DAPP_SECRET_KEY'])
      secret_key_not_found_in << '`DAPP_SECRET_KEY`'

      if dappfile_exists?
        file_path = path('.dapp_secret_key')
        if file_path.file?
          secret_key = path('.dapp_secret_key').read.chomp
        else
          secret_key_not_found_in << "`#{file_path}`"
        end
      else
        log_warning(desc: { code: :secret_key_dappfile_not_found })
      end
    end

    Secret.new(secret_key) if secret_key
  end
end

#secret_key_not_found_inObject



224
225
226
# File 'lib/dapp/kube/dapp/command/common.rb', line 224

def secret_key_not_found_in
  @secret_key_not_found_in ||= []
end

#secret_key_should_exist!Object

Raises:



171
172
173
174
175
176
# File 'lib/dapp/kube/dapp/command/common.rb', line 171

def secret_key_should_exist!
  raise(Error::Command,
    code: :secret_key_not_found,
    data: {not_found_in: secret_key_not_found_in.join(', ')}
  ) if secret.nil?
end

#with_kube_tmp_chart_dirObject



190
191
192
193
194
# File 'lib/dapp/kube/dapp/command/common.rb', line 190

def with_kube_tmp_chart_dir
  yield if block_given?
ensure
  FileUtils.rm_rf(@kube_tmp_helm_chart_dir) if @kube_tmp_helm_chart_dir
end