Class: Hippo::Kubernetes
- Inherits:
-
Object
- Object
- Hippo::Kubernetes
- Includes:
- Util
- Defined in:
- lib/hippo/kubernetes.rb
Constant Summary collapse
- OBJECT_DIRECTORY_NAMES =
%w[config deployments jobs/install jobs/deploy services].freeze
Instance Method Summary collapse
- #apply_namespace(stage) ⇒ Object
-
#apply_with_kubectl(yaml_parts) ⇒ void
Apply the given configuration with kubectl.
-
#delete_job(stage, name) ⇒ void
Delete a named job from the cluster.
-
#get_with_kubectl(stage, *names) ⇒ Array<Hash>
Get details of objects using kubectl.
-
#initialize(recipe, options) ⇒ Kubernetes
constructor
A new instance of Kubernetes.
-
#objects(path, stage, commit) ⇒ Object
Load and return a set of objects from a given path.
-
#wait_for_jobs(stage, names, times = 120) ⇒ Array<Boolean, Array<Hash>]
Poll the named jobs and return them when all are complete or the number of checks is exceeded.
Methods included from Util
#load_yaml_from_data, #load_yaml_from_directory, #load_yaml_from_path, #open_in_editor
Constructor Details
#initialize(recipe, options) ⇒ Kubernetes
12 13 14 15 |
# File 'lib/hippo/kubernetes.rb', line 12 def initialize(recipe, ) @recipe = recipe @options = end |
Instance Method Details
#apply_namespace(stage) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/hippo/kubernetes.rb', line 71 def apply_namespace(stage) namespace = { 'kind' => 'Namespace', 'apiVersion' => 'v1', 'metadata' => { 'name' => stage.namespace } } add_default_labels(namespace, stage) apply_with_kubectl(namespace.to_yaml) end |
#apply_with_kubectl(yaml_parts) ⇒ void
This method returns an undefined value.
Apply the given configuration with kubectl
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/hippo/kubernetes.rb', line 87 def apply_with_kubectl(yaml_parts) unless yaml_parts.is_a?(String) yaml_parts = [yaml_parts] unless yaml_parts.is_a?(Array) yaml_parts = yaml_parts.map { |yp| yp.hash.to_yaml }.join("\n---\n") end Open3.popen3('kubectl apply -f -') do |stdin, stdout, stderr, wt| stdin.puts yaml_parts stdin.close stdout = stdout.read.strip stderr = stderr.read.strip if wt.value.success? puts stdout stdout.split("\n").each_with_object({}) do |line, hash| if line =~ %r{\A([\w\/\-\.]+) (\w+)\z} hash[Regexp.last_match(1)] = Regexp.last_match(2) end end else raise Error, "[kubectl] #{stderr}" end end end |
#delete_job(stage, name) ⇒ void
This method returns an undefined value.
Delete a named job from the cluster
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/hippo/kubernetes.rb', line 144 def delete_job(stage, name) command = [ 'kubectl', '-n', stage.namespace, 'delete', 'job', name ] Open3.popen3(*command) do |_, stdout, stderr, wt| if wt.value.success? puts stdout.read true else stderr = stderr.read if stderr =~ /\"#{name}\" not found/ false else raise Error, "[kutectl] #{stderr.read}" end end end end |
#get_with_kubectl(stage, *names) ⇒ Array<Hash>
Get details of objects using kubectl.
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/hippo/kubernetes.rb', line 119 def get_with_kubectl(stage, *names) command = [ 'kubectl', '-n', stage.namespace, 'get', names, '-o', 'yaml' ].flatten.reject(&:nil?) Open3.popen3(*command) do |_, stdout, stderr, wt| if wt.value.success? yaml = YAML.safe_load(stdout.read, permitted_classes: [Time]) yaml['items'] || [yaml] else raise Error, "[kutectl] #{stderr.read}" end end end |
#objects(path, stage, commit) ⇒ Object
Load and return a set of objects from a given path. Parse them through the templating and return them in the appropriate context.
25 26 27 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 |
# File 'lib/hippo/kubernetes.rb', line 25 def objects(path, stage, commit) time = Time.now yamls = load_yaml_from_directory(path) yamls |= load_yaml_from_directory(File.join(path, stage.name)) yamls.map do |yaml_part| object = yaml_part.parse(@recipe, stage, commit) # Unless a namespace has been specified in the metadata we will # want to add the namespace for the current stage. if object['metadata'].nil? || object['metadata']['namespace'].nil? object['metadata'] ||= {} object['metadata']['namespace'] = stage.namespace end # Add our own details to the metadata of all objets created by us so # we know where they came from. object['metadata']['annotations'] ||= {} object['metadata']['annotations']['hippo.adam.ac/builtAt'] ||= time.to_s object['metadata']['annotations']['hippo.adam.ac/builtBy'] ||= ENV['USER'] || 'unknown' add_default_labels(object, stage) # Add some information to Deployments to reflect the latest # information about this deployment. if object['kind'] == 'Deployment' object['metadata']['annotations']['hippo.adam.ac/deployID'] ||= time.to_i.to_s if commit object['metadata']['annotations']['hippo.adam.ac/commitRef'] ||= commit.objectish object['metadata']['annotations']['hippo.adam.ac/commitMessage'] ||= commit. end if = object.dig('spec', 'template', 'metadata') ['annotations'] ||= {} ['annotations']['hippo.adam.ac/deployID'] ||= time.to_i.to_s if commit ['annotations']['hippo.adam.ac/commitRef'] ||= commit.objectish end end end object end end |
#wait_for_jobs(stage, names, times = 120) ⇒ Array<Boolean, Array<Hash>]
Poll the named jobs and return them when all are complete or the number of checks is exceeded.
175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/hippo/kubernetes.rb', line 175 def wait_for_jobs(stage, names, times = 120) jobs = nil times.times do jobs = get_with_kubectl(stage, *names) # Are all the jobs completed? if jobs.all? { |j| j['status']['active'].nil? } return [false, jobs] else sleep 2 end end [true, jobs] end |