vagrant-k8s 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +12 -0
- data/LICENSE.md +21 -0
- data/README.fr.md +61 -0
- data/README.md +63 -0
- data/lib/vagrant-k8s/VERSION +1 -0
- data/lib/vagrant-k8s/command_runner.rb +51 -0
- data/lib/vagrant-k8s/config.rb +30 -0
- data/lib/vagrant-k8s/helm_provisioner.rb +96 -0
- data/lib/vagrant-k8s/kubeconfig.rb +30 -0
- data/lib/vagrant-k8s/kustomize_provisioner.rb +52 -0
- data/lib/vagrant-k8s/plugin.rb +19 -0
- data/lib/vagrant-k8s/provisioner.rb +27 -0
- data/lib/vagrant-k8s/version.rb +5 -0
- data/lib/vagrant-k8s.rb +4 -0
- metadata +134 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 07217ff90e6ba7b0c4f90a89b21385d0d8527863ae936fe052d3e6f39e1b7800
|
|
4
|
+
data.tar.gz: d2f5f10123b86cf8bf40a5523bcbfa41b0c2b35953c11cb7705113a396a750e0
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: a57e7c941f796d9be993199ef70a384b0cfb049833317578794f2565774ba6c4be20142cb6d15d56c424cb1547fdc2a164a433983acc6b96b40bf3920c728a66
|
|
7
|
+
data.tar.gz: 23b76a729143ce4355192ee75eff409fa7e868c0617a2b75fe0501d59a8bbf9b1cfd231287bfb8c4260f36f29945a69ab07b08ce8195b417e5d5f7768809f6d8
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.2.0](https://github.com/julienpoirou/vagrant-k8s/compare/v0.1.4...v0.2.0) (2026-07-05)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Fonctionnalités ✨
|
|
7
|
+
|
|
8
|
+
* Initial vagrant-k8s plugin implementation ([66cb354](https://github.com/julienpoirou/vagrant-k8s/commit/66cb3545b61e6300fa1549c8690411c348252d19))
|
|
9
|
+
|
|
10
|
+
## 0.1.0
|
|
11
|
+
|
|
12
|
+
- Initial release with shared Kubernetes configuration, `vagrant k8s`, and Helm/Kustomize provisioners.
|
data/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Julien Poirou
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.fr.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# vagrant-k8s
|
|
2
|
+
|
|
3
|
+
Plugin Vagrant pour piloter un cluster Kubernetes depuis la machine hôte, avec des provisionneurs Helm et Kustomize.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
vagrant plugin install vagrant-k8s
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Configuration du cluster
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
Vagrant.configure("2") do |config|
|
|
15
|
+
config.k8s.kubeconfig = "config/kubeconfig.yaml" # relatif au Vagrantfile
|
|
16
|
+
config.k8s.context = "kind-dev"
|
|
17
|
+
config.k8s.namespace = "demo"
|
|
18
|
+
config.k8s.kubectl = "kubectl" # facultatif
|
|
19
|
+
end
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Laissez `kubeconfig` à `nil` pour utiliser la configuration habituelle de Kubectl (dont `KUBECONFIG`).
|
|
23
|
+
|
|
24
|
+
## Provisionneur Helm
|
|
25
|
+
|
|
26
|
+
```ruby
|
|
27
|
+
config.vm.provision "nginx", type: "helm" do |helm|
|
|
28
|
+
helm.release = "nginx"
|
|
29
|
+
helm.chart = "ingress-nginx"
|
|
30
|
+
helm.repo = "https://kubernetes.github.io/ingress-nginx"
|
|
31
|
+
helm.version = "4.11.3"
|
|
32
|
+
helm.namespace = "ingress-nginx"
|
|
33
|
+
helm.create_namespace = true
|
|
34
|
+
helm.values = ["k8s/ingress-values.yaml"]
|
|
35
|
+
helm.set = { "controller.replicaCount" => 2 }
|
|
36
|
+
helm.wait = true
|
|
37
|
+
helm.atomic = true
|
|
38
|
+
helm.timeout = "5m"
|
|
39
|
+
end
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Le provisionneur exécute `helm upgrade --install` sur le contexte configuré dans `config.k8s`.
|
|
43
|
+
|
|
44
|
+
## Provisionneur Kustomize
|
|
45
|
+
|
|
46
|
+
```ruby
|
|
47
|
+
config.vm.provision "application", type: "kustomize" do |kustomize|
|
|
48
|
+
kustomize.path = "k8s/overlays/dev"
|
|
49
|
+
kustomize.namespace = "demo" # remplace config.k8s.namespace
|
|
50
|
+
kustomize.server_side = true
|
|
51
|
+
kustomize.prune = true
|
|
52
|
+
kustomize.prune_selector = "app.kubernetes.io/managed-by=vagrant"
|
|
53
|
+
kustomize.wait = true
|
|
54
|
+
end
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Il exécute `kubectl apply -k`. Avec `wait`, il attend les pods prêts pendant cinq minutes.
|
|
58
|
+
|
|
59
|
+
## Prérequis
|
|
60
|
+
|
|
61
|
+
`kubectl` est requis sur l'hôte. Helm est requis uniquement pour le provisionneur Helm. Les chemins de manifests et de fichiers values sont relatifs au répertoire du Vagrantfile.
|
data/README.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# vagrant-k8s
|
|
2
|
+
|
|
3
|
+
Vagrant plugin to drive a Kubernetes cluster from the host machine, with Helm and Kustomize provisioners.
|
|
4
|
+
|
|
5
|
+
See [the French documentation](README.fr.md) for the same content in French.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
vagrant plugin install vagrant-k8s
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Cluster configuration
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
Vagrant.configure("2") do |config|
|
|
17
|
+
config.k8s.kubeconfig = "config/kubeconfig.yaml" # relative to the Vagrantfile
|
|
18
|
+
config.k8s.context = "kind-dev"
|
|
19
|
+
config.k8s.namespace = "demo"
|
|
20
|
+
config.k8s.kubectl = "kubectl" # optional
|
|
21
|
+
end
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Leave `kubeconfig` at `nil` to use the usual Kubectl configuration (including `KUBECONFIG`).
|
|
25
|
+
|
|
26
|
+
## Helm provisioner
|
|
27
|
+
|
|
28
|
+
```ruby
|
|
29
|
+
config.vm.provision "nginx", type: "helm" do |helm|
|
|
30
|
+
helm.release = "nginx"
|
|
31
|
+
helm.chart = "ingress-nginx"
|
|
32
|
+
helm.repo = "https://kubernetes.github.io/ingress-nginx"
|
|
33
|
+
helm.version = "4.11.3"
|
|
34
|
+
helm.namespace = "ingress-nginx"
|
|
35
|
+
helm.create_namespace = true
|
|
36
|
+
helm.values = ["k8s/ingress-values.yaml"]
|
|
37
|
+
helm.set = { "controller.replicaCount" => 2 }
|
|
38
|
+
helm.wait = true
|
|
39
|
+
helm.atomic = true
|
|
40
|
+
helm.timeout = "5m"
|
|
41
|
+
end
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The provisioner runs `helm upgrade --install` against the context configured in `config.k8s`.
|
|
45
|
+
|
|
46
|
+
## Kustomize provisioner
|
|
47
|
+
|
|
48
|
+
```ruby
|
|
49
|
+
config.vm.provision "application", type: "kustomize" do |kustomize|
|
|
50
|
+
kustomize.path = "k8s/overlays/dev"
|
|
51
|
+
kustomize.namespace = "demo" # overrides config.k8s.namespace
|
|
52
|
+
kustomize.server_side = true
|
|
53
|
+
kustomize.prune = true
|
|
54
|
+
kustomize.prune_selector = "app.kubernetes.io/managed-by=vagrant"
|
|
55
|
+
kustomize.wait = true
|
|
56
|
+
end
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
It runs `kubectl apply -k`. With `wait`, it waits for pods to become ready for five minutes.
|
|
60
|
+
|
|
61
|
+
## Requirements
|
|
62
|
+
|
|
63
|
+
`kubectl` is required on the host. Helm is required only for the Helm provisioner. Manifest and values file paths are relative to the Vagrantfile directory.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.2.0
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'open3'
|
|
4
|
+
|
|
5
|
+
module VagrantK8s
|
|
6
|
+
module CommandRunner
|
|
7
|
+
# Raised when a command exits non-zero. Subclasses VagrantError so callers
|
|
8
|
+
# can still rescue it as one, but carries its own message: VagrantError drops
|
|
9
|
+
# a positional message string and would otherwise display "No error message".
|
|
10
|
+
class CommandError < Vagrant::Errors::VagrantError
|
|
11
|
+
def initialize(message)
|
|
12
|
+
@command_error_message = message
|
|
13
|
+
super()
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def to_s
|
|
17
|
+
@command_error_message
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def message
|
|
21
|
+
@command_error_message
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
module_function
|
|
26
|
+
|
|
27
|
+
# tolerate: optional Regexp. When the command fails but its stderr matches it,
|
|
28
|
+
# the failure is treated as a benign no-op (e.g. `kubectl wait` finding no
|
|
29
|
+
# matching resources) — logged as detail instead of raising.
|
|
30
|
+
# tolerate_message: friendly text to log in that case instead of echoing the
|
|
31
|
+
# raw (and alarming) stderr.
|
|
32
|
+
def run(ui, command, chdir: nil, tolerate: nil, tolerate_message: nil)
|
|
33
|
+
ui.detail("Executing: #{command.join(' ')}")
|
|
34
|
+
stdout, stderr, status = Open3.capture3(*command, chdir: chdir)
|
|
35
|
+
ui.detail(stdout.rstrip) unless stdout.empty?
|
|
36
|
+
|
|
37
|
+
if !status.success? && tolerate && stderr.match?(tolerate)
|
|
38
|
+
note = tolerate_message || stderr.rstrip
|
|
39
|
+
ui.detail(note) unless note.to_s.empty?
|
|
40
|
+
return stdout
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
ui.error(stderr.rstrip) unless stderr.empty?
|
|
44
|
+
raise CommandError, "Command failed (exit #{status.exitstatus}): #{command.first}" unless status.success?
|
|
45
|
+
|
|
46
|
+
stdout
|
|
47
|
+
rescue Errno::ENOENT
|
|
48
|
+
raise CommandError, "Executable not found: #{command.first}"
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module VagrantK8s
|
|
4
|
+
class Config < Vagrant.plugin('2', :config)
|
|
5
|
+
attr_accessor :kubeconfig, :context, :namespace, :kubectl
|
|
6
|
+
|
|
7
|
+
def initialize
|
|
8
|
+
@kubeconfig = UNSET_VALUE
|
|
9
|
+
@context = UNSET_VALUE
|
|
10
|
+
@namespace = UNSET_VALUE
|
|
11
|
+
@kubectl = UNSET_VALUE
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def finalize!
|
|
15
|
+
@kubeconfig = nil if @kubeconfig == UNSET_VALUE
|
|
16
|
+
@context = nil if @context == UNSET_VALUE
|
|
17
|
+
@namespace = nil if @namespace == UNSET_VALUE
|
|
18
|
+
@kubectl = 'kubectl' if @kubectl == UNSET_VALUE
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def validate(_machine)
|
|
22
|
+
errors = []
|
|
23
|
+
errors << 'k8s.kubeconfig must be a path string or nil' unless @kubeconfig.nil? || @kubeconfig.is_a?(String)
|
|
24
|
+
errors << 'k8s.context must be a string or nil' unless @context.nil? || @context.is_a?(String)
|
|
25
|
+
errors << 'k8s.namespace must be a string or nil' unless @namespace.nil? || @namespace.is_a?(String)
|
|
26
|
+
errors << 'k8s.kubectl must be a command string' unless @kubectl.is_a?(String) && !@kubectl.empty?
|
|
27
|
+
{ 'vagrant-k8s' => errors }
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'open3'
|
|
4
|
+
require_relative 'provisioner'
|
|
5
|
+
|
|
6
|
+
module VagrantK8s
|
|
7
|
+
class HelmConfig < Vagrant.plugin('2', :config)
|
|
8
|
+
attr_accessor :release, :chart, :repo, :version, :namespace, :values, :set, :wait, :atomic, :create_namespace,
|
|
9
|
+
:timeout, :helm
|
|
10
|
+
|
|
11
|
+
def initialize
|
|
12
|
+
@release = @chart = UNSET_VALUE
|
|
13
|
+
@repo = @version = @namespace = UNSET_VALUE
|
|
14
|
+
@values = @set = UNSET_VALUE
|
|
15
|
+
@wait = @atomic = @create_namespace = @timeout = @helm = UNSET_VALUE
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def finalize!
|
|
19
|
+
@repo = nil if @repo == UNSET_VALUE
|
|
20
|
+
@version = nil if @version == UNSET_VALUE
|
|
21
|
+
@namespace = nil if @namespace == UNSET_VALUE
|
|
22
|
+
@values = [] if @values == UNSET_VALUE
|
|
23
|
+
@set = {} if @set == UNSET_VALUE
|
|
24
|
+
@wait = false if @wait == UNSET_VALUE
|
|
25
|
+
@atomic = false if @atomic == UNSET_VALUE
|
|
26
|
+
@create_namespace = false if @create_namespace == UNSET_VALUE
|
|
27
|
+
@timeout = nil if @timeout == UNSET_VALUE
|
|
28
|
+
@helm = 'helm' if @helm == UNSET_VALUE
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def validate(_machine)
|
|
32
|
+
errors = []
|
|
33
|
+
errors << 'helm.release is required' unless @release.is_a?(String) && !@release.empty?
|
|
34
|
+
errors << 'helm.chart is required' unless @chart.is_a?(String) && !@chart.empty?
|
|
35
|
+
errors << 'helm.values must be an array' unless @values.is_a?(Array)
|
|
36
|
+
errors << 'helm.set must be a hash' unless @set.is_a?(Hash)
|
|
37
|
+
{ 'vagrant-k8s' => errors }
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
class HelmProvisioner < BaseProvisioner
|
|
42
|
+
def provision
|
|
43
|
+
command = [@config.helm, 'upgrade', '--install', @config.release, @config.chart]
|
|
44
|
+
append_release_options(command)
|
|
45
|
+
append_values_and_set(command)
|
|
46
|
+
append_cluster_options(command)
|
|
47
|
+
run(command)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def append_release_options(command)
|
|
53
|
+
command.push('--repo', @config.repo) if Kubeconfig.present?(@config.repo)
|
|
54
|
+
command.push('--version', @config.version) if Kubeconfig.present?(@config.version)
|
|
55
|
+
namespace = @config.namespace || @machine.config.k8s.namespace
|
|
56
|
+
command.push('--namespace', namespace) if Kubeconfig.present?(namespace)
|
|
57
|
+
command << '--create-namespace' if @config.create_namespace
|
|
58
|
+
command << '--wait' if @config.wait
|
|
59
|
+
command << atomic_flag if @config.atomic
|
|
60
|
+
command.push('--timeout', @config.timeout) if Kubeconfig.present?(@config.timeout)
|
|
61
|
+
command
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def append_values_and_set(command)
|
|
65
|
+
@config.values.each { |value| command.push('--values', root_path(value)) }
|
|
66
|
+
@config.set.each { |key, value| command.push('--set', "#{key}=#{value}") }
|
|
67
|
+
command
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# helm 4 deprecated --atomic in favour of --rollback-on-failure. Pick the
|
|
71
|
+
# flag matching the installed helm; fall back to --atomic when the version
|
|
72
|
+
# can't be determined (correct for helm 3, still accepted — with a
|
|
73
|
+
# deprecation notice — on helm 4).
|
|
74
|
+
def atomic_flag
|
|
75
|
+
helm_major >= 4 ? '--rollback-on-failure' : '--atomic'
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def helm_major
|
|
79
|
+
out, _err, status = Open3.capture3(@config.helm, 'version', '--short')
|
|
80
|
+
return 3 unless status.success?
|
|
81
|
+
|
|
82
|
+
match = out.strip.match(/v?(\d+)\./)
|
|
83
|
+
match ? match[1].to_i : 3
|
|
84
|
+
rescue StandardError
|
|
85
|
+
3
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def append_cluster_options(command)
|
|
89
|
+
global = @machine.config.k8s
|
|
90
|
+
kubeconfig = Kubeconfig.resolve_path(@machine, global.kubeconfig)
|
|
91
|
+
command.push('--kubeconfig', kubeconfig) if kubeconfig
|
|
92
|
+
command.push('--kube-context', global.context) if Kubeconfig.present?(global.context)
|
|
93
|
+
command
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module VagrantK8s
|
|
4
|
+
module Kubeconfig
|
|
5
|
+
module_function
|
|
6
|
+
|
|
7
|
+
def kubectl_command(machine, extra_args, namespace: nil, context: nil)
|
|
8
|
+
config = machine.config.k8s
|
|
9
|
+
command = [config.kubectl]
|
|
10
|
+
kubeconfig = resolve_path(machine, config.kubeconfig)
|
|
11
|
+
command += ['--kubeconfig', kubeconfig] if kubeconfig
|
|
12
|
+
selected_context = context || config.context
|
|
13
|
+
selected_namespace = namespace || config.namespace
|
|
14
|
+
command += ['--context', selected_context] if present?(selected_context)
|
|
15
|
+
command += ['--namespace', selected_namespace] if present?(selected_namespace)
|
|
16
|
+
command + extra_args
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def resolve_path(machine, path)
|
|
20
|
+
return nil unless present?(path)
|
|
21
|
+
return path if Pathname.new(path).absolute?
|
|
22
|
+
|
|
23
|
+
File.expand_path(path, machine.env.root_path.to_s)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def present?(value)
|
|
27
|
+
value.is_a?(String) && !value.empty?
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'provisioner'
|
|
4
|
+
|
|
5
|
+
module VagrantK8s
|
|
6
|
+
class KustomizeConfig < Vagrant.plugin('2', :config)
|
|
7
|
+
attr_accessor :path, :namespace, :prune, :prune_selector, :server_side, :force_conflicts, :wait
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
@path = @namespace = @prune_selector = UNSET_VALUE
|
|
11
|
+
@prune = @server_side = @force_conflicts = @wait = UNSET_VALUE
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def finalize!
|
|
15
|
+
@namespace = nil if @namespace == UNSET_VALUE
|
|
16
|
+
@prune_selector = nil if @prune_selector == UNSET_VALUE
|
|
17
|
+
@prune = false if @prune == UNSET_VALUE
|
|
18
|
+
@server_side = false if @server_side == UNSET_VALUE
|
|
19
|
+
@force_conflicts = false if @force_conflicts == UNSET_VALUE
|
|
20
|
+
@wait = false if @wait == UNSET_VALUE
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def validate(_machine)
|
|
24
|
+
errors = []
|
|
25
|
+
errors << 'kustomize.path is required' unless @path.is_a?(String) && !@path.empty?
|
|
26
|
+
if @prune && !Kubeconfig.present?(@prune_selector)
|
|
27
|
+
errors << 'kustomize.prune_selector is required when prune is true'
|
|
28
|
+
end
|
|
29
|
+
{ 'vagrant-k8s' => errors }
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
class KustomizeProvisioner < BaseProvisioner
|
|
34
|
+
def provision
|
|
35
|
+
command = Kubeconfig.kubectl_command(@machine, ['apply', '-k', root_path(@config.path)],
|
|
36
|
+
namespace: @config.namespace)
|
|
37
|
+
command << '--server-side' if @config.server_side
|
|
38
|
+
command << '--force-conflicts' if @config.force_conflicts
|
|
39
|
+
command += ['--prune', '--selector', @config.prune_selector] if @config.prune
|
|
40
|
+
run(command)
|
|
41
|
+
return unless @config.wait
|
|
42
|
+
|
|
43
|
+
# A kustomization may apply only non-pod resources (e.g. a ConfigMap), in
|
|
44
|
+
# which case `kubectl wait pod --all` exits non-zero with "no matching
|
|
45
|
+
# resources found". That's nothing to wait for, not a failure.
|
|
46
|
+
run(Kubeconfig.kubectl_command(@machine, ['wait', '--for=condition=ready', 'pod', '--all', '--timeout=300s'],
|
|
47
|
+
namespace: @config.namespace),
|
|
48
|
+
tolerate: /no matching resources found/i,
|
|
49
|
+
tolerate_message: 'No pods to wait for — the kustomization applied no pod-bearing resources.')
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'vagrant'
|
|
4
|
+
require 'pathname'
|
|
5
|
+
require_relative 'config'
|
|
6
|
+
require_relative 'helm_provisioner'
|
|
7
|
+
require_relative 'kustomize_provisioner'
|
|
8
|
+
|
|
9
|
+
module VagrantK8s
|
|
10
|
+
class Plugin < Vagrant.plugin('2')
|
|
11
|
+
name 'vagrant-k8s'
|
|
12
|
+
|
|
13
|
+
config(:k8s) { Config }
|
|
14
|
+
config(:helm, :provisioner) { HelmConfig }
|
|
15
|
+
provisioner(:helm) { HelmProvisioner }
|
|
16
|
+
config(:kustomize, :provisioner) { KustomizeConfig }
|
|
17
|
+
provisioner(:kustomize) { KustomizeProvisioner }
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'command_runner'
|
|
4
|
+
require_relative 'kubeconfig'
|
|
5
|
+
|
|
6
|
+
module VagrantK8s
|
|
7
|
+
class BaseProvisioner < Vagrant.plugin('2', :provisioner)
|
|
8
|
+
def initialize(machine, config)
|
|
9
|
+
super
|
|
10
|
+
@machine = machine
|
|
11
|
+
@config = config
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def run(command, tolerate: nil, tolerate_message: nil)
|
|
17
|
+
CommandRunner.run(@machine.ui, command, chdir: @machine.env.root_path.to_s,
|
|
18
|
+
tolerate: tolerate, tolerate_message: tolerate_message)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def root_path(path)
|
|
22
|
+
return path if Pathname.new(path).absolute?
|
|
23
|
+
|
|
24
|
+
File.expand_path(path, @machine.env.root_path.to_s)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
data/lib/vagrant-k8s.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: vagrant-k8s
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.2.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Julien Poirou
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-07-05 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rake
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '13.0'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '13.0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rspec
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '3.12'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '3.12'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rubocop
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '1.75'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '1.75'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rubocop-rspec
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '3.6'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '3.6'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: yard
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0.9'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0.9'
|
|
83
|
+
description: Configures a Kubernetes cluster from a Vagrantfile and provides Helm
|
|
84
|
+
and Kustomize provisioners.
|
|
85
|
+
email:
|
|
86
|
+
- julienpoirou@protonmail.com
|
|
87
|
+
executables: []
|
|
88
|
+
extensions: []
|
|
89
|
+
extra_rdoc_files: []
|
|
90
|
+
files:
|
|
91
|
+
- CHANGELOG.md
|
|
92
|
+
- LICENSE.md
|
|
93
|
+
- README.fr.md
|
|
94
|
+
- README.md
|
|
95
|
+
- lib/vagrant-k8s.rb
|
|
96
|
+
- lib/vagrant-k8s/VERSION
|
|
97
|
+
- lib/vagrant-k8s/command_runner.rb
|
|
98
|
+
- lib/vagrant-k8s/config.rb
|
|
99
|
+
- lib/vagrant-k8s/helm_provisioner.rb
|
|
100
|
+
- lib/vagrant-k8s/kubeconfig.rb
|
|
101
|
+
- lib/vagrant-k8s/kustomize_provisioner.rb
|
|
102
|
+
- lib/vagrant-k8s/plugin.rb
|
|
103
|
+
- lib/vagrant-k8s/provisioner.rb
|
|
104
|
+
- lib/vagrant-k8s/version.rb
|
|
105
|
+
homepage: https://github.com/julienpoirou/vagrant-k8s
|
|
106
|
+
licenses:
|
|
107
|
+
- MIT
|
|
108
|
+
metadata:
|
|
109
|
+
rubygems_mfa_required: 'true'
|
|
110
|
+
bug_tracker_uri: https://github.com/julienpoirou/vagrant-k8s/issues
|
|
111
|
+
changelog_uri: https://github.com/julienpoirou/vagrant-k8s/blob/main/CHANGELOG.md
|
|
112
|
+
documentation_uri: https://www.rubydoc.info/gems/vagrant-k8s/
|
|
113
|
+
source_code_uri: https://github.com/julienpoirou/vagrant-k8s
|
|
114
|
+
homepage_uri: https://github.com/julienpoirou/vagrant-k8s
|
|
115
|
+
post_install_message:
|
|
116
|
+
rdoc_options: []
|
|
117
|
+
require_paths:
|
|
118
|
+
- lib
|
|
119
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
120
|
+
requirements:
|
|
121
|
+
- - ">="
|
|
122
|
+
- !ruby/object:Gem::Version
|
|
123
|
+
version: '3.1'
|
|
124
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
125
|
+
requirements:
|
|
126
|
+
- - ">="
|
|
127
|
+
- !ruby/object:Gem::Version
|
|
128
|
+
version: '0'
|
|
129
|
+
requirements: []
|
|
130
|
+
rubygems_version: 3.4.19
|
|
131
|
+
signing_key:
|
|
132
|
+
specification_version: 4
|
|
133
|
+
summary: Vagrant integration for Kubernetes with Helm and Kustomize provisioners
|
|
134
|
+
test_files: []
|