sct 0.1.35 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 730e908365c08b32f6c0bcffce79d1497b2139190f68980cb2c3d340a233dee8
4
- data.tar.gz: 813a1f8db688ecd7ad902bf87d2415c4000933c2aac86957d08b43fe0513a8e5
3
+ metadata.gz: 14d8446d9ad177cfe1423a229687670d9731830389539014fda62491d09ca054
4
+ data.tar.gz: fa3083af252bb67c0b776d270a69b29605e6ce33e06cfe8b6625998ab0cff29a
5
5
  SHA512:
6
- metadata.gz: 2e813fe74dd20bc360a2644cf57bf4731b122b0916e4ccfb64259fad0e69d9f5238741b9eafcd6fa0b1a523dbd5f617b83d55dee709a61ce290fdf07e47b8031
7
- data.tar.gz: ab9e05165e62681cb5a851eac335320ef44030351482ab7307a36fad1b900f6fe8036a10b72d593d88c6d6edd3e2fc3b3b7c5a7fda5daae5484e77606ecab0f9
6
+ metadata.gz: d62a9c18d78ce4a821d32cb0848c4bbc2dc88e1ca526f7600c1bb8b7945a36522f157e94a365036cc68e7549ae76f90368d2c54a1335b43d2cc2233c4c354d54
7
+ data.tar.gz: 98381741d7493183b420c176843062d005b8f6620d0a67ce0739d53da77ae2bf11c73c60817b2a0965dfd41a338a249446ec482ee27ba465f8b92708cb768db8
@@ -2,96 +2,92 @@ require 'commander'
2
2
  require_relative 'runner'
3
3
 
4
4
  module Cluster
5
- class CommandsGenerator
6
- include Commander::Methods
5
+ class CommandsGenerator
6
+ include Commander::Methods
7
7
 
8
- def self.start
9
- self.new.run
10
- end
11
-
12
- def run
13
- program :name, 'cluster'
14
- program :version, Sct::VERSION
15
- program :description, 'CLI for \'cluster\' - Manage your local kubernetes cluster'
16
-
17
- global_option('--verbose') { $verbose = true }
18
-
19
- command :start do |c|
20
- c.syntax = "sct cluster start"
21
- c.description = "start the cluster"
22
-
23
- c.action do |args, options|
24
- Cluster::Runner.new.start
25
- end
26
-
27
- end
28
-
29
- command :stop do |c|
30
- c.syntax = 'sct cluster stop'
31
- c.description = 'stop the cluster'
32
-
33
- c.action do |args, options|
34
- Cluster::Runner.new.stop
35
- end
36
- end
37
-
38
- command :restart do |c|
39
- c.syntax = "sct cluster restart"
40
- c.description = "restart the cluster"
8
+ def self.start
9
+ self.new.run
10
+ end
41
11
 
42
- c.action do |args, options|
43
- Cluster::Runner.new.restart
44
- end
12
+ def run
13
+ program :name, 'cluster'
14
+ program :version, Sct::VERSION
15
+ program :description, 'CLI for \'cluster\' - Manage your local Docker cluster'
45
16
 
46
- end
17
+ global_option('--verbose') { $verbose = true }
47
18
 
48
- command :delete do |c|
49
- c.syntax = "sct cluster delete"
50
- c.description = "delete the cluster"
19
+ command :start do |c|
20
+ c.syntax = "sct cluster start"
21
+ c.description = "start the cluster"
22
+ c.option '--build', '(re)build images before starting'
23
+ c.option '--pull', 'pull latest images before starting'
51
24
 
52
- c.action do |args, options|
53
- Cluster::Runner.new.delete
54
- end
25
+ c.action do |args, options|
26
+ Cluster::Runner.new.start args, options
27
+ end
28
+ end
55
29
 
56
- end
30
+ command :stop do |c|
31
+ c.syntax = 'sct cluster stop'
32
+ c.description = 'stop the cluster'
57
33
 
58
- command :reset do |c|
59
- c.syntax = 'sct cluster reset'
60
- c.description = 'delete the cluster and start a new cluster'
34
+ c.action do |args, options|
35
+ Cluster::Runner.new.stop
36
+ end
37
+ end
61
38
 
62
- c.action do |args, options|
63
- Cluster::Runner.new.reset
64
- end
65
- end
39
+ command :restart do |c|
40
+ c.syntax = "sct cluster restart"
41
+ c.description = "restart the cluster"
66
42
 
67
- command :status do |c|
68
- c.syntax = 'sct cluster status'
69
- c.description = 'see the status of your cluster'
43
+ c.action do |args, options|
44
+ Cluster::Runner.new.restart
45
+ end
46
+ end
70
47
 
71
- c.action do |args, options|
72
- Cluster::Runner.new.status
73
- end
74
- end
48
+ command :delete do |c|
49
+ c.syntax = "sct cluster delete"
50
+ c.description = "delete the cluster"
75
51
 
76
- command :'update config' do |c|
77
- c.syntax = 'sct cluster update config'
78
- c.description = 'update the cluster configuration'
52
+ c.action do |args, options|
53
+ Cluster::Runner.new.delete
54
+ end
55
+ end
79
56
 
80
- c.action do |args, options|
81
- Cluster::Runner.new.update_config
82
- end
83
- end
57
+ command :reset do |c|
58
+ c.syntax = 'sct cluster reset'
59
+ c.description = 'delete the cluster and start a new cluster'
84
60
 
85
- command :'apply deployments' do |c|
86
- c.syntax = 'sct cluster apply deployments'
87
- c.description = 'apply deployments from the k8s folder'
61
+ c.action do |args, options|
62
+ Cluster::Runner.new.reset args, options
63
+ end
64
+ end
88
65
 
89
- c.action do |args, options|
90
- Cluster::Runner.new.apply_deployments
91
- end
92
- end
66
+ command :status do |c|
67
+ c.syntax = 'sct cluster status'
68
+ c.description = 'see the status of your cluster'
93
69
 
94
- run!
70
+ c.action do |args, options|
71
+ Cluster::Runner.new.status
72
+ end
73
+ end
74
+
75
+ command :logs do |c|
76
+ c.syntax = 'sct cluster logs'
77
+ c.description = 'see the logs of your cluster'
78
+ c.option '-f', 'follow log output'
79
+ c.option '--follow', 'follow log output'
80
+ c.option '-t', 'show timestamps'
81
+ c.option '--timestamps', 'show timestamps'
82
+ c.option '--tail LINES', 'number of lines to show from the end of the logs for each container (default: "all")'
83
+
84
+ c.action do |args, options|
85
+ Cluster::Runner.new.logs args, options
95
86
  end
87
+ end
88
+
89
+ run!
96
90
  end
91
+
92
+ end
97
93
  end
@@ -1,343 +1,70 @@
1
1
  module Cluster
2
- class Runner
2
+ class Runner
3
3
 
4
- def start
5
- SctCore::Helper.ensure_windows_administrator # "sct hostfile" will need it later on
6
-
7
- existing_cluster = cluster_exists?
8
-
9
- start_cluster
10
-
11
- if existing_cluster
12
- run_command "kubectl rollout restart -n kube-system deployment registry-creds"
13
- run_command "kubectl rollout status -n kube-system deployment registry-creds"
14
- else
15
- create_secrets
16
- enable_addons
17
- wait_for_gcr_secret
18
- run_command "kubectl apply -f ~/development/spend-cloud/k8s/ingress.yml"
19
- wait_for_ingress_ip
20
- run_command "kubectl apply -f ~/development/spend-cloud/k8s/dependencies.yml"
21
- wait_for_pods
22
- create_keycloak_database_user
23
- run_command "kubectl apply -f ~/development/spend-cloud/k8s/keycloak-server.yml"
24
- wait_for_pods
25
- run_command "kubectl apply -f ~/development/spend-cloud/k8s/"
26
- end
27
-
28
- post_start
29
- end
30
-
31
- def stop
32
- run_command "minikube stop"
33
- end
34
-
35
- def restart
36
- SctCore::Helper.ensure_windows_administrator # "sct hostfile" will need it later on
37
-
38
- stop
39
- start
40
- end
41
-
42
- def delete
43
- run_command "minikube delete"
44
- end
45
-
46
- def reset
47
- SctCore::Helper.ensure_windows_administrator # "sct hostfile" will need it later on
48
-
49
- delete
50
- start
51
- end
52
-
53
- def status
54
- print_contexts
55
- print_minikube_status
56
-
57
- if get_minikube_status.find_all { |status| status[1] == 'Stopped' }.count == 0
58
- print_pods_status("kube-system")
59
- print_pods_status
60
- else
61
- UI.important("Please check your minikube status. If all services are stopped you should start the minikube first.")
62
- end
63
- end
64
-
65
- def update_config
66
- run_command "kubectl config use-context minikube"
67
-
68
- run_command "kubectl replace -n kube-system -f #{File.expand_path('resources/corefile.yml', __dir__)}"
69
- run_command "kubectl rollout restart -n kube-system deployment coredns"
70
- run_command "kubectl rollout status -n kube-system deployment coredns"
4
+ def run command, options = {}
5
+ begin
6
+ if !system command, options
7
+ raise command.red
71
8
  end
9
+ rescue Interrupt
10
+ # user pressed Ctrl+C, do nothing
11
+ end
12
+ end
72
13
 
73
- def apply_deployments
74
- run_command "kubectl apply -f ~/development/spend-cloud/k8s/"
75
- end
76
-
77
-
78
- def cluster_exists?
79
- if system "minikube status", { out: "/dev/null" }
80
- # cluster exists and is running
81
- return true
82
- end
83
-
84
- if $?.exitstatus == 85
85
- # cluster does not exist
86
- return false
87
- end
88
-
89
- # cluster exists but is stopped
90
- return true
91
- end
92
-
93
- def start_cluster
94
- if SctCore::Helper.operatingSystem == SctCore::Helper::MAC_OS
95
- run_command "minikube start --driver=hyperkit --vm=true --cpus=$(sysctl -n hw.ncpu) --memory=8G"
96
- else
97
- run_command "minikube start --driver=docker --cpus=$(cat /proc/cpuinfo | grep processor | wc -l) --memory=3G"
98
- end
99
- update_config
100
- end
101
-
102
- def post_start
103
- wait_for_pods
104
- copy_proactive_accounts_file
105
- if SctCore::Helper.operatingSystem == SctCore::Helper::UBUNTU
106
- UI.success("\nAdding SSH tunnel to port 443!")
107
- run_command "sudo ssh -f -N -i $(minikube ssh-key) docker@$(minikube ip) -L 443:127.0.0.1:443"
108
- end
109
- # run_command "sudo sct hostfile"
110
- run_command "minikube tunnel &", { out: "/dev/null", err: "/dev/null" } if SctCore::Helper::is_windows? # leave this running detached forever in the background
111
- UI.success("\n✔️ You can visit your environment at 👉 https://spend-cloud.dev.spend.cloud 👌")
112
- end
113
-
114
- def enable_addons
115
- enable_addon "registry-creds"
116
- enable_addon "ingress"
117
- end
118
-
119
- def enable_addon(addon)
120
- run_command "minikube addons enable #{addon}"
121
-
122
- deployment = deployments("kube-system").find { |deployment| deployment[:name].include? addon }
123
-
124
- run_command "kubectl rollout status -n kube-system deployment #{deployment[:name]}"
125
- end
126
-
127
- def wait_for_pods
128
- UI.important("Waiting for pods to become ready...")
129
-
130
- previous_lines = 0
131
-
132
- while ! pods.all? { |pod| pod[:ready] }
133
- pods_status_lines = get_pods_status.to_s.lines.map { |line| line.chomp }
134
-
135
- current_lines = pods_status_lines.length
136
-
137
- line_difference = current_lines - previous_lines
138
-
139
- if line_difference < 0 # there are now less lines than before
140
- line_difference.abs.times do
141
- print "\033[1A\033[K" # move the cursor up a line and clear the line
142
- end
143
-
144
- print "\033[#{current_lines}A" # move the cursor all the way up to the start of the table
145
- elsif previous_lines > 0
146
- print "\033[#{previous_lines}A" # move the cursor all the way up to the start of the table
147
- end
148
-
149
- pods_status_lines.each do |line|
150
- print "#{line}\033[K#{$/}" # print the content of the line, clear remaining characters and add a new line
151
- end
152
-
153
- previous_lines = current_lines
154
-
155
- sleep 5
156
- end
157
-
158
- previous_lines.times do
159
- print "\033[1A\033[K" # move the cursor up a line and clear the line
160
- end
161
-
162
- UI.success("Pods are now ready.")
163
- end
164
-
165
- def deployments(namespace = "default")
166
- output = `kubectl get deployments -n #{namespace}`
167
-
168
- # split output lines
169
- lines = output.split "\n"
170
-
171
- # exclude first line (table header)
172
- lines = lines[1..-1]
173
-
174
- # get name and status of each pod
175
- lines.map do |line|
176
- columns = line.split(" ")
177
-
178
- name = columns[0]
179
-
180
- {
181
- name: name
182
- }
183
- end
184
- end
185
-
186
- def pods(namespace = "default")
187
- output = `kubectl get pods -n #{namespace}`
188
-
189
- # split output lines
190
- lines = output.split "\n"
191
-
192
- # exclude first line (table header)
193
- lines = lines[1..-1]
194
-
195
- # get name and status of each pod
196
- lines.map do |line|
197
- columns = line.split(" ")
198
-
199
- name = columns[0]
200
- ready = columns[1].split("/").reduce { |l, r| l == r }
201
- replicas = columns[1]
202
- status = columns[2]
203
-
204
- {
205
- name: name,
206
- ready: ready,
207
- replicas: replicas,
208
- status: status
209
- }
210
- end
211
- end
212
-
213
- def create_secrets
214
- run_command "kubectl create secret generic gcloud-credentials --from-file=\"$(echo ~)/.config/gcloud/application_default_credentials.json\""
215
- run_command "kubectl create secret generic -n kube-system registry-creds-dpr --from-literal DOCKER_PRIVATE_REGISTRY_PASSWORD=changeme --from-literal DOCKER_PRIVATE_REGISTRY_SERVER=changeme --from-literal DOCKER_PRIVATE_REGISTRY_USER=changeme"
216
- run_command "kubectl patch secret -n kube-system registry-creds-dpr -p='{\"metadata\": {\"labels\": { \"app\": \"registry-creds\", \"cloud\": \"dpr\", \"kubernetes.io/minikube-addons\": \"registry-creds\"}}}'"
217
- run_command "kubectl create secret generic -n kube-system registry-creds-ecr --from-literal AWS_ACCESS_KEY_ID=changeme --from-literal AWS_SECRET_ACCESS_KEY=changeme --from-literal AWS_SESSION_TOKEN=\"\" --from-literal aws-account=changeme --from-literal aws-assume-role=changeme --from-literal aws-region=changeme"
218
- run_command "kubectl patch secret -n kube-system registry-creds-ecr -p='{\"metadata\": {\"labels\": { \"app\": \"registry-creds\", \"cloud\": \"ecr\", \"kubernetes.io/minikube-addons\": \"registry-creds\"}}}'"
219
- run_command "kubectl create secret generic -n kube-system registry-creds-gcr --from-file=\"$(echo ~)/.config/gcloud/application_default_credentials.json\" --from-literal=gcrurl=\"https://eu.gcr.io\""
220
- run_command "kubectl patch secret -n kube-system registry-creds-gcr -p='{\"metadata\": {\"labels\": { \"app\": \"registry-creds\", \"cloud\": \"gcr\", \"kubernetes.io/minikube-addons\": \"registry-creds\"}}}'"
221
- run_command "kubectl create secret generic -n kube-system registry-creds-acr --from-literal ACR_PASSWORD=changeme --from-literal ACR_CLIENT_ID=changeme --from-literal ACR_URL=changeme"
222
- run_command "kubectl patch secret -n kube-system registry-creds-acr -p='{\"metadata\": {\"labels\": { \"app\": \"registry-creds\", \"cloud\": \"acr\", \"kubernetes.io/minikube-addons\": \"registry-creds\"}}}'"
223
- end
224
-
225
- def wait_for_gcr_secret
226
- UI.important("Waiting for Google Cloud Registry secret to become available...")
227
-
228
- while ! `kubectl get secrets`.include? "gcr-secret"
229
- sleep 5
230
- end
231
-
232
- UI.success("Google Cloud Registry secret is now available.")
233
- end
234
-
235
- def wait_for_ingress_ip
236
- UI.important("Waiting for ingress IP to become available...")
237
-
238
- while `kubectl describe ingress | grep "Address" | awk '{print $2}'`.empty?
239
- sleep 5
240
- end
241
-
242
- UI.success("Ingress IP is now available.")
243
- end
244
-
245
- def print_contexts
246
- output = `kubectl config get-contexts`
247
-
248
- lines = output.split "\n"
249
- lines = lines[1..-1]
250
-
251
- rows = lines.map do |line|
252
- columns = line.split(" ")
253
-
254
- current_context = columns[0] == "*" ? "Yes".green : "No".red
255
-
256
- [columns[2], current_context]
257
- end
258
-
259
- puts Terminal::Table.new title: "Contexts".green, headings: ['Cluster', 'Using context'], rows: rows
260
- end
261
-
262
- def print_minikube_status
263
- puts Terminal::Table.new title: "Minikube status".green, headings: ['Name', 'Status'], rows: get_minikube_status
264
- end
265
-
266
- def get_minikube_status
267
- output = `minikube status`
268
-
269
- lines = output.split "\n"
270
-
271
- rows = lines.map do |line|
272
- columns = line.split(" ")
14
+ def run_dc command, options = {}
15
+ run "docker-compose -f ~/development/spend-cloud/docker-compose.yml #{command}", options
16
+ end
273
17
 
274
- [columns[0][0..-2], columns[1]]
275
- end
276
- end
18
+ def start args, options
19
+ if options.pull
20
+ run_dc "pull"
21
+ end
277
22
 
278
- def print_pods_status(namespace = "default")
279
- output = get_pods_status(namespace)
23
+ if options.build
24
+ run_dc "build #{options.pull ? "--pull" : ""}"
25
+ end
280
26
 
281
- puts output if output
282
- end
27
+ run "docker container prune -f"
283
28
 
284
- def get_pods_status(namespace = "default")
285
- rows = pods(namespace).map do |pod|
286
- status = pod[:status]
287
- replicas = pod[:replicas]
29
+ run_dc "up --detach"
288
30
 
289
- [
290
- pod[:name],
291
- status == "Running" ? status.green : status.red,
292
- pod[:ready] ? replicas.green : replicas.red
293
- ]
294
- end
31
+ if options.pull or options.build
32
+ system "docker image prune -f"
33
+ end
295
34
 
296
- if rows.empty?
297
- return
298
- end
299
-
300
- return Terminal::Table.new title: "Pods (namespace: #{namespace})".green, headings: ['Name', 'Status', 'Replicas ready'], rows: rows
301
- end
35
+ UI.success("\n✔️ You can visit your environment at 👉 https://spend-cloud.dev.spend.cloud 👌")
36
+ end
302
37
 
303
- def copy_proactive_accounts_file
304
- container_name = "proactive-config"
305
- pod_id = pods().select {|pod| pod[:name].start_with?(container_name)}.first[:name]
38
+ def stop
39
+ run_dc "down --remove-orphans"
40
+ end
306
41
 
307
- begin
308
- UI.important("Checking ProActive accounts file...")
309
- run_command "kubectl exec #{pod_id} -- test -e /data/proactive_accounts.ini", [:out, :err] => File::NULL
310
- rescue => e
311
- UI.important("Copying ProActive accounts file to deployments...")
312
- src_path = "#{Dir.home()}/development/spend-cloud/k8s/conf/proactive_accounts.ini"
313
- command = "kubectl cp #{src_path} #{pod_id}:/data/proactive_accounts.ini -c #{container_name}"
314
- run_command command
315
- end
42
+ def restart
43
+ run_dc "restart"
44
+ end
316
45
 
317
- UI.success("ProActive accounts file is available")
318
- end
46
+ def delete
47
+ run_dc "down --remove-orphans -v"
48
+ end
319
49
 
320
- def create_keycloak_database_user
321
- container_name = "mysql-service"
322
- pod_id = pods().select {|pod| pod[:name].start_with?(container_name)}.first[:name]
50
+ def reset args, options
51
+ delete
52
+ start args, options
53
+ end
323
54
 
324
- UI.important("Creating keycloak user")
325
- create_user = 'CREATE USER "keycloak"@"%" IDENTIFIED BY "keycloak";'
326
- run_command "kubectl exec #{pod_id} -- mysql -e '#{create_user}' >> /dev/null"
55
+ def status
56
+ run_dc "ps"
57
+ end
327
58
 
328
- UI.important("Creating keycloak database")
329
- create_database = "CREATE DATABASE keycloak CHARACTER SET utf8 COLLATE UTF8_UNICODE_CI;"
330
- run_command "kubectl exec #{pod_id} -- mysql -e '#{create_database}' >> /dev/null"
59
+ def logs args, options
60
+ command = "logs"
331
61
 
332
- UI.important("Granting privileges to keycloak user")
333
- grant_privileges = 'GRANT ALL PRIVILEGES ON keycloak.* TO "keycloak"@"%";'
334
- run_command "kubectl exec #{pod_id} -- mysql -e '#{grant_privileges}' >> /dev/null"
335
- end
62
+ command << " --follow" if options.f or options.follow
63
+ command << " --timestamps" if options.t or options.timestamps
64
+ command << " --tail #{options.tail}" if options.tail
336
65
 
337
- def run_command command, options = {}
338
- if ! system command, options
339
- raise command.red
340
- end
341
- end
66
+ run_dc "#{command} #{args.join " "}"
342
67
  end
68
+
69
+ end
343
70
  end