sct 0.1.18 → 0.1.23
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/bin/sct +3 -4
- data/{.DS_Store → cluster/lib/.DS_Store} +0 -0
- data/cluster/lib/cluster.rb +6 -0
- data/cluster/lib/cluster/commands_generator.rb +109 -0
- data/cluster/lib/cluster/module.rb +7 -0
- data/{lib/sct → cluster/lib/cluster/resources}/.DS_Store +0 -0
- data/{resources → cluster/lib/cluster/resources}/corefile.yml +0 -0
- data/{lib/sct/commands/cluster.rb → cluster/lib/cluster/runner.rb} +137 -132
- data/{lib → sct/lib}/.DS_Store +0 -0
- data/sct/lib/sct.rb +17 -0
- data/sct/lib/sct/.DS_Store +0 -0
- data/sct/lib/sct/cli_tools_distributor.rb +50 -0
- data/{lib → sct/lib}/sct/command.rb +0 -0
- data/{lib → sct/lib}/sct/commands/hostfile.rb +7 -23
- data/sct/lib/sct/commands/init.rb +37 -0
- data/sct/lib/sct/commands/mysqlproxy.rb +20 -0
- data/sct/lib/sct/commands_generator.rb +56 -0
- data/sct/lib/sct/tools.rb +12 -0
- data/sct/lib/sct/version.rb +3 -0
- data/sct_core/lib/.DS_Store +0 -0
- data/sct_core/lib/sct_core.rb +14 -0
- data/sct_core/lib/sct_core/.DS_Store +0 -0
- data/sct_core/lib/sct_core/command_executor.rb +104 -0
- data/{lib/sct → sct_core/lib/sct_core}/config.rb +3 -3
- data/sct_core/lib/sct_core/core_ext/string.rb +9 -0
- data/{lib/sct/setup/helpers.rb → sct_core/lib/sct_core/helper.rb} +10 -2
- data/sct_core/lib/sct_core/module.rb +0 -0
- data/sct_core/lib/sct_core/sct_pty.rb +53 -0
- data/sct_core/lib/sct_core/ui/implementations/shell.rb +129 -0
- data/sct_core/lib/sct_core/ui/interface.rb +120 -0
- data/sct_core/lib/sct_core/ui/ui.rb +26 -0
- data/sct_core/lib/sct_core/update_checker/update_checker.rb +76 -0
- data/shell/README.md +0 -0
- data/shell/lib/shell.rb +3 -0
- data/{lib/sct → shell/lib/shell}/ClassLevelInheritableAttributes.rb +0 -0
- data/shell/lib/shell/commands_generator.rb +14 -0
- data/shell/lib/shell/docker/composer.rb +16 -0
- data/{lib/sct → shell/lib/shell}/docker/docker.rb +54 -38
- data/shell/lib/shell/docker/php.rb +52 -0
- data/shell/lib/shell/docker/yarn.rb +17 -0
- data/shell/lib/shell/module.rb +9 -0
- data/shell/lib/shell/runner.rb +34 -0
- data/shell/lib/shell/tools.rb +7 -0
- metadata +126 -53
- data/.gitignore +0 -12
- data/.gitlab/merge_request_templates/DefinitionOfDone.md +0 -14
- data/.rspec +0 -3
- data/.travis.yml +0 -7
- data/CODE_OF_CONDUCT.md +0 -74
- data/Gemfile +0 -4
- data/Gemfile.lock +0 -48
- data/LICENSE.txt +0 -21
- data/README.md +0 -134
- data/Rakefile +0 -6
- data/lib/sct.rb +0 -61
- data/lib/sct/command_interface.rb +0 -18
- data/lib/sct/command_option.rb +0 -14
- data/lib/sct/commands/composer.rb +0 -29
- data/lib/sct/commands/init.rb +0 -51
- data/lib/sct/commands/mysqlproxy.rb +0 -38
- data/lib/sct/commands/php.rb +0 -37
- data/lib/sct/commands/yarn.rb +0 -26
- data/lib/sct/docker/composer.rb +0 -15
- data/lib/sct/docker/php.rb +0 -14
- data/lib/sct/docker/yarn.rb +0 -16
- data/lib/sct/version.rb +0 -3
- data/sct.gemspec +0 -40
data/{lib → sct/lib}/.DS_Store
RENAMED
File without changes
|
data/sct/lib/sct.rb
ADDED
@@ -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,50 @@
|
|
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
|
+
ensure
|
44
|
+
SctCore::UpdateChecker.start_looking_for_update('sct')
|
45
|
+
SctCore::UpdateChecker.show_update_status('sct', Sct::VERSION)
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
File without changes
|
@@ -1,28 +1,14 @@
|
|
1
|
-
require 'sct/command_interface'
|
2
|
-
|
3
1
|
module Sct
|
4
2
|
class HostfileCommand
|
5
3
|
|
6
|
-
IS_PUBLIC_COMMAND = true
|
7
|
-
SYNTAX = 'sct hostfile'
|
8
|
-
SUMMARY = 'adds the ingress url to the users hostfile'
|
9
|
-
DESCRIPTION = ""
|
10
|
-
EXAMPLE = "sct hostfile"
|
11
|
-
EXAMPLE_DESCRIPTION = ""
|
12
|
-
|
13
|
-
OPTIONS = []
|
14
|
-
|
15
|
-
def self.options
|
16
|
-
end
|
17
|
-
|
18
4
|
def execute(args, options)
|
19
|
-
return
|
20
|
-
|
21
|
-
return puts "This command needs to be run with sudo.".red unless Sct::Helpers.isSudo
|
5
|
+
return UI.error("SCT has not been initialized. Run 'sct init' first.") unless SctCore::Config.exists
|
22
6
|
|
23
|
-
return unless
|
7
|
+
return UI.error("This command needs to be run with sudo.") unless SctCore::Helper.isSudo
|
24
8
|
|
25
|
-
|
9
|
+
return unless SctCore::Helper.ingressAddress
|
10
|
+
|
11
|
+
ingressAddress = SctCore::Helper.ingressAddress
|
26
12
|
|
27
13
|
entries = [
|
28
14
|
{
|
@@ -52,7 +38,7 @@ module Sct
|
|
52
38
|
else
|
53
39
|
hosts_paths = ["/etc/hosts"]
|
54
40
|
|
55
|
-
if
|
41
|
+
if SctCore::Helper.operatingSystem == SctCore::Helper::WINDOWS
|
56
42
|
hosts_paths << "/mnt/c/Windows/System32/drivers/etc/hosts"
|
57
43
|
end
|
58
44
|
end
|
@@ -72,13 +58,11 @@ module Sct
|
|
72
58
|
|
73
59
|
File.write hosts_path, lines.join
|
74
60
|
|
75
|
-
|
61
|
+
UI.success("Patched #{hosts_path} with #{ingressAddress}")
|
76
62
|
end
|
77
63
|
|
78
64
|
end
|
79
65
|
|
80
|
-
implements CommandInterface
|
81
|
-
|
82
66
|
end
|
83
67
|
|
84
68
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'sct_core/ui/ui'
|
2
|
+
require 'sct_core/config'
|
3
|
+
|
4
|
+
module Sct
|
5
|
+
|
6
|
+
class InitCommand
|
7
|
+
|
8
|
+
def execute(args, options)
|
9
|
+
|
10
|
+
dir = SctCore::Config.dir
|
11
|
+
|
12
|
+
cli = HighLine.new
|
13
|
+
|
14
|
+
email = cli.ask("What is your email address?") { |q|
|
15
|
+
q.validate = URI::MailTo::EMAIL_REGEXP
|
16
|
+
}
|
17
|
+
|
18
|
+
cloud_proxy_path = cli.ask("What is the path of your cloud proxy json credentials?") { |q|
|
19
|
+
q.default = "~/.config/gcloud/application_default_credentials.json"
|
20
|
+
}
|
21
|
+
|
22
|
+
contents = ""
|
23
|
+
contents << "email=#{email}\n"
|
24
|
+
contents << "cloud-proxy-path=#{File.expand_path(cloud_proxy_path)}\n"
|
25
|
+
|
26
|
+
if !File.directory?(dir)
|
27
|
+
FileUtils.mkdir_p(dir)
|
28
|
+
end
|
29
|
+
|
30
|
+
File.write(SctCore::Config.path, contents)
|
31
|
+
|
32
|
+
puts "Generated config file at #{SctCore::Config.path}"
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Sct
|
2
|
+
class MysqlproxyCommand
|
3
|
+
|
4
|
+
DEFAULT_SECRET_NAME = "gcloud-credentials"
|
5
|
+
|
6
|
+
def execute(args, options)
|
7
|
+
|
8
|
+
return UI.error("SCT has not been initialized. Run 'sct init' first.") unless SctCore::Config.exists
|
9
|
+
|
10
|
+
path = SctCore::Config.get('cloud-proxy-path')
|
11
|
+
|
12
|
+
system("kubectl delete secret gcloud-credentials")
|
13
|
+
system("kubectl create secret generic gcloud-credentials --from-file=#{path}")
|
14
|
+
|
15
|
+
UI.success("Authenticated with secret-name: '#{DEFAULT_SECRET_NAME}'")
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'commander'
|
2
|
+
require 'sct/command'
|
3
|
+
|
4
|
+
module Sct
|
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, 'sct'
|
14
|
+
program :version, Sct::VERSION
|
15
|
+
program :summary, 'CLI helper tool for local SCT development'
|
16
|
+
program :description, 'SCT is a CLI tool for developers using the Visma Continuous Deployment Model in conjunction with the Google Cloud Platform (GCP). It provides multiple command to set up and maintain a kubernetes cluster on a machine for local development'
|
17
|
+
|
18
|
+
global_option('--verbose') { $verbose = true }
|
19
|
+
|
20
|
+
command :init do |c|
|
21
|
+
c.syntax = 'sct init'
|
22
|
+
c.description = 'setup sct'
|
23
|
+
|
24
|
+
c.action do |args, options|
|
25
|
+
UI.important("setting up sct")
|
26
|
+
Sct::InitCommand.new.execute(args, options)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
command :hostfile do |c|
|
31
|
+
|
32
|
+
c.syntax = 'sct hostfile'
|
33
|
+
c.description = 'patch hostfile with kubernetes ip'
|
34
|
+
|
35
|
+
c.action do |args, options|
|
36
|
+
UI.important("Trying to patch hostfile")
|
37
|
+
Sct::HostfileCommand.new.execute(args, options)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
command :'mysql proxy' do |c|
|
42
|
+
|
43
|
+
c.syntax = 'sct mysql proxy'
|
44
|
+
c.description = 'setup google mysql proxy'
|
45
|
+
|
46
|
+
c.action do |args, options|
|
47
|
+
UI.important("Trying to setup mysql proxy")
|
48
|
+
Sct::MysqlproxyCommand.new.execute(args, options)
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
run!
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
Binary file
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative 'sct_core/core_ext/string'
|
2
|
+
require_relative 'sct_core/config'
|
3
|
+
require_relative 'sct_core/helper'
|
4
|
+
require_relative 'sct_core/update_checker/update_checker'
|
5
|
+
require_relative 'sct_core/command_executor'
|
6
|
+
require_relative 'sct_core/ui/ui'
|
7
|
+
require_relative 'sct_core/sct_pty'
|
8
|
+
|
9
|
+
# third party code
|
10
|
+
require 'colored'
|
11
|
+
require 'commander'
|
12
|
+
|
13
|
+
# these need to be imported after commander
|
14
|
+
require_relative 'sct_core/module'
|
Binary file
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require_relative 'ui/ui'
|
2
|
+
require_relative 'sct_pty'
|
3
|
+
|
4
|
+
module SctCore
|
5
|
+
# Executes commands and takes care of error handling and more
|
6
|
+
class CommandExecutor
|
7
|
+
class << self
|
8
|
+
# Cross-platform way of finding an executable in the $PATH. Respects the $PATHEXT, which lists
|
9
|
+
# valid file extensions for executables on Windows.
|
10
|
+
#
|
11
|
+
# which('ruby') #=> /usr/bin/ruby
|
12
|
+
#
|
13
|
+
# Derived from https://stackoverflow.com/a/5471032/3005
|
14
|
+
def which(cmd)
|
15
|
+
# PATHEXT contains the list of file extensions that Windows considers executable, semicolon separated.
|
16
|
+
# e.g. ".COM;.EXE;.BAT;.CMD"
|
17
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : []
|
18
|
+
exts << '' # Always have an empty string (= no file extension)
|
19
|
+
|
20
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
21
|
+
exts.each do |ext|
|
22
|
+
cmd_path = File.join(path, "#{cmd}#{ext}")
|
23
|
+
return cmd_path if Helper.executable?(cmd_path)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
return nil
|
28
|
+
end
|
29
|
+
|
30
|
+
# @param command [String] The command to be executed
|
31
|
+
# @param print_all [Boolean] Do we want to print out the command output while running?
|
32
|
+
# @param print_command [Boolean] Should we print the command that's being executed
|
33
|
+
# @param error [Block] A block that's called if an error occurs
|
34
|
+
# @param prefix [Array] An array containing a prefix + block which might get applied to the output
|
35
|
+
# @param loading [String] A loading string that is shown before the first output
|
36
|
+
# @param suppress_output [Boolean] Should we print the command's output?
|
37
|
+
# @return [String] All the output as string
|
38
|
+
def execute(command: nil, print_all: false, print_command: true, error: nil, prefix: nil, loading: nil, suppress_output: false)
|
39
|
+
print_all = true if $verbose
|
40
|
+
prefix ||= {}
|
41
|
+
|
42
|
+
output = []
|
43
|
+
command = command.join(" ") if command.kind_of?(Array)
|
44
|
+
command = self.escape_characters_in_string(command)
|
45
|
+
UI.command(command) if print_command
|
46
|
+
|
47
|
+
if print_all && loading # this is only used to show the "Loading text"...
|
48
|
+
UI.command_output(loading)
|
49
|
+
end
|
50
|
+
|
51
|
+
begin
|
52
|
+
status = SctCore::SctPty.spawn(command) do |command_stdout, command_stdin, pid|
|
53
|
+
command_stdout.each do |l|
|
54
|
+
line = l.chomp
|
55
|
+
output << line
|
56
|
+
|
57
|
+
next unless print_all
|
58
|
+
|
59
|
+
# Prefix the current line with a string
|
60
|
+
prefix.each do |element|
|
61
|
+
line = element[:prefix] + line if element[:block] && element[:block].call(line)
|
62
|
+
end
|
63
|
+
|
64
|
+
UI.command_output(line) unless suppress_output
|
65
|
+
end
|
66
|
+
end
|
67
|
+
rescue => ex
|
68
|
+
# SctPty adds exit_status on to StandardError so every error will have a status code
|
69
|
+
status = ex.exit_status
|
70
|
+
|
71
|
+
# This could happen when the environment is wrong:
|
72
|
+
# > invalid byte sequence in US-ASCII (ArgumentError)
|
73
|
+
output << ex.to_s
|
74
|
+
o = output.join("\n")
|
75
|
+
puts(o)
|
76
|
+
if error
|
77
|
+
error.call(o, nil)
|
78
|
+
else
|
79
|
+
raise ex
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Exit status for build command, should be 0 if build succeeded
|
84
|
+
if status != 0
|
85
|
+
o = output.join("\n")
|
86
|
+
puts(o) unless suppress_output # the user has the right to see the raw output
|
87
|
+
UI.error("Exit status: #{status}")
|
88
|
+
if error
|
89
|
+
error.call(o, status)
|
90
|
+
else
|
91
|
+
UI.user_error!("Exit status: #{status}")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
return output.join("\n")
|
96
|
+
end
|
97
|
+
|
98
|
+
def escape_characters_in_string(string)
|
99
|
+
pattern = /(\'|\"|\.|\*|\/|\-|\\|\)|\$|\+|\(|\^|\?|\!|\~|\`)/
|
100
|
+
string.gsub(pattern){|match|"\\" + match}
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -1,8 +1,8 @@
|
|
1
|
-
module
|
1
|
+
module SctCore
|
2
2
|
class Config
|
3
3
|
|
4
4
|
def self.dir
|
5
|
-
return "#{
|
5
|
+
return "#{SctCore::Helper.homePath}/.config/sct"
|
6
6
|
end
|
7
7
|
|
8
8
|
def self.path
|
@@ -30,7 +30,7 @@ module Sct
|
|
30
30
|
|
31
31
|
contents = File.read(self.path)
|
32
32
|
|
33
|
-
return
|
33
|
+
return SctCore::Helper.to_hash(contents)
|
34
34
|
end
|
35
35
|
end
|
36
36
|
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
module
|
2
|
-
class
|
1
|
+
module SctCore
|
2
|
+
class Helper
|
3
3
|
|
4
4
|
WINDOWS = "Windows"
|
5
5
|
MAC_OS = "MacOS"
|
@@ -86,5 +86,13 @@ module Sct
|
|
86
86
|
def self.isSudo
|
87
87
|
return !ENV["SUDO_USER"].nil? && !ENV["SUDO_USER"].empty?
|
88
88
|
end
|
89
|
+
|
90
|
+
def self.minikube
|
91
|
+
if self.operatingSystem == WINDOWS
|
92
|
+
return "minikube.exe"
|
93
|
+
else
|
94
|
+
return "minikube"
|
95
|
+
end
|
96
|
+
end
|
89
97
|
end
|
90
98
|
end
|