sct 0.1.14 → 0.1.19

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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/bin/sct +3 -4
  3. data/{.DS_Store → cluster/lib/.DS_Store} +0 -0
  4. data/cluster/lib/cluster.rb +6 -0
  5. data/cluster/lib/cluster/commands_generator.rb +95 -0
  6. data/cluster/lib/cluster/module.rb +7 -0
  7. data/cluster/lib/cluster/runner.rb +239 -0
  8. data/{lib → sct/lib}/.DS_Store +0 -0
  9. data/sct/lib/sct.rb +17 -0
  10. data/sct/lib/sct/.DS_Store +0 -0
  11. data/sct/lib/sct/cli_tools_distributor.rb +46 -0
  12. data/{lib → sct/lib}/sct/command.rb +0 -0
  13. data/sct/lib/sct/commands/hostfile.rb +68 -0
  14. data/sct/lib/sct/commands/init.rb +37 -0
  15. data/sct/lib/sct/commands/mysqlproxy.rb +20 -0
  16. data/sct/lib/sct/commands_generator.rb +56 -0
  17. data/sct/lib/sct/tools.rb +12 -0
  18. data/sct/lib/sct/version.rb +3 -0
  19. data/sct_core/lib/.DS_Store +0 -0
  20. data/sct_core/lib/sct_core.rb +13 -0
  21. data/{lib/sct → sct_core/lib/sct_core}/.DS_Store +0 -0
  22. data/sct_core/lib/sct_core/command_executor.rb +104 -0
  23. data/{lib/sct → sct_core/lib/sct_core}/config.rb +3 -3
  24. data/sct_core/lib/sct_core/core_ext/string.rb +9 -0
  25. data/{lib/sct/setup/helpers.rb → sct_core/lib/sct_core/helper.rb} +2 -2
  26. data/sct_core/lib/sct_core/module.rb +0 -0
  27. data/sct_core/lib/sct_core/sct_pty.rb +53 -0
  28. data/sct_core/lib/sct_core/ui/implementations/shell.rb +129 -0
  29. data/sct_core/lib/sct_core/ui/interface.rb +120 -0
  30. data/sct_core/lib/sct_core/ui/ui.rb +26 -0
  31. data/shell/README.md +0 -0
  32. data/shell/lib/shell.rb +3 -0
  33. data/{lib/sct → shell/lib/shell}/ClassLevelInheritableAttributes.rb +0 -0
  34. data/shell/lib/shell/commands_generator.rb +14 -0
  35. data/{lib/sct → shell/lib/shell}/docker/composer.rb +4 -3
  36. data/{lib/sct → shell/lib/shell}/docker/docker.rb +7 -10
  37. data/{lib/sct → shell/lib/shell}/docker/php.rb +3 -2
  38. data/{lib/sct → shell/lib/shell}/docker/yarn.rb +4 -3
  39. data/shell/lib/shell/module.rb +9 -0
  40. data/shell/lib/shell/runner.rb +34 -0
  41. data/shell/lib/shell/tools.rb +7 -0
  42. metadata +92 -54
  43. data/.gitignore +0 -12
  44. data/.rspec +0 -3
  45. data/.travis.yml +0 -7
  46. data/CODE_OF_CONDUCT.md +0 -74
  47. data/Gemfile +0 -4
  48. data/Gemfile.lock +0 -48
  49. data/LICENSE.txt +0 -21
  50. data/README.md +0 -134
  51. data/Rakefile +0 -6
  52. data/lib/sct.rb +0 -61
  53. data/lib/sct/command_interface.rb +0 -18
  54. data/lib/sct/command_option.rb +0 -14
  55. data/lib/sct/commands/cluster.rb +0 -121
  56. data/lib/sct/commands/composer.rb +0 -29
  57. data/lib/sct/commands/hostfile.rb +0 -125
  58. data/lib/sct/commands/init.rb +0 -51
  59. data/lib/sct/commands/mysqlproxy.rb +0 -38
  60. data/lib/sct/commands/php.rb +0 -37
  61. data/lib/sct/commands/yarn.rb +0 -26
  62. data/lib/sct/version.rb +0 -3
  63. data/sct.gemspec +0 -40
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2377fe5a5cfd760e9a8ed93321849ac8207588721325ce48aa2d6bd8cf8f631e
4
- data.tar.gz: 5952de0af59fb21add421797a785584763a27286f94feb8303aadfaa3e57cc91
3
+ metadata.gz: e738ce105b1b145395e1126e272a2100112b7bc2282963b5ea08f76e0057f26e
4
+ data.tar.gz: 46076d0d575a48bca094be8a6eaf298ca3cb9943788ed8e52cbe131b1708764f
5
5
  SHA512:
6
- metadata.gz: 85ce38ef50434f38d01560de81c688aeea4c5ae9362c9f7b6eab2ea77acb8381906a2adcc506d8f4e2f812ec4d191ae8fc6d80e6c49e1ebcf4ac9de0a711ccf2
7
- data.tar.gz: 1678c667cf147b5c406819bfe5b2aa00624de2f08a42776d49725cc8416457e89bf3c96f06f8b25cdd02182e12aab191cb42ca83c166f8cdffb2b809d2d44e5e
6
+ metadata.gz: c56a04592b7e8e81065dbad8c2f0913df26e90381bf2d0581741ad4e34db4b044da88688b8a1a5fdf8e08a7ac89676867934efc9f8ff6641eda2437c62df3ef0
7
+ data.tar.gz: a598f85d2e88af7230783a9918a1d0d90c5e6dd622fd3b98fbed1ea52081d3acde39e95bbf03cc8811e6a0eb6c66c7d7c37e5ff98dad51eb3003bc2f0bb7ea3d
data/bin/sct CHANGED
@@ -1,8 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'commander/import'
4
- require 'sct'
5
-
6
3
  if RUBY_VERSION < '2.0.0'
7
4
  abort("sct requires Ruby 2.0.0 or higher")
8
5
  end
@@ -11,6 +8,8 @@ def self.windows?
11
8
  (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
12
9
  end
13
10
 
11
+ require 'sct/cli_tools_distributor'
12
+
14
13
  if ARGV.include?('-v') || ARGV.include?('--version')
15
14
  # This will print out the sct binary path right above the
16
15
  # version number. Very often, users are not aware they have
@@ -20,4 +19,4 @@ if ARGV.include?('-v') || ARGV.include?('--version')
20
19
  puts("-----------------------------")
21
20
  end
22
21
 
23
- Sct::SctCore.take_off(Sct.constants.map(&Sct.method(:const_get)).grep(Class))
22
+ Sct::CLIToolsDistributor.take_off
@@ -0,0 +1,6 @@
1
+ require 'sct_core'
2
+
3
+ require 'terminal-table'
4
+
5
+ require_relative 'cluster/runner'
6
+ require_relative 'cluster/module'
@@ -0,0 +1,95 @@
1
+ require 'commander'
2
+ require_relative 'runner'
3
+
4
+ module Cluster
5
+ class CommandsGenerator
6
+ include Commander::Methods
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 :up do |c|
20
+
21
+ c.syntax = "sct cluster up"
22
+ c.description = "Start the cluster"
23
+ c.option '--clean', 'start a clean cluster. Old cluster will be purged if available.'
24
+
25
+ c.action do |args, options|
26
+ if options.clean
27
+ Cluster::Runner.new.reset
28
+ else
29
+ Cluster::Runner.new.launch
30
+ end
31
+ end
32
+
33
+ end
34
+
35
+ command :down do |c|
36
+
37
+ c.syntax = 'sct cluster down'
38
+ c.description = 'stop the cluster'
39
+
40
+ c.action do |args, options|
41
+ Cluster::Runner.new.down
42
+ end
43
+ end
44
+
45
+ command :reset do |c|
46
+
47
+ c.syntax = 'sct cluster reset'
48
+ c.description = 'reset your cluster and start with a clean cluster'
49
+
50
+ c.action do |args, options|
51
+ Cluster::Runner.new.reset
52
+ end
53
+ end
54
+
55
+ alias_command :'setup', :'reset'
56
+
57
+ command :status do |c|
58
+
59
+ c.syntax = 'sct cluster status'
60
+ c.description = 'see the status of your cluster'
61
+
62
+ c.action do |args, options|
63
+ Cluster::Runner.new.status
64
+ end
65
+ end
66
+
67
+ command :'update config' do |c|
68
+
69
+ c.syntax = 'sct cluster update config'
70
+ c.description = 'update the cluster configuration'
71
+
72
+ c.action do |args, options|
73
+ Cluster::Runner.new.update_config
74
+ end
75
+ end
76
+
77
+ command :'delete pods' do |c|
78
+ c.syntax = 'sct cluster delete stalled pods'
79
+ c.description = 'delete stalled pods from the cluster'
80
+ c.option '--stalled', 'delete stalled pods'
81
+ c.option '--all', 'delete all pods'
82
+
83
+ c.action do |args, options|
84
+
85
+ Cluster::Runner.new.delete_stalled_pods if options.stalled
86
+ UI.important("Currently its not possible to delete all pods") if options.all
87
+ end
88
+ end
89
+
90
+ default_command :status
91
+
92
+ run!
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,7 @@
1
+ module Cluster
2
+
3
+ # import the helper functionality from SCT
4
+ Helpers = Sct::Helper
5
+ UI = Sct::UI
6
+
7
+ end
@@ -0,0 +1,239 @@
1
+ module Cluster
2
+ class Runner
3
+
4
+ def launch
5
+ return UI.error("SCT has not been initialized. Run 'sct init' first.") unless SctCore::Config.exists
6
+ start_cluster
7
+ run_command "kubectl delete pod -n kube-system #{pods("kube-system").map { |pod| pod[:name] if pod[:name].start_with? "registry-creds" } .compact.join(" ")}"
8
+ run_command "kubectl rollout status -n kube-system deployment/registry-creds"
9
+ post_start
10
+ end
11
+
12
+ def start_cluster
13
+ if SctCore::Helper.operatingSystem == SctCore::Helper::MAC_OS
14
+ run_command "#{minikube} start --cpus=$(sysctl -n hw.ncpu) --memory=8G"
15
+ else
16
+ run_command "#{minikube} start --cpus=$(cat /proc/cpuinfo | grep processor | wc -l) --memory=10G"
17
+ end
18
+ run_command "#{minikube} ssh -- 'sudo su -c \"echo 10048576 > /proc/sys/fs/inotify/max_user_watches\"'"
19
+ update_config
20
+ end
21
+
22
+ def post_start
23
+ wait_for_pods
24
+ run_command "sudo sct hostfile"
25
+ UI.success("\n✔️ You can visit your environment at 👉 https://spend-cloud.spend.cloud.local 👌")
26
+ end
27
+
28
+ def down
29
+ run_command "#{minikube} stop"
30
+ end
31
+
32
+ def reset
33
+ run_command "#{minikube} delete"
34
+ start_cluster
35
+ create_secrets
36
+ run_command "#{minikube} addons enable registry-creds"
37
+ run_command "#{minikube} addons enable ingress"
38
+ run_command "kubectl rollout status -n kube-system deployment/registry-creds"
39
+ run_command "kubectl rollout status -n kube-system deployment/nginx-ingress-controller"
40
+ wait_for_gcr_secret
41
+ run_command "kubectl apply -f ~/development/spend-cloud/k8s/ingress.yml"
42
+ wait_for_ingress_ip
43
+ run_command "kubectl apply -f ~/development/spend-cloud/k8s/dependencies.yml"
44
+ wait_for_pods
45
+ run_command "kubectl apply -f ~/development/spend-cloud/k8s/"
46
+ post_start
47
+ end
48
+
49
+ def wait_for_pods
50
+ UI.important("Waiting for pods to become ready...")
51
+
52
+ while ! pods.all? { |pod| pod[:status] == "Running" }
53
+ delete_stalled_pods
54
+
55
+ sleep 5
56
+ end
57
+
58
+ UI.success("Pods are now ready.")
59
+ end
60
+
61
+ def delete_stalled_pods(feedback: false)
62
+
63
+ return UI.success("No stalled pods found") unless !pods.to_a.empty?
64
+
65
+ stalled_pods = pods.select { |pod| pod[:stalled] }
66
+
67
+ if stalled_pods.empty?
68
+ UI.success("There are no stalled pods.") if feedback
69
+ else
70
+ run_command "kubectl delete pods #{stalled_pods.map { |pod| pod[:name] } .join(" ")}"
71
+ end
72
+ end
73
+
74
+ def update_config
75
+ if SctCore::Helper.operatingSystem == SctCore::Helper::WINDOWS
76
+ windows_home_path = SctCore::Helper.windowsHomePath
77
+ kube_file_path = windows_home_path+"/.kube/config"
78
+
79
+ if !File.exists?(kube_file_path)
80
+ return UI.error("#{kube_file_path} doesn't exist")
81
+ end
82
+
83
+ run_command "sed -e 's~\\\\~/~g' -e 's~C:~/mnt/c~g' < #{kube_file_path} > ~/.kube/minikube-config"
84
+
85
+ UI.success("#{kube_file_path} copied to ~/.kube/minikube-config")
86
+ end
87
+
88
+ run_command "kubectl config use-context minikube"
89
+
90
+ run_command "kubectl replace -n kube-system -f #{File.expand_path('../../resources/corefile.yml', __dir__)}"
91
+ old_list = pods("kube-system").map { |pod| pod[:name] if pod[:name].start_with? "coredns" }.compact
92
+ run_command "kubectl delete pod -n kube-system #{old_list.join(" ")}" unless old_list.to_a.empty?
93
+ run_command "kubectl rollout status -n kube-system deployment/coredns"
94
+ end
95
+
96
+ def pods(namespace = nil)
97
+ if namespace
98
+ output = `kubectl get pods -n #{namespace}`
99
+ else
100
+ output = `kubectl get pods`
101
+ end
102
+
103
+ # split output lines
104
+ lines = output.split "\n"
105
+
106
+ # exclude first line (table header)
107
+ lines = lines[1..-1]
108
+
109
+ if lines.to_a.empty?
110
+ return
111
+ end
112
+
113
+ # get name and status of each pod
114
+ lines.map do |line|
115
+ columns = line.split(" ")
116
+
117
+ name = columns[0]
118
+ status = columns[2]
119
+ stalled = status == "ErrImagePull" || status == "ImagePullBackOff"
120
+
121
+ {
122
+ name: name,
123
+ status: status,
124
+ stalled: stalled
125
+ }
126
+ end
127
+ end
128
+
129
+ def create_secrets
130
+ run_command "kubectl create secret generic gcloud-credentials --from-file=\"$(echo ~)/.config/gcloud/application_default_credentials.json\""
131
+ 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"
132
+ 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\"}}}'"
133
+ 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"
134
+ 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\"}}}'"
135
+ 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\""
136
+ 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\"}}}'"
137
+ 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"
138
+ 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\"}}}'"
139
+ end
140
+
141
+ def wait_for_gcr_secret
142
+ UI.important("Waiting for Google Cloud Registry secret to become available...")
143
+
144
+ while ! `kubectl get secrets`.include? "gcr-secret"
145
+ sleep 5
146
+ end
147
+
148
+ UI.success("Google Cloud Registry secret is now available.")
149
+ end
150
+
151
+ def wait_for_ingress_ip
152
+ UI.important("Waiting for ingress IP to become available...")
153
+
154
+ while `kubectl describe ingress | grep "Address" | awk '{print $2}'`.empty?
155
+ sleep 5
156
+ end
157
+
158
+ UI.success("Ingress IP is now available.")
159
+ end
160
+
161
+ def status
162
+ print_contexts
163
+ print_minikube_status
164
+
165
+ if get_minikube_status.find_all { |status| status[1] == 'Stopped' }.count == 0
166
+ print_pods_status("kube-system")
167
+ print_pods_status
168
+ else
169
+ UI.important("Please check your minikube status. If all services are stopped you should start the minikube first.")
170
+ end
171
+ end
172
+
173
+ def print_contexts
174
+ output = `kubectl config get-contexts`
175
+
176
+ lines = output.split "\n"
177
+ lines = lines[1..-1]
178
+
179
+ rows = lines.map do |line|
180
+ columns = line.split(" ")
181
+
182
+ current_context = columns[0] == "*" ? "Yes".green : "No".red
183
+
184
+ [columns[2], current_context]
185
+ end
186
+
187
+ puts Terminal::Table.new title: "Contexts".green, headings: ['Cluster', 'Using context'], rows: rows
188
+ end
189
+
190
+ def print_minikube_status
191
+
192
+ puts Terminal::Table.new title: "Minikube status".green, headings: ['Name', 'Status'], rows: get_minikube_status
193
+ end
194
+
195
+ def get_minikube_status
196
+ output = `#{minikube} status`
197
+
198
+ lines = output.split "\n"
199
+
200
+ rows = lines.map do |line|
201
+ columns = line.split(" ")
202
+
203
+ [columns[0][0..-2], columns[1]]
204
+ end
205
+ end
206
+
207
+ def print_pods_status(namespace = nil)
208
+
209
+ pods_list = pods(namespace)
210
+
211
+ if pods_list.to_a.empty?
212
+ return
213
+ end
214
+
215
+ rows = pods_list.map do |pod|
216
+ [
217
+ pod[:name],
218
+ pod[:status] == "Running" ? pod[:status].green : pod[:status].red
219
+ ]
220
+ end
221
+
222
+ puts Terminal::Table.new title: "Pods (namespace: #{namespace || "default"})".green, headings: ['Name', 'Status'], rows: rows
223
+ end
224
+
225
+ def run_command command
226
+ if ! system command
227
+ raise command.red
228
+ end
229
+ end
230
+
231
+ def minikube
232
+ if SctCore::Helper.operatingSystem == SctCore::Helper::WINDOWS
233
+ return "minikube.exe"
234
+ else
235
+ return "minikube"
236
+ end
237
+ end
238
+ end
239
+ end
File without changes
@@ -0,0 +1,17 @@
1
+ require 'sct_core'
2
+
3
+ require 'sct/version'
4
+ require 'sct/tools'
5
+
6
+ module Sct
7
+
8
+ Helper = SctCore::Helper
9
+ UI = SctCore::UI
10
+
11
+ class << self
12
+ def load_actions
13
+ # we should load actions here. Something like:
14
+ # Sct::Actions.load_default_actions
15
+ end
16
+ end
17
+ end
Binary file
@@ -0,0 +1,46 @@
1
+ module Sct
2
+ class CLIToolsDistributor
3
+ class << self
4
+ def take_off
5
+ require 'sct'
6
+
7
+ tool_name = ARGV.first ? ARGV.first.downcase : nil
8
+
9
+ if tool_name && Sct::TOOLS.include?(tool_name.to_sym)
10
+ # Triggering a specific tool
11
+
12
+ require tool_name
13
+ begin
14
+ # First, remove the tool's name from the arguments
15
+ # Since it will be parsed by the `commander` at a later point
16
+ # and it must not contain the binary name
17
+ ARGV.shift
18
+
19
+ # Import the CommandsGenerator class, which is used to parse
20
+ # the user input
21
+ require File.join(tool_name, "commands_generator")
22
+
23
+ # Call the tool's CommandsGenerator class and let it do its thing
24
+ commands_generator = Object.const_get(tool_name.sct_module)::CommandsGenerator
25
+ rescue LoadError
26
+ # This will only happen if the tool we call here, doesn't provide
27
+ # a CommandsGenerator class yet
28
+ # When we launch this feature, this should never be the case
29
+ abort("#{tool_name} can't be called via `sct #{tool_name}`, run '#{tool_name}' directly instead".red)
30
+ end
31
+
32
+ # Some of the tools might use other actions so need to load all
33
+ # actions before we start the tool generator here in the future
34
+ Sct.load_actions
35
+
36
+ # trigger start on tool
37
+ commands_generator.start
38
+
39
+ else
40
+ require "sct/commands_generator"
41
+ Sct::CommandsGenerator.start
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end