helm-wrapper 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,79 @@
1
+ ###############################################################################
2
+
3
+ require 'json'
4
+ require 'net/http'
5
+ require 'singleton'
6
+ require 'uri'
7
+
8
+ ###############################################################################
9
+
10
+ module HelmWrapper
11
+
12
+ ###############################################################################
13
+
14
+ module Shared
15
+
16
+ ###############################################################################
17
+
18
+ class Latest
19
+
20
+ ###############################################################################
21
+
22
+ include Singleton
23
+
24
+ ###############################################################################
25
+
26
+ include HelmWrapper::Shared::Logging
27
+
28
+ ###############################################################################
29
+
30
+ @version
31
+
32
+ ###############################################################################
33
+
34
+ def version
35
+ @version ||= refresh
36
+
37
+ return @version
38
+ end
39
+
40
+ ###############################################################################
41
+
42
+ private
43
+
44
+ ###############################################################################
45
+
46
+ def refresh
47
+ logger.info("Finding latest available Helm release...")
48
+
49
+ response = Net::HTTP.get_response(URI("https://api.github.com/repos/helm/helm/releases/latest"))
50
+
51
+ logger.fatal("GitHub API did not return status 200 for latest version check!") if response.code != "200"
52
+ logger.fatal("Response body from GitHub API is not permitted!") if not response.class.body_permitted?
53
+ logger.fatal("Response body from GitHub API is empty!") if response.body.nil?
54
+
55
+ body = JSON.parse(response.body)
56
+
57
+ logger.fatal("GitHub API JSON response did not include latest available Helm tag name!") if not body.key?("tag_name")
58
+ logger.fatal("GitHub API indicated the latest available tag name for Helm is blank!") if body["tag_name"].empty?
59
+
60
+ version = body["tag_name"]
61
+
62
+ logger.success("Latest available Helm release found: #{version}")
63
+
64
+ return version
65
+ end
66
+
67
+ ###############################################################################
68
+
69
+ end
70
+
71
+ ###############################################################################
72
+
73
+ end
74
+
75
+ ###############################################################################
76
+
77
+ end
78
+
79
+ ###############################################################################
@@ -0,0 +1,80 @@
1
+ ###############################################################################
2
+
3
+ require 'logger'
4
+
5
+ ###############################################################################
6
+
7
+ module HelmWrapper
8
+
9
+ ###############################################################################
10
+
11
+ module Shared
12
+
13
+ ###############################################################################
14
+
15
+ class Logger < ::Logger
16
+
17
+ ###############################################################################
18
+
19
+ @colour = false
20
+
21
+ ###############################################################################
22
+
23
+ def colour()
24
+ @colour
25
+ end
26
+
27
+ ###############################################################################
28
+
29
+ def colour=(enabled)
30
+ @colour = [ true, false ].include?(enabled) ? enabled : false
31
+ end
32
+
33
+ ###############################################################################
34
+
35
+ def success(message)
36
+ info(format(colour: 32, message: message))
37
+ end
38
+
39
+ ###############################################################################
40
+
41
+ def warn(message)
42
+ super(format(colour: 33, message: message))
43
+ end
44
+
45
+ ###############################################################################
46
+
47
+ def error(message)
48
+ super(format(colour: 31, message: message))
49
+ end
50
+
51
+ ###############################################################################
52
+
53
+ def fatal(message)
54
+ super(format(colour: 31, message: message))
55
+ exit(1)
56
+ end
57
+
58
+ ###############################################################################
59
+
60
+ private
61
+
62
+ ###############################################################################
63
+
64
+ def format(colour: 32, message:)
65
+ return @colour ? "\e[" + colour.to_s + "m" + message + "\e[0m" : message
66
+ end
67
+
68
+ ###############################################################################
69
+
70
+ end
71
+
72
+ ###############################################################################
73
+
74
+ end
75
+
76
+ ###############################################################################
77
+
78
+ end
79
+
80
+ ###############################################################################
@@ -0,0 +1,77 @@
1
+ ###############################################################################
2
+
3
+ require 'logger'
4
+
5
+ ###############################################################################
6
+
7
+ module HelmWrapper
8
+
9
+ ###############################################################################
10
+
11
+ module Shared
12
+
13
+ ###############################################################################
14
+
15
+ module Logging
16
+
17
+ ###############################################################################
18
+
19
+ private
20
+
21
+ ###############################################################################
22
+
23
+ def logger
24
+ @logger ||= Logging.logger_for(self.class.name)
25
+ end
26
+
27
+ ###############################################################################
28
+
29
+ @loggers = {}
30
+
31
+ ###############################################################################
32
+
33
+ class << self
34
+
35
+ ###############################################################################
36
+
37
+ def logger_for(classname)
38
+ @loggers[classname] ||= configure_logger_for(classname)
39
+ end
40
+
41
+ ###############################################################################
42
+
43
+ def configure_logger_for(classname)
44
+ colour = ENV["HELM_WRAPPER_LOG_COLOUR"] || "true"
45
+ level = ENV["HELM_WRAPPER_LOG_LEVEL"] || "INFO"
46
+
47
+ logger = ::HelmWrapper::Shared::Logger.new(STDOUT)
48
+
49
+ logger.colour = colour.downcase == "true"
50
+ logger.level = level.upcase
51
+ logger.progname = classname
52
+
53
+ logger.formatter = proc do |severity, datetime, progname, msg|
54
+ sevId = severity.chars.first.upcase
55
+ "[#{sevId}] [#{progname}] #{msg}\n"
56
+ end
57
+
58
+ logger
59
+ end
60
+
61
+ ###############################################################################
62
+
63
+ end
64
+
65
+ ###############################################################################
66
+
67
+ end
68
+
69
+ ###############################################################################
70
+
71
+ end
72
+
73
+ ###############################################################################
74
+
75
+ end
76
+
77
+ ###############################################################################
@@ -0,0 +1,250 @@
1
+ ###############################################################################
2
+
3
+ require 'open3'
4
+
5
+ ###############################################################################
6
+
7
+ module HelmWrapper
8
+
9
+ ###############################################################################
10
+
11
+ module Shared
12
+
13
+ ###############################################################################
14
+
15
+ class Runner
16
+
17
+ ###############################################################################
18
+
19
+ include HelmWrapper::Shared::Logging
20
+
21
+ ###############################################################################
22
+
23
+ @@repo_actions = [ "registry", "repo" ]
24
+
25
+ ###############################################################################
26
+
27
+ @auths_attempted = false
28
+
29
+ ###############################################################################
30
+
31
+ attr_reader :auths
32
+ attr_reader :binary
33
+ attr_reader :chart
34
+ attr_reader :config
35
+ attr_reader :repos
36
+
37
+ ###############################################################################
38
+
39
+ def initialize(binary:, chart:, config:)
40
+ @binary = binary
41
+ @chart = chart
42
+ @config = config
43
+
44
+ @auths = false
45
+ @repos = false
46
+ end
47
+
48
+ ###############################################################################
49
+
50
+ def init_auths()
51
+ @auths_attempted = true
52
+
53
+ config.auths.map(&:auth)
54
+
55
+ @auths = true
56
+ end
57
+
58
+ ###############################################################################
59
+
60
+ def init_repos(force: false)
61
+ ENV["HELM_EXPERIMENTAL_OCI"] = "true"
62
+
63
+ @chart.oci.each_with_index do |oci_repo, oci_index|
64
+ logger.info("Logging into OCI repository: #{oci_repo["name"]}")
65
+ @chart.oci_active(active: true, index: oci_index)
66
+
67
+ parameters = Array.new
68
+ parameters.append("login")
69
+ parameters.append("\"#{oci_repo["url"]}\"")
70
+ parameters.append("--username=\"#{oci_repo["username"]}\"")
71
+ parameters.append("--password-stdin")
72
+ logger.fatal("Failed to login to Helm OCI repository: #{oci_repo["name"]}, url: #{oci_repo["url"]}") unless run(action: "registry", parameters: parameters, stdin: oci_repo["password"])
73
+ end
74
+
75
+ if @chart.artefact.length > 0 then
76
+
77
+ @chart.artefact.each_with_index do |artefact_repo, artefact_index|
78
+ logger.info("Adding artefact repository: #{artefact_repo["name"]}")
79
+ @chart.artefact_active(active: true, index: artefact_index)
80
+
81
+ parameters = Array.new
82
+ parameters.append("add")
83
+ parameters.append("\"#{artefact_repo["name"]}\"")
84
+ parameters.append("\"#{artefact_repo["url"]}\"")
85
+ parameters.append("--username=\"#{artefact_repo["username"]}\"") unless artefact_repo["username"].nil?
86
+ parameters.append("--password=\"#{artefact_repo["password"]}\"") unless artefact_repo["password"].nil?
87
+ parameters.append("--force-update") if force
88
+ logger.fatal("Failed to add Helm repository: #{artefact_repo["name"]}, url: #{artefact_repo["url"]}") unless run(action: "repo", parameters: parameters)
89
+ end
90
+
91
+ logger.info("Updating artefact repositories...")
92
+ logger.fatal("Failed to update Helm artefact repositories!") unless run(action: "repo", parameters: Array.new([ "update" ]))
93
+ end
94
+
95
+ @repos = true
96
+ end
97
+
98
+ ###############################################################################
99
+
100
+ def clean(repos: true)
101
+ clean_repos if repos
102
+ clean_auths if @auths_attempted
103
+ end
104
+
105
+ ###############################################################################
106
+
107
+ def delete()
108
+ logger.fatal("Cannot Helm delete before initialising authenticators!") unless auths
109
+
110
+ parameters = Array.new
111
+ parameters.append("--namespace \"#{@config.namespace}\"")
112
+ parameters.append(@config.release)
113
+
114
+ logger.fatal("Helm delete failed!") unless run(action: "delete", parameters: parameters)
115
+ end
116
+
117
+ ###############################################################################
118
+
119
+ def upgrade(install: true)
120
+ logger.fatal("Cannot Helm upgrade before initialising authenticators!") unless auths
121
+ logger.fatal("Cannot Helm upgrade before initialising repositories!") unless repos
122
+
123
+ parameters = Array.new
124
+ parameters.append("--namespace \"#{@config.namespace}\"")
125
+ parameters.append("--install") if install
126
+ parameters.append(@config.release)
127
+ parameters.append(@chart.name)
128
+ parameters.concat(variable_files)
129
+ parameters.concat(variable_strings)
130
+
131
+ logger.fatal("Helm upgrade failed!") unless run(action: "upgrade", parameters: parameters)
132
+ end
133
+
134
+ ###############################################################################
135
+
136
+ private
137
+
138
+ ###############################################################################
139
+
140
+ def clean_auths
141
+ @auths = false
142
+ config.auths.map(&:clear)
143
+ @auths_attempted = false
144
+ end
145
+
146
+ ###############################################################################
147
+
148
+ def clean_repos
149
+ @repos = false
150
+
151
+ @chart.oci.each do |oci_repo|
152
+ if oci_repo["active"] then
153
+ logger.info("Logging out of OCI repository: #{oci_repo["name"]}")
154
+
155
+ parameters = Array.new
156
+ parameters.append("logout")
157
+ parameters.append("\"#{oci_repo["url"]}\"")
158
+ logger.error("Failed to logout of Helm OCI repository: #{oci_repo["name"]}, url: #{oci_repo["url"]}") unless run(action: "registry", parameters: parameters)
159
+ end
160
+ end
161
+
162
+ @chart.artefact.each do |artefact_repo|
163
+ if artefact_repo["active"] then
164
+ if artefact_repo["password"].nil? then
165
+ logger.info("Not removing artefact repository: #{artefact_repo["name"]}, no credentials stored.")
166
+ else
167
+ logger.info("Removing artefact repository: #{artefact_repo["name"]}")
168
+
169
+ parameters = Array.new
170
+ parameters.append("remove")
171
+ parameters.append("\"#{artefact_repo["name"]}\"")
172
+ logger.error("Failed to remove Helm repository: #{artefact_repo["name"]}, url: #{artefact_repo["url"]}") unless run(action: "repo", parameters: parameters)
173
+ end
174
+ end
175
+ end
176
+
177
+ ENV.delete("HELM_EXPERIMENTAL_OCI")
178
+ end
179
+
180
+ ###############################################################################
181
+
182
+ def variable_files
183
+ result = Array.new
184
+
185
+ @config.variable_files.each do |variable_file|
186
+ result.append("--values=\"#{variable_file}\"")
187
+ end
188
+
189
+ return result
190
+ end
191
+
192
+ ###############################################################################
193
+
194
+ def variable_strings
195
+ result = Array.new
196
+
197
+ result.append("--set=\"config=#{@config.name}\"")
198
+
199
+ @config.variables.values.each do |key, value|
200
+ result.append("--set=\"#{key.to_s}=#{value}\"")
201
+ end
202
+
203
+ return result
204
+ end
205
+
206
+ ###############################################################################
207
+
208
+ def run(action:, parameters: Array.new, stdin: nil)
209
+ result = false
210
+
211
+ parameters.reject! { |item| not item.kind_of?(String) or item.strip.empty? }
212
+
213
+ cmdline = [ "\"#{@binary.path}\"", action ].concat(parameters).join(" ")
214
+
215
+ if @@repo_actions.include?(action)
216
+ begin
217
+ out, status = Open3.capture2e(cmdline, :stdin_data=>stdin)
218
+ logger.debug("Helm output:")
219
+ logger.debug(out)
220
+ result = status.success?
221
+ rescue
222
+ result = false
223
+ end
224
+ else
225
+ logger.info("Starting Helm, action: #{action}")
226
+
227
+ fatal("Running Helm with data for stdin can only be used when configuring repos!") unless stdin.nil?
228
+ puts("\n" + ('#' * 80) + "\n\n")
229
+
230
+ result = system(cmdline) || false
231
+
232
+ puts("\n" + ('#' * 80) + "\n\n")
233
+ end
234
+
235
+ return result
236
+ end
237
+
238
+ ###############################################################################
239
+
240
+ end
241
+
242
+ ###############################################################################
243
+
244
+ end
245
+
246
+ ###############################################################################
247
+
248
+ end
249
+
250
+ ###############################################################################