module KubeDeployTools::RenderDeploysHook
Constants
- TEMPLATING_SUFFIX
Public Class Methods
get_valid_files(file_filters, input_dir)
click to toggle source
# File lib/kube_deploy_tools/render_deploys_hook.rb, line 90 def self.get_valid_files(file_filters, input_dir) filtered_files = FileFilter.filter_files(filters: file_filters, files_path: input_dir) filtered_files.select { |f| f =~ /\.y.?ml[^\/]*$/ } end
render_deploys(config_file, input_dir, output_root, file_filters)
click to toggle source
# File lib/kube_deploy_tools/render_deploys_hook.rb, line 16 def self.render_deploys(config_file, input_dir, output_root, file_filters) # Parse config into a struct. config = YAML.load_file(config_file) t = KubeDeployTools::Templater.new get_valid_files(file_filters, input_dir).each do |yml| # PREFIX/b/c/foo.yml.in -> foo.yml output_base = File.basename(yml, TEMPLATING_SUFFIX) # PREFIX/b/c/foo.yml.in -> b/c subdir = File.dirname(yml[input_dir.size..-1]) # PREFIX/b/c/foo.yml.in -> output/b/c/foo.yml if subdir == '.' # If |subdir| is '.', joining it with output_root results in # output_root/. , which is not concise for human readability. # Handle this case explicitly. output_dir = output_root else output_dir = File.join(output_root, subdir) end output_file = File.join(output_dir, output_base) if yml.end_with? TEMPLATING_SUFFIX # File needs to be templated with templater. Logger.debug("Generating #{output_file} from #{yml}") t.template_to_file(yml, config, output_file) else # File is not templatable, and is copied verbatim. Logger.debug("Copying #{output_file} from #{yml}") FileUtils.mkdir_p output_dir FileUtils.copy(yml, output_file) end # Bonus: YAML validate the output. # * Must be valid YAML # * If .kind is a type that takes .metadata.namespace, then require # that .metadata.namespace is present. begin if File.file?(output_file) yaml = [] YAML.load_stream(File.read(output_file)) { |doc| yaml << doc } yaml = yaml. compact. map do |data| # XXX(joshk): Non-exhaustive list. must_have_ns = [ 'ConfigMap', 'CronJob', 'DaemonSet', 'Deployment', 'Endpoints', 'HorizontalPodAutoscaler', 'Ingress', 'PersistentVolumeClaim', 'PodDisruptionBudget', 'ServiceAccount', 'Secret', 'Service' ] if must_have_ns.member?(data.fetch('kind')) raise "Rendered Kubernetes template missing a .metadata.namespace: #{yml}" if data.fetch('metadata', {}).fetch('namespace', '').empty? end # annotation added to each manifest annotations = data['metadata']['annotations'] || {} if config['git_commit'] annotations['git_commit'] = config['git_commit'] end if config['git_project'] annotations['git_project'] = config['git_project'] end data['metadata']['annotations'] = annotations data end File.open(output_file, 'w') { |f| f << YAML.dump_stream(*yaml) } end rescue => e raise "Failed to YAML validate #{output_file} (generated from #{yml}): #{e}" end end end