Class: KubeDeployTools::DeployConfigFile
- Includes:
- DeployConfigFileUtil
- Defined in:
- lib/kube_deploy_tools/deploy_config_file.rb
Overview
Read-only model for the deploy.yaml configuration file.
Instance Attribute Summary collapse
-
#artifact_registries ⇒ Object
Returns the value of attribute artifact_registries.
-
#artifact_registry ⇒ Object
Returns the value of attribute artifact_registry.
-
#artifacts ⇒ Object
Returns the value of attribute artifacts.
-
#default_flags ⇒ Object
Returns the value of attribute default_flags.
-
#expiration ⇒ Object
Returns the value of attribute expiration.
-
#flavors ⇒ Object
Returns the value of attribute flavors.
-
#hooks ⇒ Object
Returns the value of attribute hooks.
-
#image_registries ⇒ Object
Returns the value of attribute image_registries.
-
#valid_image_registries ⇒ Object
Returns the value of attribute valid_image_registries.
Class Method Summary collapse
Instance Method Summary collapse
-
#extend!(other) ⇒ Object
Extend this DeployConfigFile with another instance.
- #fetch_and_parse_version2_config! ⇒ Object
-
#initialize(filename) ⇒ DeployConfigFile
constructor
TODO(joshk): Refactor into initialize(fp) which takes a file-like object; after this, auto discovery should go into DeployConfigFile.locate classmethod.
- #map_image_registry(image_registries) ⇒ Object
- #parse_artifact_registries(artifact_registries) ⇒ Object
- #parse_artifact_registry(artifact_registry, artifact_registries) ⇒ Object
- #parse_image_registries(image_registries) ⇒ Object
- #select_duplicates(array) ⇒ Object
- #to_h ⇒ Object
-
#upgrade! ⇒ Object
upgrade! converts the config to a YAML string in the format of the latest supported version e.g.
-
#validate_artifacts! ⇒ Object
.artifacts depends on .default_flags and .image_registries.
- #validate_default_flags ⇒ Object
- #validate_expiration ⇒ Object
- #validate_flavors ⇒ Object
- #validate_hooks ⇒ Object
Methods included from DeployConfigFileUtil
#check_and_err, #check_and_warn, #load_library
Constructor Details
#initialize(filename) ⇒ DeployConfigFile
TODO(joshk): Refactor into initialize(fp) which takes a file-like object; after this, auto discovery should go into DeployConfigFile.locate classmethod. This would require erasing auto-upgrade capability, which should be possible if we major version bump.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/kube_deploy_tools/deploy_config_file.rb', line 28 def initialize(filename) config = nil if !filename.nil? && Pathname.new(filename).absolute? config = YAML.load_file(filename) else original_dir = Dir.pwd changed_dir = false until Dir.pwd == '/' # Try looking for filename specified by user. # If no filename was specified by the user, then look for # deploy.yml or deploy.yaml. if !filename.nil? && File.exist?(filename) config = YAML.load_file(filename) break elsif filename.nil? && File.exist?(DEPLOY_YAML) filename = DEPLOY_YAML config = YAML.load_file(filename) break end # KDT should run in the directory containing the deploy config file. changed_dir = true Dir.chdir('..') end if config.nil? Dir.chdir(original_dir) if ! filename.nil? raise "Could not locate file: config file '#{filename}' in any directory" else raise "Could not locate file: config file '#{DEPLOY_YAML}' in any directory" end end if changed_dir Logger.warn "Changed directory to #{Dir.pwd} (location of #{filename})" end end @filename = filename @original_config = config version = config.fetch('version', 1) check_and_warn( config.has_key?('version'), 'Expected .version to be specified, but .version is missing. Falling back to version 1 config schema') check_and_err([1, 2].include?(version), "Expected valid version, but received unsupported version '#{version}'") case version when 2 fetch_and_parse_version2_config! else raise "Unsupported version #{version}" end end |
Instance Attribute Details
#artifact_registries ⇒ Object
Returns the value of attribute artifact_registries.
20 21 22 |
# File 'lib/kube_deploy_tools/deploy_config_file.rb', line 20 def artifact_registries @artifact_registries end |
#artifact_registry ⇒ Object
Returns the value of attribute artifact_registry.
20 21 22 |
# File 'lib/kube_deploy_tools/deploy_config_file.rb', line 20 def artifact_registry @artifact_registry end |
#artifacts ⇒ Object
Returns the value of attribute artifacts.
20 21 22 |
# File 'lib/kube_deploy_tools/deploy_config_file.rb', line 20 def artifacts @artifacts end |
#default_flags ⇒ Object
Returns the value of attribute default_flags.
20 21 22 |
# File 'lib/kube_deploy_tools/deploy_config_file.rb', line 20 def default_flags @default_flags end |
#expiration ⇒ Object
Returns the value of attribute expiration.
20 21 22 |
# File 'lib/kube_deploy_tools/deploy_config_file.rb', line 20 def expiration @expiration end |
#flavors ⇒ Object
Returns the value of attribute flavors.
20 21 22 |
# File 'lib/kube_deploy_tools/deploy_config_file.rb', line 20 def flavors @flavors end |
#hooks ⇒ Object
Returns the value of attribute hooks.
20 21 22 |
# File 'lib/kube_deploy_tools/deploy_config_file.rb', line 20 def hooks @hooks end |
#image_registries ⇒ Object
Returns the value of attribute image_registries.
20 21 22 |
# File 'lib/kube_deploy_tools/deploy_config_file.rb', line 20 def image_registries @image_registries end |
#valid_image_registries ⇒ Object
Returns the value of attribute valid_image_registries.
20 21 22 |
# File 'lib/kube_deploy_tools/deploy_config_file.rb', line 20 def valid_image_registries @valid_image_registries end |
Class Method Details
.deep_merge(h, other) ⇒ Object
282 283 284 |
# File 'lib/kube_deploy_tools/deploy_config_file.rb', line 282 def self.deep_merge(h, other) end |
Instance Method Details
#extend!(other) ⇒ Object
Extend this DeployConfigFile with another instance.
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 |
# File 'lib/kube_deploy_tools/deploy_config_file.rb', line 245 def extend!(other) # Any image_registries entry in |self| should take precedence # over any identical key in |other|. The behavior of merge is that # the 'other' hash wins. @image_registries = other.image_registries.merge(@image_registries) # Same behavior as above for #default_flags. @default_flags = other.default_flags.merge(@default_flags) # artifacts should be merged by 'name'. In other words, if |self| and |other| # specify the same 'name' of a registry, self's config for that registry # should win wholesale (no merging of flags.) @artifacts = (@artifacts + other.artifacts).uniq { |h| h.fetch('name') } # Same behavior as for flags and registries, but the flags within the flavor # are in a Hash, so we need a deep merge. @flavors = other.flavors.deep_merge(@flavors) # A break from the preceding merging logic - Dependent hooks have to come # first and a given named hook can only be run once. But seriously, you # probably don't want to make a library that specifies hooks. @hooks = (other.hooks + @hooks).uniq @expiration = (@expiration + other.expiration).uniq { |h| h.fetch('repository') } end |
#fetch_and_parse_version2_config! ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/kube_deploy_tools/deploy_config_file.rb', line 81 def fetch_and_parse_version2_config! # The literal contents of your deploy.yaml are now populated into |self|. config = @original_config @image_registries = parse_image_registries(config.fetch('image_registries', [])) @default_flags = config.fetch('default_flags', {}) @artifacts = config.fetch('artifacts', []) @flavors = config.fetch('flavors', {}) @hooks = config.fetch('hooks', ['default']) @expiration = config.fetch('expiration', []) @artifact_registries = parse_artifact_registries(config.fetch('artifact_registries', [])) @artifact_registry = parse_artifact_registry(config.fetch('artifact_registry', ''), @artifact_registries) validate_default_flags validate_flavors validate_hooks validate_expiration # Augment these literal contents by resolving all libraries. # extend! typically gives the current file precedence when merge conflicts occur, # but the expected precedence of library inclusion is the reverse (library 2 should # overwrite what library 1 specifies), so reverse the libraries list first. config.fetch('libraries', []).reverse.each do |libfn| extend!(load_library(libfn)) end # Now that we have a complete list of image registries, validation is now possible. # Note that this also populates @valid_image_registries. validate_artifacts! end |
#map_image_registry(image_registries) ⇒ Object
127 128 129 130 131 132 133 |
# File 'lib/kube_deploy_tools/deploy_config_file.rb', line 127 def map_image_registry(image_registries) valid_image_registries = {} image_registries.each do |reg_name, reg_info| valid_image_registries[reg_name] = reg_info.prefix end valid_image_registries end |
#parse_artifact_registries(artifact_registries) ⇒ Object
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/kube_deploy_tools/deploy_config_file.rb', line 187 def parse_artifact_registries(artifact_registries) check_and_err(artifact_registries.is_a?(Array), '.artifact_registries is not an Array') artifact_registries = artifact_registries.map { |r| ArtifactRegistry.new(r) } # Validate that each artifact registry is named uniquely duplicates = select_duplicates(artifact_registries.map { |r| r.name }) check_and_err( duplicates.count == 0, "Expected .artifact_registries names to be unique, but found duplicates: #{duplicates}" ) unsupported_drivers = artifact_registries. select { |r| !ArtifactRegistry::Driver::MAPPINGS.key? r.driver_name }. map { |r| r.driver_name } check_and_err( unsupported_drivers.count == 0, "Expected .artifact_registries drivers to be valid, but found unsupported drivers: #{unsupported_drivers}. Must be a driver in: #{ArtifactRegistry::Driver::MAPPINGS.keys}", ) artifact_registries .select { |r| r.driver_name == "gcs" } .select { |r| !r.config.has_key? "bucket" } .each { |r| check_and_err(false, "Expected .artifact_registries['#{r.config.name}'].config.bucket to exist, but no GCS bucket is specified") } artifact_registries .map { |r| [r.name, r] } .to_h end |
#parse_artifact_registry(artifact_registry, artifact_registries) ⇒ Object
217 218 219 220 221 222 223 224 225 |
# File 'lib/kube_deploy_tools/deploy_config_file.rb', line 217 def parse_artifact_registry(artifact_registry, artifact_registries) check_and_err(artifact_registry.is_a?(String), '.artifact_registry is not a String') check_and_err( artifact_registry.empty? || artifact_registries.key?(artifact_registry), "#{artifact_registry} is not a valid Artifact Registry. Has to be one of #{artifact_registries.keys}" ) artifact_registry end |
#parse_image_registries(image_registries) ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/kube_deploy_tools/deploy_config_file.rb', line 111 def parse_image_registries(image_registries) check_and_err(image_registries.is_a?(Array), '.image_registries is not an Array') image_registries = image_registries.map { |i| ImageRegistry.new(i) } # Validate that only one instance of each driver is registered duplicates = select_duplicates(image_registries.map { |i| i.name }) check_and_err( duplicates.count == 0, "Expected .image_registries names to be unique, but found duplicates: #{duplicates}" ) image_registries .map { |i| [i.name, i] } .to_h end |
#select_duplicates(array) ⇒ Object
240 241 242 |
# File 'lib/kube_deploy_tools/deploy_config_file.rb', line 240 def select_duplicates(array) array.select { |n| array.count(n) > 1 }.uniq end |
#to_h ⇒ Object
271 272 273 274 275 276 277 278 279 280 |
# File 'lib/kube_deploy_tools/deploy_config_file.rb', line 271 def to_h { 'image_registries' => @image_registries.values.map(&:to_h), 'default_flags' => @default_flags, 'artifacts' => @artifacts, 'flavors' => @flavors, 'hooks' => @hooks, 'expiration' => @expiration, } end |
#upgrade! ⇒ Object
upgrade! converts the config to a YAML string in the format of the latest supported version e.g. with the latest supported version as v2, to_yaml will always print a valid v2 YAML
231 232 233 234 235 236 237 238 |
# File 'lib/kube_deploy_tools/deploy_config_file.rb', line 231 def upgrade! version = @original_config.fetch('version', 1) case version when 2 # TODO(joshk): Any required updates to v3 or remove this entire method true end end |
#validate_artifacts! ⇒ Object
.artifacts depends on .default_flags and .image_registries
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/kube_deploy_tools/deploy_config_file.rb', line 136 def validate_artifacts! check_and_err(artifacts.is_a?(Array), '.artifacts is not an Array') duplicates = select_duplicates(artifacts.map { |i| i.fetch('name') }) check_and_err( duplicates.count == 0, "Expected .artifacts names to be unique, but found duplicates: #{duplicates}" ) @valid_image_registries = map_image_registry(@image_registries) artifacts.each_with_index { |artifact, index| check_and_err( artifact.key?('name'), "Expected .artifacts[#{index}].name key to exist, but .name is missing" ) name = artifact.fetch('name') check_and_err( artifact.key?('image_registry'), "Expected .artifacts[#{index}].image_registry key to exist, but .image_registry is missing" ) image_registry = artifact.fetch('image_registry') check_and_err( @valid_image_registries.key?(image_registry), "#{image_registry} is not a valid Image Registry. Has to be one of #{@valid_image_registries.keys}" ) check_and_err( artifact.key?('flags'), "Expected .artifacts.#{name}.flags key to exist, but .flags is missing" ) } end |
#validate_default_flags ⇒ Object
171 172 173 |
# File 'lib/kube_deploy_tools/deploy_config_file.rb', line 171 def validate_default_flags check_and_err(@default_flags.is_a?(Hash), '.default_flags is not a Hash') end |
#validate_expiration ⇒ Object
183 184 185 |
# File 'lib/kube_deploy_tools/deploy_config_file.rb', line 183 def validate_expiration check_and_err(@expiration.is_a?(Array), '.expiration is not an Array') end |
#validate_flavors ⇒ Object
175 176 177 |
# File 'lib/kube_deploy_tools/deploy_config_file.rb', line 175 def validate_flavors check_and_err(@flavors.is_a?(Hash), '.flavors is not a Hash') end |
#validate_hooks ⇒ Object
179 180 181 |
# File 'lib/kube_deploy_tools/deploy_config_file.rb', line 179 def validate_hooks check_and_err(@hooks.is_a?(Array), '.hooks is not an Array') end |