sct 0.1.28 → 0.1.34

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,13 +2,7 @@ module Sct
2
2
  class HostfileCommand
3
3
 
4
4
  def execute(args, options)
5
- return UI.error("SCT has not been initialized. Run 'sct init' first.") unless SctCore::Config.exists
6
-
7
- return UI.error("This command needs to be run with sudo.") unless SctCore::Helper.isSudo
8
-
9
- return unless SctCore::Helper.ingressAddress
10
-
11
- ingressAddress = SctCore::Helper.ingressAddress
5
+ SctCore::Helper.ensure_permissions
12
6
 
13
7
  entries = [
14
8
  {
@@ -37,32 +31,42 @@ module Sct
37
31
  }
38
32
  ]
39
33
 
34
+ is_windows = SctCore::Helper::is_windows?
35
+
36
+ if is_windows
37
+ ingress_address = "127.0.0.1"
38
+ else
39
+ ingress_address = `sudo -u $SUDO_USER minikube ip`.chomp
40
+ end
41
+
42
+ windows_hosts_path = "/mnt/c/Windows/System32/drivers/etc/hosts"
43
+
40
44
  if options.path
41
45
  hosts_paths = [options.path]
42
46
  else
43
47
  hosts_paths = ["/etc/hosts"]
44
48
 
45
- if SctCore::Helper.operatingSystem == SctCore::Helper::WINDOWS
46
- hosts_paths << "/mnt/c/Windows/System32/drivers/etc/hosts"
49
+ if is_windows
50
+ hosts_paths << windows_hosts_path
47
51
  end
48
52
  end
49
53
 
50
54
  hosts_paths.each do |hosts_path|
51
- line_ending = hosts_path == "/mnt/c/Windows/System32/drivers/etc/hosts" ? "\r\n" : "\n"
55
+ line_ending = hosts_path == windows_hosts_path ? "\r\n" : "\n"
52
56
 
53
57
  lines = File.readlines hosts_path
54
58
 
55
59
  # select the lines that do not include any entry
56
- lines = lines.select { |line| ! entries.any? { |entry| line.include? entry[:host] } }
60
+ lines = lines.select { |line| ! entries.any? { |entry| line.include? " #{entry[:host]}" } }
57
61
 
58
62
  # add entries
59
63
  entries.each do |entry|
60
- lines << "#{ingressAddress} #{entry[:host]} # #{entry[:comment]}#{line_ending}"
64
+ lines << "#{ingress_address} #{entry[:host]} # #{entry[:comment]}#{line_ending}"
61
65
  end
62
66
 
63
67
  File.write hosts_path, lines.join
64
68
 
65
- UI.success("Patched #{hosts_path} with #{ingressAddress}")
69
+ UI.success("Patched #{hosts_path} with #{ingress_address}")
66
70
  end
67
71
 
68
72
  end
@@ -9,7 +9,7 @@ module Sct
9
9
  self.new.run
10
10
  end
11
11
 
12
- def run
12
+ def run
13
13
  program :name, 'sct'
14
14
  program :version, Sct::VERSION
15
15
  program :summary, 'CLI helper tool for local SCT development'
@@ -17,11 +17,11 @@ module Sct
17
17
 
18
18
  global_option('--verbose') { $verbose = true }
19
19
 
20
- command :init do |c|
20
+ command :init do |c|
21
21
  c.syntax = 'sct init'
22
22
  c.description = 'setup sct'
23
23
 
24
- c.action do |args, options|
24
+ c.action do |args, options|
25
25
  UI.important("setting up sct")
26
26
  Sct::InitCommand.new.execute(args, options)
27
27
  end
@@ -33,17 +33,17 @@ module Sct
33
33
  c.description = 'patch hostfile with kubernetes ip'
34
34
 
35
35
  c.action do |args, options|
36
- UI.important("Trying to patch hostfile")
36
+ UI.important("Trying to patch hosts file...")
37
37
  Sct::HostfileCommand.new.execute(args, options)
38
38
  end
39
39
  end
40
40
 
41
- command :'mysql proxy' do |c|
41
+ command :'mysql-proxy' do |c|
42
42
 
43
- c.syntax = 'sct mysql proxy'
43
+ c.syntax = 'sct mysql-proxy'
44
44
  c.description = 'setup google mysql proxy'
45
45
 
46
- c.action do |args, options|
46
+ c.action do |args, options|
47
47
  UI.important("Trying to setup mysql proxy")
48
48
  Sct::MysqlproxyCommand.new.execute(args, options)
49
49
  end
@@ -67,4 +67,4 @@ module Sct
67
67
  run!
68
68
  end
69
69
  end
70
- end
70
+ end
@@ -1,3 +1,3 @@
1
1
  module Sct
2
- VERSION = "0.1.28"
2
+ VERSION = "0.1.34"
3
3
  end
@@ -5,27 +5,6 @@ module SctCore
5
5
  MAC_OS = "MacOS"
6
6
  UBUNTU = "Ubuntu"
7
7
 
8
- def self.ingressAddress
9
- if self.operatingSystem == WINDOWS
10
- kubeconfig_file = "minikube-config"
11
- else
12
- kubeconfig_file = "config"
13
- end
14
-
15
- kubeconfig_path= "#{self.homePath}/.kube/#{kubeconfig_file}"
16
-
17
- ip = `KUBECONFIG="#{kubeconfig_path}" kubectl get ingress`
18
-
19
- if ip.nil? || ip.empty?
20
- puts "Can't fetch IP from kubectl".yellow
21
- return nil
22
- end
23
-
24
- match = ip.scan(/((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3})/)
25
-
26
- return match.first.first
27
- end
28
-
29
8
  def self.to_hash(str)
30
9
  Hash[
31
10
  str.split("\n").map{|i|i.split('=')}
@@ -60,7 +39,7 @@ module SctCore
60
39
  end
61
40
 
62
41
  def self.windowsHomePath
63
- if self.operatingSystem == WINDOWS
42
+ if self.is_windows?
64
43
  return self.convertWindowsToWSLPath(`cmd.exe /c echo %userprofile%`)
65
44
  end
66
45
 
@@ -68,7 +47,7 @@ module SctCore
68
47
  end
69
48
 
70
49
  def self.convertWindowsToWSLPath(path)
71
- if self.operatingSystem == WINDOWS
50
+ if self.is_windows?
72
51
  return path.gsub(/C:\\/, '/mnt/c/').gsub(/\\\\/, "/").gsub(/\\/, '/').gsub(/\r\n?/, '')
73
52
  end
74
53
 
@@ -76,23 +55,43 @@ module SctCore
76
55
  end
77
56
 
78
57
  def self.convertWSLToWindowsPath(path)
79
- if self.operatingSystem == WINDOWS
58
+ if self.is_windows?
80
59
  return path.gsub(/\/mnt\/c/, 'C:/').gsub(/\/\//, '/').gsub(/\\\\/, "/").gsub(/\r\n?/, '')
81
60
  end
82
61
 
83
62
  return path
84
63
  end
85
64
 
86
- def self.isSudo
65
+ def self.is_sudo?
87
66
  return !ENV["SUDO_USER"].nil? && !ENV["SUDO_USER"].empty?
88
67
  end
89
68
 
90
- def self.minikube
91
- if self.operatingSystem == WINDOWS
92
- return "minikube.exe"
93
- else
94
- return "minikube"
69
+ def self.is_windows?
70
+ return self.operatingSystem == WINDOWS
71
+ end
72
+
73
+ def self.is_windows_administrator?
74
+ # https://serverfault.com/a/95464
75
+ return `/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe -c "(New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)"` == "True\r\n"
76
+ end
77
+
78
+ def self.ensure_sudo
79
+ if !self.is_sudo?
80
+ UI.error "This command needs to be run with sudo."
81
+ exit 1
95
82
  end
96
83
  end
84
+
85
+ def self.ensure_windows_administrator
86
+ if self.is_windows? && !self.is_windows_administrator?
87
+ UI.error "This command needs to be run in an admin shell."
88
+ exit 1
89
+ end
90
+ end
91
+
92
+ def self.ensure_permissions
93
+ self.ensure_sudo
94
+ self.ensure_windows_administrator
95
+ end
97
96
  end
98
97
  end
@@ -38,11 +38,7 @@ module SctCore
38
38
  UI.important("# An update for #{gem_name} is available. You are on #{current_version}.")
39
39
  end
40
40
  UI.important("# You should use the latest version.")
41
- UI.important("# Please update using `#{self.update_command(gem_name: gem_name)}`.")
42
-
43
- UI.important('#######################################################################')
44
- UI.important("# Run `sudo gem cleanup` from time to time to speed up sct.")
45
-
41
+ UI.important("# Please update by running `#{self.update_command(gem_name: gem_name)}`.")
46
42
  UI.important('#######################################################################')
47
43
 
48
44
  ensure_rubygems_source
@@ -62,7 +58,7 @@ module SctCore
62
58
  end
63
59
 
64
60
  def self.update_command(gem_name: "sct")
65
- "sudo gem install #{gem_name.downcase}"
61
+ "sudo gem update #{gem_name.downcase}"
66
62
  end
67
63
 
68
64
  def self.fetch_latest(gem_name)
@@ -1,3 +1,2 @@
1
- require_relative 'shell/tools'
2
1
  require_relative 'shell/runner'
3
- require_relative 'shell/module'
2
+ require_relative 'shell/module'
@@ -7,8 +7,8 @@ module Shell
7
7
  self.new.run
8
8
  end
9
9
 
10
- def run
10
+ def run
11
11
  Shell::Runner.new.launch
12
12
  end
13
13
  end
14
- end
14
+ end
@@ -4,6 +4,6 @@ module Shell
4
4
 
5
5
  # import the helper functionality from SCT
6
6
  Helpers = Sct::Helper
7
- UI = Sct::UI
7
+ UI = Sct::UI
8
8
 
9
- end
9
+ end
@@ -1,34 +1,83 @@
1
+ require 'yaml'
2
+
1
3
  module Shell
2
4
  class Runner
3
- # define launch work
4
- def launch
5
-
6
- tool_name = ARGV.first ? ARGV.first.downcase : nil
7
-
8
- if tool_name && Shell::TOOLS.include?(tool_name.to_sym)
9
-
10
- require_relative "docker/#{tool_name}"
11
- command = "#{ARGV[1..(ARGV.length+1)].join(" ")}"
12
-
13
- case ARGV.first
14
- when 'php'
15
- Shell::Php.exec(command)
16
- when 'composer'
17
- Shell::Composer.exec(command)
18
- when 'yarn'
19
- Shell::Yarn.exec(command)
20
- else
21
- show_error
22
- end
23
-
5
+
6
+ def launch
7
+ command = ARGV.join(" ")
8
+
9
+ if ! File.exist? "./okteto.yml"
10
+ error "Could not find file 'okteto.yml'."
11
+ end
12
+
13
+ manifest = YAML.load File.read "./okteto.yml"
14
+
15
+ deployment = manifest["name"]
16
+
17
+ pod = find_pod deployment
18
+
19
+ if command.empty?
20
+ system "kubectl exec #{pod} -it -- sh", { in: :in, out: :out, err: :err }
24
21
  else
25
- show_error
22
+ system "kubectl exec #{pod} -it -- #{command}", { in: :in, out: :out, err: :err }
23
+ end
24
+ end
25
+
26
+ def find_pod deployment
27
+ output = `kubectl get pods --show-labels`
28
+
29
+ # split output lines
30
+ lines = output.split "\n"
31
+
32
+ # exclude first line (table header)
33
+ lines = lines[1..-1]
34
+
35
+ # get the name and labels of each pod
36
+ pods = lines.map do |line|
37
+ columns = line.split " "
38
+
39
+ name = columns[0]
40
+
41
+ labels = columns[5].split(",").reduce({}) do |labels, label|
42
+ key, value = label.split "="
43
+ labels[key] = value
44
+ labels
45
+ end
46
+
47
+ {
48
+ name: name,
49
+ labels: labels
50
+ }
26
51
  end
52
+
53
+ # filter by deployment
54
+ pods = pods.filter { |pod| pod[:labels]["app"] == deployment }
55
+
56
+ if pods.length == 0
57
+ error "Could not find pod for deployment #{deployment}."
58
+ elsif pods.length > 1
59
+ error "Found more than one pod for deployment #{deployment}. Multiple pods are not supported."
60
+ end
61
+
62
+ pod = pods.first
63
+
64
+ if pod[:labels]["dev.okteto.com"] != "true"
65
+ print "The current pod is running a production image and was not started by Okteto. Are you sure you want to continue? [y/N] ".red
66
+
67
+ answer = $stdin.readline.chomp.downcase
68
+
69
+ if answer != "y"
70
+ exit
71
+ end
72
+ end
73
+
74
+ pod[:name]
27
75
  end
28
76
 
29
- def show_error
30
- tools = Shell::TOOLS.map { |tool| tool.to_s }.join(", ")
31
- UI.error("Tool not found. Try one of these: #{tools}")
77
+ def error message
78
+ UI.error message
79
+ exit 1
32
80
  end
81
+
33
82
  end
34
- end
83
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sct
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.28
4
+ version: 0.1.34
5
5
  platform: ruby
6
6
  authors:
7
7
  - Reshad Farid
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-15 00:00:00.000000000 Z
11
+ date: 2020-12-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colored
@@ -227,17 +227,10 @@ files:
227
227
  - sct_core/lib/sct_core/ui/interface.rb
228
228
  - sct_core/lib/sct_core/ui/ui.rb
229
229
  - sct_core/lib/sct_core/update_checker/update_checker.rb
230
- - shell/README.md
231
230
  - shell/lib/shell.rb
232
- - shell/lib/shell/ClassLevelInheritableAttributes.rb
233
231
  - shell/lib/shell/commands_generator.rb
234
- - shell/lib/shell/docker/composer.rb
235
- - shell/lib/shell/docker/docker.rb
236
- - shell/lib/shell/docker/php.rb
237
- - shell/lib/shell/docker/yarn.rb
238
232
  - shell/lib/shell/module.rb
239
233
  - shell/lib/shell/runner.rb
240
- - shell/lib/shell/tools.rb
241
234
  homepage: https://gitlab.com/proactive-software/packages/sct
242
235
  licenses:
243
236
  - MIT
@@ -263,7 +256,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
263
256
  - !ruby/object:Gem::Version
264
257
  version: '0'
265
258
  requirements: []
266
- rubygems_version: 3.0.6
259
+ rubygems_version: 3.1.2
267
260
  signing_key:
268
261
  specification_version: 4
269
262
  summary: Spend Cloud Tool.
File without changes
@@ -1,25 +0,0 @@
1
- module ClassLevelInheritableAttributes
2
- def self.included(base)
3
- base.extend(ClassMethods)
4
- end
5
-
6
- module ClassMethods
7
- def inheritable_attributes(*args)
8
- @inheritable_attributes ||= [:inheritable_attributes]
9
- @inheritable_attributes += args
10
- args.each do |arg|
11
- class_eval %(
12
- class << self; attr_accessor :#{arg} end
13
- )
14
- end
15
- @inheritable_attributes
16
- end
17
-
18
- def inherited(subclass)
19
- @inheritable_attributes.each do |inheritable_attribute|
20
- instance_var = "@#{inheritable_attribute}"
21
- subclass.instance_variable_set(instance_var, instance_variable_get(instance_var))
22
- end
23
- end
24
- end
25
- end
@@ -1,16 +0,0 @@
1
- require "sct_core"
2
- require_relative "docker"
3
-
4
- module Shell
5
- class Composer < Docker
6
-
7
- # Configure the Yarn command
8
- def self.config
9
- self.set_image("eu.gcr.io/dev-pasc-vcdm/helpers-composer:latest", true)
10
- self.set_pwd_as_volume("/app")
11
- self.add_volume(SctCore::Helper.convertWSLToWindowsPath("#{SctCore::Helper.windowsHomePath || SctCore::Helper.homePath}/.composer") , "/tmp")
12
- self.set_current_user_and_group()
13
- self.set_entrypoint("composer")
14
- end
15
- end
16
- end