helm-wrapper 0.1.0 → 1.1.1
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.
- checksums.yaml +4 -4
- data/lib/helm-wrapper.rb +34 -4
- data/lib/helm-wrapper/common.rb +12 -1
- data/lib/helm-wrapper/shared/auths/azure.rb +21 -20
- data/lib/helm-wrapper/shared/auths/common.rb +1 -1
- data/lib/helm-wrapper/shared/chart.rb +18 -14
- data/lib/helm-wrapper/shared/config.rb +11 -52
- data/lib/helm-wrapper/shared/runner.rb +84 -15
- data/lib/helm-wrapper/shared/variables.rb +83 -10
- data/lib/helm-wrapper/tasks.rb +3 -0
- data/lib/helm-wrapper/tasks/apply.rb +1 -1
- data/lib/helm-wrapper/tasks/destroy.rb +1 -1
- data/lib/helm-wrapper/tasks/push.rb +67 -0
- data/lib/helm-wrapper/tasks/template.rb +71 -0
- data/lib/helm-wrapper/tasks/validate.rb +58 -0
- data/lib/helm-wrapper/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 76acfe4805299ed72c029326ed693127fe8518078eea2d5c81880be17d1823d4
|
4
|
+
data.tar.gz: 6355e496234578a2f414cf8873b2ecfff6d0aa710a4045a3741e940e1996ada8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3ec82adad9abe9ad074f6f60fc4ed5711e9f08a7c92258b1b6e71fcf6da491c3a9a0f211796d7ccab3d2f30c027ad0cfdad06955233547bb788faef0e81172f5
|
7
|
+
data.tar.gz: 0b1299e87f67e83c2a7289049a9222b7a269739fd50b8fc9e18e94f818076dd9c857607507911b690feebae91e6a7fe0c7a5a3408883361705ec6f61201c4d83
|
data/lib/helm-wrapper.rb
CHANGED
@@ -22,8 +22,8 @@ module HelmWrapper
|
|
22
22
|
|
23
23
|
###############################################################################
|
24
24
|
|
25
|
-
def self.
|
26
|
-
@logger.info("Building tasks for chart: #{chart}...")
|
25
|
+
def self.deployment_tasks(chart:, namespace:, release:, options: Hash.new)
|
26
|
+
@logger.info("Building deployment tasks for chart: #{chart}...")
|
27
27
|
|
28
28
|
@logger.fatal("Options must be specified as a hash!") unless options.kind_of?(Hash)
|
29
29
|
|
@@ -32,8 +32,10 @@ module HelmWrapper
|
|
32
32
|
binary_options["version"] = options.key?("binary-version") ? options["binary-version"] : Shared::Latest.instance.version
|
33
33
|
|
34
34
|
chart_options = Hash.new
|
35
|
-
chart_options["name"]
|
36
|
-
chart_options["
|
35
|
+
chart_options["name"] = chart
|
36
|
+
chart_options["path"] = nil
|
37
|
+
chart_options["repos"] = options.key?("chart-repos") ? options["chart-repos"] : Array.new
|
38
|
+
chart_options["version"] = options.key?("chart-version") ? options["chart-version"] : String.new
|
37
39
|
|
38
40
|
config_options = Hash.new
|
39
41
|
config_options["auth-azure"] = options.key?("config-auth-azure") ? options["config-auth-azure"] : false
|
@@ -49,6 +51,34 @@ module HelmWrapper
|
|
49
51
|
tasks << HelmWrapper::Tasks::Apply.new(binary: binary, chart: chart, options: config_options)
|
50
52
|
tasks << HelmWrapper::Tasks::Binary.new(binary: binary)
|
51
53
|
tasks << HelmWrapper::Tasks::Destroy.new(binary: binary, chart: chart, options: config_options)
|
54
|
+
tasks << HelmWrapper::Tasks::Template.new(binary: binary, chart: chart, options: config_options)
|
55
|
+
return tasks
|
56
|
+
end
|
57
|
+
|
58
|
+
###############################################################################
|
59
|
+
|
60
|
+
def self.development_tasks(chart:, path:, options: Hash.new)
|
61
|
+
@logger.info("Building development tasks for path: #{path}...")
|
62
|
+
|
63
|
+
@logger.fatal("Options must be specified as a hash!") unless options.kind_of?(Hash)
|
64
|
+
|
65
|
+
binary_options = Hash.new
|
66
|
+
binary_options["base"] = options.key?("binary-base") ? options["binary-base"] : File.join(Dir.pwd, "vendor", "helm")
|
67
|
+
binary_options["version"] = options.key?("binary-version") ? options["binary-version"] : Shared::Latest.instance.version
|
68
|
+
|
69
|
+
chart_options = Hash.new
|
70
|
+
chart_options["name"] = chart
|
71
|
+
chart_options["path"] = path
|
72
|
+
chart_options["repos"] = options.key?("chart-repos") ? options["chart-repos"] : Array.new
|
73
|
+
chart_options["version"] = String.new
|
74
|
+
|
75
|
+
binary = HelmWrapper::Shared::Binary.new(options: binary_options)
|
76
|
+
chart = HelmWrapper::Shared::Chart.new(options: chart_options)
|
77
|
+
|
78
|
+
tasks = Array.new
|
79
|
+
tasks << HelmWrapper::Tasks::Binary.new(binary: binary)
|
80
|
+
tasks << HelmWrapper::Tasks::Push.new(binary: binary, chart: chart)
|
81
|
+
tasks << HelmWrapper::Tasks::Validate.new(binary: binary, chart: chart)
|
52
82
|
return tasks
|
53
83
|
end
|
54
84
|
|
data/lib/helm-wrapper/common.rb
CHANGED
@@ -4,7 +4,7 @@ module HelmWrapper
|
|
4
4
|
|
5
5
|
###############################################################################
|
6
6
|
|
7
|
-
def self.create_directory(directory:,
|
7
|
+
def self.create_directory(directory:, exists: true, purpose: nil)
|
8
8
|
return exists if File.directory?(directory)
|
9
9
|
|
10
10
|
result = false
|
@@ -20,6 +20,17 @@ module HelmWrapper
|
|
20
20
|
result = File.directory?(directory)
|
21
21
|
end
|
22
22
|
|
23
|
+
###############################################################################
|
24
|
+
|
25
|
+
def self.find(base:, name:, exts:, description: "File")
|
26
|
+
exts.each do |ext|
|
27
|
+
path = File.join(base, name + ext)
|
28
|
+
return path if File.file?(path)
|
29
|
+
end
|
30
|
+
|
31
|
+
@logger.fatal("#{description} name: #{name} not found in location: #{base}!")
|
32
|
+
end
|
33
|
+
|
23
34
|
###############################################################################
|
24
35
|
|
25
36
|
end
|
@@ -29,13 +29,14 @@ module HelmWrapper
|
|
29
29
|
|
30
30
|
###############################################################################
|
31
31
|
|
32
|
-
@
|
33
|
-
@
|
32
|
+
@keyvault
|
33
|
+
@secret_ca
|
34
|
+
@secret_endpoint
|
35
|
+
@secret_token
|
34
36
|
|
35
37
|
###############################################################################
|
36
38
|
|
37
|
-
|
38
|
-
attr_reader :endpoint
|
39
|
+
@ca_tempfile = nil
|
39
40
|
|
40
41
|
###############################################################################
|
41
42
|
|
@@ -46,6 +47,10 @@ module HelmWrapper
|
|
46
47
|
###############################################################################
|
47
48
|
|
48
49
|
def auth()
|
50
|
+
ca = secret(vault: @keyvault, name: @secret_ca)
|
51
|
+
endpoint = secret(vault: @keyvault, name: @secret_endpoint)
|
52
|
+
token = secret(vault: @keyvault, name: @secret_token)
|
53
|
+
|
49
54
|
@ca_tempfile = Tempfile.new('helm-wrapper-auths-azure-ca')
|
50
55
|
|
51
56
|
begin
|
@@ -57,8 +62,8 @@ module HelmWrapper
|
|
57
62
|
logger.success("Azure authenticator successfully written Kubernetes CA to file!")
|
58
63
|
|
59
64
|
ENV["HELM_KUBECAFILE"] = @ca_tempfile.path
|
60
|
-
ENV["HELM_KUBEAPISERVER"] =
|
61
|
-
ENV["HELM_KUBETOKEN"] =
|
65
|
+
ENV["HELM_KUBEAPISERVER"] = endpoint
|
66
|
+
ENV["HELM_KUBETOKEN"] = token
|
62
67
|
|
63
68
|
logger.success("Azure authenticator environment variables set!")
|
64
69
|
end
|
@@ -109,18 +114,18 @@ module HelmWrapper
|
|
109
114
|
###############################################################################
|
110
115
|
|
111
116
|
def specific()
|
112
|
-
logger.fatal("Azure CLI must
|
117
|
+
logger.fatal("Azure CLI must be installed and accessible to use the Azure authenticator.") unless cli
|
113
118
|
|
114
119
|
logger.fatal("Azure authenticator mandatory option 'keyvault' has not been set!") unless @options.key?("keyvault")
|
115
120
|
logger.fatal("Azure authenticator keyvault must be a string!") unless @options["keyvault"].kind_of?(String)
|
116
121
|
logger.fatal("Azure authenticator keyvault must not be blank!") if @options["keyvault"].strip.empty?
|
117
122
|
|
118
123
|
keyvault = @options["keyvault"]
|
119
|
-
if @options.key?("ca-
|
120
|
-
logger.fatal("Azure authenticator keyvault
|
121
|
-
logger.fatal("Azure authenticator keyvault
|
124
|
+
if @options.key?("ca-secret") then
|
125
|
+
logger.fatal("Azure authenticator keyvault secret for Kubernetes CA must be a string!") unless @options["ca-secret"].kind_of?(String)
|
126
|
+
logger.fatal("Azure authenticator keyvault secret for Kubernetes CA must not be blank!") if @options["ca-secret"].strip.empty?
|
122
127
|
|
123
|
-
ca = @options["ca-
|
128
|
+
ca = @options["ca-secret"]
|
124
129
|
else
|
125
130
|
ca = "kubernetes-ca"
|
126
131
|
end
|
@@ -144,17 +149,13 @@ module HelmWrapper
|
|
144
149
|
end
|
145
150
|
|
146
151
|
begin
|
147
|
-
keyvault
|
148
|
-
|
149
|
-
|
150
|
-
|
152
|
+
@keyvault = keyvault % @variables.identifiers
|
153
|
+
@secret_ca = ca % @variables.identifiers
|
154
|
+
@secret_endpoint = endpoint % @variables.identifiers
|
155
|
+
@secret_token = token % @variables.identifiers
|
151
156
|
rescue
|
152
|
-
logger.fatal("Azure authenticator options contain
|
157
|
+
logger.fatal("Azure authenticator options contain identifiers that are not included in the configuration file!")
|
153
158
|
end
|
154
|
-
|
155
|
-
@ca = secret(vault: keyvault, name: ca)
|
156
|
-
@endpoint = secret(vault: keyvault, name: endpoint)
|
157
|
-
@token = secret(vault: keyvault, name: token)
|
158
159
|
end
|
159
160
|
|
160
161
|
###############################################################################
|
@@ -29,7 +29,7 @@ module HelmWrapper
|
|
29
29
|
|
30
30
|
###############################################################################
|
31
31
|
|
32
|
-
def initialize(
|
32
|
+
def initialize(options:, variables:)
|
33
33
|
logger.fatal("This class should not be used directly! Please create an authenticator-specific class instead!")
|
34
34
|
end
|
35
35
|
|
@@ -16,9 +16,11 @@ module HelmWrapper
|
|
16
16
|
|
17
17
|
###############################################################################
|
18
18
|
|
19
|
-
attr_reader :oci
|
20
|
-
attr_reader :name
|
21
19
|
attr_reader :artefact
|
20
|
+
attr_reader :name
|
21
|
+
attr_reader :path
|
22
|
+
attr_reader :oci
|
23
|
+
attr_reader :version
|
22
24
|
|
23
25
|
###############################################################################
|
24
26
|
|
@@ -28,6 +30,18 @@ module HelmWrapper
|
|
28
30
|
|
29
31
|
@name = options["name"]
|
30
32
|
|
33
|
+
logger.fatal("Chart version must be a string!") unless options["version"].kind_of?(String)
|
34
|
+
|
35
|
+
@version = options["version"]
|
36
|
+
|
37
|
+
unless options["path"].nil? then
|
38
|
+
logger.fatal("Chart path must be a string!") unless options["path"].kind_of?(String)
|
39
|
+
logger.fatal("Chart path must not be blank!") if options["path"].strip.empty?
|
40
|
+
logger.fatal("Chart path must exist!") unless File.directory?(options["path"])
|
41
|
+
end
|
42
|
+
|
43
|
+
@path = options["path"]
|
44
|
+
|
31
45
|
logger.fatal("Chart repos must be a list of hashes!") unless options["repos"].kind_of?(Array)
|
32
46
|
|
33
47
|
repos = options["repos"]
|
@@ -63,23 +77,13 @@ module HelmWrapper
|
|
63
77
|
logger.fatal("Chart repo: #{hash["name"]} username must be a string!") unless repo["username"].kind_of?(String)
|
64
78
|
logger.fatal("Chart repo: #{hash["name"]} username must not be blank!") if repo["username"].strip.empty?
|
65
79
|
|
66
|
-
|
67
|
-
|
68
|
-
logger.fatal("Chart repo: #{hash["name"]} username attribute must refer to a valid environment variable that holds the actual repository username!") unless ENV.key?(repo_username)
|
69
|
-
logger.fatal("Environment variable holding the username for chart repo: #{hash["name"]} is blank!") if ENV[repo_username].strip.empty?
|
70
|
-
|
71
|
-
hash["username"] = ENV[repo_username].strip
|
80
|
+
hash["username"] = repo["username"].strip
|
72
81
|
|
73
82
|
logger.fatal("Chart repo: #{hash["name"]} must have a password attribute if 'username' is set!") unless repo.key?("password")
|
74
83
|
logger.fatal("Chart repo: #{hash["name"]} password must be a string!") unless repo["password"].kind_of?(String)
|
75
84
|
logger.fatal("Chart repo: #{hash["name"]} password must not be blank!") if repo["password"].strip.empty?
|
76
85
|
|
77
|
-
|
78
|
-
|
79
|
-
logger.fatal("Chart repo: #{hash["name"]} password attribute must refer to a valid environment variable that holds the actual repository password!") unless ENV.key?(repo_password)
|
80
|
-
logger.fatal("Environment variable holding the password for chart repo: #{hash["name"]} is blank!") if ENV[repo_password].strip.empty?
|
81
|
-
|
82
|
-
hash["password"] = ENV[repo_password].strip
|
86
|
+
hash["password"] = repo["password"].strip
|
83
87
|
else
|
84
88
|
fatal("Chart repo: #{hash["name"]} is an OCI repository therefore must have a username attribute! Public OCI repositories do not need to be declared.") if is_oci
|
85
89
|
hash["username"] = nil
|
@@ -22,11 +22,6 @@ module HelmWrapper
|
|
22
22
|
|
23
23
|
@@config_exts = [ "", ".yaml", ".yml" ]
|
24
24
|
|
25
|
-
###############################################################################
|
26
|
-
|
27
|
-
@@variable_files_name = "helmvars"
|
28
|
-
@@variable_files_exts = [ ".yaml", ".yml" ]
|
29
|
-
|
30
25
|
###############################################################################
|
31
26
|
|
32
27
|
attr_reader :auths
|
@@ -36,7 +31,6 @@ module HelmWrapper
|
|
36
31
|
attr_reader :namespace
|
37
32
|
attr_reader :path
|
38
33
|
attr_reader :release
|
39
|
-
attr_reader :variable_files
|
40
34
|
attr_reader :variables
|
41
35
|
|
42
36
|
###############################################################################
|
@@ -71,65 +65,30 @@ module HelmWrapper
|
|
71
65
|
auth_azure_options = options["auth-azure-options"]
|
72
66
|
|
73
67
|
@chart = chart
|
74
|
-
@path = find(base: @base, name: @name, exts: @@config_exts, description: "Configuration")
|
68
|
+
@path = ::HelmWrapper.find(base: @base, name: @name, exts: @@config_exts, description: "Configuration")
|
75
69
|
|
76
70
|
yaml = YAML.load(File.read(@path))
|
77
71
|
logger.fatal("Invalid YAML in configuration file: #{@path}") unless yaml.kind_of?(Hash)
|
78
72
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
else
|
83
|
-
@variables = HelmWrapper::Shared::Variables.new()
|
84
|
-
end
|
73
|
+
identifers = yaml.key?("identifiers") ? yaml["identifiers"] : Hash.new
|
74
|
+
@variables = HelmWrapper::Shared::Variables.new(chart: @chart.name, config: @name, namespace: namespace, release: release, identifiers: identifers)
|
75
|
+
@variables.add_variables(variables: yaml["globals"]) if yaml.key?("globals")
|
85
76
|
|
86
|
-
|
77
|
+
if yaml.key?("helm") then
|
78
|
+
logger.fatal("Key 'helm' is not a hash in configuration file: #{@path}") unless yaml["helm"].kind_of?(Hash)
|
79
|
+
helm = yaml["helm"]
|
87
80
|
|
88
|
-
|
89
|
-
|
90
|
-
release = release % @variables.values
|
91
|
-
rescue
|
92
|
-
logger.fatal("Provided configuration options contain variables that are not included in the configuration file!")
|
81
|
+
@variables.add_variables(variables: helm["variables"]) if helm.key?("variables")
|
82
|
+
@variables.add_files(base: @base, files: helm["files"]) if helm.key?("files")
|
93
83
|
end
|
94
84
|
|
95
|
-
@namespace = namespace
|
96
|
-
@release = release
|
85
|
+
@namespace = @variables.core[:namespace]
|
86
|
+
@release = @variables.core[:release]
|
97
87
|
|
98
88
|
@auths = Array.new
|
99
89
|
@auths.append(HelmWrapper::Shared::Auths::Azure.new(options: auth_azure_options, variables: @variables)) if auth_azure
|
100
90
|
end
|
101
91
|
|
102
|
-
###############################################################################
|
103
|
-
|
104
|
-
private
|
105
|
-
|
106
|
-
###############################################################################
|
107
|
-
|
108
|
-
def find(base:, name:, exts:, description: "File")
|
109
|
-
@@config_exts.each do |config_ext|
|
110
|
-
path = File.join(base, name + config_ext)
|
111
|
-
return path if File.file?(path)
|
112
|
-
end
|
113
|
-
|
114
|
-
logger.fatal("#{description} name: #{@name} not found in location: #{@base}!")
|
115
|
-
end
|
116
|
-
|
117
|
-
###############################################################################
|
118
|
-
|
119
|
-
def validate(variable_files:)
|
120
|
-
logger.fatal("Optional key 'variable_files' must be a list of strings!") unless variable_files.kind_of?(Array)
|
121
|
-
|
122
|
-
result = Array.new
|
123
|
-
|
124
|
-
variable_files.each do |variable_file|
|
125
|
-
logger.fatal("All elements of 'helm' must be strings!") unless variable_file.kind_of?(String)
|
126
|
-
logger.fatal("All elements of 'helm' must not be blank!") if variable_file.strip.empty?
|
127
|
-
result.append(find(base: File.join(@base, @@variable_files_name), name: variable_file.strip, exts: @@variable_files_exts, description: "Helm values file"))
|
128
|
-
end
|
129
|
-
|
130
|
-
return result
|
131
|
-
end
|
132
|
-
|
133
92
|
###############################################################################
|
134
93
|
|
135
94
|
end
|
@@ -36,7 +36,7 @@ module HelmWrapper
|
|
36
36
|
|
37
37
|
###############################################################################
|
38
38
|
|
39
|
-
def initialize(binary:, chart:, config:)
|
39
|
+
def initialize(binary:, chart:, config: nil)
|
40
40
|
@binary = binary
|
41
41
|
@chart = chart
|
42
42
|
@config = config
|
@@ -48,6 +48,8 @@ module HelmWrapper
|
|
48
48
|
###############################################################################
|
49
49
|
|
50
50
|
def init_auths()
|
51
|
+
logger.fatal("Cannot initialise authenticators without a valid configuration!") if @config.nil?
|
52
|
+
|
51
53
|
@auths_attempted = true
|
52
54
|
|
53
55
|
config.auths.map(&:auth)
|
@@ -62,28 +64,36 @@ module HelmWrapper
|
|
62
64
|
|
63
65
|
@chart.oci.each_with_index do |oci_repo, oci_index|
|
64
66
|
logger.info("Logging into OCI repository: #{oci_repo["name"]}")
|
67
|
+
|
68
|
+
username = from_environment(variable: oci_repo["username"])
|
69
|
+
password = from_environment(variable: oci_repo["password"])
|
70
|
+
|
65
71
|
@chart.oci_active(active: true, index: oci_index)
|
66
72
|
|
67
73
|
parameters = Array.new
|
68
74
|
parameters.append("login")
|
69
75
|
parameters.append("\"#{oci_repo["url"]}\"")
|
70
|
-
parameters.append("--username=\"#{
|
76
|
+
parameters.append("--username=\"#{username}\"")
|
71
77
|
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:
|
78
|
+
logger.fatal("Failed to login to Helm OCI repository: #{oci_repo["name"]}, url: #{oci_repo["url"]}") unless run(action: "registry", parameters: parameters, stdin: password)
|
73
79
|
end
|
74
80
|
|
75
81
|
if @chart.artefact.length > 0 then
|
76
82
|
|
77
83
|
@chart.artefact.each_with_index do |artefact_repo, artefact_index|
|
78
84
|
logger.info("Adding artefact repository: #{artefact_repo["name"]}")
|
85
|
+
|
86
|
+
username = artefact_repo["username"].nil? ? nil : from_environment(variable: artefact_repo["username"])
|
87
|
+
password = artefact_repo["password"].nil? ? nil : from_environment(variable: artefact_repo["password"])
|
88
|
+
|
79
89
|
@chart.artefact_active(active: true, index: artefact_index)
|
80
90
|
|
81
91
|
parameters = Array.new
|
82
92
|
parameters.append("add")
|
83
93
|
parameters.append("\"#{artefact_repo["name"]}\"")
|
84
94
|
parameters.append("\"#{artefact_repo["url"]}\"")
|
85
|
-
parameters.append("--username=\"#{
|
86
|
-
parameters.append("--password=\"#{
|
95
|
+
parameters.append("--username=\"#{username}\"") unless username.nil?
|
96
|
+
parameters.append("--password=\"#{password}\"") unless password.nil?
|
87
97
|
parameters.append("--force-update") if force
|
88
98
|
logger.fatal("Failed to add Helm repository: #{artefact_repo["name"]}, url: #{artefact_repo["url"]}") unless run(action: "repo", parameters: parameters)
|
89
99
|
end
|
@@ -105,32 +115,84 @@ module HelmWrapper
|
|
105
115
|
###############################################################################
|
106
116
|
|
107
117
|
def delete()
|
118
|
+
logger.fatal("Cannot Helm delete without a valid configuration!") if @config.nil?
|
108
119
|
logger.fatal("Cannot Helm delete before initialising authenticators!") unless auths
|
109
120
|
|
110
121
|
parameters = Array.new
|
111
|
-
parameters.append("--namespace
|
112
|
-
parameters.append(@config.release)
|
122
|
+
parameters.append("--namespace=\"#{@config.namespace}\"")
|
123
|
+
parameters.append("\"#{@config.release}\"")
|
113
124
|
|
114
125
|
logger.fatal("Helm delete failed!") unless run(action: "delete", parameters: parameters)
|
115
126
|
end
|
116
127
|
|
128
|
+
###############################################################################
|
129
|
+
|
130
|
+
def template()
|
131
|
+
logger.fatal("Cannot Helm template without a valid configuration!") if @config.nil?
|
132
|
+
logger.fatal("Cannot Helm template before initialising repositories!") unless repos
|
133
|
+
|
134
|
+
parameters = Array.new
|
135
|
+
parameters.append("--namespace=\"#{@config.namespace}\"")
|
136
|
+
parameters.append("\"#{@config.release}\"")
|
137
|
+
parameters.append("\"#{@chart.name}\"")
|
138
|
+
parameters.append("--version=\"#{@chart.version}\"") unless @chart.version.strip.empty?
|
139
|
+
parameters.concat(variable_files)
|
140
|
+
parameters.concat(variable_strings)
|
141
|
+
|
142
|
+
logger.fatal("Helm template failed!") unless run(action: "template", parameters: parameters)
|
143
|
+
end
|
144
|
+
|
117
145
|
###############################################################################
|
118
146
|
|
119
147
|
def upgrade(install: true)
|
148
|
+
logger.fatal("Cannot Helm upgrade without a valid configuration!") if @config.nil?
|
120
149
|
logger.fatal("Cannot Helm upgrade before initialising authenticators!") unless auths
|
121
150
|
logger.fatal("Cannot Helm upgrade before initialising repositories!") unless repos
|
122
151
|
|
123
152
|
parameters = Array.new
|
124
|
-
parameters.append("--namespace
|
153
|
+
parameters.append("--namespace=\"#{@config.namespace}\"")
|
125
154
|
parameters.append("--install") if install
|
126
|
-
parameters.append(@config.release)
|
127
|
-
parameters.append(@chart.name)
|
155
|
+
parameters.append("\"#{@config.release}\"")
|
156
|
+
parameters.append("\"#{@chart.name}\"")
|
157
|
+
parameters.append("--version=\"#{@chart.version}\"") unless @chart.version.strip.empty?
|
128
158
|
parameters.concat(variable_files)
|
129
159
|
parameters.concat(variable_strings)
|
130
160
|
|
131
161
|
logger.fatal("Helm upgrade failed!") unless run(action: "upgrade", parameters: parameters)
|
132
162
|
end
|
133
163
|
|
164
|
+
###############################################################################
|
165
|
+
|
166
|
+
def lint()
|
167
|
+
parameters = Array.new
|
168
|
+
parameters.append("\"#{@chart.path}\"")
|
169
|
+
|
170
|
+
logger.fatal("Helm validate failed!") unless run(action: "lint", parameters: parameters)
|
171
|
+
end
|
172
|
+
|
173
|
+
###############################################################################
|
174
|
+
|
175
|
+
def push(tag:)
|
176
|
+
logger.fatal("Cannot Helm push before initialising repositories!") unless repos
|
177
|
+
|
178
|
+
parameters = Array.new
|
179
|
+
parameters.append("push")
|
180
|
+
parameters.append("\"#{@chart.name}:#{tag}\"")
|
181
|
+
|
182
|
+
logger.fatal("Helm push failed!") unless run(action: "chart", parameters: parameters)
|
183
|
+
end
|
184
|
+
|
185
|
+
###############################################################################
|
186
|
+
|
187
|
+
def save(tag:)
|
188
|
+
parameters = Array.new
|
189
|
+
parameters.append("save")
|
190
|
+
parameters.append("\"#{@chart.path}\"")
|
191
|
+
parameters.append("\"#{@chart.name}:#{tag}\"")
|
192
|
+
|
193
|
+
logger.fatal("Helm save failed!") unless run(action: "chart", parameters: parameters)
|
194
|
+
end
|
195
|
+
|
134
196
|
###############################################################################
|
135
197
|
|
136
198
|
private
|
@@ -182,8 +244,8 @@ module HelmWrapper
|
|
182
244
|
def variable_files
|
183
245
|
result = Array.new
|
184
246
|
|
185
|
-
@config.
|
186
|
-
result.append("--values=\"#{
|
247
|
+
@config.variables.files.each do |file|
|
248
|
+
result.append("--values=\"#{file}\"")
|
187
249
|
end
|
188
250
|
|
189
251
|
return result
|
@@ -194,8 +256,6 @@ module HelmWrapper
|
|
194
256
|
def variable_strings
|
195
257
|
result = Array.new
|
196
258
|
|
197
|
-
result.append("--set=\"config=#{@config.name}\"")
|
198
|
-
|
199
259
|
@config.variables.values.each do |key, value|
|
200
260
|
result.append("--set=\"#{key.to_s}=#{value}\"")
|
201
261
|
end
|
@@ -217,7 +277,7 @@ module HelmWrapper
|
|
217
277
|
out, status = Open3.capture2e(cmdline, :stdin_data=>stdin)
|
218
278
|
logger.debug("Helm output:")
|
219
279
|
logger.debug(out)
|
220
|
-
result =
|
280
|
+
result = statrepo_usernameus.success?
|
221
281
|
rescue
|
222
282
|
result = false
|
223
283
|
end
|
@@ -235,6 +295,15 @@ module HelmWrapper
|
|
235
295
|
return result
|
236
296
|
end
|
237
297
|
|
298
|
+
###############################################################################
|
299
|
+
|
300
|
+
def from_environment(variable:)
|
301
|
+
logger.fatal("Environment variable: #{variable} does not exist") unless ENV.key?(variable)
|
302
|
+
logger.fatal("Environment variable: #{variable} is blank!") if ENV[variable].strip.empty?
|
303
|
+
|
304
|
+
return ENV[variable].strip
|
305
|
+
end
|
306
|
+
|
238
307
|
###############################################################################
|
239
308
|
|
240
309
|
end
|
@@ -16,36 +16,109 @@ module HelmWrapper
|
|
16
16
|
|
17
17
|
###############################################################################
|
18
18
|
|
19
|
-
@@
|
19
|
+
@@variable_files_name = "helmvars"
|
20
|
+
@@variable_files_exts = [ ".yaml", ".yml" ]
|
20
21
|
|
21
22
|
###############################################################################
|
22
23
|
|
24
|
+
attr_reader :core
|
25
|
+
attr_reader :files
|
26
|
+
attr_reader :identifiers
|
23
27
|
attr_reader :values
|
24
28
|
|
25
29
|
###############################################################################
|
26
30
|
|
27
|
-
def initialize(
|
28
|
-
|
29
|
-
|
31
|
+
def initialize(chart:, config:, namespace:, release:, identifiers: Hash.new, sort: false)
|
32
|
+
logger.fatal("Identifiers provided must be a hash!") unless identifiers.kind_of?(Hash)
|
33
|
+
|
34
|
+
core = Hash.new()
|
35
|
+
core[:chart] = chart
|
36
|
+
core[:config] = config
|
37
|
+
core[:namespace] = nil
|
38
|
+
core[:release] = nil
|
39
|
+
|
40
|
+
user = cleanse(variables: identifiers, reserved: core.keys)
|
41
|
+
|
42
|
+
begin
|
43
|
+
core[:namespace] = namespace % user
|
44
|
+
core[:release] = release % user
|
45
|
+
rescue
|
46
|
+
logger.fatal("Provided configuration options include identifiers that are not included in the configuration file!")
|
47
|
+
end
|
48
|
+
|
49
|
+
merged = core.merge(user)
|
50
|
+
|
51
|
+
@core = core
|
52
|
+
@identifiers = sort ? merged.sort.to_h : merged
|
53
|
+
@values = @identifiers
|
54
|
+
@files = Array.new
|
55
|
+
end
|
56
|
+
|
57
|
+
###############################################################################
|
58
|
+
|
59
|
+
def add_files(base:, files:)
|
60
|
+
logger.fatal("Variable files provided must be an array!") unless files.kind_of?(Array)
|
61
|
+
|
62
|
+
files.each do |file|
|
63
|
+
logger.fatal("All provided variable file names must be strings!") unless file.kind_of?(String)
|
64
|
+
logger.fatal("All provided variable file names must not be blank!") if file.strip.empty?
|
65
|
+
|
66
|
+
path = ::HelmWrapper.find(base: File.join(base, @@variable_files_name), name: file.strip, exts: @@variable_files_exts, description: "Helm values file")
|
67
|
+
|
68
|
+
if @files.include?(path) then
|
69
|
+
logger.warn("Helm variables file is included more than once: #{file.strip}")
|
70
|
+
else
|
71
|
+
@files.append(path)
|
72
|
+
end
|
73
|
+
end
|
30
74
|
end
|
31
75
|
|
32
76
|
###############################################################################
|
33
77
|
|
78
|
+
def add_variables(variables:, sort: false)
|
79
|
+
logger.fatal("Variables provided must be a hash!") unless variables.kind_of?(Hash)
|
80
|
+
|
81
|
+
cleansed = cleanse(variables: variables, reserved: @values.keys)
|
82
|
+
|
83
|
+
begin
|
84
|
+
cleansed = cleansed.map{ |key, value| [ key, value % @identifiers ] }.to_h
|
85
|
+
rescue
|
86
|
+
logger.fatal("Variables contain identifiers that are not included in the configuration file!")
|
87
|
+
end
|
88
|
+
|
89
|
+
merged = @values.merge(cleansed)
|
90
|
+
@values = sort ? merged.sort.to_h : merged
|
91
|
+
end
|
92
|
+
|
93
|
+
###############################################################################
|
94
|
+
|
95
|
+
def clear_files()
|
96
|
+
@files = Array.new
|
97
|
+
end
|
98
|
+
|
99
|
+
###############################################################################
|
100
|
+
|
101
|
+
def clear_variables()
|
102
|
+
@values = @identifers
|
103
|
+
end
|
104
|
+
|
105
|
+
###############################################################################
|
106
|
+
|
34
107
|
private
|
35
108
|
|
36
109
|
###############################################################################
|
37
110
|
|
38
|
-
def cleanse(
|
111
|
+
def cleanse(variables:, reserved:)
|
39
112
|
result = Hash.new
|
40
113
|
|
41
|
-
|
114
|
+
variables.keys.each do |key|
|
42
115
|
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
|
116
|
+
logger.fatal("Could not clean variables hash, key: #{key.downcase} is reserved or already in use and cannot be used!") if reserved.include?(key.downcase.to_sym)
|
44
117
|
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
|
46
|
-
logger.fatal("Could not clean variables hash, value for: #{key.downcase} is empty!") if
|
118
|
+
logger.fatal("Could not clean variables hash, value for: #{key.downcase} is not a string!") unless variables[key].kind_of?(String)
|
119
|
+
logger.fatal("Could not clean variables hash, value for: #{key.downcase} is empty!") if variables[key].strip.empty?
|
47
120
|
|
48
|
-
result[key.downcase.to_sym] =
|
121
|
+
result[key.downcase.to_sym] = variables[key].strip
|
49
122
|
end
|
50
123
|
|
51
124
|
return result
|
data/lib/helm-wrapper/tasks.rb
CHANGED
@@ -7,5 +7,8 @@ require 'rake/tasklib'
|
|
7
7
|
require_relative 'tasks/apply'
|
8
8
|
require_relative 'tasks/binary'
|
9
9
|
require_relative 'tasks/destroy'
|
10
|
+
require_relative 'tasks/push'
|
11
|
+
require_relative 'tasks/template'
|
12
|
+
require_relative 'tasks/validate'
|
10
13
|
|
11
14
|
###############################################################################
|
@@ -45,7 +45,7 @@ module HelmWrapper
|
|
45
45
|
config = HelmWrapper::Shared::Config.new(chart: @chart, options: options)
|
46
46
|
runner = HelmWrapper::Shared::Runner.new(binary: @binary, chart: @chart, config: config)
|
47
47
|
|
48
|
-
logger.info("Running Helm upgrade for
|
48
|
+
logger.info("Running Helm upgrade for release: #{config.release}, namespace: #{config.namespace}...")
|
49
49
|
|
50
50
|
begin
|
51
51
|
runner.init_repos
|
@@ -44,7 +44,7 @@ module HelmWrapper
|
|
44
44
|
config = HelmWrapper::Shared::Config.new(chart: @chart, options: options)
|
45
45
|
runner = HelmWrapper::Shared::Runner.new(binary: @binary, chart: @chart, config: config)
|
46
46
|
|
47
|
-
logger.info("Running Helm delete for
|
47
|
+
logger.info("Running Helm delete for release: #{config.release}, namespace: #{config.namespace}...")
|
48
48
|
|
49
49
|
begin
|
50
50
|
runner.init_auths
|
@@ -0,0 +1,67 @@
|
|
1
|
+
###############################################################################
|
2
|
+
|
3
|
+
module HelmWrapper
|
4
|
+
|
5
|
+
###############################################################################
|
6
|
+
|
7
|
+
module Tasks
|
8
|
+
|
9
|
+
###############################################################################
|
10
|
+
|
11
|
+
class Push < ::Rake::TaskLib
|
12
|
+
|
13
|
+
###############################################################################
|
14
|
+
|
15
|
+
include HelmWrapper::Shared::Logging
|
16
|
+
|
17
|
+
###############################################################################
|
18
|
+
|
19
|
+
@binary
|
20
|
+
@chart
|
21
|
+
|
22
|
+
###############################################################################
|
23
|
+
|
24
|
+
def initialize(binary:, chart:)
|
25
|
+
@binary = binary
|
26
|
+
@chart = chart
|
27
|
+
|
28
|
+
yield self if block_given?
|
29
|
+
|
30
|
+
push_task
|
31
|
+
end
|
32
|
+
|
33
|
+
###############################################################################
|
34
|
+
|
35
|
+
def push_task
|
36
|
+
desc "Pushes a Helm chart to an OCI Helm repository."
|
37
|
+
task :push, [:tag, :clean] => :binary do |t, args|
|
38
|
+
tag = (args[:tag].kind_of?(String) and (not args[:tag].strip.empty?)) ? args[:tag].strip : "latest"
|
39
|
+
clean = args[:clean].kind_of?(String) ? args[:clean].downcase == "true" : true
|
40
|
+
|
41
|
+
runner = HelmWrapper::Shared::Runner.new(binary: @binary, chart: @chart)
|
42
|
+
|
43
|
+
logger.info("Running Helm push for path: #{@chart.path}...")
|
44
|
+
|
45
|
+
begin
|
46
|
+
runner.init_repos
|
47
|
+
runner.save(tag: tag)
|
48
|
+
runner.push(tag: tag)
|
49
|
+
ensure
|
50
|
+
runner.clean(repos: clean)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
###############################################################################
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
###############################################################################
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
###############################################################################
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
###############################################################################
|
@@ -0,0 +1,71 @@
|
|
1
|
+
###############################################################################
|
2
|
+
|
3
|
+
module HelmWrapper
|
4
|
+
|
5
|
+
###############################################################################
|
6
|
+
|
7
|
+
module Tasks
|
8
|
+
|
9
|
+
###############################################################################
|
10
|
+
|
11
|
+
class Template < ::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
|
+
template_task
|
33
|
+
end
|
34
|
+
|
35
|
+
###############################################################################
|
36
|
+
|
37
|
+
def template_task
|
38
|
+
desc "Templates a chart with Helm for a given configuration."
|
39
|
+
task :template, [: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 template...")
|
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 template for release: #{config.release}, namespace: #{config.namespace}...")
|
49
|
+
|
50
|
+
begin
|
51
|
+
runner.init_repos
|
52
|
+
runner.template
|
53
|
+
ensure
|
54
|
+
runner.clean(repos: clean)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
###############################################################################
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
###############################################################################
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
###############################################################################
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
###############################################################################
|
@@ -0,0 +1,58 @@
|
|
1
|
+
###############################################################################
|
2
|
+
|
3
|
+
module HelmWrapper
|
4
|
+
|
5
|
+
###############################################################################
|
6
|
+
|
7
|
+
module Tasks
|
8
|
+
|
9
|
+
###############################################################################
|
10
|
+
|
11
|
+
class Validate < ::Rake::TaskLib
|
12
|
+
|
13
|
+
###############################################################################
|
14
|
+
|
15
|
+
include HelmWrapper::Shared::Logging
|
16
|
+
|
17
|
+
###############################################################################
|
18
|
+
|
19
|
+
@binary
|
20
|
+
@chart
|
21
|
+
|
22
|
+
###############################################################################
|
23
|
+
|
24
|
+
def initialize(binary:, chart:)
|
25
|
+
@binary = binary
|
26
|
+
@chart = chart
|
27
|
+
|
28
|
+
yield self if block_given?
|
29
|
+
|
30
|
+
validate_task
|
31
|
+
end
|
32
|
+
|
33
|
+
###############################################################################
|
34
|
+
|
35
|
+
def validate_task
|
36
|
+
desc "Validates a Helm chart stored locally."
|
37
|
+
task :validate => :binary do |t, args|
|
38
|
+
runner = HelmWrapper::Shared::Runner.new(binary: @binary, chart: @chart)
|
39
|
+
|
40
|
+
logger.info("Running Helm validate for path: #{@chart.path}...")
|
41
|
+
|
42
|
+
runner.lint
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
###############################################################################
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
###############################################################################
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
###############################################################################
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
###############################################################################
|
data/lib/helm-wrapper/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: helm-wrapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Richard Lees
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-03-
|
11
|
+
date: 2021-03-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -58,6 +58,9 @@ files:
|
|
58
58
|
- lib/helm-wrapper/tasks/apply.rb
|
59
59
|
- lib/helm-wrapper/tasks/binary.rb
|
60
60
|
- lib/helm-wrapper/tasks/destroy.rb
|
61
|
+
- lib/helm-wrapper/tasks/push.rb
|
62
|
+
- lib/helm-wrapper/tasks/template.rb
|
63
|
+
- lib/helm-wrapper/tasks/validate.rb
|
61
64
|
- lib/helm-wrapper/version.rb
|
62
65
|
homepage: https://gitlab.com/rlees85-ruby/helm-wrapper/
|
63
66
|
licenses:
|