Class: Hippo::Stage
- Inherits:
-
Object
- Object
- Hippo::Stage
- Defined in:
- lib/hippo/stage.rb
Instance Attribute Summary collapse
-
#config_root ⇒ Object
readonly
Returns the value of attribute config_root.
-
#wd ⇒ Object
readonly
Returns the value of attribute wd.
Instance Method Summary collapse
-
#all_objects ⇒ Hash
Return an array of all objects that should be managed by Hippo.
-
#apply(objects) ⇒ Hash
Apply a series of objecst with.
- #branch ⇒ Object
- #command(name) ⇒ Object
- #config ⇒ Object
-
#configs ⇒ Hash<String,Hippo::ObjectDefinition>
Return an array of all configuration objects.
- #context ⇒ Object
-
#decorator ⇒ Object
Return a new decorator object that can be passed to objects that would like to decorator things.
-
#delete(*names) ⇒ Boolean
Delete an object from the kubernetes API.
-
#delete_pruneable_objects ⇒ void
Remove any objects which are prunable.
-
#deployments ⇒ Hash<String,Hippo::ObjectDefinition>
Return an array of all deployments for this stage.
-
#get(*names) ⇒ Array<Hippo::ObjectDefinition>
Get some data from the kubernetes API.
- #image_tag ⇒ Object
- #images ⇒ Object
-
#initialize(wd, config_root, options) ⇒ Stage
constructor
A new instance of Stage.
-
#jobs(type) ⇒ Hash<String,Hippo::ObjectDefinition>
Return an array of all job objects.
-
#kubectl(*commands) ⇒ Array<String>
Return a kubectl command ready for use within this stage’s namespace and context.
-
#live_objects(pruneable_only: false) ⇒ Array<Hash>
Return an array of objects that currently exist on the kubernetesa API.
- #manifest ⇒ Object
- #name ⇒ Object
- #namespace ⇒ Object
- #objects(path) ⇒ Object
-
#overridden_package_values ⇒ Hash
Return any package values that have been defined.
-
#packages ⇒ Hash<String, Hippo::Package>
Return a hash of all packages available in the stage.
- #readme ⇒ Object
- #secret_manager ⇒ Object
-
#services ⇒ Hash<String,Hippo::ObjectDefinition>
Return an array of all services/ingresses for this stage.
-
#template_vars ⇒ Object
These are the vars to represent this.
-
#wait_for_jobs(names, times = 120) ⇒ Object
Wait for the named jobs to complete.
Constructor Details
#initialize(wd, config_root, options) ⇒ Stage
Returns a new instance of Stage.
14 15 16 17 18 |
# File 'lib/hippo/stage.rb', line 14 def initialize(wd, config_root, ) @wd = wd @config_root = config_root @options = end |
Instance Attribute Details
#config_root ⇒ Object (readonly)
Returns the value of attribute config_root.
12 13 14 |
# File 'lib/hippo/stage.rb', line 12 def config_root @config_root end |
#wd ⇒ Object (readonly)
Returns the value of attribute wd.
11 12 13 |
# File 'lib/hippo/stage.rb', line 11 def wd @wd end |
Instance Method Details
#all_objects ⇒ Hash
Return an array of all objects that should be managed by Hippo
170 171 172 173 174 175 176 177 178 |
# File 'lib/hippo/stage.rb', line 170 def all_objects @all_objects ||= begin all = (deployments | services | configs | jobs('install') | jobs('deploy')) all.each_with_object({}) do |object, hash| hash[object.kind] ||= {} hash[object.kind][object.name] = object end end end |
#apply(objects) ⇒ Hash
Apply a series of objecst with
212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/hippo/stage.rb', line 212 def apply(objects) command = ['kubectl'] command += ['--context', context] if context command += ['apply', '-f', '-'] yaml_to_apply = objects.map(&:yaml_to_apply).join("\n") stdout, stderr, status = Open3.capture3(command.join(' '), stdin_data: yaml_to_apply + "\n") raise Error, "[kubectl] #{stderr}" unless status.success? Util.parse_kubectl_apply_lines(stdout) end |
#branch ⇒ Object
28 29 30 |
# File 'lib/hippo/stage.rb', line 28 def branch @options['branch'] end |
#command(name) ⇒ Object
48 49 50 51 52 53 54 55 56 |
# File 'lib/hippo/stage.rb', line 48 def command(name) base = manifest.commands[name] return nil if base.nil? { target: base['target'], command: decorator.call(base['command']) } end |
#config ⇒ Object
44 45 46 |
# File 'lib/hippo/stage.rb', line 44 def config @options['config'] end |
#configs ⇒ Hash<String,Hippo::ObjectDefinition>
Return an array of all configuration objects
155 156 157 |
# File 'lib/hippo/stage.rb', line 155 def configs @configs ||= Util.create_object_definitions(objects('config'), self) end |
#context ⇒ Object
40 41 42 |
# File 'lib/hippo/stage.rb', line 40 def context @options['context'] end |
#decorator ⇒ Object
Return a new decorator object that can be passed to objects that would like to decorator things.
83 84 85 86 87 88 89 90 91 92 |
# File 'lib/hippo/stage.rb', line 83 def decorator proc do |data| begin template = Liquid::Template.parse(data) template.render(template_vars, filters: [LiquidFilters]) rescue Liquid::SyntaxError => e raise Error, "Template error: #{e.}" end end end |
#delete(*names) ⇒ Boolean
Delete an object from the kubernetes API
244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/hippo/stage.rb', line 244 def delete(*names) command = kubectl('delete', *names) stdout, stderr, status = Open3.capture3(*command) if status.success? Util.parse_kubectl_apply_lines(stdout) true else if stderr =~ /\" not found$/ false else raise Error, "[kutectl] #{stderr}" end end end |
#delete_pruneable_objects ⇒ void
This method returns an undefined value.
Remove any objects which are prunable
123 124 125 126 127 128 |
# File 'lib/hippo/stage.rb', line 123 def delete_pruneable_objects live_objects(pruneable_only: true).each do |object| object = object[:live] delete(object.kind, object.name) end end |
#deployments ⇒ Hash<String,Hippo::ObjectDefinition>
Return an array of all deployments for this stage
141 142 143 |
# File 'lib/hippo/stage.rb', line 141 def deployments @deployments ||= Util.create_object_definitions(objects('deployments'), self, required_kinds: ['Deployment']) end |
#get(*names) ⇒ Array<Hippo::ObjectDefinition>
Get some data from the kubernetes API
230 231 232 233 234 235 236 237 238 |
# File 'lib/hippo/stage.rb', line 230 def get(*names) command = kubectl('get', '-o', 'yaml', *names) stdout, stderr, status = Open3.capture3(*command) raise Error, "[kubectl] #{stderr}" unless status.success? yaml = YAML.safe_load(stdout, permitted_classes: [Time]) yaml = yaml['items'] || [yaml] yaml.map { |y| ObjectDefinition.new(y, self, clean: true) } end |
#image_tag ⇒ Object
32 33 34 |
# File 'lib/hippo/stage.rb', line 32 def image_tag @options['image-tag'] end |
#images ⇒ Object
58 59 60 61 62 |
# File 'lib/hippo/stage.rb', line 58 def images @images ||= manifest.images.deep_merge(@options['images'] || {}).each_with_object({}) do |(key, image), hash| hash[key] = Image.new(key, image) end end |
#jobs(type) ⇒ Hash<String,Hippo::ObjectDefinition>
Return an array of all job objects
162 163 164 165 |
# File 'lib/hippo/stage.rb', line 162 def jobs(type) @jobs ||= {} @jobs[type] ||= Util.create_object_definitions(objects("jobs/#{type}"), self) end |
#kubectl(*commands) ⇒ Array<String>
Return a kubectl command ready for use within this stage’s namespace and context
201 202 203 204 205 206 |
# File 'lib/hippo/stage.rb', line 201 def kubectl(*commands) prefix = ['kubectl'] prefix += ['--context', context] if context prefix += ['-n', namespace] prefix + commands end |
#live_objects(pruneable_only: false) ⇒ Array<Hash>
Return an array of objects that currently exist on the kubernetesa API.
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/hippo/stage.rb', line 104 def live_objects(pruneable_only: false) los = get(all_objects.keys.join(','), '--selector', 'app.kubernetes.io/managed-by=hippo') los.each_with_object([]) do |live_obj, array| local = all_objects.dig(live_obj.kind, live_obj.name) pruneable = local.nil? && (live_obj.kind != 'Secret' && live_obj.name != 'hippo-secret-key') next if pruneable_only && !pruneable array << { live: live_obj, local: local, pruneable: pruneable } end end |
#manifest ⇒ Object
20 21 22 |
# File 'lib/hippo/stage.rb', line 20 def manifest wd.manifest end |
#name ⇒ Object
24 25 26 |
# File 'lib/hippo/stage.rb', line 24 def name @options['name'] end |
#namespace ⇒ Object
36 37 38 |
# File 'lib/hippo/stage.rb', line 36 def namespace @options['namespace'] end |
#objects(path) ⇒ Object
130 131 132 |
# File 'lib/hippo/stage.rb', line 130 def objects(path) manifest.objects(path, decorator: decorator) end |
#overridden_package_values ⇒ Hash
Return any package values that have been defined
193 194 195 |
# File 'lib/hippo/stage.rb', line 193 def overridden_package_values @options['packages'] || {} end |
#packages ⇒ Hash<String, Hippo::Package>
Return a hash of all packages available in the stage
183 184 185 186 187 188 |
# File 'lib/hippo/stage.rb', line 183 def packages @packages ||= objects('packages').values.each_with_object({}) do |package_hash, hash| package = Package.new(package_hash.first, self) hash[package.name] = package end end |
#readme ⇒ Object
94 95 96 97 98 |
# File 'lib/hippo/stage.rb', line 94 def readme return unless manifest.readme decorator.call(manifest.readme) end |
#secret_manager ⇒ Object
134 135 136 |
# File 'lib/hippo/stage.rb', line 134 def secret_manager @secret_manager ||= SecretManager.new(self) end |
#services ⇒ Hash<String,Hippo::ObjectDefinition>
Return an array of all services/ingresses for this stage
148 149 150 |
# File 'lib/hippo/stage.rb', line 148 def services @services ||= Util.create_object_definitions(objects('services'), self, required_kinds: %w[Service Ingress NetworkPolicy]) end |
#template_vars ⇒ Object
These are the vars to represent this
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/hippo/stage.rb', line 65 def template_vars @template_vars ||= begin { 'manifest' => manifest.template_vars, 'stage-name' => name, 'branch' => branch, 'image-tag' => image_tag, 'namespace' => namespace, 'context' => context, 'images' => images.values.each_with_object({}) { |image, hash| hash[image.name] = image.template_vars }, 'config' => manifest.config.deep_merge(config), 'secrets' => secret_manager.all } end end |
#wait_for_jobs(names, times = 120) ⇒ Object
Wait for the named jobs to complete
260 261 262 263 264 265 266 267 268 269 270 271 272 273 |
# File 'lib/hippo/stage.rb', line 260 def wait_for_jobs(names, times = 120) jobs = nil times.times do jobs = get(*names) if jobs.all? { |j| j['status']['active'].nil? } return [false, jobs] else sleep 2 end end [true, jobs] end |