kerbi 0.0.2 → 0.0.6
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 +4 -4
- data/lib/cli/base_handler.rb +18 -4
- data/lib/cli/release_handler.rb +41 -0
- data/lib/cli/release_serializer.rb +46 -0
- data/lib/cli/root_handler.rb +2 -0
- data/lib/cli/state_handler.rb +16 -23
- data/{boilerplate → lib/code-gen/new-project}/Gemfile.erb +0 -0
- data/lib/code-gen/new-project/kerbifile.rb.erb +9 -0
- data/lib/code-gen/new-project/values.yaml.erb +1 -0
- data/lib/config/cli_schema.rb +70 -27
- data/lib/config/run_opts.rb +13 -1
- data/lib/config/state_consts.rb +2 -1
- data/lib/kerbi.rb +4 -1
- data/lib/main/code_gen.rb +1 -1
- data/lib/main/errors.rb +6 -0
- data/lib/main/mixer.rb +8 -2
- data/lib/mixins/cli_state_helpers.rb +5 -33
- data/lib/mixins/cm_backend_testing.rb +18 -4
- data/lib/state/base_backend.rb +34 -0
- data/lib/state/config_map_backend.rb +72 -18
- data/lib/state/resources.yaml.erb +3 -3
- data/lib/utils/cli.rb +32 -0
- data/spec/cli/config_handler_spec.rb +32 -32
- data/spec/cli/release_handler_spec.rb +128 -0
- data/spec/cli/root_handler_spec.rb +12 -11
- data/spec/cli/state_handler_spec.rb +21 -52
- data/spec/{expectations → fixtures/expectations}/common/bad-tag.txt +0 -0
- data/spec/{expectations → fixtures/expectations}/config/bad-set.txt +0 -0
- data/spec/{expectations → fixtures/expectations}/config/set.txt +0 -0
- data/spec/{expectations → fixtures/expectations}/config/show-default.yaml +0 -0
- data/spec/fixtures/expectations/release/delete.txt +1 -0
- data/spec/fixtures/expectations/release/init-already-existed.txt +2 -0
- data/spec/fixtures/expectations/release/init-both-created.txt +2 -0
- data/spec/fixtures/expectations/release/list.txt +5 -0
- data/spec/{expectations/state → fixtures/expectations/release}/status-all-working.txt +2 -1
- data/spec/fixtures/expectations/release/status-data-unreadable.txt +5 -0
- data/spec/{expectations/state → fixtures/expectations/release}/status-not-provisioned.txt +2 -1
- data/spec/{expectations → fixtures/expectations}/root/template-inlines.yaml +2 -2
- data/spec/{expectations → fixtures/expectations}/root/template-production.yaml +2 -2
- data/spec/{expectations → fixtures/expectations}/root/template-read-inlines.yaml +4 -4
- data/spec/{expectations → fixtures/expectations}/root/template-read.yaml +4 -4
- data/spec/{expectations → fixtures/expectations}/root/template-write.yaml +4 -4
- data/spec/{expectations → fixtures/expectations}/root/template.yaml +2 -2
- data/spec/{expectations → fixtures/expectations}/root/values.json +0 -0
- data/spec/{expectations → fixtures/expectations}/state/delete.txt +0 -0
- data/spec/{expectations → fixtures/expectations}/state/demote.txt +0 -0
- data/spec/{expectations → fixtures/expectations}/state/list.json +0 -0
- data/spec/{expectations → fixtures/expectations}/state/list.txt +0 -0
- data/spec/{expectations → fixtures/expectations}/state/list.yaml +0 -0
- data/spec/{expectations → fixtures/expectations}/state/promote.txt +0 -0
- data/spec/{expectations → fixtures/expectations}/state/prune-candidates.txt +0 -0
- data/spec/{expectations → fixtures/expectations}/state/retag.txt +0 -0
- data/spec/{expectations → fixtures/expectations}/state/set.txt +0 -0
- data/spec/{expectations → fixtures/expectations}/state/show.json +0 -0
- data/spec/{expectations → fixtures/expectations}/state/show.txt +0 -0
- data/spec/{expectations → fixtures/expectations}/state/show.yaml +0 -0
- data/spec/{expectations → fixtures/expectations}/values/order-of-precedence.yaml +0 -0
- data/spec/main/configmap_backend_spec.rb +14 -13
- data/spec/main/project_code_gen_spec.rb +8 -2
- data/spec/mini-projects/hello-kerbi/common/metadata.yaml.erb +5 -0
- data/spec/mini-projects/hello-kerbi/consts.rb +5 -0
- data/spec/mini-projects/hello-kerbi/helpers.rb +8 -0
- data/spec/mini-projects/hello-kerbi/kerbifile.rb +18 -0
- data/spec/mini-projects/hello-kerbi/pod-and-service.yaml.erb +23 -0
- data/spec/mini-projects/hello-kerbi/values/production.yaml +2 -0
- data/spec/mini-projects/hello-kerbi/values/v2.yaml +2 -0
- data/spec/mini-projects/hello-kerbi/values/values.yaml +4 -0
- data/spec/spec_helper.rb +67 -11
- data/spec/utils/helm_spec.rb +89 -89
- data/spec/utils/k8s_auth_spec.rb +28 -28
- metadata +87 -61
- data/boilerplate/kerbifile.rb.erb +0 -9
- data/boilerplate/values.yaml.erb +0 -1
- data/spec/expectations/state/init-already-existed.txt +0 -2
- data/spec/expectations/state/init-both-created.txt +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 937fb81498f6daddbe5c1423bf45305308d5efc0c470cb9cdf2c768833a74309
|
4
|
+
data.tar.gz: 5029481946997af877014f2c6978734ee0b3170fbf95f1ec2d466a65b65186c0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f727c0838420f27c8e84e08dfb0b4c1da69a9e3543a36d513fc02701873b7f1a742381561e62a435958a7625446fda4d1e628c885fd004491971eb8c33dcbb9
|
7
|
+
data.tar.gz: 50223a1ee355ad1bf47152e0ac9c9309a3490382caf2366db30bb15dceaa9431453cffc4c8d163aa93357da85a5982fe08a430af2a06a7e801f75c4cade31edf
|
data/lib/cli/base_handler.rb
CHANGED
@@ -11,10 +11,12 @@ module Kerbi
|
|
11
11
|
##
|
12
12
|
# Convenience method for instantiating (and memoizating) a state
|
13
13
|
# management backend.
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
def state_backend(**opts)
|
15
|
+
@_state_backend ||= generate_state_backend(**opts)
|
16
|
+
end
|
17
|
+
|
18
|
+
def mem_release_name(release_name)
|
19
|
+
self.run_opts.release_name = release_name
|
18
20
|
end
|
19
21
|
|
20
22
|
##
|
@@ -170,6 +172,18 @@ module Kerbi
|
|
170
172
|
true
|
171
173
|
end
|
172
174
|
|
175
|
+
def user_confirmed?(message='Are you sure?')
|
176
|
+
unless run_opts.confirmed?
|
177
|
+
end_with = "Enter 'yes' to confirm or re-run with --confirm."
|
178
|
+
echo("#{message} #{end_with}")
|
179
|
+
unless STDIN.gets.strip.downcase == "yes"
|
180
|
+
echo("Aborted")
|
181
|
+
return false
|
182
|
+
end
|
183
|
+
end
|
184
|
+
true
|
185
|
+
end
|
186
|
+
|
173
187
|
private
|
174
188
|
|
175
189
|
def utils
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Kerbi
|
2
|
+
module Cli
|
3
|
+
class ReleaseHandler < BaseHandler
|
4
|
+
|
5
|
+
cmd_meta Kerbi::Consts::CommandSchemas::INIT_RELEASE
|
6
|
+
# @param [String] release_name refers to a Kubernetes namespace
|
7
|
+
def init(release_name)
|
8
|
+
mem_release_name(release_name)
|
9
|
+
state_backend.provision_missing_resources(verbose: run_opts.verbose?)
|
10
|
+
ns_key = Kerbi::Consts::OptionSchemas::NAMESPACE
|
11
|
+
Kerbi::ConfigFile.patch({ns_key => release_name})
|
12
|
+
end
|
13
|
+
|
14
|
+
cmd_meta Kerbi::Consts::CommandSchemas::RELEASE_STATUS
|
15
|
+
def status(release_name)
|
16
|
+
mem_release_name(release_name)
|
17
|
+
backend = state_backend
|
18
|
+
backend.test_connection(verbose: run_opts.verbose?)
|
19
|
+
end
|
20
|
+
|
21
|
+
cmd_meta Kerbi::Consts::CommandSchemas::RELEASE_LIST
|
22
|
+
def list
|
23
|
+
prep_opts(Kerbi::Consts::OptionDefaults::LIST_STATE)
|
24
|
+
auth_bundle = Kerbi::Utils::Cli.make_k8s_auth_bundle(run_opts)
|
25
|
+
backends = Kerbi::State::ConfigMapBackend.releases(auth_bundle)
|
26
|
+
backends.each(&:prime)
|
27
|
+
echo_data(backends, serializer: Kerbi::Cli::ReleaseSerializer)
|
28
|
+
end
|
29
|
+
|
30
|
+
cmd_meta Kerbi::Consts::CommandSchemas::RELEASE_DELETE
|
31
|
+
def delete(release_name)
|
32
|
+
mem_release_name(release_name)
|
33
|
+
backend = state_backend
|
34
|
+
return unless user_confirmed?
|
35
|
+
old_signature = backend.resource_signature
|
36
|
+
backend.delete
|
37
|
+
echo("Deleted #{old_signature}")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Kerbi
|
2
|
+
module Cli
|
3
|
+
class ReleaseSerializer < Kerbi::Cli::BaseSerializer
|
4
|
+
has_attributes(
|
5
|
+
:name,
|
6
|
+
:backend,
|
7
|
+
:namespace,
|
8
|
+
:resource,
|
9
|
+
:states,
|
10
|
+
:latest
|
11
|
+
)
|
12
|
+
|
13
|
+
def name
|
14
|
+
object.release_name
|
15
|
+
end
|
16
|
+
|
17
|
+
def backend
|
18
|
+
object.class.type_signature
|
19
|
+
end
|
20
|
+
|
21
|
+
def resource
|
22
|
+
object.resource_name
|
23
|
+
end
|
24
|
+
|
25
|
+
def states
|
26
|
+
if object.working?
|
27
|
+
object.entries.count
|
28
|
+
else
|
29
|
+
broken_txt
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def latest
|
34
|
+
if object.working?
|
35
|
+
object.entry_set.latest&.tag
|
36
|
+
else
|
37
|
+
broken_txt
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def broken_txt
|
42
|
+
"ERR"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/cli/root_handler.rb
CHANGED
@@ -34,6 +34,7 @@ module Kerbi
|
|
34
34
|
cmd_meta Kerbi::Consts::CommandSchemas::TEMPLATE
|
35
35
|
# @param [String] release_name helm-like Kubernetes release name
|
36
36
|
def template(release_name)
|
37
|
+
mem_release_name(release_name)
|
37
38
|
utils::Cli.load_kerbifile(run_opts.project_root)
|
38
39
|
values = compile_values
|
39
40
|
persist_compiled_values
|
@@ -59,6 +60,7 @@ module Kerbi
|
|
59
60
|
|
60
61
|
sub_cmd_meta Kerbi::Consts::CommandSchemas::VALUES_SUPER, ValuesHandler
|
61
62
|
sub_cmd_meta Kerbi::Consts::CommandSchemas::PROJECT_SUPER, ProjectHandler
|
63
|
+
sub_cmd_meta Kerbi::Consts::CommandSchemas::RELEASE_SUPER, ReleaseHandler
|
62
64
|
sub_cmd_meta Kerbi::Consts::CommandSchemas::STATE_SUPER, StateHandler
|
63
65
|
sub_cmd_meta Kerbi::Consts::CommandSchemas::CONFIG_SUPER, ConfigHandler
|
64
66
|
end
|
data/lib/cli/state_handler.rb
CHANGED
@@ -1,24 +1,10 @@
|
|
1
1
|
module Kerbi
|
2
2
|
module Cli
|
3
3
|
class StateHandler < BaseHandler
|
4
|
-
cmd_meta Kerbi::Consts::CommandSchemas::INIT_STATE
|
5
|
-
# @param [String] namespace refers to a Kubernetes namespace
|
6
|
-
def init(namespace)
|
7
|
-
state_backend(namespace).provision_missing_resources(
|
8
|
-
verbose: run_opts.verbose?
|
9
|
-
)
|
10
|
-
ns_key = Kerbi::Consts::OptionSchemas::NAMESPACE
|
11
|
-
Kerbi::ConfigFile.patch({ns_key => namespace})
|
12
|
-
end
|
13
|
-
|
14
|
-
cmd_meta Kerbi::Consts::CommandSchemas::STATE_STATUS
|
15
|
-
def status
|
16
|
-
state_backend.test_connection(verbose: run_opts.verbose?)
|
17
|
-
end
|
18
|
-
|
19
4
|
cmd_meta Kerbi::Consts::CommandSchemas::LIST_STATE
|
20
|
-
def list
|
5
|
+
def list(release_name)
|
21
6
|
prep_opts(Kerbi::Consts::OptionDefaults::LIST_STATE)
|
7
|
+
mem_release_name(release_name)
|
22
8
|
echo_data(
|
23
9
|
state_backend.entries,
|
24
10
|
table_serializer: Kerbi::Cli::EntryRowSerializer,
|
@@ -28,8 +14,9 @@ module Kerbi
|
|
28
14
|
|
29
15
|
cmd_meta Kerbi::Consts::CommandSchemas::SHOW_STATE
|
30
16
|
# @param [String] tag_expr e.g 1.9.1, @latest
|
31
|
-
def show(tag_expr)
|
17
|
+
def show(release_name, tag_expr)
|
32
18
|
prep_opts(Kerbi::Consts::OptionDefaults::LIST_STATE)
|
19
|
+
mem_release_name(release_name)
|
33
20
|
entry = find_readable_entry(tag_expr)
|
34
21
|
echo_data(
|
35
22
|
entry,
|
@@ -41,7 +28,8 @@ module Kerbi
|
|
41
28
|
cmd_meta Kerbi::Consts::CommandSchemas::RETAG_STATE
|
42
29
|
# @param [String] old_tag_expr e.g 1.9.1, @latest
|
43
30
|
# @param [String] new_tag_expr e.g 1.9.1, @latest
|
44
|
-
def retag(old_tag_expr, new_tag_expr)
|
31
|
+
def retag(release_name, old_tag_expr, new_tag_expr)
|
32
|
+
mem_release_name(release_name)
|
45
33
|
entry = find_readable_entry(old_tag_expr)
|
46
34
|
old_tag = entry.retag(new_tag_expr)
|
47
35
|
touch_and_save_entry(entry, tag: old_tag)
|
@@ -49,7 +37,8 @@ module Kerbi
|
|
49
37
|
|
50
38
|
cmd_meta Kerbi::Consts::CommandSchemas::PROMOTE_STATE
|
51
39
|
# @param [String] tag_expr e.g 1.9.1, @latest
|
52
|
-
def promote(tag_expr)
|
40
|
+
def promote(release_name, tag_expr)
|
41
|
+
mem_release_name(release_name)
|
53
42
|
entry = find_readable_entry(tag_expr)
|
54
43
|
old_name = entry.promote
|
55
44
|
touch_and_save_entry(entry, tag: old_name)
|
@@ -57,7 +46,8 @@ module Kerbi
|
|
57
46
|
|
58
47
|
cmd_meta Kerbi::Consts::CommandSchemas::DEMOTE_STATE
|
59
48
|
# @param [String] tag_expr e.g 1.9.1, @latest
|
60
|
-
def demote(tag_expr)
|
49
|
+
def demote(release_name, tag_expr)
|
50
|
+
mem_release_name(release_name)
|
61
51
|
entry = find_readable_entry(tag_expr)
|
62
52
|
old_name = entry.demote
|
63
53
|
touch_and_save_entry(entry, tag: old_name)
|
@@ -67,7 +57,8 @@ module Kerbi
|
|
67
57
|
# @param [String] tag_expr e.g 1.9.1, @latest
|
68
58
|
# @param [String] attr_name e.g message
|
69
59
|
# @param [String] new_value e.g i am a new message
|
70
|
-
def set(tag_expr, attr_name, new_value)
|
60
|
+
def set(release_name, tag_expr, attr_name, new_value)
|
61
|
+
mem_release_name(release_name)
|
71
62
|
entry = find_readable_entry(tag_expr)
|
72
63
|
old_value = entry.assign_attr(attr_name, new_value)
|
73
64
|
touch_and_save_entry(entry, attr_name => old_value)
|
@@ -75,7 +66,8 @@ module Kerbi
|
|
75
66
|
|
76
67
|
cmd_meta Kerbi::Consts::CommandSchemas::DELETE_STATE
|
77
68
|
# @param [String] tag_expr e.g 1.9.1, @latest
|
78
|
-
def delete(tag_expr)
|
69
|
+
def delete(release_name, tag_expr)
|
70
|
+
mem_release_name(release_name)
|
79
71
|
entry = find_readable_entry(tag_expr)
|
80
72
|
state_backend.delete_entry(entry)
|
81
73
|
new_count = state_backend.entries.count
|
@@ -83,7 +75,8 @@ module Kerbi
|
|
83
75
|
end
|
84
76
|
|
85
77
|
cmd_meta Kerbi::Consts::CommandSchemas::PRUNE_CANDIDATES_STATE
|
86
|
-
def prune_candidates
|
78
|
+
def prune_candidates(release_name)
|
79
|
+
mem_release_name(release_name)
|
87
80
|
old_count = entry_set.entries.count
|
88
81
|
entry_set.prune_candidates
|
89
82
|
state_backend.save
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
message: "normal"
|
data/lib/config/cli_schema.rb
CHANGED
@@ -11,6 +11,7 @@ module Kerbi
|
|
11
11
|
|
12
12
|
RUBY_VER = "ruby-version"
|
13
13
|
VERBOSE = "verbose"
|
14
|
+
PRE_CONFIRM = "confirm"
|
14
15
|
|
15
16
|
STATE_BACKEND_TYPE = "state-backend"
|
16
17
|
READ_STATE = "read-state"
|
@@ -19,21 +20,21 @@ module Kerbi
|
|
19
20
|
NAMESPACE = "namespace"
|
20
21
|
WRITE_STATE_MESSAGE = "message"
|
21
22
|
|
22
|
-
K8S_AUTH_TYPE = "auth-type"
|
23
|
+
K8S_AUTH_TYPE = "k8s-auth-type"
|
23
24
|
KUBE_CONFIG_PATH = "kube-config-path"
|
24
25
|
KUBE_CONFIG_CONTEXT = "kube-config-context"
|
25
|
-
|
26
|
-
|
27
|
-
|
26
|
+
KUBE_ACCESS_TOKEN = "k8s-access-token"
|
27
|
+
K8S_USERNAME = "k8s-username"
|
28
|
+
K8S_PASSWORD = "k8s-password"
|
29
|
+
K8S_TOKEN = "k8s-access-token"
|
28
30
|
|
29
31
|
LEGAL_CONFIG_FILE_KEYS = [
|
30
32
|
STATE_BACKEND_TYPE,
|
31
|
-
NAMESPACE,
|
32
33
|
K8S_AUTH_TYPE,
|
33
34
|
KUBE_CONFIG_CONTEXT,
|
34
35
|
K8S_USERNAME,
|
35
36
|
K8S_PASSWORD,
|
36
|
-
|
37
|
+
KUBE_ACCESS_TOKEN
|
37
38
|
]
|
38
39
|
end
|
39
40
|
|
@@ -50,19 +51,25 @@ module Kerbi
|
|
50
51
|
LIST_STATE = BASE.merge(
|
51
52
|
OptionKeys::OUTPUT_FMT => "table"
|
52
53
|
).freeze
|
54
|
+
|
55
|
+
LIST_RELEASE = BASE.merge(
|
56
|
+
OptionKeys::OUTPUT_FMT => "table"
|
57
|
+
).freeze
|
53
58
|
end
|
54
59
|
|
55
60
|
module OptionSchemas
|
56
61
|
|
57
62
|
PROJECT_ROOT = {
|
58
63
|
key: OptionKeys::PROJECT_ROOT,
|
59
|
-
desc: "Project root. An abs path, a rel path,
|
64
|
+
desc: "Project root. An abs path, a rel path, "\
|
65
|
+
"or remote (/foo, foo, @foo/bar)",
|
60
66
|
aliases: "-p"
|
61
67
|
}
|
62
68
|
|
63
69
|
K8S_AUTH_TYPE = {
|
64
70
|
key: OptionKeys::K8S_AUTH_TYPE,
|
65
|
-
desc: "Strategy for connecting to target cluster
|
71
|
+
desc: "Strategy for connecting to target cluster "\
|
72
|
+
"(defaults to kube-config)",
|
66
73
|
enum: %w[kube-config in-cluster basic token]
|
67
74
|
}.freeze
|
68
75
|
|
@@ -101,7 +108,8 @@ defaults to $(kubectl config current-context)"
|
|
101
108
|
|
102
109
|
STATE_BACKEND_TYPE = {
|
103
110
|
key: OptionKeys::STATE_BACKEND_TYPE,
|
104
|
-
desc: "Persistent store to keep track of applied
|
111
|
+
desc: "Persistent store to keep track of applied "\
|
112
|
+
"values (configmap, secret)",
|
105
113
|
enum: %w[configmap secret]
|
106
114
|
}.freeze
|
107
115
|
|
@@ -115,7 +123,8 @@ defaults to $(kubectl config current-context)"
|
|
115
123
|
INLINE_ASSIGNMENT = {
|
116
124
|
key: OptionKeys::INLINE_ASSIGNMENT,
|
117
125
|
aliases: "--set",
|
118
|
-
desc: "An inline variable assignment, e.g --set x.y=foo
|
126
|
+
desc: "An inline variable assignment, e.g --set x.y=foo "\
|
127
|
+
"--set x.z=bar",
|
119
128
|
repeatable: true
|
120
129
|
}.freeze
|
121
130
|
|
@@ -126,7 +135,8 @@ defaults to $(kubectl config current-context)"
|
|
126
135
|
|
127
136
|
STRICT_READ_STATE = {
|
128
137
|
key: OptionKeys::STRICT_READ_STATE,
|
129
|
-
desc: "Makes read-state operations fail if the
|
138
|
+
desc: "Makes read-state operations fail if the " \
|
139
|
+
"state does not exist for the given tag",
|
130
140
|
}.freeze
|
131
141
|
|
132
142
|
WRITE_STATE = {
|
@@ -159,6 +169,12 @@ defaults to $(kubectl config current-context)"
|
|
159
169
|
enum: %w[true false]
|
160
170
|
}.freeze
|
161
171
|
|
172
|
+
PRE_CONFIRM = {
|
173
|
+
key: OptionKeys::PRE_CONFIRM,
|
174
|
+
desc: "Skip CLI confirmation",
|
175
|
+
enum: %w[true false]
|
176
|
+
}.freeze
|
177
|
+
|
162
178
|
KUBERNETES_OPTIONS = [
|
163
179
|
NAMESPACE,
|
164
180
|
STATE_BACKEND_TYPE,
|
@@ -190,7 +206,12 @@ defaults to $(kubectl config current-context)"
|
|
190
206
|
|
191
207
|
STATE_SUPER = {
|
192
208
|
name: "state",
|
193
|
-
desc: "Command group for state actions
|
209
|
+
desc: "Command group for state actions"
|
210
|
+
}.freeze
|
211
|
+
|
212
|
+
RELEASE_SUPER = {
|
213
|
+
name: "release",
|
214
|
+
desc: "Command group for release actions"
|
194
215
|
}.freeze
|
195
216
|
|
196
217
|
CONFIG_SUPER = {
|
@@ -234,18 +255,39 @@ defaults to $(kubectl config current-context)"
|
|
234
255
|
]
|
235
256
|
}.freeze
|
236
257
|
|
237
|
-
|
238
|
-
name: "status",
|
239
|
-
desc: "Verbosely assesses the readiness of your
|
258
|
+
RELEASE_STATUS = {
|
259
|
+
name: "status [RELEASE_NAME]",
|
260
|
+
desc: "Verbosely assesses the readiness of your "\
|
261
|
+
"state-tracking backend.",
|
240
262
|
options: [
|
241
263
|
*OptionSchemas::KUBERNETES_OPTIONS,
|
242
264
|
OptionSchemas::VERBOSE
|
243
265
|
]
|
244
266
|
}.freeze
|
245
267
|
|
246
|
-
|
268
|
+
RELEASE_LIST = {
|
247
269
|
name: "list",
|
248
|
-
desc: "
|
270
|
+
desc: "Lists all known Kerbi releases by scanning cluster" \
|
271
|
+
" ConfigMaps/Secrets",
|
272
|
+
options: [
|
273
|
+
*OptionSchemas::KUBERNETES_OPTIONS,
|
274
|
+
OptionSchemas::VERBOSE
|
275
|
+
]
|
276
|
+
}.freeze
|
277
|
+
|
278
|
+
RELEASE_DELETE = {
|
279
|
+
name: "delete [RELEASE_NAME]",
|
280
|
+
desc: "Delete the ConfigMap/Secret storing states for"\
|
281
|
+
" this release",
|
282
|
+
options: [
|
283
|
+
*OptionSchemas::KUBERNETES_OPTIONS,
|
284
|
+
OptionSchemas::PRE_CONFIRM
|
285
|
+
]
|
286
|
+
}.freeze
|
287
|
+
|
288
|
+
LIST_STATE = {
|
289
|
+
name: "list [RELEASE_NAME]",
|
290
|
+
desc: "Print all recorded states for [RELEASE_NAME]",
|
249
291
|
options: [
|
250
292
|
*OptionSchemas::KUBERNETES_OPTIONS,
|
251
293
|
OptionSchemas::OUTPUT_FMT
|
@@ -253,8 +295,8 @@ defaults to $(kubectl config current-context)"
|
|
253
295
|
defaults: OptionDefaults::LIST_STATE
|
254
296
|
}.freeze
|
255
297
|
|
256
|
-
|
257
|
-
name: "init [
|
298
|
+
INIT_RELEASE = {
|
299
|
+
name: "init [RELEASE_NAME]",
|
258
300
|
desc: "Provision the resources for persisting the state",
|
259
301
|
options: [
|
260
302
|
*OptionSchemas::KUBERNETES_OPTIONS,
|
@@ -263,7 +305,7 @@ defaults to $(kubectl config current-context)"
|
|
263
305
|
}.freeze
|
264
306
|
|
265
307
|
SHOW_STATE = {
|
266
|
-
name: "show [TAG]",
|
308
|
+
name: "show [RELEASE_NAME] [TAG]",
|
267
309
|
desc: "Print summary of state identified by [TAG]",
|
268
310
|
options: [
|
269
311
|
*OptionSchemas::KUBERNETES_OPTIONS,
|
@@ -273,7 +315,7 @@ defaults to $(kubectl config current-context)"
|
|
273
315
|
}.freeze
|
274
316
|
|
275
317
|
RETAG_STATE = {
|
276
|
-
name: "retag [OLD_TAG] [NEW_TAG]",
|
318
|
+
name: "retag [RELEASE_NAME] [OLD_TAG] [NEW_TAG]",
|
277
319
|
desc: "Updates entry's tag given by [OLD_TAG] to [NEW_TAG]",
|
278
320
|
options: [
|
279
321
|
*OptionSchemas::KUBERNETES_OPTIONS,
|
@@ -283,7 +325,7 @@ defaults to $(kubectl config current-context)"
|
|
283
325
|
}.freeze
|
284
326
|
|
285
327
|
PROMOTE_STATE = {
|
286
|
-
name: "promote [TAG]",
|
328
|
+
name: "promote [RELEASE_NAME] [TAG]",
|
287
329
|
desc: "Removes the [cand]- prefix from the given entry,
|
288
330
|
removing its candidate status.",
|
289
331
|
options: [
|
@@ -293,7 +335,7 @@ defaults to $(kubectl config current-context)"
|
|
293
335
|
}.freeze
|
294
336
|
|
295
337
|
DEMOTE_STATE = {
|
296
|
-
name: "promote [TAG]",
|
338
|
+
name: "promote [RELEASE_NAME] [TAG]",
|
297
339
|
desc: "Adds the [cand]- prefix from the given entry,
|
298
340
|
giving it candidate status.",
|
299
341
|
options: [
|
@@ -303,7 +345,7 @@ defaults to $(kubectl config current-context)"
|
|
303
345
|
}.freeze
|
304
346
|
|
305
347
|
DELETE_STATE = {
|
306
|
-
name: "delete [TAG]",
|
348
|
+
name: "delete [RELEASE_NAME] [TAG]",
|
307
349
|
desc: "Deletes the state entry given by [TAG]",
|
308
350
|
options: [
|
309
351
|
*OptionSchemas::KUBERNETES_OPTIONS,
|
@@ -311,15 +353,16 @@ defaults to $(kubectl config current-context)"
|
|
311
353
|
}.freeze
|
312
354
|
|
313
355
|
SET_STATE_ATTR = {
|
314
|
-
name: "set [TAG] [ATTR_NAME] [NEW_VALUE]",
|
315
|
-
desc: "Updates state entry [TAG], attribute
|
356
|
+
name: "set [RELEASE_NAME] [TAG] [ATTR_NAME] [NEW_VALUE]",
|
357
|
+
desc: "Updates state entry [TAG], attribute "\
|
358
|
+
"[ATTR_NAME] to value [NEW_VALUE]",
|
316
359
|
options: [
|
317
360
|
*OptionSchemas::KUBERNETES_OPTIONS,
|
318
361
|
]
|
319
362
|
}.freeze
|
320
363
|
|
321
364
|
PRUNE_CANDIDATES_STATE = {
|
322
|
-
name: "prune-candidates",
|
365
|
+
name: "prune-candidates [RELEASE_NAME]",
|
323
366
|
desc: "Deletes all state entries flagged as candidates",
|
324
367
|
options: [
|
325
368
|
*OptionSchemas::KUBERNETES_OPTIONS,
|
data/lib/config/run_opts.rb
CHANGED
@@ -7,6 +7,7 @@ module Kerbi
|
|
7
7
|
class RunOpts
|
8
8
|
|
9
9
|
attr_reader :options
|
10
|
+
attr_accessor :release_name
|
10
11
|
|
11
12
|
# @param [Hash{Symbol, Object}] cli_opts CLI args as a hash via Thor
|
12
13
|
# @param [Hash{Symbol, Object}] defaults contextual defaults (per cmd)
|
@@ -111,7 +112,8 @@ module Kerbi
|
|
111
112
|
|
112
113
|
# @return [String]
|
113
114
|
def state_backend_type
|
114
|
-
options[consts::STATE_BACKEND_TYPE]
|
115
|
+
value = options[consts::STATE_BACKEND_TYPE]
|
116
|
+
value.is_a?(String) ? value : ''
|
115
117
|
end
|
116
118
|
|
117
119
|
# @return [String]
|
@@ -139,6 +141,16 @@ module Kerbi
|
|
139
141
|
options[consts::PROJECT_ROOT].presence
|
140
142
|
end
|
141
143
|
|
144
|
+
# @return [TrueClass, FalseClass]
|
145
|
+
def in_cluster?
|
146
|
+
options[consts::K8S_AUTH_TYPE] == 'in-cluster'
|
147
|
+
end
|
148
|
+
|
149
|
+
# @return [TrueClass, FalseClass]
|
150
|
+
def confirmed?
|
151
|
+
options[consts::PRE_CONFIRM].present?
|
152
|
+
end
|
153
|
+
|
142
154
|
private
|
143
155
|
|
144
156
|
# @return [Module<Kerbi::Consts::OptionKeys>]
|
data/lib/config/state_consts.rb
CHANGED
data/lib/kerbi.rb
CHANGED
@@ -37,17 +37,19 @@ require_relative './config/run_opts'
|
|
37
37
|
|
38
38
|
require_relative './mixins/mixer'
|
39
39
|
require_relative './mixins/cm_backend_testing'
|
40
|
+
require_relative './utils/cli'
|
40
41
|
require_relative './mixins/cli_state_helpers'
|
41
42
|
|
42
43
|
require_relative './utils/mixing'
|
43
44
|
require_relative './utils/helm'
|
44
|
-
|
45
|
+
|
45
46
|
require_relative './utils/values'
|
46
47
|
require_relative './main/code_gen'
|
47
48
|
|
48
49
|
require_relative './main/mixer'
|
49
50
|
|
50
51
|
require_relative './cli/entry_serializers'
|
52
|
+
require_relative './cli/release_serializer'
|
51
53
|
|
52
54
|
require_relative './mixins/entry_tag_logic'
|
53
55
|
require_relative './state/entry_set'
|
@@ -62,4 +64,5 @@ require_relative './cli/config_handler'
|
|
62
64
|
require_relative './cli/values_handler'
|
63
65
|
require_relative './cli/project_handler'
|
64
66
|
require_relative './cli/state_handler'
|
67
|
+
require_relative './cli/release_handler'
|
65
68
|
require_relative './cli/root_handler'
|
data/lib/main/code_gen.rb
CHANGED
data/lib/main/errors.rb
CHANGED
@@ -78,6 +78,12 @@ module Kerbi
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
|
+
class UnsupportedBackendError < Error
|
82
|
+
def initialize(name)
|
83
|
+
super("Unsupported state backend type")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
81
87
|
class EntryValidationError < Error
|
82
88
|
MSG = "Cannot write state because of validation errors: "
|
83
89
|
|
data/lib/main/mixer.rb
CHANGED
@@ -12,6 +12,11 @@ module Kerbi
|
|
12
12
|
# @return [String] symbol-keyed hash
|
13
13
|
attr_reader :release_name
|
14
14
|
|
15
|
+
##
|
16
|
+
# Namespace (defaults to release_name) from CLI options
|
17
|
+
# @return [String] symbol-keyed hash
|
18
|
+
attr_reader :namespace
|
19
|
+
|
15
20
|
##
|
16
21
|
# Array of res-hashes being aggregated
|
17
22
|
# @return [Array<Hash>] list of hashes
|
@@ -27,12 +32,13 @@ module Kerbi
|
|
27
32
|
# @param [Hash] values the values tree that will be accessible to the subclass
|
28
33
|
def initialize(values, opts={})
|
29
34
|
@output = []
|
30
|
-
@release_name = opts[:release_name]
|
35
|
+
@release_name = opts[:release_name]
|
36
|
+
@namespace = opts[:namespace] || @release_name
|
31
37
|
@patch_stack = []
|
32
38
|
@values = self.class.compute_own_values_subtree(
|
33
39
|
values,
|
34
40
|
opts[:overwrite_values_root]
|
35
|
-
)
|
41
|
+
).freeze
|
36
42
|
end
|
37
43
|
|
38
44
|
##
|
@@ -91,44 +91,16 @@ module Kerbi
|
|
91
91
|
# generate an instance of the corresponding backend
|
92
92
|
# class.
|
93
93
|
# @return [Kerbi::State::Backend]
|
94
|
-
def generate_state_backend(namespace
|
95
|
-
if run_opts.state_backend_type == 'configmap'
|
96
|
-
auth_bundle = make_k8s_auth_bundle
|
94
|
+
def generate_state_backend(release_name: nil, namespace: nil)
|
95
|
+
if run_opts.state_backend_type.downcase.strip == 'configmap'
|
96
|
+
auth_bundle = Kerbi::Utils::Cli.make_k8s_auth_bundle(run_opts)
|
97
97
|
Kerbi::State::ConfigMapBackend.new(
|
98
98
|
auth_bundle,
|
99
|
+
release_name || run_opts.release_name,
|
99
100
|
namespace || run_opts.cluster_namespace
|
100
101
|
)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
##
|
105
|
-
# Given the various Kubernetes authentication options and
|
106
|
-
# configs, generates a Hash with the necessary data/schema
|
107
|
-
# to pass onto the internal k8s authentication logic.
|
108
|
-
#
|
109
|
-
# This method only delegates. Actual work done is done here at:
|
110
|
-
# Kerbi::Utils::K8sAuth.
|
111
|
-
# @return [Hash] auth bundle for the k8s authentication logic.
|
112
|
-
def make_k8s_auth_bundle
|
113
|
-
case run_opts.k8s_auth_type
|
114
|
-
when "kube-config"
|
115
|
-
Kerbi::Utils::K8sAuth.kube_config_bundle(
|
116
|
-
path: run_opts.kube_config_path,
|
117
|
-
name: run_opts.kube_context_name
|
118
|
-
)
|
119
|
-
when "basic"
|
120
|
-
Kerbi::Utils::K8sAuth.basic_auth_bundle(
|
121
|
-
username: run_opts.k8s_auth_username,
|
122
|
-
password: run_opts.k8s_auth_password
|
123
|
-
)
|
124
|
-
when "token"
|
125
|
-
Kerbi::Utils::K8sAuth.token_auth_bundle(
|
126
|
-
bearer_token: run_opts.k8s_auth_token,
|
127
|
-
)
|
128
|
-
when "in-cluster"
|
129
|
-
Kerbi::Utils::K8sAuth.in_cluster_auth_bundle
|
130
102
|
else
|
131
|
-
raise
|
103
|
+
raise Kerbi::UnsupportedBackendError
|
132
104
|
end
|
133
105
|
end
|
134
106
|
end
|