class KubernetesCLI

Constants

STATUS_KEY
STDERR_KEY
STDOUT_KEY
VERSION

Attributes

executable[R]
kubeconfig_path[R]

Public Class Methods

new(kubeconfig_path, executable = KubectlRb.executable) click to toggle source
# File lib/kubernetes-cli.rb, line 25
def initialize(kubeconfig_path, executable = KubectlRb.executable)
  @kubeconfig_path = kubeconfig_path
  @executable = executable
  @before_execute = []
  @after_execute = []
end

Public Instance Methods

after_execute(&block) click to toggle source
# File lib/kubernetes-cli.rb, line 36
def after_execute(&block)
  @after_execute << block
end
annotate(type, namespace, name, annotations, overwrite: true) click to toggle source
# File lib/kubernetes-cli.rb, line 138
def annotate(type, namespace, name, annotations, overwrite: true)
  cmd = [
    executable,
    '--kubeconfig', kubeconfig_path,
    '-n', namespace,
    'annotate'
  ]

  cmd << '--overwrite' if overwrite
  cmd += [type, name]

  annotations.each do |key, value|
    cmd << "'#{key}'='#{value}'"
  end

  systemm(cmd)

  unless last_status.success?
    raise KubernetesError, "could not annotate resource '#{name}': kubectl "\
      "exited with status code #{last_status.exitstatus}"
  end
end
api_resources() click to toggle source
# File lib/kubernetes-cli.rb, line 174
def api_resources
  cmd = [executable, '--kubeconfig', kubeconfig_path, 'api-resources']
  result = backticks(cmd)

  unless last_status.success?
    raise KubernetesError, 'could not fetch API resources: kubectl exited with '\
      "status code #{last_status.exitstatus}. #{result}"
  end

  result
end
apply(res, dry_run: false) click to toggle source
# File lib/kubernetes-cli.rb, line 63
def apply(res, dry_run: false)
  cmd = [executable, '--kubeconfig', kubeconfig_path, 'apply', '--validate']
  cmd << '--dry-run=client' if dry_run
  cmd += ['-f', '-']

  open3_w(env, cmd) do |stdin|
    stdin.puts(res.to_resource.to_yaml)
  end

  unless last_status.success?
    err = InvalidResourceError.new("Could not apply #{res.kind_sym.to_s.humanize.downcase} "\
      "'#{res.metadata.name}': kubectl exited with status code #{last_status.exitstatus}"
    )

    err.resource = res
    raise err
  end
end
apply_uri(uri, dry_run: false) click to toggle source
# File lib/kubernetes-cli.rb, line 82
def apply_uri(uri, dry_run: false)
  cmd = [executable, '--kubeconfig', kubeconfig_path, 'apply', '--validate']
  cmd << '--dry-run=client' if dry_run
  cmd += ['-f', uri]
  systemm(cmd)

  unless last_status.success?
    err = InvalidResourceUriError.new("Could not apply #{uri}: "\
      "kubectl exited with status code #{last_status.exitstatus}"
    )

    err.resource_uri = uri
    raise err
  end
end
before_execute(&block) click to toggle source
# File lib/kubernetes-cli.rb, line 32
def before_execute(&block)
  @before_execute << block
end
current_context() click to toggle source
# File lib/kubernetes-cli.rb, line 169
def current_context
  cmd = [executable, '--kubeconfig', kubeconfig_path, 'config', 'current-context']
  backticks(cmd).strip
end
exec_cmd(container_cmd, namespace, pod, tty = true) click to toggle source
# File lib/kubernetes-cli.rb, line 49
def exec_cmd(container_cmd, namespace, pod, tty = true)
  cmd = [executable, '--kubeconfig', kubeconfig_path, '-n', namespace, 'exec']
  cmd += ['-it'] if tty
  cmd += [pod, '--', *Array(container_cmd)]
  execc(cmd)
end
get_object(type, namespace, name = nil, match_labels = {}) click to toggle source
# File lib/kubernetes-cli.rb, line 98
def get_object(type, namespace, name = nil, match_labels = {})
  cmd = [executable, '--kubeconfig', kubeconfig_path, '-n', namespace]
  cmd += ['get', type, name]

  unless match_labels.empty?
    cmd += ['--selector', match_labels.map { |key, value| "#{key}=#{value}" }.join(',')]
  end

  cmd += ['-o', 'json']

  result = backticks(cmd)

  unless last_status.success?
    raise GetResourceError, "couldn't get resources of type '#{type}' "\
      "in namespace #{namespace}: kubectl exited with status code #{last_status.exitstatus}"
  end

  JSON.parse(result)
end
get_objects(type, namespace, match_labels = {}) click to toggle source
# File lib/kubernetes-cli.rb, line 118
def get_objects(type, namespace, match_labels = {})
  cmd = [executable, '--kubeconfig', kubeconfig_path, '-n', namespace]
  cmd += ['get', type]

  unless match_labels.empty?
    cmd += ['--selector', match_labels.map { |key, value| "#{key}=#{value}" }.join(',')]
  end

  cmd += ['-o', 'json']

  result = backticks(cmd)

  unless last_status.success?
    raise GetResourceError, "couldn't get resources of type '#{type}' "\
      "in namespace #{namespace}: kubectl exited with status code #{last_status.exitstatus}"
  end

  JSON.parse(result)['items']
end
last_status() click to toggle source
# File lib/kubernetes-cli.rb, line 40
def last_status
  Thread.current[STATUS_KEY]
end
logtail(namespace, selector, follow: true) click to toggle source
# File lib/kubernetes-cli.rb, line 161
def logtail(namespace, selector, follow: true)
  cmd = [executable, '--kubeconfig', kubeconfig_path, '-n', namespace, 'logs']
  cmd << '-f' if follow
  cmd << '--selector'
  cmd << selector.map { |k, v| "#{k}=#{v}" }.join(',')
  execc(cmd)
end
restart_deployment(namespace, deployment) click to toggle source
# File lib/kubernetes-cli.rb, line 186
def restart_deployment(namespace, deployment)
  cmd = [
    executable,
    '--kubeconfig', kubeconfig_path,
    '-n', namespace,
    'rollout', 'restart', 'deployment', deployment
  ]

  systemm(cmd)

  unless last_status.success?
    raise KubernetesError, 'could not restart deployment: kubectl exited with '\
      "status code #{last_status.exitstatus}"
  end
end
run_cmd(cmd) click to toggle source
# File lib/kubernetes-cli.rb, line 44
def run_cmd(cmd)
  cmd = [executable, '--kubeconfig', kubeconfig_path, *Array(cmd)]
  execc(cmd)
end
stderr() click to toggle source
# File lib/kubernetes-cli.rb, line 221
def stderr
  Thread.current[STDERR_KEY] || STDERR
end
stderr=(new_stderr) click to toggle source
# File lib/kubernetes-cli.rb, line 225
def stderr=(new_stderr)
  Thread.current[STDERR_KEY] = new_stderr
end
stdout() click to toggle source
# File lib/kubernetes-cli.rb, line 213
def stdout
  Thread.current[STDOUT_KEY] || STDOUT
end
stdout=(new_stdout) click to toggle source
# File lib/kubernetes-cli.rb, line 217
def stdout=(new_stdout)
  Thread.current[STDOUT_KEY] = new_stdout
end
system_cmd(container_cmd, namespace, pod, tty = true) click to toggle source
# File lib/kubernetes-cli.rb, line 56
def system_cmd(container_cmd, namespace, pod, tty = true)
  cmd = [executable, '--kubeconfig', kubeconfig_path, '-n', namespace, 'exec']
  cmd += ['-it'] if tty
  cmd += [pod, '--', *Array(container_cmd)]
  systemm(cmd)
end
with_pipes(out = STDOUT, err = STDERR) { || ... } click to toggle source
# File lib/kubernetes-cli.rb, line 202
def with_pipes(out = STDOUT, err = STDERR)
  previous_stdout = self.stdout
  previous_stderr = self.stderr
  self.stdout = out
  self.stderr = err
  yield
ensure
  self.stdout = previous_stdout
  self.stderr = previous_stderr
end

Private Instance Methods

backticks(cmd) click to toggle source
# File lib/kubernetes-cli.rb, line 288
def backticks(cmd)
  if stdout == STDOUT && stderr == STDERR
    backticks_default(cmd)
  else
    backticks_open3(cmd)
  end
end
backticks_default(cmd) click to toggle source
# File lib/kubernetes-cli.rb, line 296
def backticks_default(cmd)
  run_before_callbacks(cmd)
  cmd_s = cmd.join(' ')
  `#{cmd_s}`.tap do
    self.last_status = $?
    run_after_callbacks(cmd)
  end
end
backticks_open3(cmd) click to toggle source
# File lib/kubernetes-cli.rb, line 305
def backticks_open3(cmd)
  run_before_callbacks(cmd)
  cmd_s = cmd.join(' ')
  result = StringIO.new

  Open3.popen3(cmd_s) do |p_stdin, p_stdout, p_stderr, wait_thread|
    Thread.new do
      begin
        p_stdout.each { |line| result.puts(line) }
      rescue IOError
      end
    end

    Thread.new(stderr) do |t_stderr|
      begin
        p_stderr.each { |line| t_stderr.puts(line) }
      rescue IOError
      end
    end

    p_stdin.close
    self.last_status = wait_thread.value
    run_after_callbacks(cmd)
    wait_thread.join
  end

  result.string
end
base_cmd() click to toggle source
# File lib/kubernetes-cli.rb, line 235
def base_cmd
  [executable, '--kubeconfig', kubeconfig_path]
end
env() click to toggle source
# File lib/kubernetes-cli.rb, line 231
def env
  @env ||= {}
end
execc(cmd) click to toggle source
# File lib/kubernetes-cli.rb, line 239
def execc(cmd)
  run_before_callbacks(cmd)
  cmd_s = cmd.join(' ')
  exec(cmd_s)
end
last_status=(status) click to toggle source
# File lib/kubernetes-cli.rb, line 370
def last_status=(status)
  Thread.current[STATUS_KEY] = status
end
open3_w(env, cmd, opts = {}) { |p_stdin| ... } click to toggle source
# File lib/kubernetes-cli.rb, line 334
def open3_w(env, cmd, opts = {}, &block)
  run_before_callbacks(cmd)
  cmd_s = cmd.join(' ')

  Open3.popen3(env, cmd_s, opts) do |p_stdin, p_stdout, p_stderr, wait_thread|
    Thread.new(stdout) do |t_stdout|
      begin
        p_stdout.each { |line| t_stdout.puts(line) }
      rescue IOError
      end
    end

    Thread.new(stderr) do |t_stderr|
      begin
        p_stderr.each { |line| t_stderr.puts(line) }
      rescue IOError
      end
    end

    yield(p_stdin).tap do
      p_stdin.close
      self.last_status = wait_thread.value
      run_after_callbacks(cmd)
      wait_thread.join
    end
  end
end
run_after_callbacks(cmd) click to toggle source
# File lib/kubernetes-cli.rb, line 366
def run_after_callbacks(cmd)
  @after_execute.each { |cb| cb.call(cmd, last_status) }
end
run_before_callbacks(cmd) click to toggle source
# File lib/kubernetes-cli.rb, line 362
def run_before_callbacks(cmd)
  @before_execute.each { |cb| cb.call(cmd) }
end
systemm(cmd) click to toggle source
# File lib/kubernetes-cli.rb, line 245
def systemm(cmd)
  if stdout == STDOUT && stderr == STDERR
    systemm_default(cmd)
  else
    systemm_open3(cmd)
  end
end
systemm_default(cmd) click to toggle source
# File lib/kubernetes-cli.rb, line 253
def systemm_default(cmd)
  run_before_callbacks(cmd)
  cmd_s = cmd.join(' ')
  system(cmd_s).tap do
    self.last_status = $?
    run_after_callbacks(cmd)
  end
end
systemm_open3(cmd) click to toggle source
# File lib/kubernetes-cli.rb, line 262
def systemm_open3(cmd)
  run_before_callbacks(cmd)
  cmd_s = cmd.join(' ')

  Open3.popen3(cmd_s) do |p_stdin, p_stdout, p_stderr, wait_thread|
    Thread.new(stdout) do |t_stdout|
      begin
        p_stdout.each { |line| t_stdout.puts(line) }
      rescue IOError
      end
    end

    Thread.new(stderr) do |t_stderr|
      begin
        p_stderr.each { |line| t_stderr.puts(line) }
      rescue IOError
      end
    end

    p_stdin.close
    self.last_status = wait_thread.value
    run_after_callbacks(cmd)
    wait_thread.join
  end
end