hetzner-k3s 0.5.9 → 0.6.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/release.yml +32 -0
- data/.gitignore +2 -0
- data/.ruby-version +1 -1
- data/Gemfile +13 -2
- data/Gemfile.lock +22 -53
- data/bin/build.sh +12 -6
- data/config/warble.rb +182 -0
- data/exe/hetzner-k3s +3 -0
- data/hetzner-k3s.gemspec +4 -4
- data/lib/hetzner/infra/client.rb +5 -5
- data/lib/hetzner/infra/firewall.rb +1 -1
- data/lib/hetzner/infra/load_balancer.rb +1 -1
- data/lib/hetzner/infra/network.rb +2 -2
- data/lib/hetzner/infra/server.rb +3 -4
- data/lib/hetzner/k3s/cli.rb +6 -5
- data/lib/hetzner/k3s/cluster.rb +38 -38
- data/lib/hetzner/k3s/configuration.rb +15 -13
- data/lib/hetzner/k3s/version.rb +1 -1
- data/lib/hetzner/utils.rb +19 -10
- metadata +25 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47fa67797132b81c083283de99f93c4a0ce0b4119a1e575f74fb98550fd1ef10
|
4
|
+
data.tar.gz: e6fb4fcf848b988b23359037d4d544e12f7866ad9993c7eb560708b4ebf94a7f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7649a2467a8b84711f30f1ba4867a662207e3dc45cbdf26589b96194bb14c6c120b7f4d81edbc1aab46416704926b86b95f3d39cc283c98ad33bdc0642a5f3e8
|
7
|
+
data.tar.gz: c4e8226ad4e473a3dc7262dde4389fae8816ca0378f644288cbf1722b9fc342ce0a0a28d5251e4907e4c21170e943159ce326e2afd61f97eabd1853cb135e7b6
|
@@ -0,0 +1,32 @@
|
|
1
|
+
name: Release
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
tags:
|
6
|
+
- '*'
|
7
|
+
|
8
|
+
jobs:
|
9
|
+
mcos:
|
10
|
+
runs-on: macos-12
|
11
|
+
steps:
|
12
|
+
- uses: actions/checkout@v3
|
13
|
+
|
14
|
+
- uses: ruby/setup-ruby@v1
|
15
|
+
with:
|
16
|
+
ruby-version: '2.7.1'
|
17
|
+
|
18
|
+
- name: Get ruby-packer
|
19
|
+
run: |
|
20
|
+
curl -o rubyc-macos https://github.com/pmq20/ruby-packer/releases/download/darwin-x64/rubyc
|
21
|
+
chmod +x rubyc-macos
|
22
|
+
|
23
|
+
- name: Build for macOS
|
24
|
+
run: |
|
25
|
+
env CC="xcrun clang -mmacosx-version-min=10.10 -Wno-implicit-function-declaration" time ./rubyc-macos -r ./ -o $GITHUB_WORKSPACE/hetzner-k3s-macos exe/hetzner-k3s
|
26
|
+
chmod +x hetzner-k3s-macos
|
27
|
+
|
28
|
+
- uses: ncipollo/release-action@v1
|
29
|
+
with:
|
30
|
+
tag: v$(ruby -r ./lib/hetzner/k3s/version -e 'puts Hetzner::K3s::VERSION')
|
31
|
+
artifacts: "hetzner-k3s-macos"
|
32
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
data/.gitignore
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ruby-
|
1
|
+
ruby-2.7.1
|
data/Gemfile
CHANGED
@@ -5,5 +5,16 @@ source 'https://rubygems.org'
|
|
5
5
|
# Specify your gem's dependencies in k3s.gemspec
|
6
6
|
gemspec
|
7
7
|
|
8
|
-
|
9
|
-
gem '
|
8
|
+
# platforms :jruby do
|
9
|
+
# gem 'rake', '~> 12.0'
|
10
|
+
# gem 'rspec', '~> 3.0'
|
11
|
+
|
12
|
+
# gem 'childprocess'
|
13
|
+
# gem 'ed25519'
|
14
|
+
# gem 'http'
|
15
|
+
# gem 'jruby-openssl'
|
16
|
+
# gem 'net-ssh'
|
17
|
+
# gem 'sshkey'
|
18
|
+
# gem 'thor'
|
19
|
+
# gem 'http-parser'
|
20
|
+
# end
|
data/Gemfile.lock
CHANGED
@@ -1,90 +1,59 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
hetzner-k3s (0.5.
|
4
|
+
hetzner-k3s (0.5.9)
|
5
5
|
bcrypt_pbkdf
|
6
|
+
childprocess
|
6
7
|
ed25519
|
7
|
-
|
8
|
+
httparty
|
8
9
|
net-ssh
|
9
10
|
sshkey
|
10
|
-
subprocess
|
11
11
|
thor
|
12
12
|
|
13
13
|
GEM
|
14
14
|
remote: https://rubygems.org/
|
15
15
|
specs:
|
16
|
-
addressable (2.8.0)
|
17
|
-
public_suffix (>= 2.0.2, < 5.0)
|
18
16
|
ast (2.4.2)
|
19
17
|
bcrypt_pbkdf (1.1.0)
|
20
|
-
|
21
|
-
domain_name (0.5.20190701)
|
22
|
-
unf (>= 0.0.5, < 1.0.0)
|
18
|
+
childprocess (4.1.0)
|
23
19
|
ed25519 (1.3.0)
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
http-form_data (~> 2.2)
|
32
|
-
http-parser (~> 1.2.0)
|
33
|
-
http-cookie (1.0.5)
|
34
|
-
domain_name (~> 0.5)
|
35
|
-
http-form_data (2.3.0)
|
36
|
-
http-parser (1.2.3)
|
37
|
-
ffi-compiler (>= 1.0, < 2.0)
|
20
|
+
httparty (0.20.0)
|
21
|
+
mime-types (~> 3.0)
|
22
|
+
multi_xml (>= 0.5.2)
|
23
|
+
mime-types (3.4.1)
|
24
|
+
mime-types-data (~> 3.2015)
|
25
|
+
mime-types-data (3.2022.0105)
|
26
|
+
multi_xml (0.6.0)
|
38
27
|
net-ssh (6.1.0)
|
39
|
-
parallel (1.
|
40
|
-
parser (3.1.
|
28
|
+
parallel (1.20.1)
|
29
|
+
parser (3.1.2.1)
|
41
30
|
ast (~> 2.4.1)
|
42
|
-
public_suffix (4.0.7)
|
43
31
|
rainbow (3.1.1)
|
44
|
-
|
45
|
-
regexp_parser (2.2.0)
|
32
|
+
regexp_parser (2.5.0)
|
46
33
|
rexml (3.2.5)
|
47
|
-
|
48
|
-
rspec-core (~> 3.10.0)
|
49
|
-
rspec-expectations (~> 3.10.0)
|
50
|
-
rspec-mocks (~> 3.10.0)
|
51
|
-
rspec-core (3.10.1)
|
52
|
-
rspec-support (~> 3.10.0)
|
53
|
-
rspec-expectations (3.10.1)
|
54
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
55
|
-
rspec-support (~> 3.10.0)
|
56
|
-
rspec-mocks (3.10.2)
|
57
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
58
|
-
rspec-support (~> 3.10.0)
|
59
|
-
rspec-support (3.10.2)
|
60
|
-
rubocop (1.25.1)
|
34
|
+
rubocop (1.12.1)
|
61
35
|
parallel (~> 1.10)
|
62
|
-
parser (>= 3.
|
36
|
+
parser (>= 3.0.0.0)
|
63
37
|
rainbow (>= 2.2.2, < 4.0)
|
64
38
|
regexp_parser (>= 1.8, < 3.0)
|
65
39
|
rexml
|
66
|
-
rubocop-ast (>= 1.
|
40
|
+
rubocop-ast (>= 1.2.0, < 2.0)
|
67
41
|
ruby-progressbar (~> 1.7)
|
68
42
|
unicode-display_width (>= 1.4.0, < 3.0)
|
69
|
-
rubocop-ast (1.
|
70
|
-
parser (>=
|
43
|
+
rubocop-ast (1.4.1)
|
44
|
+
parser (>= 2.7.1.5)
|
71
45
|
ruby-progressbar (1.11.0)
|
72
46
|
sshkey (2.0.0)
|
73
|
-
subprocess (1.5.5)
|
74
47
|
thor (1.2.1)
|
75
|
-
|
76
|
-
unf_ext
|
77
|
-
unf_ext (0.0.8.2)
|
78
|
-
unicode-display_width (2.1.0)
|
48
|
+
unicode-display_width (2.2.0)
|
79
49
|
|
80
50
|
PLATFORMS
|
81
51
|
ruby
|
52
|
+
x86_64-darwin-21
|
82
53
|
|
83
54
|
DEPENDENCIES
|
84
55
|
hetzner-k3s!
|
85
|
-
rake (~> 12.0)
|
86
|
-
rspec (~> 3.0)
|
87
56
|
rubocop
|
88
57
|
|
89
58
|
BUNDLED WITH
|
90
|
-
2.3.
|
59
|
+
2.3.21
|
data/bin/build.sh
CHANGED
@@ -2,11 +2,17 @@
|
|
2
2
|
|
3
3
|
set -e
|
4
4
|
|
5
|
-
IMAGE="vitobotta/hetzner-k3s"
|
5
|
+
# IMAGE="vitobotta/hetzner-k3s"
|
6
6
|
|
7
|
-
docker build -t ${IMAGE}:v0.5.9 \
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
# docker build -t ${IMAGE}:v0.5.9 \
|
8
|
+
# --platform=linux/amd64 \
|
9
|
+
# --cache-from ${IMAGE}:v0.5.8 \
|
10
|
+
# --build-arg BUILDKIT_INLINE_CACHE=1 .
|
11
11
|
|
12
|
-
docker push vitobotta/hetzner-k3s:v0.5.9
|
12
|
+
# docker push vitobotta/hetzner-k3s:v0.5.9
|
13
|
+
|
14
|
+
warble
|
15
|
+
|
16
|
+
echo "#!/usr/bin/env java -jar" > dist/hetzner-k3s
|
17
|
+
cat dist/hetzner-k3s.jar >> dist/hetzner-k3s
|
18
|
+
chmod +x dist/hetzner-k3s
|
data/config/warble.rb
ADDED
@@ -0,0 +1,182 @@
|
|
1
|
+
# Disable Rake-environment-task framework detection by uncommenting/setting to false
|
2
|
+
# Warbler.framework_detection = false
|
3
|
+
|
4
|
+
# Warbler web application assembly configuration file
|
5
|
+
Warbler::Config.new do |config|
|
6
|
+
# Features: additional options controlling how the jar is built.
|
7
|
+
# Currently the following features are supported:
|
8
|
+
# - *gemjar*: package the gem repository in a jar file in WEB-INF/lib
|
9
|
+
# - *executable*: embed a web server and make the war executable
|
10
|
+
# - *runnable*: allows to run bin scripts e.g. `java -jar my.war -S rake -T`
|
11
|
+
# - *compiled*: compile .rb files to .class files
|
12
|
+
config.features = %w(executable runnable compiled)
|
13
|
+
|
14
|
+
# Application directories to be included in the webapp.
|
15
|
+
config.dirs = %w(bin config exe lib)
|
16
|
+
|
17
|
+
# Additional files/directories to include, above those in config.dirs
|
18
|
+
# config.includes = FileList["db"]
|
19
|
+
|
20
|
+
# Additional files/directories to exclude
|
21
|
+
# config.excludes = FileList["lib/tasks/*"]
|
22
|
+
|
23
|
+
# Additional Java .jar files to include. Note that if .jar files are placed
|
24
|
+
# in lib (and not otherwise excluded) then they need not be mentioned here.
|
25
|
+
# JRuby and JRuby-Rack are pre-loaded in this list. Be sure to include your
|
26
|
+
# own versions if you directly set the value
|
27
|
+
# config.java_libs += FileList["lib/java/*.jar"]
|
28
|
+
|
29
|
+
# Loose Java classes and miscellaneous files to be included.
|
30
|
+
# config.java_classes = FileList["target/classes/**.*"]
|
31
|
+
|
32
|
+
# One or more pathmaps defining how the java classes should be copied into
|
33
|
+
# the archive. The example pathmap below accompanies the java_classes
|
34
|
+
# configuration above. See http://rake.rubyforge.org/classes/String.html#M000017
|
35
|
+
# for details of how to specify a pathmap.
|
36
|
+
# config.pathmaps.java_classes << "%{target/classes/,}p"
|
37
|
+
|
38
|
+
# Bundler support is built-in. If Warbler finds a Gemfile in the
|
39
|
+
# project directory, it will be used to collect the gems to bundle
|
40
|
+
# in your application. If you wish to explicitly disable this
|
41
|
+
# functionality, uncomment here.
|
42
|
+
config.bundler = true
|
43
|
+
|
44
|
+
# An array of Bundler groups to avoid including in the war file.
|
45
|
+
# Defaults to ["development", "test", "assets"].
|
46
|
+
# config.bundle_without = []
|
47
|
+
|
48
|
+
# Other gems to be included. If you don't use Bundler or a gemspec
|
49
|
+
# file, you need to tell Warbler which gems your application needs
|
50
|
+
# so that they can be packaged in the archive.
|
51
|
+
# For Rails applications, the Rails gems are included by default
|
52
|
+
# unless the vendor/rails directory is present.
|
53
|
+
# config.gems += ["activerecord-jdbcmysql-adapter", "jruby-openssl"]
|
54
|
+
# config.gems << "tzinfo"
|
55
|
+
|
56
|
+
# Uncomment this if you don't want to package rails gem.
|
57
|
+
# config.gems -= ["rails"]
|
58
|
+
|
59
|
+
# The most recent versions of gems are used.
|
60
|
+
# You can specify versions of gems by using a hash assignment:
|
61
|
+
# config.gems["rails"] = "4.2.5"
|
62
|
+
|
63
|
+
# You can also use regexps or Gem::Dependency objects for flexibility or
|
64
|
+
# finer-grained control.
|
65
|
+
# config.gems << /^sinatra-/
|
66
|
+
# config.gems << Gem::Dependency.new("sinatra", "= 1.4.7")
|
67
|
+
|
68
|
+
# Include gem dependencies not mentioned specifically. Default is
|
69
|
+
# true, uncomment to turn off.
|
70
|
+
# config.gem_dependencies = false
|
71
|
+
|
72
|
+
# Array of regular expressions matching relative paths in gems to be
|
73
|
+
# excluded from the war. Defaults to empty, but you can set it like
|
74
|
+
# below, which excludes test files.
|
75
|
+
# config.gem_excludes = [/^(test|spec)\//]
|
76
|
+
|
77
|
+
# Pathmaps for controlling how application files are copied into the archive
|
78
|
+
# config.pathmaps.application = ["WEB-INF/%p"]
|
79
|
+
|
80
|
+
# Name of the archive (without the extension). Defaults to the basename
|
81
|
+
# of the project directory.
|
82
|
+
config.jar_name = "hetzner-k3s"
|
83
|
+
|
84
|
+
# File extension for the archive. Defaults to either 'jar' or 'war'.
|
85
|
+
config.jar_extension = "jar"
|
86
|
+
|
87
|
+
# Destionation for the created archive. Defaults to project's root directory.
|
88
|
+
config.autodeploy_dir = "dist/"
|
89
|
+
|
90
|
+
# Name of the MANIFEST.MF template for the war file. Defaults to a simple
|
91
|
+
# MANIFEST.MF that contains the version of Warbler used to create the war file.
|
92
|
+
# config.manifest_file = "config/MANIFEST.MF"
|
93
|
+
|
94
|
+
# When using the 'compiled' feature and specified, only these Ruby
|
95
|
+
# files will be compiled. Default is to compile all \.rb files in
|
96
|
+
# the application.
|
97
|
+
# config.compiled_ruby_files = FileList['app/**/*.rb']
|
98
|
+
|
99
|
+
# Determines if ruby files in supporting gems will be compiled.
|
100
|
+
# Ignored unless compile feature is used.
|
101
|
+
config.compile_gems = true
|
102
|
+
|
103
|
+
# When set it specify the bytecode version for compiled class files
|
104
|
+
# config.bytecode_version = "1.6"
|
105
|
+
|
106
|
+
# When set to true, Warbler will override the value of ENV['GEM_HOME'] even it
|
107
|
+
# has already been set. When set to false it will use any existing value of
|
108
|
+
# GEM_HOME if it is set.
|
109
|
+
# config.override_gem_home = true
|
110
|
+
|
111
|
+
# Allows for specifing custom executables
|
112
|
+
# config.executable = ["exe/hetzner-k3s"]
|
113
|
+
|
114
|
+
# Sets default (prefixed) parameters for the executables
|
115
|
+
# config.executable_params = "do:something"
|
116
|
+
|
117
|
+
# If set to true, moves jar files into WEB-INF/lib. Prior to version 1.4.2 of Warbler this was done
|
118
|
+
# by default. But since 1.4.2 this config defaults to false. It may need to be set to true for
|
119
|
+
# web servers that do not explode the WAR file.
|
120
|
+
# Alternatively, this option can be set to a regular expression, which will
|
121
|
+
# act as a jar selector -- only jar files that match the pattern will be
|
122
|
+
# included in the archive.
|
123
|
+
# config.move_jars_to_webinf_lib = false
|
124
|
+
|
125
|
+
# === War files only below here ===
|
126
|
+
|
127
|
+
# Embedded webserver to use with the 'executable' feature. Currently supported
|
128
|
+
# webservers are:
|
129
|
+
# - *jetty* - Embedded Jetty from Eclipse
|
130
|
+
# config.webserver = 'jetty'
|
131
|
+
|
132
|
+
# Path to the pre-bundled gem directory inside the war file. Default
|
133
|
+
# is 'WEB-INF/gems'. Specify path if gems are already bundled
|
134
|
+
# before running Warbler. This also sets 'gem.path' inside web.xml.
|
135
|
+
# config.gem_path = "WEB-INF/vendor/bundler_gems"
|
136
|
+
|
137
|
+
# Files for WEB-INF directory (next to web.xml). This contains
|
138
|
+
# web.xml by default. If there is an .erb-File it will be processed
|
139
|
+
# with webxml-config. You may want to exclude this file via
|
140
|
+
# config.excludes.
|
141
|
+
# config.webinf_files += FileList["jboss-web.xml"]
|
142
|
+
|
143
|
+
# Files to be included in the root of the webapp. Note that files in public
|
144
|
+
# will have the leading 'public/' part of the path stripped during staging.
|
145
|
+
# config.public_html = FileList["public/**/*", "doc/**/*"]
|
146
|
+
|
147
|
+
# Pathmaps for controlling how public HTML files are copied into the .war
|
148
|
+
# config.pathmaps.public_html = ["%{public/,}p"]
|
149
|
+
|
150
|
+
# Value of RAILS_ENV for the webapp -- default as shown below
|
151
|
+
# config.webxml.rails.env = ENV['RAILS_ENV'] || 'production'
|
152
|
+
|
153
|
+
# Public ROOT mapping, by default assets are copied into .war ROOT directory.
|
154
|
+
# config.public.root = ''
|
155
|
+
|
156
|
+
# Application booter to use, either :rack or :rails (autodetected by default)
|
157
|
+
# config.webxml.booter = :rails
|
158
|
+
|
159
|
+
# When using the :rack booter, "Rackup" script to use.
|
160
|
+
# - For 'rackup.path', the value points to the location of the rackup
|
161
|
+
# script in the web archive file. You need to make sure this file
|
162
|
+
# gets included in the war, possibly by adding it to config.includes
|
163
|
+
# or config.webinf_files above.
|
164
|
+
# - For 'rackup', the rackup script you provide as an inline string
|
165
|
+
# is simply embedded in web.xml.
|
166
|
+
# The script is evaluated in a Rack::Builder to load the application.
|
167
|
+
# Examples:
|
168
|
+
# config.webxml.rackup.path = 'WEB-INF/hello.ru'
|
169
|
+
# config.webxml.rackup = %{require './lib/demo'; run Rack::Adapter::Camping.new(Demo)}
|
170
|
+
# config.webxml.rackup = require 'cgi' && CGI::escapeHTML(File.read("config.ru"))
|
171
|
+
|
172
|
+
# Control the pool of Rails runtimes. Leaving unspecified means
|
173
|
+
# the pool will grow as needed to service requests. It is recommended
|
174
|
+
# that you fix these values when running a production server!
|
175
|
+
# If you're using threadsafe! mode, you probably don't want to set these values,
|
176
|
+
# since 1 runtime(default for threadsafe mode) will be enough.
|
177
|
+
# config.webxml.jruby.min.runtimes = 2
|
178
|
+
# config.webxml.jruby.max.runtimes = 4
|
179
|
+
|
180
|
+
# JNDI data source name
|
181
|
+
# config.webxml.jndi = 'jdbc/rails'
|
182
|
+
end
|
data/exe/hetzner-k3s
CHANGED
data/hetzner-k3s.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.description = 'A CLI to create a Kubernetes cluster in Hetzner Cloud very quickly using k3s.'
|
13
13
|
spec.homepage = 'https://github.com/vitobotta/hetzner-k3s'
|
14
14
|
spec.license = 'MIT'
|
15
|
-
spec.required_ruby_version = Gem::Requirement.new('
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new('~> 2.7.1')
|
16
16
|
|
17
17
|
# spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
|
18
18
|
|
@@ -20,12 +20,12 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.metadata['source_code_uri'] = 'https://github.com/vitobotta/hetzner-k3s'
|
21
21
|
spec.metadata['changelog_uri'] = 'https://github.com/vitobotta/hetzner-k3s'
|
22
22
|
|
23
|
-
spec.add_dependency '
|
23
|
+
spec.add_dependency 'childprocess'
|
24
24
|
spec.add_dependency 'ed25519'
|
25
|
-
spec.add_dependency '
|
25
|
+
spec.add_dependency 'httparty'
|
26
|
+
spec.add_dependency 'bcrypt_pbkdf'
|
26
27
|
spec.add_dependency 'net-ssh'
|
27
28
|
spec.add_dependency 'sshkey'
|
28
|
-
spec.add_dependency 'subprocess'
|
29
29
|
spec.add_dependency 'thor'
|
30
30
|
spec.add_development_dependency 'rubocop'
|
31
31
|
|
data/lib/hetzner/infra/client.rb
CHANGED
@@ -12,19 +12,19 @@ module Hetzner
|
|
12
12
|
|
13
13
|
def get(path)
|
14
14
|
make_request do
|
15
|
-
JSON.parse
|
15
|
+
JSON.parse HTTParty.get(BASE_URI + path, headers: headers).body
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
19
|
def post(path, data)
|
20
20
|
make_request do
|
21
|
-
|
21
|
+
HTTParty.post(BASE_URI + path, body: data.to_json, headers: headers)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
def delete(path, id)
|
26
26
|
make_request do
|
27
|
-
|
27
|
+
HTTParty.delete("#{BASE_URI}#{path}/#{id}", headers: headers)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -32,8 +32,8 @@ module Hetzner
|
|
32
32
|
|
33
33
|
def headers
|
34
34
|
{
|
35
|
-
Authorization
|
36
|
-
'Content-Type'
|
35
|
+
'Authorization' => "Bearer #{@token}",
|
36
|
+
'Content-Type' => 'application/json'
|
37
37
|
}
|
38
38
|
end
|
39
39
|
|
@@ -30,8 +30,8 @@ module Hetzner
|
|
30
30
|
|
31
31
|
def delete
|
32
32
|
if (network = find_network)
|
33
|
-
if network[
|
34
|
-
puts
|
33
|
+
if network['name'] == existing_network
|
34
|
+
puts 'Network existed before cluster, skipping.'
|
35
35
|
else
|
36
36
|
puts 'Deleting network...'
|
37
37
|
hetzner_client.delete('/networks', network['id'])
|
data/lib/hetzner/infra/server.rb
CHANGED
@@ -37,7 +37,6 @@ module Hetzner
|
|
37
37
|
else
|
38
38
|
puts "Error creating server #{server_name}. Response details below:"
|
39
39
|
puts
|
40
|
-
p response
|
41
40
|
end
|
42
41
|
end
|
43
42
|
|
@@ -99,8 +98,8 @@ module Hetzner
|
|
99
98
|
def server_config
|
100
99
|
@server_config ||= {
|
101
100
|
name: server_name,
|
102
|
-
location
|
103
|
-
image
|
101
|
+
location: location,
|
102
|
+
image: image,
|
104
103
|
firewalls: [
|
105
104
|
{ firewall: firewall_id }
|
106
105
|
],
|
@@ -111,7 +110,7 @@ module Hetzner
|
|
111
110
|
ssh_keys: [
|
112
111
|
ssh_key_id
|
113
112
|
],
|
114
|
-
user_data
|
113
|
+
user_data: user_data,
|
115
114
|
labels: {
|
116
115
|
cluster: cluster_name,
|
117
116
|
role: (server_name =~ /master/ ? 'master' : 'worker')
|
data/lib/hetzner/k3s/cli.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'thor'
|
4
|
-
require '
|
4
|
+
require 'openssl'
|
5
|
+
require 'httparty'
|
5
6
|
require 'sshkey'
|
6
7
|
require 'ipaddr'
|
7
8
|
require 'open-uri'
|
@@ -27,14 +28,14 @@ module Hetzner
|
|
27
28
|
option :config_file, required: true
|
28
29
|
def create_cluster
|
29
30
|
configuration.validate action: :create
|
30
|
-
Cluster.new(configuration:).create
|
31
|
+
Cluster.new(configuration: configuration).create
|
31
32
|
end
|
32
33
|
|
33
34
|
desc 'delete-cluster', 'Delete an existing k3s cluster in Hetzner Cloud'
|
34
35
|
option :config_file, required: true
|
35
36
|
def delete_cluster
|
36
37
|
configuration.validate action: :delete
|
37
|
-
Cluster.new(configuration:).delete
|
38
|
+
Cluster.new(configuration: configuration).delete
|
38
39
|
end
|
39
40
|
|
40
41
|
desc 'upgrade-cluster', 'Upgrade an existing k3s cluster in Hetzner Cloud to a new version'
|
@@ -43,7 +44,7 @@ module Hetzner
|
|
43
44
|
option :force, default: 'false'
|
44
45
|
def upgrade_cluster
|
45
46
|
configuration.validate action: :upgrade
|
46
|
-
Cluster.new(configuration:).upgrade(new_k3s_version: options[:new_k3s_version], config_file: options[:config_file])
|
47
|
+
Cluster.new(configuration: configuration).upgrade(new_k3s_version: options[:new_k3s_version], config_file: options[:config_file])
|
47
48
|
end
|
48
49
|
|
49
50
|
desc 'releases', 'List available k3s releases'
|
@@ -59,7 +60,7 @@ module Hetzner
|
|
59
60
|
|
60
61
|
def configuration
|
61
62
|
@configuration ||= begin
|
62
|
-
config = ::Hetzner::Configuration.new(options:)
|
63
|
+
config = ::Hetzner::Configuration.new(options: options)
|
63
64
|
@hetzner_token = config.hetzner_token
|
64
65
|
config
|
65
66
|
end
|
data/lib/hetzner/k3s/cluster.rb
CHANGED
@@ -4,7 +4,7 @@ require 'net/ssh'
|
|
4
4
|
require 'securerandom'
|
5
5
|
require 'base64'
|
6
6
|
require 'timeout'
|
7
|
-
require '
|
7
|
+
require 'fileutils'
|
8
8
|
|
9
9
|
require_relative '../infra/client'
|
10
10
|
require_relative '../infra/firewall'
|
@@ -93,7 +93,7 @@ class Cluster
|
|
93
93
|
end
|
94
94
|
|
95
95
|
def latest_k3s_version
|
96
|
-
response =
|
96
|
+
response = HTTParty.get('https://api.github.com/repos/k3s-io/k3s/tags').body
|
97
97
|
JSON.parse(response).first['name']
|
98
98
|
end
|
99
99
|
|
@@ -103,22 +103,22 @@ class Cluster
|
|
103
103
|
end
|
104
104
|
|
105
105
|
def delete_placement_groups
|
106
|
-
Hetzner::PlacementGroup.new(hetzner_client
|
106
|
+
Hetzner::PlacementGroup.new(hetzner_client: hetzner_client, cluster_name: cluster_name).delete
|
107
107
|
|
108
108
|
worker_node_pools.each do |pool|
|
109
109
|
pool_name = pool['name']
|
110
|
-
Hetzner::PlacementGroup.new(hetzner_client
|
110
|
+
Hetzner::PlacementGroup.new(hetzner_client: hetzner_client, cluster_name: cluster_name, pool_name: pool_name).delete
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
114
|
def delete_resources
|
115
|
-
Hetzner::LoadBalancer.new(hetzner_client
|
115
|
+
Hetzner::LoadBalancer.new(hetzner_client: hetzner_client, cluster_name: cluster_name).delete(high_availability: (masters.size > 1))
|
116
116
|
|
117
|
-
Hetzner::Firewall.new(hetzner_client
|
117
|
+
Hetzner::Firewall.new(hetzner_client: hetzner_client, cluster_name: cluster_name).delete(all_servers)
|
118
118
|
|
119
|
-
Hetzner::Network.new(hetzner_client
|
119
|
+
Hetzner::Network.new(hetzner_client: hetzner_client, cluster_name: cluster_name, existing_network: existing_network).delete
|
120
120
|
|
121
|
-
Hetzner::SSHKey.new(hetzner_client
|
121
|
+
Hetzner::SSHKey.new(hetzner_client: hetzner_client, cluster_name: cluster_name).delete(public_ssh_key_path: public_ssh_key_path)
|
122
122
|
|
123
123
|
delete_placement_groups
|
124
124
|
delete_servers
|
@@ -202,14 +202,14 @@ class Cluster
|
|
202
202
|
selected_version_index = available_k3s_releases.find_index(k3s_version)
|
203
203
|
|
204
204
|
flannel_wireguard = if enable_encryption
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
205
|
+
if selected_version_index >= wireguard_native_min_version_index
|
206
|
+
' --flannel-backend=wireguard-native '
|
207
|
+
else
|
208
|
+
' --flannel-backend=wireguard '
|
209
|
+
end
|
210
|
+
else
|
211
|
+
' '
|
212
|
+
end
|
213
213
|
|
214
214
|
extra_args = "#{kube_api_server_args_list} #{kube_scheduler_args_list} #{kube_controller_manager_args_list} #{kube_cloud_controller_manager_args_list} #{kubelet_args_list} #{kube_proxy_args_list}"
|
215
215
|
taint = schedule_workloads_on_masters? ? ' ' : ' --node-taint CriticalAddonsOnly=true:NoExecute '
|
@@ -423,7 +423,7 @@ class Cluster
|
|
423
423
|
|
424
424
|
masters.each do |master|
|
425
425
|
master_private_ip = master['private_net'][0]['ip']
|
426
|
-
sans
|
426
|
+
sans += " --tls-san=#{master_private_ip} "
|
427
427
|
end
|
428
428
|
|
429
429
|
sans
|
@@ -473,7 +473,7 @@ class Cluster
|
|
473
473
|
|
474
474
|
def placement_group_id(pool_name = nil)
|
475
475
|
@placement_groups ||= {}
|
476
|
-
@placement_groups[pool_name || '__masters__'] ||= Hetzner::PlacementGroup.new(hetzner_client
|
476
|
+
@placement_groups[pool_name || '__masters__'] ||= Hetzner::PlacementGroup.new(hetzner_client: hetzner_client, cluster_name: cluster_name, pool_name: pool_name).create
|
477
477
|
end
|
478
478
|
|
479
479
|
def master_instance_type
|
@@ -485,15 +485,15 @@ class Cluster
|
|
485
485
|
end
|
486
486
|
|
487
487
|
def firewall_id
|
488
|
-
@firewall_id ||= Hetzner::Firewall.new(hetzner_client
|
488
|
+
@firewall_id ||= Hetzner::Firewall.new(hetzner_client: hetzner_client, cluster_name: cluster_name).create(high_availability: (masters_count > 1), ssh_networks: ssh_networks, api_networks: api_networks)
|
489
489
|
end
|
490
490
|
|
491
491
|
def network_id
|
492
|
-
@network_id ||= Hetzner::Network.new(hetzner_client
|
492
|
+
@network_id ||= Hetzner::Network.new(hetzner_client: hetzner_client, cluster_name: cluster_name, existing_network: existing_network).create(location: masters_location)
|
493
493
|
end
|
494
494
|
|
495
495
|
def ssh_key_id
|
496
|
-
@ssh_key_id ||= Hetzner::SSHKey.new(hetzner_client
|
496
|
+
@ssh_key_id ||= Hetzner::SSHKey.new(hetzner_client: hetzner_client, cluster_name: cluster_name).create(public_ssh_key_path: public_ssh_key_path)
|
497
497
|
end
|
498
498
|
|
499
499
|
def master_definitions_for_create
|
@@ -504,13 +504,13 @@ class Cluster
|
|
504
504
|
instance_type: master_instance_type,
|
505
505
|
instance_id: "master#{i + 1}",
|
506
506
|
location: masters_location,
|
507
|
-
placement_group_id
|
508
|
-
firewall_id
|
509
|
-
network_id
|
510
|
-
ssh_key_id
|
511
|
-
image
|
512
|
-
additional_packages
|
513
|
-
additional_post_create_commands:
|
507
|
+
placement_group_id: placement_group_id,
|
508
|
+
firewall_id: firewall_id,
|
509
|
+
network_id: network_id,
|
510
|
+
ssh_key_id: ssh_key_id,
|
511
|
+
image: image,
|
512
|
+
additional_packages: additional_packages,
|
513
|
+
additional_post_create_commands: additional_post_create_commands
|
514
514
|
}
|
515
515
|
end
|
516
516
|
|
@@ -544,12 +544,12 @@ class Cluster
|
|
544
544
|
instance_id: "pool-#{worker_node_pool_name}-worker#{i + 1}",
|
545
545
|
placement_group_id: placement_group_id(worker_node_pool_name),
|
546
546
|
location: worker_location,
|
547
|
-
firewall_id
|
548
|
-
network_id
|
549
|
-
ssh_key_id
|
550
|
-
image
|
551
|
-
additional_packages
|
552
|
-
additional_post_create_commands:
|
547
|
+
firewall_id: firewall_id,
|
548
|
+
network_id: network_id,
|
549
|
+
ssh_key_id: ssh_key_id,
|
550
|
+
image: image,
|
551
|
+
additional_packages: additional_packages,
|
552
|
+
additional_post_create_commands: additional_post_create_commands
|
553
553
|
}
|
554
554
|
end
|
555
555
|
|
@@ -557,7 +557,7 @@ class Cluster
|
|
557
557
|
end
|
558
558
|
|
559
559
|
def create_load_balancer
|
560
|
-
Hetzner::LoadBalancer.new(hetzner_client
|
560
|
+
Hetzner::LoadBalancer.new(hetzner_client: hetzner_client, cluster_name: cluster_name).create(location: masters_location, network_id: network_id)
|
561
561
|
end
|
562
562
|
|
563
563
|
def server_configs
|
@@ -577,7 +577,7 @@ class Cluster
|
|
577
577
|
|
578
578
|
threads = server_configs.map do |server_config|
|
579
579
|
Thread.new do
|
580
|
-
servers << Hetzner::Server.new(hetzner_client
|
580
|
+
servers << Hetzner::Server.new(hetzner_client: hetzner_client, cluster_name: cluster_name).create(**server_config)
|
581
581
|
end
|
582
582
|
end
|
583
583
|
|
@@ -599,7 +599,7 @@ class Cluster
|
|
599
599
|
def delete_servers
|
600
600
|
threads = all_servers.map do |server|
|
601
601
|
Thread.new do
|
602
|
-
Hetzner::Server.new(hetzner_client
|
602
|
+
Hetzner::Server.new(hetzner_client: hetzner_client, cluster_name: cluster_name).delete(server_name: server['name'])
|
603
603
|
end
|
604
604
|
end
|
605
605
|
|
@@ -659,6 +659,6 @@ class Cluster
|
|
659
659
|
end
|
660
660
|
|
661
661
|
def existing_network
|
662
|
-
configuration[
|
662
|
+
configuration['existing_network']
|
663
663
|
end
|
664
664
|
end
|
@@ -92,12 +92,10 @@ module Hetzner
|
|
92
92
|
configuration
|
93
93
|
end
|
94
94
|
|
95
|
-
|
96
|
-
|
97
|
-
attr_reader :configuration, :errors, :options
|
95
|
+
private_class_method
|
98
96
|
|
99
97
|
def self.fetch_releases(url)
|
100
|
-
response =
|
98
|
+
response = HTTParty.get(url)
|
101
99
|
[response, JSON.parse(response.body).map { |hash| hash['name'] }]
|
102
100
|
end
|
103
101
|
|
@@ -121,13 +119,17 @@ module Hetzner
|
|
121
119
|
end
|
122
120
|
end
|
123
121
|
|
122
|
+
private
|
123
|
+
|
124
|
+
attr_reader :configuration, :errors, :options
|
125
|
+
|
124
126
|
def validate_create
|
125
127
|
validate_public_ssh_key
|
126
128
|
validate_private_ssh_key
|
127
129
|
validate_ssh_allowed_networks
|
128
130
|
validate_api_allowed_networks
|
129
131
|
validate_masters_location
|
130
|
-
validate_k3s_version
|
132
|
+
# validate_k3s_version
|
131
133
|
validate_masters
|
132
134
|
validate_worker_node_pools
|
133
135
|
validate_verify_host_key
|
@@ -144,7 +146,7 @@ module Hetzner
|
|
144
146
|
|
145
147
|
def validate_upgrade
|
146
148
|
validate_kubeconfig_path_must_exist
|
147
|
-
validate_new_k3s_version
|
149
|
+
# validate_new_k3s_version
|
148
150
|
end
|
149
151
|
|
150
152
|
def validate_public_ssh_key
|
@@ -399,7 +401,7 @@ module Hetzner
|
|
399
401
|
|
400
402
|
begin
|
401
403
|
token = hetzner_token
|
402
|
-
@hetzner_client = Hetzner::Client.new(token:)
|
404
|
+
@hetzner_client = Hetzner::Client.new(token: token)
|
403
405
|
response = hetzner_client.get('/locations')
|
404
406
|
error_code = response.dig('error', 'code')
|
405
407
|
@valid = error_code != 'unauthorized'
|
@@ -472,13 +474,13 @@ module Hetzner
|
|
472
474
|
end
|
473
475
|
|
474
476
|
def validate_existing_network
|
475
|
-
|
476
|
-
existing_network = Hetzner::Network.new(hetzner_client:, cluster_name: configuration["cluster_name"], existing_network: configuration["existing_network"]).get
|
477
|
+
return unless configuration['existing_network']
|
477
478
|
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
479
|
+
existing_network = Hetzner::Network.new(hetzner_client: hetzner_client, cluster_name: configuration['cluster_name'], existing_network: configuration['existing_network']).get
|
480
|
+
|
481
|
+
return if existing_network
|
482
|
+
|
483
|
+
@errors << "You have specified that you want to use the existing network named '#{configuration['existing_network']} but this network doesn't exist"
|
482
484
|
end
|
483
485
|
end
|
484
486
|
end
|
data/lib/hetzner/k3s/version.rb
CHANGED
data/lib/hetzner/utils.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
Net::SSH::Transport::Algorithms::ALGORITHMS.values.each { |algs| algs.reject! { |a| a =~ /^ecd(sa|h)-sha2/ } }
|
4
|
+
Net::SSH::KnownHosts::SUPPORTED_TYPE.reject! { |t| t =~ /^ecd(sa|h)-sha2/ }
|
5
|
+
|
6
|
+
require 'childprocess'
|
7
|
+
|
3
8
|
module Utils
|
4
9
|
CMD_FILE_PATH = '/tmp/cli.cmd'
|
5
10
|
|
@@ -19,8 +24,6 @@ module Utils
|
|
19
24
|
end
|
20
25
|
|
21
26
|
def run(command, kubeconfig_path:)
|
22
|
-
env = ENV.to_hash.merge({ 'KUBECONFIG' => kubeconfig_path })
|
23
|
-
|
24
27
|
write_file CMD_FILE_PATH, <<-CONTENT
|
25
28
|
set -euo pipefail
|
26
29
|
#{command}
|
@@ -29,20 +32,19 @@ module Utils
|
|
29
32
|
FileUtils.chmod('+x', CMD_FILE_PATH)
|
30
33
|
|
31
34
|
begin
|
32
|
-
process =
|
35
|
+
process = ChildProcess.build('bash', '-c', CMD_FILE_PATH)
|
36
|
+
process.io.inherit!
|
37
|
+
process.environment['KUBECONFIG'] = kubeconfig_path
|
38
|
+
process.environment['HCLOUD_TOKEN'] = ENV.fetch('HCLOUD_TOKEN', '')
|
33
39
|
|
34
40
|
at_exit do
|
35
|
-
process
|
41
|
+
process.stop
|
36
42
|
rescue Errno::ESRCH, Interrupt
|
37
43
|
# ignore
|
38
44
|
end
|
39
45
|
|
40
|
-
|
41
|
-
|
42
|
-
end
|
43
|
-
rescue Subprocess::NonZeroExit
|
44
|
-
puts 'Command failed: non-zero exit code'
|
45
|
-
exit 1
|
46
|
+
process.start
|
47
|
+
process.wait
|
46
48
|
rescue Interrupt
|
47
49
|
puts 'Command interrupted'
|
48
50
|
exit 1
|
@@ -86,6 +88,13 @@ module Utils
|
|
86
88
|
end
|
87
89
|
end
|
88
90
|
output.chop
|
91
|
+
# rescue StandardError => e
|
92
|
+
# p [e.class, e.message]
|
93
|
+
# retries += 1
|
94
|
+
# retry unless retries > 15 || e.message =~ /Bad file descriptor/
|
95
|
+
rescue Timeout::Error, IOError, Errno::EBADF
|
96
|
+
retries += 1
|
97
|
+
retry unless retries > 15
|
89
98
|
rescue Net::SSH::Disconnect => e
|
90
99
|
retries += 1
|
91
100
|
retry unless retries > 15 || e.message =~ /Too many authentication failures/
|
metadata
CHANGED
@@ -1,122 +1,122 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hetzner-k3s
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0.pre1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vito Botta
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-08-
|
11
|
+
date: 2022-08-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name: bcrypt_pbkdf
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
16
15
|
requirements:
|
17
16
|
- - ">="
|
18
17
|
- !ruby/object:Gem::Version
|
19
18
|
version: '0'
|
20
|
-
|
19
|
+
name: childprocess
|
21
20
|
prerelease: false
|
21
|
+
type: :runtime
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name: ed25519
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
30
29
|
requirements:
|
31
30
|
- - ">="
|
32
31
|
- !ruby/object:Gem::Version
|
33
32
|
version: '0'
|
34
|
-
|
33
|
+
name: ed25519
|
35
34
|
prerelease: false
|
35
|
+
type: :runtime
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name: http
|
43
42
|
requirement: !ruby/object:Gem::Requirement
|
44
43
|
requirements:
|
45
44
|
- - ">="
|
46
45
|
- !ruby/object:Gem::Version
|
47
46
|
version: '0'
|
48
|
-
|
47
|
+
name: httparty
|
49
48
|
prerelease: false
|
49
|
+
type: :runtime
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name: net-ssh
|
57
56
|
requirement: !ruby/object:Gem::Requirement
|
58
57
|
requirements:
|
59
58
|
- - ">="
|
60
59
|
- !ruby/object:Gem::Version
|
61
60
|
version: '0'
|
62
|
-
|
61
|
+
name: bcrypt_pbkdf
|
63
62
|
prerelease: false
|
63
|
+
type: :runtime
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name: sshkey
|
71
70
|
requirement: !ruby/object:Gem::Requirement
|
72
71
|
requirements:
|
73
72
|
- - ">="
|
74
73
|
- !ruby/object:Gem::Version
|
75
74
|
version: '0'
|
76
|
-
|
75
|
+
name: net-ssh
|
77
76
|
prerelease: false
|
77
|
+
type: :runtime
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name: subprocess
|
85
84
|
requirement: !ruby/object:Gem::Requirement
|
86
85
|
requirements:
|
87
86
|
- - ">="
|
88
87
|
- !ruby/object:Gem::Version
|
89
88
|
version: '0'
|
90
|
-
|
89
|
+
name: sshkey
|
91
90
|
prerelease: false
|
91
|
+
type: :runtime
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name: thor
|
99
98
|
requirement: !ruby/object:Gem::Requirement
|
100
99
|
requirements:
|
101
100
|
- - ">="
|
102
101
|
- !ruby/object:Gem::Version
|
103
102
|
version: '0'
|
104
|
-
|
103
|
+
name: thor
|
105
104
|
prerelease: false
|
105
|
+
type: :runtime
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
|
-
name: rubocop
|
113
112
|
requirement: !ruby/object:Gem::Requirement
|
114
113
|
requirements:
|
115
114
|
- - ">="
|
116
115
|
- !ruby/object:Gem::Version
|
117
116
|
version: '0'
|
118
|
-
|
117
|
+
name: rubocop
|
119
118
|
prerelease: false
|
119
|
+
type: :development
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - ">="
|
@@ -131,6 +131,7 @@ executables:
|
|
131
131
|
extensions: []
|
132
132
|
extra_rdoc_files: []
|
133
133
|
files:
|
134
|
+
- ".github/workflows/release.yml"
|
134
135
|
- ".gitignore"
|
135
136
|
- ".rspec"
|
136
137
|
- ".rubocop.yml"
|
@@ -147,6 +148,7 @@ files:
|
|
147
148
|
- bin/console.sh
|
148
149
|
- bin/setup.sh
|
149
150
|
- cluster_config.yaml.example
|
151
|
+
- config/warble.rb
|
150
152
|
- entrypoint.sh
|
151
153
|
- exe/hetzner-k3s
|
152
154
|
- hetzner-k3s.gemspec
|
@@ -178,16 +180,16 @@ require_paths:
|
|
178
180
|
- lib
|
179
181
|
required_ruby_version: !ruby/object:Gem::Requirement
|
180
182
|
requirements:
|
181
|
-
- - "
|
183
|
+
- - "~>"
|
182
184
|
- !ruby/object:Gem::Version
|
183
|
-
version:
|
185
|
+
version: 2.7.1
|
184
186
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
185
187
|
requirements:
|
186
|
-
- - "
|
188
|
+
- - ">"
|
187
189
|
- !ruby/object:Gem::Version
|
188
|
-
version:
|
190
|
+
version: 1.3.1
|
189
191
|
requirements: []
|
190
|
-
rubygems_version: 3.
|
192
|
+
rubygems_version: 3.2.29
|
191
193
|
signing_key:
|
192
194
|
specification_version: 4
|
193
195
|
summary: A CLI to create a Kubernetes cluster in Hetzner Cloud very quickly using
|