kube_deploy_tools 3.0.5
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 +7 -0
- data/LICENSE.txt +177 -0
- data/README.md +142 -0
- data/bin/deploy +60 -0
- data/bin/generate +28 -0
- data/bin/kdt +17 -0
- data/bin/make_configmap +20 -0
- data/bin/publish +28 -0
- data/bin/push +57 -0
- data/bin/render_deploys_hook +18 -0
- data/bin/templater +34 -0
- data/bin/upgrade +23 -0
- data/lib/kube_deploy_tools.rb +17 -0
- data/lib/kube_deploy_tools/artifact_registry.rb +30 -0
- data/lib/kube_deploy_tools/artifact_registry/driver.rb +13 -0
- data/lib/kube_deploy_tools/artifact_registry/driver_artifactory.rb +155 -0
- data/lib/kube_deploy_tools/artifact_registry/driver_base.rb +37 -0
- data/lib/kube_deploy_tools/artifact_registry/driver_gcs.rb +120 -0
- data/lib/kube_deploy_tools/built_artifacts_file.rb +28 -0
- data/lib/kube_deploy_tools/concurrency.rb +18 -0
- data/lib/kube_deploy_tools/deferred_summary_logging.rb +69 -0
- data/lib/kube_deploy_tools/deploy.rb +215 -0
- data/lib/kube_deploy_tools/deploy/options.rb +114 -0
- data/lib/kube_deploy_tools/deploy_config_file.rb +286 -0
- data/lib/kube_deploy_tools/deploy_config_file/deep_merge.rb +38 -0
- data/lib/kube_deploy_tools/deploy_config_file/util.rb +39 -0
- data/lib/kube_deploy_tools/errors.rb +5 -0
- data/lib/kube_deploy_tools/file_filter.rb +43 -0
- data/lib/kube_deploy_tools/formatted_logger.rb +59 -0
- data/lib/kube_deploy_tools/generate.rb +145 -0
- data/lib/kube_deploy_tools/generate/options.rb +66 -0
- data/lib/kube_deploy_tools/image_registry.rb +30 -0
- data/lib/kube_deploy_tools/image_registry/driver.rb +18 -0
- data/lib/kube_deploy_tools/image_registry/driver/aws.rb +121 -0
- data/lib/kube_deploy_tools/image_registry/driver/base.rb +50 -0
- data/lib/kube_deploy_tools/image_registry/driver/gcp.rb +71 -0
- data/lib/kube_deploy_tools/image_registry/driver/login.rb +26 -0
- data/lib/kube_deploy_tools/image_registry/driver/noop.rb +15 -0
- data/lib/kube_deploy_tools/image_registry/image.rb +17 -0
- data/lib/kube_deploy_tools/kdt.rb +52 -0
- data/lib/kube_deploy_tools/kubectl.rb +25 -0
- data/lib/kube_deploy_tools/kubernetes_resource.rb +57 -0
- data/lib/kube_deploy_tools/kubernetes_resource/deployment.rb +56 -0
- data/lib/kube_deploy_tools/make_configmap.rb +51 -0
- data/lib/kube_deploy_tools/make_configmap/options.rb +39 -0
- data/lib/kube_deploy_tools/object.rb +11 -0
- data/lib/kube_deploy_tools/publish.rb +40 -0
- data/lib/kube_deploy_tools/publish/options.rb +34 -0
- data/lib/kube_deploy_tools/push.rb +129 -0
- data/lib/kube_deploy_tools/push/options.rb +46 -0
- data/lib/kube_deploy_tools/render_deploys_hook.rb +95 -0
- data/lib/kube_deploy_tools/shellrunner.rb +46 -0
- data/lib/kube_deploy_tools/tag.rb +33 -0
- data/lib/kube_deploy_tools/templater.rb +63 -0
- data/lib/kube_deploy_tools/templater/options.rb +74 -0
- data/lib/kube_deploy_tools/version.rb +3 -0
- metadata +191 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
# Downloaded from
|
2
|
+
# https://raw.githubusercontent.com/rails/rails/v6.0.2.2/activesupport/lib/active_support/core_ext/hash/deep_merge.rb
|
3
|
+
# to avoid a dependency on activesupport.
|
4
|
+
|
5
|
+
# frozen_string_literal: true
|
6
|
+
|
7
|
+
class Hash
|
8
|
+
# Returns a new hash with +self+ and +other_hash+ merged recursively.
|
9
|
+
#
|
10
|
+
# h1 = { a: true, b: { c: [1, 2, 3] } }
|
11
|
+
# h2 = { a: false, b: { x: [3, 4, 5] } }
|
12
|
+
#
|
13
|
+
# h1.deep_merge(h2) # => { a: false, b: { c: [1, 2, 3], x: [3, 4, 5] } }
|
14
|
+
#
|
15
|
+
# Like with Hash#merge in the standard library, a block can be provided
|
16
|
+
# to merge values:
|
17
|
+
#
|
18
|
+
# h1 = { a: 100, b: 200, c: { c1: 100 } }
|
19
|
+
# h2 = { b: 250, c: { c1: 200 } }
|
20
|
+
# h1.deep_merge(h2) { |key, this_val, other_val| this_val + other_val }
|
21
|
+
# # => { a: 100, b: 450, c: { c1: 300 } }
|
22
|
+
def deep_merge(other_hash, &block)
|
23
|
+
dup.deep_merge!(other_hash, &block)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Same as +deep_merge+, but modifies +self+.
|
27
|
+
def deep_merge!(other_hash, &block)
|
28
|
+
merge!(other_hash) do |key, this_val, other_val|
|
29
|
+
if this_val.is_a?(Hash) && other_val.is_a?(Hash)
|
30
|
+
this_val.deep_merge(other_val, &block)
|
31
|
+
elsif block_given?
|
32
|
+
block.call(key, this_val, other_val)
|
33
|
+
else
|
34
|
+
other_val
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
|
2
|
+
module KubeDeployTools
|
3
|
+
module DeployConfigFileUtil
|
4
|
+
def check_and_err(condition, error)
|
5
|
+
if ! condition
|
6
|
+
Logger.error("Error in configuration #{@filename}")
|
7
|
+
raise ArgumentError, error
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def check_and_warn(condition, warning)
|
12
|
+
if ! condition
|
13
|
+
Logger.warn("Warning in configuration #{@filename}")
|
14
|
+
Logger.warn(warning)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def load_library(lib)
|
19
|
+
# All paths must be valid accessible gcs paths for the current user.
|
20
|
+
# To modify gcloud identity being used by this process, set
|
21
|
+
# GOOGLE_APPLICATION_CREDENTIALS or sign in with `gcloud auth login`
|
22
|
+
lib_config = nil
|
23
|
+
if lib.start_with?('gs://')
|
24
|
+
Tempfile.open(['gs-kdt-library', '.yaml']) do |t|
|
25
|
+
out = Shellrunner.check_call('gsutil', 'cat', lib)
|
26
|
+
t.write(out)
|
27
|
+
t.flush
|
28
|
+
lib_config = DeployConfigFile.new(t.path)
|
29
|
+
end
|
30
|
+
elsif File.exist?(lib)
|
31
|
+
lib_config = DeployConfigFile.new(lib)
|
32
|
+
else
|
33
|
+
raise "Unsupported or non-existent library: #{lib}"
|
34
|
+
end
|
35
|
+
|
36
|
+
lib_config
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'kube_deploy_tools/formatted_logger'
|
2
|
+
|
3
|
+
# frozen_string_literal: true
|
4
|
+
module KubeDeployTools
|
5
|
+
module FileFilter
|
6
|
+
VALID_FILTER_NAMES = %w(include_dir exclude_dir)
|
7
|
+
|
8
|
+
def self.filter_files(filters:, files_path:)
|
9
|
+
all_files = Dir[File.join(files_path, '**', '*')].to_set
|
10
|
+
filtered_files = if filters.any? { |k, _| k =~ /include_/ }
|
11
|
+
Set.new
|
12
|
+
else
|
13
|
+
Set.new(all_files)
|
14
|
+
end
|
15
|
+
|
16
|
+
filters.each do |action, globpath|
|
17
|
+
if action =~ /_dir$/
|
18
|
+
# ensure globpath correctly selects an entire dir recursively
|
19
|
+
# always starts with files_path
|
20
|
+
# always ends with /**/* (to recusively select entire dir)
|
21
|
+
globpath = File.join(files_path, globpath.gsub(/^[\/*]+|[\/*]+$/, ""), '**', '*')
|
22
|
+
end
|
23
|
+
|
24
|
+
case action
|
25
|
+
when /^include_(files|dir)$/
|
26
|
+
filtered_files.merge( all_files.select{ |f| File.fnmatch?(globpath, f, File::FNM_PATHNAME) } )
|
27
|
+
when /^exclude_(files|dir)$/
|
28
|
+
filtered_files.reject!{ |f| File.fnmatch?(globpath, f, File::FNM_PATHNAME) }
|
29
|
+
else
|
30
|
+
raise "you want to #{action}: wat do"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
Logger.debug("\nYour filter generates following paths: \n#{filtered_files.to_a.join("\n")}")
|
34
|
+
filtered_files
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.filters_from_hash(h)
|
38
|
+
VALID_FILTER_NAMES.flat_map do |filter_name|
|
39
|
+
Array(h[filter_name]).map { |dir_path| [filter_name, dir_path] }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
require 'colorized_string'
|
5
|
+
|
6
|
+
require 'kube_deploy_tools/deferred_summary_logging'
|
7
|
+
|
8
|
+
module KubeDeployTools
|
9
|
+
class FormattedLogger < ::Logger
|
10
|
+
include DeferredSummaryLogging
|
11
|
+
|
12
|
+
def self.build(context: nil, namespace: nil, stream: $stderr)
|
13
|
+
l = new(stream)
|
14
|
+
l.level = level_from_env
|
15
|
+
|
16
|
+
l.formatter = proc do |severity, datetime, _progname, msg|
|
17
|
+
middle = context ? "[#{context}]" : ""
|
18
|
+
if ! namespace.nil? && namespace != 'default'
|
19
|
+
middle += "[#{namespace}]"
|
20
|
+
end
|
21
|
+
|
22
|
+
dt = datetime.strftime('%F %T')
|
23
|
+
colorized_line = ColorizedString.new("[#{severity}][#{dt}]#{middle} #{msg}\n")
|
24
|
+
|
25
|
+
case severity
|
26
|
+
when "FATAL"
|
27
|
+
ColorizedString.new("[#{severity}][#{dt}]#{middle} ").red + "#{msg}\n"
|
28
|
+
when "ERROR"
|
29
|
+
colorized_line.red
|
30
|
+
when "WARN"
|
31
|
+
colorized_line.yellow
|
32
|
+
else
|
33
|
+
colorized_line
|
34
|
+
end
|
35
|
+
end
|
36
|
+
l
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.level_from_env
|
40
|
+
return ::Logger::DEBUG if ENV["DEBUG"]
|
41
|
+
|
42
|
+
if ENV["LEVEL"]
|
43
|
+
::Logger.const_get(ENV["LEVEL"].upcase)
|
44
|
+
else
|
45
|
+
::Logger::INFO
|
46
|
+
end
|
47
|
+
end
|
48
|
+
private_class_method :level_from_env
|
49
|
+
end
|
50
|
+
|
51
|
+
class Logger
|
52
|
+
class << self
|
53
|
+
extend Forwardable
|
54
|
+
|
55
|
+
attr_accessor :logger
|
56
|
+
def_delegators :@logger, *(::Logger.public_instance_methods(false) + DeferredSummaryLogging.public_instance_methods(false))
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'tempfile'
|
4
|
+
require 'time'
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
require 'kube_deploy_tools/render_deploys_hook'
|
8
|
+
require 'kube_deploy_tools/deploy_config_file'
|
9
|
+
require 'kube_deploy_tools/file_filter'
|
10
|
+
require 'kube_deploy_tools/shellrunner'
|
11
|
+
require 'kube_deploy_tools/tag'
|
12
|
+
|
13
|
+
DEFAULT_HOOK_SCRIPT = 'render_deploys_hook'
|
14
|
+
DEFAULT_HOOK_SCRIPT_LABEL = 'default'
|
15
|
+
|
16
|
+
module KubeDeployTools
|
17
|
+
DEFAULT_FLAGS = {
|
18
|
+
'image_tag' => tag_from_local_env,
|
19
|
+
'tag' => tag_from_local_env,
|
20
|
+
}.freeze
|
21
|
+
class Generate
|
22
|
+
def initialize(manifest, input_dir, output_dir, file_filters: [], print_flags_only: false, literals: {})
|
23
|
+
@project = KubeDeployTools::PROJECT
|
24
|
+
@build_number = KubeDeployTools::BUILD_NUMBER
|
25
|
+
|
26
|
+
@config = DeployConfigFile.new(manifest)
|
27
|
+
@literals = literals
|
28
|
+
|
29
|
+
@input_dir = input_dir
|
30
|
+
@output_dir = output_dir
|
31
|
+
FileUtils.mkdir_p @output_dir
|
32
|
+
|
33
|
+
@file_filters = file_filters
|
34
|
+
|
35
|
+
@print_flags_only = print_flags_only
|
36
|
+
end
|
37
|
+
|
38
|
+
def git_commit
|
39
|
+
commit_sha = Shellrunner.check_call(*%w(git rev-parse HEAD))
|
40
|
+
commit_sha ? commit_sha.strip : ''
|
41
|
+
end
|
42
|
+
|
43
|
+
def git_project
|
44
|
+
project_url = Shellrunner.check_call(*%w(git config --get remote.origin.url))
|
45
|
+
project_url ? project_url.strip : ''
|
46
|
+
end
|
47
|
+
|
48
|
+
def generate
|
49
|
+
permutations = {}
|
50
|
+
@config.artifacts.each do |c|
|
51
|
+
artifact = c.fetch('name')
|
52
|
+
|
53
|
+
# Get metadata for this target/environment pair from manifest
|
54
|
+
cluster_flags = DEFAULT_FLAGS.dup
|
55
|
+
|
56
|
+
cluster_flags['image_registry'] = c.fetch('image_registry')
|
57
|
+
|
58
|
+
# Merge in configured default flags
|
59
|
+
cluster_flags.merge!(@config.default_flags)
|
60
|
+
|
61
|
+
# Update and merge deploy flags for rendering
|
62
|
+
cluster_flags.merge!(generate_erb_flags(c.fetch('flags', {})))
|
63
|
+
|
64
|
+
cluster_flags['image_registry'] = @config.valid_image_registries[cluster_flags['image_registry']]
|
65
|
+
# Allow deploy.yaml to gate certain flavors to certain targets.
|
66
|
+
cluster_flavors = @config.flavors.select { |key, value| c['flavors'].nil? || c['flavors'].include?(key) }
|
67
|
+
cluster_flavors.each do |flavor, flavor_flags|
|
68
|
+
full_flags = cluster_flags.clone
|
69
|
+
full_flags.merge!(generate_erb_flags(flavor_flags)) if flavor_flags
|
70
|
+
# Project information used to identify source of various manifests
|
71
|
+
full_flags.merge!({
|
72
|
+
'git_commit' => git_commit,
|
73
|
+
'git_project' => git_project
|
74
|
+
})
|
75
|
+
|
76
|
+
full_flags.merge!(@literals)
|
77
|
+
|
78
|
+
# Print all flags for each artifact-flavor
|
79
|
+
puts "artifact '#{artifact}', flavor '#{flavor}'"
|
80
|
+
full_flags.
|
81
|
+
sort_by { |k, v| k }.
|
82
|
+
each do |k, v|
|
83
|
+
puts "config['#{k}'] = #{v}"
|
84
|
+
end
|
85
|
+
puts ""
|
86
|
+
# Skip rendering ERB templates and generating artifacts
|
87
|
+
# if printing flags only
|
88
|
+
next if @print_flags_only
|
89
|
+
|
90
|
+
file_filters = FileFilter.filters_from_hash(c) + @file_filters
|
91
|
+
|
92
|
+
# Call individual templating hook with the rendered configuration
|
93
|
+
# and a prefix to place all the files. Run many hooks in the
|
94
|
+
# background.
|
95
|
+
flavor_dir = File.join(@output_dir, "#{artifact}_#{flavor}")
|
96
|
+
FileUtils.rm_rf flavor_dir
|
97
|
+
FileUtils.mkdir_p flavor_dir
|
98
|
+
pid = fork do
|
99
|
+
# Save rendered release configuration to a temp file.
|
100
|
+
rendered = Tempfile.new('deploy_config')
|
101
|
+
rendered << YAML.dump(full_flags)
|
102
|
+
rendered.flush
|
103
|
+
|
104
|
+
# Run every hook sequentially. 'default' hook is special.
|
105
|
+
@config.hooks.each do |hook|
|
106
|
+
if hook == DEFAULT_HOOK_SCRIPT_LABEL
|
107
|
+
# TODO(joshk): render_deploys method should take a hash for testability
|
108
|
+
KubeDeployTools::RenderDeploysHook.render_deploys(rendered.path, @input_dir, flavor_dir, file_filters)
|
109
|
+
else
|
110
|
+
Shellrunner.check_call(hook, rendered.path, @input_dir, flavor_dir)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
permutations[pid] = "#{artifact}_#{flavor}"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
failure = false
|
120
|
+
Process.waitall.each do |pid, status|
|
121
|
+
if status.exitstatus != 0
|
122
|
+
Logger.error "Rendering #{permutations[pid]} failed: exit status #{status.exitstatus}"
|
123
|
+
failure = true
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
raise 'rendering deploy configurations failed' if failure
|
128
|
+
end
|
129
|
+
|
130
|
+
def generate_erb_flags(flags)
|
131
|
+
result = Hash.new
|
132
|
+
|
133
|
+
flags.each do |key, template|
|
134
|
+
if template.is_a?(String)
|
135
|
+
templater = ERB.new(template)
|
136
|
+
result[key] = templater.result
|
137
|
+
else
|
138
|
+
result[key] = template
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
result
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module KubeDeployTools
|
4
|
+
class Generate::Optparser
|
5
|
+
class Options
|
6
|
+
attr_accessor :manifest_file, :input_path, :output_path, :file_filters, :print_flags_only, :literals
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
self.input_path = File.join('kubernetes/')
|
10
|
+
self.output_path = File.join('build', 'kubernetes')
|
11
|
+
self.file_filters = []
|
12
|
+
self.literals = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def define_options(parser)
|
16
|
+
parser.on('-mMANIFEST', '--manifest MANIFEST', 'The configuration MANIFEST to render deploys with.') do |f|
|
17
|
+
self.manifest_file = f
|
18
|
+
end
|
19
|
+
|
20
|
+
parser.on('-iPATH', '--input-path PATH', 'Path where Kubernetes manifests and manifest templates (.erb) are located.') do |p|
|
21
|
+
self.input_path = p
|
22
|
+
end
|
23
|
+
|
24
|
+
parser.on('-oPATH', '--output-path PATH', 'Path where rendered manifests should be written.') do |p|
|
25
|
+
self.output_path = p
|
26
|
+
end
|
27
|
+
|
28
|
+
parser.on('-p', '--print', 'Print all available ERB config values only.') do |p|
|
29
|
+
self.print_flags_only = p
|
30
|
+
end
|
31
|
+
|
32
|
+
parser.on('--from-literal KEY=VALUE', "Specify a key and literal value in the ERB context e.g. mykey=myvalue") do |p|
|
33
|
+
parts = p.split('=')
|
34
|
+
raise ArgumentError, "Expected --from-literal to be in the format key=value, but got '#{p}'" if parts.length != 2
|
35
|
+
key, value = parts
|
36
|
+
self.literals[key] = value
|
37
|
+
end
|
38
|
+
|
39
|
+
parser.on('--include INCLUDE', "Include glob pattern. Example: --include=**/* will include every file. Default is ''.") do |p|
|
40
|
+
self.file_filters.push(["include_files", p])
|
41
|
+
end
|
42
|
+
|
43
|
+
parser.on('--exclude EXCLUDE', "Exclude glob pattern. Example: --exclude=**/gazette/* will exclude every file in gazette folder. Default is ''.") do |p|
|
44
|
+
self.file_filters.push(["exclude_files", p])
|
45
|
+
end
|
46
|
+
|
47
|
+
parser.on('--include-dir INCLUDE', "Recursively include all files in a directory and its subdirectories. Example: --include-dir=gazette/ (equivalent of --include=**/gazette/**/*)") do |p|
|
48
|
+
self.file_filters.push(["include_dir", p])
|
49
|
+
end
|
50
|
+
|
51
|
+
parser.on('--exclude-dir EXCLUDE', "Recursively exclude all files in a directory and its subdirectories. Example: --exclude-dir=gazette/ (equivalent of --exclude=**/gazette/**/*)") do |p|
|
52
|
+
self.file_filters.push(["exclude_dir", p])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def parse(args)
|
58
|
+
@options = Options.new
|
59
|
+
OptionParser.new do |parser|
|
60
|
+
@options.define_options(parser)
|
61
|
+
parser.parse(args)
|
62
|
+
end
|
63
|
+
@options
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module KubeDeployTools
|
2
|
+
# Read-only model for image_registries[] array element in KDT deploy.yaml
|
3
|
+
# configuration file.
|
4
|
+
class ImageRegistry
|
5
|
+
attr_accessor :name, :driver, :prefix, :config
|
6
|
+
|
7
|
+
def initialize(h)
|
8
|
+
@name = h['name']
|
9
|
+
@driver = h['driver']
|
10
|
+
@prefix = h['prefix']
|
11
|
+
@config = h['config']
|
12
|
+
end
|
13
|
+
|
14
|
+
def ==(o)
|
15
|
+
@name == o.name
|
16
|
+
@driver == o.driver
|
17
|
+
@prefix == o.prefix
|
18
|
+
@config == o.config
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_h
|
22
|
+
{
|
23
|
+
'name' => @name,
|
24
|
+
'driver' => @driver,
|
25
|
+
'prefix' => @prefix,
|
26
|
+
'config' => @config,
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative 'driver/base'
|
2
|
+
require_relative 'driver/aws'
|
3
|
+
require_relative 'driver/gcp'
|
4
|
+
require_relative 'driver/login'
|
5
|
+
require_relative 'driver/noop'
|
6
|
+
|
7
|
+
module KubeDeployTools
|
8
|
+
class ImageRegistry
|
9
|
+
module Driver
|
10
|
+
MAPPINGS = {
|
11
|
+
'aws' => Aws,
|
12
|
+
'gcp' => Gcp,
|
13
|
+
'login' => Login,
|
14
|
+
'noop' => Noop
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|