kitchen-k8s 0.9.2 → 0.9.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -1
- data/lib/kitchen/driver/k8s.rb +48 -0
- data/lib/kitchen/driver/k8s_version.rb +1 -1
- data/lib/kitchen/transport/k8s.rb +6 -4
- data/lib/kitchen/verifier/k8s.rb +71 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a19eb36821f265a527c1e28e93796ec45c004aa3
|
4
|
+
data.tar.gz: e6388f01c84365f087d74986e14da83bf0418da4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 72b84e9c0e56c57be9792d949b32add73edf6fd928ee929f26535400e2edd33d533131d072488de8ef1fbd112fe1f352dee93ed410199b17eaf496ddcc05e8ea
|
7
|
+
data.tar.gz: 244f09bf4579c5a64f69c6ce24b80b4b3ec9b29a06da713c986f3214092b7b892e212894d759fec3ab2a0365cba57e7f5133ad3648da7bca919286ea29d5376a
|
data/README.md
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
[![Build Status](https://img.shields.io/travis/mickfeech/kitchen-k8s.svg)](https://travis-ci.org/mickfeech/kitchen-k8s)
|
4
4
|
[![Gem Version](https://badge.fury.io/rb/kitchen-k8s.svg)](https://badge.fury.io/rb/kitchen-k8s)
|
5
|
+
[![Maintainability](https://api.codeclimate.com/v1/badges/d8b7b21a196fecda1b18/maintainability)](https://codeclimate.com/github/mickfeech/kitchen-k8s/maintainability)
|
5
6
|
|
6
7
|
A [Test Kitchen](https://github.com/test-kitchen/test-kitchen) driver for testing on top of a Kubernetes cluster.
|
7
8
|
|
@@ -68,4 +69,4 @@ Copyright 2018, Chris McFee
|
|
68
69
|
|
69
70
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0).
|
70
71
|
|
71
|
-
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
72
|
+
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
data/lib/kitchen/driver/k8s.rb
CHANGED
@@ -8,6 +8,8 @@ require 'uri'
|
|
8
8
|
|
9
9
|
require 'kitchen/driver/base'
|
10
10
|
require 'kitchen/transport/k8s'
|
11
|
+
require 'kitchen/provisioner/chef_base'
|
12
|
+
require 'kitchen/verifier/busser'
|
11
13
|
|
12
14
|
module Kitchen
|
13
15
|
module Driver
|
@@ -53,7 +55,53 @@ module Kitchen
|
|
53
55
|
# @api private
|
54
56
|
def finalize_config!(instance)
|
55
57
|
super.tap do
|
58
|
+
# Force the use of the Kubernetes transport since it isn't much use
|
59
|
+
# without that.
|
56
60
|
instance.transport = Kitchen::Transport::K8s.new(config)
|
61
|
+
# Leave room for the possibility of other provisioners in the future,
|
62
|
+
# but force some options we need.
|
63
|
+
if instance.provisioner.is_a?(Kitchen::Provisioner::ChefBase)
|
64
|
+
instance.provisioner.send(:config).update(
|
65
|
+
require_chef_omnibus: false,
|
66
|
+
product_name: nil,
|
67
|
+
chef_omnibus_root: '/opt/chef',
|
68
|
+
sudo: false,
|
69
|
+
)
|
70
|
+
end
|
71
|
+
# Ditto to the above, other verifiers will need their own hacks, but
|
72
|
+
# this is a start at least.
|
73
|
+
if instance.verifier.is_a?(Kitchen::Verifier::Busser)
|
74
|
+
instance.verifier.send(:config).update(
|
75
|
+
root_path: '/tmp/kitchen/verifier',
|
76
|
+
sudo: false,
|
77
|
+
)
|
78
|
+
elsif defined?(Kitchen::Verifier::Inspec) && instance.verifier.is_a?(Kitchen::Verifier::Inspec)
|
79
|
+
# Monkeypatch kitchen-inspec to use a copy of the k8s train transport.
|
80
|
+
require 'kitchen/verifier/k8s'
|
81
|
+
_config = config # Because closure madness.
|
82
|
+
old_runner_options = instance.verifier.method(:runner_options)
|
83
|
+
instance.verifier.send(:define_singleton_method, :runner_options) do |transport, state = {}, platform = nil, suite = nil|
|
84
|
+
if transport.is_a?(Kitchen::Transport::K8s)
|
85
|
+
{
|
86
|
+
"backend" => "k8s_hack",
|
87
|
+
"logger" => logger,
|
88
|
+
"pod" => state[:pod_id],
|
89
|
+
"container" => "default",
|
90
|
+
"kubectl_path" => _config[:binary],
|
91
|
+
"context" => _config[:context],
|
92
|
+
}.tap do |runner_options|
|
93
|
+
# Copied directly from kitchen-inspec because there is no way not to. Sigh.
|
94
|
+
runner_options["color"] = (config[:color].nil? ? true : config[:color])
|
95
|
+
runner_options["format"] = config[:format] unless config[:format].nil?
|
96
|
+
runner_options["output"] = config[:output] % { platform: platform, suite: suite } unless config[:output].nil?
|
97
|
+
runner_options["profiles_path"] = config[:profiles_path] unless config[:profiles_path].nil?
|
98
|
+
runner_options[:controls] = config[:controls]
|
99
|
+
end
|
100
|
+
else
|
101
|
+
old_runner_options.call(transport, state, platform, suite)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
57
105
|
end
|
58
106
|
end
|
59
107
|
|
@@ -3,6 +3,7 @@ require 'shellwords'
|
|
3
3
|
require 'kitchen/login_command'
|
4
4
|
require 'kitchen/shell_out'
|
5
5
|
require 'kitchen/transport/base'
|
6
|
+
require 'thor/util'
|
6
7
|
|
7
8
|
require 'kitchen/helper/k8s'
|
8
9
|
|
@@ -31,7 +32,7 @@ module Kitchen
|
|
31
32
|
# (see Base::Connection#execute)
|
32
33
|
def execute(command)
|
33
34
|
return if command.nil?
|
34
|
-
run_command(kubectl_command('exec', '--tty', '--container=default', options[:pod_id], '--', *Shellwords.split(command)))
|
35
|
+
run_command(kubectl_command('exec', '--tty', '--container=default', options[:pod_id], '--', *Shellwords.split(wrap_command(command))))
|
35
36
|
end
|
36
37
|
|
37
38
|
# (see Base::Connection#upload)
|
@@ -43,9 +44,10 @@ module Kitchen
|
|
43
44
|
end
|
44
45
|
end
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
47
|
+
protected
|
48
|
+
|
49
|
+
def wrap_command(cmd)
|
50
|
+
cmd.match(/\Ash\s\-c/) ? cmd : Util.wrap_command(cmd.gsub('\'', "'\\\\''"))
|
49
51
|
end
|
50
52
|
end
|
51
53
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'mixlib/shellout'
|
2
|
+
|
3
|
+
require 'train'
|
4
|
+
|
5
|
+
module Train::Transports
|
6
|
+
class K8sHack < Train.plugin(1)
|
7
|
+
name 'k8s_hack'
|
8
|
+
|
9
|
+
include_options Train::Extras::CommandWrapper
|
10
|
+
option :pod, required: true
|
11
|
+
option :container, default: nil
|
12
|
+
option :kubectl_path, default: 'kubectl'
|
13
|
+
option :context, default: nil
|
14
|
+
|
15
|
+
def connection(state = {})
|
16
|
+
opts = merge_options(options, state || {})
|
17
|
+
validate_options(opts)
|
18
|
+
opts[:logger] ||= logger
|
19
|
+
unless @connection && @connection_opts == opts
|
20
|
+
@connection ||= Connection.new(opts)
|
21
|
+
@connection_opts = opts.dup
|
22
|
+
end
|
23
|
+
@connection
|
24
|
+
end
|
25
|
+
|
26
|
+
class Connection < BaseConnection
|
27
|
+
if Gem::Requirement.create('< 0.30').satisfied_by?(Gem::Version.create(Train::VERSION))
|
28
|
+
# The API for a connection changed a lot in 0.30, this is a compat shim.
|
29
|
+
def os
|
30
|
+
@os ||= OSCommon.new(self, family: 'unix')
|
31
|
+
end
|
32
|
+
|
33
|
+
def file(path)
|
34
|
+
@files[path] ||= file_via_connection(path)
|
35
|
+
end
|
36
|
+
|
37
|
+
def run_command(cmd)
|
38
|
+
run_command_via_connection(cmd)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def file_via_connection(path)
|
43
|
+
defined?(Train::File::Remote::Linux) ? Train::File::Remote::Linux.new(self, path) : LinuxFile.new(self, path)
|
44
|
+
end
|
45
|
+
|
46
|
+
def run_command_via_connection(cmd)
|
47
|
+
kubectl_cmd = [options[:kubectl_path], 'exec']
|
48
|
+
kubectl_cmd.concat(['--context', options[:context]]) if options[:context]
|
49
|
+
kubectl_cmd.concat(['--container', options[:container]]) if options[:container]
|
50
|
+
kubectl_cmd.concat([options[:pod], '--', '/bin/sh', '-c', cmd])
|
51
|
+
|
52
|
+
so = Mixlib::ShellOut.new(kubectl_cmd, logger: logger)
|
53
|
+
so.run_command
|
54
|
+
if so.error?
|
55
|
+
# Trim the "command terminated with exit code N" line from the end
|
56
|
+
# of the stderr content.
|
57
|
+
so.stderr.gsub!(/command terminated with exit code #{so.exitstatus}\n\Z/, '')
|
58
|
+
end
|
59
|
+
CommandResult.new(so.stdout, so.stderr, so.exitstatus)
|
60
|
+
end
|
61
|
+
|
62
|
+
def uri
|
63
|
+
if options[:container]
|
64
|
+
"kubernetes://#{options[:pod]}/#{options[:container]}"
|
65
|
+
else
|
66
|
+
"kubernetes://#{options[:pod]}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kitchen-k8s
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris McFee
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-03-
|
11
|
+
date: 2018-03-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: kubeclient
|
@@ -205,6 +205,7 @@ files:
|
|
205
205
|
- lib/kitchen/driver/k8s_version.rb
|
206
206
|
- lib/kitchen/helper/k8s.rb
|
207
207
|
- lib/kitchen/transport/k8s.rb
|
208
|
+
- lib/kitchen/verifier/k8s.rb
|
208
209
|
- test/.kitchen.yml
|
209
210
|
- test/cookbooks/test/metadata.rb
|
210
211
|
- test/cookbooks/test/recipes/default.rb
|