kerbi 0.0.1 → 0.0.5
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 +194 -0
- data/lib/cli/base_serializer.rb +120 -0
- data/lib/cli/config_handler.rb +51 -0
- data/lib/cli/entry_serializers.rb +99 -0
- data/lib/cli/project_handler.rb +2 -2
- data/lib/cli/release_handler.rb +41 -0
- data/lib/cli/release_serializer.rb +46 -0
- data/lib/cli/root_handler.rb +34 -13
- data/lib/cli/state_handler.rb +88 -0
- data/lib/cli/values_handler.rb +4 -3
- 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 +343 -28
- data/lib/config/config_file.rb +60 -0
- data/lib/config/globals.rb +4 -0
- data/lib/config/run_opts.rb +162 -0
- data/lib/config/state_consts.rb +11 -0
- data/lib/kerbi.rb +35 -10
- data/lib/main/code_gen.rb +1 -1
- data/lib/main/errors.rb +115 -0
- data/lib/main/mixer.rb +20 -10
- data/lib/mixins/cli_state_helpers.rb +108 -0
- data/lib/mixins/cm_backend_testing.rb +109 -0
- data/lib/mixins/entry_tag_logic.rb +183 -0
- data/lib/state/base_backend.rb +93 -0
- data/lib/state/config_map_backend.rb +173 -0
- data/lib/state/entry.rb +173 -0
- data/lib/state/entry_set.rb +137 -0
- data/lib/state/metadata.yaml.erb +11 -0
- data/lib/state/mixers.rb +23 -0
- data/lib/state/resources.yaml.erb +17 -0
- data/lib/utils/cli.rb +108 -9
- data/lib/utils/helm.rb +10 -12
- data/lib/utils/k8s_auth.rb +87 -0
- data/lib/utils/misc.rb +36 -1
- data/lib/utils/mixing.rb +1 -1
- data/lib/utils/values.rb +13 -22
- data/spec/cli/config_handler_spec.rb +38 -0
- data/spec/cli/release_handler_spec.rb +127 -0
- data/spec/cli/root_handler_spec.rb +100 -0
- data/spec/cli/state_handler_spec.rb +108 -0
- data/spec/cli/values_handler_spec.rb +17 -0
- data/spec/fixtures/expectations/common/bad-tag.txt +1 -0
- data/spec/fixtures/expectations/config/bad-set.txt +1 -0
- data/spec/fixtures/expectations/config/set.txt +1 -0
- data/spec/fixtures/expectations/config/show-default.yaml +6 -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/fixtures/expectations/release/status-all-working.txt +5 -0
- data/spec/fixtures/expectations/release/status-data-unreadable.txt +5 -0
- data/spec/fixtures/expectations/release/status-not-provisioned.txt +5 -0
- data/spec/fixtures/expectations/root/template-inlines.yaml +31 -0
- data/spec/fixtures/expectations/root/template-production.yaml +31 -0
- data/spec/fixtures/expectations/root/template-read-inlines.yaml +31 -0
- data/spec/fixtures/expectations/root/template-read.yaml +31 -0
- data/spec/fixtures/expectations/root/template-write.yaml +31 -0
- data/spec/fixtures/expectations/root/template.yaml +31 -0
- data/spec/fixtures/expectations/root/values.json +28 -0
- data/spec/fixtures/expectations/state/delete.txt +1 -0
- data/spec/fixtures/expectations/state/demote.txt +1 -0
- data/spec/fixtures/expectations/state/list.json +51 -0
- data/spec/fixtures/expectations/state/list.txt +6 -0
- data/spec/fixtures/expectations/state/list.yaml +35 -0
- data/spec/fixtures/expectations/state/promote.txt +1 -0
- data/spec/fixtures/expectations/state/prune-candidates.txt +1 -0
- data/spec/fixtures/expectations/state/retag.txt +1 -0
- data/spec/fixtures/expectations/state/set.txt +1 -0
- data/spec/fixtures/expectations/state/show.json +13 -0
- data/spec/fixtures/expectations/state/show.txt +13 -0
- data/spec/fixtures/expectations/state/show.yaml +8 -0
- data/spec/fixtures/expectations/values/order-of-precedence.yaml +4 -0
- data/spec/main/configmap_backend_spec.rb +110 -0
- data/spec/main/project_code_gen_spec.rb +8 -2
- data/spec/main/state_entry_set_spec.rb +112 -0
- data/spec/main/state_entry_spec.rb +109 -0
- 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 +143 -1
- data/spec/utils/helm_spec.rb +89 -109
- data/spec/utils/k8s_auth_spec.rb +32 -0
- data/spec/utils/misc_utils_spec.rb +9 -0
- data/spec/utils/values_utils_spec.rb +12 -19
- metadata +143 -16
- data/boilerplate/kerbifile.rb.erb +0 -9
- data/boilerplate/values.yaml.erb +0 -1
- data/lib/cli/base.rb +0 -83
- data/lib/config/cli_opts.rb +0 -50
- data/lib/config/manager.rb +0 -36
- data/lib/main/state_manager.rb +0 -47
- data/lib/utils/kubectl.rb +0 -58
- data/spec/main/examples_spec.rb +0 -12
- data/spec/main/state_manager_spec.rb +0 -84
- data/spec/utils/state_utils.rb +0 -15
@@ -0,0 +1,88 @@
|
|
1
|
+
module Kerbi
|
2
|
+
module Cli
|
3
|
+
class StateHandler < BaseHandler
|
4
|
+
cmd_meta Kerbi::Consts::CommandSchemas::LIST_STATE
|
5
|
+
def list(release_name)
|
6
|
+
prep_opts(Kerbi::Consts::OptionDefaults::LIST_STATE)
|
7
|
+
mem_release_name(release_name)
|
8
|
+
echo_data(
|
9
|
+
state_backend.entries,
|
10
|
+
table_serializer: Kerbi::Cli::EntryRowSerializer,
|
11
|
+
serializer: Kerbi::Cli::EntryYamlJsonSerializer
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
cmd_meta Kerbi::Consts::CommandSchemas::SHOW_STATE
|
16
|
+
# @param [String] tag_expr e.g 1.9.1, @latest
|
17
|
+
def show(release_name, tag_expr)
|
18
|
+
prep_opts(Kerbi::Consts::OptionDefaults::LIST_STATE)
|
19
|
+
mem_release_name(release_name)
|
20
|
+
entry = find_readable_entry(tag_expr)
|
21
|
+
echo_data(
|
22
|
+
entry,
|
23
|
+
table_serializer: Kerbi::Cli::FullEntryRowSerializer,
|
24
|
+
serializer: Kerbi::Cli::EntryYamlJsonSerializer
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
cmd_meta Kerbi::Consts::CommandSchemas::RETAG_STATE
|
29
|
+
# @param [String] old_tag_expr e.g 1.9.1, @latest
|
30
|
+
# @param [String] new_tag_expr e.g 1.9.1, @latest
|
31
|
+
def retag(release_name, old_tag_expr, new_tag_expr)
|
32
|
+
mem_release_name(release_name)
|
33
|
+
entry = find_readable_entry(old_tag_expr)
|
34
|
+
old_tag = entry.retag(new_tag_expr)
|
35
|
+
touch_and_save_entry(entry, tag: old_tag)
|
36
|
+
end
|
37
|
+
|
38
|
+
cmd_meta Kerbi::Consts::CommandSchemas::PROMOTE_STATE
|
39
|
+
# @param [String] tag_expr e.g 1.9.1, @latest
|
40
|
+
def promote(release_name, tag_expr)
|
41
|
+
mem_release_name(release_name)
|
42
|
+
entry = find_readable_entry(tag_expr)
|
43
|
+
old_name = entry.promote
|
44
|
+
touch_and_save_entry(entry, tag: old_name)
|
45
|
+
end
|
46
|
+
|
47
|
+
cmd_meta Kerbi::Consts::CommandSchemas::DEMOTE_STATE
|
48
|
+
# @param [String] tag_expr e.g 1.9.1, @latest
|
49
|
+
def demote(release_name, tag_expr)
|
50
|
+
mem_release_name(release_name)
|
51
|
+
entry = find_readable_entry(tag_expr)
|
52
|
+
old_name = entry.demote
|
53
|
+
touch_and_save_entry(entry, tag: old_name)
|
54
|
+
end
|
55
|
+
|
56
|
+
cmd_meta Kerbi::Consts::CommandSchemas::SET_STATE_ATTR
|
57
|
+
# @param [String] tag_expr e.g 1.9.1, @latest
|
58
|
+
# @param [String] attr_name e.g message
|
59
|
+
# @param [String] new_value e.g i am a new message
|
60
|
+
def set(release_name, tag_expr, attr_name, new_value)
|
61
|
+
mem_release_name(release_name)
|
62
|
+
entry = find_readable_entry(tag_expr)
|
63
|
+
old_value = entry.assign_attr(attr_name, new_value)
|
64
|
+
touch_and_save_entry(entry, attr_name => old_value)
|
65
|
+
end
|
66
|
+
|
67
|
+
cmd_meta Kerbi::Consts::CommandSchemas::DELETE_STATE
|
68
|
+
# @param [String] tag_expr e.g 1.9.1, @latest
|
69
|
+
def delete(release_name, tag_expr)
|
70
|
+
mem_release_name(release_name)
|
71
|
+
entry = find_readable_entry(tag_expr)
|
72
|
+
state_backend.delete_entry(entry)
|
73
|
+
new_count = state_backend.entries.count
|
74
|
+
puts "Deleted state[#{entry.tag}]. Remaining entries: #{new_count}"
|
75
|
+
end
|
76
|
+
|
77
|
+
cmd_meta Kerbi::Consts::CommandSchemas::PRUNE_CANDIDATES_STATE
|
78
|
+
def prune_candidates(release_name)
|
79
|
+
mem_release_name(release_name)
|
80
|
+
old_count = entry_set.entries.count
|
81
|
+
entry_set.prune_candidates
|
82
|
+
state_backend.save
|
83
|
+
new_count = entry_set.entries.count
|
84
|
+
puts "Pruned #{old_count - new_count} state entries"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
data/lib/cli/values_handler.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
module Kerbi
|
2
2
|
module Cli
|
3
3
|
class ValuesHandler < BaseHandler
|
4
|
-
|
4
|
+
cmd_meta Kerbi::Consts::CommandSchemas::SHOW_VALUES
|
5
5
|
def show
|
6
|
-
values =
|
7
|
-
|
6
|
+
values = compile_values
|
7
|
+
persist_compiled_values
|
8
|
+
echo_data(values, coerce_type: "Hash")
|
8
9
|
end
|
9
10
|
end
|
10
11
|
end
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
message: "normal"
|
data/lib/config/cli_schema.rb
CHANGED
@@ -2,51 +2,194 @@ module Kerbi
|
|
2
2
|
module Consts
|
3
3
|
|
4
4
|
module OptionKeys
|
5
|
-
|
5
|
+
PROJECT_ROOT = "project-root"
|
6
|
+
|
7
|
+
OUTPUT_FMT = "output-format"
|
6
8
|
INLINE_ASSIGNMENT = "inline-value"
|
9
|
+
LOAD_DEFAULT_VALUES = "load-defaults"
|
7
10
|
VALUE_FNAMES = "values-file"
|
8
|
-
|
11
|
+
|
9
12
|
RUBY_VER = "ruby-version"
|
10
13
|
VERBOSE = "verbose"
|
14
|
+
PRE_CONFIRM = "confirm"
|
15
|
+
|
16
|
+
STATE_BACKEND_TYPE = "state-backend"
|
17
|
+
READ_STATE = "read-state"
|
18
|
+
STRICT_READ_STATE = "strict-read"
|
19
|
+
WRITE_STATE = "write-state"
|
20
|
+
NAMESPACE = "namespace"
|
21
|
+
WRITE_STATE_MESSAGE = "message"
|
22
|
+
|
23
|
+
K8S_AUTH_TYPE = "k8s-auth-type"
|
24
|
+
KUBE_CONFIG_PATH = "kube-config-path"
|
25
|
+
KUBE_CONFIG_CONTEXT = "kube-config-context"
|
26
|
+
KUBE_ACCESS_TOKEN = "k8s-access-token"
|
27
|
+
K8S_USERNAME = "k8s-username"
|
28
|
+
K8S_PASSWORD = "k8s-password"
|
29
|
+
K8S_TOKEN = "k8s-access-token"
|
30
|
+
|
31
|
+
LEGAL_CONFIG_FILE_KEYS = [
|
32
|
+
STATE_BACKEND_TYPE,
|
33
|
+
K8S_AUTH_TYPE,
|
34
|
+
KUBE_CONFIG_CONTEXT,
|
35
|
+
K8S_USERNAME,
|
36
|
+
K8S_PASSWORD,
|
37
|
+
KUBE_ACCESS_TOKEN
|
38
|
+
]
|
39
|
+
end
|
40
|
+
|
41
|
+
module OptionDefaults
|
42
|
+
BASE = {
|
43
|
+
OptionKeys::LOAD_DEFAULT_VALUES => true,
|
44
|
+
OptionKeys::INLINE_ASSIGNMENT => [],
|
45
|
+
OptionKeys::VALUE_FNAMES => [],
|
46
|
+
OptionKeys::OUTPUT_FMT => "yaml",
|
47
|
+
OptionKeys::STATE_BACKEND_TYPE => "configmap",
|
48
|
+
OptionKeys::K8S_AUTH_TYPE => "kube-config"
|
49
|
+
}.freeze
|
50
|
+
|
51
|
+
LIST_STATE = BASE.merge(
|
52
|
+
OptionKeys::OUTPUT_FMT => "table"
|
53
|
+
).freeze
|
54
|
+
|
55
|
+
LIST_RELEASE = BASE.merge(
|
56
|
+
OptionKeys::OUTPUT_FMT => "table"
|
57
|
+
).freeze
|
11
58
|
end
|
12
59
|
|
13
60
|
module OptionSchemas
|
14
|
-
OUTPUT_FMT = {
|
15
|
-
key: OptionKeys::OUTPUT_FMT,
|
16
|
-
desc: "Specify YAML or JSON. Defaults to YAML",
|
17
|
-
enum: %w[yaml json]
|
18
|
-
}
|
19
61
|
|
20
|
-
|
21
|
-
key: OptionKeys::
|
22
|
-
desc: "
|
23
|
-
|
62
|
+
PROJECT_ROOT = {
|
63
|
+
key: OptionKeys::PROJECT_ROOT,
|
64
|
+
desc: "Project root. An abs path, a rel path, "\
|
65
|
+
"or remote (/foo, foo, @foo/bar)",
|
66
|
+
aliases: "-p"
|
24
67
|
}
|
25
68
|
|
69
|
+
K8S_AUTH_TYPE = {
|
70
|
+
key: OptionKeys::K8S_AUTH_TYPE,
|
71
|
+
desc: "Strategy for connecting to target cluster "\
|
72
|
+
"(defaults to kube-config)",
|
73
|
+
enum: %w[kube-config in-cluster basic token]
|
74
|
+
}.freeze
|
75
|
+
|
76
|
+
KUBE_CONFIG_PATH = {
|
77
|
+
key: OptionKeys::KUBE_CONFIG_PATH,
|
78
|
+
desc: "path to your kube-config file, defaults to ~/.kube/config"
|
79
|
+
}.freeze
|
80
|
+
|
81
|
+
KUBE_CONFIG_CONTEXT = {
|
82
|
+
key: OptionKeys::KUBE_CONFIG_CONTEXT,
|
83
|
+
desc: "context to use in your kube config,
|
84
|
+
defaults to $(kubectl config current-context)"
|
85
|
+
}.freeze
|
86
|
+
|
87
|
+
K8S_USERNAME = {
|
88
|
+
key: OptionKeys::K8S_USERNAME,
|
89
|
+
desc: "Kubernetes auth username for basic password auth"
|
90
|
+
}.freeze
|
91
|
+
|
92
|
+
K8S_PASSWORD = {
|
93
|
+
key: OptionKeys::K8S_PASSWORD,
|
94
|
+
desc: "Kubernetes auth password for basic password auth"
|
95
|
+
}.freeze
|
96
|
+
|
97
|
+
LOAD_DEFAULT_VALUES = {
|
98
|
+
key: OptionKeys::LOAD_DEFAULT_VALUES,
|
99
|
+
desc: "Automatically load values.yaml. Defaults to true.",
|
100
|
+
type: "boolean",
|
101
|
+
default: true
|
102
|
+
}.freeze
|
103
|
+
|
104
|
+
K8S_TOKEN = {
|
105
|
+
key: OptionKeys::K8S_TOKEN,
|
106
|
+
desc: "Kubernetes auth bearer token for token auth"
|
107
|
+
}.freeze
|
108
|
+
|
109
|
+
STATE_BACKEND_TYPE = {
|
110
|
+
key: OptionKeys::STATE_BACKEND_TYPE,
|
111
|
+
desc: "Persistent store to keep track of applied "\
|
112
|
+
"values (configmap, secret)",
|
113
|
+
enum: %w[configmap secret]
|
114
|
+
}.freeze
|
115
|
+
|
116
|
+
OUTPUT_FMT = {
|
117
|
+
key: OptionKeys::OUTPUT_FMT,
|
118
|
+
aliases: "-o",
|
119
|
+
desc: "Specify YAML, JSON, or table",
|
120
|
+
enum: %w[yaml json table]
|
121
|
+
}.freeze
|
122
|
+
|
26
123
|
INLINE_ASSIGNMENT = {
|
27
124
|
key: OptionKeys::INLINE_ASSIGNMENT,
|
28
125
|
aliases: "--set",
|
29
|
-
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",
|
30
128
|
repeatable: true
|
31
|
-
}
|
129
|
+
}.freeze
|
130
|
+
|
131
|
+
READ_STATE = {
|
132
|
+
key: OptionKeys::READ_STATE,
|
133
|
+
desc: "Merge values from given state record into final values.",
|
134
|
+
}.freeze
|
135
|
+
|
136
|
+
STRICT_READ_STATE = {
|
137
|
+
key: OptionKeys::STRICT_READ_STATE,
|
138
|
+
desc: "Makes read-state operations fail if the " \
|
139
|
+
"state does not exist for the given tag",
|
140
|
+
}.freeze
|
141
|
+
|
142
|
+
WRITE_STATE = {
|
143
|
+
key: OptionKeys::WRITE_STATE,
|
144
|
+
desc: "write compiled values into given state record"
|
145
|
+
}.freeze
|
146
|
+
|
147
|
+
NAMESPACE = {
|
148
|
+
key: OptionKeys::NAMESPACE,
|
149
|
+
aliases: "-n",
|
150
|
+
desc: "for state operations, tell kerbi that the state
|
151
|
+
configmap/secret is in this namespace"
|
152
|
+
}.freeze
|
32
153
|
|
33
154
|
VALUE_FNAMES = {
|
34
155
|
key: OptionKeys::VALUE_FNAMES,
|
35
156
|
aliases: "-f",
|
36
157
|
desc: "Name of a values file to be loaded.",
|
37
158
|
repeatable: true
|
38
|
-
}
|
159
|
+
}.freeze
|
39
160
|
|
40
161
|
RUBY_VER = {
|
41
162
|
key: OptionKeys::RUBY_VER,
|
42
163
|
desc: "Specify ruby version for Gemfile in a new project"
|
43
|
-
}
|
164
|
+
}.freeze
|
44
165
|
|
45
166
|
VERBOSE = {
|
46
167
|
key: OptionKeys::VERBOSE,
|
47
168
|
desc: "Run in verbose mode",
|
48
169
|
enum: %w[true false]
|
49
|
-
}
|
170
|
+
}.freeze
|
171
|
+
|
172
|
+
PRE_CONFIRM = {
|
173
|
+
key: OptionKeys::PRE_CONFIRM,
|
174
|
+
desc: "Skip CLI confirmation",
|
175
|
+
enum: %w[true false]
|
176
|
+
}.freeze
|
177
|
+
|
178
|
+
KUBERNETES_OPTIONS = [
|
179
|
+
NAMESPACE,
|
180
|
+
STATE_BACKEND_TYPE,
|
181
|
+
READ_STATE,
|
182
|
+
WRITE_STATE,
|
183
|
+
K8S_AUTH_TYPE,
|
184
|
+
KUBE_CONFIG_PATH,
|
185
|
+
KUBE_CONFIG_CONTEXT
|
186
|
+
].freeze
|
187
|
+
|
188
|
+
VALUES_OPTIONS = [
|
189
|
+
VALUE_FNAMES,
|
190
|
+
INLINE_ASSIGNMENT,
|
191
|
+
LOAD_DEFAULT_VALUES,
|
192
|
+
].freeze
|
50
193
|
end
|
51
194
|
|
52
195
|
module CommandSchemas
|
@@ -54,31 +197,54 @@ module Kerbi
|
|
54
197
|
VALUES_SUPER = {
|
55
198
|
name: "values",
|
56
199
|
desc: "Command group for values actions: show, get"
|
57
|
-
}
|
200
|
+
}.freeze
|
58
201
|
|
59
202
|
PROJECT_SUPER = {
|
60
203
|
name: "project",
|
61
204
|
desc: "Command group for project actions: new, info"
|
62
|
-
}
|
205
|
+
}.freeze
|
206
|
+
|
207
|
+
STATE_SUPER = {
|
208
|
+
name: "state",
|
209
|
+
desc: "Command group for state actions"
|
210
|
+
}.freeze
|
211
|
+
|
212
|
+
RELEASE_SUPER = {
|
213
|
+
name: "release",
|
214
|
+
desc: "Command group for release actions"
|
215
|
+
}.freeze
|
216
|
+
|
217
|
+
CONFIG_SUPER = {
|
218
|
+
name: "config",
|
219
|
+
desc: "Command group for config actions: set, get, show"
|
220
|
+
}.freeze
|
63
221
|
|
64
222
|
TEMPLATE = {
|
65
223
|
name: "template [KERBIFILE] [RELEASE_NAME]",
|
66
224
|
desc: "Runs mixers for RELEASE_NAME",
|
67
225
|
options: [
|
226
|
+
OptionSchemas::PROJECT_ROOT,
|
68
227
|
OptionSchemas::OUTPUT_FMT,
|
69
|
-
OptionSchemas::
|
70
|
-
OptionSchemas::
|
228
|
+
*OptionSchemas::VALUES_OPTIONS,
|
229
|
+
*OptionSchemas::KUBERNETES_OPTIONS
|
71
230
|
]
|
72
|
-
}
|
231
|
+
}.freeze
|
73
232
|
|
74
233
|
CONSOLE = {
|
75
234
|
name: "console",
|
76
235
|
desc: "Opens an IRB console so you can play with your mixers",
|
77
236
|
options: [
|
237
|
+
OptionSchemas::PROJECT_ROOT,
|
78
238
|
OptionSchemas::VALUE_FNAMES,
|
79
239
|
OptionSchemas::INLINE_ASSIGNMENT
|
80
240
|
]
|
81
|
-
}
|
241
|
+
}.freeze
|
242
|
+
|
243
|
+
VERSION = {
|
244
|
+
name: "version",
|
245
|
+
desc: "Prints the version of this RubyGem",
|
246
|
+
options: []
|
247
|
+
}.freeze
|
82
248
|
|
83
249
|
NEW_PROJECT = {
|
84
250
|
name: "new",
|
@@ -87,18 +253,167 @@ module Kerbi
|
|
87
253
|
OptionSchemas::RUBY_VER,
|
88
254
|
OptionSchemas::VERBOSE
|
89
255
|
]
|
90
|
-
}
|
256
|
+
}.freeze
|
257
|
+
|
258
|
+
RELEASE_STATUS = {
|
259
|
+
name: "status [RELEASE_NAME]",
|
260
|
+
desc: "Verbosely assesses the readiness of your "\
|
261
|
+
"state-tracking backend.",
|
262
|
+
options: [
|
263
|
+
*OptionSchemas::KUBERNETES_OPTIONS,
|
264
|
+
OptionSchemas::VERBOSE
|
265
|
+
]
|
266
|
+
}.freeze
|
267
|
+
|
268
|
+
RELEASE_LIST = {
|
269
|
+
name: "list",
|
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]",
|
291
|
+
options: [
|
292
|
+
*OptionSchemas::KUBERNETES_OPTIONS,
|
293
|
+
OptionSchemas::OUTPUT_FMT
|
294
|
+
],
|
295
|
+
defaults: OptionDefaults::LIST_STATE
|
296
|
+
}.freeze
|
297
|
+
|
298
|
+
INIT_RELEASE = {
|
299
|
+
name: "init [RELEASE_NAME]",
|
300
|
+
desc: "Provision the resources for persisting the state",
|
301
|
+
options: [
|
302
|
+
*OptionSchemas::KUBERNETES_OPTIONS,
|
303
|
+
OptionSchemas::VERBOSE
|
304
|
+
]
|
305
|
+
}.freeze
|
306
|
+
|
307
|
+
SHOW_STATE = {
|
308
|
+
name: "show [RELEASE_NAME] [TAG]",
|
309
|
+
desc: "Print summary of state identified by [TAG]",
|
310
|
+
options: [
|
311
|
+
*OptionSchemas::KUBERNETES_OPTIONS,
|
312
|
+
OptionSchemas::OUTPUT_FMT
|
313
|
+
],
|
314
|
+
defaults: OptionDefaults::LIST_STATE
|
315
|
+
}.freeze
|
316
|
+
|
317
|
+
RETAG_STATE = {
|
318
|
+
name: "retag [RELEASE_NAME] [OLD_TAG] [NEW_TAG]",
|
319
|
+
desc: "Updates entry's tag given by [OLD_TAG] to [NEW_TAG]",
|
320
|
+
options: [
|
321
|
+
*OptionSchemas::KUBERNETES_OPTIONS,
|
322
|
+
OptionSchemas::OUTPUT_FMT
|
323
|
+
],
|
324
|
+
defaults: OptionDefaults::LIST_STATE
|
325
|
+
}.freeze
|
326
|
+
|
327
|
+
PROMOTE_STATE = {
|
328
|
+
name: "promote [RELEASE_NAME] [TAG]",
|
329
|
+
desc: "Removes the [cand]- prefix from the given entry,
|
330
|
+
removing its candidate status.",
|
331
|
+
options: [
|
332
|
+
*OptionSchemas::KUBERNETES_OPTIONS,
|
333
|
+
],
|
334
|
+
defaults: OptionDefaults::LIST_STATE
|
335
|
+
}.freeze
|
336
|
+
|
337
|
+
DEMOTE_STATE = {
|
338
|
+
name: "promote [RELEASE_NAME] [TAG]",
|
339
|
+
desc: "Adds the [cand]- prefix from the given entry,
|
340
|
+
giving it candidate status.",
|
341
|
+
options: [
|
342
|
+
*OptionSchemas::KUBERNETES_OPTIONS,
|
343
|
+
],
|
344
|
+
defaults: OptionDefaults::LIST_STATE
|
345
|
+
}.freeze
|
346
|
+
|
347
|
+
DELETE_STATE = {
|
348
|
+
name: "delete [RELEASE_NAME] [TAG]",
|
349
|
+
desc: "Deletes the state entry given by [TAG]",
|
350
|
+
options: [
|
351
|
+
*OptionSchemas::KUBERNETES_OPTIONS,
|
352
|
+
]
|
353
|
+
}.freeze
|
354
|
+
|
355
|
+
SET_STATE_ATTR = {
|
356
|
+
name: "set [RELEASE_NAME] [TAG] [ATTR_NAME] [NEW_VALUE]",
|
357
|
+
desc: "Updates state entry [TAG], attribute "\
|
358
|
+
"[ATTR_NAME] to value [NEW_VALUE]",
|
359
|
+
options: [
|
360
|
+
*OptionSchemas::KUBERNETES_OPTIONS,
|
361
|
+
]
|
362
|
+
}.freeze
|
363
|
+
|
364
|
+
PRUNE_CANDIDATES_STATE = {
|
365
|
+
name: "prune-candidates [RELEASE_NAME]",
|
366
|
+
desc: "Deletes all state entries flagged as candidates",
|
367
|
+
options: [
|
368
|
+
*OptionSchemas::KUBERNETES_OPTIONS,
|
369
|
+
]
|
370
|
+
}.freeze
|
371
|
+
|
372
|
+
SHOW_VERSION = {
|
373
|
+
name: "version",
|
374
|
+
desc: "Print kerbi version",
|
375
|
+
options: []
|
376
|
+
}.freeze
|
91
377
|
|
92
378
|
SHOW_VALUES = {
|
93
379
|
name: "show",
|
94
380
|
desc: "Print out loaded values as YAML",
|
95
381
|
options: [
|
382
|
+
OptionSchemas::PROJECT_ROOT,
|
96
383
|
OptionSchemas::OUTPUT_FMT,
|
97
|
-
OptionSchemas::
|
98
|
-
OptionSchemas::
|
384
|
+
*OptionSchemas::VALUES_OPTIONS,
|
385
|
+
*OptionSchemas::KUBERNETES_OPTIONS
|
99
386
|
]
|
100
|
-
}
|
387
|
+
}.freeze
|
388
|
+
|
389
|
+
CONFIG_LOCATION = {
|
390
|
+
name: "location",
|
391
|
+
desc: "Prints out filesystem path for global Kerbi config"
|
392
|
+
}.freeze
|
393
|
+
|
394
|
+
CONFIG_SET = {
|
395
|
+
name: "set [KEY] [VALUE]",
|
396
|
+
desc: "Writes an x=y configuration to the global kerbi config"
|
397
|
+
}.freeze
|
398
|
+
|
399
|
+
CONFIG_GET = {
|
400
|
+
name: "get [KEY]",
|
401
|
+
desc: "Prints out the value of KEY as loaded into the options"
|
402
|
+
}.freeze
|
403
|
+
|
404
|
+
CONFIG_SHOW = {
|
405
|
+
name: "show",
|
406
|
+
desc: "Prints out the value of KEY as loaded into the options",
|
407
|
+
options: [
|
408
|
+
OptionSchemas::OUTPUT_FMT
|
409
|
+
]
|
410
|
+
}.freeze
|
411
|
+
|
412
|
+
CONFIG_RESET = {
|
413
|
+
name: "reset",
|
414
|
+
desc: "Resets the config file to its default state",
|
415
|
+
options: []
|
416
|
+
}.freeze
|
101
417
|
end
|
102
418
|
end
|
103
|
-
end
|
104
|
-
|
419
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Kerbi
|
2
|
+
|
3
|
+
module ConfigFile
|
4
|
+
|
5
|
+
DIR_NAME = ".kerbi"
|
6
|
+
FILE_NAME = "config.yaml"
|
7
|
+
|
8
|
+
def self.file_path
|
9
|
+
"#{Dir.home}/#{DIR_NAME}/#{FILE_NAME}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.dir_path
|
13
|
+
"#{Dir.home}/#{DIR_NAME}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.create_file_if_missing
|
17
|
+
unless File.exists?(file_path)
|
18
|
+
unless Dir.exists?(dir_path)
|
19
|
+
Dir.mkdir(dir_path)
|
20
|
+
end
|
21
|
+
write({}, skip_check: true)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Hash{Symbol, String}]
|
26
|
+
def self.read
|
27
|
+
begin
|
28
|
+
create_file_if_missing
|
29
|
+
contents = YAML.load_file(file_path)
|
30
|
+
contents.slice(*legal_keys)
|
31
|
+
rescue StandardError => e
|
32
|
+
puts "[WARN] failed to read config #{file_path} (#{e})"
|
33
|
+
{}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# @param [Hash] config
|
38
|
+
def self.write(config, skip_check: false)
|
39
|
+
create_file_if_missing unless skip_check
|
40
|
+
config = config.deep_dup.stringify_keys.slice(*legal_keys)
|
41
|
+
File.write(file_path, YAML.dump(config))
|
42
|
+
end
|
43
|
+
|
44
|
+
# @param [Hash] config
|
45
|
+
def self.patch(config)
|
46
|
+
existing_config = read
|
47
|
+
new_config = existing_config.merge(config)
|
48
|
+
write(new_config)
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.reset
|
52
|
+
create_file_if_missing
|
53
|
+
write({})
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.legal_keys
|
57
|
+
Kerbi::Consts::OptionKeys::LEGAL_CONFIG_FILE_KEYS
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|