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,91 @@
1
+ ###############################################################################
2
+
3
+ module HelmWrapper
4
+
5
+ ###############################################################################
6
+
7
+ module Shared
8
+
9
+ ###############################################################################
10
+
11
+ module Auths
12
+
13
+ ###############################################################################
14
+
15
+ class Common
16
+
17
+ ###############################################################################
18
+
19
+ include HelmWrapper::Shared::Logging
20
+
21
+ ###############################################################################
22
+
23
+ @@type
24
+
25
+ ###############################################################################
26
+
27
+ @options
28
+ @variables
29
+
30
+ ###############################################################################
31
+
32
+ def initialize(code:, config:, options:, service:, variables:)
33
+ logger.fatal("This class should not be used directly! Please create an authenticator-specific class instead!")
34
+ end
35
+
36
+ ###############################################################################
37
+
38
+ def auth()
39
+ logger.fatal("The authenticator specific class should override the 'auth' method to complete the authentication process!")
40
+ end
41
+
42
+ ###############################################################################
43
+
44
+ def clear()
45
+ logger.fatal("The authenticator specific class should override the 'auth' method to clear any authentication details!")
46
+ end
47
+
48
+ ###############################################################################
49
+
50
+ def type()
51
+ logger.fatal("The authenticator specific class should set the 'type' class variable to a string!") unless @@type.kind_of?(String)
52
+
53
+ return @@type
54
+ end
55
+
56
+ ###############################################################################
57
+
58
+ private
59
+
60
+ ###############################################################################
61
+
62
+ def construct(options:, variables:)
63
+ @options = options
64
+ @variables = variables
65
+
66
+ specific
67
+ end
68
+
69
+ ###############################################################################
70
+
71
+ def specific()
72
+ logger.fatal("The authenticator specific class should override the 'specific' method to include authenticator specific validation and setup, or simply return 'true' if it is not required.")
73
+ end
74
+
75
+ ###############################################################################
76
+
77
+ end
78
+
79
+ ###############################################################################
80
+
81
+ end
82
+
83
+ ###############################################################################
84
+
85
+ end
86
+
87
+ ###############################################################################
88
+
89
+ end
90
+
91
+ ###############################################################################
@@ -0,0 +1,113 @@
1
+ ###############################################################################
2
+
3
+ module HelmWrapper
4
+
5
+ ###############################################################################
6
+
7
+ module Shared
8
+
9
+ ###############################################################################
10
+
11
+ class Binary
12
+
13
+ ###############################################################################
14
+
15
+ include HelmWrapper::Shared::Logging
16
+
17
+ ###############################################################################
18
+
19
+ attr_accessor :name
20
+
21
+ ###############################################################################
22
+
23
+ attr_reader :base
24
+ attr_reader :directory
25
+ attr_reader :platform
26
+ attr_reader :version
27
+
28
+ ###############################################################################
29
+
30
+ def initialize(options:)
31
+ logger.fatal("Binary base path must be a string!") unless options["base"].kind_of?(String)
32
+ logger.fatal("Binary base path must not be blank!") if options["base"].strip.empty?
33
+
34
+ @base = options["base"]
35
+
36
+ logger.fatal("Binary version must be a string!") unless options["version"].kind_of?(String)
37
+ logger.fatal("Binary version must not be blank!") if options["version"].strip.empty?
38
+
39
+ @version = options["version"]
40
+
41
+ @platform = platform_detect
42
+
43
+ @directory = File.join(@base, @version, @platform)
44
+ @name = "helm"
45
+ end
46
+
47
+ ###############################################################################
48
+
49
+ def check()
50
+ result = false
51
+
52
+ if exists and executable then
53
+ result = system("\"#{path}\" version --short") || false
54
+ end
55
+
56
+ return result
57
+ end
58
+
59
+ ###############################################################################
60
+
61
+ def exists()
62
+ return File.exist?(path)
63
+ end
64
+
65
+ ###############################################################################
66
+
67
+ def executable()
68
+ return File.executable?(path)
69
+ end
70
+
71
+ ###############################################################################
72
+
73
+ def path()
74
+ return File.join(@directory, @name)
75
+ end
76
+
77
+ ###############################################################################
78
+
79
+ private
80
+
81
+ ###############################################################################
82
+
83
+ def platform_detect
84
+ return "darwin" if platform_is_mac
85
+ return "linux" if platform_is_linux
86
+ logger.fatal("Platform is NOT supported: #{RUBY_PLATFORM}")
87
+ end
88
+
89
+ ###############################################################################
90
+
91
+ def platform_is_mac
92
+ RUBY_PLATFORM =~ /darwin/
93
+ end
94
+
95
+ ###############################################################################
96
+
97
+ def platform_is_linux
98
+ RUBY_PLATFORM =~ /linux/
99
+ end
100
+
101
+ ###############################################################################
102
+
103
+ end
104
+
105
+ ###############################################################################
106
+
107
+ end
108
+
109
+ ###############################################################################
110
+
111
+ end
112
+
113
+ ###############################################################################
@@ -0,0 +1,120 @@
1
+ ###############################################################################
2
+
3
+ module HelmWrapper
4
+
5
+ ###############################################################################
6
+
7
+ module Shared
8
+
9
+ ###############################################################################
10
+
11
+ class Chart
12
+
13
+ ###############################################################################
14
+
15
+ include HelmWrapper::Shared::Logging
16
+
17
+ ###############################################################################
18
+
19
+ attr_reader :oci
20
+ attr_reader :name
21
+ attr_reader :artefact
22
+
23
+ ###############################################################################
24
+
25
+ def initialize(options:)
26
+ logger.fatal("Chart name must be a string!") unless options["name"].kind_of?(String)
27
+ logger.fatal("Chart name must not be blank!") if options["name"].strip.empty?
28
+
29
+ @name = options["name"]
30
+
31
+ logger.fatal("Chart repos must be a list of hashes!") unless options["repos"].kind_of?(Array)
32
+
33
+ repos = options["repos"]
34
+
35
+ @oci = Array.new
36
+ @artefact = Array.new
37
+
38
+ repos.each do |repo|
39
+ logger.fatal("All elements of chart repos must be hashes!") unless repo.kind_of?(Hash)
40
+
41
+ logger.fatal("Chart repo: #{hash["name"]} must have a type attribute!") unless repo.key?("type")
42
+ logger.fatal("Chart repo: #{hash["name"]} type must be a string!") unless repo["type"].kind_of?(String)
43
+ logger.fatal("Chart repo: #{hash["name"]} type must either be 'artefact' or 'oci'.") unless [ "artefact", "oci" ].include?(repo["type"])
44
+
45
+ is_artefact = repo["type"] == "artefact" ? true : false
46
+ is_oci = repo["type"] == "oci" ? true : false
47
+
48
+ hash = Hash.new
49
+
50
+ logger.fatal("Chart repos must have a name attribute!") unless repo.key?("name")
51
+ logger.fatal("Chart repo name must be a string!") unless repo["name"].kind_of?(String)
52
+ logger.fatal("Chart repo name must not be blank!") if repo["name"].strip.empty?
53
+
54
+ hash["name"] = repo["name"].strip
55
+
56
+ logger.fatal("Chart repo: #{hash["name"]} must have a url attribute!") unless repo.key?("url")
57
+ logger.fatal("Chart repo: #{hash["name"]} url must be a string!") unless repo["url"].kind_of?(String)
58
+ logger.fatal("Chart repo: #{hash["name"]} url must not be blank!") if repo["url"].strip.empty?
59
+
60
+ hash["url"] = repo["url"].strip
61
+
62
+ if repo.key?("username") then
63
+ logger.fatal("Chart repo: #{hash["name"]} username must be a string!") unless repo["username"].kind_of?(String)
64
+ logger.fatal("Chart repo: #{hash["name"]} username must not be blank!") if repo["username"].strip.empty?
65
+
66
+ repo_username = repo["username"].strip
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
72
+
73
+ logger.fatal("Chart repo: #{hash["name"]} must have a password attribute if 'username' is set!") unless repo.key?("password")
74
+ logger.fatal("Chart repo: #{hash["name"]} password must be a string!") unless repo["password"].kind_of?(String)
75
+ logger.fatal("Chart repo: #{hash["name"]} password must not be blank!") if repo["password"].strip.empty?
76
+
77
+ repo_password = repo["password"].strip
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
83
+ else
84
+ 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
+ hash["username"] = nil
86
+ hash["password"] = nil
87
+ end
88
+
89
+ hash["active"] = false
90
+
91
+ artefact.append(hash) if is_artefact
92
+ oci.append(hash) if is_oci
93
+ end
94
+ end
95
+
96
+ ###############################################################################
97
+
98
+ def artefact_active(active:, index:)
99
+ artefact[index]["active"] = active
100
+ end
101
+
102
+ ###############################################################################
103
+
104
+ def oci_active(active:, index:)
105
+ oci[index]["active"] = active
106
+ end
107
+
108
+ ###############################################################################
109
+
110
+ end
111
+
112
+ ###############################################################################
113
+
114
+ end
115
+
116
+ ###############################################################################
117
+
118
+ end
119
+
120
+ ###############################################################################
@@ -0,0 +1,145 @@
1
+ ###############################################################################
2
+
3
+ require 'yaml'
4
+
5
+ ###############################################################################
6
+
7
+ module HelmWrapper
8
+
9
+ ###############################################################################
10
+
11
+ module Shared
12
+
13
+ ###############################################################################
14
+
15
+ class Config
16
+
17
+ ###############################################################################
18
+
19
+ include HelmWrapper::Shared::Logging
20
+
21
+ ###############################################################################
22
+
23
+ @@config_exts = [ "", ".yaml", ".yml" ]
24
+
25
+ ###############################################################################
26
+
27
+ @@variable_files_name = "helmvars"
28
+ @@variable_files_exts = [ ".yaml", ".yml" ]
29
+
30
+ ###############################################################################
31
+
32
+ attr_reader :auths
33
+ attr_reader :base
34
+ attr_reader :chart
35
+ attr_reader :name
36
+ attr_reader :namespace
37
+ attr_reader :path
38
+ attr_reader :release
39
+ attr_reader :variable_files
40
+ attr_reader :variables
41
+
42
+ ###############################################################################
43
+
44
+ def initialize(chart:, options:)
45
+ logger.fatal("Configuration base path must be a string!") unless options["base"].kind_of?(String)
46
+ logger.fatal("Configuration base path must not be blank!") if options["base"].strip.empty?
47
+
48
+ @base = options["base"]
49
+
50
+ logger.fatal("Configuration name must be a string!") unless options["name"].kind_of?(String)
51
+ logger.fatal("Configuration name must not be blank!") if options["name"].strip.empty?
52
+
53
+ @name = options["name"]
54
+
55
+ logger.fatal("Configuration destination namespace must be a string!") unless options["namespace"].kind_of?(String)
56
+ logger.fatal("Configuration destination namespace must not be blank!") if options["namespace"].strip.empty?
57
+
58
+ namespace = options["namespace"]
59
+
60
+ logger.fatal("Configuration release name must be a string!") unless options["release"].kind_of?(String)
61
+ logger.fatal("Configuration release name must not be blank!") if options["release"].strip.empty?
62
+
63
+ release = options["release"]
64
+
65
+ logger.fatal("Configuration authenticator for Azure enabled must be a Boolean!") unless [ true, false ].include?(options["auth-azure"])
66
+
67
+ auth_azure = options["auth-azure"]
68
+
69
+ logger.fatal("Configuration authenticator for Azure options must be a Hash!") unless options["auth-azure-options"].kind_of?(Hash)
70
+
71
+ auth_azure_options = options["auth-azure-options"]
72
+
73
+ @chart = chart
74
+ @path = find(base: @base, name: @name, exts: @@config_exts, description: "Configuration")
75
+
76
+ yaml = YAML.load(File.read(@path))
77
+ logger.fatal("Invalid YAML in configuration file: #{@path}") unless yaml.kind_of?(Hash)
78
+
79
+ if yaml.key?("variables") then
80
+ logger.fatal("Key 'variables' is not a hash in configuration file: #{@path}") unless yaml["variables"].kind_of?(Hash)
81
+ @variables = HelmWrapper::Shared::Variables.new(values: yaml["variables"])
82
+ else
83
+ @variables = HelmWrapper::Shared::Variables.new()
84
+ end
85
+
86
+ @variable_files = yaml.key?("helm") ? validate(variable_files: yaml["helm"]) : Array.new
87
+
88
+ begin
89
+ namespace = namespace % @variables.values
90
+ release = release % @variables.values
91
+ rescue
92
+ logger.fatal("Provided configuration options contain variables that are not included in the configuration file!")
93
+ end
94
+
95
+ @namespace = namespace
96
+ @release = release
97
+
98
+ @auths = Array.new
99
+ @auths.append(HelmWrapper::Shared::Auths::Azure.new(options: auth_azure_options, variables: @variables)) if auth_azure
100
+ end
101
+
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
+ ###############################################################################
134
+
135
+ end
136
+
137
+ ###############################################################################
138
+
139
+ end
140
+
141
+ ###############################################################################
142
+
143
+ end
144
+
145
+ ###############################################################################