Class: KubernetesCLI

Inherits:
Object
  • Object
show all
Defined in:
lib/kubernetes-cli.rb,
lib/kubernetes-cli/version.rb

Defined Under Namespace

Classes: GetResourceError, InvalidResourceError, InvalidResourceUriError, KubernetesError

Constant Summary collapse

STATUS_KEY =
:kubernetes_cli_last_status
STDOUT_KEY =
:kubernetes_cli_stdout
STDERR_KEY =
:kubernetes_cli_stderr
VERSION =
'0.3.2'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(kubeconfig_path, executable = KubectlRb.executable) ⇒ KubernetesCLI

Returns a new instance of KubernetesCLI.



25
26
27
28
29
30
# 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

Instance Attribute Details

#executableObject (readonly)

Returns the value of attribute executable.



23
24
25
# File 'lib/kubernetes-cli.rb', line 23

def executable
  @executable
end

#kubeconfig_pathObject (readonly)

Returns the value of attribute kubeconfig_path.



23
24
25
# File 'lib/kubernetes-cli.rb', line 23

def kubeconfig_path
  @kubeconfig_path
end

Instance Method Details

#after_execute(&block) ⇒ Object



36
37
38
# File 'lib/kubernetes-cli.rb', line 36

def after_execute(&block)
  @after_execute << block
end

#annotate(type, namespace, name, annotations, overwrite: true) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# 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_resourcesObject



174
175
176
177
178
179
180
181
182
183
184
# 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) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# 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..name}': kubectl exited with status code #{last_status.exitstatus}"
    )

    err.resource = res
    raise err
  end
end

#apply_uri(uri, dry_run: false) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# 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) ⇒ Object



32
33
34
# File 'lib/kubernetes-cli.rb', line 32

def before_execute(&block)
  @before_execute << block
end

#current_contextObject



169
170
171
172
# 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) ⇒ Object



49
50
51
52
53
54
# 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 = {}) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# 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 = {}) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# 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_statusObject



40
41
42
# File 'lib/kubernetes-cli.rb', line 40

def last_status
  Thread.current[STATUS_KEY]
end

#logtail(namespace, selector, follow: true) ⇒ Object



161
162
163
164
165
166
167
# 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) ⇒ Object



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# 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) ⇒ Object



44
45
46
47
# File 'lib/kubernetes-cli.rb', line 44

def run_cmd(cmd)
  cmd = [executable, '--kubeconfig', kubeconfig_path, *Array(cmd)]
  execc(cmd)
end

#stderrObject



221
222
223
# File 'lib/kubernetes-cli.rb', line 221

def stderr
  Thread.current[STDERR_KEY] || STDERR
end

#stderr=(new_stderr) ⇒ Object



225
226
227
# File 'lib/kubernetes-cli.rb', line 225

def stderr=(new_stderr)
  Thread.current[STDERR_KEY] = new_stderr
end

#stdoutObject



213
214
215
# File 'lib/kubernetes-cli.rb', line 213

def stdout
  Thread.current[STDOUT_KEY] || STDOUT
end

#stdout=(new_stdout) ⇒ Object



217
218
219
# 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) ⇒ Object



56
57
58
59
60
61
# 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) ⇒ Object



202
203
204
205
206
207
208
209
210
211
# 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