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.1'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of KubernetesCLI.



24
25
26
27
28
29
# File 'lib/kubernetes-cli.rb', line 24

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.



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

def executable
  @executable
end

#kubeconfig_pathObject (readonly)

Returns the value of attribute kubeconfig_path.



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

def kubeconfig_path
  @kubeconfig_path
end

Instance Method Details

#after_execute(&block) ⇒ Object



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

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

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



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/kubernetes-cli.rb', line 137

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



173
174
175
176
177
178
179
180
181
182
183
# File 'lib/kubernetes-cli.rb', line 173

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



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/kubernetes-cli.rb', line 62

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



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/kubernetes-cli.rb', line 81

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



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

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

#current_contextObject



168
169
170
171
# File 'lib/kubernetes-cli.rb', line 168

def current_context
  cmd = [executable, '--kubeconfig', kubeconfig_path, 'config', 'current-context']
  backticks(cmd).strip
end

#exec_cmd(container_cmd, namespace, pod, tty = true) ⇒ Object



48
49
50
51
52
53
# File 'lib/kubernetes-cli.rb', line 48

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



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/kubernetes-cli.rb', line 97

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



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/kubernetes-cli.rb', line 117

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



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

def last_status
  Thread.current[STATUS_KEY]
end

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



160
161
162
163
164
165
166
# File 'lib/kubernetes-cli.rb', line 160

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



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/kubernetes-cli.rb', line 185

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



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

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

#stderrObject



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

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

#stderr=(new_stderr) ⇒ Object



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

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

#stdoutObject



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

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

#stdout=(new_stdout) ⇒ Object



216
217
218
# File 'lib/kubernetes-cli.rb', line 216

def stdout=(new_stdout)
  Thread.current[STDOUT_KEY] = new_stdout
end

#system_cmd(container_cmd, namespace, pod, tty = true) ⇒ Object



55
56
57
58
59
60
# File 'lib/kubernetes-cli.rb', line 55

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



201
202
203
204
205
206
207
208
209
210
# File 'lib/kubernetes-cli.rb', line 201

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