sct 0.1.14 → 0.1.19

Sign up to get free protection for your applications and to get access to all the features.
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