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,66 @@
1
+ ###############################################################################
2
+
3
+ module HelmWrapper
4
+
5
+ ###############################################################################
6
+
7
+ module Shared
8
+
9
+ ###############################################################################
10
+
11
+ class Variables
12
+
13
+ ###############################################################################
14
+
15
+ include HelmWrapper::Shared::Logging
16
+
17
+ ###############################################################################
18
+
19
+ @@reserved = [ "chart" ]
20
+
21
+ ###############################################################################
22
+
23
+ attr_reader :values
24
+
25
+ ###############################################################################
26
+
27
+ def initialize(values: Hash.new, sort: true)
28
+ cleansed = cleanse(values: values)
29
+ @values = sort ? cleansed.sort.to_h : cleansed
30
+ end
31
+
32
+ ###############################################################################
33
+
34
+ private
35
+
36
+ ###############################################################################
37
+
38
+ def cleanse(values:)
39
+ result = Hash.new
40
+
41
+ values.keys.each do |key|
42
+ logger.fatal("Could not clean variables hash. All keys MUST be strings!") unless key.kind_of?(String)
43
+ logger.fatal("Could not clean variables hash, key: #{key.downcase} is reserved and cannot be used!") if @@reserved.include?(key.downcase)
44
+ logger.fatal("Could not clean variables hash, duplicate key found: #{key.downcase}!") if result.key?(key.downcase.to_sym)
45
+ logger.fatal("Could not clean variables hash, value for: #{key.downcase} is not a string!") unless values[key].kind_of?(String)
46
+ logger.fatal("Could not clean variables hash, value for: #{key.downcase} is empty!") if values[key].strip.empty?
47
+
48
+ result[key.downcase.to_sym] = values[key].strip
49
+ end
50
+
51
+ return result
52
+ end
53
+
54
+ ###############################################################################
55
+
56
+ end
57
+
58
+ ###############################################################################
59
+
60
+ end
61
+
62
+ ###############################################################################
63
+
64
+ end
65
+
66
+ ###############################################################################
@@ -0,0 +1,11 @@
1
+ ###############################################################################
2
+
3
+ require 'rake/tasklib'
4
+
5
+ ###############################################################################
6
+
7
+ require_relative 'tasks/apply'
8
+ require_relative 'tasks/binary'
9
+ require_relative 'tasks/destroy'
10
+
11
+ ###############################################################################
@@ -0,0 +1,72 @@
1
+ ###############################################################################
2
+
3
+ module HelmWrapper
4
+
5
+ ###############################################################################
6
+
7
+ module Tasks
8
+
9
+ ###############################################################################
10
+
11
+ class Apply < ::Rake::TaskLib
12
+
13
+ ###############################################################################
14
+
15
+ include HelmWrapper::Shared::Logging
16
+
17
+ ###############################################################################
18
+
19
+ @binary
20
+ @chart
21
+ @options
22
+
23
+ ###############################################################################
24
+
25
+ def initialize(binary:, chart:, options:)
26
+ @binary = binary
27
+ @chart = chart
28
+ @options = options
29
+
30
+ yield self if block_given?
31
+
32
+ apply_task
33
+ end
34
+
35
+ ###############################################################################
36
+
37
+ def apply_task
38
+ desc "Applies chart with Helm for a given configuration."
39
+ task :apply, [:config, :clean] => :binary do |t, args|
40
+ options = @options.merge({"name" => args[:config]})
41
+ clean = args[:clean].kind_of?(String) ? args[:clean].downcase == "true" : true
42
+
43
+ logger.info("Processing configuration for Helm apply...")
44
+
45
+ config = HelmWrapper::Shared::Config.new(chart: @chart, options: options)
46
+ runner = HelmWrapper::Shared::Runner.new(binary: @binary, chart: @chart, config: config)
47
+
48
+ logger.info("Running Helm upgrade for chart: #{@chart.name}...")
49
+
50
+ begin
51
+ runner.init_repos
52
+ runner.init_auths
53
+ runner.upgrade
54
+ ensure
55
+ runner.clean(repos: clean)
56
+ end
57
+ end
58
+ end
59
+
60
+ ###############################################################################
61
+
62
+ end
63
+
64
+ ###############################################################################
65
+
66
+ end
67
+
68
+ ###############################################################################
69
+
70
+ end
71
+
72
+ ###############################################################################
@@ -0,0 +1,195 @@
1
+ ###############################################################################
2
+
3
+ require 'digest'
4
+ require 'fileutils'
5
+ require 'net/http'
6
+ require 'rubygems/package'
7
+ require 'uri'
8
+ require 'zlib'
9
+
10
+ ###############################################################################
11
+
12
+ module HelmWrapper
13
+
14
+ ###############################################################################
15
+
16
+ module Tasks
17
+
18
+ ###############################################################################
19
+
20
+ class Binary < ::Rake::TaskLib
21
+
22
+ ###############################################################################
23
+
24
+ include HelmWrapper::Shared::Logging
25
+
26
+ ###############################################################################
27
+
28
+ @binary
29
+
30
+ ###############################################################################
31
+
32
+ def initialize(binary:)
33
+ @binary = binary
34
+
35
+ yield self if block_given?
36
+
37
+ binary_task
38
+ end
39
+
40
+ ###############################################################################
41
+
42
+ def binary_task
43
+ desc "Downloads and extracts the expected version of the Helm binary if it is not already present."
44
+ task :binary do |t, args|
45
+ logger.info("Checking Helm binary for platform: #{@binary.platform}, version: #{@binary.version}")
46
+
47
+ if not @binary.exists then
48
+ logger.info("Helm binary not found. Preparing binary...")
49
+
50
+ logger.fatal("Failed to create binary directory: #{directory}") unless ::HelmWrapper.create_directory(directory: @binary.directory, purpose: "binaries")
51
+
52
+ archive_binary = "#{@binary.platform}-amd64/helm"
53
+ archive_file = "helm-#{@binary.version}-#{@binary.platform}-amd64.tar.gz"
54
+ archive_path = File.join(@binary.directory, archive_file)
55
+ archive_uri = "https://get.helm.sh/#{archive_file}"
56
+
57
+ sums_file = "#{archive_file}.sha256sum"
58
+ sums_path = File.join(@binary.directory, sums_file)
59
+ sums_uri = "https://get.helm.sh/#{sums_file}"
60
+
61
+ begin
62
+ download(path: archive_path, uri: archive_uri) if not File.file?(archive_path)
63
+ download(path: sums_path, uri: sums_uri) if not File.file?(sums_path)
64
+ verify(file: archive_file, path: archive_path, sums: sums_path)
65
+ extract(archive: archive_path, binary: archive_binary, destination: @binary.path)
66
+ ensure
67
+ clean(archive: archive_path, sums: sums_path)
68
+ end
69
+ end
70
+
71
+ if not @binary.executable then
72
+ logger.info("Helm binary not executable. Setting permissions...")
73
+ executable(path: @binary.path)
74
+ end
75
+
76
+ logger.fatal("Problem with checking the Helm binary!") unless @binary.check
77
+ end
78
+ end
79
+
80
+ ###############################################################################
81
+
82
+ private
83
+
84
+ ###############################################################################
85
+
86
+ def download(path:, uri:)
87
+ logger.info("Downloading: #{uri}")
88
+
89
+ response = Net::HTTP.get_response(URI(uri))
90
+
91
+ logger.fatal("Download request did not return HTTP status 200!") if response.code != "200"
92
+ logger.fatal("Download response body is not permitted!") unless response.class.body_permitted?
93
+ logger.fatal("Download response body is empty!") if response.body.nil?
94
+
95
+ open(path, "wb") { |file|
96
+ file.write(response.body)
97
+ }
98
+
99
+ logger.fatal("Download failed!") unless File.file?(path)
100
+ end
101
+
102
+ ###############################################################################
103
+
104
+ def verify(file:, path:, sums:)
105
+ logger.info("Checking SHA256 for: #{file}")
106
+
107
+ result = false
108
+
109
+ sha256 = Digest::SHA256.hexdigest File.read(path)
110
+
111
+ File.readlines(sums).each do |line|
112
+ begin
113
+ fields = line.match /^(?<sum>\S+)\s+(?<file>\S+)$/
114
+ sum_file = fields["file"]
115
+ sum_sha256 = fields["sum"]
116
+ rescue
117
+ logger.warn("Unexpected data in sums file: #{sums}")
118
+ next
119
+ end
120
+
121
+ if sum_file == file then
122
+ logger.info("Expected SHA256 sum: #{sum_sha256}")
123
+ logger.info("Actual SHA256 sum: #{sha256}")
124
+ result = (sum_sha256 == sha256)
125
+ break
126
+ end
127
+ end
128
+
129
+ logger.fatal("Error whilst verifying the SHA256 sum of the downloaded Helm archive!") unless result
130
+ end
131
+
132
+ ###############################################################################
133
+
134
+ def extract(archive:, binary:, destination:)
135
+ logger.info("Extracting: #{archive}")
136
+
137
+ longlink = "././@LongLink"
138
+
139
+ Gem::Package::TarReader.new(Zlib::GzipReader.open(archive)) do |tar|
140
+ cursor = nil
141
+ tar.each do |file|
142
+ if file.full_name == longlink then
143
+ cursor = file.read.strip
144
+ else
145
+ cursor ||= file.full_name.strip
146
+ if file.file? and (cursor == binary) then
147
+ File.open(destination, 'wb') do |output|
148
+ output.write(file.read)
149
+ end
150
+ end
151
+ cursor = nil
152
+ end
153
+ end
154
+ end
155
+
156
+ logger.fatal("Extraction of Helm binary: #{binary}, from archive: #{archive} has failed!") unless File.file?(destination)
157
+ end
158
+
159
+ ###############################################################################
160
+
161
+ def executable(path:)
162
+ logger.info("Making executable: #{path}")
163
+ FileUtils.chmod("+x", path)
164
+ logger.fatal("Setting executable bit on file: #{path} has failed!") unless File.executable?(path)
165
+ end
166
+
167
+ ###############################################################################
168
+
169
+ def clean(archive:, sums:)
170
+ [archive, sums].each do |file|
171
+ if File.file?(file)
172
+ logger.info("Removing file: #{file}")
173
+
174
+ begin
175
+ File.delete(file)
176
+ rescue
177
+ logger.error("Failed to delete: #{file}, please remove manually.")
178
+ end
179
+ end
180
+ end
181
+ end
182
+
183
+ ###############################################################################
184
+
185
+ end
186
+
187
+ ###############################################################################
188
+
189
+ end
190
+
191
+ ###############################################################################
192
+
193
+ end
194
+
195
+ ###############################################################################
@@ -0,0 +1,70 @@
1
+ ###############################################################################
2
+
3
+ module HelmWrapper
4
+
5
+ ###############################################################################
6
+
7
+ module Tasks
8
+
9
+ ###############################################################################
10
+
11
+ class Destroy < ::Rake::TaskLib
12
+
13
+ ###############################################################################
14
+
15
+ include HelmWrapper::Shared::Logging
16
+
17
+ ###############################################################################
18
+
19
+ @binary
20
+ @chart
21
+ @options
22
+
23
+ ###############################################################################
24
+
25
+ def initialize(binary:, chart:, options:)
26
+ @binary = binary
27
+ @chart = chart
28
+ @options = options
29
+
30
+ yield self if block_given?
31
+
32
+ destroy_task
33
+ end
34
+
35
+ ###############################################################################
36
+
37
+ def destroy_task
38
+ desc "Removes a chart release with Helm for a given configuration."
39
+ task :destroy, [:config] => :binary do |t, args|
40
+ options = @options.merge({"name" => args[:config]})
41
+
42
+ logger.info("Processing configuration for Helm destroy...")
43
+
44
+ config = HelmWrapper::Shared::Config.new(chart: @chart, options: options)
45
+ runner = HelmWrapper::Shared::Runner.new(binary: @binary, chart: @chart, config: config)
46
+
47
+ logger.info("Running Helm delete for chart: #{@chart.name}...")
48
+
49
+ begin
50
+ runner.init_auths
51
+ runner.delete
52
+ ensure
53
+ runner.clean(repos: false)
54
+ end
55
+ end
56
+ end
57
+
58
+ ###############################################################################
59
+
60
+ end
61
+
62
+ ###############################################################################
63
+
64
+ end
65
+
66
+ ###############################################################################
67
+
68
+ end
69
+
70
+ ###############################################################################
@@ -0,0 +1,13 @@
1
+ ###############################################################################
2
+
3
+ module HelmWrapper
4
+
5
+ ###############################################################################
6
+
7
+ VERSION = "0.1.0"
8
+
9
+ ###############################################################################
10
+
11
+ end
12
+
13
+ ###############################################################################
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: helm-wrapper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Richard Lees
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-03-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '13.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '13.0'
27
+ description: A ruby wrapper for managing Helm binaries and chart deployment. Helm
28
+ Wrapper also supports authenticating with specific Kubernetes clusters.
29
+ email:
30
+ - git0@bitservices.io
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".gitignore"
36
+ - ".gitlab-ci.yml"
37
+ - Gemfile
38
+ - LICENSE.txt
39
+ - Rakefile
40
+ - bin/console
41
+ - bin/setup
42
+ - helm-wrapper.gemspec
43
+ - lib/helm-wrapper.rb
44
+ - lib/helm-wrapper/common.rb
45
+ - lib/helm-wrapper/shared.rb
46
+ - lib/helm-wrapper/shared/auths.rb
47
+ - lib/helm-wrapper/shared/auths/azure.rb
48
+ - lib/helm-wrapper/shared/auths/common.rb
49
+ - lib/helm-wrapper/shared/binary.rb
50
+ - lib/helm-wrapper/shared/chart.rb
51
+ - lib/helm-wrapper/shared/config.rb
52
+ - lib/helm-wrapper/shared/latest.rb
53
+ - lib/helm-wrapper/shared/logger.rb
54
+ - lib/helm-wrapper/shared/logging.rb
55
+ - lib/helm-wrapper/shared/runner.rb
56
+ - lib/helm-wrapper/shared/variables.rb
57
+ - lib/helm-wrapper/tasks.rb
58
+ - lib/helm-wrapper/tasks/apply.rb
59
+ - lib/helm-wrapper/tasks/binary.rb
60
+ - lib/helm-wrapper/tasks/destroy.rb
61
+ - lib/helm-wrapper/version.rb
62
+ homepage: https://gitlab.com/rlees85-ruby/helm-wrapper/
63
+ licenses:
64
+ - MIT
65
+ metadata:
66
+ homepage_uri: https://gitlab.com/rlees85-ruby/helm-wrapper/
67
+ source_code_uri: https://gitlab.com/rlees85-ruby/helm-wrapper/
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: 2.6.0
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ requirements: []
83
+ rubygems_version: 3.2.3
84
+ signing_key:
85
+ specification_version: 4
86
+ summary: A ruby wrapper for managing Helm binaries and chart deployment.
87
+ test_files: []